How to set a TransformNode world rotation?

I have a model with a hierarchy of bones, and I want to set the world rotation of a certain bone. How can I do that?
I’ve read this topic: How to set world rotation for a transformNode with multiple hierarchy nodes?
But the given answer doesn’t work for me. Setting the local .rotation with the world rotation delta seems wrong. And I can’t figure out how to use matrices for this purpose.

In terms of bones you can use setAxisAngle, setYawPitchRoll, setRotation, or setRotationMatrix to rotate a bone to a specific rotation in local or world space, as you need.

http://grideasy.github.io/tutorials/How_to_use_Bones_and_Skeletons

I am using a .glb model, so I have to set rotation using TransformNode.

This would explain why it doesn’t to just change rotation property. You will have to change rotationQuaternion.

Multiply absoluteRotationQuaternion.inverse() of TransformNode’s parent with your world rotation (as quaternion):

var worldRotation = ... // the world rotation you want to apply on bone (or its TransformNode)
var worldRotationQuat = BABYLON.Quaternion.FromEulerVector(worldRotation);
boneNode.rotationQuaternion = worldRotationQuat.multiply(boneNode.parent.absoluteRotationQuaternion.inverse());
2 Likes

Thanks for the answer! But I am still not sure if it is working properly… Rotation seems off.

I had to reset the root mesh transform, as avatar was initially spawned with (0,180,0) rotation and (1,1,-1) scale for some reason. I’ve also added computeWorldMatrix(true) to get the correct absoluteRotationQuaternion from the parent node (if I understand it correctly). And changed inverse() to invert(). Still no luck!

@romaleks360 your model has quite a large rotation applied by the parent probably by design https://www.babylonjs-playground.com/#WGZLGJ#7792

By setting an absolute 0 0 0 for instance you would cancel the parent rotation making your model probably looking off here.

You will get into conflict by just setting scaling of glb-model to positive values, instead i recommend to use scene.useRightHandedSystem = true.

Also I am not quite sure why it doesn’t work for you. If I apply (0, Math.PI, 0) on head bone node the head is facing backwards, if I apply (0, 0, 0) it is facing forwards. Maybe you didn’t want world rotation (instead one that is relative to bone/mesh/node alignment)?

Here is the head facing backwards PG (neck gets deformed):

In Unity, running headTransform.rotation = Quaternion.Euler(0, 180, 0); gives me another result. The head’s line of sight is paralell to the ground. It applies local offset on the X axis to cancel the neck rotation. I was expecting the same result.
In your sandbox, the final local head rotation in Inspector is (0, 180, 0), which is the same as the target world rotation, so it doesn’t cancel the neck/hierarchy rotation.

I am not sure that it is that simple as currently to stand straight the node is not at 0 0 0 rotation but

You would need to keep this rotation factored in.