PrimalQuery3.h 10.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293
  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.10.17
  7. #pragma once
  8. #include <Mathematics/Vector3.h>
  9. // Queries about the relation of a point to various geometric objects. The
  10. // choices for N when using UIntegerFP32<N> for either BSNumber of BSRational
  11. // are determined in GeometricTools/GTEngine/Tools/PrecisionCalculator. These
  12. // N-values are worst case scenarios. Your specific input data might require
  13. // much smaller N, in which case you can modify PrecisionCalculator to use the
  14. // BSPrecision(int32_t,int32_t,int32_t,bool) constructors.
  15. namespace WwiseGTE
  16. {
  17. template <typename Real>
  18. class PrimalQuery3
  19. {
  20. public:
  21. // The caller is responsible for ensuring that the array is not empty
  22. // before calling queries and that the indices passed to the queries
  23. // are valid. The class does no range checking.
  24. PrimalQuery3()
  25. :
  26. mNumVertices(0),
  27. mVertices(nullptr)
  28. {
  29. }
  30. PrimalQuery3(int numVertices, Vector3<Real> const* vertices)
  31. :
  32. mNumVertices(numVertices),
  33. mVertices(vertices)
  34. {
  35. }
  36. // Member access.
  37. inline void Set(int numVertices, Vector3<Real> const* vertices)
  38. {
  39. mNumVertices = numVertices;
  40. mVertices = vertices;
  41. }
  42. inline int GetNumVertices() const
  43. {
  44. return mNumVertices;
  45. }
  46. inline Vector3<Real> const* GetVertices() const
  47. {
  48. return mVertices;
  49. }
  50. // In the following, point P refers to vertices[i] or 'test' and Vi
  51. // refers to vertices[vi].
  52. // For a plane with origin V0 and normal N = Cross(V1-V0,V2-V0),
  53. // ToPlane returns
  54. // +1, P on positive side of plane (side to which N points)
  55. // -1, P on negative side of plane (side to which -N points)
  56. // 0, P on the plane
  57. //
  58. // Choice of N for UIntegerFP32<N>.
  59. // input type | compute type | N
  60. // -----------+--------------+----
  61. // float | BSNumber | 27
  62. // double | BSNumber | 197
  63. // float | BSRational | 79
  64. // double | BSRational | 591
  65. int ToPlane(int i, int v0, int v1, int v2) const
  66. {
  67. return ToPlane(mVertices[i], v0, v1, v2);
  68. }
  69. int ToPlane(Vector3<Real> const& test, int v0, int v1, int v2) const
  70. {
  71. Vector3<Real> const& vec0 = mVertices[v0];
  72. Vector3<Real> const& vec1 = mVertices[v1];
  73. Vector3<Real> const& vec2 = mVertices[v2];
  74. Real x0 = test[0] - vec0[0];
  75. Real y0 = test[1] - vec0[1];
  76. Real z0 = test[2] - vec0[2];
  77. Real x1 = vec1[0] - vec0[0];
  78. Real y1 = vec1[1] - vec0[1];
  79. Real z1 = vec1[2] - vec0[2];
  80. Real x2 = vec2[0] - vec0[0];
  81. Real y2 = vec2[1] - vec0[1];
  82. Real z2 = vec2[2] - vec0[2];
  83. Real y1z2 = y1 * z2;
  84. Real y2z1 = y2 * z1;
  85. Real y2z0 = y2 * z0;
  86. Real y0z2 = y0 * z2;
  87. Real y0z1 = y0 * z1;
  88. Real y1z0 = y1 * z0;
  89. Real c0 = y1z2 - y2z1;
  90. Real c1 = y2z0 - y0z2;
  91. Real c2 = y0z1 - y1z0;
  92. Real x0c0 = x0 * c0;
  93. Real x1c1 = x1 * c1;
  94. Real x2c2 = x2 * c2;
  95. Real term = x0c0 + x1c1;
  96. Real det = term + x2c2;
  97. Real const zero(0);
  98. return (det > zero ? +1 : (det < zero ? -1 : 0));
  99. }
  100. // For a tetrahedron with vertices ordered as described in the file
  101. // TetrahedronKey.h, the function returns
  102. // +1, P outside tetrahedron
  103. // -1, P inside tetrahedron
  104. // 0, P on tetrahedron
  105. //
  106. // Choice of N for UIntegerFP32<N>.
  107. // input type | compute type | N
  108. // -----------+--------------+----
  109. // float | BSNumber | 27
  110. // double | BSNumber | 197
  111. // float | BSRational | 79
  112. // double | BSRational | 591
  113. // The query involves four calls of ToPlane, so the numbers match
  114. // those of ToPlane.
  115. int ToTetrahedron(int i, int v0, int v1, int v2, int v3) const
  116. {
  117. return ToTetrahedron(mVertices[i], v0, v1, v2, v3);
  118. }
  119. int ToTetrahedron(Vector3<Real> const& test, int v0, int v1, int v2, int v3) const
  120. {
  121. int sign0 = ToPlane(test, v1, v2, v3);
  122. if (sign0 > 0)
  123. {
  124. return +1;
  125. }
  126. int sign1 = ToPlane(test, v0, v2, v3);
  127. if (sign1 < 0)
  128. {
  129. return +1;
  130. }
  131. int sign2 = ToPlane(test, v0, v1, v3);
  132. if (sign2 > 0)
  133. {
  134. return +1;
  135. }
  136. int sign3 = ToPlane(test, v0, v1, v2);
  137. if (sign3 < 0)
  138. {
  139. return +1;
  140. }
  141. return ((sign0 && sign1 && sign2 && sign3) ? -1 : 0);
  142. }
  143. // For a tetrahedron with vertices ordered as described in the file
  144. // TetrahedronKey.h, the function returns
  145. // +1, P outside circumsphere of tetrahedron
  146. // -1, P inside circumsphere of tetrahedron
  147. // 0, P on circumsphere of tetrahedron
  148. //
  149. // Choice of N for UIntegerFP32<N>.
  150. // input type | compute type | N
  151. // -----------+--------------+-----
  152. // float | BSNumber | 44
  153. // double | BSNumber | 329
  154. // float | BSNumber | 262
  155. // double | BSRational | 1969
  156. int ToCircumsphere(int i, int v0, int v1, int v2, int v3) const
  157. {
  158. return ToCircumsphere(mVertices[i], v0, v1, v2, v3);
  159. }
  160. int ToCircumsphere(Vector3<Real> const& test, int v0, int v1, int v2, int v3) const
  161. {
  162. Vector3<Real> const& vec0 = mVertices[v0];
  163. Vector3<Real> const& vec1 = mVertices[v1];
  164. Vector3<Real> const& vec2 = mVertices[v2];
  165. Vector3<Real> const& vec3 = mVertices[v3];
  166. Real x0 = vec0[0] - test[0];
  167. Real y0 = vec0[1] - test[1];
  168. Real z0 = vec0[2] - test[2];
  169. Real s00 = vec0[0] + test[0];
  170. Real s01 = vec0[1] + test[1];
  171. Real s02 = vec0[2] + test[2];
  172. Real t00 = s00 * x0;
  173. Real t01 = s01 * y0;
  174. Real t02 = s02 * z0;
  175. Real t00pt01 = t00 + t01;
  176. Real w0 = t00pt01 + t02;
  177. Real x1 = vec1[0] - test[0];
  178. Real y1 = vec1[1] - test[1];
  179. Real z1 = vec1[2] - test[2];
  180. Real s10 = vec1[0] + test[0];
  181. Real s11 = vec1[1] + test[1];
  182. Real s12 = vec1[2] + test[2];
  183. Real t10 = s10 * x1;
  184. Real t11 = s11 * y1;
  185. Real t12 = s12 * z1;
  186. Real t10pt11 = t10 + t11;
  187. Real w1 = t10pt11 + t12;
  188. Real x2 = vec2[0] - test[0];
  189. Real y2 = vec2[1] - test[1];
  190. Real z2 = vec2[2] - test[2];
  191. Real s20 = vec2[0] + test[0];
  192. Real s21 = vec2[1] + test[1];
  193. Real s22 = vec2[2] + test[2];
  194. Real t20 = s20 * x2;
  195. Real t21 = s21 * y2;
  196. Real t22 = s22 * z2;
  197. Real t20pt21 = t20 + t21;
  198. Real w2 = t20pt21 + t22;
  199. Real x3 = vec3[0] - test[0];
  200. Real y3 = vec3[1] - test[1];
  201. Real z3 = vec3[2] - test[2];
  202. Real s30 = vec3[0] + test[0];
  203. Real s31 = vec3[1] + test[1];
  204. Real s32 = vec3[2] + test[2];
  205. Real t30 = s30 * x3;
  206. Real t31 = s31 * y3;
  207. Real t32 = s32 * z3;
  208. Real t30pt31 = t30 + t31;
  209. Real w3 = t30pt31 + t32;
  210. Real x0y1 = x0 * y1;
  211. Real x0y2 = x0 * y2;
  212. Real x0y3 = x0 * y3;
  213. Real x1y0 = x1 * y0;
  214. Real x1y2 = x1 * y2;
  215. Real x1y3 = x1 * y3;
  216. Real x2y0 = x2 * y0;
  217. Real x2y1 = x2 * y1;
  218. Real x2y3 = x2 * y3;
  219. Real x3y0 = x3 * y0;
  220. Real x3y1 = x3 * y1;
  221. Real x3y2 = x3 * y2;
  222. Real a0 = x0y1 - x1y0;
  223. Real a1 = x0y2 - x2y0;
  224. Real a2 = x0y3 - x3y0;
  225. Real a3 = x1y2 - x2y1;
  226. Real a4 = x1y3 - x3y1;
  227. Real a5 = x2y3 - x3y2;
  228. Real z0w1 = z0 * w1;
  229. Real z0w2 = z0 * w2;
  230. Real z0w3 = z0 * w3;
  231. Real z1w0 = z1 * w0;
  232. Real z1w2 = z1 * w2;
  233. Real z1w3 = z1 * w3;
  234. Real z2w0 = z2 * w0;
  235. Real z2w1 = z2 * w1;
  236. Real z2w3 = z2 * w3;
  237. Real z3w0 = z3 * w0;
  238. Real z3w1 = z3 * w1;
  239. Real z3w2 = z3 * w2;
  240. Real b0 = z0w1 - z1w0;
  241. Real b1 = z0w2 - z2w0;
  242. Real b2 = z0w3 - z3w0;
  243. Real b3 = z1w2 - z2w1;
  244. Real b4 = z1w3 - z3w1;
  245. Real b5 = z2w3 - z3w2;
  246. Real a0b5 = a0 * b5;
  247. Real a1b4 = a1 * b4;
  248. Real a2b3 = a2 * b3;
  249. Real a3b2 = a3 * b2;
  250. Real a4b1 = a4 * b1;
  251. Real a5b0 = a5 * b0;
  252. Real term0 = a0b5 - a1b4;
  253. Real term1 = term0 + a2b3;
  254. Real term2 = term1 + a3b2;
  255. Real term3 = term2 - a4b1;
  256. Real det = term3 + a5b0;
  257. Real const zero(0);
  258. return (det > zero ? 1 : (det < zero ? -1 : 0));
  259. }
  260. private:
  261. int mNumVertices;
  262. Vector3<Real> const* mVertices;
  263. };
  264. }