TetrahedronKey.h 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. // David Eberly, Geometric Tools, Redmond WA 98052
  2. // Copyright (c) 1998-2020
  3. // Distributed under the Boost Software License, Version 1.0.
  4. // https://www.boost.org/LICENSE_1_0.txt
  5. // https://www.geometrictools.com/License/Boost/LICENSE_1_0.txt
  6. // Version: 4.0.2019.08.13
  7. #pragma once
  8. #include <Mathematics/FeatureKey.h>
  9. // An ordered tetrahedron has V[0] = min(v0, v1, v2, v3). Let {u1, u2, u3}
  10. // be the set of inputs excluding the one assigned to V[0] and define
  11. // V[1] = min(u1, u2, u3). Choose (V[1], V[2], V[3]) to be a permutation
  12. // of (u1, u2, u3) so that the final storage is one of
  13. // (v0, v1, v2, v3), (v0, v2, v3, v1), (v0, v3, v1, v2)
  14. // (v1, v3, v2, v0), (v1, v2, v0, v3), (v1, v0, v3, v2)
  15. // (v2, v3, v0, v1), (v2, v0, v1, v3), (v2, v1, v3, v0)
  16. // (v3, v1, v0, v2), (v3, v0, v2, v1), (v3, v2, v1, v0)
  17. // The idea is that if v0 corresponds to (1, 0, 0, 0), v1 corresponds to
  18. // (0, 1, 0, 0), v2 corresponds to (0, 0, 1, 0), and v3 corresponds to
  19. // (0, 0, 0, 1), the ordering (v0, v1, v2, v3) corresponds to the 4x4 identity
  20. // matrix I; the rows are the specified 4-tuples. The permutation
  21. // (V[0], V[1], V[2], V[3]) induces a permutation of the rows of the identity
  22. // matrix to form a permutation matrix P with det(P) = 1 = det(I).
  23. //
  24. // An unordered tetrahedron stores a permutation of (v0, v1, v2, v3) so
  25. // that V[0] < V[1] < V[2] < V[3].
  26. namespace WwiseGTE
  27. {
  28. template <bool Ordered>
  29. class TetrahedronKey : public FeatureKey<4, Ordered>
  30. {
  31. public:
  32. TetrahedronKey()
  33. {
  34. this->V = { -1, -1, -1, -1 };
  35. }
  36. explicit TetrahedronKey(int v0, int v1, int v2, int v3)
  37. {
  38. Initialize(v0, v1, v2, v3);
  39. }
  40. // Indexing for the vertices of the triangle opposite a vertex. The
  41. // triangle opposite vertex j is
  42. // <oppositeFace[j][0], oppositeFace[j][1], oppositeFace[j][2]>
  43. // and is listed in counterclockwise order when viewed from outside
  44. // the tetrahedron.
  45. static inline std::array<std::array<int, 3>, 4> const& GetOppositeFace()
  46. {
  47. static std::array<std::array<int, 3>, 4> const sOppositeFace =
  48. {{
  49. { 1, 2, 3 },
  50. { 0, 3, 2 },
  51. { 0, 1, 3 },
  52. { 0, 2, 1 }
  53. }};
  54. return sOppositeFace;
  55. }
  56. private:
  57. template <bool Dummy = Ordered>
  58. typename std::enable_if<Dummy, void>::type
  59. Initialize(int v0, int v1, int v2, int v3)
  60. {
  61. int imin = 0;
  62. this->V[0] = v0;
  63. if (v1 < this->V[0])
  64. {
  65. this->V[0] = v1;
  66. imin = 1;
  67. }
  68. if (v2 < this->V[0])
  69. {
  70. this->V[0] = v2;
  71. imin = 2;
  72. }
  73. if (v3 < this->V[0])
  74. {
  75. this->V[0] = v3;
  76. imin = 3;
  77. }
  78. if (imin == 0)
  79. {
  80. Permute(v1, v2, v3);
  81. }
  82. else if (imin == 1)
  83. {
  84. Permute(v0, v3, v2);
  85. }
  86. else if (imin == 2)
  87. {
  88. Permute(v0, v1, v3);
  89. }
  90. else // imin == 3
  91. {
  92. Permute(v0, v2, v1);
  93. }
  94. }
  95. template <bool Dummy = Ordered>
  96. typename std::enable_if<!Dummy, void>::type
  97. Initialize(int v0, int v1, int v2, int v3)
  98. {
  99. this->V[0] = v0;
  100. this->V[1] = v1;
  101. this->V[2] = v2;
  102. this->V[3] = v3;
  103. std::sort(this->V.begin(), this->V.end());
  104. }
  105. template <bool Dummy = Ordered>
  106. typename std::enable_if<Dummy, void>::type
  107. Permute(int u0, int u1, int u2)
  108. {
  109. // Once V[0] is determined, create a permutation
  110. // (V[1], V[2], V[3]) so that (V[0], V[1], V[2], V[3]) is a
  111. // permutation of (v0, v1, v2, v3) that corresponds to the
  112. // identity matrix as mentioned in the comments at the beginning
  113. // of this file.
  114. if (u0 < u1)
  115. {
  116. if (u0 < u2)
  117. {
  118. // u0 is minimum
  119. this->V[1] = u0;
  120. this->V[2] = u1;
  121. this->V[3] = u2;
  122. }
  123. else
  124. {
  125. // u2 is minimum
  126. this->V[1] = u2;
  127. this->V[2] = u0;
  128. this->V[3] = u1;
  129. }
  130. }
  131. else
  132. {
  133. if (u1 < u2)
  134. {
  135. // u1 is minimum
  136. this->V[1] = u1;
  137. this->V[2] = u2;
  138. this->V[3] = u0;
  139. }
  140. else
  141. {
  142. // u2 is minimum
  143. this->V[1] = u2;
  144. this->V[2] = u0;
  145. this->V[3] = u1;
  146. }
  147. }
  148. }
  149. };
  150. }