Skeletal animation
The skeletal animation system provided by REDsdk gives access to multiple interfaces that allow to animate a character in real-time. It gives the ability to build complex animation trees and dynamically animate any part of a skeleton.
The base interface of all the skeletal animation objects is RED::ISkeletalAnimationController. This class has many purposes:
- associating the animation to external skinned meshes;
- providing functions to blend and fade the animations;
- filtering the animated bones of the skeleton;
- defining root motion policies.
According to the parameter set, the animations will be evaluated at each application frame by calling the RED::ISkeletalAnimationController::Update method. This function updates the animation handled by the controller and then move the skinned meshes skeletons according to it.
The skeletal animation system exposes two main objects to the user. Both of them implement the RED::ISkeletalAnimationController interface:
- The skeletal animation clip controller brings the animation clip capabilities to the skeletal API;
- The skeletal animation blender allows to build animation blend trees to mix various animations.
More details about these two objects can be found later in this chapter.

Skeletal animation system objects and interfaces
Link to the skinned mesh
Because the goal of the skeletal animation system is to animate a skeleton, it needs a skeleton to animate. In REDsdk, the skeleton definition is contained in a RED::IMeshShape object (details about skinned mesh shapes can be read here: Skinned mesh shapes).
The RED::ISkeletalAnimationController::AddSkinnedMesh associates the skinned mesh we want to animate to the animation controller. Each skeletal animation controller must be linked to at least one skinned mesh.
Note:
Because a controller animates a single skeleton, all the skinned meshes associated to it must have the same skeleton.
The RED::ISkeletalAnimationController::SetIsAppliedToSkeleton option allows to specify if the result of the animation evaluation must be applied to the associated skinned meshes or not. If not, the user can query the result for each bone with the RED::ISkeletalAnimationController::GetBoneTransform function.
Bone filtering
The RED::ISkeletalAnimationController interface provides functions to filter the bones. Sometimes, you don't want to animate the full skeleton. The bone filtering option allows to select the bone hierarchy to animate via one function: RED::ISkeletalAnimationController::SetBoneFilter.
The function lets the user choose the bone or bone hierarchy he wants to filter in or filter out.

Task: Filtering skeleton bones
In this task, we want to split the animation of a humanoid skeleton between two controllers: one for the upper body and one for the lower body.
Below is the skeleton we want to animate:

The skeleton and bone indices
For each controller, we will use the RED::ISkeletalAnimationController::SetBoneFilter to filter-in and filter-out the desired bones.
// RED::Object* lowerController and upperController are skeletal animation clip controllers controlling the same skeleton.
RED::ISkeletalAnimationController* ilowerController = lowerController->As< RED::ISkeletalAnimationController >();
RED::ISkeletalAnimationController* iupperController = upperController->As< RED::ISkeletalAnimationController >();
// By default, bones are unfiltered. Just filter-out the upper body.
RC_TEST( ilowerController->SetBoneFilter( 1, true, true ) );
// Filter-out all the skeleton then filter-in the upper body.
RC_TEST( iupperController->SetBoneFilter( 0, true, true ) );
RC_TEST( iupperController->SetBoneFilter( 1, false, false ) );
In the lower body controller, we have excluded the bone hierarchy from bone 1.
In the upper body controller, we first excluded all the bones then included the bone hierarchy from bone 1.
For upper body, we could also have excluded bone 0 only, then leg bones and their hierarchies:
// The lower body filtering could be done also:
RC_TEST( iupperController->SetBoneFilter( 0, true, false ) );
RC_TEST( iupperController->SetBoneFilter( 8, true, true ) );
RC_TEST( iupperController->SetBoneFilter( 11, true, true ) );
The skeletal animation clip controller
The skeletal animation clip controller is the link between the animation clip controller seen here: Basic animation and the skeletal system. Because it implements the RED::IAnimationClipController interface, it has all the clip-related functions like play, pause, stop, etc.. Added to this are the skeletal system options: associated mesh, bone filtering, root motion, etc..
User can access to each functionalities by requesting one or the other of the interfaces: RED::ISkeletalAnimationController or RED::IAnimationClipController.
The skeletal animation clip controller is created by the factory with the RED::Factory::CreateSkeletalAnimationClipController function and deleted with RED::Factory::DeleteInstance.

