BsMeshData.h 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337
  1. #pragma once
  2. #include "BsCorePrerequisites.h"
  3. #include "BsGpuResourceData.h"
  4. #include "BsVertexBuffer.h"
  5. #include "BsIndexBuffer.h"
  6. #include "BsVertexDeclaration.h"
  7. #include "BsDrawOps.h"
  8. #include "BsSubMesh.h"
  9. #include "BsBounds.h"
  10. namespace BansheeEngine
  11. {
  12. /**
  13. * @brief Iterator that allows you to easily populate or read vertex elements
  14. * in MeshData.
  15. */
  16. template<class T>
  17. class VertexElemIter
  18. {
  19. public:
  20. VertexElemIter()
  21. :mData(nullptr), mEnd(nullptr), mByteStride(0), mNumElements(0)
  22. {
  23. }
  24. VertexElemIter(UINT8* data, UINT32 byteStride, UINT32 numElements)
  25. :mData(data), mByteStride(byteStride), mNumElements(numElements)
  26. {
  27. mEnd = mData + byteStride * numElements;
  28. }
  29. /**
  30. * @brief Adds a new value to the iterators current position and
  31. * advances the iterator.
  32. */
  33. void addValue(const T& value)
  34. {
  35. setValue(value);
  36. moveNext();
  37. }
  38. /**
  39. * @brief Sets a new value at the iterators current position.
  40. */
  41. void setValue(const T& value)
  42. {
  43. memcpy(mData, &value, sizeof(T));
  44. }
  45. /**
  46. * @brief Returns the value at the iterators current position.
  47. */
  48. T& getValue()
  49. {
  50. return *((T*)mData);
  51. }
  52. /**
  53. * @brief Moves the iterator to the next position. Returns true
  54. * if there are more elements.
  55. */
  56. bool moveNext()
  57. {
  58. #ifdef BS_DEBUG_MODE
  59. if(mData >= mEnd)
  60. {
  61. BS_EXCEPT(InternalErrorException, "Vertex element iterator out of buffer bounds.");
  62. }
  63. #endif
  64. mData += mByteStride;
  65. return mData < mEnd;
  66. }
  67. /**
  68. * @brief Returns the number of elements this iterator can iterate over.
  69. */
  70. UINT32 getNumElements() const { return mNumElements; }
  71. private:
  72. UINT8* mData;
  73. UINT8* mEnd;
  74. UINT32 mByteStride;
  75. UINT32 mNumElements;
  76. };
  77. /**
  78. * @brief Contains per-vertex bone weights and indexes used
  79. * for skinning, for up to four bones.
  80. */
  81. struct BoneWeight
  82. {
  83. int index0;
  84. int index1;
  85. int index2;
  86. int index3;
  87. float weight0;
  88. float weight1;
  89. float weight2;
  90. float weight3;
  91. };
  92. /**
  93. * @brief Used for initializing, updating and reading mesh data from Meshes.
  94. */
  95. class BS_CORE_EXPORT MeshData : public GpuResourceData
  96. {
  97. public:
  98. /**
  99. * @brief Constructs a new object that can hold number of vertices described by the provided vertex data description. As well
  100. * as a number of indices of the provided type.
  101. */
  102. MeshData(UINT32 numVertices, UINT32 numIndexes, const VertexDataDescPtr& vertexData, IndexType indexType = IT_32BIT);
  103. ~MeshData();
  104. /**
  105. * @brief Copies data from "data" parameter into the internal buffer for the specified semantic.
  106. *
  107. * @param semantic Semantic that allows the engine to connect the data to a shader input slot.
  108. * @param data Vertex data, containing at least "size" bytes.
  109. * @param size The size of the data. Must be the size of the vertex element type * number of vertices.
  110. * @param semanticIdx (optional) If there are multiple semantics with the same name, use different index to differentiate between them.
  111. * @param streamIdx (optional) Zero-based index of the stream. Each stream will internally be represented as a single vertex buffer.
  112. */
  113. void setVertexData(VertexElementSemantic semantic, UINT8* data, UINT32 size, UINT32 semanticIdx = 0, UINT32 streamIdx = 0);
  114. /**
  115. * @brief Copies data from the internal buffer to the pre-allocated buffer for the specified semantic.
  116. *
  117. * @param semantic Semantic that allows the engine to connect the data to a shader input slot.
  118. * @param data Buffer that will receive vertex data, of at least "size" bytes.
  119. * @param size The size of the data. Must be the size of the vertex element type * number of vertices.
  120. * @param semanticIdx (optional) If there are multiple semantics with the same name, use different index to differentiate between them.
  121. * @param streamIdx (optional) Zero-based index of the stream. Each stream will internally be represented as a single vertex buffer.
  122. */
  123. void getVertexData(VertexElementSemantic semantic, UINT8* data, UINT32 size, UINT32 semanticIdx = 0, UINT32 streamIdx = 0);
  124. /**
  125. * @brief Returns an iterator you can use for easily retrieving or setting Vector2 vertex elements. This is the preferred
  126. * method of assigning or reading vertex data.
  127. *
  128. * @note If vertex data of this type/semantic/index/stream doesn't exist and exception will be thrown.
  129. */
  130. VertexElemIter<Vector2> getVec2DataIter(VertexElementSemantic semantic, UINT32 semanticIdx = 0, UINT32 streamIdx = 0);
  131. /**
  132. * @brief Returns an iterator you can use for easily retrieving or setting Vector3 vertex elements. This is the preferred
  133. * method of assigning or reading vertex data.
  134. *
  135. * @note If vertex data of this type/semantic/index/stream doesn't exist and exception will be thrown.
  136. */
  137. VertexElemIter<Vector3> getVec3DataIter(VertexElementSemantic semantic, UINT32 semanticIdx = 0, UINT32 streamIdx = 0);
  138. /**
  139. * @brief Returns an iterator you can use for easily retrieving or setting Vector4 vertex elements. This is the preferred
  140. * method of assigning or reading vertex data.
  141. *
  142. * @note If vertex data of this type/semantic/index/stream doesn't exist and exception will be thrown.
  143. */
  144. VertexElemIter<Vector4> getVec4DataIter(VertexElementSemantic semantic, UINT32 semanticIdx = 0, UINT32 streamIdx = 0);
  145. /**
  146. * @brief Returns an iterator you can use for easily retrieving or setting DWORD vertex elements. This is the preferred
  147. * method of assigning or reading vertex data.
  148. *
  149. * @note If vertex data of this type/semantic/index/stream doesn't exist and exception will be thrown.
  150. */
  151. VertexElemIter<UINT32> getDWORDDataIter(VertexElementSemantic semantic, UINT32 semanticIdx = 0, UINT32 streamIdx = 0);
  152. /**
  153. * @brief Returns the total number of vertices this object can hold.
  154. */
  155. UINT32 getNumVertices() const { return mNumVertices; }
  156. /**
  157. * @brief Returns the total number of indices this object can hold.
  158. */
  159. UINT32 getNumIndices() const;
  160. /**
  161. * @brief Returns a 16-bit pointer to the start of the internal index buffer.
  162. */
  163. UINT16* getIndices16() const;
  164. /**
  165. * @brief Returns a 32-bit pointer to the start of the internal index buffer.
  166. */
  167. UINT32* getIndices32() const;
  168. /**
  169. * @brief Returns the size of an index element in bytes.
  170. */
  171. UINT32 getIndexElementSize() const;
  172. /**
  173. * @brief Returns the type of an index element.
  174. */
  175. IndexType getIndexType() const { return mIndexType; }
  176. /**
  177. * @brief Returns the pointer to the first element of the specified type. If you want to
  178. * iterate over all elements you need to call getVertexStride() to get the number
  179. * of bytes you need to advance between each element.
  180. *
  181. * @param semantic Semantic that allows the engine to connect the data to a shader input slot.
  182. * @param semanticIdx (optional) If there are multiple semantics with the same name, use different index to differentiate between them.
  183. * @param streamIdx (optional) Zero-based index of the stream. Each stream will internally be represented as a single vertex buffer.
  184. *
  185. * @return null if it fails, else the element data.
  186. */
  187. UINT8* getElementData(VertexElementSemantic semantic, UINT32 semanticIdx = 0, UINT32 streamIdx = 0) const;
  188. /**
  189. * @brief Returns an offset into the internal buffer where this element with the provided semantic starts.
  190. * Offset is provided in number of bytes.
  191. *
  192. * @param semantic Semantic that allows the engine to connect the data to a shader input slot.
  193. * @param semanticIdx (optional) If there are multiple semantics with the same name, use different index to differentiate between them.
  194. * @param streamIdx (optional) Zero-based index of the stream. Each stream will internally be represented as a single vertex buffer.
  195. */
  196. UINT32 getElementOffset(VertexElementSemantic semantic, UINT32 semanticIdx = 0, UINT32 streamIdx = 0) const;
  197. /**
  198. * @brief Returns an object that describes data contained in a single vertex.
  199. */
  200. const VertexDataDescPtr& getVertexDesc() const { return mVertexData; }
  201. /**
  202. * @brief Return the size (in bytes) of the entire buffer.
  203. */
  204. UINT32 getSize() const { return getInternalBufferSize(); }
  205. /**
  206. * @brief Calculates the bounds of all vertices stored in the internal buffer.
  207. */
  208. Bounds calculateBounds() const;
  209. /**
  210. * @brief Combines a number of submeshes and their mesh data into one large mesh data buffer.
  211. *
  212. * @param elements Data containing vertices and indices referenced by the submeshes. Number of elements
  213. * must be the same as number of submeshes.
  214. * @param subMeshes Submeshes representing vertex and index range to take from mesh data and combine. Number of
  215. * submeshes must match the number of provided MeshData elements.
  216. * @param [out] subMeshes Outputs all combined sub-meshes with their new index and vertex offsets referencing
  217. * the newly created MeshData.
  218. *
  219. * @returns Combined mesh data containing all vertices and indexes references by the provided sub-meshes.
  220. */
  221. static MeshDataPtr combine(const Vector<MeshDataPtr>& elements, const Vector<Vector<SubMesh>>& allSubMeshes,
  222. Vector<SubMesh>& subMeshes);
  223. protected:
  224. /**
  225. * @brief Returns the size of the internal buffer in bytes.
  226. */
  227. UINT32 getInternalBufferSize() const;
  228. private:
  229. /**
  230. * @brief Returns a pointer to the start of the index buffer.
  231. */
  232. UINT8* getIndexData() const { return getData(); }
  233. /**
  234. * @brief Returns a pointer to the start of the specified vertex stream.
  235. */
  236. UINT8* getStreamData(UINT32 streamIdx) const;
  237. /**
  238. * @brief Returns an offset in bytes to the start of the index buffer from the start of the
  239. * internal buffer.
  240. */
  241. UINT32 getIndexBufferOffset() const;
  242. /**
  243. * @brief Returns an offset in bytes to the start of the stream from the start of the
  244. * internal buffer.
  245. */
  246. UINT32 getStreamOffset(UINT32 streamIdx = 0) const;
  247. /**
  248. * @brief Returns the size of the index buffer in bytes.
  249. */
  250. UINT32 getIndexBufferSize() const;
  251. /**
  252. * @brief Returns the size of the specified stream in bytes.
  253. */
  254. UINT32 getStreamSize(UINT32 streamIdx) const;
  255. /**
  256. * @brief Returns the size of all the streams in bytes.
  257. */
  258. UINT32 getStreamSize() const;
  259. /**
  260. * @brief Returns the data needed for iterating over the requested vertex element.
  261. *
  262. * @param semantic Semantic of the element we are looking for.
  263. * @param semanticIdx If there are multiple semantics with the same name, use different index to differentiate between them.
  264. * @param streamIdx Zero-based index of the stream the element resides in.
  265. * @param [out] data Pointer to the start of this elements data.
  266. * @param [out] stride Number of bytes between vertex elements of this type.
  267. */
  268. void getDataForIterator(VertexElementSemantic semantic, UINT32 semanticIdx, UINT32 streamIdx, UINT8*& data, UINT32& stride) const;
  269. private:
  270. friend class Mesh;
  271. friend class MeshCore;
  272. friend class MeshHeap;
  273. friend class MeshHeapCore;
  274. UINT32 mDescBuilding;
  275. UINT32 mNumVertices;
  276. UINT32 mNumIndices;
  277. IndexType mIndexType;
  278. VertexDataDescPtr mVertexData;
  279. /************************************************************************/
  280. /* SERIALIZATION */
  281. /************************************************************************/
  282. private:
  283. MeshData(); // Serialization only
  284. public:
  285. friend class MeshDataRTTI;
  286. static RTTITypeBase* getRTTIStatic();
  287. virtual RTTITypeBase* getRTTI() const;
  288. };
  289. }