#ifndef __ANIMATION_MANAGER_H__ #define __ANIMATION_MANAGER_H__ /* Animation Sets ------------------- Fairly self explanatory--this is a structure that contains data for a collection of animations. The actual allocation/de-allocation of the structure is done by an Animator object, although the animation sets and animator objects themselves are managed by the AnimationManager. Each AnimationSet inherits from the AnimationSet structure. The AnimationSet structure does not contain any methods, only member variables, as should each of its child structures. Animators -------------------- Responsible for allocating, de-allocating, and computing vertices on a mesh. Each Animator object inherits from the IAnimator interface, and is stored in a map based on a hash value. This hash value is returned by the Animator object. By default, no animators are stored on the AnimationManager--these have to be set up using the registerAnimator method, presumably by the main Game object or somewhere similar. Animation Nodes ------------------- The AnimationManager contains a list of header nodes per animator object. New nodes can be allocated as needed by a mesh. Each header node has an animation tree attached: Animation Tree: /----- Walk /--- Jog --| (w=0.5) / (w=1.0) \----- Run Header -| (w=0.5) \ \--- Shoot (w=1.0) On each update, the manager collapses each tree, calculating actual weights that will be used during calculation of vertices. What results is a stack of nodes that each contain an animation: Animation Stack: +------------------+ | Shoot (w=0.50) | +------------------+ | Walk (w=0.25) | +------------------+ | Run (w=0.25) | +------------------+ Each stack is passed to an Animator object which pops each animation, calculating vertex positions for rendering. These stacks are stored on their respective header nodes. */ #include <string> #include <map> #include "Util/Singleton.h" #include "Util/Hash.h" #include "Records/AnimationSet.h" #include "Records/AnimationNode.h" class IAnimator; class AnimationManager : public Singleton<AnimationManager> { public: typedef AnimationSet::Map AnimationSetMap; typedef AnimationSet::MapIterator AnimationSetIterator; typedef AnimationNode::List AnimationNodeList; typedef AnimationNode::ListIterator AnimationNodeIterator; typedef std::map<hash32,AnimationNodeList*> NodeListMap; typedef NodeListMap::iterator NodeListMapIterator; typedef std::map<hash32,IAnimator*> AnimatorMap; typedef AnimatorMap::iterator AnimatorIterator; public: AnimationManager(); ~AnimationManager(); int initiate(); int update(); int shutdown(); // if animation set with correspondig filename is found, that animation set is returned, // otherwise, appropriate structure based on animatorHash argument is allocated, stored, then returned. // (the data variable is a structure specific to the animator object that will be doing the allocating. // it will most likely be a structure that has already been loaded somewhere else to create a model. For // example, when creating an md2 animation set, data will be a pointer to an md2 structure containg file data.) AnimationSet *createAnimationSet(std::string fileName, hash32 animatorHash, void *data); // decreases animation set reference count, destroying it if reference count is 0 void destroyAnimationSet(AnimationSet *set); // allocates an animation node for a mesh AnimationNode *createAnimationNode(AnimationNode *parent, Mesh *mesh, int flags, float weight); // deallocates an animation node and recursively destroys its chidlren void destroyAnimationNode(AnimationNode *node); // allocates/adds an animator to the animator map. // (an animator is only added if an animator with the same hash is not found. // over writing an animator is not allowed as it might disrupt an animation node list) template <class TYPE> int registerAnimator() { IAnimator *animator = new TYPE; hash32 hash = animator->getHash(); pair<AnimatorIterator,bool> insertResult; int result = 1; insertResult = m_animators.insert( pair<hash32,IAnimator*>(hash,animator) ); if(insertResult.second == false) { delete animator; result = 0; } else m_animationNodeLists[ hash ] = new AnimationNodeList(); return result; } private: // used by update to collapse trees attached to a list of header nodes void collapseNodes(AnimationNodeList *nodes); // used by collapseNodes to collapse an individual tree attached to a header node void collapseTree(AnimationNode *header, float elapsed); // used by destroyAnimationNode to recursively destroy nodes void _destroyAnimationNode(AnimationNode *node); private: // map of loaded animation sets AnimationSetMap m_animationSets; // map of node lists, each node in list is a header node, one list per animator object NodeListMap m_animationNodeLists; // map animator objects which responsible for allocation/de-allocation of a particular animation set, // as well as actual vertex calculation AnimatorMap m_animators; }; #endif