animation and blending

Started by
6 comments, last by Buckeye 13 years ago
Hi there
I have successfully loaded and animated multiple animation clips for a given mesh using COLLADA DOM. Now I want to blend from an animation to another animation. What equation should I use? Are there any useful articles on the internet about this topic?
Regards
-Ehsan-
Advertisement
There's really not just a single equation involved. However, to transition from one animation to another, a common method is:

Keep track of some time values:

a. The animationTime - the time you normally use to advance the animation.
b. currentTime - the time value for the transition.
c. deltaTime - see 1. below

1. Choose a deltaTime for the transition ( the time for the resulting animation to transition from "all" anim1 to "all" anim2 ).

2. Start with a "currentTime" of 0.

3. Each frame, calculate the individual animation quaternions, translation and scales as you would for a single animation, using the animationTime. End up with a quat/translation/scale for each of the 2 animations.

4. Slerp the 2 animation quaternions and lerp the translations and scales, using a blend factor from 0 to 1, where the blend factor is currentTime/deltaTime.

5. currentTime += frameTime, and, of course, animationTime += frameTime

6. goto 3 until blend factor = 1

Please don't PM me with questions. Post them in the forums for everyone's benefit, and I can embarrass myself publicly.

You don't forget how to play when you grow old; you grow old when you forget how to play.

Thank you. I guess the previous algorithm explains the cross fade and we can use the following diagram for it:
diagram_05.jpg
Am I correct?

Now I need to blend multiple animations. For the sake of simplicity, I want to blend animation 2 with animation 1.Here's the diagram:
diagram_06.jpg

So what algorithm should I use to get the appropriate result?
Regards
-Ehsan-
(I'm Buckeye, but gamedev apparently has some issues with IE8)

I'm afraid I don't understand what you mean by "cross fade" or what exactly you're trying to represent with your diagrams.

Your original post implied you wanted to "blend" from one animation to another. I took that as transitioning from one animation to another, ending up with the character fully in the second animation.

So what algorithm should I use to get the appropriate result?[/quote]
The algorithm I posted above will combine 2 animations using a blend factor. If you want to blend 2 animations continually ( e.g., walking blended with running with a blend factor of 0.5 ), that same algorithm will serve. Just hold the blend factor at 0.5 (or whatever ratio you want for the animations).

By the way, I'm assuming you're talking about skinned meshes ( i.e., vertices with bone weighting factors, etc. )

Please don't PM me with questions. Post them in the forums for everyone's benefit, and I can embarrass myself publicly.

You don't forget how to play when you grow old; you grow old when you forget how to play.

So if I want to blend 2 animations continually , I should use a blend factor of 1/2 = 0.5?
well, this page has explained 3 types of blending. If you're familiar with Cal3D, it has 2 functions called blendCycle() and ClearCycle(). Now I want to implement the same functionality in my game engine.


bool CalMixer::blendCycle ( int id,
float weight,
float delay
)

Interpolates the weight of an animation cycle.

This function interpolates the weight of an animation cycle to a new value in a given amount of time. If the specified animation cycle is not active yet, it is activated.


So I don't know how to interpolate this animation with other animations. "How to start from weight 0 to the final weight?"
Thanks
-Ehsan-
Assuming you have 2 lists of joints that make up an animation. For simplicity and efficiency sake each joint has a translation vec3, a scale vec3, and a rotation quaternion.
You would have the first animation playing and looping lets say, say this animation is 3sec long.
You then hit a key (or event, or w/e) at some point during this animation and want to begin blending to the second animation. The animation after this key press would no longer be coming directly from the local joint pose of animation one but a blend of the two

blend time between anim1 and anim2, lets say 0.5sec (you pick what looks best). So the blend time advances from 0.0 -> 0.5 during the blend between anim1 and anim2 starting with the key press. Now you start advancing the current blend time each frame during the blend.

blend factor = bf = current blend time / total blend time = ? / 0.5

for each joint in the skeleton
currentPose.joint.translation = Lerp(anim1.joint.translation, anim2.joint.translation, bf)
currentPose.joint.rotation = NLerp(anim1.joint.rotation, anim2.joint.rotation, bf)
currentPose.joint.scale = Lerp(anim1.joint scale, anim2.joint.scale, bf)

Where blend factor is between 0.0 and 1.0, once current time >= 0.5, the blend is complete, the second anim2 has taken over, you start sourcing your final joint poses from anim2 at this point.
When the "key" is pressed to start the animation blend, you can either continue advancing the first animation during the blend, or freeze it at the time when the key event hit. At which point during the blend the same key data for anim1 will be used throughout the blend.
Chances are you wont really notice SLERP and normalized lerp diffferences if using quaternions for the joints rotation representation, normalized lerp will probably be faster.
Just hold the blend factor at 0.5 (or whatever ratio you want for the animations).[/quote]
Thank you. And what about 3 or more animations?

Just hold the blend factor at 0.5 (or whatever ratio you want for the animations).

Thank you. And what about 3 or more animations?
[/quote]
I'm not familiar with Cal3D, so I can't help you there.

You can blend as many animations as you want using the algorithm I posted.

1. Calculate the individual animation frames.
2. Slerp and lerp them together using blend factors.

Notes:
The total of the blend factors should equal 1. E.g., the idea is that the final animation = 0.333*anim1 + 0.333*anim2 + 0.333*anim3, or any combination of blendfactors that sum to 1.

The animations must all be of the same duration. I.e., duration = trackspeed * animation-duration.

For the best results, the animations, as mentioned in the article you referenced, have to be reasonably similar at the frame time for the blend, or the blend won't appear properly. E.g., if you're blending a walk and a run animation, the animations should be at the same relative point in the animation - both left legs should reach their maximum extension at the same time; right legs, etc., similarly.

Please don't PM me with questions. Post them in the forums for everyone's benefit, and I can embarrass myself publicly.

You don't forget how to play when you grow old; you grow old when you forget how to play.

This topic is closed to new replies.

Advertisement