BsMeshData.h 12 KB

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