Sign in to follow this  

Collada Joint Loading

This topic is 1496 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hey guys, I'm a little brain dead, and I'm trying to figure out how to correctly create the bind pose for a model.

 

I've tried a couple of different permutations of multiplying matrices and I'm looking for some support.

So my general understanding is that I read in the nodes with the "JOINT" type. Then I store their matrix data as their local transform. Then I convert the joint's transform to world space by concatenating the matrices starting from the parent node and walking down the joint list.

Is this the bind pose?

If I multiply this matrix with the joint's InvBindMatrix will that work? Or do I need to walk the joint tree again and concatenate the InvBindMatrices as well?
Where should I apply the bind matrix shape?

All I want to do right now is draw the skeleton for a model. I'm not looking to apply skinning yet.

I know this is kind of vague, but I'm just looking for some feedback.

Share this post


Link to post
Share on other sites

So you have the local transform for all the joints, you get the world transform for all the joints by concatenating a given joints local with its parents world

jointWorld = parentJointWorld * jointLocal   // build each frame

The bind shape matrix needs to be applied every frame to the original vertices, for this reason you may want to apply it to the mesh and store it, youll need it every frame to animate.

bindShapeVertex = bindShapeMatrix * meshVertex  // can be precomputed

Each joints invBindMatrix must be combined with its world matrix, so if a joints local transform changes (from animation sampling or its parent local/world changes) then a joints world will change, and its invBindMatrix gets concatenated. call this the skinning matrix.

jointSkinMatrix = jointWorld * jointInvBindMatrix   // build each frame

So......

For Each original vertex (ov)

    skinnedVertex = (0, 0, 0)

    For Each joint affecting ov with some weight

        skinnedVertex += ((jointWorld * jointInvBindMatrix) * (bindShapeMatrix * ov))) * affectingJointWeight

 

where "bindShapeMatrix * ov" can be precalculated and "jointWorld * jointInvBindMatrix" is the joints skin matrix

The bind pose (terminology bounces around) for me, is the initial local transform for the skeleton with the formula above applied.

Share this post


Link to post
Share on other sites

Thanks very much for the help!
A couple of question so I can be sure on vocabulary, and it's been a long time since I've done smooth skinning.
So for a test before I move on to reading out animations, I'm just trying to draw the skeleton for the model. In order to show the "T-Pose" or "Bind-Pose" as a series of lines representing the joints, I would multiply a world space point by the skinning matrix, correct?

Sorry I'm inheriting a very old code base, and I want to make absolutely sure this isn't something I'm doing wrong in Collada before I start tearing through the engine.

Share this post


Link to post
Share on other sites

Any frame or pose, is just a set of local transforms for a set of joints at a given point in time (the important part of a joint being the local transform, joints as a whole contain lots of other info).

So say you have a character that was rigged, arms flat out to sides, head straight, legs straight but slightly apart to allow room to work. You can consider this as frame 0 of a 1 frame animation, this would be your T-Pose/BindPose, the location where the skeletons local transforms and mesh vertices were when the skinning began in the modeling package.

If youre just gonna draw the lines between the joints world transforms, its probably enough to just traverse the skeleton from root, calculate each joints world and draw lines between their world translations. using the joints initial local transform.

Share this post


Link to post
Share on other sites

Just a note on "jointWorld = parentJointWorld * jointLocal   // build each frame"

 

Dont forget that depending on how you've read the data in, you may be in row major format multiplying by column major, and that these matrices are noncommutative. I got caught out by this more times that i care to admit to...

 

jointWorld worked out for me to be: jointWorld = jointLocal * parentJointWorld.

Share this post


Link to post
Share on other sites

This topic is 1496 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this