Add data structures for vertex animation. Basing on recent ML discussion.
git-svn-id: https://assimp.svn.sourceforge.net/svnroot/assimp/trunk@720 67173fc5-114c-0410-ac8e-9d2fd5bffc1fpull/1/head
parent
261f49c468
commit
255082c39b
168
include/aiAnim.h
168
include/aiAnim.h
|
@ -57,9 +57,10 @@ extern "C" {
|
|||
/** A time-value pair specifying a certain 3D vector for the given time. */
|
||||
struct aiVectorKey
|
||||
{
|
||||
//! The time of this key
|
||||
/** The time of this key */
|
||||
double mTime;
|
||||
//! The value of this key
|
||||
|
||||
/** The value of this key */
|
||||
C_STRUCT aiVector3D mValue;
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -76,8 +77,7 @@ struct aiVectorKey
|
|||
|
||||
typedef aiVector3D elem_type;
|
||||
|
||||
//! Comparison operators. Just the key value is compared
|
||||
//! For use with std::find();
|
||||
// Comparison operators. For use with std::find();
|
||||
bool operator == (const aiVectorKey& o) const {
|
||||
return o.mValue == this->mValue;
|
||||
}
|
||||
|
@ -85,8 +85,7 @@ struct aiVectorKey
|
|||
return o.mValue != this->mValue;
|
||||
}
|
||||
|
||||
//! Relational operators. Just the key time is compared
|
||||
//! For use with std::sort();
|
||||
// Relational operators. For use with std::sort();
|
||||
bool operator < (const aiVectorKey& o) const {
|
||||
return mTime < o.mTime;
|
||||
}
|
||||
|
@ -97,22 +96,21 @@ struct aiVectorKey
|
|||
};
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
/** A time-value pair specifying a rotation for the given time. For joint
|
||||
* animations the rotation is usually expressed using a quaternion.
|
||||
*/
|
||||
/** A time-value pair specifying a rotation for the given time.
|
||||
* Rotations are expressed with quaternions. */
|
||||
struct aiQuatKey
|
||||
{
|
||||
//! The time of this key
|
||||
/** The time of this key */
|
||||
double mTime;
|
||||
//! The value of this key
|
||||
|
||||
/** The value of this key */
|
||||
C_STRUCT aiQuaternion mValue;
|
||||
|
||||
#ifdef __cplusplus
|
||||
aiQuatKey(){
|
||||
}
|
||||
|
||||
//! Default constructor
|
||||
aiQuatKey(){}
|
||||
|
||||
//! Construction from a given time and key value
|
||||
/** Construction from a given time and key value */
|
||||
aiQuatKey(double time, const aiQuaternion& value)
|
||||
: mTime (time)
|
||||
, mValue (value)
|
||||
|
@ -120,8 +118,7 @@ struct aiQuatKey
|
|||
|
||||
typedef aiQuaternion elem_type;
|
||||
|
||||
//! Comparison operators. Just the key value is compared
|
||||
//! For use with std::find();
|
||||
// Comparison operators. For use with std::find();
|
||||
bool operator == (const aiQuatKey& o) const {
|
||||
return o.mValue == this->mValue;
|
||||
}
|
||||
|
@ -129,8 +126,7 @@ struct aiQuatKey
|
|||
return o.mValue != this->mValue;
|
||||
}
|
||||
|
||||
//! Relational operators. Just the key time is compared
|
||||
//! For use with std::sort();
|
||||
// Relational operators. For use with std::sort();
|
||||
bool operator < (const aiQuatKey& o) const {
|
||||
return mTime < o.mTime;
|
||||
}
|
||||
|
@ -140,6 +136,51 @@ struct aiQuatKey
|
|||
#endif
|
||||
};
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
/** Binds a anim mesh to a specific point in time. */
|
||||
struct aiMeshKey
|
||||
{
|
||||
/** The time of this key */
|
||||
double mTime;
|
||||
|
||||
/** Index into the aiMesh::mAnimMeshes array of the
|
||||
* mesh coresponding to the #aiMeshAnim hosting this
|
||||
* key frame. The referenced anim mesh is evaluated
|
||||
* according to the rules defined in the docs for #aiAnimMesh.*/
|
||||
unsigned int mValue;
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
aiMeshKey() {
|
||||
}
|
||||
|
||||
/** Construction from a given time and key value */
|
||||
aiMeshKey(double time, const unsigned int value)
|
||||
: mTime (time)
|
||||
, mValue (value)
|
||||
{}
|
||||
|
||||
typedef unsigned int elem_type;
|
||||
|
||||
// Comparison operators. For use with std::find();
|
||||
bool operator == (const aiMeshKey& o) const {
|
||||
return o.mValue == this->mValue;
|
||||
}
|
||||
bool operator != (const aiMeshKey& o) const {
|
||||
return o.mValue != this->mValue;
|
||||
}
|
||||
|
||||
// Relational operators. For use with std::sort();
|
||||
bool operator < (const aiMeshKey& o) const {
|
||||
return mTime < o.mTime;
|
||||
}
|
||||
bool operator > (const aiMeshKey& o) const {
|
||||
return mTime > o.mTime;
|
||||
}
|
||||
|
||||
#endif
|
||||
};
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
/** Defines how an animation channel behaves outside the defined time
|
||||
* range. This corresponds to aiNodeAnim::mPreState and
|
||||
|
@ -184,8 +225,8 @@ enum aiAnimBehaviour
|
|||
*
|
||||
* @note All keys are returned in their correct, chronological order.
|
||||
* Duplicate keys don't pass the validation step. Most likely there
|
||||
* will be no negative time values, but they are not forbidden ( so you should
|
||||
* be able to handle them ) */
|
||||
* will be no negative time values, but they are not forbidden also ( so
|
||||
* implementations need to cope with them! ) */
|
||||
struct aiNodeAnim
|
||||
{
|
||||
/** The name of the node affected by this animation. The node
|
||||
|
@ -258,6 +299,41 @@ struct aiNodeAnim
|
|||
#endif // __cplusplus
|
||||
};
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
/** Describes vertex-based animations for a single mesh or a group of
|
||||
* meshes. Meshes carry the animation data for each frame in their
|
||||
* aiMesh::mAnimMeshes array. The purpose of aiMeshAnim is to
|
||||
* define keyframes linking each mesh attachment to a particular
|
||||
* point in time. */
|
||||
struct aiMeshAnim
|
||||
{
|
||||
/** Name of the mesh to be animated. An empty string is not allowed,
|
||||
* animated meshes need to be named (not necessarily uniquely,
|
||||
* the name can basically serve as wildcard to select a group
|
||||
* of meshes with similar animation setup)*/
|
||||
C_STRUCT aiString mName;
|
||||
|
||||
/** Size of the #mKeys array. Must be 1, at least. */
|
||||
unsigned int mNumKeys;
|
||||
|
||||
/** Key frames of the animation. May not be NULL. */
|
||||
C_STRUCT aiMeshKey* mKeys;
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
aiMeshAnim()
|
||||
: mNumKeys()
|
||||
, mKeys()
|
||||
{}
|
||||
|
||||
~aiMeshAnim()
|
||||
{
|
||||
delete[] mKeys;
|
||||
}
|
||||
|
||||
#endif
|
||||
};
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
/** An animation consists of keyframe data for a number of nodes. For
|
||||
* each node affected by the animation a separate series of data is given.*/
|
||||
|
@ -282,24 +358,43 @@ struct aiAnimation
|
|||
* The array is mNumChannels in size. */
|
||||
C_STRUCT aiNodeAnim** mChannels;
|
||||
|
||||
|
||||
/** The number of mesh animation channels. Each channel affects
|
||||
* a single mesh and defines vertex-based animation. */
|
||||
unsigned int mNumMeshChannels;
|
||||
|
||||
/** The mesh animation channels. Each channel affects a single mesh.
|
||||
* The array is mNumMeshChannels in size. */
|
||||
C_STRUCT aiMeshAnim** mMeshChannels;
|
||||
|
||||
#ifdef __cplusplus
|
||||
aiAnimation()
|
||||
: mDuration(-1.)
|
||||
, mTicksPerSecond()
|
||||
, mNumChannels()
|
||||
, mChannels()
|
||||
, mNumMeshChannels()
|
||||
, mMeshChannels()
|
||||
{
|
||||
mDuration = -1.;
|
||||
mTicksPerSecond = 0;
|
||||
mNumChannels = 0; mChannels = NULL;
|
||||
}
|
||||
|
||||
~aiAnimation()
|
||||
{
|
||||
// DO NOT REMOVE THIS ADDITIONAL CHECK
|
||||
if (mNumChannels && mChannels)
|
||||
{
|
||||
for( unsigned int a = 0; a < mNumChannels; a++)
|
||||
if (mNumChannels && mChannels) {
|
||||
for( unsigned int a = 0; a < mNumChannels; a++) {
|
||||
delete mChannels[a];
|
||||
}
|
||||
|
||||
delete [] mChannels;
|
||||
}
|
||||
if (mNumMeshChannels && mMeshChannels) {
|
||||
for( unsigned int a = 0; a < mNumMeshChannels; a++) {
|
||||
delete mMeshChannels[a];
|
||||
}
|
||||
|
||||
delete [] mMeshChannels;
|
||||
}
|
||||
}
|
||||
#endif // __cplusplus
|
||||
};
|
||||
|
@ -341,6 +436,15 @@ struct Interpolator <aiQuaternion> {
|
|||
}
|
||||
}; // ! Interpolator <aiQuaternion>
|
||||
|
||||
template <>
|
||||
struct Interpolator <unsigned int> {
|
||||
void operator () (unsigned int& out,unsigned int a,
|
||||
unsigned int b, float d) const
|
||||
{
|
||||
out = d>0.5f ? b : a;
|
||||
}
|
||||
}; // ! Interpolator <aiQuaternion>
|
||||
|
||||
template <>
|
||||
struct Interpolator <aiVectorKey> {
|
||||
void operator () (aiVector3D& out,const aiVectorKey& a,
|
||||
|
@ -361,6 +465,16 @@ struct Interpolator <aiQuatKey> {
|
|||
}
|
||||
}; // ! Interpolator <aiQuatKey>
|
||||
|
||||
template <>
|
||||
struct Interpolator <aiMeshKey> {
|
||||
void operator () (unsigned int& out, const aiMeshKey a,
|
||||
const aiMeshKey& b, float d) const
|
||||
{
|
||||
Interpolator<unsigned int> ipl;
|
||||
ipl(out,a.mValue,b.mValue,d);
|
||||
}
|
||||
}; // ! Interpolator <aiQuatKey>
|
||||
|
||||
//! @endcond
|
||||
} // ! end namespace Assimp
|
||||
|
||||
|
|
140
include/aiMesh.h
140
include/aiMesh.h
|
@ -302,6 +302,110 @@ enum aiPrimitiveType
|
|||
#define AI_PRIMITIVE_TYPE_FOR_N_INDICES(n) \
|
||||
((n) > 3 ? aiPrimitiveType_POLYGON : (aiPrimitiveType)(1u << ((n)-1)))
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
/** @brief An AnimMesh is an attachment to an #aiMesh stores per-vertex
|
||||
* animations for a particular frame.
|
||||
*
|
||||
* You may think of an #aiAnimMesh as a `patch` for the host mesh, which
|
||||
* replaces only certain vertex data streams at a particular time.
|
||||
* Each mesh stores n attached attached meshes (#aiMesh::mAnimMeshes).
|
||||
* The actual relationship between the time line and anim meshes is
|
||||
* established by #aiMeshAnim, which references singular mesh attachments
|
||||
* by their ID and binds them to a time offset.
|
||||
*/
|
||||
struct aiAnimMesh
|
||||
{
|
||||
/** Replacement for aiMesh::mVertices. If this array is non-NULL,
|
||||
* it *must* contain aiMesh::mNumVertices entries. The corresponding
|
||||
* array in the host mesh must be non-NULL as well - animation
|
||||
* meshes may neither add or nor remove vertex components (if
|
||||
* a replacement array is NULL and the corresponding source
|
||||
* array is not, the source data is taken instead)*/
|
||||
C_STRUCT aiVector3D* mVertices;
|
||||
|
||||
/** Replacement for aiMesh::mNormals. */
|
||||
C_STRUCT aiVector3D* mNormals;
|
||||
|
||||
/** Replacement for aiMesh::mTangents. */
|
||||
C_STRUCT aiVector3D* mTangents;
|
||||
|
||||
/** Replacement for aiMesh::mBitangents. */
|
||||
C_STRUCT aiVector3D* mBitangents;
|
||||
|
||||
/** Replacement for aiMesh::mColors */
|
||||
C_STRUCT aiColor4D* mColors[AI_MAX_NUMBER_OF_COLOR_SETS];
|
||||
|
||||
/** Replacement for aiMesh::mTextureCoords */
|
||||
C_STRUCT aiVector3D* mTextureCoords[AI_MAX_NUMBER_OF_TEXTURECOORDS];
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
aiAnimMesh()
|
||||
: mVertices()
|
||||
, mNormals()
|
||||
, mTangents()
|
||||
, mBitangents()
|
||||
{
|
||||
// fixme consider moving this to the ctor initializer list as well
|
||||
for( unsigned int a = 0; a < AI_MAX_NUMBER_OF_TEXTURECOORDS; a++){
|
||||
mTextureCoords[a] = NULL;
|
||||
}
|
||||
for( unsigned int a = 0; a < AI_MAX_NUMBER_OF_COLOR_SETS; a++) {
|
||||
mColors[a] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
~aiAnimMesh()
|
||||
{
|
||||
delete [] mVertices;
|
||||
delete [] mNormals;
|
||||
delete [] mTangents;
|
||||
delete [] mBitangents;
|
||||
for( unsigned int a = 0; a < AI_MAX_NUMBER_OF_TEXTURECOORDS; a++) {
|
||||
delete [] mTextureCoords[a];
|
||||
}
|
||||
for( unsigned int a = 0; a < AI_MAX_NUMBER_OF_COLOR_SETS; a++) {
|
||||
delete [] mColors[a];
|
||||
}
|
||||
}
|
||||
|
||||
/** Check whether the anim mesh overrides the vertex positions
|
||||
* of its host mesh*/
|
||||
bool HasPositions() const {
|
||||
return mVertices != NULL;
|
||||
}
|
||||
|
||||
/** Check whether the anim mesh overrides the vertex normals
|
||||
* of its host mesh*/
|
||||
bool HasNormals() const {
|
||||
return mNormals != NULL;
|
||||
}
|
||||
|
||||
/** Check whether the anim mesh overrides the vertex tangents
|
||||
* and bitangents of its host mesh. As for aiMesh,
|
||||
* tangents and bitangents always go together. */
|
||||
bool HasTangentsAndBitangents() const {
|
||||
return mTangents != NULL;
|
||||
}
|
||||
|
||||
/** Check whether the anim mesh overrides a particular
|
||||
* set of vertex colors on his host mesh.
|
||||
* @param pIndex 0<index<AI_MAX_NUMBER_OF_COLOR_SETS */
|
||||
bool HasVertexColors( unsigned int pIndex) const {
|
||||
return pIndex >= AI_MAX_NUMBER_OF_COLOR_SETS ? false : mColors[pIndex] != NULL;
|
||||
}
|
||||
|
||||
/** Check whether the anim mesh overrides a particular
|
||||
* set of texture coordinates on his host mesh.
|
||||
* @param pIndex 0<index<AI_MAX_NUMBER_OF_TEXTURECOORDS */
|
||||
bool HasTextureCoords( unsigned int pIndex) const {
|
||||
return pIndex >= AI_MAX_NUMBER_OF_TEXTURECOORDS ? false : mTextureCoords[pIndex] != NULL;
|
||||
}
|
||||
|
||||
#endif
|
||||
};
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
/** @brief A mesh represents a geometry or model with a single material.
|
||||
*
|
||||
|
@ -453,6 +557,14 @@ struct aiMesh
|
|||
**/
|
||||
aiString mName;
|
||||
|
||||
/** The number of attachment meshes */
|
||||
unsigned int mNumAnimMeshes;
|
||||
|
||||
/** Attachment meshes for this mesh, for vertex-based animation.
|
||||
* Attachment meshes carry replacement data for some of the
|
||||
* mesh'es vertex components (usually positions, normals). */
|
||||
C_STRUCT aiAnimMesh** mAnimMeshes;
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
//! Default constructor. Initializes all members to 0
|
||||
|
@ -460,10 +572,12 @@ struct aiMesh
|
|||
{
|
||||
mNumVertices = 0;
|
||||
mNumFaces = 0;
|
||||
mNumAnimMeshes = 0;
|
||||
mPrimitiveTypes = 0;
|
||||
mVertices = NULL; mFaces = NULL;
|
||||
mNormals = NULL; mTangents = NULL;
|
||||
mBitangents = NULL;
|
||||
mAnimMeshes = NULL;
|
||||
for( unsigned int a = 0; a < AI_MAX_NUMBER_OF_TEXTURECOORDS; a++)
|
||||
{
|
||||
mNumUVComponents[a] = 0;
|
||||
|
@ -482,24 +596,33 @@ struct aiMesh
|
|||
delete [] mNormals;
|
||||
delete [] mTangents;
|
||||
delete [] mBitangents;
|
||||
for( unsigned int a = 0; a < AI_MAX_NUMBER_OF_TEXTURECOORDS; a++)
|
||||
for( unsigned int a = 0; a < AI_MAX_NUMBER_OF_TEXTURECOORDS; a++) {
|
||||
delete [] mTextureCoords[a];
|
||||
for( unsigned int a = 0; a < AI_MAX_NUMBER_OF_COLOR_SETS; a++)
|
||||
}
|
||||
for( unsigned int a = 0; a < AI_MAX_NUMBER_OF_COLOR_SETS; a++) {
|
||||
delete [] mColors[a];
|
||||
}
|
||||
|
||||
// DO NOT REMOVE THIS ADDITIONAL CHECK
|
||||
if (mNumBones && mBones)
|
||||
{
|
||||
for( unsigned int a = 0; a < mNumBones; a++)
|
||||
if (mNumBones && mBones) {
|
||||
for( unsigned int a = 0; a < mNumBones; a++) {
|
||||
delete mBones[a];
|
||||
}
|
||||
delete [] mBones;
|
||||
}
|
||||
if (mNumAnimMeshes && mAnimMeshes) {
|
||||
for( unsigned int a = 0; a < mNumAnimMeshes; a++) {
|
||||
delete mAnimMeshes[a];
|
||||
}
|
||||
delete [] mBones;
|
||||
}
|
||||
|
||||
delete [] mFaces;
|
||||
}
|
||||
|
||||
//! Check whether the mesh contains positions. If no special scene flags
|
||||
//! (such as AI_SCENE_FLAGS_ANIM_SKELETON_ONLY) are set this will
|
||||
//! always return true
|
||||
//! Check whether the mesh contains positions. Provided no special
|
||||
//! scene flags are set (such as AI_SCENE_FLAGS_ANIM_SKELETON_ONLY),
|
||||
//! this will always be true
|
||||
bool HasPositions() const
|
||||
{ return mVertices != NULL && mNumVertices > 0; }
|
||||
|
||||
|
@ -562,6 +685,7 @@ struct aiMesh
|
|||
#endif // __cplusplus
|
||||
};
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif //! extern "C"
|
||||
|
|
Loading…
Reference in New Issue