Sign in to follow this  
Endemoniada

Skeletal Animation Root Translation ?

Recommended Posts

Hi guys,

 

I'm having a problem and I can't understand what's happening. My skeleton's root bone/joint is the pelvis. I set up two (looping) keyframes for a simple squat, the feet should stay planted on the ground while the pelvis goes up and down with the knees bending accordingly; the rig works fine in 3ds Max. It kind of works in my engine but there is a problem: when the pelvis is going down, the knees bend nicely but the feet go down a little then back up, and when the pelvis is going back up the feet go down and up again, so the feet go down, up, down, up during one animation cycle.

 

When I create the pelvis transform, which I do first since it's the root, I interpolate it's translation between the two keyframes. Please note that this is the only bone/joint whose translation is interpolated, all the other bones only need their rotation interpolated (slerp).

 

If I don't interpolate the pelvis translation the pelvis stays stationary and the feet come up off the ground with the knees bending very nicely, without that weird down/up cycle of the feet.

 

I did a dump of the pelvis translation values and they are fine, with just one inflection point per cycle.

 

I'm not sure what I'm doing wrong or how to handle the root node.

 

Thanks a lot.

 

Share this post


Link to post
Share on other sites

That's really odd. It almost sounds like the bone offsets between the feet and knees are being extended (translated also). I'm wondering what order and how the transformation math is applied. I know the common rule is bone_offset, then scale, then rotation, then position_offset and also the children inherit the position and rotation changes from the parents.

I don't think I do this conventionally at all - I've never properly studied how other people do it but here is some psuedocode to compare to  - maybe it can shed some clues? :

//this first

InterpolateKeysAndStoreIntoBones();

//then this

TransformSkeleton(int parent) {

if (parent==root) {

Loop through children (a=0 to child_count) {

 child=bones[parent].child_list[a];

 if (child==parent) {Error "cannot be its own child - that's just wrong..." a++; continue; }

 vec = child__offset_vector_from_parent // ie: bones[child].bone_point

 vec = rotateVector(vec, parent_rotatation) 

 vec += position_change; //(if doing)

 bones[child].final_vec=vec; //record the child bone's new point

 bones[child].final_rotate = parent_rotation; //pass rotation into child (to be added)

}

} end child loop

bones[parent].final_vec = bones[parent].position_change;

bones[parent].final_rotate = bones[parent].rotate;

else { // IS CHILD

loop thru children(a=0 to child_count) {:

 if no children break;

 child = bones[parent].child_list[a] 

 if (child==parent) {Error: "Can't be its own child"; a++; continue}

 vec = child__offset_vector_from_its_parent  // ie: bones[child].bone_point

 rot = final_rot[parent]+rotate[parent] //combine inherited rotations

 vec = rotateVector(vec,rot);

 bones[child].final_rotate = rot; //pass rotation into child (to be added)

 bones[child].final_vec = vec + bones[parent].vec + bones[parent].position_change; // or just [child] = vec + bones[parent].vec;

 TransformSkeleton(child);

end loop children

bones[parent].final_rot += bones[parent].rotate;

bones[parent].final_vec += bones[parent].position_change;

 

//then skin mesh:

Share this post


Link to post
Share on other sites

Just as a guess: the problem may be with SLERP'ing the rotations to compensate for a linear translation.

 

If the same data works differently in another program, then (as you surmise) the code must be different. I'm not familiar with 3ds, but if the animation was created in 3ds (you don't say), see if the docs mention how rotation is implemented. It may be that 3ds LERPs or NLERPs the rotations, rather than SLERP.

 

Suggestions:

 

1. In your program, use NLERP (normalized linear interpolation) for the rotations, rather than SLERP to see if that displays the data as desired.

2. In 3ds, IF it allows selection of rotation interpolation, change the option to SLERP, redo your model, export it, and see if your SLERP'ing displays the data as desired.

Share this post


Link to post
Share on other sites

Hi,

 

I really don't think it's the animation part of my engine, I put a lot of time into checking that and it seems really solid (Buckeye helped me.)

 

This also only happens when I use IK solvers in 3ds, that's how the feet stay planted to the floor.

 

I'm almost positive the flaw is in my FBX converter, which isn't pretty because that was a nightmare to build.

 

I'm going to try to make a MaxScript exporter, if I make very little progress in the next few days I'll see if I can fix the FBX converter.

 

Wish me luck. Thanks guys.

Share this post


Link to post
Share on other sites

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