Inconsistent GLTF bone transformations

Hi,
some GLTF characters have their bone positions and/or rotations messed up. I can’t say what’s exactly wrong, but BoneAxesViewer also gets it wrong. That’s regression in v5.
Playground: Babylon.js Playground

pinging @bghgary

I’m doing a first check to see if I can fix within the next hour

Ok I found the root cause :slight_smile:
The way we handled skeleton within glTF was a bit too convoluted in 4.2

So we decided to simplify it a bit. From the breaking changes of 5.0:

Loading glTF assets with skins now places skinned meshes as siblings of the corresponding skeleton root nodes instead of using skeleton.overrideMesh

(@bghgary I think we should document that and how it works in the skeleton documentation)

Here is the fix for your PG:
GLTF character bone positions | Babylon.js Playground (babylonjs.com)

The idea is to figure out which transformNode is the root of the actual mesh

1 Like

Maybe we need a link. I documented how this works for gltf here: glTF 2.0 Skinning | Babylon.js Documentation

2 Likes

Even better:
GLTF character bone positions | Babylon.js Playground (babylonjs.com)

I’m using node.getTransformNode() on the root bone to get the mesh to use with BoneAxesViewer

… and that seems to be container.skeletons[0].bones[0].getTransformNode() - at least as far as BoneAxisViewer is concerned, at least in the playground :slight_smile:
Locally I have a twilight zone: two BoneAxisViewers, for upper and lower leg, and they work fine as long as I update lower one first :grin: Otherwise I get like


Something seems off with transformation hierarchy…

I have update on this: GLTF character bone positions | Babylon.js Playground (babylonjs.com)
This looks fine; but create root mesh and bone absolute position goes way away.

So really, what do I need to do to get actual bone position?

cc @bghgary

Sorry, I’m not understanding this. What do you mean?

@bghgary see the playground above, in particular

            // replace this with with that to mess it up
            var root = container.meshes[0];
            //var root = container.createRootMesh();

and

            var absolutePos = bone.getAbsolutePosition(transform);
            console.log(absolutePos);
            var sphere = BABYLON.MeshBuilder.CreateSphere();
            sphere.position = absolutePos;

The absolute position of the bone changes from
_x: -1.195454716682434, _y: 1.6862452030181885, _z: -0.047228556126356125
to
_x: -3.9090933799743652, _y: 33.72490310668945, _z: 0.9445710778236389
when the root mesh is created. Not very absolute is it? :wink:
So is it expected behavior? If it is, what do I need to do to get actual absolute position of the bone?

You would need to force computing the world matrices if you do changes before using them: https://playground.babylonjs.com/#H925CH#8

2 Likes

Oh dang, but on transform node!
I’ve been trying on bone :slight_smile:
Alright thanks @sebavan