Mesh.cs 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243
  1. //********************************** Banshee Engine (www.banshee3d.com) **************************************************//
  2. //**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
  3. using System;
  4. using System.Runtime.CompilerServices;
  5. using System.Runtime.InteropServices;
  6. namespace BansheeEngine
  7. {
  8. /** @addtogroup Rendering
  9. * @{
  10. */
  11. /// <summary>
  12. /// Primary class for holding geometry. Stores data in the form of a vertex buffers and optionally index buffer,
  13. /// which may be bound to the pipeline for drawing. May contain multiple sub-meshes.
  14. /// </summary>
  15. public class Mesh : Resource
  16. {
  17. /// <summary>
  18. /// Constructor for internal use by the runtime.
  19. /// </summary>
  20. private Mesh()
  21. { }
  22. /// <summary>
  23. /// Creates a new mesh with enough space to hold the a number of primitives using the specified layout. All indices
  24. /// will be part of a single sub-mesh.
  25. /// </summary>
  26. /// <param name="numVertices">Number of vertices in the mesh.</param>
  27. /// <param name="numIndices">Number of indices in the mesh. </param>
  28. /// <param name="topology">Determines how should the provided indices be interpreted by the pipeline. Default option
  29. /// is a triangle list, where three indices represent a single triangle.</param>
  30. /// <param name="usage">Optimizes performance depending on planned usage of the mesh.</param>
  31. /// <param name="vertex">Controls how are vertices organized in the vertex buffer and what data they contain.</param>
  32. /// <param name="index">Size of indices, use smaller size for better performance, however be careful not to go over
  33. /// the number of vertices limited by the size.</param>
  34. public Mesh(int numVertices, int numIndices, MeshTopology topology = MeshTopology.TriangleList,
  35. MeshUsage usage = MeshUsage.Default, VertexType vertex = VertexType.Position,
  36. IndexType index = IndexType.Index32)
  37. {
  38. SubMesh[] subMeshes = {new SubMesh(0, numIndices, topology)};
  39. Internal_CreateInstance(this, numVertices, numIndices, subMeshes, usage, vertex, index);
  40. }
  41. /// <summary>
  42. /// Creates a new mesh with enough space to hold the a number of primitives using the specified layout. Indices can
  43. /// be references by multiple sub-meshes.
  44. /// </summary>
  45. /// <param name="numVertices">Number of vertices in the mesh.</param>
  46. /// <param name="numIndices">Number of indices in the mesh. </param>
  47. /// <param name="subMeshes">Defines how are indices separated into sub-meshes, and how are those sub-meshes rendered.
  48. /// Sub-meshes may be rendered independently.</param>
  49. /// <param name="usage">Optimizes performance depending on planned usage of the mesh.</param>
  50. /// <param name="vertex">Controls how are vertices organized in the vertex buffer and what data they contain.</param>
  51. /// <param name="index">Size of indices, use smaller size for better performance, however be careful not to go over
  52. /// the number of vertices limited by the size.</param>
  53. public Mesh(int numVertices, int numIndices, SubMesh[] subMeshes, MeshUsage usage = MeshUsage.Default,
  54. VertexType vertex = VertexType.Position, IndexType index = IndexType.Index32)
  55. {
  56. Internal_CreateInstance(this, numVertices, numIndices, subMeshes, usage, vertex, index);
  57. }
  58. /// <summary>
  59. /// Creates a new mesh from an existing mesh data. Created mesh will match the vertex and index buffers described
  60. /// by the mesh data exactly. Mesh will have no sub-meshes.
  61. /// </summary>
  62. /// <param name="data">Vertex and index data to initialize the mesh with.</param>
  63. /// <param name="topology">Determines how should the provided indices be interpreted by the pipeline. Default option
  64. /// is a triangle list, where three indices represent a single triangle.</param>
  65. /// <param name="usage">Optimizes performance depending on planned usage of the mesh.</param>
  66. public Mesh(MeshData data, MeshTopology topology = MeshTopology.TriangleList, MeshUsage usage = MeshUsage.Default)
  67. {
  68. int numIndices = 0;
  69. IntPtr dataPtr = IntPtr.Zero;
  70. if (data != null)
  71. {
  72. numIndices = data.IndexCount;
  73. dataPtr = data.GetCachedPtr();
  74. }
  75. SubMesh[] subMeshes = { new SubMesh(0, numIndices, topology) };
  76. Internal_CreateInstanceMeshData(this, dataPtr, subMeshes, usage);
  77. }
  78. /// <summary>
  79. /// Creates a new mesh from an existing mesh data. Created mesh will match the vertex and index buffers described
  80. /// by the mesh data exactly. Mesh will have specified the sub-meshes.
  81. /// </summary>
  82. /// <param name="data">Vertex and index data to initialize the mesh with.</param>
  83. /// <param name="subMeshes">Defines how are indices separated into sub-meshes, and how are those sub-meshes rendered.
  84. /// Sub-meshes may be rendered independently.</param>
  85. /// <param name="usage">Optimizes performance depending on planned usage of the mesh.</param>
  86. public Mesh(MeshData data, SubMesh[] subMeshes, MeshUsage usage = MeshUsage.Default)
  87. {
  88. IntPtr dataPtr = IntPtr.Zero;
  89. if (data != null)
  90. dataPtr = data.GetCachedPtr();
  91. Internal_CreateInstanceMeshData(this, dataPtr, subMeshes, usage);
  92. }
  93. /// <summary>
  94. /// Returns the number of sub-meshes contained in the mesh.
  95. /// </summary>
  96. public int SubMeshCount
  97. {
  98. get { return Internal_GetSubMeshCount(mCachedPtr); }
  99. }
  100. /// <summary>
  101. /// Returns all sub-meshes contained in the mesh.
  102. /// </summary>
  103. public SubMesh[] SubMeshes
  104. {
  105. get { return Internal_GetSubMeshes(mCachedPtr); }
  106. }
  107. /// <summary>
  108. /// Returns local bounds of the geometry contained in the vertex buffers for all sub-meshes.
  109. /// </summary>
  110. public Bounds Bounds
  111. {
  112. get
  113. {
  114. AABox box;
  115. Sphere sphere;
  116. Internal_GetBounds(mCachedPtr, out box, out sphere);
  117. return new Bounds(box, sphere);
  118. }
  119. }
  120. /// <summary>
  121. /// Accesses the vertex and index data of the mesh. If reading, mesh must have been created with the
  122. /// <see cref="MeshUsage.CPUCached"/> flag. If writing the caller must ensure the data matches mesh's vertex/index
  123. /// counts, vertex layout and index format.
  124. /// </summary>
  125. public MeshData MeshData
  126. {
  127. get { return Internal_GetMeshData(mCachedPtr); }
  128. set
  129. {
  130. IntPtr meshDataPtr = IntPtr.Zero;
  131. if (value != null)
  132. meshDataPtr = value.GetCachedPtr();
  133. Internal_SetMeshData(mCachedPtr, meshDataPtr);
  134. }
  135. }
  136. /// <summary>
  137. /// Gets the skeleton required for animation of this mesh, if any is available.
  138. /// </summary>
  139. public Skeleton Skeleton
  140. {
  141. get { return Internal_GetSkeleton(mCachedPtr); }
  142. }
  143. [MethodImpl(MethodImplOptions.InternalCall)]
  144. private static extern void Internal_CreateInstance(Mesh instance, int numVertices,
  145. int numIndices, SubMesh[] subMeshes, MeshUsage usage, VertexType vertex, IndexType index);
  146. [MethodImpl(MethodImplOptions.InternalCall)]
  147. private static extern void Internal_CreateInstanceMeshData(Mesh instance, IntPtr data, SubMesh[] subMeshes,
  148. MeshUsage usage);
  149. [MethodImpl(MethodImplOptions.InternalCall)]
  150. private static extern SubMesh[] Internal_GetSubMeshes(IntPtr thisPtr);
  151. [MethodImpl(MethodImplOptions.InternalCall)]
  152. private static extern int Internal_GetSubMeshCount(IntPtr thisPtr);
  153. [MethodImpl(MethodImplOptions.InternalCall)]
  154. private static extern Skeleton Internal_GetSkeleton(IntPtr thisPtr);
  155. [MethodImpl(MethodImplOptions.InternalCall)]
  156. private static extern void Internal_GetBounds(IntPtr thisPtr, out AABox box, out Sphere sphere);
  157. [MethodImpl(MethodImplOptions.InternalCall)]
  158. private static extern MeshData Internal_GetMeshData(IntPtr thisPtr);
  159. [MethodImpl(MethodImplOptions.InternalCall)]
  160. private static extern void Internal_SetMeshData(IntPtr thisPtr, IntPtr value);
  161. }
  162. /// <summary>
  163. /// Data about a sub-mesh range and the type of primitives contained in the range.
  164. /// </summary>
  165. [StructLayout(LayoutKind.Sequential)]
  166. public struct SubMesh // Note: Must match C++ class SubMesh
  167. {
  168. public SubMesh(int indexOffset, int indexCount, MeshTopology topology = MeshTopology.TriangleList)
  169. {
  170. IndexOffset = indexOffset;
  171. IndexCount = indexCount;
  172. Topology = topology;
  173. }
  174. public int IndexOffset;
  175. public int IndexCount;
  176. public MeshTopology Topology;
  177. }
  178. /// <summary>
  179. /// Determines how are mesh indices interpreted by the renderer.
  180. /// </summary>
  181. public enum MeshTopology // Note: Must match C++ class MeshTopology
  182. {
  183. PointList = 1,
  184. LineList = 2,
  185. LineStrip = 3,
  186. TriangleList = 4,
  187. TriangleStrip = 5,
  188. TriangleFan = 6
  189. }
  190. /// <summary>
  191. /// Planned usage for the mesh that allow various optimizations.
  192. /// </summary>
  193. public enum MeshUsage // Note: Must match C++ enum MeshUsage
  194. {
  195. /// <summary>
  196. /// Specify for a mesh that is not often updated from the CPU.
  197. /// </summary>
  198. Default = 0x1,
  199. /// <summary>
  200. /// Specify for a mesh that is often updated from the CPU.
  201. /// </summary>
  202. Dynamic = 0x2,
  203. /// <summary>
  204. /// All mesh data will also be cached in CPU memory allowing the mesh data to be read.
  205. /// </summary>
  206. CPUCached = 0x1000
  207. }
  208. /** @} */
  209. }