Character animation programming guide
The character animation system in OpenTissue supports deformation of skin meshes using a skeleton of bones. OpenTissue supports both Linear Blend Skinning and Spherical Blend Skinning implemented in both software and hardware (for NVIDIA GPUs series 6 and higher). Software skinning support an arbitrary number of bone influences for each skin vertex, while hardware skinning support up to 4 bone influences per skin vertex. It must be decided at compile time whether software or hardware skinning is to be used. Introduction
To employ the character animation system, the following header file must be included:
#include
A ready-to-compile-and-run demo using the character animation system is located in:
/demos/opengl/character/
Here it is shown how the system can be used to animate a running/walking human character.
The character animation uses skeletons and skin meshes. To define a skeleton type, a mandatory math type argument must be provided. To use the default math type, the following type can be defined: Setting up the system
typedef OpenTissue::Math::default_math_types math_types;This type can then be provided to the skeleton:
typedef OpenTissue::SkeletonTypes skeleton_types;To define a skin type, the math type must again be used along with an argument denoting the skinning method to be used. In the following hardware supported Spherical Blend Skinning is used:
typedef OpenTissue::SkinTypes skin_types;Finally, the character types can be defined using:
typedef OpenTissue::CharacterTypes character_types;And relevant types can then be extracted, and private members can be setup:
typedef character_types::skeleton_type skeleton_type; typedef character_types::bone_type bone_type; typedef character_types::skin_type skin_type; typedef character_types::keyframe_animation_type keyframe_animation_type; typedef character_types::naive_blend_scheduler_type naive_blend_scheduler_type; typedef character_types::skin_render_type skin_render_type;skeleton_type m_skeleton; ///< Skeleton (i.e. bones). keyframe_animation_type m_animation[100]; ///< The raw animations. naive_blend_scheduler_type m_blend_scheduler; ///< The animation blend scheduler (combines raw animations into final animation). real_type m_time; ///< The current animation time. real_type m_delta_time; ///< Time in between two poses (i.e. 1/fps). real_type m_duration; ///< Duration of animation. ///< Skin container. bool m_display_bones; ///< Boolean flag used to turn on/off rendering of bones. bool m_display_skin; ///< Boolean flag used to turn on/off rendering of skin. skin_type m_skin; ///< The skin being deformed by the skeleton skin_render_type m_skin_render; ///< The render used for skinning
Before any animation can be done, skeleton and skin data must be loaded into the system. OpenTissue supports two formats: An xml formal and CAL3D's animation format. In the following it is shown how the xml reader can be used to load data into the character animation system. Loading character data
First of all, the path to the folder containing data must be extracted:
std::string data_path = OpenTissue::get_environment_variable("OPENTISSUE");
Then data can be loaded into the skeleton container:
skeleton_xml_read(data_path + "/data/xml/character1.xml",m_skeleton);
Animation data can be loaded into the animation container:
keyframe_animation_xml_read(data_path + "/data/xml/character1_idle.xml",m_animation[0]); keyframe_animation_xml_read(data_path + "/data/xml/character1_jog.xml",m_animation[1]); keyframe_animation_xml_read(data_path + "/data/xml/character1_shoot_arrow.xml",m_animation[2]); ...
Skin and material data can be loaded into the skin container:
skin_xml_read(data_path + "/data/xml/character1_calf_left.xml",m_skin.m_skin_parts[0]); skin_xml_read(data_path + "/data/xml/character1_hand_right.xml",m_skin.m_skin_parts[1]); skin_xml_read(data_path + "/data/xml/character1_ponytail.xml",m_skin.m_skin_parts[2]); ... material_xml_read(data_path + "/data/xml/character1_skin_material.xml",m_skin.m_material[0]); material_xml_read(data_path + "/data/xml/character1_ponytail_material.xml",m_skin.m_material[1]); material_xml_read(data_path + "/data/xml/character1_chest_material.xml",m_skin.m_material[2]); ...
finally, some initialization must be done...