Blending skeletal animations together

The skeletal animation blender is the object that allows to build complex animation blend trees. Its goal is to mix several skeletal animation controllers together to produce smooth transitions between them or to merge partial skeletal animations.

Properties of the skeletal animation blender

This object implements both interfaces: RED::ISkeletalAnimationController and RED::ISkeletalAnimationBlender.

The blender contains a list of RED::ISkeletalAnimationController child objects. Because the blender also implements this interface, it can be added to the children list of other blenders allowing to build animation trees.

The RED::ISkeletalAnimationBlender interface provides functions to:

The RED::ISkeletalAnimationController objects hold all the parameters needed by the blender to apply its rules:

An example of animation tree

In the previous figure, we can imagine a character animation blend tree where the animations of the group 1 are body animations like idle and walk and animations of the group 2 are head animations. The group 1 controllers have filtered-out the head bones whereas the group 2 controllers have filtered-out the body bones.

Like every RED::ISkeletalAnimationController object, the blender needs to be updated at each frame by calling its RED::ISkeletalAnimationController::Update function. One important point: it handles the update of its children, so no need for the user to call the children update functions. Only the animation tree root blender update needs to be done.

The RED::ISkeletalAnimationController::SetIsAppliedToSkeleton method specifies if the result of the animation evaluation must be applied to the associated skinned mesh or not. Generally, in a blend tree, only the root blender result must be applied to the skeleton, all the children should set this option to false.

The skeletal animation blender is created by the factory with the RED::Factory::CreateSkeletalAnimationBlender function and deleted with RED::Factory::DeleteInstance.

task

Task: Creating a skeletal animation blender

A skeletal animation blender is an object used to combine several skeletal animations and mix their outputs dynamically. It is created using the RED::Factory.

// Create a skeletal animation blender.
RED_RC rc;
RED::Object* animBlender = RED::Factory::CreateSkeletalAnimationBlender( *resmgr, rc );
RC_TEST( rc );

// It implements both interfaces.
RED::ISkeletalAnimationBlender* iblender = animBlender->As< RED::ISkeletalAnimationBlender >();
RED::ISkeletalAnimationController* iskeletalController = animBlender->As< RED::ISkeletalAnimationController >();

The destruction of the animation blender is done like this:

// Delete the skeletal animation blender.
RC_TEST( RED::Factory::DeleteInstance( animBlender, iresmgr->GetState() ) );
task

Task: Doing smooth transitions between skeletal animations

The blender main task is to do smooth transitions between animation clips. The RED::ISkeletalAnimationBlender::BlendTo function gives the user the ability to do that.

Let's have a blender containing two skeletal animation clip controllers: idle and walk.

At the initialization step, we want the idle to be played:

// RED::Object* idleController and walkController are skeletal animation clip controllers controlling the same skeleton.
RED::ISkeletalAnimationController* iidleController = idleController->As< RED::ISkeletalAnimationController >();
RED::ISkeletalAnimationController* iwalkController = walkController->As< RED::ISkeletalAnimationController >();

// Add the animations to the blender.
RED::ISkeletalAnimationBlender* iblender = blender->As< RED::ISkeletalAnimationBlender >();
RC_TEST( iblender->AddController( idleController ) );
RC_TEST( iblender->AddController( walkController ) );

// At initialization, idle animation is played.
iidleController->SetBlendWeight( 1.0 );
iwalkController->SetBlendWeight( 0.0 );

After calling the RED::ISkeletalAnimationController::Update method, we see that only the idle animation is applied to the mesh.

Now, if we invert the blend weights, the walk animation will be played but there will be no transitions to them.

Fortunately, the blender is here to ease the task thanks to its RED::ISkeletalAnimationBlender::BlendTo function. By calling it, the user can specify the target animation, the duration of the transition and the target blend weight. It will fade-out the currently played animations and fade-in the target animation.

// Send a message to the blender: blend to the walk animation in 0.3s.
RC_TEST( iblender->BlendTo( walkController, 0.3, 1.0 ) );

Note:

The cross-fade is done on animations belonging to the same group (RED::ISkeletalAnimationController::SetGroup).

This operation is equivalent to calling the function RED::ISkeletalAnimationController::SetFadeParameters of both idle and walk animation controllers.

task

Task: Merging skeletal animations onto different body parts

Thanks to the blender, any user can split the skeleton into body parts and animate them separately. Doing it is simple: filter the bones and define groups.

Let's have a blender containing two skeletal animation clip controllers: body and head.

At the initialization step, we want both to be played but on different bones:

// RED::Object* headController and bodyController are skeletal animation clip controllers controlling the same skeleton.
RED::ISkeletalAnimationController* iheadController = headController->As< RED::ISkeletalAnimationController >();
RED::ISkeletalAnimationController* ibodyController = bodyController->As< RED::ISkeletalAnimationController >();

// Add the animations to the blender.
RED::ISkeletalAnimationBlender* iblender = blender->As< RED::ISkeletalAnimationBlender >();
RC_TEST( iblender->AddController( headController ) );
RC_TEST( iblender->AddController( bodyController ) );

// Filter the head and body bones (head bone index is 3).
RC_TEST( iheadController->SetBoneFilter( 0, true, true ) );
RC_TEST( iheadController->SetBoneFilter( 3, false, true ) );
RC_TEST( ibodyController->SetBoneFilter( 3, true, true ) );

// Make them belong to a different group (useful for later BlendTo).
iheadController->SetGroup( 0 );
ibodyController->SetGroup( 1 );

// Both animations are played. We can do this because they animate different bones.
iheadController->SetBlendWeight( 1.0 );
ibodyController->SetBlendWeight( 1.0 );

After calling the RED::ISkeletalAnimationController::Update method, we see that both animations are played, each on its dedicated body part.

Additive animations

The RED::ISkeletalAnimationController animations can be flagged to be additive (RED::ISkeletalAnimationController::SetAdditive).

Additive animations are not blended like other animations, they are not cross-faded. Instead, as indicated by its name, they are added to the currently played animations. They are very useful to add small variations.

The blend weight of additive animation is used to control the amount of the additive animation we want to add: 0 being not added, 1 being totally added.