![]() |
|
|||
File indexing completed on 2025-02-21 09:30:09
0001 /* 0002 --------------------------------------------------------------------------- 0003 Open Asset Import Library (assimp) 0004 --------------------------------------------------------------------------- 0005 0006 Copyright (c) 2006-2024, assimp team 0007 0008 All rights reserved. 0009 0010 Redistribution and use of this software in source and binary forms, 0011 with or without modification, are permitted provided that the following 0012 conditions are met: 0013 0014 * Redistributions of source code must retain the above 0015 copyright notice, this list of conditions and the 0016 following disclaimer. 0017 0018 * Redistributions in binary form must reproduce the above 0019 copyright notice, this list of conditions and the 0020 following disclaimer in the documentation and/or other 0021 materials provided with the distribution. 0022 0023 * Neither the name of the assimp team, nor the names of its 0024 contributors may be used to endorse or promote products 0025 derived from this software without specific prior 0026 written permission of the assimp team. 0027 0028 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 0029 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 0030 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 0031 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 0032 OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 0033 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 0034 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 0035 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 0036 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 0037 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 0038 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 0039 --------------------------------------------------------------------------- 0040 */ 0041 0042 /** @file mesh.h 0043 * @brief Declares the data structures in which the imported geometry is 0044 returned by ASSIMP: aiMesh, aiFace and aiBone data structures. 0045 */ 0046 #pragma once 0047 #ifndef AI_MESH_H_INC 0048 #define AI_MESH_H_INC 0049 0050 #ifdef __GNUC__ 0051 #pragma GCC system_header 0052 #endif 0053 0054 #ifdef _MSC_VER 0055 #pragma warning(disable : 4351) 0056 #endif // _MSC_VER 0057 0058 #include <assimp/aabb.h> 0059 #include <assimp/types.h> 0060 0061 #ifdef __cplusplus 0062 #include <unordered_set> 0063 0064 extern "C" { 0065 #endif 0066 0067 // --------------------------------------------------------------------------- 0068 // Limits. These values are required to match the settings Assimp was 0069 // compiled against. Therefore, do not redefine them unless you build the 0070 // library from source using the same definitions. 0071 // --------------------------------------------------------------------------- 0072 0073 /** @def AI_MAX_FACE_INDICES 0074 * Maximum number of indices per face (polygon). */ 0075 0076 #ifndef AI_MAX_FACE_INDICES 0077 #define AI_MAX_FACE_INDICES 0x7fff 0078 #endif 0079 0080 /** @def AI_MAX_BONE_WEIGHTS 0081 * Maximum number of indices per face (polygon). */ 0082 0083 #ifndef AI_MAX_BONE_WEIGHTS 0084 #define AI_MAX_BONE_WEIGHTS 0x7fffffff 0085 #endif 0086 0087 /** @def AI_MAX_VERTICES 0088 * Maximum number of vertices per mesh. */ 0089 0090 #ifndef AI_MAX_VERTICES 0091 #define AI_MAX_VERTICES 0x7fffffff 0092 #endif 0093 0094 /** @def AI_MAX_FACES 0095 * Maximum number of faces per mesh. */ 0096 0097 #ifndef AI_MAX_FACES 0098 #define AI_MAX_FACES 0x7fffffff 0099 #endif 0100 0101 /** @def AI_MAX_NUMBER_OF_COLOR_SETS 0102 * Supported number of vertex color sets per mesh. */ 0103 0104 #ifndef AI_MAX_NUMBER_OF_COLOR_SETS 0105 #define AI_MAX_NUMBER_OF_COLOR_SETS 0x8 0106 #endif // !! AI_MAX_NUMBER_OF_COLOR_SETS 0107 0108 /** @def AI_MAX_NUMBER_OF_TEXTURECOORDS 0109 * Supported number of texture coord sets (UV(W) channels) per mesh */ 0110 0111 #ifndef AI_MAX_NUMBER_OF_TEXTURECOORDS 0112 #define AI_MAX_NUMBER_OF_TEXTURECOORDS 0x8 0113 #endif // !! AI_MAX_NUMBER_OF_TEXTURECOORDS 0114 0115 // --------------------------------------------------------------------------- 0116 /** 0117 * @brief A single face in a mesh, referring to multiple vertices. 0118 * 0119 * If mNumIndices is 3, we call the face 'triangle', for mNumIndices > 3 0120 * it's called 'polygon' (hey, that's just a definition!). 0121 * <br> 0122 * aiMesh::mPrimitiveTypes can be queried to quickly examine which types of 0123 * primitive are actually present in a mesh. The #aiProcess_SortByPType flag 0124 * executes a special post-processing algorithm which splits meshes with 0125 * *different* primitive types mixed up (e.g. lines and triangles) in several 0126 * 'clean' sub-meshes. Furthermore there is a configuration option ( 0127 * #AI_CONFIG_PP_SBP_REMOVE) to force #aiProcess_SortByPType to remove 0128 * specific kinds of primitives from the imported scene, completely and forever. 0129 * In many cases you'll probably want to set this setting to 0130 * @code 0131 * aiPrimitiveType_LINE|aiPrimitiveType_POINT 0132 * @endcode 0133 * Together with the #aiProcess_Triangulate flag you can then be sure that 0134 * #aiFace::mNumIndices is always 3. 0135 * @note Take a look at the @link data Data Structures page @endlink for 0136 * more information on the layout and winding order of a face. 0137 */ 0138 struct aiFace { 0139 //! Number of indices defining this face. 0140 //! The maximum value for this member is #AI_MAX_FACE_INDICES. 0141 unsigned int mNumIndices; 0142 0143 //! Pointer to the indices array. Size of the array is given in numIndices. 0144 unsigned int *mIndices; 0145 0146 #ifdef __cplusplus 0147 0148 //! @brief Default constructor. 0149 aiFace() AI_NO_EXCEPT 0150 : mNumIndices(0), 0151 mIndices(nullptr) { 0152 // empty 0153 } 0154 0155 //! @brief Default destructor. Delete the index array 0156 ~aiFace() { 0157 delete[] mIndices; 0158 } 0159 0160 //! @brief Copy constructor. Copy the index array 0161 aiFace(const aiFace &o) : 0162 mNumIndices(0), mIndices(nullptr) { 0163 *this = o; 0164 } 0165 0166 //! @brief Assignment operator. Copy the index array 0167 aiFace &operator=(const aiFace &o) { 0168 if (&o == this) { 0169 return *this; 0170 } 0171 0172 delete[] mIndices; 0173 mNumIndices = o.mNumIndices; 0174 if (mNumIndices) { 0175 mIndices = new unsigned int[mNumIndices]; 0176 ::memcpy(mIndices, o.mIndices, mNumIndices * sizeof(unsigned int)); 0177 } else { 0178 mIndices = nullptr; 0179 } 0180 0181 return *this; 0182 } 0183 0184 //! @brief Comparison operator. Checks whether the index array of two faces is identical. 0185 bool operator==(const aiFace &o) const { 0186 if (mIndices == o.mIndices) { 0187 return true; 0188 } 0189 0190 if (nullptr != mIndices && mNumIndices != o.mNumIndices) { 0191 return false; 0192 } 0193 0194 if (nullptr == mIndices) { 0195 return false; 0196 } 0197 0198 for (unsigned int i = 0; i < this->mNumIndices; ++i) { 0199 if (mIndices[i] != o.mIndices[i]) { 0200 return false; 0201 } 0202 } 0203 0204 return true; 0205 } 0206 0207 //! @brief Inverse comparison operator. Checks whether the index 0208 //! array of two faces is NOT identical 0209 bool operator!=(const aiFace &o) const { 0210 return !(*this == o); 0211 } 0212 #endif // __cplusplus 0213 }; // struct aiFace 0214 0215 // --------------------------------------------------------------------------- 0216 /** @brief A single influence of a bone on a vertex. 0217 */ 0218 struct aiVertexWeight { 0219 //! Index of the vertex which is influenced by the bone. 0220 unsigned int mVertexId; 0221 0222 //! The strength of the influence in the range (0...1). 0223 //! The influence from all bones at one vertex amounts to 1. 0224 ai_real mWeight; 0225 0226 #ifdef __cplusplus 0227 0228 //! @brief Default constructor 0229 aiVertexWeight() AI_NO_EXCEPT 0230 : mVertexId(0), 0231 mWeight(0.0f) { 0232 // empty 0233 } 0234 0235 //! @brief Initialization from a given index and vertex weight factor 0236 //! \param pID ID 0237 //! \param pWeight Vertex weight factor 0238 aiVertexWeight(unsigned int pID, float pWeight) : 0239 mVertexId(pID), mWeight(pWeight) { 0240 // empty 0241 } 0242 0243 bool operator==(const aiVertexWeight &rhs) const { 0244 return (mVertexId == rhs.mVertexId && mWeight == rhs.mWeight); 0245 } 0246 0247 bool operator!=(const aiVertexWeight &rhs) const { 0248 return (*this == rhs); 0249 } 0250 0251 #endif // __cplusplus 0252 }; 0253 0254 // Forward declare aiNode (pointer use only) 0255 struct aiNode; 0256 0257 // --------------------------------------------------------------------------- 0258 /** @brief A single bone of a mesh. 0259 * 0260 * A bone has a name by which it can be found in the frame hierarchy and by 0261 * which it can be addressed by animations. In addition it has a number of 0262 * influences on vertices, and a matrix relating the mesh position to the 0263 * position of the bone at the time of binding. 0264 */ 0265 struct aiBone { 0266 /** 0267 * The name of the bone. 0268 */ 0269 C_STRUCT aiString mName; 0270 0271 /** 0272 * The number of vertices affected by this bone. 0273 * The maximum value for this member is #AI_MAX_BONE_WEIGHTS. 0274 */ 0275 unsigned int mNumWeights; 0276 0277 #ifndef ASSIMP_BUILD_NO_ARMATUREPOPULATE_PROCESS 0278 /** 0279 * The bone armature node - used for skeleton conversion 0280 * you must enable aiProcess_PopulateArmatureData to populate this 0281 */ 0282 C_STRUCT aiNode *mArmature; 0283 0284 /** 0285 * The bone node in the scene - used for skeleton conversion 0286 * you must enable aiProcess_PopulateArmatureData to populate this 0287 */ 0288 C_STRUCT aiNode *mNode; 0289 0290 #endif 0291 /** 0292 * The influence weights of this bone, by vertex index. 0293 */ 0294 C_STRUCT aiVertexWeight *mWeights; 0295 0296 /** 0297 * Matrix that transforms from mesh space to bone space in bind pose. 0298 * 0299 * This matrix describes the position of the mesh 0300 * in the local space of this bone when the skeleton was bound. 0301 * Thus it can be used directly to determine a desired vertex position, 0302 * given the world-space transform of the bone when animated, 0303 * and the position of the vertex in mesh space. 0304 * 0305 * It is sometimes called an inverse-bind matrix, 0306 * or inverse bind pose matrix. 0307 */ 0308 C_STRUCT aiMatrix4x4 mOffsetMatrix; 0309 0310 #ifdef __cplusplus 0311 0312 /// @brief Default constructor 0313 aiBone() AI_NO_EXCEPT 0314 : mName(), 0315 mNumWeights(0), 0316 #ifndef ASSIMP_BUILD_NO_ARMATUREPOPULATE_PROCESS 0317 mArmature(nullptr), 0318 mNode(nullptr), 0319 #endif 0320 mWeights(nullptr), 0321 mOffsetMatrix() { 0322 // empty 0323 } 0324 0325 /// @brief Copy constructor 0326 aiBone(const aiBone &other) : 0327 mName(other.mName), 0328 mNumWeights(other.mNumWeights), 0329 #ifndef ASSIMP_BUILD_NO_ARMATUREPOPULATE_PROCESS 0330 mArmature(nullptr), 0331 mNode(nullptr), 0332 #endif 0333 mWeights(nullptr), 0334 mOffsetMatrix(other.mOffsetMatrix) { 0335 copyVertexWeights(other); 0336 } 0337 0338 void copyVertexWeights( const aiBone &other ) { 0339 if (other.mWeights == nullptr || other.mNumWeights == 0) { 0340 mWeights = nullptr; 0341 mNumWeights = 0; 0342 return; 0343 } 0344 0345 mNumWeights = other.mNumWeights; 0346 if (mWeights) { 0347 delete[] mWeights; 0348 } 0349 0350 mWeights = new aiVertexWeight[mNumWeights]; 0351 ::memcpy(mWeights, other.mWeights, mNumWeights * sizeof(aiVertexWeight)); 0352 } 0353 0354 //! @brief Assignment operator 0355 aiBone &operator = (const aiBone &other) { 0356 if (this == &other) { 0357 return *this; 0358 } 0359 0360 mName = other.mName; 0361 mNumWeights = other.mNumWeights; 0362 mOffsetMatrix = other.mOffsetMatrix; 0363 copyVertexWeights(other); 0364 0365 return *this; 0366 } 0367 0368 /// @brief Compare operator. 0369 bool operator==(const aiBone &rhs) const { 0370 if (mName != rhs.mName || mNumWeights != rhs.mNumWeights ) { 0371 return false; 0372 } 0373 0374 for (size_t i = 0; i < mNumWeights; ++i) { 0375 if (mWeights[i] != rhs.mWeights[i]) { 0376 return false; 0377 } 0378 } 0379 0380 return true; 0381 } 0382 //! @brief Destructor - deletes the array of vertex weights 0383 ~aiBone() { 0384 delete[] mWeights; 0385 } 0386 #endif // __cplusplus 0387 }; 0388 0389 // --------------------------------------------------------------------------- 0390 /** @brief Enumerates the types of geometric primitives supported by Assimp. 0391 * 0392 * @see aiFace Face data structure 0393 * @see aiProcess_SortByPType Per-primitive sorting of meshes 0394 * @see aiProcess_Triangulate Automatic triangulation 0395 * @see AI_CONFIG_PP_SBP_REMOVE Removal of specific primitive types. 0396 */ 0397 enum aiPrimitiveType { 0398 /** 0399 * @brief A point primitive. 0400 * 0401 * This is just a single vertex in the virtual world, 0402 * #aiFace contains just one index for such a primitive. 0403 */ 0404 aiPrimitiveType_POINT = 0x1, 0405 0406 /** 0407 * @brief A line primitive. 0408 * 0409 * This is a line defined through a start and an end position. 0410 * #aiFace contains exactly two indices for such a primitive. 0411 */ 0412 aiPrimitiveType_LINE = 0x2, 0413 0414 /** 0415 * @brief A triangular primitive. 0416 * 0417 * A triangle consists of three indices. 0418 */ 0419 aiPrimitiveType_TRIANGLE = 0x4, 0420 0421 /** 0422 * @brief A higher-level polygon with more than 3 edges. 0423 * 0424 * A triangle is a polygon, but polygon in this context means 0425 * "all polygons that are not triangles". The "Triangulate"-Step 0426 * is provided for your convenience, it splits all polygons in 0427 * triangles (which are much easier to handle). 0428 */ 0429 aiPrimitiveType_POLYGON = 0x8, 0430 0431 /** 0432 * @brief A flag to determine whether this triangles only mesh is NGON encoded. 0433 * 0434 * NGON encoding is a special encoding that tells whether 2 or more consecutive triangles 0435 * should be considered as a triangle fan. This is identified by looking at the first vertex index. 0436 * 2 consecutive triangles with the same 1st vertex index are part of the same 0437 * NGON. 0438 * 0439 * At the moment, only quads (concave or convex) are supported, meaning that polygons are 'seen' as 0440 * triangles, as usual after a triangulation pass. 0441 * 0442 * To get an NGON encoded mesh, please use the aiProcess_Triangulate post process. 0443 * 0444 * @see aiProcess_Triangulate 0445 * @link https://github.com/KhronosGroup/glTF/pull/1620 0446 */ 0447 aiPrimitiveType_NGONEncodingFlag = 0x10, 0448 0449 /** 0450 * This value is not used. It is just here to force the 0451 * compiler to map this enum to a 32 Bit integer. 0452 */ 0453 #ifndef SWIG 0454 _aiPrimitiveType_Force32Bit = INT_MAX 0455 #endif 0456 }; //! enum aiPrimitiveType 0457 0458 // Get the #aiPrimitiveType flag for a specific number of face indices 0459 #define AI_PRIMITIVE_TYPE_FOR_N_INDICES(n) \ 0460 ((n) > 3 ? aiPrimitiveType_POLYGON : (aiPrimitiveType)(1u << ((n)-1))) 0461 0462 // --------------------------------------------------------------------------- 0463 /** @brief An AnimMesh is an attachment to an #aiMesh stores per-vertex 0464 * animations for a particular frame. 0465 * 0466 * You may think of an #aiAnimMesh as a `patch` for the host mesh, which 0467 * replaces only certain vertex data streams at a particular time. 0468 * Each mesh stores n attached attached meshes (#aiMesh::mAnimMeshes). 0469 * The actual relationship between the time line and anim meshes is 0470 * established by #aiMeshAnim, which references singular mesh attachments 0471 * by their ID and binds them to a time offset. 0472 */ 0473 struct aiAnimMesh { 0474 /**Anim Mesh name */ 0475 C_STRUCT aiString mName; 0476 0477 /** Replacement for aiMesh::mVertices. If this array is non-nullptr, 0478 * it *must* contain mNumVertices entries. The corresponding 0479 * array in the host mesh must be non-nullptr as well - animation 0480 * meshes may neither add or nor remove vertex components (if 0481 * a replacement array is nullptr and the corresponding source 0482 * array is not, the source data is taken instead)*/ 0483 C_STRUCT aiVector3D *mVertices; 0484 0485 /** Replacement for aiMesh::mNormals. */ 0486 C_STRUCT aiVector3D *mNormals; 0487 0488 /** Replacement for aiMesh::mTangents. */ 0489 C_STRUCT aiVector3D *mTangents; 0490 0491 /** Replacement for aiMesh::mBitangents. */ 0492 C_STRUCT aiVector3D *mBitangents; 0493 0494 /** Replacement for aiMesh::mColors */ 0495 C_STRUCT aiColor4D *mColors[AI_MAX_NUMBER_OF_COLOR_SETS]; 0496 0497 /** Replacement for aiMesh::mTextureCoords */ 0498 C_STRUCT aiVector3D *mTextureCoords[AI_MAX_NUMBER_OF_TEXTURECOORDS]; 0499 0500 /** The number of vertices in the aiAnimMesh, and thus the length of all 0501 * the member arrays. 0502 * 0503 * This has always the same value as the mNumVertices property in the 0504 * corresponding aiMesh. It is duplicated here merely to make the length 0505 * of the member arrays accessible even if the aiMesh is not known, e.g. 0506 * from language bindings. 0507 */ 0508 unsigned int mNumVertices; 0509 0510 /** 0511 * Weight of the AnimMesh. 0512 */ 0513 float mWeight; 0514 0515 #ifdef __cplusplus 0516 /// @brief The class constructor. 0517 aiAnimMesh() AI_NO_EXCEPT : 0518 mVertices(nullptr), 0519 mNormals(nullptr), 0520 mTangents(nullptr), 0521 mBitangents(nullptr), 0522 mColors {nullptr}, 0523 mTextureCoords{nullptr}, 0524 mNumVertices(0), 0525 mWeight(0.0f) { 0526 // empty 0527 } 0528 0529 /// @brief The class destructor. 0530 ~aiAnimMesh() { 0531 delete[] mVertices; 0532 delete[] mNormals; 0533 delete[] mTangents; 0534 delete[] mBitangents; 0535 for (unsigned int a = 0; a < AI_MAX_NUMBER_OF_TEXTURECOORDS; a++) { 0536 delete[] mTextureCoords[a]; 0537 } 0538 for (unsigned int a = 0; a < AI_MAX_NUMBER_OF_COLOR_SETS; a++) { 0539 delete[] mColors[a]; 0540 } 0541 } 0542 0543 /** 0544 * @brief Check whether the anim-mesh overrides the vertex positions 0545 * of its host mesh. 0546 * @return true if positions are stored, false if not. 0547 */ 0548 bool HasPositions() const { 0549 return mVertices != nullptr; 0550 } 0551 0552 /** 0553 * @brief Check whether the anim-mesh overrides the vertex normals 0554 * of its host mesh 0555 * @return true if normals are stored, false if not. 0556 */ 0557 bool HasNormals() const { 0558 return mNormals != nullptr; 0559 } 0560 0561 /** 0562 * @brief Check whether the anim-mesh overrides the vertex tangents 0563 * and bitangents of its host mesh. As for aiMesh, 0564 * tangents and bitangents always go together. 0565 * @return true if tangents and bi-tangents are stored, false if not. 0566 */ 0567 bool HasTangentsAndBitangents() const { 0568 return mTangents != nullptr; 0569 } 0570 0571 /** 0572 * @brief Check whether the anim mesh overrides a particular 0573 * set of vertex colors on his host mesh. 0574 * @param pIndex 0<index<AI_MAX_NUMBER_OF_COLOR_SETS 0575 * @return true if vertex colors are stored, false if not. 0576 */ 0577 0578 bool HasVertexColors(unsigned int pIndex) const { 0579 return pIndex >= AI_MAX_NUMBER_OF_COLOR_SETS ? false : mColors[pIndex] != nullptr; 0580 } 0581 0582 /** 0583 * @brief Check whether the anim mesh overrides a particular 0584 * set of texture coordinates on his host mesh. 0585 * @param pIndex 0<index<AI_MAX_NUMBER_OF_TEXTURECOORDS 0586 * @return true if texture coordinates are stored, false if not. 0587 */ 0588 bool HasTextureCoords(unsigned int pIndex) const { 0589 return pIndex >= AI_MAX_NUMBER_OF_TEXTURECOORDS ? false : mTextureCoords[pIndex] != nullptr; 0590 } 0591 0592 #endif 0593 }; 0594 0595 // --------------------------------------------------------------------------- 0596 /** @brief Enumerates the methods of mesh morphing supported by Assimp. 0597 */ 0598 enum aiMorphingMethod { 0599 /** Morphing method to be determined */ 0600 aiMorphingMethod_UNKNOWN = 0x0, 0601 0602 /** Interpolation between morph targets */ 0603 aiMorphingMethod_VERTEX_BLEND = 0x1, 0604 0605 /** Normalized morphing between morph targets */ 0606 aiMorphingMethod_MORPH_NORMALIZED = 0x2, 0607 0608 /** Relative morphing between morph targets */ 0609 aiMorphingMethod_MORPH_RELATIVE = 0x3, 0610 0611 /** This value is not used. It is just here to force the 0612 * compiler to map this enum to a 32 Bit integer. 0613 */ 0614 #ifndef SWIG 0615 _aiMorphingMethod_Force32Bit = INT_MAX 0616 #endif 0617 }; //! enum aiMorphingMethod 0618 0619 // --------------------------------------------------------------------------- 0620 /** @brief A mesh represents a geometry or model with a single material. 0621 * 0622 * It usually consists of a number of vertices and a series of primitives/faces 0623 * referencing the vertices. In addition there might be a series of bones, each 0624 * of them addressing a number of vertices with a certain weight. Vertex data 0625 * is presented in channels with each channel containing a single per-vertex 0626 * information such as a set of texture coordinates or a normal vector. 0627 * If a data pointer is non-null, the corresponding data stream is present. 0628 * From C++-programs you can also use the comfort functions Has*() to 0629 * test for the presence of various data streams. 0630 * 0631 * A Mesh uses only a single material which is referenced by a material ID. 0632 * @note The mPositions member is usually not optional. However, vertex positions 0633 * *could* be missing if the #AI_SCENE_FLAGS_INCOMPLETE flag is set in 0634 * @code 0635 * aiScene::mFlags 0636 * @endcode 0637 */ 0638 struct aiMesh { 0639 /** 0640 * Bitwise combination of the members of the #aiPrimitiveType enum. 0641 * This specifies which types of primitives are present in the mesh. 0642 * The "SortByPrimitiveType"-Step can be used to make sure the 0643 * output meshes consist of one primitive type each. 0644 */ 0645 unsigned int mPrimitiveTypes; 0646 0647 /** 0648 * The number of vertices in this mesh. 0649 * This is also the size of all of the per-vertex data arrays. 0650 * The maximum value for this member is #AI_MAX_VERTICES. 0651 */ 0652 unsigned int mNumVertices; 0653 0654 /** 0655 * The number of primitives (triangles, polygons, lines) in this mesh. 0656 * This is also the size of the mFaces array. 0657 * The maximum value for this member is #AI_MAX_FACES. 0658 */ 0659 unsigned int mNumFaces; 0660 0661 /** 0662 * @brief Vertex positions. 0663 * 0664 * This array is always present in a mesh. The array is 0665 * mNumVertices in size. 0666 */ 0667 C_STRUCT aiVector3D *mVertices; 0668 0669 /** 0670 * @brief Vertex normals. 0671 * 0672 * The array contains normalized vectors, nullptr if not present. 0673 * The array is mNumVertices in size. Normals are undefined for 0674 * point and line primitives. A mesh consisting of points and 0675 * lines only may not have normal vectors. Meshes with mixed 0676 * primitive types (i.e. lines and triangles) may have normals, 0677 * but the normals for vertices that are only referenced by 0678 * point or line primitives are undefined and set to QNaN (WARN: 0679 * qNaN compares to inequal to *everything*, even to qNaN itself. 0680 * Using code like this to check whether a field is qnan is: 0681 * @code 0682 * #define IS_QNAN(f) (f != f) 0683 * @endcode 0684 * still dangerous because even 1.f == 1.f could evaluate to false! ( 0685 * remember the subtleties of IEEE754 artithmetics). Use stuff like 0686 * @c fpclassify instead. 0687 * @note Normal vectors computed by Assimp are always unit-length. 0688 * However, this needn't apply for normals that have been taken 0689 * directly from the model file. 0690 */ 0691 C_STRUCT aiVector3D *mNormals; 0692 0693 /** 0694 * @brief Vertex tangents. 0695 * 0696 * The tangent of a vertex points in the direction of the positive 0697 * X texture axis. The array contains normalized vectors, nullptr if 0698 * not present. The array is mNumVertices in size. A mesh consisting 0699 * of points and lines only may not have normal vectors. Meshes with 0700 * mixed primitive types (i.e. lines and triangles) may have 0701 * normals, but the normals for vertices that are only referenced by 0702 * point or line primitives are undefined and set to qNaN. See 0703 * the #mNormals member for a detailed discussion of qNaNs. 0704 * @note If the mesh contains tangents, it automatically also 0705 * contains bitangents. 0706 */ 0707 C_STRUCT aiVector3D *mTangents; 0708 0709 /** 0710 * @brief Vertex bitangents. 0711 * 0712 * The bitangent of a vertex points in the direction of the positive 0713 * Y texture axis. The array contains normalized vectors, nullptr if not 0714 * present. The array is mNumVertices in size. 0715 * @note If the mesh contains tangents, it automatically also contains 0716 * bitangents. 0717 */ 0718 C_STRUCT aiVector3D *mBitangents; 0719 0720 /** 0721 * @brief Vertex color sets. 0722 * 0723 * A mesh may contain 0 to #AI_MAX_NUMBER_OF_COLOR_SETS vertex 0724 * colors per vertex. nullptr if not present. Each array is 0725 * mNumVertices in size if present. 0726 */ 0727 C_STRUCT aiColor4D *mColors[AI_MAX_NUMBER_OF_COLOR_SETS]; 0728 0729 /** 0730 * @brief Vertex texture coordinates, also known as UV channels. 0731 * 0732 * A mesh may contain 0 to AI_MAX_NUMBER_OF_TEXTURECOORDS channels per 0733 * vertex. Used and unused (nullptr) channels may go in any order. 0734 * The array is mNumVertices in size. 0735 */ 0736 C_STRUCT aiVector3D *mTextureCoords[AI_MAX_NUMBER_OF_TEXTURECOORDS]; 0737 0738 /** 0739 * @brief Specifies the number of components for a given UV channel. 0740 * 0741 * Up to three channels are supported (UVW, for accessing volume 0742 * or cube maps). If the value is 2 for a given channel n, the 0743 * component p.z of mTextureCoords[n][p] is set to 0.0f. 0744 * If the value is 1 for a given channel, p.y is set to 0.0f, too. 0745 * @note 4D coordinates are not supported 0746 */ 0747 unsigned int mNumUVComponents[AI_MAX_NUMBER_OF_TEXTURECOORDS]; 0748 0749 /** 0750 * @brief The faces the mesh is constructed from. 0751 * 0752 * Each face refers to a number of vertices by their indices. 0753 * This array is always present in a mesh, its size is given 0754 * in mNumFaces. If the #AI_SCENE_FLAGS_NON_VERBOSE_FORMAT 0755 * is NOT set each face references an unique set of vertices. 0756 */ 0757 C_STRUCT aiFace *mFaces; 0758 0759 /** 0760 * The number of bones this mesh contains. Can be 0, in which case the mBones array is nullptr. 0761 */ 0762 unsigned int mNumBones; 0763 0764 /** 0765 * @brief The bones of this mesh. 0766 * 0767 * A bone consists of a name by which it can be found in the 0768 * frame hierarchy and a set of vertex weights. 0769 */ 0770 C_STRUCT aiBone **mBones; 0771 0772 /** 0773 * @brief The material used by this mesh. 0774 * 0775 * A mesh uses only a single material. If an imported model uses 0776 * multiple materials, the import splits up the mesh. Use this value 0777 * as index into the scene's material list. 0778 */ 0779 unsigned int mMaterialIndex; 0780 0781 /** 0782 * Name of the mesh. Meshes can be named, but this is not a 0783 * requirement and leaving this field empty is totally fine. 0784 * There are mainly three uses for mesh names: 0785 * - some formats name nodes and meshes independently. 0786 * - importers tend to split meshes up to meet the 0787 * one-material-per-mesh requirement. Assigning 0788 * the same (dummy) name to each of the result meshes 0789 * aids the caller at recovering the original mesh 0790 * partitioning. 0791 * - Vertex animations refer to meshes by their names. 0792 */ 0793 C_STRUCT aiString mName; 0794 0795 /** 0796 * The number of attachment meshes. 0797 * Currently known to work with loaders: 0798 * - Collada 0799 * - gltf 0800 */ 0801 unsigned int mNumAnimMeshes; 0802 0803 /** 0804 * Attachment meshes for this mesh, for vertex-based animation. 0805 * Attachment meshes carry replacement data for some of the 0806 * mesh'es vertex components (usually positions, normals). 0807 * Currently known to work with loaders: 0808 * - Collada 0809 * - gltf 0810 */ 0811 C_STRUCT aiAnimMesh **mAnimMeshes; 0812 0813 /** 0814 * Method of morphing when anim-meshes are specified. 0815 * @see aiMorphingMethod to learn more about the provided morphing targets. 0816 */ 0817 enum aiMorphingMethod mMethod; 0818 0819 /** 0820 * The bounding box. 0821 */ 0822 C_STRUCT aiAABB mAABB; 0823 0824 /** 0825 * Vertex UV stream names. Pointer to array of size AI_MAX_NUMBER_OF_TEXTURECOORDS 0826 */ 0827 C_STRUCT aiString **mTextureCoordsNames; 0828 0829 #ifdef __cplusplus 0830 0831 //! The default class constructor. 0832 aiMesh() AI_NO_EXCEPT 0833 : mPrimitiveTypes(0), 0834 mNumVertices(0), 0835 mNumFaces(0), 0836 mVertices(nullptr), 0837 mNormals(nullptr), 0838 mTangents(nullptr), 0839 mBitangents(nullptr), 0840 mColors{nullptr}, 0841 mTextureCoords{nullptr}, 0842 mNumUVComponents{0}, 0843 mFaces(nullptr), 0844 mNumBones(0), 0845 mBones(nullptr), 0846 mMaterialIndex(0), 0847 mNumAnimMeshes(0), 0848 mAnimMeshes(nullptr), 0849 mMethod(aiMorphingMethod_UNKNOWN), 0850 mAABB(), 0851 mTextureCoordsNames(nullptr) { 0852 // empty 0853 } 0854 0855 //! @brief The class destructor. 0856 ~aiMesh() { 0857 delete[] mVertices; 0858 delete[] mNormals; 0859 delete[] mTangents; 0860 delete[] mBitangents; 0861 for (unsigned int a = 0; a < AI_MAX_NUMBER_OF_TEXTURECOORDS; a++) { 0862 delete[] mTextureCoords[a]; 0863 } 0864 0865 if (mTextureCoordsNames) { 0866 for (unsigned int a = 0; a < AI_MAX_NUMBER_OF_TEXTURECOORDS; a++) { 0867 delete mTextureCoordsNames[a]; 0868 } 0869 delete[] mTextureCoordsNames; 0870 } 0871 0872 for (unsigned int a = 0; a < AI_MAX_NUMBER_OF_COLOR_SETS; a++) { 0873 delete[] mColors[a]; 0874 } 0875 0876 // DO NOT REMOVE THIS ADDITIONAL CHECK 0877 if (mNumBones && mBones) { 0878 std::unordered_set<const aiBone *> bones; 0879 for (unsigned int a = 0; a < mNumBones; a++) { 0880 if (mBones[a]) { 0881 bones.insert(mBones[a]); 0882 } 0883 } 0884 for (const aiBone *bone: bones) { 0885 delete bone; 0886 } 0887 delete[] mBones; 0888 } 0889 0890 if (mNumAnimMeshes && mAnimMeshes) { 0891 for (unsigned int a = 0; a < mNumAnimMeshes; a++) { 0892 delete mAnimMeshes[a]; 0893 } 0894 delete[] mAnimMeshes; 0895 } 0896 0897 delete[] mFaces; 0898 } 0899 0900 //! @brief Check whether the mesh contains positions. Provided no special 0901 //! scene flags are set, this will always be true 0902 //! @return true, if positions are stored, false if not. 0903 bool HasPositions() const { 0904 return mVertices != nullptr && mNumVertices > 0; 0905 } 0906 0907 //! @brief Check whether the mesh contains faces. If no special scene flags 0908 //! are set this should always return true 0909 //! @return true, if faces are stored, false if not. 0910 bool HasFaces() const { 0911 return mFaces != nullptr && mNumFaces > 0; 0912 } 0913 0914 //! @brief Check whether the mesh contains normal vectors 0915 //! @return true, if normals are stored, false if not. 0916 bool HasNormals() const { 0917 return mNormals != nullptr && mNumVertices > 0; 0918 } 0919 0920 //! @brief Check whether the mesh contains tangent and bitangent vectors. 0921 //! 0922 //! It is not possible that it contains tangents and no bitangents 0923 //! (or the other way round). The existence of one of them 0924 //! implies that the second is there, too. 0925 //! @return true, if tangents and bi-tangents are stored, false if not. 0926 bool HasTangentsAndBitangents() const { 0927 return mTangents != nullptr && mBitangents != nullptr && mNumVertices > 0; 0928 } 0929 0930 //! @brief Check whether the mesh contains a vertex color set 0931 //! @param index Index of the vertex color set 0932 //! @return true, if vertex colors are stored, false if not. 0933 bool HasVertexColors(unsigned int index) const { 0934 if (index >= AI_MAX_NUMBER_OF_COLOR_SETS) { 0935 return false; 0936 } 0937 return mColors[index] != nullptr && mNumVertices > 0; 0938 } 0939 0940 //! @brief Check whether the mesh contains a texture coordinate set 0941 //! @param index Index of the texture coordinates set 0942 //! @return true, if texture coordinates are stored, false if not. 0943 bool HasTextureCoords(unsigned int index) const { 0944 if (index >= AI_MAX_NUMBER_OF_TEXTURECOORDS) { 0945 return false; 0946 } 0947 return (mTextureCoords[index] != nullptr && mNumVertices > 0); 0948 } 0949 0950 //! @brief Get the number of UV channels the mesh contains. 0951 //! @return the number of stored uv-channels. 0952 unsigned int GetNumUVChannels() const { 0953 unsigned int n(0); 0954 for (unsigned i = 0; i < AI_MAX_NUMBER_OF_TEXTURECOORDS; i++) { 0955 if (mTextureCoords[i]) { 0956 ++n; 0957 } 0958 } 0959 0960 return n; 0961 } 0962 0963 //! @brief Get the number of vertex color channels the mesh contains. 0964 //! @return The number of stored color channels. 0965 unsigned int GetNumColorChannels() const { 0966 unsigned int n(0); 0967 while (n < AI_MAX_NUMBER_OF_COLOR_SETS && mColors[n]) { 0968 ++n; 0969 } 0970 return n; 0971 } 0972 0973 //! @brief Check whether the mesh contains bones. 0974 //! @return true, if bones are stored. 0975 bool HasBones() const { 0976 return mBones != nullptr && mNumBones > 0; 0977 } 0978 0979 //! @brief Check whether the mesh contains a texture coordinate set name 0980 //! @param pIndex Index of the texture coordinates set 0981 //! @return true, if texture coordinates for the index exists. 0982 bool HasTextureCoordsName(unsigned int pIndex) const { 0983 if (mTextureCoordsNames == nullptr || pIndex >= AI_MAX_NUMBER_OF_TEXTURECOORDS) { 0984 return false; 0985 } 0986 return mTextureCoordsNames[pIndex] != nullptr; 0987 } 0988 0989 //! @brief Set a texture coordinate set name 0990 //! @param pIndex Index of the texture coordinates set 0991 //! @param texCoordsName name of the texture coordinate set 0992 void SetTextureCoordsName(unsigned int pIndex, const aiString &texCoordsName) { 0993 if (pIndex >= AI_MAX_NUMBER_OF_TEXTURECOORDS) { 0994 return; 0995 } 0996 0997 if (mTextureCoordsNames == nullptr) { 0998 // Construct and null-init array 0999 mTextureCoordsNames = new aiString *[AI_MAX_NUMBER_OF_TEXTURECOORDS]; 1000 for (size_t i=0; i<AI_MAX_NUMBER_OF_TEXTURECOORDS; ++i) { 1001 mTextureCoordsNames[i] = nullptr; 1002 } 1003 } 1004 1005 if (texCoordsName.length == 0) { 1006 delete mTextureCoordsNames[pIndex]; 1007 mTextureCoordsNames[pIndex] = nullptr; 1008 return; 1009 } 1010 1011 if (mTextureCoordsNames[pIndex] == nullptr) { 1012 mTextureCoordsNames[pIndex] = new aiString(texCoordsName); 1013 return; 1014 } 1015 1016 *mTextureCoordsNames[pIndex] = texCoordsName; 1017 } 1018 1019 //! @brief Get a texture coordinate set name 1020 //! @param pIndex Index of the texture coordinates set 1021 //! @return The texture coordinate name. 1022 const aiString *GetTextureCoordsName(unsigned int index) const { 1023 if (mTextureCoordsNames == nullptr || index >= AI_MAX_NUMBER_OF_TEXTURECOORDS) { 1024 return nullptr; 1025 } 1026 1027 return mTextureCoordsNames[index]; 1028 } 1029 1030 #endif // __cplusplus 1031 }; 1032 1033 /** 1034 * @brief A skeleton bone represents a single bone is a skeleton structure. 1035 * 1036 * Skeleton-Animations can be represented via a skeleton struct, which describes 1037 * a hierarchical tree assembled from skeleton bones. A bone is linked to a mesh. 1038 * The bone knows its parent bone. If there is no parent bone the parent id is 1039 * marked with -1. 1040 * The skeleton-bone stores a pointer to its used armature. If there is no 1041 * armature this value if set to nullptr. 1042 * A skeleton bone stores its offset-matrix, which is the absolute transformation 1043 * for the bone. The bone stores the locale transformation to its parent as well. 1044 * You can compute the offset matrix by multiplying the hierarchy like: 1045 * Tree: s1 -> s2 -> s3 1046 * Offset-Matrix s3 = locale-s3 * locale-s2 * locale-s1 1047 */ 1048 struct aiSkeletonBone { 1049 /// The parent bone index, is -1 one if this bone represents the root bone. 1050 int mParent; 1051 1052 1053 #ifndef ASSIMP_BUILD_NO_ARMATUREPOPULATE_PROCESS 1054 /// @brief The bone armature node - used for skeleton conversion 1055 /// you must enable aiProcess_PopulateArmatureData to populate this 1056 C_STRUCT aiNode *mArmature; 1057 1058 /// @brief The bone node in the scene - used for skeleton conversion 1059 /// you must enable aiProcess_PopulateArmatureData to populate this 1060 C_STRUCT aiNode *mNode; 1061 1062 #endif 1063 /// @brief The number of weights 1064 unsigned int mNumnWeights; 1065 1066 /// The mesh index, which will get influenced by the weight. 1067 C_STRUCT aiMesh *mMeshId; 1068 1069 /// The influence weights of this bone, by vertex index. 1070 C_STRUCT aiVertexWeight *mWeights; 1071 1072 /** Matrix that transforms from bone space to mesh space in bind pose. 1073 * 1074 * This matrix describes the position of the mesh 1075 * in the local space of this bone when the skeleton was bound. 1076 * Thus it can be used directly to determine a desired vertex position, 1077 * given the world-space transform of the bone when animated, 1078 * and the position of the vertex in mesh space. 1079 * 1080 * It is sometimes called an inverse-bind matrix, 1081 * or inverse bind pose matrix. 1082 */ 1083 C_STRUCT aiMatrix4x4 mOffsetMatrix; 1084 1085 /// Matrix that transforms the locale bone in bind pose. 1086 C_STRUCT aiMatrix4x4 mLocalMatrix; 1087 1088 #ifdef __cplusplus 1089 /// @brief The class constructor. 1090 aiSkeletonBone() : 1091 mParent(-1), 1092 #ifndef ASSIMP_BUILD_NO_ARMATUREPOPULATE_PROCESS 1093 mArmature(nullptr), 1094 mNode(nullptr), 1095 #endif 1096 mNumnWeights(0), 1097 mMeshId(nullptr), 1098 mWeights(nullptr), 1099 mOffsetMatrix(), 1100 mLocalMatrix() { 1101 // empty 1102 } 1103 1104 /// @brief The class constructor with its parent 1105 /// @param parent The parent node index. 1106 aiSkeletonBone(unsigned int parent) : 1107 mParent(parent), 1108 #ifndef ASSIMP_BUILD_NO_ARMATUREPOPULATE_PROCESS 1109 mArmature(nullptr), 1110 mNode(nullptr), 1111 #endif 1112 mNumnWeights(0), 1113 mMeshId(nullptr), 1114 mWeights(nullptr), 1115 mOffsetMatrix(), 1116 mLocalMatrix() { 1117 // empty 1118 } 1119 /// @brief The class destructor. 1120 ~aiSkeletonBone() { 1121 delete[] mWeights; 1122 mWeights = nullptr; 1123 } 1124 #endif // __cplusplus 1125 }; 1126 /** 1127 * @brief A skeleton represents the bone hierarchy of an animation. 1128 * 1129 * Skeleton animations can be described as a tree of bones: 1130 * root 1131 * | 1132 * node1 1133 * / \ 1134 * node3 node4 1135 * If you want to calculate the transformation of node three you need to compute the 1136 * transformation hierarchy for the transformation chain of node3: 1137 * root->node1->node3 1138 * Each node is represented as a skeleton instance. 1139 */ 1140 struct aiSkeleton { 1141 /** 1142 * @brief The name of the skeleton instance. 1143 */ 1144 C_STRUCT aiString mName; 1145 1146 /** 1147 * @brief The number of bones in the skeleton. 1148 */ 1149 unsigned int mNumBones; 1150 1151 /** 1152 * @brief The bone instance in the skeleton. 1153 */ 1154 C_STRUCT aiSkeletonBone **mBones; 1155 1156 #ifdef __cplusplus 1157 /** 1158 * @brief The class constructor. 1159 */ 1160 aiSkeleton() AI_NO_EXCEPT : mName(), mNumBones(0), mBones(nullptr) { 1161 // empty 1162 } 1163 1164 /** 1165 * @brief The class destructor. 1166 */ 1167 ~aiSkeleton() { 1168 delete[] mBones; 1169 } 1170 #endif // __cplusplus 1171 }; 1172 #ifdef __cplusplus 1173 } 1174 #endif //! extern "C" 1175 1176 #endif // AI_MESH_H_INC 1177
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |
![]() ![]() |