BsMesh.h 14 KB

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