Convert Ragdoll matrices back to Animation matrices

Started by
1 comment, last by Kest 11 years, 11 months ago
Hey guys! I've been trying to figure this out for while now, with no luck.

My animated characters use a hierarchy skeletal system. Each limb has a rotational state, which is converted to a rendering matrix by multiplying it with its parents. I have easily figured out how to pose my ragdoll for physics start by determining their matrices using the character's rendering matrices. My ragdoll body parts are not in a hierarchy (which is part of what is confusing me).

Each ragdoll body part has a bind transform - a matrix that takes the body part from the zero-origin-point and places it at the limb location of the character. So when all ragdoll parts render with just their bind pose, it would look like a character in their bind pose. In order to place the ragdoll parts, I multiply each ragdoll part's bind pose with the character's rendering matrix for that bone. For instance:
Ragdoll_Leg->Transform = MUL( Ragdoll_Leg->Bind_Transform, Character->Leg->RenderMatrix );

This works, and the ragdoll starts exactly where my character is posed. However, I'm having a lot of confusion reversing this procedure and obtaining animated states for the character by using the ragdoll transforms.

My character's RenderMatrix for each bone is computed like this:

void KRaceBone::ComputeHierarchy(const MTX *states, MTX *finals, const MTX &derive)
{
finals[Index] = MUL( JointToOrigin, states[Index] );
finals[Index] = MUL( finals[Index], OriginToJoint );
finals[Index] = MUL( finals[Index], derive );

// Compute Children
for(int e=0; e<Bones.GetCount(); e++)
Bones[e].ComputeHierarchy( states, finals, finals[Index] );
}


Note the inclusion of the "[size=2][font=Liberation Mono]states[color=#00FF00][color=#00FF00][color=#00FF00][[color=#008000][color=#008000][color=#008000]Index[color=#00FF00][color=#00FF00][color=#00FF00]][/font]". That is the pure-rotational local state of each bone. That is what I'm trying to convert my ragdoll parts back into. Anyone have any advice? Anything at all is appreciated. I've been pretty lost at this.

Thanks!
Advertisement
You often use two separate skeletons for animation and ragdoll physics, with the ragdoll skeleton being of lower resolution. The trick is often, that you switch between the two skeletons only once, from animation skel to ragdoll skel. So, I don't understand, why you want to map the animation bone orientation to the ragdoll bones.

Nevertheless, first off, when you want to map/compare matrices, you need to convert both into the same space. You have two skeletons here, the animation skeleton has many hierachy layers, whereas the ragdoll skeleton is really flat, but they have still the same basic structure.

Final bone position:

- ani skel: a_final_bone_i = a_local_bone_i * a_parent_bone_i
- ragdoll skel: r_final_bone_i = r_local_bone_i * r_parent_bone_i = r_local_bone_i * r_root_bone_i = r_local_bone_i * identity = r_local_bone_i


Transform mesh to final bone orientation:
- ani/ragdoll: mesh_bone_i = final_bone_i * inverse_bind_i

When you want to recalculate i.e. a single bone position from ragdoll to animation (i.e. the hand), the final bone space (object space) would be fine, therefore:


r_final_bone_i = a_final_bone_i
<=>
r_local_bone_i = a_local_bone_i * a_parent_bone_i
<=>
r_local_bone_i * inv(a_parent_bone_i) = a_local_bone_i


The problem is, you don't know a_parent_bone_i either. So you need to either use some kind of inverse kinetics to recalculate the parent bone, or you must start with a bone which is has a fix/known parent bone (i.e. the root bone)

The latter is ok, but you have now the problem of a ragdol skeleton which has a lower resolution (less bones), therefore you need to recreate/map parent animation bones on the fly by assuming its orientation relative to its parent bone. I.e. your animation skel has two spine bones, whereas your ragdoll only one (faster), then you need to remap the second spine bone relative to the first.
After two days of working at it, I finally figured it out. For anyone trying to do the same thing, this is essentially what I did:

1. Remove the primitive bind pose from all ragdoll shapes (ie: inverse(ragdoll_bind_pose)*ragdoll_transform for every ragdoll bone).
2. Treat the resulting ragdoll transforms (after #1) like rendering matrices, and convert them back to raw unrelative animation states.
3. In order to convert to animation states, I had to do the opposite procedure I did to convert normal animation states to rendering states.

For instance, if you compute a character render matrix like this: RenderMatrix = ToOrigin * state * ToJoint * parent;.
Then you would reverse that as something like this: state = inverse(ToOrigin) * RenderMatrix * inverse(parent) * inverse(ToJoint);

And this worked for me. Now I just need to figure out how to turn the top level bone into character motion.
Thanks for your help Ashman!

This topic is closed to new replies.

Advertisement