1 /*
2 ---------------------------------------------------------------------------
3 Open Asset Import Library (assimp)
4 ---------------------------------------------------------------------------
5 
6 Copyright (c) 2006-2019, assimp team
7 
8 
9 All rights reserved.
10 
11 Redistribution and use of this software in source and binary forms,
12 with or without modification, are permitted provided that the following
13 conditions 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 
29 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
30 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
31 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
32 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
33 OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
34 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
35 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
36 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
37 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
38 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
39 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
40 ---------------------------------------------------------------------------
41 */
42 
43 /** @file mesh.h
44  *  @brief Declares the data structures in which the imported geometry is
45     returned by ASSIMP: aiMesh, aiFace and aiBone data structures.
46  */
47 #pragma once
48 #ifndef AI_MESH_H_INC
49 #define AI_MESH_H_INC
50 
51 #ifdef __GNUC__
52 #   pragma GCC system_header
53 #endif
54 
55 #include <assimp/types.h>
56 #include <assimp/aabb.h>
57 
58 #ifdef __cplusplus
59 extern "C" {
60 #endif
61 
62 // ---------------------------------------------------------------------------
63 // Limits. These values are required to match the settings Assimp was
64 // compiled against. Therefore, do not redefine them unless you build the
65 // library from source using the same definitions.
66 // ---------------------------------------------------------------------------
67 
68 /** @def AI_MAX_FACE_INDICES
69  *  Maximum number of indices per face (polygon). */
70 
71 #ifndef AI_MAX_FACE_INDICES
72 #   define AI_MAX_FACE_INDICES 0x7fff
73 #endif
74 
75 /** @def AI_MAX_BONE_WEIGHTS
76  *  Maximum number of indices per face (polygon). */
77 
78 #ifndef AI_MAX_BONE_WEIGHTS
79 #   define AI_MAX_BONE_WEIGHTS 0x7fffffff
80 #endif
81 
82 /** @def AI_MAX_VERTICES
83  *  Maximum number of vertices per mesh.  */
84 
85 #ifndef AI_MAX_VERTICES
86 #   define AI_MAX_VERTICES 0x7fffffff
87 #endif
88 
89 /** @def AI_MAX_FACES
90  *  Maximum number of faces per mesh. */
91 
92 #ifndef AI_MAX_FACES
93 #   define AI_MAX_FACES 0x7fffffff
94 #endif
95 
96 /** @def AI_MAX_NUMBER_OF_COLOR_SETS
97  *  Supported number of vertex color sets per mesh. */
98 
99 #ifndef AI_MAX_NUMBER_OF_COLOR_SETS
100 #   define AI_MAX_NUMBER_OF_COLOR_SETS 0x8
101 #endif // !! AI_MAX_NUMBER_OF_COLOR_SETS
102 
103 /** @def AI_MAX_NUMBER_OF_TEXTURECOORDS
104  *  Supported number of texture coord sets (UV(W) channels) per mesh */
105 
106 #ifndef AI_MAX_NUMBER_OF_TEXTURECOORDS
107 #   define AI_MAX_NUMBER_OF_TEXTURECOORDS 0x8
108 #endif // !! AI_MAX_NUMBER_OF_TEXTURECOORDS
109 
110 // ---------------------------------------------------------------------------
111 /** @brief A single face in a mesh, referring to multiple vertices.
112  *
113  * If mNumIndices is 3, we call the face 'triangle', for mNumIndices > 3
114  * it's called 'polygon' (hey, that's just a definition!).
115  * <br>
116  * aiMesh::mPrimitiveTypes can be queried to quickly examine which types of
117  * primitive are actually present in a mesh. The #aiProcess_SortByPType flag
118  * executes a special post-processing algorithm which splits meshes with
119  * *different* primitive types mixed up (e.g. lines and triangles) in several
120  * 'clean' submeshes. Furthermore there is a configuration option (
121  * #AI_CONFIG_PP_SBP_REMOVE) to force #aiProcess_SortByPType to remove
122  * specific kinds of primitives from the imported scene, completely and forever.
123  * In many cases you'll probably want to set this setting to
124  * @code
125  * aiPrimitiveType_LINE|aiPrimitiveType_POINT
126  * @endcode
127  * Together with the #aiProcess_Triangulate flag you can then be sure that
128  * #aiFace::mNumIndices is always 3.
129  * @note Take a look at the @link data Data Structures page @endlink for
130  * more information on the layout and winding order of a face.
131  */
132 struct aiFace
133 {
134     //! Number of indices defining this face.
135     //! The maximum value for this member is #AI_MAX_FACE_INDICES.
136     unsigned int mNumIndices;
137 
138     //! Pointer to the indices array. Size of the array is given in numIndices.
139     unsigned int* mIndices;
140 
141 #ifdef __cplusplus
142 
143     //! Default constructor
aiFaceaiFace144     aiFace() AI_NO_EXCEPT
145     : mNumIndices( 0 )
146     , mIndices( nullptr ) {
147         // empty
148     }
149 
150     //! Default destructor. Delete the index array
~aiFaceaiFace151     ~aiFace()
152     {
153         delete [] mIndices;
154     }
155 
156     //! Copy constructor. Copy the index array
aiFaceaiFace157     aiFace( const aiFace& o)
158     : mNumIndices(0)
159     , mIndices( nullptr ) {
160         *this = o;
161     }
162 
163     //! Assignment operator. Copy the index array
164     aiFace& operator = ( const aiFace& o) {
165         if (&o == this) {
166             return *this;
167         }
168 
169         delete[] mIndices;
170         mNumIndices = o.mNumIndices;
171         if (mNumIndices) {
172             mIndices = new unsigned int[mNumIndices];
173             ::memcpy( mIndices, o.mIndices, mNumIndices * sizeof( unsigned int));
174         } else {
175             mIndices = nullptr;
176         }
177 
178         return *this;
179     }
180 
181     //! Comparison operator. Checks whether the index array
182     //! of two faces is identical
183     bool operator== (const aiFace& o) const {
184         if (mIndices == o.mIndices) {
185             return true;
186         }
187 
188         if (nullptr != mIndices && mNumIndices != o.mNumIndices) {
189             return false;
190         }
191 
192         if (nullptr == mIndices) {
193             return false;
194         }
195 
196         for (unsigned int i = 0; i < this->mNumIndices; ++i) {
197             if (mIndices[i] != o.mIndices[i]) {
198                 return false;
199             }
200         }
201 
202         return true;
203     }
204 
205     //! Inverse comparison operator. Checks whether the index
206     //! array of two faces is NOT identical
207     bool operator != (const aiFace& o) const {
208         return !(*this == o);
209     }
210 #endif // __cplusplus
211 }; // struct aiFace
212 
213 
214 // ---------------------------------------------------------------------------
215 /** @brief A single influence of a bone on a vertex.
216  */
217 struct aiVertexWeight {
218     //! Index of the vertex which is influenced by the bone.
219     unsigned int mVertexId;
220 
221     //! The strength of the influence in the range (0...1).
222     //! The influence from all bones at one vertex amounts to 1.
223     float mWeight;
224 
225 #ifdef __cplusplus
226 
227     //! Default constructor
aiVertexWeightaiVertexWeight228     aiVertexWeight() AI_NO_EXCEPT
229     : mVertexId(0)
230     , mWeight(0.0f) {
231         // empty
232     }
233 
234     //! Initialization from a given index and vertex weight factor
235     //! \param pID ID
236     //! \param pWeight Vertex weight factor
aiVertexWeightaiVertexWeight237     aiVertexWeight( unsigned int pID, float pWeight )
238     : mVertexId( pID )
239     , mWeight( pWeight ) {
240         // empty
241     }
242 
243     bool operator == ( const aiVertexWeight &rhs ) const {
244         return ( mVertexId == rhs.mVertexId && mWeight == rhs.mWeight );
245     }
246 
247     bool operator != ( const aiVertexWeight &rhs ) const {
248         return ( *this == rhs );
249     }
250 
251 #endif // __cplusplus
252 };
253 
254 
255 // Forward declare aiNode (pointer use only)
256 struct aiNode;
257 
258 // ---------------------------------------------------------------------------
259 /** @brief A single bone of a mesh.
260  *
261  *  A bone has a name by which it can be found in the frame hierarchy and by
262  *  which it can be addressed by animations. In addition it has a number of
263  *  influences on vertices, and a matrix relating the mesh position to the
264  *  position of the bone at the time of binding.
265  */
266 struct aiBone {
267     //! The name of the bone.
268     C_STRUCT aiString mName;
269 
270     //! The number of vertices affected by this bone.
271     //! The maximum value for this member is #AI_MAX_BONE_WEIGHTS.
272     unsigned int mNumWeights;
273 
274 #ifndef ASSIMP_BUILD_NO_ARMATUREPOPULATE_PROCESS
275     // The bone armature node - used for skeleton conversion
276     // you must enable aiProcess_PopulateArmatureData to populate this
277     C_STRUCT aiNode* mArmature;
278 
279     // The bone node in the scene - used for skeleton conversion
280     // you must enable aiProcess_PopulateArmatureData to populate this
281     C_STRUCT aiNode* mNode;
282 
283 #endif
284     //! The influence weights of this bone, by vertex index.
285     C_STRUCT aiVertexWeight* mWeights;
286 
287     /** Matrix that transforms from bone space to mesh space in bind pose.
288      *
289      * This matrix describes the position of the mesh
290      * in the local space of this bone when the skeleton was bound.
291      * Thus it can be used directly to determine a desired vertex position,
292      * given the world-space transform of the bone when animated,
293      * and the position of the vertex in mesh space.
294      *
295      * It is sometimes called an inverse-bind matrix,
296      * or inverse bind pose matrix.
297      */
298     C_STRUCT aiMatrix4x4 mOffsetMatrix;
299 
300 #ifdef __cplusplus
301 
302     //! Default constructor
aiBoneaiBone303     aiBone() AI_NO_EXCEPT
304     : mName()
305     , mNumWeights( 0 )
306     , mWeights( nullptr )
307     , mOffsetMatrix() {
308         // empty
309     }
310 
311     //! Copy constructor
aiBoneaiBone312     aiBone(const aiBone& other)
313     : mName( other.mName )
314     , mNumWeights( other.mNumWeights )
315     , mWeights(nullptr)
316     , mOffsetMatrix( other.mOffsetMatrix ) {
317         if (other.mWeights && other.mNumWeights) {
318             mWeights = new aiVertexWeight[mNumWeights];
319             ::memcpy(mWeights,other.mWeights,mNumWeights * sizeof(aiVertexWeight));
320         }
321     }
322 
323 
324     //! Assignment operator
325     aiBone &operator=(const aiBone& other) {
326         if (this == &other) {
327             return *this;
328         }
329 
330         mName         = other.mName;
331         mNumWeights   = other.mNumWeights;
332         mOffsetMatrix = other.mOffsetMatrix;
333 
334         if (other.mWeights && other.mNumWeights)
335         {
336             if (mWeights) {
337                 delete[] mWeights;
338             }
339 
340             mWeights = new aiVertexWeight[mNumWeights];
341             ::memcpy(mWeights,other.mWeights,mNumWeights * sizeof(aiVertexWeight));
342         }
343 
344         return *this;
345     }
346 
347     bool operator == ( const aiBone &rhs ) const {
348         if ( mName != rhs.mName || mNumWeights != rhs.mNumWeights ) {
349             return false;
350         }
351 
352         for ( size_t i = 0; i < mNumWeights; ++i ) {
353             if ( mWeights[ i ] != rhs.mWeights[ i ] ) {
354                 return false;
355             }
356         }
357 
358         return true;
359     }
360     //! Destructor - deletes the array of vertex weights
~aiBoneaiBone361     ~aiBone() {
362         delete [] mWeights;
363     }
364 #endif // __cplusplus
365 };
366 
367 
368 // ---------------------------------------------------------------------------
369 /** @brief Enumerates the types of geometric primitives supported by Assimp.
370  *
371  *  @see aiFace Face data structure
372  *  @see aiProcess_SortByPType Per-primitive sorting of meshes
373  *  @see aiProcess_Triangulate Automatic triangulation
374  *  @see AI_CONFIG_PP_SBP_REMOVE Removal of specific primitive types.
375  */
376 enum aiPrimitiveType
377 {
378     /** A point primitive.
379      *
380      * This is just a single vertex in the virtual world,
381      * #aiFace contains just one index for such a primitive.
382      */
383     aiPrimitiveType_POINT       = 0x1,
384 
385     /** A line primitive.
386      *
387      * This is a line defined through a start and an end position.
388      * #aiFace contains exactly two indices for such a primitive.
389      */
390     aiPrimitiveType_LINE        = 0x2,
391 
392     /** A triangular primitive.
393      *
394      * A triangle consists of three indices.
395      */
396     aiPrimitiveType_TRIANGLE    = 0x4,
397 
398     /** A higher-level polygon with more than 3 edges.
399      *
400      * A triangle is a polygon, but polygon in this context means
401      * "all polygons that are not triangles". The "Triangulate"-Step
402      * is provided for your convenience, it splits all polygons in
403      * triangles (which are much easier to handle).
404      */
405     aiPrimitiveType_POLYGON     = 0x8,
406 
407 
408     /** This value is not used. It is just here to force the
409      *  compiler to map this enum to a 32 Bit integer.
410      */
411 #ifndef SWIG
412     _aiPrimitiveType_Force32Bit = INT_MAX
413 #endif
414 }; //! enum aiPrimitiveType
415 
416 // Get the #aiPrimitiveType flag for a specific number of face indices
417 #define AI_PRIMITIVE_TYPE_FOR_N_INDICES(n) \
418     ((n) > 3 ? aiPrimitiveType_POLYGON : (aiPrimitiveType)(1u << ((n)-1)))
419 
420 
421 
422 // ---------------------------------------------------------------------------
423 /** @brief An AnimMesh is an attachment to an #aiMesh stores per-vertex
424  *  animations for a particular frame.
425  *
426  *  You may think of an #aiAnimMesh as a `patch` for the host mesh, which
427  *  replaces only certain vertex data streams at a particular time.
428  *  Each mesh stores n attached attached meshes (#aiMesh::mAnimMeshes).
429  *  The actual relationship between the time line and anim meshes is
430  *  established by #aiMeshAnim, which references singular mesh attachments
431  *  by their ID and binds them to a time offset.
432 */
433 struct aiAnimMesh
434 {
435     /**Anim Mesh name */
436     C_STRUCT aiString mName;
437 
438     /** Replacement for aiMesh::mVertices. If this array is non-nullptr,
439      *  it *must* contain mNumVertices entries. The corresponding
440      *  array in the host mesh must be non-nullptr as well - animation
441      *  meshes may neither add or nor remove vertex components (if
442      *  a replacement array is nullptr and the corresponding source
443      *  array is not, the source data is taken instead)*/
444     C_STRUCT aiVector3D* mVertices;
445 
446     /** Replacement for aiMesh::mNormals.  */
447     C_STRUCT aiVector3D* mNormals;
448 
449     /** Replacement for aiMesh::mTangents. */
450     C_STRUCT aiVector3D* mTangents;
451 
452     /** Replacement for aiMesh::mBitangents. */
453     C_STRUCT aiVector3D* mBitangents;
454 
455     /** Replacement for aiMesh::mColors */
456     C_STRUCT aiColor4D* mColors[AI_MAX_NUMBER_OF_COLOR_SETS];
457 
458     /** Replacement for aiMesh::mTextureCoords */
459     C_STRUCT aiVector3D* mTextureCoords[AI_MAX_NUMBER_OF_TEXTURECOORDS];
460 
461     /** The number of vertices in the aiAnimMesh, and thus the length of all
462      * the member arrays.
463      *
464      * This has always the same value as the mNumVertices property in the
465      * corresponding aiMesh. It is duplicated here merely to make the length
466      * of the member arrays accessible even if the aiMesh is not known, e.g.
467      * from language bindings.
468      */
469     unsigned int mNumVertices;
470 
471     /**
472      * Weight of the AnimMesh.
473      */
474     float mWeight;
475 
476 #ifdef __cplusplus
477 
aiAnimMeshaiAnimMesh478     aiAnimMesh() AI_NO_EXCEPT
479         : mVertices( nullptr )
480         , mNormals(nullptr)
481         , mTangents(nullptr)
482         , mBitangents(nullptr)
483         , mColors()
484         , mTextureCoords()
485         , mNumVertices( 0 )
486         , mWeight( 0.0f )
487     {
488         // fixme consider moving this to the ctor initializer list as well
489         for( unsigned int a = 0; a < AI_MAX_NUMBER_OF_TEXTURECOORDS; a++){
490             mTextureCoords[a] = nullptr;
491         }
492         for( unsigned int a = 0; a < AI_MAX_NUMBER_OF_COLOR_SETS; a++) {
493             mColors[a] = nullptr;
494         }
495     }
496 
~aiAnimMeshaiAnimMesh497     ~aiAnimMesh()
498     {
499         delete [] mVertices;
500         delete [] mNormals;
501         delete [] mTangents;
502         delete [] mBitangents;
503         for( unsigned int a = 0; a < AI_MAX_NUMBER_OF_TEXTURECOORDS; a++) {
504             delete [] mTextureCoords[a];
505         }
506         for( unsigned int a = 0; a < AI_MAX_NUMBER_OF_COLOR_SETS; a++) {
507             delete [] mColors[a];
508         }
509     }
510 
511     /** Check whether the anim mesh overrides the vertex positions
512      *  of its host mesh*/
HasPositionsaiAnimMesh513     bool HasPositions() const {
514         return mVertices != nullptr;
515     }
516 
517     /** Check whether the anim mesh overrides the vertex normals
518      *  of its host mesh*/
HasNormalsaiAnimMesh519     bool HasNormals() const {
520         return mNormals != nullptr;
521     }
522 
523     /** Check whether the anim mesh overrides the vertex tangents
524      *  and bitangents of its host mesh. As for aiMesh,
525      *  tangents and bitangents always go together. */
HasTangentsAndBitangentsaiAnimMesh526     bool HasTangentsAndBitangents() const {
527         return mTangents != nullptr;
528     }
529 
530     /** Check whether the anim mesh overrides a particular
531      * set of vertex colors on his host mesh.
532      *  @param pIndex 0<index<AI_MAX_NUMBER_OF_COLOR_SETS */
HasVertexColorsaiAnimMesh533     bool HasVertexColors( unsigned int pIndex) const    {
534         return pIndex >= AI_MAX_NUMBER_OF_COLOR_SETS ? false : mColors[pIndex] != nullptr;
535     }
536 
537     /** Check whether the anim mesh overrides a particular
538      * set of texture coordinates on his host mesh.
539      *  @param pIndex 0<index<AI_MAX_NUMBER_OF_TEXTURECOORDS */
HasTextureCoordsaiAnimMesh540     bool HasTextureCoords( unsigned int pIndex) const   {
541         return pIndex >= AI_MAX_NUMBER_OF_TEXTURECOORDS ? false : mTextureCoords[pIndex] != nullptr;
542     }
543 
544 #endif
545 };
546 
547 // ---------------------------------------------------------------------------
548 /** @brief Enumerates the methods of mesh morphing supported by Assimp.
549  */
550 enum aiMorphingMethod
551 {
552     /** Interpolation between morph targets */
553     aiMorphingMethod_VERTEX_BLEND       = 0x1,
554 
555     /** Normalized morphing between morph targets  */
556     aiMorphingMethod_MORPH_NORMALIZED   = 0x2,
557 
558     /** Relative morphing between morph targets  */
559     aiMorphingMethod_MORPH_RELATIVE     = 0x3,
560 
561     /** This value is not used. It is just here to force the
562      *  compiler to map this enum to a 32 Bit integer.
563      */
564 #ifndef SWIG
565     _aiMorphingMethod_Force32Bit = INT_MAX
566 #endif
567 }; //! enum aiMorphingMethod
568 
569 // ---------------------------------------------------------------------------
570 /** @brief A mesh represents a geometry or model with a single material.
571 *
572 * It usually consists of a number of vertices and a series of primitives/faces
573 * referencing the vertices. In addition there might be a series of bones, each
574 * of them addressing a number of vertices with a certain weight. Vertex data
575 * is presented in channels with each channel containing a single per-vertex
576 * information such as a set of texture coords or a normal vector.
577 * If a data pointer is non-null, the corresponding data stream is present.
578 * From C++-programs you can also use the comfort functions Has*() to
579 * test for the presence of various data streams.
580 *
581 * A Mesh uses only a single material which is referenced by a material ID.
582 * @note The mPositions member is usually not optional. However, vertex positions
583 * *could* be missing if the #AI_SCENE_FLAGS_INCOMPLETE flag is set in
584 * @code
585 * aiScene::mFlags
586 * @endcode
587 */
588 struct aiMesh
589 {
590     /** Bitwise combination of the members of the #aiPrimitiveType enum.
591      * This specifies which types of primitives are present in the mesh.
592      * The "SortByPrimitiveType"-Step can be used to make sure the
593      * output meshes consist of one primitive type each.
594      */
595     unsigned int mPrimitiveTypes;
596 
597     /** The number of vertices in this mesh.
598     * This is also the size of all of the per-vertex data arrays.
599     * The maximum value for this member is #AI_MAX_VERTICES.
600     */
601     unsigned int mNumVertices;
602 
603     /** The number of primitives (triangles, polygons, lines) in this  mesh.
604     * This is also the size of the mFaces array.
605     * The maximum value for this member is #AI_MAX_FACES.
606     */
607     unsigned int mNumFaces;
608 
609     /** Vertex positions.
610     * This array is always present in a mesh. The array is
611     * mNumVertices in size.
612     */
613     C_STRUCT aiVector3D* mVertices;
614 
615     /** Vertex normals.
616     * The array contains normalized vectors, nullptr if not present.
617     * The array is mNumVertices in size. Normals are undefined for
618     * point and line primitives. A mesh consisting of points and
619     * lines only may not have normal vectors. Meshes with mixed
620     * primitive types (i.e. lines and triangles) may have normals,
621     * but the normals for vertices that are only referenced by
622     * point or line primitives are undefined and set to QNaN (WARN:
623     * qNaN compares to inequal to *everything*, even to qNaN itself.
624     * Using code like this to check whether a field is qnan is:
625     * @code
626     * #define IS_QNAN(f) (f != f)
627     * @endcode
628     * still dangerous because even 1.f == 1.f could evaluate to false! (
629     * remember the subtleties of IEEE754 artithmetics). Use stuff like
630     * @c fpclassify instead.
631     * @note Normal vectors computed by Assimp are always unit-length.
632     * However, this needn't apply for normals that have been taken
633     *   directly from the model file.
634     */
635     C_STRUCT aiVector3D* mNormals;
636 
637     /** Vertex tangents.
638     * The tangent of a vertex points in the direction of the positive
639     * X texture axis. The array contains normalized vectors, nullptr if
640     * not present. The array is mNumVertices in size. A mesh consisting
641     * of points and lines only may not have normal vectors. Meshes with
642     * mixed primitive types (i.e. lines and triangles) may have
643     * normals, but the normals for vertices that are only referenced by
644     * point or line primitives are undefined and set to qNaN.  See
645     * the #mNormals member for a detailed discussion of qNaNs.
646     * @note If the mesh contains tangents, it automatically also
647     * contains bitangents.
648     */
649     C_STRUCT aiVector3D* mTangents;
650 
651     /** Vertex bitangents.
652     * The bitangent of a vertex points in the direction of the positive
653     * Y texture axis. The array contains normalized vectors, nullptr if not
654     * present. The array is mNumVertices in size.
655     * @note If the mesh contains tangents, it automatically also contains
656     * bitangents.
657     */
658     C_STRUCT aiVector3D* mBitangents;
659 
660     /** Vertex color sets.
661     * A mesh may contain 0 to #AI_MAX_NUMBER_OF_COLOR_SETS vertex
662     * colors per vertex. nullptr if not present. Each array is
663     * mNumVertices in size if present.
664     */
665     C_STRUCT aiColor4D* mColors[AI_MAX_NUMBER_OF_COLOR_SETS];
666 
667     /** Vertex texture coords, also known as UV channels.
668     * A mesh may contain 0 to AI_MAX_NUMBER_OF_TEXTURECOORDS per
669     * vertex. nullptr if not present. The array is mNumVertices in size.
670     */
671     C_STRUCT aiVector3D* mTextureCoords[AI_MAX_NUMBER_OF_TEXTURECOORDS];
672 
673     /** Specifies the number of components for a given UV channel.
674     * Up to three channels are supported (UVW, for accessing volume
675     * or cube maps). If the value is 2 for a given channel n, the
676     * component p.z of mTextureCoords[n][p] is set to 0.0f.
677     * If the value is 1 for a given channel, p.y is set to 0.0f, too.
678     * @note 4D coords are not supported
679     */
680     unsigned int mNumUVComponents[AI_MAX_NUMBER_OF_TEXTURECOORDS];
681 
682     /** The faces the mesh is constructed from.
683     * Each face refers to a number of vertices by their indices.
684     * This array is always present in a mesh, its size is given
685     * in mNumFaces. If the #AI_SCENE_FLAGS_NON_VERBOSE_FORMAT
686     * is NOT set each face references an unique set of vertices.
687     */
688     C_STRUCT aiFace* mFaces;
689 
690     /** The number of bones this mesh contains.
691     * Can be 0, in which case the mBones array is nullptr.
692     */
693     unsigned int mNumBones;
694 
695     /** The bones of this mesh.
696     * A bone consists of a name by which it can be found in the
697     * frame hierarchy and a set of vertex weights.
698     */
699     C_STRUCT aiBone** mBones;
700 
701     /** The material used by this mesh.
702      * A mesh uses only a single material. If an imported model uses
703      * multiple materials, the import splits up the mesh. Use this value
704      * as index into the scene's material list.
705      */
706     unsigned int mMaterialIndex;
707 
708     /** Name of the mesh. Meshes can be named, but this is not a
709      *  requirement and leaving this field empty is totally fine.
710      *  There are mainly three uses for mesh names:
711      *   - some formats name nodes and meshes independently.
712      *   - importers tend to split meshes up to meet the
713      *      one-material-per-mesh requirement. Assigning
714      *      the same (dummy) name to each of the result meshes
715      *      aids the caller at recovering the original mesh
716      *      partitioning.
717      *   - Vertex animations refer to meshes by their names.
718      **/
719     C_STRUCT aiString mName;
720 
721 
722     /** The number of attachment meshes. Note! Currently only works with Collada loader. */
723     unsigned int mNumAnimMeshes;
724 
725     /** Attachment meshes for this mesh, for vertex-based animation.
726      *  Attachment meshes carry replacement data for some of the
727      *  mesh'es vertex components (usually positions, normals).
728      *  Note! Currently only works with Collada loader.*/
729     C_STRUCT aiAnimMesh** mAnimMeshes;
730 
731     /**
732      *  Method of morphing when animeshes are specified.
733      */
734     unsigned int mMethod;
735 
736     /**
737      *
738      */
739     C_STRUCT aiAABB mAABB;
740 
741 #ifdef __cplusplus
742 
743     //! Default constructor. Initializes all members to 0
aiMeshaiMesh744     aiMesh() AI_NO_EXCEPT
745     : mPrimitiveTypes( 0 )
746     , mNumVertices( 0 )
747     , mNumFaces( 0 )
748     , mVertices( nullptr )
749     , mNormals(nullptr)
750     , mTangents(nullptr)
751     , mBitangents(nullptr)
752     , mColors()
753     , mTextureCoords()
754     , mNumUVComponents()
755     , mFaces(nullptr)
756     , mNumBones( 0 )
757     , mBones(nullptr)
758     , mMaterialIndex( 0 )
759     , mNumAnimMeshes( 0 )
760     , mAnimMeshes(nullptr)
761     , mMethod( 0 )
762     , mAABB() {
763         for( unsigned int a = 0; a < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++a ) {
764             mNumUVComponents[a] = 0;
765             mTextureCoords[a] = nullptr;
766         }
767 
768         for (unsigned int a = 0; a < AI_MAX_NUMBER_OF_COLOR_SETS; ++a) {
769             mColors[a] = nullptr;
770         }
771     }
772 
773     //! Deletes all storage allocated for the mesh
~aiMeshaiMesh774     ~aiMesh() {
775         delete [] mVertices;
776         delete [] mNormals;
777         delete [] mTangents;
778         delete [] mBitangents;
779         for( unsigned int a = 0; a < AI_MAX_NUMBER_OF_TEXTURECOORDS; a++) {
780             delete [] mTextureCoords[a];
781         }
782         for( unsigned int a = 0; a < AI_MAX_NUMBER_OF_COLOR_SETS; a++) {
783             delete [] mColors[a];
784         }
785 
786         // DO NOT REMOVE THIS ADDITIONAL CHECK
787         if (mNumBones && mBones)    {
788             for( unsigned int a = 0; a < mNumBones; a++) {
789                 if(mBones[a])
790                 {
791                     delete mBones[a];
792                 }
793             }
794             delete [] mBones;
795         }
796 
797         if (mNumAnimMeshes && mAnimMeshes)  {
798             for( unsigned int a = 0; a < mNumAnimMeshes; a++) {
799                 delete mAnimMeshes[a];
800             }
801             delete [] mAnimMeshes;
802         }
803 
804         delete [] mFaces;
805     }
806 
807     //! Check whether the mesh contains positions. Provided no special
808     //! scene flags are set, this will always be true
HasPositionsaiMesh809     bool HasPositions() const
810         { return mVertices != nullptr && mNumVertices > 0; }
811 
812     //! Check whether the mesh contains faces. If no special scene flags
813     //! are set this should always return true
HasFacesaiMesh814     bool HasFaces() const
815         { return mFaces != nullptr && mNumFaces > 0; }
816 
817     //! Check whether the mesh contains normal vectors
HasNormalsaiMesh818     bool HasNormals() const
819         { return mNormals != nullptr && mNumVertices > 0; }
820 
821     //! Check whether the mesh contains tangent and bitangent vectors
822     //! It is not possible that it contains tangents and no bitangents
823     //! (or the other way round). The existence of one of them
824     //! implies that the second is there, too.
HasTangentsAndBitangentsaiMesh825     bool HasTangentsAndBitangents() const
826         { return mTangents != nullptr && mBitangents != nullptr && mNumVertices > 0; }
827 
828     //! Check whether the mesh contains a vertex color set
829     //! \param pIndex Index of the vertex color set
HasVertexColorsaiMesh830     bool HasVertexColors( unsigned int pIndex) const {
831         if (pIndex >= AI_MAX_NUMBER_OF_COLOR_SETS) {
832             return false;
833         } else {
834             return mColors[pIndex] != nullptr && mNumVertices > 0;
835         }
836     }
837 
838     //! Check whether the mesh contains a texture coordinate set
839     //! \param pIndex Index of the texture coordinates set
HasTextureCoordsaiMesh840     bool HasTextureCoords( unsigned int pIndex) const {
841         if (pIndex >= AI_MAX_NUMBER_OF_TEXTURECOORDS) {
842             return false;
843         } else {
844             return mTextureCoords[pIndex] != nullptr && mNumVertices > 0;
845         }
846     }
847 
848     //! Get the number of UV channels the mesh contains
GetNumUVChannelsaiMesh849     unsigned int GetNumUVChannels() const {
850         unsigned int n( 0 );
851         while (n < AI_MAX_NUMBER_OF_TEXTURECOORDS && mTextureCoords[n]) {
852             ++n;
853         }
854 
855         return n;
856     }
857 
858     //! Get the number of vertex color channels the mesh contains
GetNumColorChannelsaiMesh859     unsigned int GetNumColorChannels() const {
860         unsigned int n(0);
861         while (n < AI_MAX_NUMBER_OF_COLOR_SETS && mColors[n]) {
862             ++n;
863         }
864         return n;
865     }
866 
867     //! Check whether the mesh contains bones
HasBonesaiMesh868     bool HasBones() const {
869         return mBones != nullptr && mNumBones > 0;
870     }
871 
872 #endif // __cplusplus
873 };
874 
875 #ifdef __cplusplus
876 }
877 #endif //! extern "C"
878 #endif // AI_MESH_H_INC
879 
880