Sign in to follow this  

Convert Ragdoll matrices back to Animation matrices

This topic is 2046 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'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:
[code]
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] );
}

[/code]
Note the inclusion of the "[size=2][font=Liberation Mono]states[color=#00FF00][color=#00FF00][color=#00FF00][[/color][/color][/color][color=#008000][color=#008000][color=#008000]Index[/color][/color][/color][color=#00FF00][color=#00FF00][color=#00FF00]][/color][/color][/color][/font][/size]". 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! Edited by Kest

Share this post


Link to post
Share on other sites
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:
[CODE]
- 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

[/CODE]
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:

[CODE]
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

[/CODE]
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.

Share this post


Link to post
Share on other sites
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:[b] inverse(ragdoll_bind_pose)*ragdoll_transform [/b]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! Edited by Kest

Share this post


Link to post
Share on other sites

This topic is 2046 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