Mesh.cs 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  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. }
  129. [MethodImpl(MethodImplOptions.InternalCall)]
  130. private static extern void Internal_CreateInstance(Mesh instance, int numVertices,
  131. int numIndices, SubMesh[] subMeshes, MeshUsage usage, VertexType vertex, IndexType index);
  132. [MethodImpl(MethodImplOptions.InternalCall)]
  133. private static extern void Internal_CreateInstanceMeshData(Mesh instance, IntPtr data, SubMesh[] subMeshes,
  134. MeshUsage usage);
  135. [MethodImpl(MethodImplOptions.InternalCall)]
  136. private static extern SubMesh[] Internal_GetSubMeshes(IntPtr thisPtr);
  137. [MethodImpl(MethodImplOptions.InternalCall)]
  138. private static extern int Internal_GetSubMeshCount(IntPtr thisPtr);
  139. [MethodImpl(MethodImplOptions.InternalCall)]
  140. private static extern void Internal_GetBounds(IntPtr thisPtr, out AABox box, out Sphere sphere);
  141. [MethodImpl(MethodImplOptions.InternalCall)]
  142. private static extern MeshData Internal_GetMeshData(IntPtr thisPtr);
  143. [MethodImpl(MethodImplOptions.InternalCall)]
  144. private static extern void Internal_SetMeshData(IntPtr thisPtr, IntPtr value);
  145. }
  146. /// <summary>
  147. /// Data about a sub-mesh range and the type of primitives contained in the range.
  148. /// </summary>
  149. [StructLayout(LayoutKind.Sequential)]
  150. public struct SubMesh // Note: Must match C++ class SubMesh
  151. {
  152. public SubMesh(int indexOffset, int indexCount, MeshTopology topology = MeshTopology.TriangleList)
  153. {
  154. IndexOffset = indexOffset;
  155. IndexCount = indexCount;
  156. Topology = topology;
  157. }
  158. public int IndexOffset;
  159. public int IndexCount;
  160. public MeshTopology Topology;
  161. }
  162. /// <summary>
  163. /// Determines how are mesh indices interpreted by the renderer.
  164. /// </summary>
  165. public enum MeshTopology // Note: Must match C++ class MeshTopology
  166. {
  167. PointList = 1,
  168. LineList = 2,
  169. LineStrip = 3,
  170. TriangleList = 4,
  171. TriangleStrip = 5,
  172. TriangleFan = 6
  173. }
  174. /// <summary>
  175. /// Planned usage for the mesh that allow various optimizations.
  176. /// </summary>
  177. public enum MeshUsage // Note: Must match C++ enum MeshUsage
  178. {
  179. /// <summary>
  180. /// Specify for a mesh that is not often updated from the CPU.
  181. /// </summary>
  182. Default = 0x1,
  183. /// <summary>
  184. /// Specify for a mesh that is often updated from the CPU.
  185. /// </summary>
  186. Dynamic = 0x2,
  187. /// <summary>
  188. /// All mesh data will also be cached in CPU memory allowing the mesh data to be read.
  189. /// </summary>
  190. CPUCached = 0x1000
  191. }
  192. /** @} */
  193. }