//Combine all BoneMatrices to a final skeleton for use for skinning vertices
This is quaternion mutiplication. Actaully this means that first you rotate your object with q_t_pose then with q1 next q2 and q3 respectively. This can be used for additive animation bledning but is not suitable for mixing animations.
So, is this how I should Animate characters?
1. Build T-Pose bones in Dual Quaternion form.
2. Create a list of animation tracks to blend and set a weight for each track.
3. For each bone, enter every animation track and get the Bone Quaternion at time t by Slerp(key1, key2, t'), convert it to Dual Quaternion, weight it and add it to T-Pose bone.
4. Combine all T-Pose bones which are now animated and send the skeleton to the GPU.
This procedure is OK as far as you normalize the weights. For the dual quaternions i have to say that i've never used it and know a little about it. I always use quaternions and it responds very well for rotations on CPU. I think you can use quaternions in CPU computations for animation blending. I have no idea about GPU computations.
I have worked with nlerp before. I prefer to use nlerp when i want the animation LOD to be low. nlerp takes less computation. It can be calculated like this:
nlerp(q1, q2, t) = (1-t ) * q1 + t * q2;
Slerp is more accurate but it takes more computations because it has to extract the quaternions and calculate many sin, cos, arccos and again multiply them. You can consider this example for using slerp:
Lets assume that you want to create a side scroller action shooter and you have 3 animations for aiming. One is aiming 90 degrees up, other is aiming forward with 0 degree with respect to horizon and the third is aiming 90 degrees down. You want to blend between these three animations for character aiming. You get the mouse world position and calculate its difference with your character's world position. Then you calculate the deviation by using the vector dot multiplication of the resulted aim direction and character forward vector. The result shows that the deviation degree is 45. Now you want to blend between aim_up_90 and aim_forward animations so your character can target the mouse cursor with 45 degrees with respect to horizon. If you use slerp blending like this:
Slerp (aim_forward_key, aim_up_90_key, 45/90)
You will catch accurate results. Your character aims at 45. But if you use nlerp your character never looks at 45 degree. For example he might look at 30 degrees while the mouse aim is at 45 degrees. So it would be great to use nlerp for the purposes which the accurate blending is not really matters.
In other words, by using quaternion Slerp you can rotate one vector to another linearly with respect to degrees between them.
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):
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: