summaryrefslogtreecommitdiff
path: root/libs/assimp/include/assimp/mesh.h
diff options
context:
space:
mode:
Diffstat (limited to 'libs/assimp/include/assimp/mesh.h')
-rw-r--r--libs/assimp/include/assimp/mesh.h943
1 files changed, 943 insertions, 0 deletions
diff --git a/libs/assimp/include/assimp/mesh.h b/libs/assimp/include/assimp/mesh.h
new file mode 100644
index 0000000..5704e7c
--- /dev/null
+++ b/libs/assimp/include/assimp/mesh.h
@@ -0,0 +1,943 @@
+/*
+---------------------------------------------------------------------------
+Open Asset Import Library (assimp)
+---------------------------------------------------------------------------
+
+Copyright (c) 2006-2022, assimp team
+
+All rights reserved.
+
+Redistribution and use of this software in source and binary forms,
+with or without modification, are permitted provided that the following
+conditions are met:
+
+* Redistributions of source code must retain the above
+ copyright notice, this list of conditions and the
+ following disclaimer.
+
+* Redistributions in binary form must reproduce the above
+ copyright notice, this list of conditions and the
+ following disclaimer in the documentation and/or other
+ materials provided with the distribution.
+
+* Neither the name of the assimp team, nor the names of its
+ contributors may be used to endorse or promote products
+ derived from this software without specific prior
+ written permission of the assimp team.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+---------------------------------------------------------------------------
+*/
+
+/** @file mesh.h
+ * @brief Declares the data structures in which the imported geometry is
+ returned by ASSIMP: aiMesh, aiFace and aiBone data structures.
+ */
+#pragma once
+#ifndef AI_MESH_H_INC
+#define AI_MESH_H_INC
+
+#ifdef __GNUC__
+#pragma GCC system_header
+#endif
+
+#ifdef _MSC_VER
+#pragma warning(disable : 4351)
+#endif // _MSC_VER
+
+#include <assimp/aabb.h>
+#include <assimp/types.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// ---------------------------------------------------------------------------
+// Limits. These values are required to match the settings Assimp was
+// compiled against. Therefore, do not redefine them unless you build the
+// library from source using the same definitions.
+// ---------------------------------------------------------------------------
+
+/** @def AI_MAX_FACE_INDICES
+ * Maximum number of indices per face (polygon). */
+
+#ifndef AI_MAX_FACE_INDICES
+#define AI_MAX_FACE_INDICES 0x7fff
+#endif
+
+/** @def AI_MAX_BONE_WEIGHTS
+ * Maximum number of indices per face (polygon). */
+
+#ifndef AI_MAX_BONE_WEIGHTS
+#define AI_MAX_BONE_WEIGHTS 0x7fffffff
+#endif
+
+/** @def AI_MAX_VERTICES
+ * Maximum number of vertices per mesh. */
+
+#ifndef AI_MAX_VERTICES
+#define AI_MAX_VERTICES 0x7fffffff
+#endif
+
+/** @def AI_MAX_FACES
+ * Maximum number of faces per mesh. */
+
+#ifndef AI_MAX_FACES
+#define AI_MAX_FACES 0x7fffffff
+#endif
+
+/** @def AI_MAX_NUMBER_OF_COLOR_SETS
+ * Supported number of vertex color sets per mesh. */
+
+#ifndef AI_MAX_NUMBER_OF_COLOR_SETS
+#define AI_MAX_NUMBER_OF_COLOR_SETS 0x8
+#endif // !! AI_MAX_NUMBER_OF_COLOR_SETS
+
+/** @def AI_MAX_NUMBER_OF_TEXTURECOORDS
+ * Supported number of texture coord sets (UV(W) channels) per mesh */
+
+#ifndef AI_MAX_NUMBER_OF_TEXTURECOORDS
+#define AI_MAX_NUMBER_OF_TEXTURECOORDS 0x8
+#endif // !! AI_MAX_NUMBER_OF_TEXTURECOORDS
+
+// ---------------------------------------------------------------------------
+/** @brief A single face in a mesh, referring to multiple vertices.
+ *
+ * If mNumIndices is 3, we call the face 'triangle', for mNumIndices > 3
+ * it's called 'polygon' (hey, that's just a definition!).
+ * <br>
+ * aiMesh::mPrimitiveTypes can be queried to quickly examine which types of
+ * primitive are actually present in a mesh. The #aiProcess_SortByPType flag
+ * executes a special post-processing algorithm which splits meshes with
+ * *different* primitive types mixed up (e.g. lines and triangles) in several
+ * 'clean' submeshes. Furthermore there is a configuration option (
+ * #AI_CONFIG_PP_SBP_REMOVE) to force #aiProcess_SortByPType to remove
+ * specific kinds of primitives from the imported scene, completely and forever.
+ * In many cases you'll probably want to set this setting to
+ * @code
+ * aiPrimitiveType_LINE|aiPrimitiveType_POINT
+ * @endcode
+ * Together with the #aiProcess_Triangulate flag you can then be sure that
+ * #aiFace::mNumIndices is always 3.
+ * @note Take a look at the @link data Data Structures page @endlink for
+ * more information on the layout and winding order of a face.
+ */
+struct aiFace {
+ //! Number of indices defining this face.
+ //! The maximum value for this member is #AI_MAX_FACE_INDICES.
+ unsigned int mNumIndices;
+
+ //! Pointer to the indices array. Size of the array is given in numIndices.
+ unsigned int *mIndices;
+
+#ifdef __cplusplus
+
+ //! Default constructor
+ aiFace() AI_NO_EXCEPT
+ : mNumIndices(0),
+ mIndices(nullptr) {
+ // empty
+ }
+
+ //! Default destructor. Delete the index array
+ ~aiFace() {
+ delete[] mIndices;
+ }
+
+ //! Copy constructor. Copy the index array
+ aiFace(const aiFace &o) :
+ mNumIndices(0), mIndices(nullptr) {
+ *this = o;
+ }
+
+ //! Assignment operator. Copy the index array
+ aiFace &operator=(const aiFace &o) {
+ if (&o == this) {
+ return *this;
+ }
+
+ delete[] mIndices;
+ mNumIndices = o.mNumIndices;
+ if (mNumIndices) {
+ mIndices = new unsigned int[mNumIndices];
+ ::memcpy(mIndices, o.mIndices, mNumIndices * sizeof(unsigned int));
+ } else {
+ mIndices = nullptr;
+ }
+
+ return *this;
+ }
+
+ //! Comparison operator. Checks whether the index array
+ //! of two faces is identical
+ bool operator==(const aiFace &o) const {
+ if (mIndices == o.mIndices) {
+ return true;
+ }
+
+ if (nullptr != mIndices && mNumIndices != o.mNumIndices) {
+ return false;
+ }
+
+ if (nullptr == mIndices) {
+ return false;
+ }
+
+ for (unsigned int i = 0; i < this->mNumIndices; ++i) {
+ if (mIndices[i] != o.mIndices[i]) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ //! Inverse comparison operator. Checks whether the index
+ //! array of two faces is NOT identical
+ bool operator!=(const aiFace &o) const {
+ return !(*this == o);
+ }
+#endif // __cplusplus
+}; // struct aiFace
+
+// ---------------------------------------------------------------------------
+/** @brief A single influence of a bone on a vertex.
+ */
+struct aiVertexWeight {
+ //! Index of the vertex which is influenced by the bone.
+ unsigned int mVertexId;
+
+ //! The strength of the influence in the range (0...1).
+ //! The influence from all bones at one vertex amounts to 1.
+ ai_real mWeight;
+
+#ifdef __cplusplus
+
+ //! Default constructor
+ aiVertexWeight() AI_NO_EXCEPT
+ : mVertexId(0),
+ mWeight(0.0f) {
+ // empty
+ }
+
+ //! Initialization from a given index and vertex weight factor
+ //! \param pID ID
+ //! \param pWeight Vertex weight factor
+ aiVertexWeight(unsigned int pID, float pWeight) :
+ mVertexId(pID), mWeight(pWeight) {
+ // empty
+ }
+
+ bool operator==(const aiVertexWeight &rhs) const {
+ return (mVertexId == rhs.mVertexId && mWeight == rhs.mWeight);
+ }
+
+ bool operator!=(const aiVertexWeight &rhs) const {
+ return (*this == rhs);
+ }
+
+#endif // __cplusplus
+};
+
+// Forward declare aiNode (pointer use only)
+struct aiNode;
+
+// ---------------------------------------------------------------------------
+/** @brief A single bone of a mesh.
+ *
+ * A bone has a name by which it can be found in the frame hierarchy and by
+ * which it can be addressed by animations. In addition it has a number of
+ * influences on vertices, and a matrix relating the mesh position to the
+ * position of the bone at the time of binding.
+ */
+struct aiBone {
+ //! The name of the bone.
+ C_STRUCT aiString mName;
+
+ //! The number of vertices affected by this bone.
+ //! The maximum value for this member is #AI_MAX_BONE_WEIGHTS.
+ unsigned int mNumWeights;
+
+#ifndef ASSIMP_BUILD_NO_ARMATUREPOPULATE_PROCESS
+ // The bone armature node - used for skeleton conversion
+ // you must enable aiProcess_PopulateArmatureData to populate this
+ C_STRUCT aiNode *mArmature;
+
+ // The bone node in the scene - used for skeleton conversion
+ // you must enable aiProcess_PopulateArmatureData to populate this
+ C_STRUCT aiNode *mNode;
+
+#endif
+ //! The influence weights of this bone, by vertex index.
+ C_STRUCT aiVertexWeight *mWeights;
+
+ /** Matrix that transforms from bone space to mesh space in bind pose.
+ *
+ * This matrix describes the position of the mesh
+ * in the local space of this bone when the skeleton was bound.
+ * Thus it can be used directly to determine a desired vertex position,
+ * given the world-space transform of the bone when animated,
+ * and the position of the vertex in mesh space.
+ *
+ * It is sometimes called an inverse-bind matrix,
+ * or inverse bind pose matrix.
+ */
+ C_STRUCT aiMatrix4x4 mOffsetMatrix;
+
+#ifdef __cplusplus
+
+ //! Default constructor
+ aiBone() AI_NO_EXCEPT
+ : mName(),
+ mNumWeights(0),
+#ifndef ASSIMP_BUILD_NO_ARMATUREPOPULATE_PROCESS
+ mArmature(nullptr),
+ mNode(nullptr),
+#endif
+ mWeights(nullptr),
+ mOffsetMatrix() {
+ // empty
+ }
+
+ //! Copy constructor
+ aiBone(const aiBone &other) :
+ mName(other.mName),
+ mNumWeights(other.mNumWeights),
+#ifndef ASSIMP_BUILD_NO_ARMATUREPOPULATE_PROCESS
+ mArmature(nullptr),
+ mNode(nullptr),
+#endif
+ mWeights(nullptr),
+ mOffsetMatrix(other.mOffsetMatrix) {
+ if (other.mWeights && other.mNumWeights) {
+ mWeights = new aiVertexWeight[mNumWeights];
+ ::memcpy(mWeights, other.mWeights, mNumWeights * sizeof(aiVertexWeight));
+ }
+ }
+
+ //! Assignment operator
+ aiBone &operator=(const aiBone &other) {
+ if (this == &other) {
+ return *this;
+ }
+
+ mName = other.mName;
+ mNumWeights = other.mNumWeights;
+ mOffsetMatrix = other.mOffsetMatrix;
+
+ if (other.mWeights && other.mNumWeights) {
+ if (mWeights) {
+ delete[] mWeights;
+ }
+
+ mWeights = new aiVertexWeight[mNumWeights];
+ ::memcpy(mWeights, other.mWeights, mNumWeights * sizeof(aiVertexWeight));
+ }
+
+ return *this;
+ }
+
+ bool operator==(const aiBone &rhs) const {
+ if (mName != rhs.mName || mNumWeights != rhs.mNumWeights) {
+ return false;
+ }
+
+ for (size_t i = 0; i < mNumWeights; ++i) {
+ if (mWeights[i] != rhs.mWeights[i]) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+ //! Destructor - deletes the array of vertex weights
+ ~aiBone() {
+ delete[] mWeights;
+ }
+#endif // __cplusplus
+};
+
+// ---------------------------------------------------------------------------
+/** @brief Enumerates the types of geometric primitives supported by Assimp.
+ *
+ * @see aiFace Face data structure
+ * @see aiProcess_SortByPType Per-primitive sorting of meshes
+ * @see aiProcess_Triangulate Automatic triangulation
+ * @see AI_CONFIG_PP_SBP_REMOVE Removal of specific primitive types.
+ */
+enum aiPrimitiveType {
+ /** A point primitive.
+ *
+ * This is just a single vertex in the virtual world,
+ * #aiFace contains just one index for such a primitive.
+ */
+ aiPrimitiveType_POINT = 0x1,
+
+ /** A line primitive.
+ *
+ * This is a line defined through a start and an end position.
+ * #aiFace contains exactly two indices for such a primitive.
+ */
+ aiPrimitiveType_LINE = 0x2,
+
+ /** A triangular primitive.
+ *
+ * A triangle consists of three indices.
+ */
+ aiPrimitiveType_TRIANGLE = 0x4,
+
+ /** A higher-level polygon with more than 3 edges.
+ *
+ * A triangle is a polygon, but polygon in this context means
+ * "all polygons that are not triangles". The "Triangulate"-Step
+ * is provided for your convenience, it splits all polygons in
+ * triangles (which are much easier to handle).
+ */
+ aiPrimitiveType_POLYGON = 0x8,
+
+ /**
+ * A flag to determine whether this triangles only mesh is NGON encoded.
+ *
+ * NGON encoding is a special encoding that tells whether 2 or more consecutive triangles
+ * should be considered as a triangle fan. This is identified by looking at the first vertex index.
+ * 2 consecutive triangles with the same 1st vertex index are part of the same
+ * NGON.
+ *
+ * At the moment, only quads (concave or convex) are supported, meaning that polygons are 'seen' as
+ * triangles, as usual after a triangulation pass.
+ *
+ * To get an NGON encoded mesh, please use the aiProcess_Triangulate post process.
+ *
+ * @see aiProcess_Triangulate
+ * @link https://github.com/KhronosGroup/glTF/pull/1620
+ */
+ aiPrimitiveType_NGONEncodingFlag = 0x10,
+
+/** This value is not used. It is just here to force the
+ * compiler to map this enum to a 32 Bit integer.
+ */
+#ifndef SWIG
+ _aiPrimitiveType_Force32Bit = INT_MAX
+#endif
+}; //! enum aiPrimitiveType
+
+// Get the #aiPrimitiveType flag for a specific number of face indices
+#define AI_PRIMITIVE_TYPE_FOR_N_INDICES(n) \
+ ((n) > 3 ? aiPrimitiveType_POLYGON : (aiPrimitiveType)(1u << ((n)-1)))
+
+// ---------------------------------------------------------------------------
+/** @brief An AnimMesh is an attachment to an #aiMesh stores per-vertex
+ * animations for a particular frame.
+ *
+ * You may think of an #aiAnimMesh as a `patch` for the host mesh, which
+ * replaces only certain vertex data streams at a particular time.
+ * Each mesh stores n attached attached meshes (#aiMesh::mAnimMeshes).
+ * The actual relationship between the time line and anim meshes is
+ * established by #aiMeshAnim, which references singular mesh attachments
+ * by their ID and binds them to a time offset.
+*/
+struct aiAnimMesh {
+ /**Anim Mesh name */
+ C_STRUCT aiString mName;
+
+ /** Replacement for aiMesh::mVertices. If this array is non-nullptr,
+ * it *must* contain mNumVertices entries. The corresponding
+ * array in the host mesh must be non-nullptr as well - animation
+ * meshes may neither add or nor remove vertex components (if
+ * a replacement array is nullptr and the corresponding source
+ * array is not, the source data is taken instead)*/
+ C_STRUCT aiVector3D *mVertices;
+
+ /** Replacement for aiMesh::mNormals. */
+ C_STRUCT aiVector3D *mNormals;
+
+ /** Replacement for aiMesh::mTangents. */
+ C_STRUCT aiVector3D *mTangents;
+
+ /** Replacement for aiMesh::mBitangents. */
+ C_STRUCT aiVector3D *mBitangents;
+
+ /** Replacement for aiMesh::mColors */
+ C_STRUCT aiColor4D *mColors[AI_MAX_NUMBER_OF_COLOR_SETS];
+
+ /** Replacement for aiMesh::mTextureCoords */
+ C_STRUCT aiVector3D *mTextureCoords[AI_MAX_NUMBER_OF_TEXTURECOORDS];
+
+ /** The number of vertices in the aiAnimMesh, and thus the length of all
+ * the member arrays.
+ *
+ * This has always the same value as the mNumVertices property in the
+ * corresponding aiMesh. It is duplicated here merely to make the length
+ * of the member arrays accessible even if the aiMesh is not known, e.g.
+ * from language bindings.
+ */
+ unsigned int mNumVertices;
+
+ /**
+ * Weight of the AnimMesh.
+ */
+ float mWeight;
+
+#ifdef __cplusplus
+
+ aiAnimMesh() AI_NO_EXCEPT
+ : mVertices(nullptr),
+ mNormals(nullptr),
+ mTangents(nullptr),
+ mBitangents(nullptr),
+ mColors(),
+ mTextureCoords(),
+ mNumVertices(0),
+ mWeight(0.0f) {
+ // fixme consider moving this to the ctor initializer list as well
+ for (unsigned int a = 0; a < AI_MAX_NUMBER_OF_TEXTURECOORDS; a++) {
+ mTextureCoords[a] = nullptr;
+ }
+ for (unsigned int a = 0; a < AI_MAX_NUMBER_OF_COLOR_SETS; a++) {
+ mColors[a] = nullptr;
+ }
+ }
+
+ ~aiAnimMesh() {
+ delete[] mVertices;
+ delete[] mNormals;
+ delete[] mTangents;
+ delete[] mBitangents;
+ for (unsigned int a = 0; a < AI_MAX_NUMBER_OF_TEXTURECOORDS; a++) {
+ delete[] mTextureCoords[a];
+ }
+ for (unsigned int a = 0; a < AI_MAX_NUMBER_OF_COLOR_SETS; a++) {
+ delete[] mColors[a];
+ }
+ }
+
+ /** Check whether the anim mesh overrides the vertex positions
+ * of its host mesh*/
+ bool HasPositions() const {
+ return mVertices != nullptr;
+ }
+
+ /** Check whether the anim mesh overrides the vertex normals
+ * of its host mesh*/
+ bool HasNormals() const {
+ return mNormals != nullptr;
+ }
+
+ /** Check whether the anim mesh overrides the vertex tangents
+ * and bitangents of its host mesh. As for aiMesh,
+ * tangents and bitangents always go together. */
+ bool HasTangentsAndBitangents() const {
+ return mTangents != nullptr;
+ }
+
+ /** Check whether the anim mesh overrides a particular
+ * set of vertex colors on his host mesh.
+ * @param pIndex 0<index<AI_MAX_NUMBER_OF_COLOR_SETS */
+ bool HasVertexColors(unsigned int pIndex) const {
+ return pIndex >= AI_MAX_NUMBER_OF_COLOR_SETS ? false : mColors[pIndex] != nullptr;
+ }
+
+ /** Check whether the anim mesh overrides a particular
+ * set of texture coordinates on his host mesh.
+ * @param pIndex 0<index<AI_MAX_NUMBER_OF_TEXTURECOORDS */
+ bool HasTextureCoords(unsigned int pIndex) const {
+ return pIndex >= AI_MAX_NUMBER_OF_TEXTURECOORDS ? false : mTextureCoords[pIndex] != nullptr;
+ }
+
+#endif
+};
+
+// ---------------------------------------------------------------------------
+/** @brief Enumerates the methods of mesh morphing supported by Assimp.
+ */
+enum aiMorphingMethod {
+ /** Interpolation between morph targets */
+ aiMorphingMethod_VERTEX_BLEND = 0x1,
+
+ /** Normalized morphing between morph targets */
+ aiMorphingMethod_MORPH_NORMALIZED = 0x2,
+
+ /** Relative morphing between morph targets */
+ aiMorphingMethod_MORPH_RELATIVE = 0x3,
+
+/** This value is not used. It is just here to force the
+ * compiler to map this enum to a 32 Bit integer.
+ */
+#ifndef SWIG
+ _aiMorphingMethod_Force32Bit = INT_MAX
+#endif
+}; //! enum aiMorphingMethod
+
+// ---------------------------------------------------------------------------
+/** @brief A mesh represents a geometry or model with a single material.
+*
+* It usually consists of a number of vertices and a series of primitives/faces
+* referencing the vertices. In addition there might be a series of bones, each
+* of them addressing a number of vertices with a certain weight. Vertex data
+* is presented in channels with each channel containing a single per-vertex
+* information such as a set of texture coordinates or a normal vector.
+* If a data pointer is non-null, the corresponding data stream is present.
+* From C++-programs you can also use the comfort functions Has*() to
+* test for the presence of various data streams.
+*
+* A Mesh uses only a single material which is referenced by a material ID.
+* @note The mPositions member is usually not optional. However, vertex positions
+* *could* be missing if the #AI_SCENE_FLAGS_INCOMPLETE flag is set in
+* @code
+* aiScene::mFlags
+* @endcode
+*/
+struct aiMesh {
+ /** Bitwise combination of the members of the #aiPrimitiveType enum.
+ * This specifies which types of primitives are present in the mesh.
+ * The "SortByPrimitiveType"-Step can be used to make sure the
+ * output meshes consist of one primitive type each.
+ */
+ unsigned int mPrimitiveTypes;
+
+ /** The number of vertices in this mesh.
+ * This is also the size of all of the per-vertex data arrays.
+ * The maximum value for this member is #AI_MAX_VERTICES.
+ */
+ unsigned int mNumVertices;
+
+ /** The number of primitives (triangles, polygons, lines) in this mesh.
+ * This is also the size of the mFaces array.
+ * The maximum value for this member is #AI_MAX_FACES.
+ */
+ unsigned int mNumFaces;
+
+ /** Vertex positions.
+ * This array is always present in a mesh. The array is
+ * mNumVertices in size.
+ */
+ C_STRUCT aiVector3D *mVertices;
+
+ /** Vertex normals.
+ * The array contains normalized vectors, nullptr if not present.
+ * The array is mNumVertices in size. Normals are undefined for
+ * point and line primitives. A mesh consisting of points and
+ * lines only may not have normal vectors. Meshes with mixed
+ * primitive types (i.e. lines and triangles) may have normals,
+ * but the normals for vertices that are only referenced by
+ * point or line primitives are undefined and set to QNaN (WARN:
+ * qNaN compares to inequal to *everything*, even to qNaN itself.
+ * Using code like this to check whether a field is qnan is:
+ * @code
+ * #define IS_QNAN(f) (f != f)
+ * @endcode
+ * still dangerous because even 1.f == 1.f could evaluate to false! (
+ * remember the subtleties of IEEE754 artithmetics). Use stuff like
+ * @c fpclassify instead.
+ * @note Normal vectors computed by Assimp are always unit-length.
+ * However, this needn't apply for normals that have been taken
+ * directly from the model file.
+ */
+ C_STRUCT aiVector3D *mNormals;
+
+ /** Vertex tangents.
+ * The tangent of a vertex points in the direction of the positive
+ * X texture axis. The array contains normalized vectors, nullptr if
+ * not present. The array is mNumVertices in size. A mesh consisting
+ * of points and lines only may not have normal vectors. Meshes with
+ * mixed primitive types (i.e. lines and triangles) may have
+ * normals, but the normals for vertices that are only referenced by
+ * point or line primitives are undefined and set to qNaN. See
+ * the #mNormals member for a detailed discussion of qNaNs.
+ * @note If the mesh contains tangents, it automatically also
+ * contains bitangents.
+ */
+ C_STRUCT aiVector3D *mTangents;
+
+ /** Vertex bitangents.
+ * The bitangent of a vertex points in the direction of the positive
+ * Y texture axis. The array contains normalized vectors, nullptr if not
+ * present. The array is mNumVertices in size.
+ * @note If the mesh contains tangents, it automatically also contains
+ * bitangents.
+ */
+ C_STRUCT aiVector3D *mBitangents;
+
+ /** Vertex color sets.
+ * A mesh may contain 0 to #AI_MAX_NUMBER_OF_COLOR_SETS vertex
+ * colors per vertex. nullptr if not present. Each array is
+ * mNumVertices in size if present.
+ */
+ C_STRUCT aiColor4D *mColors[AI_MAX_NUMBER_OF_COLOR_SETS];
+
+ /** Vertex texture coordinates, also known as UV channels.
+ * A mesh may contain 0 to AI_MAX_NUMBER_OF_TEXTURECOORDS per
+ * vertex. nullptr if not present. The array is mNumVertices in size.
+ */
+ C_STRUCT aiVector3D *mTextureCoords[AI_MAX_NUMBER_OF_TEXTURECOORDS];
+
+ /** Specifies the number of components for a given UV channel.
+ * Up to three channels are supported (UVW, for accessing volume
+ * or cube maps). If the value is 2 for a given channel n, the
+ * component p.z of mTextureCoords[n][p] is set to 0.0f.
+ * If the value is 1 for a given channel, p.y is set to 0.0f, too.
+ * @note 4D coordinates are not supported
+ */
+ unsigned int mNumUVComponents[AI_MAX_NUMBER_OF_TEXTURECOORDS];
+
+ /** The faces the mesh is constructed from.
+ * Each face refers to a number of vertices by their indices.
+ * This array is always present in a mesh, its size is given
+ * in mNumFaces. If the #AI_SCENE_FLAGS_NON_VERBOSE_FORMAT
+ * is NOT set each face references an unique set of vertices.
+ */
+ C_STRUCT aiFace *mFaces;
+
+ /** The number of bones this mesh contains.
+ * Can be 0, in which case the mBones array is nullptr.
+ */
+ unsigned int mNumBones;
+
+ /** The bones of this mesh.
+ * A bone consists of a name by which it can be found in the
+ * frame hierarchy and a set of vertex weights.
+ */
+ C_STRUCT aiBone **mBones;
+
+ /** The material used by this mesh.
+ * A mesh uses only a single material. If an imported model uses
+ * multiple materials, the import splits up the mesh. Use this value
+ * as index into the scene's material list.
+ */
+ unsigned int mMaterialIndex;
+
+ /** Name of the mesh. Meshes can be named, but this is not a
+ * requirement and leaving this field empty is totally fine.
+ * There are mainly three uses for mesh names:
+ * - some formats name nodes and meshes independently.
+ * - importers tend to split meshes up to meet the
+ * one-material-per-mesh requirement. Assigning
+ * the same (dummy) name to each of the result meshes
+ * aids the caller at recovering the original mesh
+ * partitioning.
+ * - Vertex animations refer to meshes by their names.
+ **/
+ C_STRUCT aiString mName;
+
+ /** The number of attachment meshes. Note! Currently only works with Collada loader. */
+ unsigned int mNumAnimMeshes;
+
+ /** Attachment meshes for this mesh, for vertex-based animation.
+ * Attachment meshes carry replacement data for some of the
+ * mesh'es vertex components (usually positions, normals).
+ * Note! Currently only works with Collada loader.*/
+ C_STRUCT aiAnimMesh **mAnimMeshes;
+
+ /**
+ * Method of morphing when anim-meshes are specified.
+ * @see aiMorphingMethod to learn more about the provided morphing targets.
+ */
+ unsigned int mMethod;
+
+ /**
+ * The bounding box.
+ */
+ C_STRUCT aiAABB mAABB;
+
+ /** Vertex UV stream names. Pointer to array of size AI_MAX_NUMBER_OF_TEXTURECOORDS
+ */
+ C_STRUCT aiString **mTextureCoordsNames;
+
+#ifdef __cplusplus
+
+ //! Default constructor. Initializes all members to 0
+ aiMesh() AI_NO_EXCEPT
+ : mPrimitiveTypes(0),
+ mNumVertices(0),
+ mNumFaces(0),
+ mVertices(nullptr),
+ mNormals(nullptr),
+ mTangents(nullptr),
+ mBitangents(nullptr),
+ mColors(),
+ mTextureCoords(),
+ mNumUVComponents(),
+ mFaces(nullptr),
+ mNumBones(0),
+ mBones(nullptr),
+ mMaterialIndex(0),
+ mNumAnimMeshes(0),
+ mAnimMeshes(nullptr),
+ mMethod(0),
+ mAABB(),
+ mTextureCoordsNames(nullptr) {
+ for (unsigned int a = 0; a < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++a) {
+ mNumUVComponents[a] = 0;
+ mTextureCoords[a] = nullptr;
+ }
+
+ for (unsigned int a = 0; a < AI_MAX_NUMBER_OF_COLOR_SETS; ++a) {
+ mColors[a] = nullptr;
+ }
+ }
+
+ //! Deletes all storage allocated for the mesh
+ ~aiMesh() {
+ delete[] mVertices;
+ delete[] mNormals;
+ delete[] mTangents;
+ delete[] mBitangents;
+ for (unsigned int a = 0; a < AI_MAX_NUMBER_OF_TEXTURECOORDS; a++) {
+ delete[] mTextureCoords[a];
+ }
+
+ if (mTextureCoordsNames) {
+ for (unsigned int a = 0; a < AI_MAX_NUMBER_OF_TEXTURECOORDS; a++) {
+ delete mTextureCoordsNames[a];
+ }
+ delete[] mTextureCoordsNames;
+ }
+
+ for (unsigned int a = 0; a < AI_MAX_NUMBER_OF_COLOR_SETS; a++) {
+ delete[] mColors[a];
+ }
+
+ // DO NOT REMOVE THIS ADDITIONAL CHECK
+ if (mNumBones && mBones) {
+ for (unsigned int a = 0; a < mNumBones; a++) {
+ if (mBones[a]) {
+ delete mBones[a];
+ }
+ }
+ delete[] mBones;
+ }
+
+ if (mNumAnimMeshes && mAnimMeshes) {
+ for (unsigned int a = 0; a < mNumAnimMeshes; a++) {
+ delete mAnimMeshes[a];
+ }
+ delete[] mAnimMeshes;
+ }
+
+ delete[] mFaces;
+ }
+
+ //! Check whether the mesh contains positions. Provided no special
+ //! scene flags are set, this will always be true
+ bool HasPositions() const { return mVertices != nullptr && mNumVertices > 0; }
+
+ //! Check whether the mesh contains faces. If no special scene flags
+ //! are set this should always return true
+ bool HasFaces() const { return mFaces != nullptr && mNumFaces > 0; }
+
+ //! Check whether the mesh contains normal vectors
+ bool HasNormals() const { return mNormals != nullptr && mNumVertices > 0; }
+
+ //! Check whether the mesh contains tangent and bitangent vectors
+ //! It is not possible that it contains tangents and no bitangents
+ //! (or the other way round). The existence of one of them
+ //! implies that the second is there, too.
+ bool HasTangentsAndBitangents() const { return mTangents != nullptr && mBitangents != nullptr && mNumVertices > 0; }
+
+ //! Check whether the mesh contains a vertex color set
+ //! \param pIndex Index of the vertex color set
+ bool HasVertexColors(unsigned int pIndex) const {
+ if (pIndex >= AI_MAX_NUMBER_OF_COLOR_SETS) {
+ return false;
+ } else {
+ return mColors[pIndex] != nullptr && mNumVertices > 0;
+ }
+ }
+
+ //! Check whether the mesh contains a texture coordinate set
+ //! \param pIndex Index of the texture coordinates set
+ bool HasTextureCoords(unsigned int pIndex) const {
+ if (pIndex >= AI_MAX_NUMBER_OF_TEXTURECOORDS) {
+ return false;
+ } else {
+ return mTextureCoords[pIndex] != nullptr && mNumVertices > 0;
+ }
+ }
+
+ //! Get the number of UV channels the mesh contains
+ unsigned int GetNumUVChannels() const {
+ unsigned int n(0);
+ while (n < AI_MAX_NUMBER_OF_TEXTURECOORDS && mTextureCoords[n]) {
+ ++n;
+ }
+
+ return n;
+ }
+
+ //! Get the number of vertex color channels the mesh contains
+ unsigned int GetNumColorChannels() const {
+ unsigned int n(0);
+ while (n < AI_MAX_NUMBER_OF_COLOR_SETS && mColors[n]) {
+ ++n;
+ }
+ return n;
+ }
+
+ //! Check whether the mesh contains bones
+ bool HasBones() const {
+ return mBones != nullptr && mNumBones > 0;
+ }
+
+ //! Check whether the mesh contains a texture coordinate set name
+ //! \param pIndex Index of the texture coordinates set
+ bool HasTextureCoordsName(unsigned int pIndex) const {
+ if (mTextureCoordsNames == nullptr || pIndex >= AI_MAX_NUMBER_OF_TEXTURECOORDS) {
+ return false;
+ }
+ return mTextureCoordsNames[pIndex] != nullptr;
+ }
+
+ //! Set a texture coordinate set name
+ //! \param pIndex Index of the texture coordinates set
+ //! \param texCoordsName name of the texture coordinate set
+ void SetTextureCoordsName(unsigned int pIndex, const aiString &texCoordsName) {
+ if (pIndex >= AI_MAX_NUMBER_OF_TEXTURECOORDS) {
+ return;
+ }
+
+ if (mTextureCoordsNames == nullptr) {
+ // Construct and null-init array
+ mTextureCoordsNames = new aiString *[AI_MAX_NUMBER_OF_TEXTURECOORDS] {};
+ }
+
+ if (texCoordsName.length == 0) {
+ delete mTextureCoordsNames[pIndex];
+ mTextureCoordsNames[pIndex] = nullptr;
+ return;
+ }
+
+ if (mTextureCoordsNames[pIndex] == nullptr) {
+ mTextureCoordsNames[pIndex] = new aiString(texCoordsName);
+ return;
+ }
+
+ *mTextureCoordsNames[pIndex] = texCoordsName;
+ }
+
+ //! Get a texture coordinate set name
+ //! \param pIndex Index of the texture coordinates set
+ const aiString *GetTextureCoordsName(unsigned int pIndex) const {
+ if (mTextureCoordsNames == nullptr || pIndex >= AI_MAX_NUMBER_OF_TEXTURECOORDS) {
+ return nullptr;
+ }
+
+ return mTextureCoordsNames[pIndex];
+ }
+
+#endif // __cplusplus
+};
+
+#ifdef __cplusplus
+}
+#endif //! extern "C"
+#endif // AI_MESH_H_INC