SplitLargeMeshes.cpp 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227
  1. /** @file Implementation of the SplitLargeMeshes postprocessing step
  2. */
  3. #include "SplitLargeMeshes.h"
  4. #include "../include/aiPostProcess.h"
  5. #include "../include/aiMesh.h"
  6. #include "../include/aiScene.h"
  7. using namespace Assimp;
  8. // Constructor to be privately used by Importer
  9. SplitLargeMeshesProcess::SplitLargeMeshesProcess()
  10. {
  11. }
  12. // Destructor, private as well
  13. SplitLargeMeshesProcess::~SplitLargeMeshesProcess()
  14. {
  15. // nothing to do here
  16. }
  17. // ------------------------------------------------------------------------------------------------
  18. // Returns whether the processing step is present in the given flag field.
  19. bool SplitLargeMeshesProcess::IsActive( unsigned int pFlags) const
  20. {
  21. return (pFlags & aiProcess_SplitLargeMeshes) != 0;
  22. }
  23. // ------------------------------------------------------------------------------------------------
  24. // Executes the post processing step on the given imported data.
  25. void SplitLargeMeshesProcess::Execute( aiScene* pScene)
  26. {
  27. std::vector<std::pair<aiMesh*, unsigned int> > avList;
  28. for( unsigned int a = 0; a < pScene->mNumMeshes; a++)
  29. this->SplitMesh(a, pScene->mMeshes[a],avList);
  30. if (avList.size() != pScene->mNumMeshes)
  31. {
  32. // it seems something has been splitted. rebuild the mesh list
  33. delete[] pScene->mMeshes;
  34. pScene->mNumMeshes = avList.size();
  35. pScene->mMeshes = new aiMesh*[avList.size()];
  36. for (unsigned int i = 0; i < avList.size();++i)
  37. pScene->mMeshes[i] = avList[i].first;
  38. // now we need to update all nodes
  39. this->UpdateNode(pScene->mRootNode,avList);
  40. }
  41. return;
  42. }
  43. // ------------------------------------------------------------------------------------------------
  44. // Update a node after some meshes have been split
  45. void SplitLargeMeshesProcess::UpdateNode(aiNode* pcNode,
  46. const std::vector<std::pair<aiMesh*, unsigned int> >& avList)
  47. {
  48. // for every index in out list build a new entry
  49. // TODO: Currently O(n^2)
  50. std::vector<unsigned int> aiEntries;
  51. aiEntries.reserve(pcNode->mNumMeshes + 1);
  52. for (unsigned int i = 0; i < pcNode->mNumMeshes;++i)
  53. {
  54. for (unsigned int a = 0; a < avList.size();++a)
  55. {
  56. if (avList[a].second == pcNode->mMeshes[i])
  57. {
  58. aiEntries.push_back(a);
  59. }
  60. }
  61. }
  62. // now build the new list
  63. delete pcNode->mMeshes;
  64. pcNode->mNumMeshes = aiEntries.size();
  65. pcNode->mMeshes = new unsigned int[pcNode->mNumMeshes];
  66. for (unsigned int b = 0; b < pcNode->mNumMeshes;++b)
  67. pcNode->mMeshes[b] = aiEntries[b];
  68. // recusively update all other nodes
  69. for (unsigned int i = 0; i < pcNode->mNumChildren;++i)
  70. {
  71. this->UpdateNode ( pcNode->mChildren[i], avList );
  72. }
  73. return;
  74. }
  75. // ------------------------------------------------------------------------------------------------
  76. // Executes the post processing step on the given imported data.
  77. void SplitLargeMeshesProcess::SplitMesh(
  78. unsigned int a,
  79. aiMesh* pMesh,
  80. std::vector<std::pair<aiMesh*, unsigned int> >& avList)
  81. {
  82. // TODO: Mesh splitting is currently not supported for meshes
  83. // containing bones
  84. if (pMesh->mNumVertices > AI_SLM_MAX_VERTICES && 0 == pMesh->mNumBones)
  85. {
  86. // we need to split this mesh into sub meshes
  87. // determine the size of a submesh
  88. const unsigned int iSubMeshes = (pMesh->mNumVertices / AI_SLM_MAX_VERTICES) + 1;
  89. const unsigned int iOutFaceNum = pMesh->mNumFaces / iSubMeshes;
  90. const unsigned int iOutVertexNum = iOutFaceNum * 3;
  91. // now generate all submeshes
  92. for (unsigned int i = 0; i < iSubMeshes;++i)
  93. {
  94. aiMesh* pcMesh = new aiMesh;
  95. pcMesh->mNumFaces = iOutFaceNum;
  96. pcMesh->mMaterialIndex = pMesh->mMaterialIndex;
  97. if (i == iSubMeshes-1)
  98. {
  99. pcMesh->mNumFaces = iOutFaceNum + (
  100. pMesh->mNumFaces - iOutFaceNum * iSubMeshes);
  101. }
  102. // copy the list of faces
  103. pcMesh->mFaces = new aiFace[pcMesh->mNumFaces];
  104. const unsigned int iBase = iOutFaceNum * i;
  105. // get the total number of indices
  106. unsigned int iCnt = 0;
  107. for (unsigned int p = iBase; p < pcMesh->mNumFaces + iBase;++p)
  108. {
  109. iCnt += pMesh->mFaces[p].mNumIndices;
  110. }
  111. pcMesh->mNumVertices = iCnt;
  112. // allocate storage
  113. if (pMesh->mVertices != NULL)
  114. pcMesh->mVertices = new aiVector3D[iCnt];
  115. if (pMesh->HasNormals())
  116. pcMesh->mNormals = new aiVector3D[iCnt];
  117. if (pMesh->HasTangentsAndBitangents())
  118. {
  119. pcMesh->mTangents = new aiVector3D[iCnt];
  120. pcMesh->mBitangents = new aiVector3D[iCnt];
  121. }
  122. // texture coordinates
  123. for (unsigned int c = 0; c < AI_MAX_NUMBER_OF_TEXTURECOORDS;++c)
  124. {
  125. pcMesh->mNumUVComponents[c] = pMesh->mNumUVComponents[c];
  126. if (pMesh->HasTextureCoords( c))
  127. {
  128. pcMesh->mTextureCoords[c] = new aiVector3D[iCnt];
  129. }
  130. }
  131. // vertex colors
  132. for (unsigned int c = 0; c < AI_MAX_NUMBER_OF_COLOR_SETS;++c)
  133. {
  134. if (pMesh->HasVertexColors( c))
  135. {
  136. pcMesh->mColors[c] = new aiColor4D[iCnt];
  137. }
  138. }
  139. // (we will also need to copy the array of indices)
  140. for (unsigned int p = 0; p < pcMesh->mNumFaces;++p)
  141. {
  142. pcMesh->mFaces[p].mNumIndices = 3;
  143. // allocate a new array
  144. unsigned int* pi = pMesh->mFaces[p + iBase].mIndices;
  145. pcMesh->mFaces[p].mIndices = new unsigned int[3];
  146. // and copy the contents of the old array, offset by current base
  147. for (unsigned int v = 0; v < 3;++v)
  148. {
  149. unsigned int iIndex = pMesh->mFaces[p+iBase].mIndices[v];
  150. unsigned int iIndexOut = p*3 + v;
  151. pcMesh->mFaces[p].mIndices[v] = iIndexOut;
  152. // copy positions
  153. if (pMesh->mVertices != NULL)
  154. {
  155. pcMesh->mVertices[iIndexOut] = pMesh->mVertices[iIndex];
  156. }
  157. // copy normals
  158. if (pMesh->HasNormals())
  159. {
  160. pcMesh->mNormals[iIndexOut] = pMesh->mNormals[iIndex];
  161. }
  162. // copy tangents/bitangents
  163. if (pMesh->HasTangentsAndBitangents())
  164. {
  165. pcMesh->mTangents[iIndexOut] = pMesh->mTangents[iIndex];
  166. pcMesh->mBitangents[iIndexOut] = pMesh->mBitangents[iIndex];
  167. }
  168. // texture coordinates
  169. for (unsigned int c = 0; c < AI_MAX_NUMBER_OF_TEXTURECOORDS;++c)
  170. {
  171. if (pMesh->HasTextureCoords( c))
  172. {
  173. pcMesh->mTextureCoords[c][iIndexOut] = pMesh->mTextureCoords[c][iIndex];
  174. }
  175. }
  176. // vertex colors
  177. for (unsigned int c = 0; c < AI_MAX_NUMBER_OF_COLOR_SETS;++c)
  178. {
  179. if (pMesh->HasVertexColors( c))
  180. {
  181. pcMesh->mColors[c][iIndexOut] = pMesh->mColors[c][iIndex];
  182. }
  183. }
  184. }
  185. }
  186. // add the newly created mesh to the list
  187. avList.push_back(std::pair<aiMesh*, unsigned int>(pcMesh,a));
  188. }
  189. // now delete the old mesh data
  190. delete pMesh;
  191. }
  192. else avList.push_back(std::pair<aiMesh*, unsigned int>(pMesh,a));
  193. return;
  194. }