BsMeshUtility.cpp 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  1. #include "BsMeshUtility.h"
  2. #include "BsVector3.h"
  3. #include "BsVector2.h"
  4. namespace BansheeEngine
  5. {
  6. struct VertexFaces
  7. {
  8. UINT32* faces;
  9. UINT32 numFaces = 0;
  10. };
  11. struct VertexConnectivity
  12. {
  13. VertexConnectivity(UINT8* indices, UINT32 numVertices, UINT32 numFaces, UINT32 indexSize)
  14. :vertexFaces(nullptr), mMaxFacesPerVertex(0), mFaces(nullptr), mNumVertices(numVertices)
  15. {
  16. vertexFaces = bs_newN<VertexFaces>(numVertices);
  17. resizeFaceArray(10);
  18. for (UINT32 i = 0; i < numFaces; i++)
  19. {
  20. for (UINT32 j = 0; j < 3; j++)
  21. {
  22. UINT32 idx = i * 3 + j;
  23. UINT32 vertexIdx = 0;
  24. memcpy(&vertexIdx, indices + idx * indexSize, indexSize);
  25. VertexFaces& faces = vertexFaces[vertexIdx];
  26. if (faces.numFaces >= mMaxFacesPerVertex)
  27. resizeFaceArray(mMaxFacesPerVertex * 2);
  28. faces.faces[faces.numFaces] = i;
  29. faces.numFaces++;
  30. }
  31. }
  32. }
  33. ~VertexConnectivity()
  34. {
  35. if (vertexFaces != nullptr)
  36. bs_deleteN(vertexFaces, mNumVertices);
  37. if (mFaces != nullptr)
  38. bs_free(mFaces);
  39. }
  40. VertexFaces* vertexFaces;
  41. private:
  42. void resizeFaceArray(UINT32 numFaces)
  43. {
  44. UINT32* newFaces = (UINT32*)bs_alloc(numFaces * mNumVertices);
  45. if (mFaces != nullptr)
  46. {
  47. for (UINT32 i = 0; i < mNumVertices; i++)
  48. memcpy(newFaces + (i * numFaces), mFaces + (i * mMaxFacesPerVertex), mMaxFacesPerVertex * sizeof(UINT32));
  49. bs_free(mFaces);
  50. }
  51. for (UINT32 i = 0; i < mNumVertices; i++)
  52. vertexFaces[i].faces = newFaces + (i * numFaces);
  53. mFaces = newFaces;
  54. mMaxFacesPerVertex = numFaces;
  55. }
  56. UINT32 mMaxFacesPerVertex;
  57. UINT32 mNumVertices;
  58. UINT32* mFaces;
  59. };
  60. void MeshUtility::calculateNormals(Vector3* vertices, UINT8* indices, UINT32 numVertices,
  61. UINT32 numIndices, Vector3* normals, UINT32 indexSize)
  62. {
  63. UINT32 numFaces = numIndices / 3;
  64. Vector3* faceNormals = bs_newN<Vector3>(numFaces);
  65. for (UINT32 i = 0; i < numFaces; i++)
  66. {
  67. UINT32 triangle[3];
  68. memcpy(&triangle[0], indices + (i * 3 + 0) * indexSize, indexSize);
  69. memcpy(&triangle[1], indices + (i * 3 + 1) * indexSize, indexSize);
  70. memcpy(&triangle[2], indices + (i * 3 + 2) * indexSize, indexSize);
  71. Vector3 edgeA = vertices[triangle[1]] - vertices[triangle[0]];
  72. Vector3 edgeB = vertices[triangle[2]] - vertices[triangle[0]];
  73. faceNormals[i] = Vector3::normalize(Vector3::cross(edgeA, edgeB));
  74. // Note: Potentially don't normalize here in order to weigh the normals
  75. // by triangle size
  76. }
  77. VertexConnectivity connectivity(indices, numVertices, numFaces, indexSize);
  78. for (UINT32 i = 0; i < numVertices; i++)
  79. {
  80. VertexFaces& faces = connectivity.vertexFaces[i];
  81. for (UINT32 j = 0; j < faces.numFaces; j++)
  82. {
  83. UINT32 faceIdx = faces.faces[j];
  84. normals[i] += faceNormals[faceIdx];
  85. }
  86. normals[i].normalize();
  87. }
  88. bs_deleteN(faceNormals, numFaces);
  89. }
  90. void MeshUtility::calculateTangents(Vector3* vertices, Vector3* normals, Vector2* uv, UINT8* indices, UINT32 numVertices,
  91. UINT32 numIndices, Vector3* tangents, Vector3* bitangents, UINT32 indexSize)
  92. {
  93. UINT32 numFaces = numIndices / 3;
  94. Vector3* faceTangents = bs_newN<Vector3>(numFaces);
  95. Vector3* faceBitangents = bs_newN<Vector3>(numFaces);
  96. for (UINT32 i = 0; i < numFaces; i++)
  97. {
  98. UINT32 triangle[3];
  99. memcpy(&triangle[0], indices + (i * 3 + 0) * indexSize, indexSize);
  100. memcpy(&triangle[1], indices + (i * 3 + 1) * indexSize, indexSize);
  101. memcpy(&triangle[2], indices + (i * 3 + 2) * indexSize, indexSize);
  102. Vector3 p0 = vertices[triangle[0]];
  103. Vector3 p1 = vertices[triangle[1]];
  104. Vector3 p2 = vertices[triangle[2]];
  105. Vector2 uv0 = uv[triangle[0]];
  106. Vector2 uv1 = uv[triangle[1]];
  107. Vector2 uv2 = uv[triangle[2]];
  108. Vector3 q0 = p1 - p0;
  109. Vector3 q1 = p2 - p0;
  110. Vector2 s;
  111. s.x = uv1.x - uv0.x;
  112. s.y = uv2.x - uv0.x;
  113. Vector2 t;
  114. t.x = uv1.y - uv0.y;
  115. t.y = uv2.y - uv0.y;
  116. float denom = s.x*t.y - s.y * t.x;
  117. if (fabs(denom) >= 0e-8f)
  118. {
  119. float r = 1.0f / denom;
  120. s *= r;
  121. t *= r;
  122. faceTangents[i] = t.y * q0 - t.x * q1;
  123. faceBitangents[i] = s.x * q0 - s.y * q1;
  124. faceTangents[i].normalize();
  125. faceBitangents[i].normalize();
  126. }
  127. // Note: Potentially don't normalize here in order to weigh the normals
  128. // by triangle size
  129. }
  130. VertexConnectivity connectivity(indices, numVertices, numFaces, indexSize);
  131. for (UINT32 i = 0; i < numVertices; i++)
  132. {
  133. VertexFaces& faces = connectivity.vertexFaces[i];
  134. for (UINT32 j = 0; j < faces.numFaces; j++)
  135. {
  136. UINT32 faceIdx = faces.faces[j];
  137. tangents[i] += faceTangents[faceIdx];
  138. bitangents[i] += faceBitangents[faceIdx];
  139. }
  140. tangents[i].normalize();
  141. bitangents[i].normalize();
  142. // Orthonormalize
  143. float dot0 = normals[i].dot(tangents[i]);
  144. tangents[i] -= dot0*normals[i];
  145. tangents[i].normalize();
  146. float dot1 = tangents[i].dot(bitangents[i]);
  147. dot0 = normals[i].dot(bitangents[i]);
  148. bitangents[i] -= dot0*normals[i] + dot1*tangents[i];
  149. bitangents[i].normalize();
  150. }
  151. bs_deleteN(faceTangents, numFaces);
  152. bs_deleteN(faceBitangents, numFaces);
  153. // TODO - Consider weighing tangents by triangle size and/or edge angles
  154. }
  155. void MeshUtility::calculateTangentSpace(Vector3* vertices, Vector2* uv, UINT8* indices, UINT32 numVertices,
  156. UINT32 numIndices, Vector3* normals, Vector3* tangents, Vector3* bitangents, UINT32 indexSize)
  157. {
  158. calculateNormals(vertices, indices, numVertices, numIndices, normals, indexSize);
  159. calculateTangents(vertices, normals, uv, indices, numVertices, numIndices, tangents, bitangents, indexSize);
  160. }
  161. }