CmMeshData.cpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401
  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. 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 = new UINT8[elemSize * numElements];
  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. delete[] indexData.indices;
  93. UINT32* indices = new UINT32[numIndices];
  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. delete[] indexData.indices;
  110. UINT16* indices = new UINT16[numIndices];
  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(new MeshData());
  188. UINT32 subMeshIndex = 0;
  189. vector<VertexElement>::type combinedVertexElements;
  190. vector<UINT8*>::type vertexElemData;
  191. vector<UINT32>::type bufferOffsets;
  192. UINT32 totalVertexCount = 0;
  193. UINT32 vertexIndexOffset = 0;
  194. for(auto& meshData : elements)
  195. {
  196. for(UINT32 i = 0; i < meshData->getNumSubmeshes(); i++)
  197. {
  198. UINT32 numIndices = meshData->getNumIndices(i);
  199. UINT32* indices = combinedMeshData->addIndices32(numIndices, subMeshIndex);
  200. UINT32* sourceIndices = meshData->getIndices32(i);
  201. for(UINT32 j = 0; j < numIndices; j++)
  202. indices[j] = sourceIndices[j] + vertexIndexOffset;
  203. subMeshIndex++;
  204. }
  205. UINT32 numVertices = meshData->getNumVertices();
  206. totalVertexCount += numVertices;
  207. vertexIndexOffset += numVertices;
  208. }
  209. UINT32 vertexOffset = 0;
  210. for(auto& meshData : elements)
  211. {
  212. vector<VertexElement>::type vertexElements = meshData->getVertexElements();
  213. UINT32 numVertices = meshData->getNumVertices();
  214. for(auto& newElement : vertexElements)
  215. {
  216. INT32 alreadyExistsIdx = -1;
  217. UINT32 idx = 0;
  218. for(auto& existingElement : combinedVertexElements)
  219. {
  220. if(newElement == existingElement)
  221. {
  222. alreadyExistsIdx = idx;
  223. break;
  224. }
  225. idx++;
  226. }
  227. if(alreadyExistsIdx == -1)
  228. {
  229. combinedVertexElements.push_back(newElement);
  230. UINT8* newBuffer = combinedMeshData->addVertexElementData(newElement.getType(), newElement.getSemantic(), totalVertexCount, newElement.getIndex(), newElement.getSource());
  231. UINT32 newBufferSize = totalVertexCount * newElement.getSize();
  232. memset(newBuffer, 0, newBufferSize);
  233. vertexElemData.push_back(newBuffer);
  234. bufferOffsets.push_back(0);
  235. alreadyExistsIdx = (UINT32)vertexElemData.size() - 1;
  236. }
  237. UINT8* source = meshData->getVertElemData(newElement.getType(), newElement.getSemantic(), newElement.getIndex(), newElement.getSource()).data;
  238. UINT32 offset = vertexOffset * newElement.getSize();
  239. memcpy(&(vertexElemData[alreadyExistsIdx]) + offset, source, numVertices * newElement.getSize());
  240. }
  241. vertexOffset += meshData->getNumVertices();
  242. }
  243. return combinedMeshData;
  244. }
  245. bool MeshData::hasElement(VertexElementSemantic semantic, UINT32 semanticIdx, UINT32 streamIdx) const
  246. {
  247. auto elemDataIter = mVertexData.find(streamIdx);
  248. if(elemDataIter == mVertexData.end())
  249. return false;
  250. const vector<VertexElementData>::type& elemData = elemDataIter->second;
  251. auto findIter = std::find_if(elemData.begin(), elemData.end(),
  252. [semantic, semanticIdx] (const VertexElementData& x)
  253. {
  254. return x.element.getSemantic() == semantic && x.element.getIndex() == semanticIdx;
  255. });
  256. if(findIter != elemData.end())
  257. return true;
  258. return false;
  259. }
  260. void MeshData::clearIfItExists(VertexElementType type, VertexElementSemantic semantic, UINT32 semanticIdx, UINT32 streamIdx)
  261. {
  262. vector<VertexElementData>::type& elemData = mVertexData[streamIdx];
  263. auto findIter = std::find_if(elemData.begin(), elemData.end(),
  264. [type, semantic, semanticIdx] (const VertexElementData& x)
  265. {
  266. return x.element.getSemantic() == semantic && x.element.getIndex() == semanticIdx;
  267. });
  268. if(findIter != elemData.end())
  269. {
  270. if(findIter->data != nullptr)
  271. delete[] findIter->data;
  272. elemData.erase(findIter);
  273. }
  274. }
  275. MeshData::VertexElementData& MeshData::getVertElemData(VertexElementType type, VertexElementSemantic semantic, UINT32 semanticIdx, UINT32 streamIdx)
  276. {
  277. vector<VertexElementData>::type& elemData = mVertexData[streamIdx];
  278. auto findIter = std::find_if(elemData.begin(), elemData.end(),
  279. [type, semantic, semanticIdx] (const VertexElementData& x)
  280. {
  281. return x.element.getSemantic() == semantic && x.element.getIndex() == semanticIdx;
  282. });
  283. if(findIter == elemData.end())
  284. CM_EXCEPT(InvalidParametersException, "No vertex element of specified type exists.");
  285. return *findIter;
  286. }
  287. /************************************************************************/
  288. /* SERIALIZATION */
  289. /************************************************************************/
  290. RTTITypeBase* MeshData::VertexElementData::getRTTIStatic()
  291. {
  292. return VertexElementDataRTTI::instance();
  293. }
  294. RTTITypeBase* MeshData::VertexElementData::getRTTI() const
  295. {
  296. return VertexElementData::getRTTIStatic();
  297. }
  298. RTTITypeBase* MeshData::IndexElementData::getRTTIStatic()
  299. {
  300. return IndexElementDataRTTI::instance();
  301. }
  302. RTTITypeBase* MeshData::IndexElementData::getRTTI() const
  303. {
  304. return IndexElementData::getRTTIStatic();
  305. }
  306. RTTITypeBase* MeshData::getRTTIStatic()
  307. {
  308. return MeshDataRTTI::instance();
  309. }
  310. RTTITypeBase* MeshData::getRTTI() const
  311. {
  312. return MeshData::getRTTIStatic();
  313. }
  314. }