166 lines
7.6 KiB
C++
166 lines
7.6 KiB
C++
/** Manages animations for a given scene and calculates present transformations for all nodes */
|
|
/*
|
|
---------------------------------------------------------------------------
|
|
Open Asset Import Library (ASSIMP)
|
|
---------------------------------------------------------------------------
|
|
|
|
Copyright (c) 2006-2008, ASSIMP Development Team
|
|
|
|
All rights reserved.
|
|
|
|
Redistribution and use of this software in source and binary forms,
|
|
with or without modification, are permitted provided that the following
|
|
conditions are met:
|
|
|
|
* Redistributions of source code must retain the above
|
|
copyright notice, this list of conditions and the
|
|
following disclaimer.
|
|
|
|
* Redistributions in binary form must reproduce the above
|
|
copyright notice, this list of conditions and the
|
|
following disclaimer in the documentation and/or other
|
|
materials provided with the distribution.
|
|
|
|
* Neither the name of the ASSIMP team, nor the names of its
|
|
contributors may be used to endorse or promote products
|
|
derived from this software without specific prior
|
|
written permission of the ASSIMP Development Team.
|
|
|
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
---------------------------------------------------------------------------
|
|
*/
|
|
|
|
#ifndef AV_SCENEANIMATOR_H_INCLUDED
|
|
#define AV_SCENEANIMATOR_H_INCLUDED
|
|
|
|
namespace AssimpView
|
|
{
|
|
|
|
/** A little tree structure to match the scene's node structure, but holding additional data. Needs to be public
|
|
* to allow using it in templates at certain compilers.
|
|
*/
|
|
struct SceneAnimNode
|
|
{
|
|
std::string mName;
|
|
SceneAnimNode* mParent;
|
|
std::vector<SceneAnimNode*> mChildren;
|
|
aiMatrix4x4 mLocalTransform; // most recently calculated local transform
|
|
aiMatrix4x4 mGlobalTransform; // same, but in world space
|
|
size_t mChannelIndex; // index in the current animation's channel array. -1 if not animated.
|
|
|
|
SceneAnimNode() { mChannelIndex = -1; mParent = NULL; }
|
|
SceneAnimNode( const std::string& pName) : mName( pName) { mChannelIndex = -1; mParent = NULL; }
|
|
~SceneAnimNode() { for( std::vector<SceneAnimNode*>::iterator it = mChildren.begin(); it != mChildren.end(); ++it) delete *it; }
|
|
};
|
|
|
|
/** Calculates the animated node transformations for a given scene and timestamp. Create an instance for a aiScene
|
|
* you want to animate and set the current animation to play. You can then have the instance calculate the current pose
|
|
* for all nodes by calling Calculate() for a given timestamp. After this you can retrieve the present transformation for a given
|
|
* node by calling GetLocalTransform() or GetGlobalTransform(). A full set of bone matrices can be retrieved by GetBoneMatrices()
|
|
* for a given mesh.
|
|
*/
|
|
class SceneAnimator
|
|
{
|
|
public:
|
|
/** Constructor for a given scene. The object keeps a reference to the scene during its lifetime, but ownership
|
|
* stays at the caller.
|
|
* @param pScene The scene to animate.
|
|
* @param pAnimIndex [optional] Index of the animation to play. Assumed to be 0 if not given.
|
|
*/
|
|
SceneAnimator( const aiScene* pScene, size_t pAnimIndex = 0);
|
|
|
|
/** Destructor */
|
|
~SceneAnimator();
|
|
|
|
/** Sets the animation to use for playback. This also recreates the internal mapping structures,
|
|
* which might take a few cycles.
|
|
* @param pAnimIndex Index of the animation in the scene's animation array
|
|
*/
|
|
void SetAnimIndex( size_t pAnimIndex);
|
|
|
|
/** Calculates the node transformations for the scene. Call this to get uptodate results
|
|
* before calling one of the getters.
|
|
* @param pTime Current time. Can be an arbitrary range.
|
|
*/
|
|
void Calculate( double pTime);
|
|
|
|
/** Retrieves the most recent local transformation matrix for the given node. The returned
|
|
* matrix is in the node's parent's local space, just like the original node's transformation
|
|
* matrix. If the node is not animated, the node's original transformation is returned so that
|
|
* you can safely use or assign it to the node itsself. If there is no node with the given name,
|
|
* the identity matrix is returned. All transformations are updated whenever Calculate() is called.
|
|
* @param pNodeName Name of the node
|
|
* @return A reference to the node's most recently calculated local transformation matrix.
|
|
*/
|
|
const aiMatrix4x4& GetLocalTransform( const std::string& pNodeName) const;
|
|
|
|
/** Retrieves the most recent global transformation matrix for the given node. The returned
|
|
* matrix is in world space, which is the same coordinate space as the transformation of the
|
|
* scene's root node. If the node is not animated, the node's original transformation is
|
|
* returned so that you can safely use or assign it to the node itsself. If there is no node
|
|
* with the given name, the identity matrix is returned. All transformations are updated whenever
|
|
* Calculate() is called.
|
|
* @param pNodeName Name of the node
|
|
* @return A reference to the node's most recently calculated global transformation matrix.
|
|
*/
|
|
const aiMatrix4x4& GetGlobalTransform( const std::string& pNodeName) const;
|
|
|
|
/** Calculates the bone matrices for the given mesh. Each bone matrix transforms from
|
|
* mesh space in bind pose to mesh space in skinned pose, it does not contain the mesh's
|
|
* world matrix. Thus the usual matrix chain for using in the vertex shader is
|
|
* boneMatrix * worldMatrix * viewMatrix * projMatrix.
|
|
* @param pNode The node carrying the mesh.
|
|
* @param pMeshIndex Index of the mesh in the node's mesh array. The NODE's mesh array, not
|
|
* the scene's mesh array! Leave out to use the first mesh of the node, which is usually
|
|
* also the only one.
|
|
* @return A reference to a vector of bone matrices. Stays stable till the next call to GetBoneMatrices();
|
|
*/
|
|
const std::vector<aiMatrix4x4>& GetBoneMatrices( const aiNode* pNode, size_t pMeshIndex = 0);
|
|
|
|
protected:
|
|
/** Recursively creates an internal node structure matching the current scene and animation. */
|
|
SceneAnimNode* CreateNodeTree( aiNode* pNode);
|
|
|
|
/** Recursively updates the internal node transformations from the given matrix array */
|
|
void UpdateTransforms( SceneAnimNode* pNode, const std::vector<aiMatrix4x4>& pTransforms);
|
|
|
|
/** Calculates the global transformation matrix for the given internal node */
|
|
void CalculateGlobalTransform( SceneAnimNode* pInternalNode);
|
|
|
|
protected:
|
|
/** The scene we're operating on */
|
|
const aiScene* mScene;
|
|
|
|
/** Current animation index */
|
|
size_t mCurrentAnimIndex;
|
|
|
|
/** The AnimEvaluator we use to calculate the current pose for the current animation */
|
|
AnimEvaluator* mAnimEvaluator;
|
|
|
|
/** Root node of the internal scene structure */
|
|
SceneAnimNode* mRootNode;
|
|
|
|
/** Name to node map to quickly find nodes by their name */
|
|
typedef std::map<std::string, SceneAnimNode*> NodeMap;
|
|
NodeMap mNodesByName;
|
|
|
|
/** Array to return transformations results inside. */
|
|
std::vector<aiMatrix4x4> mTransforms;
|
|
|
|
/** Identity matrix to return a reference to in case of error */
|
|
aiMatrix4x4 mIdentityMatrix;
|
|
};
|
|
|
|
} // end of namespace AssimpView
|
|
|
|
#endif // AV_SCENEANIMATOR_H_INCLUDED
|