Layering animations: interpolation

Started by
5 comments, last by jmakitalo 11 years, 3 months ago

I wish to animate a human character by layering e.g. walking and shooting animations. At this point, I have implemented simple MD5 mesh animation system.

I suppose I will add masks for each animation to select the bones that they should affect. I would like that the upper-body animation (say shooting) could be reused for different character stances, which would be described by lower-body animations. The lower-body should control the root bone to move the whole character and the upper body should always follow.

I then see a problem in interpolation: thus far, I have first constructed two keyframes and then interpolated the final positions vectors and orientation quaternions of the bones. If I apply this to the two animations separately and then combine the animations, the upper body can appear incorrectly as the root bone is only affected by the lower-body animation.

One solution might be to interpolate the bones in local spaces for the two animations and then combine the animations. The parent multiplication would be performed during the combination procedure. Then the upper body would be transformed by a correctly transformed root bone. These operations probably don't commute, so it is not clear that this will lead to good results. How is this usually done?

Advertisement
I would use an additive rather than a modulative approach to animation layering. Each frame, the skeleton will be reset to the bind pose. Then, the whole skeleton will be transformed by the lower-body animation pose. You can then transform the skeleton by additional poses to add on a shooting animation, a waving animation, and so on. In this way, the upper-body animations won't affect the root bone as long as the pose keeps the root static.
I would use an additive rather than a modulative approach to animation layering. Each frame, the skeleton will be reset to the bind pose. Then, the whole skeleton will be transformed by the lower-body animation pose. You can then transform the skeleton by additional poses to add on a shooting animation, a waving animation, and so on. In this way, the upper-body animations won't affect the root bone as long as the pose keeps the root static.

I guess that in order to sensibly add animations, the bone transformations of the keyframes must be relative to bind pose. I think for me they are absolute, since after constructing the keyframe transformations, I transform vertices from inverse bind pose space. Adding such transformations would then effectively apply bind pose multiple times, which would be undesirable.

But I think that parent multiplication should be done after adding the animations in local bone spaces. The upper-body animations should not affect the root bone, but the previously transformed root bone should affect the upper body.

You can do it like this:

1. Update all local bone matrices for both animations A and B independently.

2. Interpolate A and B by some bone dependent weight: F_i = weight_i * A_i + (1-weight_i) * B_i

3. Build your final matrices by considering the according parent bone matrices.

4. Apply the bind pose.

Some hints: the main animation (e.g. walking) should control the whole lower body including the root. The upper body can be blended using a weight >0, e.g. use 0.25 to 1.0 for the spine and 1.0 for the rest of the upper body.

You can do it like this:

1. Update all local bone matrices for both animations A and B independently.

2. Interpolate A and B by some bone dependent weight: F_i = weight_i * A_i + (1-weight_i) * B_i

3. Build your final matrices by considering the according parent bone matrices.

4. Apply the bind pose.

Some hints: the main animation (e.g. walking) should control the whole lower body including the root. The upper body can be blended using a weight >0, e.g. use 0.25 to 1.0 for the spine and 1.0 for the rest of the upper body.

Ok. I think this is close to what I was trying to go for. In step 1 the interpolation for each animation is performed in local bone space. This is different to what I was doing in my simple one animation case, where first the frames were fully constructed in bind pose space and then interpolated, which makes sense intuitively. But I guess that interpolation in local space also works, although I suspect that it is different in a strict sense.

I suppose I will add masks for each animation to select the bones that they should affect. I would like that the upper-body animation (say shooting) could be reused for different character stances, which would be described by lower-body animations. The lower-body should control the root bone to move the whole character and the upper body should always follow.

Good plan.

I then see a problem in interpolation: thus far, I have first constructed two keyframes and then interpolated the final positions vectors and orientation quaternions of the bones. If I apply this to the two animations separately and then combine the animations, the upper body can appear incorrectly as the root bone is only affected by the lower-body animation.

Should never happen.

One solution might be to interpolate the bones in local spaces for the two animations and then combine the animations. The parent multiplication would be performed during the combination procedure. Then the upper body would be transformed by a correctly transformed root bone. These operations probably don't commute, so it is not clear that this will lead to good results. How is this usually done?

All interpolation should ALWAYS* happen in local space ( *not strictly true, but I'll spare you the details. ). Once you've performed the local space interpolations, simply convert those transforms into world space by multiplying by their parent transforms.

[quote name='RobTheBloke' timestamp='1357228518' post='5017158']
All interpolation should ALWAYS* happen in local space ( *not strictly true, but I'll spare you the details. ). Once you've performed the local space interpolations, simply convert those transforms into world space by multiplying by their parent transforms.
[/quote]

Ok then. I will try this out.

Thanks all for the help.

This topic is closed to new replies.

Advertisement