You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

243 lines
9.0 KiB

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