/src/Assets_Assimp/tools/assimp_view/SceneAnimator.h
C Header | 243 lines | 59 code | 36 blank | 148 comment | 2 complexity | 9f3a8fc2ce5b7458cf24dec516f1fff9 MD5 | raw file
Possible License(s): AGPL-3.0, LGPL-2.1, LGPL-3.0, GPL-2.0
1/* 2--------------------------------------------------------------------------- 3Open Asset Import Library (ASSIMP) 4--------------------------------------------------------------------------- 5 6Copyright (c) 2006-2010, ASSIMP Development Team 7 8All rights reserved. 9 10Redistribution and use of this software in source and binary forms, 11with or without modification, are permitted provided that the following 12conditions are met: 13 14* Redistributions of source code must retain the above 15 copyright notice, this list of conditions and the 16 following disclaimer. 17 18* Redistributions in binary form must reproduce the above 19 copyright notice, this list of conditions and the 20 following disclaimer in the documentation and/or other 21 materials provided with the distribution. 22 23* Neither the name of the ASSIMP team, nor the names of its 24 contributors may be used to endorse or promote products 25 derived from this software without specific prior 26 written permission of the ASSIMP Development Team. 27 28THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 29"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 30LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 31A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 32OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 33SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 34LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 35DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 36THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 37(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 38OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 39--------------------------------------------------------------------------- 40*/ 41 42/** @file SceneAnimator.h 43 * Manages animations for a given scene and calculates present 44 * transformations for all nodes 45 */ 46 47#ifndef AV_SCENEANIMATOR_H_INCLUDED 48#define AV_SCENEANIMATOR_H_INCLUDED 49 50#include <map> 51 52namespace AssimpView { 53 54// --------------------------------------------------------------------------------- 55/** A little tree structure to match the scene's node structure, but holding 56 * additional data. Needs to be public to allow using it in templates at 57 * certain compilers. 58 */ 59struct SceneAnimNode 60{ 61 std::string mName; 62 SceneAnimNode* mParent; 63 std::vector<SceneAnimNode*> mChildren; 64 65 //! most recently calculated local transform 66 aiMatrix4x4 mLocalTransform; 67 68 //! same, but in world space 69 aiMatrix4x4 mGlobalTransform; 70 71 //! index in the current animation's channel array. -1 if not animated. 72 size_t mChannelIndex; 73 74 //! Default construction 75 SceneAnimNode() { 76 mChannelIndex = -1; mParent = NULL; 77 } 78 79 //! Construction from a given name 80 SceneAnimNode( const std::string& pName) 81 : mName( pName) { 82 mChannelIndex = -1; mParent = NULL; 83 } 84 85 //! Destruct all children recursively 86 ~SceneAnimNode() { 87 for( std::vector<SceneAnimNode*>::iterator it = mChildren.begin(); it != mChildren.end(); ++it) 88 delete *it; 89 } 90}; 91 92// --------------------------------------------------------------------------------- 93/** Calculates the animated node transformations for a given scene and timestamp. 94 * 95 * Create an instance for a aiScene you want to animate and set the current animation 96 * to play. You can then have the instance calculate the current pose for all nodes 97 * by calling Calculate() for a given timestamp. After this you can retrieve the 98 * present transformation for a given node by calling GetLocalTransform() or 99 * GetGlobalTransform(). A full set of bone matrices can be retrieved by 100 * GetBoneMatrices() for a given mesh. 101 */ 102class SceneAnimator 103{ 104public: 105 106 // ---------------------------------------------------------------------------- 107 /** Constructor for a given scene. 108 * 109 * The object keeps a reference to the scene during its lifetime, but 110 * ownership stays at the caller. 111 * @param pScene The scene to animate. 112 * @param pAnimIndex [optional] Index of the animation to play. Assumed to 113 * be 0 if not given. 114 */ 115 SceneAnimator( const aiScene* pScene, size_t pAnimIndex = 0); 116 117 /** Destructor */ 118 ~SceneAnimator(); 119 120 // ---------------------------------------------------------------------------- 121 /** Sets the animation to use for playback. This also recreates the internal 122 * mapping structures, which might take a few cycles. 123 * @param pAnimIndex Index of the animation in the scene's animation array 124 */ 125 void SetAnimIndex( size_t pAnimIndex); 126 127 // ---------------------------------------------------------------------------- 128 /** Calculates the node transformations for the scene. Call this to get 129 * uptodate results before calling one of the getters. 130 * @param pTime Current time. Can be an arbitrary range. 131 */ 132 void Calculate( double pTime); 133 134 // ---------------------------------------------------------------------------- 135 /** Retrieves the most recent local transformation matrix for the given node. 136 * 137 * The returned matrix is in the node's parent's local space, just like the 138 * original node's transformation matrix. If the node is not animated, the 139 * node's original transformation is returned so that you can safely use or 140 * assign it to the node itsself. If there is no node with the given name, 141 * the identity matrix is returned. All transformations are updated whenever 142 * Calculate() is called. 143 * @param pNodeName Name of the node 144 * @return A reference to the node's most recently calculated local 145 * transformation matrix. 146 */ 147 const aiMatrix4x4& GetLocalTransform( const aiNode* node) const; 148 149 // ---------------------------------------------------------------------------- 150 /** Retrieves the most recent global transformation matrix for the given node. 151 * 152 * The returned matrix is in world space, which is the same coordinate space 153 * as the transformation of the scene's root node. If the node is not animated, 154 * the node's original transformation is returned so that you can safely use or 155 * assign it to the node itsself. If there is no node with the given name, the 156 * identity matrix is returned. All transformations are updated whenever 157 * Calculate() is called. 158 * @param pNodeName Name of the node 159 * @return A reference to the node's most recently calculated global 160 * transformation matrix. 161 */ 162 const aiMatrix4x4& GetGlobalTransform( const aiNode* node) const; 163 164 // ---------------------------------------------------------------------------- 165 /** Calculates the bone matrices for the given mesh. 166 * 167 * Each bone matrix transforms from mesh space in bind pose to mesh space in 168 * skinned pose, it does not contain the mesh's world matrix. Thus the usual 169 * matrix chain for using in the vertex shader is 170 * @code 171 * boneMatrix * worldMatrix * viewMatrix * projMatrix 172 * @endcode 173 * @param pNode The node carrying the mesh. 174 * @param pMeshIndex Index of the mesh in the node's mesh array. The NODE's 175 * mesh array, not the scene's mesh array! Leave out to use the first mesh 176 * of the node, which is usually also the only one. 177 * @return A reference to a vector of bone matrices. Stays stable till the 178 * next call to GetBoneMatrices(); 179 */ 180 const std::vector<aiMatrix4x4>& GetBoneMatrices( const aiNode* pNode, 181 size_t pMeshIndex = 0); 182 183 184 // ---------------------------------------------------------------------------- 185 /** @brief Get the current animation index 186 */ 187 size_t CurrentAnimIndex() const { 188 return mCurrentAnimIndex; 189 } 190 191 // ---------------------------------------------------------------------------- 192 /** @brief Get the current animation or NULL 193 */ 194 aiAnimation* CurrentAnim() const { 195 return mCurrentAnimIndex < mScene->mNumAnimations ? mScene->mAnimations[ mCurrentAnimIndex ] : NULL; 196 } 197 198protected: 199 200 /** Recursively creates an internal node structure matching the 201 * current scene and animation. 202 */ 203 SceneAnimNode* CreateNodeTree( aiNode* pNode, SceneAnimNode* pParent); 204 205 /** Recursively updates the internal node transformations from the 206 * given matrix array 207 */ 208 void UpdateTransforms( SceneAnimNode* pNode, const std::vector<aiMatrix4x4>& pTransforms); 209 210 /** Calculates the global transformation matrix for the given internal node */ 211 void CalculateGlobalTransform( SceneAnimNode* pInternalNode); 212 213protected: 214 /** The scene we're operating on */ 215 const aiScene* mScene; 216 217 /** Current animation index */ 218 size_t mCurrentAnimIndex; 219 220 /** The AnimEvaluator we use to calculate the current pose for the current animation */ 221 AnimEvaluator* mAnimEvaluator; 222 223 /** Root node of the internal scene structure */ 224 SceneAnimNode* mRootNode; 225 226 /** Name to node map to quickly find nodes by their name */ 227 typedef std::map<const aiNode*, SceneAnimNode*> NodeMap; 228 NodeMap mNodesByName; 229 230 /** Name to node map to quickly find nodes for given bones by their name */ 231 typedef std::map<const char*, const aiNode*> BoneMap; 232 BoneMap mBoneNodesByName; 233 234 /** Array to return transformations results inside. */ 235 std::vector<aiMatrix4x4> mTransforms; 236 237 /** Identity matrix to return a reference to in case of error */ 238 aiMatrix4x4 mIdentityMatrix; 239}; 240 241} // end of namespace AssimpView 242 243#endif // AV_SCENEANIMATOR_H_INCLUDED