Collada Joint Loading

Started by
4 comments, last by Stragen 10 years, 5 months ago

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.

Perception is when one imagination clashes with another
Advertisement

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.

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.

Perception is when one imagination clashes with another

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.

Okay, that's what I'm doing now. I'm not getting the right values though, so maybe there is something else going on. Thanks for clearing up everything!

Perception is when one imagination clashes with another

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.

This topic is closed to new replies.

Advertisement