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