1/*
2---------------------------------------------------------------------------
3Open Asset Import Library (assimp)
4---------------------------------------------------------------------------
5
6Copyright (c) 2006-2017, assimp team
7
8
9All rights reserved.
10
11Redistribution and use of this software in source and binary forms,
12with or without modification, are permitted provided that the following
13conditions are met:
14
15* Redistributions of source code must retain the above
16 copyright notice, this list of conditions and the
17 following disclaimer.
18
19* Redistributions in binary form must reproduce the above
20 copyright notice, this list of conditions and the
21 following disclaimer in the documentation and/or other
22 materials provided with the distribution.
23
24* Neither the name of the assimp team, nor the names of its
25 contributors may be used to endorse or promote products
26 derived from this software without specific prior
27 written permission of the assimp team.
28
29THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
30"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
31LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
32A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
33OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
34SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
35LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
36DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
37THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
38(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
39OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
40---------------------------------------------------------------------------
41*/
42
43/**
44 * @file anim.h
45 * @brief Defines the data structures in which the imported animations
46 * are returned.
47 */
48#pragma once
49#ifndef AI_ANIM_H_INC
50#define AI_ANIM_H_INC
51
52#include <assimp/types.h>
53#include <assimp/quaternion.h>
54
55#ifdef __cplusplus
56extern "C" {
57#endif
58
59// ---------------------------------------------------------------------------
60/** A time-value pair specifying a certain 3D vector for the given time. */
61struct aiVectorKey
62{
63 /** The time of this key */
64 double mTime;
65
66 /** The value of this key */
67 C_STRUCT aiVector3D mValue;
68
69#ifdef __cplusplus
70
71 /// @brief The default constructor.
72 aiVectorKey()
73 : mTime( 0.0 )
74 , mValue() {
75 // empty
76 }
77
78 /// @brief Construction from a given time and key value.
79
80 aiVectorKey(double time, const aiVector3D& value)
81 : mTime (time)
82 , mValue (value)
83 {}
84
85 typedef aiVector3D elem_type;
86
87 // Comparison operators. For use with std::find();
88 bool operator == (const aiVectorKey& o) const {
89 return o.mValue == this->mValue;
90 }
91 bool operator != (const aiVectorKey& o) const {
92 return o.mValue != this->mValue;
93 }
94
95 // Relational operators. For use with std::sort();
96 bool operator < (const aiVectorKey& o) const {
97 return mTime < o.mTime;
98 }
99 bool operator > (const aiVectorKey& o) const {
100 return mTime > o.mTime;
101 }
102#endif // __cplusplus
103};
104
105// ---------------------------------------------------------------------------
106/** A time-value pair specifying a rotation for the given time.
107 * Rotations are expressed with quaternions. */
108struct aiQuatKey
109{
110 /** The time of this key */
111 double mTime;
112
113 /** The value of this key */
114 C_STRUCT aiQuaternion mValue;
115
116#ifdef __cplusplus
117 aiQuatKey()
118 : mTime( 0.0 )
119 , mValue() {
120 // empty
121 }
122
123 /** Construction from a given time and key value */
124 aiQuatKey(double time, const aiQuaternion& value)
125 : mTime (time)
126 , mValue (value)
127 {}
128
129 typedef aiQuaternion elem_type;
130
131 // Comparison operators. For use with std::find();
132 bool operator == (const aiQuatKey& o) const {
133 return o.mValue == this->mValue;
134 }
135 bool operator != (const aiQuatKey& o) const {
136 return o.mValue != this->mValue;
137 }
138
139 // Relational operators. For use with std::sort();
140 bool operator < (const aiQuatKey& o) const {
141 return mTime < o.mTime;
142 }
143 bool operator > (const aiQuatKey& o) const {
144 return mTime > o.mTime;
145 }
146#endif
147};
148
149// ---------------------------------------------------------------------------
150/** Binds a anim mesh to a specific point in time. */
151struct aiMeshKey
152{
153 /** The time of this key */
154 double mTime;
155
156 /** Index into the aiMesh::mAnimMeshes array of the
157 * mesh corresponding to the #aiMeshAnim hosting this
158 * key frame. The referenced anim mesh is evaluated
159 * according to the rules defined in the docs for #aiAnimMesh.*/
160 unsigned int mValue;
161
162#ifdef __cplusplus
163
164 aiMeshKey() {
165 }
166
167 /** Construction from a given time and key value */
168 aiMeshKey(double time, const unsigned int value)
169 : mTime (time)
170 , mValue (value)
171 {}
172
173 typedef unsigned int elem_type;
174
175 // Comparison operators. For use with std::find();
176 bool operator == (const aiMeshKey& o) const {
177 return o.mValue == this->mValue;
178 }
179 bool operator != (const aiMeshKey& o) const {
180 return o.mValue != this->mValue;
181 }
182
183 // Relational operators. For use with std::sort();
184 bool operator < (const aiMeshKey& o) const {
185 return mTime < o.mTime;
186 }
187 bool operator > (const aiMeshKey& o) const {
188 return mTime > o.mTime;
189 }
190
191#endif
192};
193
194// ---------------------------------------------------------------------------
195/** Binds a morph anim mesh to a specific point in time. */
196struct aiMeshMorphKey
197{
198 /** The time of this key */
199 double mTime;
200
201 /** The values and weights at the time of this key */
202 unsigned int *mValues;
203 double *mWeights;
204
205 /** The number of values and weights */
206 unsigned int mNumValuesAndWeights;
207#ifdef __cplusplus
208 aiMeshMorphKey()
209 : mTime(0.0)
210 , mValues(NULL)
211 , mWeights(NULL)
212 , mNumValuesAndWeights(0)
213 {
214
215 }
216
217 ~aiMeshMorphKey()
218 {
219 if (mNumValuesAndWeights && mValues && mWeights) {
220 delete [] mValues;
221 delete [] mWeights;
222 }
223 }
224#endif
225};
226
227// ---------------------------------------------------------------------------
228/** Defines how an animation channel behaves outside the defined time
229 * range. This corresponds to aiNodeAnim::mPreState and
230 * aiNodeAnim::mPostState.*/
231enum aiAnimBehaviour
232{
233 /** The value from the default node transformation is taken*/
234 aiAnimBehaviour_DEFAULT = 0x0,
235
236 /** The nearest key value is used without interpolation */
237 aiAnimBehaviour_CONSTANT = 0x1,
238
239 /** The value of the nearest two keys is linearly
240 * extrapolated for the current time value.*/
241 aiAnimBehaviour_LINEAR = 0x2,
242
243 /** The animation is repeated.
244 *
245 * If the animation key go from n to m and the current
246 * time is t, use the value at (t-n) % (|m-n|).*/
247 aiAnimBehaviour_REPEAT = 0x3,
248
249 /** This value is not used, it is just here to force the
250 * the compiler to map this enum to a 32 Bit integer */
251#ifndef SWIG
252 _aiAnimBehaviour_Force32Bit = INT_MAX
253#endif
254};
255
256// ---------------------------------------------------------------------------
257/** Describes the animation of a single node. The name specifies the
258 * bone/node which is affected by this animation channel. The keyframes
259 * are given in three separate series of values, one each for position,
260 * rotation and scaling. The transformation matrix computed from these
261 * values replaces the node's original transformation matrix at a
262 * specific time.
263 * This means all keys are absolute and not relative to the bone default pose.
264 * The order in which the transformations are applied is
265 * - as usual - scaling, rotation, translation.
266 *
267 * @note All keys are returned in their correct, chronological order.
268 * Duplicate keys don't pass the validation step. Most likely there
269 * will be no negative time values, but they are not forbidden also ( so
270 * implementations need to cope with them! ) */
271struct aiNodeAnim {
272 /** The name of the node affected by this animation. The node
273 * must exist and it must be unique.*/
274 C_STRUCT aiString mNodeName;
275
276 /** The number of position keys */
277 unsigned int mNumPositionKeys;
278
279 /** The position keys of this animation channel. Positions are
280 * specified as 3D vector. The array is mNumPositionKeys in size.
281 *
282 * If there are position keys, there will also be at least one
283 * scaling and one rotation key.*/
284 C_STRUCT aiVectorKey* mPositionKeys;
285
286 /** The number of rotation keys */
287 unsigned int mNumRotationKeys;
288
289 /** The rotation keys of this animation channel. Rotations are
290 * given as quaternions, which are 4D vectors. The array is
291 * mNumRotationKeys in size.
292 *
293 * If there are rotation keys, there will also be at least one
294 * scaling and one position key. */
295 C_STRUCT aiQuatKey* mRotationKeys;
296
297 /** The number of scaling keys */
298 unsigned int mNumScalingKeys;
299
300 /** The scaling keys of this animation channel. Scalings are
301 * specified as 3D vector. The array is mNumScalingKeys in size.
302 *
303 * If there are scaling keys, there will also be at least one
304 * position and one rotation key.*/
305 C_STRUCT aiVectorKey* mScalingKeys;
306
307 /** Defines how the animation behaves before the first
308 * key is encountered.
309 *
310 * The default value is aiAnimBehaviour_DEFAULT (the original
311 * transformation matrix of the affected node is used).*/
312 C_ENUM aiAnimBehaviour mPreState;
313
314 /** Defines how the animation behaves after the last
315 * key was processed.
316 *
317 * The default value is aiAnimBehaviour_DEFAULT (the original
318 * transformation matrix of the affected node is taken).*/
319 C_ENUM aiAnimBehaviour mPostState;
320
321#ifdef __cplusplus
322 aiNodeAnim()
323 : mNumPositionKeys( 0 )
324 , mPositionKeys( NULL )
325 , mNumRotationKeys( 0 )
326 , mRotationKeys( NULL )
327 , mNumScalingKeys( 0 )
328 , mScalingKeys( NULL )
329 , mPreState( aiAnimBehaviour_DEFAULT )
330 , mPostState( aiAnimBehaviour_DEFAULT ) {
331 // empty
332 }
333
334 ~aiNodeAnim() {
335 delete [] mPositionKeys;
336 delete [] mRotationKeys;
337 delete [] mScalingKeys;
338 }
339#endif // __cplusplus
340};
341
342// ---------------------------------------------------------------------------
343/** Describes vertex-based animations for a single mesh or a group of
344 * meshes. Meshes carry the animation data for each frame in their
345 * aiMesh::mAnimMeshes array. The purpose of aiMeshAnim is to
346 * define keyframes linking each mesh attachment to a particular
347 * point in time. */
348struct aiMeshAnim
349{
350 /** Name of the mesh to be animated. An empty string is not allowed,
351 * animated meshes need to be named (not necessarily uniquely,
352 * the name can basically serve as wild-card to select a group
353 * of meshes with similar animation setup)*/
354 C_STRUCT aiString mName;
355
356 /** Size of the #mKeys array. Must be 1, at least. */
357 unsigned int mNumKeys;
358
359 /** Key frames of the animation. May not be NULL. */
360 C_STRUCT aiMeshKey* mKeys;
361
362#ifdef __cplusplus
363
364 aiMeshAnim()
365 : mNumKeys()
366 , mKeys()
367 {}
368
369 ~aiMeshAnim()
370 {
371 delete[] mKeys;
372 }
373
374#endif
375};
376
377// ---------------------------------------------------------------------------
378/** Describes a morphing animation of a given mesh. */
379struct aiMeshMorphAnim
380{
381 /** Name of the mesh to be animated. An empty string is not allowed,
382 * animated meshes need to be named (not necessarily uniquely,
383 * the name can basically serve as wildcard to select a group
384 * of meshes with similar animation setup)*/
385 C_STRUCT aiString mName;
386
387 /** Size of the #mKeys array. Must be 1, at least. */
388 unsigned int mNumKeys;
389
390 /** Key frames of the animation. May not be NULL. */
391 C_STRUCT aiMeshMorphKey* mKeys;
392
393#ifdef __cplusplus
394
395 aiMeshMorphAnim()
396 : mNumKeys()
397 , mKeys()
398 {}
399
400 ~aiMeshMorphAnim()
401 {
402 delete[] mKeys;
403 }
404
405#endif
406};
407
408// ---------------------------------------------------------------------------
409/** An animation consists of key-frame data for a number of nodes. For
410 * each node affected by the animation a separate series of data is given.*/
411struct aiAnimation {
412 /** The name of the animation. If the modeling package this data was
413 * exported from does support only a single animation channel, this
414 * name is usually empty (length is zero). */
415 C_STRUCT aiString mName;
416
417 /** Duration of the animation in ticks. */
418 double mDuration;
419
420 /** Ticks per second. 0 if not specified in the imported file */
421 double mTicksPerSecond;
422
423 /** The number of bone animation channels. Each channel affects
424 * a single node. */
425 unsigned int mNumChannels;
426
427 /** The node animation channels. Each channel affects a single node.
428 * The array is mNumChannels in size. */
429 C_STRUCT aiNodeAnim** mChannels;
430
431
432 /** The number of mesh animation channels. Each channel affects
433 * a single mesh and defines vertex-based animation. */
434 unsigned int mNumMeshChannels;
435
436 /** The mesh animation channels. Each channel affects a single mesh.
437 * The array is mNumMeshChannels in size. */
438 C_STRUCT aiMeshAnim** mMeshChannels;
439
440 /** The number of mesh animation channels. Each channel affects
441 * a single mesh and defines morphing animation. */
442 unsigned int mNumMorphMeshChannels;
443
444 /** The morph mesh animation channels. Each channel affects a single mesh.
445 * The array is mNumMorphMeshChannels in size. */
446 C_STRUCT aiMeshMorphAnim **mMorphMeshChannels;
447
448#ifdef __cplusplus
449 aiAnimation()
450 : mDuration(-1.)
451 , mTicksPerSecond(0.)
452 , mNumChannels(0)
453 , mChannels(NULL)
454 , mNumMeshChannels(0)
455 , mMeshChannels(NULL)
456 , mNumMorphMeshChannels(0)
457 , mMorphMeshChannels(NULL) {
458 // empty
459 }
460
461 ~aiAnimation() {
462 // DO NOT REMOVE THIS ADDITIONAL CHECK
463 if ( mNumChannels && mChannels ) {
464 for( unsigned int a = 0; a < mNumChannels; a++) {
465 delete mChannels[ a ];
466 }
467
468 delete [] mChannels;
469 }
470 if (mNumMeshChannels && mMeshChannels) {
471 for( unsigned int a = 0; a < mNumMeshChannels; a++) {
472 delete mMeshChannels[a];
473 }
474
475 delete [] mMeshChannels;
476 }
477 if (mNumMorphMeshChannels && mMorphMeshChannels) {
478 for( unsigned int a = 0; a < mNumMorphMeshChannels; a++) {
479 delete mMorphMeshChannels[a];
480 }
481
482 delete [] mMorphMeshChannels;
483 }
484 }
485#endif // __cplusplus
486};
487
488#ifdef __cplusplus
489
490}
491
492/// @brief Some C++ utilities for inter- and extrapolation
493namespace Assimp {
494
495// ---------------------------------------------------------------------------
496/**
497 * @brief CPP-API: Utility class to simplify interpolations of various data types.
498 *
499 * The type of interpolation is chosen automatically depending on the
500 * types of the arguments.
501 */
502template <typename T>
503struct Interpolator
504{
505 // ------------------------------------------------------------------
506 /** @brief Get the result of the interpolation between a,b.
507 *
508 * The interpolation algorithm depends on the type of the operands.
509 * aiQuaternion's and aiQuatKey's SLERP, the rest does a simple
510 * linear interpolation. */
511 void operator () (T& out,const T& a, const T& b, ai_real d) const {
512 out = a + (b-a)*d;
513 }
514}; // ! Interpolator <T>
515
516//! @cond Never
517
518template <>
519struct Interpolator <aiQuaternion> {
520 void operator () (aiQuaternion& out,const aiQuaternion& a,
521 const aiQuaternion& b, ai_real d) const
522 {
523 aiQuaternion::Interpolate(out,a,b,d);
524 }
525}; // ! Interpolator <aiQuaternion>
526
527template <>
528struct Interpolator <unsigned int> {
529 void operator () (unsigned int& out,unsigned int a,
530 unsigned int b, ai_real d) const
531 {
532 out = d>0.5f ? b : a;
533 }
534}; // ! Interpolator <aiQuaternion>
535
536template <>
537struct Interpolator<aiVectorKey> {
538 void operator () (aiVector3D& out,const aiVectorKey& a,
539 const aiVectorKey& b, ai_real d) const
540 {
541 Interpolator<aiVector3D> ipl;
542 ipl(out,a.mValue,b.mValue,d);
543 }
544}; // ! Interpolator <aiVectorKey>
545
546template <>
547struct Interpolator<aiQuatKey> {
548 void operator () (aiQuaternion& out, const aiQuatKey& a,
549 const aiQuatKey& b, ai_real d) const
550 {
551 Interpolator<aiQuaternion> ipl;
552 ipl(out,a.mValue,b.mValue,d);
553 }
554}; // ! Interpolator <aiQuatKey>
555
556template <>
557struct Interpolator<aiMeshKey> {
558 void operator () (unsigned int& out, const aiMeshKey& a,
559 const aiMeshKey& b, ai_real d) const
560 {
561 Interpolator<unsigned int> ipl;
562 ipl(out,a.mValue,b.mValue,d);
563 }
564}; // ! Interpolator <aiQuatKey>
565
566//! @endcond
567
568} // ! end namespace Assimp
569
570#endif // __cplusplus
571
572#endif // AI_ANIM_H_INC
573