Skeletal Animation (nearly right)

Started by
1 comment, last by gzboli 15 years, 4 months ago
Hi everyone I have simple skeletons and 3ds max's bipeds animating correctly but when it comes to an artist's custom rig my code isn't holding up. Before I continue I should mention I'm using COLLADA to export from 3ds max, then converting to a binary format. Even if you aren't familiar with COLLADA I'd appreciate hearing some "gotchas" you've encountered, they might be what I'm missing! I know the COLLADA file contains the correct data because re-importing results in a correct animation. The transforms that I'm aware of(and they seem to be all of them in the COLLADA file are: Skin bind matrix - SkinBind - Brings the geometry into bind space at the time the mesh was bound to the skeleton. Bone bind matrix - iBBind - The transform of bone i at the time the mesh was bound to the skeleton. Bone Animation matrix - iBAnim - This is the animated transform of bone i for some time t. It is a local transform, not premultiplied with the hierarchy. It is an absolute transform, not a relative. Bone Inverse Bind - iInvB - Brings the geometry from object space to bone space. I think that covers it. Which gives us the equation: (with column vector v) (with combined parent BAnim ComboParent) final = ComboParent * iBAnim * iInvB * SkinBind * v The thing is, even without skinning the animation isn't running correctly, so let's simplify the equation to get the origin of a bone: BoneOrigin = ComboParent * iBAnim * Transpose(0,0,0,1) That's right isn't it? All I should need is the current transform of the hierarchy? Some other notes: - This rig is different from the others in that the skeleton has multiple root bones. But this seems trivial, my skeleton is organized in with ->sibling and ->child pointers. So the first root has siblings to other roots. - For bones that are not animated, I use the bone's bind matrix iBBind. - If I use the bone bind matrices instead of the animation data, the skeleton is still wrong. After writing this it makes me think maybe it's just some code I've over looked. Like my hierarchy not evaluating the way I think it is. =/ Anyway, thanks if you read this far =P Any comments/ideas?
Advertisement
In your matrix operations, does your parent result come first or your bone?

I ask because order is important - you must transform the bone first by the animation matrix, then take that and multiply it by the final transform of your parent, to get your final transform.

edit: Actually, I see in your equation it's right to left, and the operation order looks fine. Next question, how is "ComboParent" calculated?

edit2: I just looked at my skinning code, and something to keep in mind is to not multiply the bone's inverse bind matrix into the "ComboParent" hierarchy. Multiply after the bones have been transformed by parents.

In other words, with three bones A-->B-->C (--> indicates parent-of), and reading matrix mul's from right to left:

transformA = animTransformA;transformB = animTransformB * transformA;transformC = animTransformC * transformB;finalTransformA = transformA * inverseBindPoseA;finalTransformB = transformB * inverseBindPoseB;finalTransformC = transformC * inverseBindPoseC;


The inverse bind pose's purpose is to move the mesh into bone space, and is only necessary upon rendering the actual mesh. In order to calculate your child bone transforms make sure that the parent's inverse bone matrices are not into the mul order.

Hope that helps --

[Edited by - Grafalgar on December 4, 2008 4:33:04 PM]
Thanks Grafalgar, I'll probably be reading that several times tonight to double check my work ;)

I looked over all of the places in my conversion code, and rendering code, for matrix multiplications. Found one out of order, the other I was replacing rather than concatenating.

I also found a bug in my quaternion slerping. Fixing this removed an artifact as well.

Here's where I'm at now:
">YouTube Animation3

Just that one leg is twitching out of control. Everything else looks like it does in 3ds Max! Anyone have something like this occur to them? I guess I'll debug that part of the hierarchy.

Again, thanks for reading and any advice!

Edit: The final solution for those who are curious
I found out what the last problem was... I'm was using uniform scaling in my VQS and just taking the maximum of the xyz scale. I set an assert to see if any of the xyz were scaling oddly. It found a scaling of (1,1,-1) on the left leg bone! I called the artist and found out that particular bone had been created by mirroring the right leg. Fortunately this is the first rig and animation, so he offered to recreate that bone.

Though, I still don't know how to programmatically handle a mirrored bone. Searching on gamedev just yielded several posts of people who had given up trying to fix it o_O



[Edited by - gzboli on December 4, 2008 11:25:56 PM]

This topic is closed to new replies.

Advertisement