BsMesh.h 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403
  1. //********************************** Banshee Engine (www.banshee3d.com) **************************************************//
  2. //**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
  3. #pragma once
  4. #include "BsCorePrerequisites.h"
  5. #include "Mesh/BsMeshBase.h"
  6. #include "Mesh/BsMeshData.h"
  7. #include "RenderAPI/BsVertexData.h"
  8. #include "RenderAPI/BsSubMesh.h"
  9. #include "Math/BsBounds.h"
  10. namespace bs
  11. {
  12. /** @addtogroup Resources
  13. * @{
  14. */
  15. /** Descriptor object used for creation of a new Mesh object. */
  16. struct BS_CORE_EXPORT MESH_DESC
  17. {
  18. MESH_DESC() { }
  19. /** Number of vertices in the mesh. */
  20. UINT32 numVertices = 0;
  21. /** Number of indices in the mesh. */
  22. UINT32 numIndices = 0;
  23. /**
  24. * Vertex description structure that describes how are vertices organized in the vertex buffer. When binding a mesh
  25. * to the pipeline you must ensure vertex description at least partially matches the input description of the
  26. * currently bound vertex GPU program.
  27. */
  28. SPtr<VertexDataDesc> vertexDesc;
  29. /**
  30. * Defines how are indices separated into sub-meshes, and how are those sub-meshes rendered. Sub-meshes may be
  31. * rendered independently.
  32. */
  33. Vector<SubMesh> subMeshes;
  34. /** Optimizes performance depending on planned usage of the mesh. */
  35. INT32 usage = MU_STATIC;
  36. /**
  37. * Size of indices, use smaller size for better performance, however be careful not to go over the number of
  38. * vertices limited by the size.
  39. */
  40. IndexType indexType = IT_32BIT;
  41. /** Optional skeleton that can be used for skeletal animation of the mesh. */
  42. SPtr<Skeleton> skeleton;
  43. /** Optional set of morph shapes that can be used for per-vertex animation of the mesh. */
  44. SPtr<MorphShapes> morphShapes;
  45. static MESH_DESC DEFAULT;
  46. };
  47. /**
  48. * Primary class for holding geometry. Stores data in the form of vertex buffers and optionally an index buffer, which
  49. * may be bound to the pipeline for drawing. May contain multiple sub-meshes.
  50. */
  51. class BS_CORE_EXPORT BS_SCRIPT_EXPORT(m:Rendering) Mesh : public MeshBase
  52. {
  53. public:
  54. virtual ~Mesh();
  55. /** @copydoc MeshBase::initialize */
  56. void initialize() override;
  57. /**
  58. * Updates the mesh with new data. Provided data buffer will be locked until the operation completes.
  59. *
  60. * @param[in] data Data of valid size and format to write to the subresource.
  61. * @param[in] discardEntireBuffer When true the existing contents of the resource you are updating will be
  62. * discarded. This can make the operation faster. Resources with certain buffer
  63. * types might require this flag to be in a specific state otherwise the operation
  64. * will fail.
  65. * @return Async operation object you can use to track operation completion.
  66. *
  67. * @note This is an @ref asyncMethod "asynchronous method".
  68. */
  69. AsyncOp writeData(const SPtr<MeshData>& data, bool discardEntireBuffer);
  70. /**
  71. * Reads internal mesh data to the provided previously allocated buffer. Provided data buffer will be locked until
  72. * the operation completes.
  73. *
  74. * @param[out] data Pre-allocated buffer of proper vertex/index format and size where data will be read
  75. * to. You can use allocBuffer() to allocate a buffer of a correct format and size.
  76. * @return Async operation object you can use to track operation completion.
  77. *
  78. * @note This is an @ref asyncMethod "asynchronous method".
  79. */
  80. AsyncOp readData(const SPtr<MeshData>& data);
  81. /**
  82. * Allocates a buffer that exactly matches the size of this mesh. This is a helper function, primarily meant for
  83. * creating buffers when reading from, or writing to a mesh.
  84. *
  85. * @note Thread safe.
  86. */
  87. SPtr<MeshData> allocBuffer() const;
  88. /**
  89. * Reads data from the cached system memory mesh buffer into the provided buffer.
  90. *
  91. * @param[out] data Pre-allocated buffer of proper vertex/index format and size where data will be read to.
  92. * You can use allocBuffer() to allocate a buffer of a correct format and size.
  93. *
  94. * @note
  95. * The data read is the cached mesh data. Any data written to the mesh from the GPU or core thread will not be
  96. * reflected in this data. Use readData() if you require those changes.
  97. * @note
  98. * The mesh must have been created with MU_CPUCACHED usage otherwise this method will not return any data.
  99. */
  100. void readCachedData(MeshData& data);
  101. /** Gets the skeleton required for animation of this mesh, if any is available. */
  102. BS_SCRIPT_EXPORT(pr:getter,n:Skeleton)
  103. SPtr<Skeleton> getSkeleton() const { return mSkeleton; }
  104. /** Returns an object containing all shapes used for morph animation, if any are available. */
  105. BS_SCRIPT_EXPORT(pr:getter,n:MorphShapes)
  106. SPtr<MorphShapes> getMorphShapes() const { return mMorphShapes; }
  107. /** Retrieves a core implementation of a mesh usable only from the core thread. */
  108. SPtr<ct::Mesh> getCore() const;
  109. /** Returns a dummy mesh, containing just one triangle. Don't modify the returned mesh. */
  110. static HMesh dummy();
  111. protected:
  112. friend class MeshManager;
  113. Mesh(const MESH_DESC& desc);
  114. Mesh(const SPtr<MeshData>& initialMeshData, const MESH_DESC& desc);
  115. /** Updates bounds by calculating them from the vertices in the provided mesh data object. */
  116. void updateBounds(const MeshData& meshData);
  117. /** @copydoc CoreObject::createCore */
  118. SPtr<ct::CoreObject> createCore() const override;
  119. /**
  120. * Creates buffers used for caching of CPU mesh data.
  121. *
  122. * @note Make sure to initialize all mesh properties before calling this.
  123. */
  124. void createCPUBuffer();
  125. /** Updates the cached CPU buffers with new data. */
  126. void updateCPUBuffer(UINT32 subresourceIdx, const MeshData& data);
  127. mutable SPtr<MeshData> mCPUData;
  128. SPtr<VertexDataDesc> mVertexDesc;
  129. int mUsage;
  130. IndexType mIndexType;
  131. SPtr<Skeleton> mSkeleton; // Immutable
  132. SPtr<MorphShapes> mMorphShapes; // Immutable
  133. /************************************************************************/
  134. /* SERIALIZATION */
  135. /************************************************************************/
  136. private:
  137. Mesh(); // Serialization only
  138. public:
  139. friend class MeshRTTI;
  140. static RTTITypeBase* getRTTIStatic();
  141. RTTITypeBase* getRTTI() const override;
  142. /************************************************************************/
  143. /* STATICS */
  144. /************************************************************************/
  145. public:
  146. /**
  147. * Creates a new empty mesh. Created mesh will have no sub-meshes.
  148. *
  149. * @param[in] numVertices Number of vertices in the mesh.
  150. * @param[in] numIndices Number of indices in the mesh.
  151. * @param[in] vertexDesc Vertex description structure that describes how are vertices organized in the
  152. * vertex buffer. When binding a mesh to the pipeline you must ensure vertex
  153. * description at least partially matches the input description of the currently bound
  154. * vertex GPU program.
  155. * @param[in] usage Optimizes performance depending on planned usage of the mesh.
  156. * @param[in] drawOp Determines how should the provided indices be interpreted by the pipeline. Default
  157. * option is a triangle list, where three indices represent a single triangle.
  158. * @param[in] indexType Size of indices, use smaller size for better performance, however be careful not to
  159. * go over the number of vertices limited by the size.
  160. */
  161. static HMesh create(UINT32 numVertices, UINT32 numIndices, const SPtr<VertexDataDesc>& vertexDesc,
  162. int usage = MU_STATIC, DrawOperationType drawOp = DOT_TRIANGLE_LIST, IndexType indexType = IT_32BIT);
  163. /**
  164. * Creates a new empty mesh.
  165. *
  166. * @param[in] desc Descriptor containing the properties of the mesh to create.
  167. */
  168. static HMesh create(const MESH_DESC& desc);
  169. /**
  170. * Creates a new mesh from an existing mesh data. Created mesh will match the vertex and index buffers described
  171. * by the mesh data exactly. Mesh will have no sub-meshes.
  172. *
  173. * @param[in] initialData Vertex and index data to initialize the mesh with.
  174. * @param[in] desc Descriptor containing the properties of the mesh to create. Vertex and index count,
  175. * vertex descriptor and index type properties are ignored and are read from provided
  176. * mesh data instead.
  177. */
  178. static HMesh create(const SPtr<MeshData>& initialData, const MESH_DESC& desc);
  179. /**
  180. * Creates a new mesh from an existing mesh data. Created mesh will match the vertex and index buffers described
  181. * by the mesh data exactly. Mesh will have no sub-meshes.
  182. *
  183. * @param[in] initialData Vertex and index data to initialize the mesh with.
  184. * @param[in] usage Optimizes performance depending on planned usage of the mesh.
  185. * @param[in] drawOp Determines how should the provided indices be interpreted by the pipeline. Default
  186. * option is a triangle strip, where three indices represent a single triangle.
  187. */
  188. static HMesh create(const SPtr<MeshData>& initialData, int usage = MU_STATIC,
  189. DrawOperationType drawOp = DOT_TRIANGLE_LIST);
  190. /** @name Internal
  191. * @{
  192. */
  193. /**
  194. * @copydoc create(const MESH_DESC&)
  195. *
  196. * @note Internal method. Use create() for normal use.
  197. */
  198. static SPtr<Mesh> _createPtr(const MESH_DESC& desc);
  199. /**
  200. * @copydoc create(const SPtr<MeshData>&, const MESH_DESC&)
  201. *
  202. * @note Internal method. Use create() for normal use.
  203. */
  204. static SPtr<Mesh> _createPtr(const SPtr<MeshData>& initialData, const MESH_DESC& desc);
  205. /**
  206. * @copydoc create(const SPtr<MeshData>&, int, DrawOperationType)
  207. *
  208. * @note Internal method. Use create() for normal use.
  209. */
  210. static SPtr<Mesh> _createPtr(const SPtr<MeshData>& initialData, int usage = MU_STATIC,
  211. DrawOperationType drawOp = DOT_TRIANGLE_LIST);
  212. /**
  213. * Creates a new empty and uninitialized mesh. You will need to manually initialize the mesh before using it.
  214. *
  215. * @note This should only be used for special cases like serialization and is not meant for normal use.
  216. */
  217. static SPtr<Mesh> createEmpty();
  218. /** @} */
  219. };
  220. /** @} */
  221. namespace ct
  222. {
  223. /** @addtogroup Resources-Internal
  224. * @{
  225. */
  226. /**
  227. * Core thread portion of a bs::Mesh.
  228. *
  229. * @note Core thread.
  230. */
  231. class BS_CORE_EXPORT Mesh : public MeshBase
  232. {
  233. public:
  234. Mesh(const SPtr<MeshData>& initialMeshData, const MESH_DESC& desc, GpuDeviceFlags deviceMask);
  235. ~Mesh();
  236. /** @copydoc CoreObject::initialize */
  237. void initialize() override;
  238. /** @copydoc MeshBase::getVertexData */
  239. SPtr<VertexData> getVertexData() const override;
  240. /** @copydoc MeshBase::getIndexBuffer */
  241. SPtr<IndexBuffer> getIndexBuffer() const override;
  242. /** @copydoc MeshBase::getVertexDesc */
  243. SPtr<VertexDataDesc> getVertexDesc() const override;
  244. /** Returns a skeleton that can be used for animating the mesh. */
  245. SPtr<Skeleton> getSkeleton() const { return mSkeleton; }
  246. /** Returns an object containing all shapes used for morph animation, if any are available. */
  247. SPtr<MorphShapes> getMorphShapes() const { return mMorphShapes; }
  248. /**
  249. * Updates the current mesh with the provided data.
  250. *
  251. * @param[in] data Data to update the mesh with.
  252. * @param[in] discardEntireBuffer When true the existing contents of the resource you are updating will be
  253. * discarded. This can make the operation faster. Resources with certain buffer
  254. * types might require this flag to be in a specific state otherwise the operation
  255. * will fail.
  256. * @param[in] updateBounds If true the internal bounds of the mesh will be recalculated based on the
  257. * provided data.
  258. * @param[in] queueIdx Device queue to perform the write operation on. See @ref queuesDoc.
  259. */
  260. virtual void writeData(const MeshData& data, bool discardEntireBuffer, bool updateBounds = true,
  261. UINT32 queueIdx = 0);
  262. /**
  263. * Reads the current mesh data into the provided @p data parameter. Data buffer needs to be pre-allocated.
  264. *
  265. * @param[out] data Pre-allocated buffer of proper vertex/index format and size where data will be
  266. * read to. You can use Mesh::allocBuffer() to allocate a buffer of a correct
  267. * format and size.
  268. * @param[in] deviceIdx Index of the device whose memory to read. If the buffer doesn't exist on this
  269. * device, no data will be read.
  270. * @param[in] queueIdx Device queue to perform the read operation on. See @ref queuesDoc.
  271. */
  272. virtual void readData(MeshData& data, UINT32 deviceIdx = 0, UINT32 queueIdx = 0);
  273. /**
  274. * Creates a new empty mesh. Created mesh will have no sub-meshes.
  275. *
  276. * @param[in] numVertices Number of vertices in the mesh.
  277. * @param[in] numIndices Number of indices in the mesh.
  278. * @param[in] vertexDesc Vertex description structure that describes how are vertices organized in the
  279. * vertex buffer. When binding a mesh to the pipeline you must ensure vertex
  280. * description at least partially matches the input description of the currently
  281. * bound vertex GPU program.
  282. * @param[in] usage Optimizes performance depending on planned usage of the mesh.
  283. * @param[in] drawOp Determines how should the provided indices be interpreted by the pipeline. Default
  284. * option is a triangle list, where three indices represent a single triangle.
  285. * @param[in] indexType Size of indices, use smaller size for better performance, however be careful not to
  286. * go over the number of vertices limited by the size.
  287. * @param[in] deviceMask Mask that determines on which GPU devices should the object be created on.
  288. */
  289. static SPtr<Mesh> create(UINT32 numVertices, UINT32 numIndices, const SPtr<VertexDataDesc>& vertexDesc,
  290. int usage = MU_STATIC, DrawOperationType drawOp = DOT_TRIANGLE_LIST, IndexType indexType = IT_32BIT,
  291. GpuDeviceFlags deviceMask = GDF_DEFAULT);
  292. /**
  293. * Creates a new empty mesh.
  294. *
  295. * @param[in] desc Descriptor containing the properties of the mesh to create.
  296. * @param[in] deviceMask Mask that determines on which GPU devices should the object be created on.
  297. */
  298. static SPtr<Mesh> create(const MESH_DESC& desc, GpuDeviceFlags deviceMask = GDF_DEFAULT);
  299. /**
  300. * Creates a new mesh from an existing mesh data. Created mesh will match the vertex and index buffers described
  301. * by the mesh data exactly.
  302. *
  303. * @param[in] initialData Vertex and index data to initialize the mesh with.
  304. * @param[in] desc Descriptor containing the properties of the mesh to create. Vertex and index count,
  305. * vertex descriptor and index type properties are ignored and are read from provided
  306. * mesh data instead.
  307. * @param[in] deviceMask Mask that determines on which GPU devices should the object be created on.
  308. */
  309. static SPtr<Mesh> create(const SPtr<MeshData>& initialData, const MESH_DESC& desc,
  310. GpuDeviceFlags deviceMask = GDF_DEFAULT);
  311. /**
  312. * Creates a new mesh from an existing mesh data. Created mesh will match the vertex and index buffers described
  313. * by the mesh data exactly. Mesh will have no sub-meshes.
  314. *
  315. * @param[in] initialData Vertex and index data to initialize the mesh with.
  316. * @param[in] usage Optimizes performance depending on planned usage of the mesh.
  317. * @param[in] drawOp Determines how should the provided indices be interpreted by the pipeline. Default
  318. * option is a triangle strip, where three indices represent a single triangle.
  319. * @param[in] deviceMask Mask that determines on which GPU devices should the object be created on.
  320. */
  321. static SPtr<Mesh> create(const SPtr<MeshData>& initialData, int usage = MU_STATIC,
  322. DrawOperationType drawOp = DOT_TRIANGLE_LIST, GpuDeviceFlags deviceMask = GDF_DEFAULT);
  323. protected:
  324. friend class bs::Mesh;
  325. /** Updates bounds by calculating them from the vertices in the provided mesh data object. */
  326. void updateBounds(const MeshData& meshData);
  327. SPtr<VertexData> mVertexData;
  328. SPtr<IndexBuffer> mIndexBuffer;
  329. SPtr<VertexDataDesc> mVertexDesc;
  330. int mUsage;
  331. IndexType mIndexType;
  332. GpuDeviceFlags mDeviceMask;
  333. SPtr<MeshData> mTempInitialMeshData;
  334. SPtr<Skeleton> mSkeleton; // Immutable
  335. SPtr<MorphShapes> mMorphShapes; // Immutable
  336. };
  337. /** @} */
  338. }
  339. }