Skeleton scale accuracy

So right now with a skeleton that I am exporting from blender, the skeleton bones seem to have a weird scaling set to them initially.

Shouldn’t they all be at 1,1,1. Is it some float accuracy thing?
for example here is some scale values from the mesh before I do anything to the bones

skeleton.bones[0].getScale()
e {x: 1, y: -1.0000196205601857, z: 1.0000196205601857}

skeleton.bones[1].getScale()
e {x: 1, y: 1.0000181462591353, z: 1.0000181462591353}

skeleton.bones[2].getScale()
e {x: 1, y: 0.9999562096314237, z: 0.9999562096314237}

do those bones have 1,1,1 scaling prior to export?

They should be, I never scaled any of them. They were adjusted with standard armature placement.

How to I check that on blender? As far as I can tell bones do not have a scale parameter other then the object scaling, which is set to 1 on everything.

Select the Armature in OBJECT mode - is it scaled 1,1,1 ?

Now go into POSE mode and select individual bones are they scaled 1,1,1?

Everything should be OK.

cheers, gryff :slight_smile:

Yup they are 1 across the board let me see if I can make a test case.

Update

I can confirm that a bone exported from blender that is just generically made and never even messed with does not come into babylon with a 1,1,1 scale after the first bone.

Unless I am doing something wrong but even with just the base scene if I go
Shift+a in object mode then add an Armature, then select the cube and the bone and do a Shift-P automatic weights, then export to .babylon file.

Upon importation of the model through BABYLON.SceneLoader.ImportMesh if I console log out
skeleton.bones[0].getScale()
e {x: 1, y: -1, z: 1}

which is cool, so back to blender. I then follow the same steps but add 3 bones by doing an armature extrude twice and then export upon console logging out this is the results:

skeleton.bones[0].getScale()
e {x: 1, y: -1, z: 1}
skeleton.bones[1].getScale()
e {x: 0.9999879617418532, y: 0.9999798092450766, z: 0.9999657783610445}
skeleton.bones[2].getScale()
e {x: 0.9999764341001853, y: 0.9999717635527345, z: 0.999977052363976}

So there is something happening here.

Well if you are using “skeleton.bones[0].getScale()” to get the scale. where does the number come from?

In a babylon file with a character skeleton I see this for the first bone(hips):

{“name”:“Hips”,“index”:0,“matrix”:[1,0,0,0,0,0.9409,0.3385,0,0,0.3385,-0.9409,0,0,1.1224,-0.0043,1],“rest”:[1,0,0,0,0,0.9409,0.3385,0,0,0.3385,-0.9409,0,0,1.1224,-0.0043,1],“parentBoneIndex”:-1,“length”:0.105,
“animation”:{“dataType”:3,“framePerSecond”:30,“keys”:[
{“frame”:1,“values”:[1,0,0,0,0,0.9409,0.3385,0,0,0.3385,-0.9409,0,0,1.1224,-0.0043,1]},

{“frame”:240,“values”:[1,0,0,0,0,-0.4951,0.8689,0,0,0.8689,0.4951,0,0,0.1191,0.7449,1]}],
“loopBehavior”:1,“name”:“anim”,“property”:"_matrix"}},

All I see is “length” and “matrix” values. Is the scale value you obtain coming from a calculation of some kind in the BJS code?

And why is the difference, for example, in value of x: 0.9999879617418532 from x:1 so important?

cheers, gryff :slight_smile:

The only way I know to set scale on a mesh in a rendered scene is to us RegisterBeforeRender. Have you tried this. If not, I would be surprised as I know you well.

Galen

@Galen it’s not mesh scale it’s bone scale that is being odd.

If I get a chance this weekend I’ll take a look at the Babylon exporter and look at the skeleton section cause there is something fishy. A bone with all it’s scaling in Blender set to 1 should come into Babylon as 1,1,1 scale. @gryff it’s grabbing the values from the transform matrix I’d assume but if a bone is at its transformation origin and just imported there is no reason for any scaling values to not be 1 unless there is some tech reason I don’t know.

Hey @Pryme8,
I didn’t think about his. But you introduced an issue I faced 20 years ago. If there is any disparity set scaling on a bone system (parenting), then the whole weight system doesn’t work. Good for you. Easy to solve if you know what you’re looking for. You got this I’m pretty sure. Otherwise send me the files and I’m happy to help

Galen

@Pryme8

Sorry Andy, I meant bone scale. The solution however is to always freeze all of your transforms before export. Here’s how the Blender manual instructs how to do this. I can’t imagine you will have any issues after this operation.

https://docs.blender.org/manual/en/latest/editors/3dview/object/editing/transform/clear_apply.html

Galen

1 Like

Thank you! I will take a look at this when I get back to town. Heading to riverside right now to go see my son, so I will not be able to check till next Tuesday.

Thanks for the solution though hopefully though.

1 Like

@Pryme8 I hope all is resolved with your Son now. I’d like to meet him as I live so very close. Let me know when you’re in town next time.

Galen

1 Like

Where you at these days? We might be able to meet up Sunday.

Nope unfortunately that does not fix it.
skeleton.bones[0].getScale()
e {x: 1, y: -1, z: 1}
skeleton.bones[1].getScale()
e {x: 1.0000036630174596, y: 0.9999823916184019, z: 0.9999959939462628}
skeleton.bones[2].getScale()
e {x: 0.9999973543322761, y: 1.0000099005088465, z: 1.000018850788985}
skeleton.bones[3].getScale()
e {x: 1.000034891772211, y: 1.0000018842605292, z: 1.0000438783243413}

I have tried to lock all the transforms and everything was for sure cleared out, can anyone else get a child bone to inherently be 1,1,1 on import?

Shouldn’t the first bone placed be 1,1,1 as well? Especially when nothing was done to it expect binding it.

Even on the bones demo it does this, Babylon.js - Bones demo where if you output the scale from any of the child bones its not 1,1,1 scale.

I think this is because the scale is extracted from a matrix (bones only hold matrices and not TRS values)

Have you tried to setScale on import of bones?

Galen

is there a way to make them all be set to 1,1,1 on the matrix on the import? I am doing something pretty specific and to have them all with random values just complicates things.

Plus if they are not 1,1,1 on import/export wouldn’t that mean they are affecting the skin even if its a tiny amount?

it is all about float32 precision which is used to store the matrices.
you can check the bone matrix to see if it is 1,1,1 at that level (providing there is no rotation)

And no the matrix seems to be off from 1,1,1 on all of them, after scanning the function responsible for it I am assuming it is the node.getLocalTM() function or whatever it was that I saw that is generating it. Would there be a way for me to overwrite the values somehow without distorting the mesh? I mean if I could even just get the scaling values to round to a 1 it would make my life soooo much easier… at this point I’m moving forward with the error though.

Like shouldn’t a default bone that has not even been touched come in at 1,1,1 not 1,-1,1 at the very least?

Blender or the exporter, which rounds to 4 digits for bone matrices might also be a cause. If you looked at the matrices in the export file, are the 0, 5, 10 elements 1?

If not, then something upstream is introducing this. I am a big believer in divide & conquer.

1 Like