Advertisement

gltf skinning matrix calculation

Started by August 26, 2019 03:35 AM
1 comment, last by iradicator 5 years ago

I'm implementing skinning following gltf 2.0 spec.

I'm loading the RiggedFigure example from gltf sample set, and although I was able to animate the bones correctly, I'm getting these weird and not symmetric artifacts (look at the right shoulder and left arm). Seems to me like the joint matrices aren’t calculated properly because of the way I’m applying the to-parent transforms – I can use some help - more info below.

https://github.com/KhronosGroup/glTF-Sample-Models/tree/master/2.0/RiggedFigure/glTF-Embedded


If someone wants to refer to the explanation in gltf cheat sheet – please provide the formulas to derive the matrices (e.g. globalTransform).
https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/figures/gltfOverview-2.0.0b.png
 

Here’s my calculation for each joint (right to left multiplication, row major matrices):

•    Apply invBindMatrix provided by gltf – this will transform positions in mesh coordinate space to joint’s bind-pose.
•    Interpolate the provided keyframe data to produce joint bind-pose to animated-pose transform (this is controlled by the animator). This is the part that I’m not 100% what matrix I’m getting back – I think it’s the transform from bind pose to animated pose for a particular joint.
•    Now I’m in animated pose for a specific joint (local coordinate system). So I’m applying a concatenation of joint-to-parent transforms back to the root and I’m done. 

animateJointTransform = AnimateUsingKeyframes(…);
jointFinalTrans = parentTransform * animateJointTransform * inverseBindMatrix;

I think I have an error calculating the to-parent total transform. Here’s my logic. If I’m in animated space, then I just need to concatenate the calculated local joint transforms as I go. That is (when passing down to children):

nextParentTransform = parentTransform * animateJointTransform;

And the init of the first toParentTransform is the transform that places the root of the skeleton in the right location in the world (this seems to work).

The surprising thing for me is that the joints are animated perfectly and in the right position and orientation, but the skin is all messed up. Also, the simpler skinning example that doesn't contain complex hierarchy also works for me.. That suggesting to me that something is fishy with the toParent transforms. What am I missing?

One thing to note is that I'm not using the local joint transform at all (the one provided in the listing of the different nodes in gltf file). My understanding is that it's not relevant because the nodes are animated - so the local transform of each joint is actually "animateJointTransform".


image.png.df8ba15a6d4a6843783086f1efcf1374.png

I figured it out.

The problem was that the order of the passed matrices must be equal to the same ordering provided in skin data.

So my assumptions above about matrix calculations are correct.

I hope others will find it useful.

image.png.98fcfaa219b36623e2aa38294b9addd9.png

This topic is closed to new replies.

Advertisement