Rotating Bone in World Space and Scaling

Rotating a bone in world space should not change the scale of the bone.

When this mesh has a parent that is scaled, the bone that is rotated in world space doesn’t maintain the proper scale.

https://www.babylonjs-playground.com/#D4ZZ8#59

1 Like

It looks like this was working at one point since there are parentScale and parentScaleInv vars. I could be wrong, though. I should probably test with an old version of BJS.

I spent a few hours trying to fix it with no luck. I came up with a hack that works, but it only takes into account one level of mesh parenting. It’s frustrating when I get side tracked by stuff like this.

1 Like

I just tested BJS 3.1.1 and the problem is there, too.

Edit: This issue was also in v2.5.

Here is my hack / band-aid that goes at toward the end of Bone._rotateWithMatrix (now working for multiple parents).

`if(space == BABYLON.Space.WORLD && mesh && mesh.parent){
            var mat = Bone._tmpMats[5];
            var scaling = Bone._tmpVecs[0];
            scaling.x = 1;
            scaling.y = 1;
            scaling.z = 1;
            var parent = mesh.parent;
            while(parent && parent.scaling){
                scaling.x *= parent.scaling.x;
                scaling.y *= parent.scaling.y;
                scaling.z *= parent.scaling.z;
                parent = parent.parent;
            }
            if(scaling.x != 1 || scaling.y != 1 || scaling.z != 1){
                BABYLON.Matrix.ScalingToRef(scaling.x, scaling.y, scaling.z, mat);
                lmat.multiplyToRef(mat, lmat);
            }
        }

`

Edit:
This fix actually needs to be in Bone._getNegativeRotationToRef - not in _rotateWithMatrix.
A similar fix needs to be added to BoneIKController when computing bone lengths.

1 Like

PG with potential fix:

https://www.babylonjs-playground.com/#D4ZZ8#60

1 Like

Just found a similar issue with the IKController. No parent mesh - just scaling bones before using ikcontroller.

https://www.babylonjs-playground.com/#PNJGW#10

so that modification to rotateWithMatrix doesn’t fix this new issue. :frowning:

On a positive note: I just earned my ‘First Emoji’ achievement in this forum. LOL

2 Likes

Here is a potential fix for the parent bone scale issue:

https://www.babylonjs-playground.com/#PNJGW#12

I added this to rotateWithMatrix in the parent && world space section:

var mat = Bone._tmpMats[5]; var scaling = Bone._tmpVecs[0]; parent.getScaleToRef(scaling); if(scaling.x != 1 || scaling.y != 1 || scaling.z != 1){ BABYLON.Matrix.ScalingToRef(-scaling.x, -scaling.y, -scaling.z, mat); mat.multiplyToRef(lmat, lmat); }

Edit: This fix is no good.

1 Like

Need to use scalingDeterminant rather than just multiplying scaling by -1;

https://www.babylonjs-playground.com/#PNJGW#13

            var mat = Bone._tmpMats[5];
            var scaling = Bone._tmpVecs[0];
            parent.getScaleToRef(scaling);
            if(scaling.x != 1 || scaling.y != 1 || scaling.z != 1){
                var sd = this._scalingDeterminant;
                BABYLON.Matrix.ScalingToRef(sd*scaling.x, sd*scaling.y, sd*scaling.z, mat);
                mat.multiplyToRef(lmat, lmat);
            }

I guess I need to update my BJS dev environment so that I can submit a PR.

Edit: just discovered that this incorrectly scales children bones when they aren’t supposed to be scaled:

https://www.babylonjs-playground.com/#PNJGW#14

Ugh. I’m hanging this up for now.

I’m remembering why the early versions of the Bone class cached more scaling info.

Edit:
It works the way it’s supposed to in v2.5:
https://jsfiddle.net/wtoadecs/

2 Likes

this was a very insightful thread… thank you.

1 Like

Woot @adam, I loved reading your dev log :slight_smile:

Please open a PR as soon as you can