Upcoming Events
Unite 2010
11/10 - 11/12 @ Montréal, Canada

GDC China
12/5 - 12/7 @ Shanghai, China

Asia Game Show 2010
12/24 - 12/27  

GDC 2011
2/28 - 3/4 @ San Francisco, CA

More events...
Quick Stats
84 people currently visiting GDNet.
2406 articles in the reference section.

Help us fight cancer!
Join SETI Team GDNet!
Link to us Events 4 Gamers
Intel sponsors gamedev.net search:

Animation in X Files

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

AnimationKey

This 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.

Animation

This 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.

AnimationSet

Acts as a container for Animation templates. The Animation templates contained in this set have the same time values.

Implementing Animations

In 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
sarmad@Tyfirty.com


Contents
  Overview of Skin Meshes
  Skin Meshes and DirectX 8
  The Implementation
  Animation

  Source code
  Printable version
  Discuss this article