CmMeshData.cpp 11 KB

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