How to restore rotation after parenting?

Heya,
I feel like this is going to be a question that might make some of you go “Again?” but I’m out of brain cells to work this out… I feel like this is a trivial thing yet I’m really struggling here.

I’m parenting a transformNode (that contains a mesh) to a bone. The goal is to keep the same rotation and position after parenting to the bone. I’m not using attachToBone for some reasons, and I think attachToBone would lead to the same issue, so bear with me in trying this with parenting…

This is my current process:

  • Place the sword to the position I want (around the hand bone).
  • Rotate the sword appropriately so it looks good.
  • Set parent
  • re-apply previous rotation and position

I got position to be re-applied fine using setAbsolutePosition, but the rotation is just always wrong;

I just can’t figure out how to re-apply exactly the same rotation to the mesh/node…

I tried something similar to this:
sword.absoluteRotationQuaternion.toEulerAngles().subtract(myBone.getRotation())
to get the rotation of the sword relative to the bone’s rotation.
But to no avail…
I tried with every different spaces and at this point I’m just throwing ideas at the wall with nothing sticking.

I made a somewhat similar repro to what I’m doing but it has some scaling issues I think.
You can comment out from line 55 to 61 to get the original rotation and position of the “sword”.

Image is just to show one needs to zoom out to see the new position/rotation of the “sword”

Would love some insights ! Thank you!

If you want the relative rotation, you may get absolute quaternions of sword & bone and then multiply sword quaternion by inverse of bone quaternion.

Actually, attachToBone does work as expected:

I don’t think parenting to a bone in user code will work, because a bone is not exactly like a TransformNode, you don’t get its transformation by calling getWorldMatrix but by calling getFinalMatrix instead. That’s precisely the purpose of using attachToBone to trigger some special code in the TransformNode.computeWorldMatrix method:

If you really don’t want to use attachToBone, I think you will have to not parent your sword at all and update each frame the sword position/rotation so that it matches the position/rotation of the bone.

Yeah this is pretty much what I want to do I think; I want to grab the relative rotation so I can re-apply it later

@Evgeni_Popov That makes a lot of sense and it’s very informative. It’s good to know. I’m still struggling to re-rotate to the proper rotation after attaching to the bone

@Takemura I tried your strategy but maybe I didn’t do it properly? (the line is the correct rotation)

This new repo: https://www.babylonjs-playground.com/#HRP145#3
Has both of your comments integrated into it

I’m not sure what you want to achieve from this position:

Which is correct (?) and is what you get from my PG above.

This is what I mean:
Rotation before parenting / attaching to Bone:
image

Rotation after parenting / attaching to Bone:
image

I had found this post which almost rephrase what I’m trying to do Rotate child mesh to match world direction vector unless I misunderstood it.
" Have rotation of a child mesh / node looks exactly the same regardless of parenting"

So my thoughts were:

  • Obtain rotation of the “sword” relative to the future parent
  • parent
  • Add relative rotation to the parent’s rotation so the new sword rotation “looks” the same as before

I’m sorry for my poor formatting and explanations

PS: Happy cake day!

One simple way would be to

var direction = sword.getDirection(BABYLON.Axis.Y)

before attach and

sword.lootAt(sword.getAbsolutePosition().add(direction))

afterwards.

The full PG:

Oooh close! thanks @Takemura ;
It’s still not quite the “original” rotation though
Before:
image
After:
image

We can see an slight rotation that’s not quite like the original one…

Oh sorry, didn’t observe carefully, here is the matrix approach:

Tell me if you have questions about it.

2 Likes

That works well!, Thanks @Takemura