/src/Geometry_GeometricTests/BPT_DynamicIntersectionTests.cpp

http://github.com/Akranar/daguerreo · C++ · 204 lines · 25 code · 1 blank · 178 comment · 0 complexity · 9a1eac424ff8005d927349d94125146d MD5 · raw file

  1. #include "BasicPrimitiveTests.h"
  2. bool BasicPrimitiveTests::IntersectingMovingSphereAgainstPlane(const BoundingSphere & sphere, const Plane & plane)
  3. {
  4. /*
  5. Main Idea:
  6. -> Interpret the sphere center's movement as a line segment.
  7. -> Intersect the line segment with the plane using Section 5.3.1
  8. -> Displaced by sphere's radius.
  9. Categorize the Sphere's movement:
  10. Since [...] indicates what side the plane the sphere is on
  11. -> dot(n, C) - d
  12. Toward plane:
  13. -> dot(n, v) * dot(n, C-d) > 0
  14. Away from plane:
  15. -> dot(n, v) * dot(n, C-d) < 0
  16. Parallel to plane:
  17. -> dot(n, v) = 0
  18. If Sphere is moving towards plane:
  19. -> Displace plane by sphere's radius towards sphere
  20. -> Interpret sphere center's movement as line segment.
  21. -> Intersect the line segment with plane.
  22. -> Use Section 5.3.1
  23. -> Insert movement segment as X into displaced plane equation.
  24. -> Solve for "t"
  25. */
  26. return false;
  27. }
  28. bool BasicPrimitiveTests::IntersectingMovingAABBAgainstPlane(const AABB & aabb, const Plane & plane)
  29. {
  30. /*
  31. Main Idea:
  32. -> Separating axis test with plane normal "n" as sole axis.
  33. -> Reduce the test to a moving-sphere-against-plane test.
  34. -> By finding the projection radius of the AABB with respect to the plane's normal.
  35. Let:
  36. Plane:
  37. -> dot(n, X) = d
  38. AABB:
  39. -> Center:
  40. -> C
  41. -> Local axis vectors:
  42. -> u0, u1, u2
  43. -> Extents:
  44. -> e0, e1, e2
  45. Test:
  46. -> Get projection radius of ABB with respect to the plane's normal:
  47. -> r = e0 * |dot(u0,n)| + e1 * |dot(u1, n)| + e2 * |dot(u2, n)|
  48. -> Since u0, u1, u2 are axis-aligned and unit length:
  49. -> r = e0 * |n.x| + e1 * |n.y| + e2 * |n.z|
  50. Test for initial contact:
  51. -> length(dot(n, C) - d) <= r
  52. If AABB moving towards plane:
  53. -> Witness point for contact on AABB will be:
  54. -> Q = C(t) - r * n
  55. -> where C(t) = center location at time "t" during intersection.
  56. -> Q on place when:
  57. -> dot(n, Q) = d
  58. -> Solve for "t":
  59. -> t = ( r + d - dot(n, C) / dot(n, v) )
  60. */
  61. return false;
  62. }
  63. bool BasicPrimitiveTests::IntersectingMovingSphereAgainstSphere(const BoundingSphere & sphere_a, const BoundingSphere & sphere_b)
  64. {
  65. /*
  66. Main Idea:
  67. Method 1:
  68. -> Get the displacement vector between sphere centers by expressing sphere movements as line segments.
  69. -> Find the time when the spheres come into contact,
  70. -> When the displacement vector's length = sum of their radii.
  71. -> Requires quadratic formula.
  72. Method 2:
  73. -> Turn problem into moving sphere against stationary sphere
  74. -> subtract one velocity from both.
  75. -> Turn problem into moving point (ray) against stationary sphere
  76. -> shrink radius of one and grow radius of the other.
  77. -> Possible because spheres first come into contact when distance between them = radius_0 + radius_1
  78. -> Solve with Section 5.3.2
  79. Method 1 Details:
  80. Let:
  81. -> d(t) = displacement vector between sphere centers.
  82. Contact Condition:
  83. -> dot( d(t), d(t)) ) = exp( r0 + r1 , 2)
  84. -> where ri = radii.
  85. -> This equation is squared on both sides to avoid square roots.
  86. -> Solve for "t"
  87. -> Encounters quadratic equation in "t".
  88. -> t = ( -b [plus/minus] sqrt(b*b - a*c) / a )
  89. -> where a = dot(v, v)
  90. -> where b = dot(v, s)
  91. -> where c = dot(s, s) - r*r
  92. -> Number of real roots => number of intersections.
  93. -> For two real root, first contact at smaller "t" then separation at larger "t".
  94. */
  95. return false;
  96. }
  97. bool BasicPrimitiveTests::IntersectingMovingSphereAgainstTriangle(const BoundingSphere & sphere, const Triangle & triangle)
  98. {
  99. /*
  100. Main Idea:
  101. -> Both methods model the movement of the first point on the sphere (not sphere center) to come in contact with the polygon's plane as a line segment.
  102. -> Call this line segment L.
  103. -> Both methods split the test into two cases:
  104. -> If the intersection is within the polygon.
  105. -> If the intersection is not inside the polygon.
  106. Movement of first point of sphere to make contact:
  107. -> L(t) = D + t * v.
  108. -> where v = sphere velocity.
  109. -> where D = C - r * n
  110. -> where r = sphere radius
  111. -> where n = plane normal
  112. Method 1:
  113. -> Intersect L with polygon's plane, then test if intersection is within polygon.
  114. -> If inside, intersects.
  115. -> If outside, must check if sphere later intersects polygon at different point.
  116. -> If if it does, it will be at point Q on that triangle/polygon that is closest to L's interesction with the plane.
  117. -> Test if sphere hits Q by shooting a ray in verse from Q towards sphere.
  118. -> Ray: Q - t * v
  119. Method 2:
  120. Main Idea:
  121. -> Ray test against the Minkowsky sum of Sphere and Triangle.
  122. -> Intersect L with polygon's plane, then test if intersection is within polygon.
  123. -> If inside, intersects.
  124. -> If outside, continue.
  125. -> Test moving sphere against each triangle edge.
  126. -> Turn this into a test between the ray of the sphere's movement against the edges turned into cylinders with sphere's radius.
  127. -> If no intersection, continue.
  128. -> Test moving sphere with each vertex.
  129. -> Equivalent to testing ray with vertices with sphere's radius.
  130. */
  131. return false;
  132. }
  133. bool BasicPrimitiveTests::IntersectingMovingSphereAgainstAABB(const BoundingSphere & sphere, const AABB & aabb)
  134. {
  135. /*
  136. Main Idea:
  137. -> Ray test with Minkowsky sum of Sphere and AABB
  138. -> Minkowsky sum will be the box with faces expanded outwards by sphere's radius WITH corners beveled.
  139. Let:
  140. -> E = Minkowsky sum of sphere and AABB, without the beveled corners.
  141. -> In other words, E = AABB with faces expanded outwards by sphere's radius.
  142. -> L = Line Segment representing sphere center's movement.
  143. Procedure:
  144. -> Intersect L with E.
  145. -> If intersect,
  146. -> Must split test into 3 cases based on if intersection is in face, vertex, or edge Voronoi region of AABB.
  147. Face Voronoi region:
  148. -> Intersects.
  149. Edge Voronoi region:
  150. -> Must intersect with the capsule of sphere's radius determined by the edge.
  151. Vertex Vornoi region:
  152. -> Must test for intersection with capsules of sphere's radius from all three edges coincident to the vertex.
  153. Potential speed-up:
  154. -> Before testing the three capsules,
  155. -> Test L with vertex with sphere's radius.
  156. -> If intersects, then test ends with this intersection.
  157. -> If no intersection, continue testing the three edge capsules.
  158. */
  159. return false;
  160. }
  161. bool BasicPrimitiveTests::IntersectingMovingAABBAgainstAABB(const AABB & aabb_a, const AABB & aabb_b)
  162. {
  163. /*
  164. Main Idea:
  165. -> Moving Separating-Axis test using the three principle axes.
  166. */
  167. return false;
  168. }