CmMeshData.cpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402
  1. #include "CmMeshData.h"
  2. #include "CmVector2.h"
  3. #include "CmVector3.h"
  4. #include "CmHardwareBufferManager.h"
  5. #include "CmMeshDataRTTI.h"
  6. #include "CmVertexDeclaration.h"
  7. #include "CmException.h"
  8. namespace CamelotEngine
  9. {
  10. MeshData::MeshData(IndexBuffer::IndexType indexType)
  11. :mIndexType(indexType)
  12. {
  13. }
  14. MeshData::~MeshData()
  15. {
  16. for(auto& vertElems : mVertexData)
  17. {
  18. for(auto& vertElem : vertElems.second)
  19. {
  20. if(vertElem.data != nullptr)
  21. CM_DELETE_BYTES(vertElem.data, ScratchAlloc);
  22. }
  23. }
  24. for(auto& indexData : mIndices)
  25. {
  26. if(indexData.indices != nullptr)
  27. CM_DELETE_BYTES(indexData.indices, ScratchAlloc);
  28. }
  29. }
  30. Vector2* MeshData::addPositionsVec2(UINT32 numElements, UINT32 streamIdx)
  31. {
  32. return reinterpret_cast<Vector2*>(addVertexElementData(VET_FLOAT2, VES_POSITION, numElements, 0, streamIdx));
  33. }
  34. Vector3* MeshData::addPositionsVec3(UINT32 numElements, UINT32 streamIdx)
  35. {
  36. return reinterpret_cast<Vector3*>(addVertexElementData(VET_FLOAT3, VES_POSITION, numElements, 0, streamIdx));
  37. }
  38. Vector4* MeshData::addPositionsVec4(UINT32 numElements, UINT32 streamIdx)
  39. {
  40. return reinterpret_cast<Vector4*>(addVertexElementData(VET_FLOAT4, VES_POSITION, numElements, 0, streamIdx));
  41. }
  42. Vector3* MeshData::addNormals(UINT32 numElements, UINT32 streamIdx)
  43. {
  44. return reinterpret_cast<Vector3*>(addVertexElementData(VET_FLOAT3, VES_NORMAL, numElements, 0, streamIdx));
  45. }
  46. Vector3* MeshData::addTangentsVec3(UINT32 numElements, UINT32 streamIdx)
  47. {
  48. return reinterpret_cast<Vector3*>(addVertexElementData(VET_FLOAT3, VES_TANGENT, numElements, 0, streamIdx));
  49. }
  50. Vector4* MeshData::addTangentsVec4(UINT32 numElements, UINT32 streamIdx)
  51. {
  52. return reinterpret_cast<Vector4*>(addVertexElementData(VET_FLOAT4, VES_TANGENT, numElements, 0, streamIdx));
  53. }
  54. Vector3* MeshData::addBitangents(UINT32 numElements, UINT32 streamIdx)
  55. {
  56. return reinterpret_cast<Vector3*>(addVertexElementData(VET_FLOAT3, VES_BITANGENT, numElements, 0, streamIdx));
  57. }
  58. Vector2* MeshData::addUV0(UINT32 numElements, UINT32 streamIdx)
  59. {
  60. return reinterpret_cast<Vector2*>(addVertexElementData(VET_FLOAT2, VES_TEXCOORD, numElements, 0, streamIdx));
  61. }
  62. Vector2* MeshData::addUV1(UINT32 numElements, UINT32 streamIdx)
  63. {
  64. return reinterpret_cast<Vector2*>(addVertexElementData(VET_FLOAT2, VES_TEXCOORD, numElements, 1, streamIdx));
  65. }
  66. Color* MeshData::addColorsFloat(UINT32 numElements, UINT32 streamIdx)
  67. {
  68. return reinterpret_cast<Color*>(addVertexElementData(VET_FLOAT4, VES_COLOR, numElements, 0, streamIdx));
  69. }
  70. UINT32* MeshData::addColorsDWORD(UINT32 numElements, UINT32 streamIdx)
  71. {
  72. return reinterpret_cast<UINT32*>(addVertexElementData(VET_COLOR, VES_COLOR, numElements, 0, streamIdx));
  73. }
  74. UINT8* MeshData::addVertexElementData(VertexElementType type, VertexElementSemantic semantic, UINT32 numElements, UINT32 semanticIdx, UINT32 streamIdx)
  75. {
  76. clearIfItExists(type, semantic, semanticIdx, streamIdx);
  77. UINT32 elemSize = VertexElement::getTypeSize(type);
  78. UINT8* elements = CM_NEW_BYTES(elemSize * numElements, ScratchAlloc);
  79. vector<VertexElementData>::type& elemData = mVertexData[streamIdx];
  80. VertexElementData newElement(type, semantic, semanticIdx, streamIdx, elements, numElements);
  81. elemData.push_back(newElement);
  82. return elements;
  83. }
  84. UINT32* MeshData::addIndices32(UINT32 numIndices, UINT32 subMesh)
  85. {
  86. if(mIndexType != IndexBuffer::IT_32BIT)
  87. CM_EXCEPT(InvalidParametersException, "Trying to set 32bit indices but the MeshData was initialized as 16bit.");
  88. if(subMesh >= mIndices.size())
  89. mIndices.resize(subMesh + 1);
  90. IndexElementData indexData = mIndices[subMesh];
  91. if(indexData.indices != nullptr)
  92. CM_DELETE_BYTES(indexData.indices, ScratchAlloc);
  93. UINT32* indices = (UINT32*)CM_NEW_BYTES(numIndices * sizeof(UINT32), ScratchAlloc);
  94. indexData.indices = (UINT8*)indices;
  95. indexData.numIndices = numIndices;
  96. indexData.elementSize = getIndexElementSize();
  97. indexData.subMesh = subMesh;
  98. mIndices[subMesh] = indexData;
  99. return indices;
  100. }
  101. UINT16* MeshData::addIndices16(UINT32 numIndices, UINT32 subMesh)
  102. {
  103. if(mIndexType != IndexBuffer::IT_16BIT)
  104. CM_EXCEPT(InvalidParametersException, "Trying to set 16bit indices but the MeshData was initialized as 32bit.");
  105. if(subMesh >= mIndices.size())
  106. mIndices.resize(subMesh + 1);
  107. IndexElementData indexData = mIndices[subMesh];
  108. if(indexData.indices != nullptr)
  109. CM_DELETE_BYTES(indexData.indices, ScratchAlloc);
  110. UINT16* indices = (UINT16*)CM_NEW_BYTES(numIndices * sizeof(UINT16), ScratchAlloc);
  111. indexData.indices = (UINT8*)indices;
  112. indexData.numIndices = numIndices;
  113. indexData.elementSize = getIndexElementSize();
  114. indexData.subMesh = subMesh;
  115. mIndices[subMesh] = indexData;
  116. return indices;
  117. }
  118. VertexDeclarationPtr MeshData::createDeclaration() const
  119. {
  120. VertexDeclarationPtr declaration = HardwareBufferManager::instance().createVertexDeclaration();
  121. for(auto& vertElems : mVertexData)
  122. {
  123. UINT32 offset = 0;
  124. for(auto& vertElem : vertElems.second)
  125. {
  126. declaration->addElement(vertElems.first, offset, vertElem.element.getType(), vertElem.element.getSemantic(), vertElem.element.getIndex());
  127. offset += vertElem.element.getSize();
  128. }
  129. }
  130. return declaration;
  131. }
  132. UINT32 MeshData::getNumVertices() const
  133. {
  134. UINT32 numVertices = 0;
  135. auto vertElemDataPerStream = mVertexData;
  136. MeshData::VertexElementData* firstElemData = nullptr;
  137. if(vertElemDataPerStream.size() > 0)
  138. {
  139. auto vertElemData = vertElemDataPerStream.begin()->second;
  140. auto firstVertElem = vertElemData.begin();
  141. if(firstVertElem != vertElemData.end())
  142. {
  143. numVertices = firstVertElem->elementCount;
  144. }
  145. }
  146. for(auto& vertElems : mVertexData)
  147. {
  148. for(auto& vertElem : vertElems.second)
  149. {
  150. if(vertElem.elementCount != numVertices)
  151. {
  152. CM_EXCEPT(InvalidParametersException, "All vertex element arrays in MeshData need to be of the same size. Found an array with semantic: " \
  153. + toString(vertElem.element.getSemantic()) + " and element count: " + toString(vertElem.elementCount) + ". This doesn't match with other " \
  154. + "element with semantic: " + toString(firstElemData->element.getSemantic()) + " and element count: " + toString(firstElemData->elementCount));
  155. }
  156. }
  157. }
  158. return numVertices;
  159. }
  160. UINT32 MeshData::getNumIndices(UINT32 subMesh) const
  161. {
  162. return mIndices.at(subMesh).numIndices;
  163. }
  164. UINT16* MeshData::getIndices16(UINT32 subMesh) const
  165. {
  166. return (UINT16*)mIndices.at(subMesh).indices;
  167. }
  168. UINT32* MeshData::getIndices32(UINT32 subMesh) const
  169. {
  170. return (UINT32*)mIndices.at(subMesh).indices;
  171. }
  172. vector<VertexElement>::type MeshData::getVertexElements() const
  173. {
  174. vector<VertexElement>::type elements;
  175. for(auto& vertElems : mVertexData)
  176. {
  177. UINT32 offset = 0;
  178. for(auto& vertElem : vertElems.second)
  179. {
  180. elements.push_back(vertElem.element);
  181. }
  182. }
  183. return elements;
  184. }
  185. MeshDataPtr MeshData::combine(const vector<MeshDataPtr>::type& elements)
  186. {
  187. MeshDataPtr combinedMeshData(CM_NEW(MeshData, PoolAlloc) MeshData(),
  188. &MemAllocDeleter<MeshData, PoolAlloc>::deleter);
  189. UINT32 subMeshIndex = 0;
  190. vector<VertexElement>::type combinedVertexElements;
  191. vector<UINT8*>::type vertexElemData;
  192. vector<UINT32>::type bufferOffsets;
  193. UINT32 totalVertexCount = 0;
  194. UINT32 vertexIndexOffset = 0;
  195. for(auto& meshData : elements)
  196. {
  197. for(UINT32 i = 0; i < meshData->getNumSubmeshes(); i++)
  198. {
  199. UINT32 numIndices = meshData->getNumIndices(i);
  200. UINT32* indices = combinedMeshData->addIndices32(numIndices, subMeshIndex);
  201. UINT32* sourceIndices = meshData->getIndices32(i);
  202. for(UINT32 j = 0; j < numIndices; j++)
  203. indices[j] = sourceIndices[j] + vertexIndexOffset;
  204. subMeshIndex++;
  205. }
  206. UINT32 numVertices = meshData->getNumVertices();
  207. totalVertexCount += numVertices;
  208. vertexIndexOffset += numVertices;
  209. }
  210. UINT32 vertexOffset = 0;
  211. for(auto& meshData : elements)
  212. {
  213. vector<VertexElement>::type vertexElements = meshData->getVertexElements();
  214. UINT32 numVertices = meshData->getNumVertices();
  215. for(auto& newElement : vertexElements)
  216. {
  217. INT32 alreadyExistsIdx = -1;
  218. UINT32 idx = 0;
  219. for(auto& existingElement : combinedVertexElements)
  220. {
  221. if(newElement == existingElement)
  222. {
  223. alreadyExistsIdx = idx;
  224. break;
  225. }
  226. idx++;
  227. }
  228. if(alreadyExistsIdx == -1)
  229. {
  230. combinedVertexElements.push_back(newElement);
  231. UINT8* newBuffer = combinedMeshData->addVertexElementData(newElement.getType(), newElement.getSemantic(), totalVertexCount, newElement.getIndex(), newElement.getSource());
  232. UINT32 newBufferSize = totalVertexCount * newElement.getSize();
  233. memset(newBuffer, 0, newBufferSize);
  234. vertexElemData.push_back(newBuffer);
  235. bufferOffsets.push_back(0);
  236. alreadyExistsIdx = (UINT32)vertexElemData.size() - 1;
  237. }
  238. UINT8* source = meshData->getVertElemData(newElement.getType(), newElement.getSemantic(), newElement.getIndex(), newElement.getSource()).data;
  239. UINT32 offset = vertexOffset * newElement.getSize();
  240. memcpy(&(vertexElemData[alreadyExistsIdx]) + offset, source, numVertices * newElement.getSize());
  241. }
  242. vertexOffset += meshData->getNumVertices();
  243. }
  244. return combinedMeshData;
  245. }
  246. bool MeshData::hasElement(VertexElementSemantic semantic, UINT32 semanticIdx, UINT32 streamIdx) const
  247. {
  248. auto elemDataIter = mVertexData.find(streamIdx);
  249. if(elemDataIter == mVertexData.end())
  250. return false;
  251. const vector<VertexElementData>::type& elemData = elemDataIter->second;
  252. auto findIter = std::find_if(elemData.begin(), elemData.end(),
  253. [semantic, semanticIdx] (const VertexElementData& x)
  254. {
  255. return x.element.getSemantic() == semantic && x.element.getIndex() == semanticIdx;
  256. });
  257. if(findIter != elemData.end())
  258. return true;
  259. return false;
  260. }
  261. void MeshData::clearIfItExists(VertexElementType type, VertexElementSemantic semantic, UINT32 semanticIdx, UINT32 streamIdx)
  262. {
  263. vector<VertexElementData>::type& elemData = mVertexData[streamIdx];
  264. auto findIter = std::find_if(elemData.begin(), elemData.end(),
  265. [type, semantic, semanticIdx] (const VertexElementData& x)
  266. {
  267. return x.element.getSemantic() == semantic && x.element.getIndex() == semanticIdx;
  268. });
  269. if(findIter != elemData.end())
  270. {
  271. if(findIter->data != nullptr)
  272. CM_DELETE_BYTES(findIter->data, ScratchAlloc);
  273. elemData.erase(findIter);
  274. }
  275. }
  276. MeshData::VertexElementData& MeshData::getVertElemData(VertexElementType type, VertexElementSemantic semantic, UINT32 semanticIdx, UINT32 streamIdx)
  277. {
  278. vector<VertexElementData>::type& elemData = mVertexData[streamIdx];
  279. auto findIter = std::find_if(elemData.begin(), elemData.end(),
  280. [type, semantic, semanticIdx] (const VertexElementData& x)
  281. {
  282. return x.element.getSemantic() == semantic && x.element.getIndex() == semanticIdx;
  283. });
  284. if(findIter == elemData.end())
  285. CM_EXCEPT(InvalidParametersException, "No vertex element of specified type exists.");
  286. return *findIter;
  287. }
  288. /************************************************************************/
  289. /* SERIALIZATION */
  290. /************************************************************************/
  291. RTTITypeBase* MeshData::VertexElementData::getRTTIStatic()
  292. {
  293. return VertexElementDataRTTI::instance();
  294. }
  295. RTTITypeBase* MeshData::VertexElementData::getRTTI() const
  296. {
  297. return VertexElementData::getRTTIStatic();
  298. }
  299. RTTITypeBase* MeshData::IndexElementData::getRTTIStatic()
  300. {
  301. return IndexElementDataRTTI::instance();
  302. }
  303. RTTITypeBase* MeshData::IndexElementData::getRTTI() const
  304. {
  305. return IndexElementData::getRTTIStatic();
  306. }
  307. RTTITypeBase* MeshData::getRTTIStatic()
  308. {
  309. return MeshDataRTTI::instance();
  310. }
  311. RTTITypeBase* MeshData::getRTTI() const
  312. {
  313. return MeshData::getRTTIStatic();
  314. }
  315. }