3DSGenNormals.cpp 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. /** @file Implementation of the 3ds importer class */
  2. #include "3DSLoader.h"
  3. #include "MaterialSystem.h"
  4. #include <algorithm>
  5. #include "../include/IOStream.h"
  6. #include "../include/IOSystem.h"
  7. #include "../include/aiMesh.h"
  8. #include "../include/aiScene.h"
  9. #include "../include/aiAssert.h"
  10. #include "3DSSpatialSort.h"
  11. using namespace Assimp;
  12. // ------------------------------------------------------------------------------------------------
  13. void Dot3DSImporter::GenNormals(Dot3DS::Mesh* sMesh)
  14. {
  15. // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  16. // First generate face normals
  17. sMesh->mNormals.resize(sMesh->mPositions.size(),aiVector3D());
  18. for( unsigned int a = 0; a < sMesh->mFaces.size(); a++)
  19. {
  20. const Dot3DS::Face& face = sMesh->mFaces[a];
  21. // assume it is a triangle
  22. aiVector3D* pV1 = &sMesh->mPositions[face.i1];
  23. aiVector3D* pV2 = &sMesh->mPositions[face.i2];
  24. aiVector3D* pV3 = &sMesh->mPositions[face.i3];
  25. aiVector3D pDelta1 = *pV2 - *pV1;
  26. aiVector3D pDelta2 = *pV3 - *pV1;
  27. aiVector3D vNor = pDelta1 ^ pDelta2;
  28. //float fLength = vNor.Length();
  29. //if (0.0f != fLength)vNor /= fLength;
  30. sMesh->mNormals[face.i1] = vNor;
  31. sMesh->mNormals[face.i2] = vNor;
  32. sMesh->mNormals[face.i3] = vNor;
  33. }
  34. // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  35. // calculate the position bounds so we have a reliable epsilon to
  36. // check position differences against
  37. // @Schrompf: This is the 6th time this snippet is repeated!
  38. aiVector3D minVec( 1e10f, 1e10f, 1e10f), maxVec( -1e10f, -1e10f, -1e10f);
  39. for( unsigned int a = 0; a < sMesh->mPositions.size(); a++)
  40. {
  41. minVec.x = std::min( minVec.x, sMesh->mPositions[a].x);
  42. minVec.y = std::min( minVec.y, sMesh->mPositions[a].y);
  43. minVec.z = std::min( minVec.z, sMesh->mPositions[a].z);
  44. maxVec.x = std::max( maxVec.x, sMesh->mPositions[a].x);
  45. maxVec.y = std::max( maxVec.y, sMesh->mPositions[a].y);
  46. maxVec.z = std::max( maxVec.z, sMesh->mPositions[a].z);
  47. }
  48. const float posEpsilon = (maxVec - minVec).Length() * 1e-5f;
  49. std::vector<aiVector3D> avNormals;
  50. avNormals.resize(sMesh->mNormals.size());
  51. // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  52. // now generate the spatial sort tree
  53. D3DSSpatialSorter sSort(sMesh);
  54. for( std::vector<Dot3DS::Face>::iterator
  55. i = sMesh->mFaces.begin();
  56. i != sMesh->mFaces.end();++i)
  57. {
  58. std::vector<unsigned int> poResult;
  59. // need to repeat the code for all three vertices of the triangle
  60. // vertex 1
  61. sSort.FindPositions(sMesh->mPositions[(*i).i1],(*i).iSmoothGroup,
  62. posEpsilon,poResult);
  63. aiVector3D vNormals;
  64. float fDiv = 0.0f;
  65. for (std::vector<unsigned int>::const_iterator
  66. a = poResult.begin();
  67. a != poResult.end();++a)
  68. {
  69. vNormals += sMesh->mNormals[(*a)];
  70. fDiv += 1.0f;
  71. }
  72. vNormals.x /= fDiv;
  73. vNormals.y /= fDiv;
  74. vNormals.z /= fDiv;
  75. vNormals.Normalize();
  76. avNormals[(*i).i1] = vNormals;
  77. poResult.clear();
  78. // vertex 2
  79. sSort.FindPositions(sMesh->mPositions[(*i).i2],(*i).iSmoothGroup,
  80. posEpsilon,poResult);
  81. vNormals = aiVector3D();
  82. fDiv = 0.0f;
  83. for (std::vector<unsigned int>::const_iterator
  84. a = poResult.begin();
  85. a != poResult.end();++a)
  86. {
  87. vNormals += sMesh->mNormals[(*a)];
  88. fDiv += 1.0f;
  89. }
  90. vNormals.x /= fDiv;
  91. vNormals.y /= fDiv;
  92. vNormals.z /= fDiv;
  93. vNormals.Normalize();
  94. avNormals[(*i).i2] = vNormals;
  95. poResult.clear();
  96. // vertex 3
  97. sSort.FindPositions(sMesh->mPositions[(*i).i3],(*i).iSmoothGroup,
  98. posEpsilon ,poResult);
  99. vNormals = aiVector3D();
  100. fDiv = 0.0f;
  101. for (std::vector<unsigned int>::const_iterator
  102. a = poResult.begin();
  103. a != poResult.end();++a)
  104. {
  105. vNormals += sMesh->mNormals[(*a)];
  106. fDiv += 1.0f;
  107. }
  108. vNormals.x /= fDiv;
  109. vNormals.y /= fDiv;
  110. vNormals.z /= fDiv;
  111. vNormals.Normalize();
  112. avNormals[(*i).i3] = vNormals;
  113. }
  114. sMesh->mNormals = avNormals;
  115. return;
  116. }