Jump to content

  • Log In with Google      Sign In   
  • Create Account

Interested in a FREE copy of HTML5 game maker Construct 2?

We'll be giving away three Personal Edition licences in next Tuesday's GDNet Direct email newsletter!

Sign up from the right-hand sidebar on our homepage and read Tuesday's newsletter for details!


Sector0

Member Since 22 May 2013
Offline Last Active Today, 01:59 AM

#5076696 Quaternions and Animation Blending questions

Posted by Sector0 on 10 July 2013 - 02:27 PM

Hi Tispe,

Obviously the quaternion multiplication is not commutative this means q1 * q2 is not equal to q2 * q1. beside this you might know that quaternion slerp always interpolates between two rotations on the shortest arc from all possible arcs between them so using slerp is a great idea to achieve animation blending.

 

For blending, first you have to order your animations in the way you need. For example you can enable walk animation firstly and next run animation could be enabled. I recommend you to always save the order of  enabled animations in a queue. Users have to enable them in order they want.

Each bone for each animation owns a weight. In animation systems there are two ways to apply weights for blending. First one is mixing and the second is additive weighting.

 

Mixing: For mixing you should calculate the average weight of each animation with respect to the other animation weights. For example if you want to blend three animations together, they should be blended like this (assume that anim1, anim2 and anim3 have been enabled in order):

 

if (anim1.weight > anim2 weight)

{

q = slerp( anim1, anim2, 1- anim1.weight/(anim1.weight + anim2.weight));

}

 

else

{

q = slerp( anim1, anim2, anim2.weight/(anim1.weight + anim2.weight));

}

 

if ( anim1.weight + anim2.weight > anim3.weight >)

{

q = slerp( q, anim3, 1- (anim1.weight + anim2.weight)/(anim1.weight + anim2.weight + anim3.weight));

}

 

else

{

q = slerp( q, anim3, (anim3.weight)/(anim1.weight + anim2.weight + anim3.weight));

}

 
After this, you can multiply q to the T-pose of the current bone: qfinal = q * T-pose
It is better to make a loop for this procedure because there maybe many animations blending with each other.
 

Some graphics engines like OGRE do not blend different animations with slerp interpolation like i mentioned above. They sequentially multiply quaternions in order. For

example three animations are calculated like this (assume that anim1, anim2 and anim3 have been enabled in order):

 

anim1.weight = anim1.weight/(anim1.weight + anim2.weight + anim3.weight)

anim2.weight = anim2.weight/(anim1.weight + anim2.weight + anim3.weight)
anim3.weight = anim3.weight/(anim1.weight + anim2.weight + anim3.weight)

 
q = (anim3.weight * q3) * (anim2.weight* q2) * (anim1.weight * q3) ;
 
This method does not provide accurate blending resultd because it does not interpolates on the shortest arc between 2 rotations but its result is acceptable and it has a better performance in comparison to using slerp for blending.
 
You might want to implement two techniques and use them for different usages. For example if you want to have animations with lower LOD you can apply the second technique to them.
 
 
Additive weight computation:  Additive animations are one type of animations that can be added with actual weights to other animations. Their weights should not to be averaged. They are used for asynchronous usages like a simple hit reaction. You can assume a simple noise animation presenting bullet hits. This noise animation can be added to any animation asynchronously. Your character can be shot in walk, run , idle or may other possible animations. This noise can be added up on the animations to show that your character has been shot while running or walking and so on. So for additive animation blending we do not need to average the weights with respect to other animations. The transforms of an additive animation is applied with its actual weights. Just note that the additive animations have to be added at the final step this means you have to calculate the mixing animations and then apply the additive animation like this:
 
Final blended rotation = additiven * additiven-1 * additiven-2 * ... * additive* MixedAnimations
 
For each animation you have to save its blending type to know whether it is average or additive to apply its weights with the proper technique.
 
I have two short posts on my blog about unit quaternions. you might want to check them out:
 
 
Hope this would help.



PARTNERS