How to change roll of bone?

I have some animations that work for this avatar I built. I found another avatar with the exact same bone hierarchy but the bones had different roll values. In the animation this resulted in twisted limbs. I solved this in Blender by unparenting the armature, changing the roll of the bones (some to 0, some to -180 or 180) then re-parenting. Is there a way to do this with BabylonJS code?

Basically bones are simple matrices. So it should be “the same”. You have to edit every bone and set the matrix to apply the the correct roll

1 Like

So I just have to alter the bone’s local matrix once?

Correct

Actually I think it’s the difference matrix that should be changed, not the local matrix, because if you just change the local matrix then those changes will be overwritten when you animate the bone…
https://playground.babylonjs.com/#BCU1XR#4247

1 Like

This is good catch:)

1 Like

Hi @ozRocker just checking in, were you able to solve your problem? :smiley:

Not yet. Unfortunately the playground example doesn’t work for me. Applying a new rotation matrix to my avatar screws up scale and position

What about doing it like below to update the existing base matrix instead of replacing it? (You might have to start an animation to see the effect).

const scale = new BABYLON.Vector3();
const rotationQuaternion = new BABYLON.Quaternion();
const position = new BABYLON.Vector3();

const differenceMatrix = bone._baseMatrix;
differenceMatrix.decompose(scale, rotationQuaternion, position);

const rotation = rotationQuaternion.toEulerAngles();
rotation.y += Math.PI;
BABYLON.Quaternion.FromEulerVectorToRef(rotation, rotationQuaternion);

BABYLON.Matrix.ComposeToRef(scale, rotationQuaternion, position, differenceMatrix);
bone.updateMatrix(differenceMatrix);

I’ve implemented those changes and I can partially get it working.
You can see my efforts here. This first playground is using the GLB with the original roll values. I’m attempting to untwist the bones https://playground.babylonjs.com/#63T6K7#1
In the second playground I’m using a GLB where I corrected the roll values in Blender and it works perfectly, so this is how it should look https://playground.babylonjs.com/#63T6K7#2

This looks better https://playground.babylonjs.com/#63T6K7#3 but there is still some serious warping going on. If you change the animation to “sitting.glb” you’ll notice it clearly.

1 Like

I get a load error trying to use these PG links but I downloaded the models and then the code woks fine so maybe the server settings are blocking it somehow? It looks better but IDK why it isn’t working - I ran out of ideas for now but if I think of something I’ll give it another try. :slight_smile:

Whoops! Sorry about the CORS errors. I just added an .htaccess that should fix that

1 Like

When I look closely at the results of this playground I see that this warps the foot bone. If you change RotationY to RotationX or RotationZ (like here https://playground.babylonjs.com/#BCU1XR#4770) you’ll see that the warping is more obvious. This is the bit I’m stuck at. I cannot seem to change the roll of the bone without warping the other bones. Has anyone figured out how to not warp the other bones?

I don’t see any warping of the foot as the leg rotates. Just the ground was covering part of it before…

EDIT: oh I see, you have to start an animation to see the deformation… IDK what the fix is then, I bet @bghgary is good person to ask for help thou. :slight_smile:

I’m not exactly sure what you are trying to do, but maybe this?

PG: https://playground.babylonjs.com/#BCU1XR#4803

I’m trying to permanently change the roll of the bone so it affects how its animated, but without warping the mesh. In all the examples I’ve seen, rolling the bone is fine until you run the animation. The reason I’m doing this is because I’m trying to copy an animation from one avatar to another but sometimes the target avatar has bones with different roll value. Here is an example of the problem I’m facing https://playground.babylonjs.com/#79BG1H#2 Original avatar is the grey one, target avatar is the white one.

I haven’t looked at the new playground yet, but what you are doing with updateMatrix seems like it’s correct.

PG: https://playground.babylonjs.com/#BCU1XR#4804

This method warps the mesh. I increased the rotation a bit on your playground https://playground.babylonjs.com/#BCU1XR#4805 Press WALK and you can see some negative side effects

1 Like

I tried a bunch of things, but I don’t know the right math to do this. The problem with just updating the base matrix and difference matrix in isolation is that the bone position doesn’t change. You can see this if you try to show the position of mixamorig:RightLeg.