Task: Creating a skeletal animation clip controller
A skeletal animation clip controller is an object merging the animation clip controller properties to the skeletal animation system. It allows to play skeletal animation clips and apply the result to a skeleton. It is created using the RED::Factory.
// Create a skeletal animation clip controller to control a RED::AnimationClip.
RED_RC rc;
RED::Object* animController = RED::Factory::CreateSkeletalAnimationClipController( *resmgr, clip, rc );
RC_TEST( rc );
// It implements both interfaces.
RED::IAnimationClipController* iclipController = animController->As< RED::IAnimationClipController >();
RED::ISkeletalAnimationController* iskeletalController = animController->As< RED::ISkeletalAnimationController >();
The destruction of the animation controller is done like this:
// Delete the skeletal animation clip controller.
RC_TEST( RED::Factory::DeleteInstance( animController, iresmgr->GetState() ) );
The skeletal animation blender
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. More details are available here: Blending skeletal animations together.
Root motion
Some animations move the skeleton in space. If the animation have to loop, the skinned mesh will jump from its last position to its first position. This is a problem if we want it to move in a continuous way in the scene.
The root motion policies are here to solve it. It exists several options to move the root bone of an animated skeleton in the scene. They can be configured thanks to the RED::ISkeletalAnimationController::SetRootMotionPolicy function.
Root bone components
Each of the skeleton root bone transformation components (RED::ROOT_MOTION_COMPONENT) can be configured individually: rotation and translations:
Splitting them allows for example to let the animation handles its rotation correctly and extract the translations to move the skeleton in the world.
Root motion policies
The policies (RED::ROOT_MOTION_POLICY) are defined like this:
The RED::RMP_DEFAULT policy is the default one: the root bone is applied like any other bone leading to the issue we described previously.
The RED::RMP_CUMULATIVE policy calculates the delta transform between each frame and cumulates it in the root bone transform. By setting this policy, we fix the issue of the position reset because translation is no more absolute but relative to the last frame.
The RED::RMP_ZERO policy sets the root bone components to zero, meaning we suppress the rotation and/or position components from the root bone.
Finally, the RED::RMP_DELTA policy applies only the delta transform between each frame to the root bone. Alone, this option is not very useful. It must be associated to the last extraction parameter.
Extraction parameter
Sometimes, it can be preferable not to move the skeleton root bone but another mesh parent shape. For instance because other objects are attached to the mesh. The 'extract' parameter of the RED::ISkeletalAnimationController::SetRootMotionPolicy function allows to do that.
If a component is defined as 'extract', its value will not be set to the skeleton root bone directly. Instead the user will be able to retrieve it via the RED::ISkeletalAnimationController::GetRootMotionMatrix function. It will then be free to apply it on the REDsdk object he wants. This is where the RED::RMP_DELTA policy become useful.

Task: Defining root motion policies for a walking character
In this task, let's take an example of root motion policies for a biped character walking on a ground:
- For RED::RMC_ROTATION: the rotation is handled by the animation and stays absolute. We set RED::RMP_DEFAULT with no extraction.
- For RED::RMC_POSITION_X and RED::RMC_POSITION_Y: the translations on the X and Y axes are handled by the animation but we want a relative motion. We set RED::RMP_DELTA with extraction and apply the delta transform ourselves on the parent shape.
- For RED::RMC_POSITION_Z: the character should follow the ground level, the translation on the Z axis is handled externally. We set RED::RMP_ZERO.
// RED::Object* animController is a skeletal animation clip controller.
RED::ISkeletalAnimationController* iskeletalController = animController->As< RED::ISkeletalAnimationController >();
// Rotation is handled by the animation.
RC_TEST( iskeletalController->SetRootMotionPolicy( RED::RMC_ROTATION, RED::RMP_DEFAULT, false ) );
// Translations on X and Y axes are handled by the animation by applied on an external shape.
RC_TEST( iskeletalController->SetRootMotionPolicy( RED::RMC_POSITION_X, RED::RMP_DELTA, true ) );
RC_TEST( iskeletalController->SetRootMotionPolicy( RED::RMC_POSITION_Y, RED::RMP_DELTA, true ) );
// Translation on Z axis is handled externally.
RC_TEST( iskeletalController->SetRootMotionPolicy( RED::RMC_POSITION_Z, RED::RMP_ZERO, false ) );
![]() | Blending skeletal animations together![]() |