XAnimator - X File Animation Loader / Player
Page Contents
Introduction to XAnimator
XAnimator is a small library I have written to support the loading and playback of x files containing animation. Writing code to read and play back animated .x files is a pretty onerous task (see Load X Hierarchy) and so I have written this small library to wrap the functionality in a simple interface. It is freely available for anyone to use for any purpose although I would appreciate a reference. Please do not distribute the actual library files directly, link to here instead.
Features
- Load and render animated .x files
- Change animation sets by merging from one to another
- Provides access to bounding shape data including low level mesh oriented boxes transformed correctly for the current animation stage
- Manages mesh data so if you load the same model many times XAnimator will store and use just one version of the mesh data. This is useful as you generally do not want to use multiple instances of the same animated model as you want the animation to be at different states / times.
Latest Version Changes and Downloads
Latest Version: 1.0 (February 2013)
- Rebuilt using Visual Studio 2012
- Added 64 bit versions
- If a texture is not found in the path indicated by the mesh it is looked for in the working directory
If the mesh is then saved this filename is saved rather than the original path
If the texture still cannot be found the texture filename is retained
- Fixed a memory leak
- Added a call to discard a model
- You can now provide an interface instance to get XAnimator debug output
- added flag XANIMATOR_NO_CACHE_MESH to prevent an XAnimator optimisation where the same mesh are opnly loaded once
- fixed a problem when saving the .x file the animation set ids were reversed
- XAnimator no longer adds a root frame by default when saving
- added Extended/Advanced functions in order to provide external access to the model data
ExGetHierarchy and ExChangeHierarchy
- added ExTransformRoot to apply a transformation to the root frame of the model
The below library download contains release and debug .lib files for 32 and 64 bit development, the XAnimator header and a ReadMe.txt with changes / version history etc. The example project shows how to use XAnimator. Rather than waste space in the download this does not include the XAnimator library files. So before building please unzip XAnimator into the project directory. You should end up with a directory path: /XAnimatorTest / XAnimatorTest/XAnimator/ (all the library files should be here).
For Visual Studio 2012
XAnimator library: XAnimator_v100.zip
Example Project: XAnimatorTest_2012.zip
For Visual Studio 2010
XAnimator library: XAnimator_v093.rar
Example Project: XAnimatorTest.rar
Bounding Shapes Example Project: XAnimatorBoundingShapes.rar
This example shows how to use the bounding shapes returned from XAnimator to create bounds in world space
Known Limitations / Issues
- There may be a memory leak under rare conditions - this is being investigated
- Model texture files are looked for in the directory containing the model
- In the event of a D3D device change, the library needs to be closed down and restarted
- Skinning is supported but only in software
- Effect files are not yet supported
- Save does not support all types of mesh data, only the most common. Unsupported data includes
- Effect data
- Rare vertex data like blend weights, tangents, binormals, fog etc.
- Vertex duplication data or face adjacency
- Progressive mesh
Possible Future Additions
- Add support for effect files
- Hardware skinning
- Further save model capabilities
- Possible utility functions to
- Provide access to the frame hierarchy
How to Install XAnimator
Installation is relatively easy, just follow these steps:
Note: the paths in these steps assume you have extracted the library compressed .rar file to your project directory i.e. the one containing your .vcproj file if you are using Visual Studio. Of course you can put it where you want - just adjust the paths below.
- Tell Visual Studio where the XAnimator include files are located: go to Project Properties / Configuration Properties / C/C++ / General and in "Additional Include Directories" enter XAnimator (Note: you will need to do this for all configurations)
- Tell Visual Studio where the XAnimator library files are located: go to Project Properties / Configuration Properties / Linker / General and in "Additional Linker Directories" enter XAnimator (Note: you will need to do this for all configurations)
- Link to the correct file via Project Properties / Configuration Properties / Linker / Input in "Additional Dependencies"
- In debug configuration you should link to XAnimator_debug.lib (from 0.94 this is XAnimator_d32.lib or XAnimator_d64.lib)
- In release configuration you should link to XAnimator.lib (from 0.94 this is XAnimator_32.lib or XAnimator_64.lib)
- Note: if you are not already linking to the Direct3D libraries XAnimator also needs these. They are dxguid.lib dxerr.lib d3d9.lib and d3dx9.lib ( d3dx9d.lib for debug mode)
Note: XAnimator requires linking to a Win32 application and was built using the DLL runtime libraries (/MD or /MDd)
How to Use XAnimator
To use XAnimator you must include the header XAnimator.h. This header defines the interface for the library.
How to initialise XAnimator
The first thing to do is to create an instance of the library (only one is needed) via a call to CreateXAnimator. This will return a pointer to the library object which provides all the functions of the library. e.g.
IXAnimator* xAnimator=0;
xAnimator=CreateXAnimator(d3dDevice);
the library requires that you pass a valid Direct3D device. Optionally you can specify a second parameter as true to get verbose output from XAnimator
To load an animated x file
Call LoadXFile with a filename and the address of an int that will be filled with a unique id (which you can use in later calls to refer to this model). Note that if the function fails it will return false. Also check the output pane in Visual Studio where XAnimator will write more details of any error.
e.g.
int skeletonGraphicId;
if (!xAnimator->LoadXFile("skeleton.x",&skeletonGraphicId)
// an error occurred
Optionally you can provide a flag to carry out certain actions (see LoadXFile below for details). You can also specify a root matrix that will be applied at the top of the model hierarchy. This could be useful if your model is upside down or facing the wrong way.
To draw and animate the x file
To draw the x file you need to call the Render function. This function takes the model id returned earlier in the LoadXFile call, a world matrix and the amount of time that has passed in milliseconds since the last render. The time is needed to advance the animation. e.g.
xAnimator->Render(skeletonGraphicId,worldMatrix,timePassed);
If you find the animation is playing back to fast or to slowly try calling ChangeAnimationPlaybackSpeed. If the model has more than one animation set you can change sets by calling ChangeAnimationSet.
Function Reference
Function List
Functions
Function Name
|
CreateXAnimator
|
Purpose
|
To initialise XAnimator and return a pointer to an instance
|
Prototype
|
IXAnimator* CreateXAnimator(LPDIRECT3DDEVICE9 device, bool verbose=true)
|
Parameters
|
LPDIRECT3DDEVICE9 device (IN) required valid Direct3D device
bool verbose (IN) optional flag. If true then XAnmator outputs useful information to the output pane in Visual Studio. If false output is limited to errors and warnings.
|
Return
|
bool false if an error has occurred. Check the output pane in Visual Studio for details.
|
|
The following functions are all members of the IXAnimator instance returned from the call above.
Function Name
|
LoadXFile
|
Purpose
|
To load a .x file and set a unique model id that can be used in later calls to refer to this model.
|
Prototype
|
bool LoadXFile(const std::string &filename,int *modelId,const D3DXMATRIX *rootFrameMat=0)
|
Parameters
|
const std::string &filename (IN) required full path and filename of the .x file to load. Note that XAnimator will look for the model's texture files in the same directory as the .x file.
int *modelId (OUT) required address of an integer variable. Will be set to a unique value so that you can refer to this model in later calls to XAnimator.
DWORD flags (IN) optional flags: XANIMATOR_OPTIMISE_MESH - attempts to optimise the mesh for faster rendering XANIMATOR_CLEAN_MESH - attempts to clean the mesh of problems.
D3DXMATRIX &rootFrameMat (IN) optional matrix. If provided XAnimator will add a new frame to the top of the model hierarchy with this matrix meaning the whole hierarchy below will be transformed by this matrix. This can be useful if you have loaded a .x file that was saved facing the wrong way e.g. your application assumes that all models face down z but this one was saved facing -z. In this case your matrix would contain a rotation around Y to permanently adjust the direction the model faces.
|
Return
|
bool false if an error has occurred. Check the output pane in Visual Studio for details.
|
|
Function Name
|
Render
|
Purpose
|
Advances the animation and then renders the a .x file in world space specified by the supplied matrix
|
Prototype
|
bool Render(int modelId,const D3DXMATRIX &mat,float timePassed)
|
Parameters
|
int modelId (IN) required unique id for this model as returned from LoadXFile.
const D3DXMATRIX &mat (IN) required world matrix created to transform the model from model space into your game world space
float timePassed (IN) required time in milliseconds since the last render was called. This value is used to advance the animation.
|
Return
|
bool false if an error has occurred. Check the output pane in Visual Studio for details.
|
|
Function Name
|
GetNumberOfAnimationSets
|
Purpose
|
Returns the number of animation sets in the .x file. x files can contain a number of animation sets e.g. run, walk, jump, die.
|
Prototype
|
int GetNumberOfAnimationSets(int modelId)
|
Parameters
|
int modelId (IN) required unique id for this model as returned from LoadXFile.
|
Return
|
int number of animation sets in the .x file
|
|
Function Name
|
ChangeAnimationSet
|
Purpose
|
Changes the current animation set by merging it into the old set over the time specified
|
Prototype
|
bool ChangeAnimationSet(int modelId,int setIndex,float transitionTime=250)
|
Parameters
|
int modelId (IN) required unique id for this model as returned from LoadXFile.
int setIndex (IN) required index of the new animation set. Note: must not be greater than the value returned from GetNumberOfAnimationSets.
float transitionTime (IN) optional time in milliseconds to take merging from the old animation set into the new one. If you were to just change animation set abruptly it would look odd as for example a model in mid run suddenly does a die animation. Therefore this function allows two animation sets to be more gradually merged leading to a smooth change in animation. If not provided a default of 250 milliseconds is used.
|
Return
|
bool false if an error has occurred. Check the output pane in Visual Studio for details.
|
|
Function Name
|
GetAnimationSetName
|
Purpose
|
Returns the name of an animation set as specified in the .x file
|
Prototype
|
bool GetAnimationSetName(int modelId,int setIndex,std::string *name)
|
Parameters
|
int modelId (IN) required unique id for this model as returned from LoadXFile.
int setIndex (IN) required index of the new animation set. Note: must not be greater than the value returned from GetNumberOfAnimationSets.
std::string *name (OUT) required pointer to a standard library string. If the function is successful this will be set to the animation name on return.
|
Return
|
bool false if an error has occurred. Check the output pane in Visual Studio for details.
|
|
Function Name
|
ChangeAnimationPlaybackSpeed
|
Purpose
|
Alters the play back speed of the animation
|
Prototype
|
bool ChangeAnimationPlaybackSpeed(int modelId,float speedRatio)
|
Parameters
|
int modelId (IN) required unique id for this model as returned from LoadXFile.
float speedRatio (IN) required new speed ratio. The default of 1.0f uses time values from the model itself. Sometimes however these can be wrong or to fast so you can apply a ration here e.g. 0.5f would be half speed
|
Return
|
bool false if an error has occurred. Check the output pane in Visual Studio for details.
|
|
Function Name
|
GetBoundingShapes
|
Purpose
|
Calculates and returns bounding shapes for the model and individual mesh in the model. These can then be used for collision detection. Note that this call updates all the shapes to take the latest animation into account. See the example project for code on using the bounding shapes.
|
Prototype
|
TMeshBounds *GetBoundingShapes(int modelId, D3DXVECTOR3 *modelMinBounds,D3DXVECTOR3 *modelMaxBounds, D3DXVECTOR3* sphereCentre=0,float *sphereRadius=0, int *numMesh=0)
|
Parameters
|
int modelId (IN) required unique id for this model as returned from LoadXFile.
D3DXVECTOR3 *modelMinBounds, *modelMaxBounds (OUT) required addresses of vectors to hold the returned minimum and maximum object space axis aligned bounds of the whole model.
D3DXVECTOR3 *sphereCentre (OUT) optional address of a vector to hold the centre of a model space bounding sphere that encompasses the whole model
float *sphereRadius (OUT) optional address of a float to hold the radius of the model space sphere
int *numMesh (OUT) optional address or an integer to hold the number of mesh contained in the return array
|
Return
|
TMeshBounds* a pointer to an array of TMeshBound holding data for each mesh in the hierarchy. The array is numMesh in size. The TMeshBound type holds a frame name, mesh name and the 8 corners of the mesh oriented bounding box in model space.
|
|
Function Name
|
AddAnimationsFromXFile
|
Purpose
|
Adds animation sets from a physically identical .x file to a currently loaded one
|
Prototype
|
bool AddAnimationsFromXFile(int modelId,const std::string &filename)
|
Parameters
|
int modelId (IN) required unique id for the model (as returned from LoadXFile) to which to add the animation to.
const std::string &filename (IN) required full path and filename of the .x file to add animations from.
|
Return
|
bool false if an error has occurred. Check the output pane in Visual Studio for details.
|
|
Function Name
|
SaveModel
|
Purpose
|
Saves a loaded model with various options
|
Prototype
|
bool SaveModel(int modelId,const std::string &filename,bool binary=true,bool compressed=true)
|
Parameters
|
int modelId (IN) required unique id for the model to save
const std::string &filename (IN) required full path and filename to save to
bool binary (IN) optional flag to specify if the file should be saved in binary format. Use false to save in text format
bool compressed (IN) optional flag to specify if the file should be compressed.
|
Return
|
bool false if an error has occurred. Check the output pane in Visual Studio for details.
|
|