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.
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.
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.
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.
PG with potential fix:
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.
On a positive note: I just earned my ‘First Emoji’ achievement in this forum. LOL
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.
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/
this was a very insightful thread… thank you.
Woot @adam, I loved reading your dev log
Please open a PR as soon as you can