BsMeshData.h 10 KB

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