#ifndef __cmesh_bi__
#define __cmesh_bi__

' Declares the data structures in which the imported geometry is returned by ASSIMP: 
' aiMesh, aiFace and aiBone data structures.

#include once "ctypes.bi"

' Limits. These values are required to match the settings Assimp was compiled against.
' Therfore, do not redefine them unless you build the library from source using the same definitions.
' Maximum number of indices per face (polygon).
#ifndef AI_MAX_FACE_INDICES 
 #define AI_MAX_FACE_INDICES &H7fff
#endif

' Maximum number of indices per face (polygon).
#ifndef AI_MAX_BONE_WEIGHTS
 #define AI_MAX_BONE_WEIGHTS &H7fffffff
#endif

' Maximum number of vertices per mesh.
#ifndef AI_MAX_VERTICES
 #define AI_MAX_VERTICES &H7fffffff
#endif

' Maximum number of faces per mesh.
#ifndef AI_MAX_FACES
 #define AI_MAX_FACES &H7fffffff
#endif

' Supported number of vertex color sets per mesh.
#ifndef AI_MAX_NUMBER_OF_COLOR_SETS
 #define AI_MAX_NUMBER_OF_COLOR_SETS &H8
#endif

' Supported number of texture coord sets (UV(W) channels) per mesh */
#ifndef AI_MAX_NUMBER_OF_TEXTURECOORDS
 #define AI_MAX_NUMBER_OF_TEXTURECOORDS &H8
#endif

' 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!).
' 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 aiPrimitiveType_LINE or aiPrimitiveType_POINT
' 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.
type aiFace
  ' Number of indices defining this face. 
  ' The maximum value for this member is AI_MAX_FACE_INDICES.
  as ulong mNumIndices
  ' Pointer to the indices array. Size of the array is given in numIndices.
  as ulong ptr mIndices
end type

' A single influence of a bone on a vertex.
type aiVertexWeight
  ' Index of the vertex which is influenced by the bone.
  as ulong mVertexId
  ' The strength of the influence in the range (0...1).
  ' The influence from all bones at one vertex amounts to 1.
  as single mWeight
end type

' A single bone of a mesh.
type aiBone
  ' The name of the bone. 
  as aiString mName
  ' The number of vertices affected by this bone
  ' The maximum value for this member is #AI_MAX_BONE_WEIGHTS.
  as ulong mNumWeights
  ' The vertices affected by this bone
  as aiVertexWeight ptr mWeights
  ' Matrix that transforms from mesh space to bone space in bind pose
  as aiMatrix4x4 mOffsetMatrix
end type

' 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    = &H1
  ' 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     = &H2
  ' A triangular primitive. A triangle consists of three indices.
  aiPrimitiveType_TRIANGLE = &H4
  ' 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  = &H8
end enum

' Get the aiPrimitiveType flag for a specific number of face indices
#define AI_PRIMITIVE_TYPE_FOR_N_INDICES(n) iif(n > 3,aiPrimitiveType_POLYGON, 1 shl (n-1))


' NOT CURRENTLY IN USE. 
' 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.
type aiAnimMesh

  ' Replacement for aiMesh::mVertices. If this array is non-NULL, 
  ' it *must* contain mNumVertices entries. The corresponding
  ' array in the host mesh must be non-NULL as well - animation
  ' meshes may neither add or nor remove vertex components (if
  ' a replacement array is NULL and the corresponding source
  ' array is not, the source data is taken instead)
  as aiVector3D ptr mVertices

  ' Replacement for aiMesh::mNormals.
  as aiVector3D ptr mNormals

  ' Replacement for aiMesh::mTangents.
  as aiVector3D ptr mTangents

  ' Replacement for aiMesh::mBitangents.
  as aiVector3D ptr mBitangents

  ' Replacement for aiMesh::mColors
  as aiColor4D ptr mColors(AI_MAX_NUMBER_OF_COLOR_SETS-1)

  ' Replacement for aiMesh::mTextureCoords
  as aiVector3D ptr mTextureCoords(AI_MAX_NUMBER_OF_TEXTURECOORDS-1)

  ' 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.
  as ulong mNumVertices
end type

' 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 coords 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 
type 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.
  as ulong 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.
  as ulong 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.
  as ulong mNumFaces
  ' Vertex positions. 
  ' This array is always present in a mesh. The array is mNumVertices in size. 
  as aiVector3D ptr mVertices

  ' Vertex normals. 
  ' The array contains normalized vectors, NULL 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:
  ' #define IS_QNAN(f) (f != f)
  ' still dangerous because even 1.f == 1.f could evaluate to false!
  ' (remember the subtleties of IEEE754 artithmetics).
  ' Use stuff like 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.
  as aiVector3D ptr mNormals

  ' Vertex tangents. 
  ' The tangent of a vertex points in the direction of the positive  X texture axis.
  ' The array contains normalized vectors, NULL 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 detailled discussion of qNaNs.
  ' @note If the mesh contains tangents, it automatically also contains bitangents.
  as aiVector3D ptr mTangents

  ' Vertex bitangents. 
  ' The bitangent of a vertex points in the direction of the positive Y texture axis.
  ' The array contains normalized vectors, NULL if not present. The array is mNumVertices in size. 
  ' @note If the mesh contains tangents, it automatically also contains bitangents.  
  as aiVector3D ptr mBitangents
  ' Vertex color sets. 
  ' A mesh may contain 0 to AI_MAX_NUMBER_OF_COLOR_SETS vertex colors per vertex. NULL if not present.
  ' Each array is mNumVertices in size if present.
  as aiColor4D ptr mColors(AI_MAX_NUMBER_OF_COLOR_SETS-1)

  ' Vertex texture coords, also known as UV channels.
  'A mesh may contain 0 to AI_MAX_NUMBER_OF_TEXTURECOORDS per vertex. NULL if not present. The array is mNumVertices in size. 
  as aiVector3D ptr mTextureCoords(AI_MAX_NUMBER_OF_TEXTURECOORDS-1)
  ' 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 coords are not supported 
  as ulong mNumUVComponents(AI_MAX_NUMBER_OF_TEXTURECOORDS-1)

  ' 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.
  as aiFace ptr mFaces
  ' The number of bones this mesh contains.
  ' Can be 0, in which case the mBones array is NULL. 
  as ulong 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.
  as aiBone ptr ptr mBones
  ' The material used by this mesh. 
  ' A mesh does use 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.
  as ulong 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.
  as aiString mName
  ' NOT CURRENTLY IN USE. The number of attachment meshes
  as ulong mNumAnimMeshes
  ' NOT CURRENTLY IN USE. 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).
  as aiAnimMesh ptr ptr mAnimMeshes
end type

#endif ' __AI_MESH_H_INC

