Animation in X FilesThe animations in X files are not specific to skin meshes; they can be applied to any Frame in the X file. X files store key frames and the application should generate the in-between frames using linear interpolation. There are four types of animation keys, rotation, scale, position, and matrix keys. Rotations are stored as quaternions and can be interpolated using spherical linear interpolation. The function D3DXQuaternionSlerp provided by D3DX implements the spherical linear interpolation. The following X file templates are used to store animations: AnimationKeyThis template is used to store animation keys. Each instance of this template contains the type of the key (position, scale, rotation, or matrix) and the array of keys. Each element in this array contains the value of the key and a DWORD value specifying the time. AnimationThis template stores the animation keys of a specific frame. It should contain at least one AnimationKey template. It should also contain a reference to the target frame. AnimationSetActs as a container for Animation templates. The Animation templates contained in this set have the same time values. Implementing AnimationsIn order to implement animations in our skin meshes, we'll need to add a new class. We'll name this class CAnimationNode. This class will hold the animation keys along with a pointer to the target frame. The class will also contain a SetTime function that will update the target frame's transformation matrix with the matrix obtained from the animation keys at the new time value. Each instance of CAnimationNode will hold the data of a single instance of the Animation template. The following figure shows the new design for our code:
With the animation taken into consideration, the loading code will be slightly changed. Following is the previous loading code after applying the required changes: CSkinMesh::Create() Begin Initialize X file API Register D3DRM templates Open the X file For every top level template in the X file Begin Retrieve the X file data object Pass the data object to RootFrame.Load End Link the bones to the skin mesh(es) Link the bones to the animations End CFrameNode::Load() Begin Check the type of the data object If the type is Mesh Begin Create new CMeshNode object Attach the new object to the frame Pass the data object to CMeshNode::Create of the new mesh End Else if type is FrameTransformationMatrix Load the transformation matrix Else if type is Frame Else if type is Animation Instruct CSkinMesh to load the new animation Begin Create new CFrameNode object Attach the new object to this frame Set the name of the child frame to the name of the template For every child template of the current Begin Retrieve the X file data object Pass it to newframe.Load End End End CSkinMesh::LoadAnimation() Begin Create new CAnimationNode object Attach the new object to the link list For every child template Call CAnimationNode::Load for the new animation object End CAnimationNode::Load() Begin Check the type of the data object If the type is a reference Begin Get the referenced template, which is a frame template Get the name of it Store the name End Else if type is data Begin Check the type of the animation key Load the key accordingly End End The SetTime function is where all the animation functionality is performed. CSkinMesh::SetTime simply calls the SetTime function of all the animation objects. CAnimationNode::SetTime() Begin If a matrix key is available Begin Get the nearest matrix to the given time Set it to the target frame End Else Begin Prepare an identity matrix called TransMat If a scale key is available Begin Calculate the accurate scale value Prepare a scale matrix for this scale value Append the matrix to TransMat End If a rotation key is available Begin Calculate the accurate rotation quaternion Prepare a rotation matrix from this value Append the matrix to TransMat End If a position key is available Begin Calculate the accurate position value Prepare a matrix for it Append the matrix to TransMat End Set TransMat to the target frame End End Now that you've understood everything related to skin meshes, it's time for you to download the source code and try it yourself. Note that the source code is simplified for the sake of clarity. Many of the checking is removed in order to simplify the code. The code assumes that you have a 3D accelerator and it assumes that your system supports the required blending weights. The code uses non-indexed vertex blending. For a more complicated sample, you can refer to the sample that comes with DX8 SDK, which performs a lot of checking and implements both indexed and non-indexed vertex blending. I hope this article was helpful to you. If you have any questions, opinions, suggestions or anything to say, feel free to mail me. Sarmad Kh Abdulla
|
|