#### /src/Geometry_GeometricTests/BPT_DynamicIntersectionTests.cpp

C++ | 204 lines | 25 code | 1 blank | 178 comment | 0 complexity | 9a1eac424ff8005d927349d94125146d MD5 | raw file

Possible License(s): AGPL-3.0, LGPL-2.1, LGPL-3.0, GPL-2.0

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