IndexedTriangle.h 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. // Jolt Physics Library (https://github.com/jrouwe/JoltPhysics)
  2. // SPDX-FileCopyrightText: 2021 Jorrit Rouwe
  3. // SPDX-License-Identifier: MIT
  4. #pragma once
  5. #include <Jolt/Core/HashCombine.h>
  6. JPH_NAMESPACE_BEGIN
  7. /// Triangle with 32-bit indices
  8. class IndexedTriangleNoMaterial
  9. {
  10. public:
  11. JPH_OVERRIDE_NEW_DELETE
  12. /// Constructor
  13. IndexedTriangleNoMaterial() = default;
  14. constexpr IndexedTriangleNoMaterial(uint32 inI1, uint32 inI2, uint32 inI3) : mIdx { inI1, inI2, inI3 } { }
  15. /// Check if two triangles are identical
  16. bool operator == (const IndexedTriangleNoMaterial &inRHS) const
  17. {
  18. return mIdx[0] == inRHS.mIdx[0] && mIdx[1] == inRHS.mIdx[1] && mIdx[2] == inRHS.mIdx[2];
  19. }
  20. /// Check if two triangles are equivalent (using the same vertices)
  21. bool IsEquivalent(const IndexedTriangleNoMaterial &inRHS) const
  22. {
  23. return (mIdx[0] == inRHS.mIdx[0] && mIdx[1] == inRHS.mIdx[1] && mIdx[2] == inRHS.mIdx[2])
  24. || (mIdx[0] == inRHS.mIdx[1] && mIdx[1] == inRHS.mIdx[2] && mIdx[2] == inRHS.mIdx[0])
  25. || (mIdx[0] == inRHS.mIdx[2] && mIdx[1] == inRHS.mIdx[0] && mIdx[2] == inRHS.mIdx[1]);
  26. }
  27. /// Check if two triangles are opposite (using the same vertices but in opposing order)
  28. bool IsOpposite(const IndexedTriangleNoMaterial &inRHS) const
  29. {
  30. return (mIdx[0] == inRHS.mIdx[0] && mIdx[1] == inRHS.mIdx[2] && mIdx[2] == inRHS.mIdx[1])
  31. || (mIdx[0] == inRHS.mIdx[1] && mIdx[1] == inRHS.mIdx[0] && mIdx[2] == inRHS.mIdx[2])
  32. || (mIdx[0] == inRHS.mIdx[2] && mIdx[1] == inRHS.mIdx[1] && mIdx[2] == inRHS.mIdx[0]);
  33. }
  34. /// Check if triangle is degenerate
  35. bool IsDegenerate(const VertexList &inVertices) const
  36. {
  37. Vec3 v0(inVertices[mIdx[0]]);
  38. Vec3 v1(inVertices[mIdx[1]]);
  39. Vec3 v2(inVertices[mIdx[2]]);
  40. return (v1 - v0).Cross(v2 - v0).IsNearZero();
  41. }
  42. /// Rotate the vertices so that the second vertex becomes first etc. This does not change the represented triangle.
  43. void Rotate()
  44. {
  45. uint32 tmp = mIdx[0];
  46. mIdx[0] = mIdx[1];
  47. mIdx[1] = mIdx[2];
  48. mIdx[2] = tmp;
  49. }
  50. /// Get center of triangle
  51. Vec3 GetCentroid(const VertexList &inVertices) const
  52. {
  53. return (Vec3(inVertices[mIdx[0]]) + Vec3(inVertices[mIdx[1]]) + Vec3(inVertices[mIdx[2]])) / 3.0f;
  54. }
  55. /// Get the hash value of this structure
  56. uint64 GetHash() const
  57. {
  58. static_assert(sizeof(IndexedTriangleNoMaterial) == 3 * sizeof(uint32), "Class should have no padding");
  59. return HashBytes(this, sizeof(IndexedTriangleNoMaterial));
  60. }
  61. uint32 mIdx[3];
  62. };
  63. /// Triangle with 32-bit indices and material index
  64. class IndexedTriangle : public IndexedTriangleNoMaterial
  65. {
  66. public:
  67. using IndexedTriangleNoMaterial::IndexedTriangleNoMaterial;
  68. /// Constructor
  69. constexpr IndexedTriangle(uint32 inI1, uint32 inI2, uint32 inI3, uint32 inMaterialIndex, uint inUserData = 0) : IndexedTriangleNoMaterial(inI1, inI2, inI3), mMaterialIndex(inMaterialIndex), mUserData(inUserData) { }
  70. /// Check if two triangles are identical
  71. bool operator == (const IndexedTriangle &inRHS) const
  72. {
  73. return mMaterialIndex == inRHS.mMaterialIndex && mUserData == inRHS.mUserData && IndexedTriangleNoMaterial::operator==(inRHS);
  74. }
  75. /// Rotate the vertices so that the lowest vertex becomes the first. This does not change the represented triangle.
  76. IndexedTriangle GetLowestIndexFirst() const
  77. {
  78. if (mIdx[0] < mIdx[1])
  79. {
  80. if (mIdx[0] < mIdx[2])
  81. return IndexedTriangle(mIdx[0], mIdx[1], mIdx[2], mMaterialIndex, mUserData); // 0 is smallest
  82. else
  83. return IndexedTriangle(mIdx[2], mIdx[0], mIdx[1], mMaterialIndex, mUserData); // 2 is smallest
  84. }
  85. else
  86. {
  87. if (mIdx[1] < mIdx[2])
  88. return IndexedTriangle(mIdx[1], mIdx[2], mIdx[0], mMaterialIndex, mUserData); // 1 is smallest
  89. else
  90. return IndexedTriangle(mIdx[2], mIdx[0], mIdx[1], mMaterialIndex, mUserData); // 2 is smallest
  91. }
  92. }
  93. /// Get the hash value of this structure
  94. uint64 GetHash() const
  95. {
  96. static_assert(sizeof(IndexedTriangle) == 5 * sizeof(uint32), "Class should have no padding");
  97. return HashBytes(this, sizeof(IndexedTriangle));
  98. }
  99. uint32 mMaterialIndex = 0;
  100. uint32 mUserData = 0; ///< User data that can be used for anything by the application, e.g. for tracking the original index of the triangle
  101. };
  102. using IndexedTriangleNoMaterialList = Array<IndexedTriangleNoMaterial>;
  103. using IndexedTriangleList = Array<IndexedTriangle>;
  104. JPH_NAMESPACE_END
  105. // Create a std::hash for IndexedTriangleNoMaterial and IndexedTriangle
  106. JPH_MAKE_STD_HASH(JPH::IndexedTriangleNoMaterial)
  107. JPH_MAKE_STD_HASH(JPH::IndexedTriangle)