##################
Skeletal Animation
##################

.. toctree::
    :maxdepth: 1
    :titlesonly:
    :hidden:

    bk_an_sa/bk_skeletal_animation_blender


The skeletal animation system provided by HOOPS Luminate 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.

.. figure:: bk_skeletal_animation01.png
    :align: center
    
    **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 HOOPS Luminate, the skeleton definition is contained in a ``RED::IMeshShape`` object (details about skinned mesh shapes can be read in the doc :doc:`/book/subjects/bk_sgo/bk_sgo_ms/bk_sg_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.

.. include:: /tasks/ta_ca/ta_ca_animation/tk_filtering_skeleton_bones.rst 

======================================
The Skeletal Animation Clip Controller
======================================

The skeletal animation clip controller is the link between the animation clip controller seen here: \ref bk_animation_basic 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``.

.. include:: /tasks/ta_ca/ta_ca_animation/tk_creating_animation_clip_controller.rst 

==============================
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: \ref bk_skeletal_animation_blender.

===========
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:

    * ``RED::RMC_ROTATION``
    * ``RED::RMC_POSITION_X``
    * ``RED::RMC_POSITION_Y``
    * ``RED::RMC_POSITION_Z``

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 HOOPS Luminate object he wants. This is where the ``RED::RMP_DELTA`` policy become useful.

.. include:: /tasks/ta_ca/ta_ca_animation/tk_defining_root_motion_policies_for_a_walking_character.rst 

