| 1 | /** |
|---|
| 2 | @file CollisionDetection.h |
|---|
| 3 | |
|---|
| 4 | |
|---|
| 5 | Moving collision detection for simple primitives. |
|---|
| 6 | |
|---|
| 7 | @author Morgan McGuire, matrix@graphics3d.com |
|---|
| 8 | @cite Spherical collision based on Paul Nettle's |
|---|
| 9 | ftp://ftp.3dmaileffects.com/pub/FluidStudios/CollisionDetection/Fluid_Studios_Generic_Collision_Detection_for_Games_Using_Ellipsoids.pdf |
|---|
| 10 | and comments by Max McGuire. Ray-sphere intersection by Eric Haines. |
|---|
| 11 | Box-Box intersection written by Kevin Egan. |
|---|
| 12 | Thanks to Max McGuire of Iron Lore for various bug fixes. |
|---|
| 13 | |
|---|
| 14 | @created 2001-11-19 |
|---|
| 15 | @edited 2006-01-10 |
|---|
| 16 | |
|---|
| 17 | Copyright 2000-2006, Morgan McGuire. |
|---|
| 18 | All rights reserved. |
|---|
| 19 | */ |
|---|
| 20 | |
|---|
| 21 | #ifndef G3D_COLLISIONDETECTION_H |
|---|
| 22 | #define G3D_COLLISIONDETECTION_H |
|---|
| 23 | |
|---|
| 24 | #include "G3D/platform.h" |
|---|
| 25 | #include "G3D/Vector3.h" |
|---|
| 26 | #include "G3D/Plane.h" |
|---|
| 27 | #include "G3D/Box.h" |
|---|
| 28 | #include "G3D/Triangle.h" |
|---|
| 29 | #include "G3D/Array.h" |
|---|
| 30 | #include "G3D/Ray.h" |
|---|
| 31 | #include "G3D/Line.h" |
|---|
| 32 | |
|---|
| 33 | namespace G3D { |
|---|
| 34 | |
|---|
| 35 | |
|---|
| 36 | /** |
|---|
| 37 | Collision detection primitives and tools for building |
|---|
| 38 | higher order collision detection schemes. |
|---|
| 39 | |
|---|
| 40 | These routines provide <I>moving</I> and static collision detection. |
|---|
| 41 | Moving collision detection allows the calculation of collisions that |
|---|
| 42 | occur during a period of time -- as opposed to the intersection of |
|---|
| 43 | two static bodies. |
|---|
| 44 | |
|---|
| 45 | Moving collision detection routines detect collisions between |
|---|
| 46 | <I>only</I> static primitives and moving spheres or points. Since the |
|---|
| 47 | reference frame can be user defined, these functions can be used to |
|---|
| 48 | detect the collision between two moving bodies by subtracting |
|---|
| 49 | the velocity vector of one object from the velocity vector of the |
|---|
| 50 | sphere or point the detection is to occur with. This unified |
|---|
| 51 | velocity vector will act as if both objects are moving simultaneously. |
|---|
| 52 | |
|---|
| 53 | Collisions are detected for single-sided objects only. That is, |
|---|
| 54 | no collision is detected when <I>leaving</I> a primitive or passing |
|---|
| 55 | through a plane or triangle opposite the normal... except for the |
|---|
| 56 | point-sphere calculation or when otherwise noted. |
|---|
| 57 | |
|---|
| 58 | For a sphere, the collision location returned is the point in world |
|---|
| 59 | space where the surface of the sphere and the fixed object meet. |
|---|
| 60 | It is <B>not</B> the position of the center of the sphere at |
|---|
| 61 | the time of the collision. |
|---|
| 62 | |
|---|
| 63 | The collision normal returned is the surface normal to the fixed |
|---|
| 64 | object at the collision location. |
|---|
| 65 | |
|---|
| 66 | <p> |
|---|
| 67 | <b>Static Collision Detection:</b> (Neither object is moving) |
|---|
| 68 | |
|---|
| 69 | <table> |
|---|
| 70 | <tr><td></td><td><b>Vector3</b></td><td><b>LineSegment</b></td><td><b>Ray *</b></td><td><b>Line</b></td><td><b>Plane</b></td><td><b>Triangle</b></td><td><b>Sphere</b></td><td><b>Cylinder</b></td><td><b>Capsule</b></td><td><b>AABox</b></td><td><b>Box</b></td></tr> |
|---|
| 71 | <tr><td><b>Vector3</b></td><td>Vector3::operator== Vector3::fuzzyEq G3D::distance</td><td bgcolor=#C0C0C0 colspan=10 ></td></tr> |
|---|
| 72 | <tr><td><b>LineSegment</b></td><td>LineSegment::closestPoint LineSegment::distance CollisionDetection::closestPointOnLineSegment</td><td></td><td bgcolor=#C0C0C0 colspan=9 ></td></tr> |
|---|
| 73 | <tr><td><b>Ray *</b></td><td>Ray::closestPoint Ray::distance</td><td></td><td></td><td bgcolor=#C0C0C0 colspan=8 ></td></tr> |
|---|
| 74 | <tr><td><b>Line</b></td><td>Line::closestPoint Line::distance</td><td></td><td>CollisionDetection::closestPointsBetweenLineAndLine</td><td></td><td bgcolor=#C0C0C0 colspan=7 ></td></tr> |
|---|
| 75 | <tr><td><b>Plane</b></td><td></td><td></td><td></td><td></td><td></td><td bgcolor=#C0C0C0 colspan=6 ></td></tr> |
|---|
| 76 | <tr><td><b>Triangle</b></td><td></td><td></td><td></td><td></td><td></td><td></td><td bgcolor=#C0C0C0 colspan=5 ></td></tr> |
|---|
| 77 | <tr><td><b>Sphere</b></td><td>Sphere::contains</td><td></td><td></td><td></td><td></td><td></td><td></td><td bgcolor=#C0C0C0 colspan=4 ></td></tr> |
|---|
| 78 | <tr><td><b>Cylinder</b></td><td>Cylinder::contains</td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td bgcolor=#C0C0C0 colspan=3 ></td></tr> |
|---|
| 79 | <tr><td><b>Capsule</b></td><td>Capsule::contains</td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td bgcolor=#C0C0C0 colspan=2 ></td></tr> |
|---|
| 80 | <tr><td><b>AABox</b></td><td>AABox::contains</td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td bgcolor=#C0C0C0 colspan=1 ></td></tr> |
|---|
| 81 | <tr><td><b>Box</b></td><td>Box::contains</td><td>(treat as Ray)</td><td>CollisionDetection::collisionTimeForMovingPointFixedBox</td><td>(treat as Ray)</td><td>CollisionDetection::penetrationDepthForFixedBoxFixedPlane</td><td>CollisionDetection::penetrationDepthForFixedBoxFixedPlane</td><td>CollisionDetection::penetrationDepthForFixedSphereFixedBox</td><td>None (use OPCODE)</td><td>CollisionDetection::movingSpherePassesThroughFixedBox</td><td>CollisionDetection::penetrationDepthForFixedBoxFixedBox</td><td>CollisionDetection::penetrationDepthForFixedBoxFixedBox</td></tr> |
|---|
| 82 | </table> |
|---|
| 83 | |
|---|
| 84 | <p> |
|---|
| 85 | <b>Moving Collision Detection:</b> |
|---|
| 86 | |
|---|
| 87 | <i>* Note: Moving collision detection against certain primitives is equivalent to static collision |
|---|
| 88 | detection against a bigger primitive. Ray, Line Segment == ``moving Point''; Capsule ==``moving Sphere''; Plane == ``moving Line''</i> |
|---|
| 89 | */ |
|---|
| 90 | class CollisionDetection { |
|---|
| 91 | private: |
|---|
| 92 | |
|---|
| 93 | /** |
|---|
| 94 | Default parameter if value passed to a function as reference is |
|---|
| 95 | not to be calculated. Must be explicitly supported by function. |
|---|
| 96 | */ |
|---|
| 97 | static Vector3 ignore; |
|---|
| 98 | |
|---|
| 99 | /** |
|---|
| 100 | Default parameter if value passed to a function as reference is |
|---|
| 101 | not to be calculated. Must be explicitly supported by function. |
|---|
| 102 | */ |
|---|
| 103 | static bool ignoreBool; |
|---|
| 104 | |
|---|
| 105 | /** |
|---|
| 106 | Default parameter if value passed to a function as reference is |
|---|
| 107 | not to be calculated. Must be explicitly supported by function. |
|---|
| 108 | */ |
|---|
| 109 | static Array<Vector3> ignoreArray; |
|---|
| 110 | |
|---|
| 111 | |
|---|
| 112 | // Static class! |
|---|
| 113 | CollisionDetection() {} |
|---|
| 114 | virtual ~CollisionDetection() {} |
|---|
| 115 | |
|---|
| 116 | public: |
|---|
| 117 | |
|---|
| 118 | /** |
|---|
| 119 | Converts an index [0, 15] to the corresponding separating axis. |
|---|
| 120 | Does not return normalized vector in the edge-edge case |
|---|
| 121 | (indices 6 through 15). |
|---|
| 122 | |
|---|
| 123 | @param separatingAxisIndex Separating axis. |
|---|
| 124 | @param box1 Box 1. |
|---|
| 125 | @param box2 Box 2. |
|---|
| 126 | |
|---|
| 127 | @return Axis that separates the two boxes. |
|---|
| 128 | */ |
|---|
| 129 | static Vector3 separatingAxisForSolidBoxSolidBox( |
|---|
| 130 | const int separatingAxisIndex, |
|---|
| 131 | const Box & box1, |
|---|
| 132 | const Box & box2); |
|---|
| 133 | |
|---|
| 134 | /** |
|---|
| 135 | Tests whether two boxes have axes that are parallel to |
|---|
| 136 | each other. If they are, axis1 and axis2 are set to be |
|---|
| 137 | the parallel axes for both box1 and box2 respectively. |
|---|
| 138 | |
|---|
| 139 | @param ca Dot products of each of the boxes axes |
|---|
| 140 | @param epsilon Fudge factor (small unit by which the dot |
|---|
| 141 | products may vary and still be considered |
|---|
| 142 | zero). |
|---|
| 143 | @param axis1 Parallel Axis 1. [Post Condition] |
|---|
| 144 | @param axis2 Parallel Axis 2. [Post Condition] |
|---|
| 145 | |
|---|
| 146 | @return true - If boxes have a parallel axis |
|---|
| 147 | @return false - otherwise. |
|---|
| 148 | */ |
|---|
| 149 | static bool parallelAxisForSolidBoxSolidBox( |
|---|
| 150 | const double* ca, |
|---|
| 151 | const double epsilon, |
|---|
| 152 | int & axis1, |
|---|
| 153 | int & axis2); |
|---|
| 154 | |
|---|
| 155 | /** |
|---|
| 156 | Calculates the projected distance between the two boxes along |
|---|
| 157 | the specified separating axis, negative distances correspond |
|---|
| 158 | to an overlap along that separating axis. The distance is not |
|---|
| 159 | divided by denominator dot(L, L), see |
|---|
| 160 | penetrationDepthForFixedSphereFixedBox() for more details |
|---|
| 161 | |
|---|
| 162 | @param separatingAxisIndex |
|---|
| 163 | @param a Box 1's bounding sphere vector |
|---|
| 164 | @param b Box 2's bounding sphere vector |
|---|
| 165 | @param D Vector between Box 1 and Box 2's center points |
|---|
| 166 | @param c Pointer to array of dot products of the axes of Box 1 |
|---|
| 167 | and Box 2. |
|---|
| 168 | @param ca Pointer to array of unsigned dot products of the axes |
|---|
| 169 | of Box 1 and Box 2. |
|---|
| 170 | @param ad Pointer to array of dot products of Box 1 axes and D. |
|---|
| 171 | @param bd Pointer to array of dot products of Box 2 axes and D. |
|---|
| 172 | |
|---|
| 173 | @return Projected distance between the two boxes along the |
|---|
| 174 | specified separating axis. |
|---|
| 175 | */ |
|---|
| 176 | static float projectedDistanceForSolidBoxSolidBox( |
|---|
| 177 | const int separatingAxisIndex, |
|---|
| 178 | const Vector3 & a, |
|---|
| 179 | const Vector3 & b, |
|---|
| 180 | const Vector3 & D, |
|---|
| 181 | const double* c, |
|---|
| 182 | const double* ca, |
|---|
| 183 | const double* ad, |
|---|
| 184 | const double* bd); |
|---|
| 185 | |
|---|
| 186 | |
|---|
| 187 | /** |
|---|
| 188 | Creates a set of standard information about two boxes in order to |
|---|
| 189 | solve for their collision. This information includes a vector to |
|---|
| 190 | the radius of the bounding sphere for each box, the vector between |
|---|
| 191 | each boxes' center and a series of dot products between differing |
|---|
| 192 | important vectors. These dot products include those between the axes |
|---|
| 193 | of both boxes (signed and unsigned values), and the dot products |
|---|
| 194 | between all the axes of box1 and the boxes' center vector and box2 |
|---|
| 195 | and the boxes' center vector. |
|---|
| 196 | |
|---|
| 197 | @pre The following space requirements must be met: |
|---|
| 198 | - c[] 9 elements |
|---|
| 199 | - ca[] 9 elements |
|---|
| 200 | - ad[] 3 elements |
|---|
| 201 | - bd[] 3 elements |
|---|
| 202 | |
|---|
| 203 | @cite dobted from David Eberly's papers, variables used in this function |
|---|
| 204 | correspond to variables used in pages 6 and 7 in the pdf |
|---|
| 205 | http://www.magic-software.com/Intersection.html |
|---|
| 206 | http://www.magic-software.com/Documentation/DynamicCollisionDetection.pdf |
|---|
| 207 | |
|---|
| 208 | @note Links are out-dated. (Kept to preserve origin and authorship) |
|---|
| 209 | |
|---|
| 210 | @param box1 Box 1 |
|---|
| 211 | @param box2 Box 2 |
|---|
| 212 | @param a Box 1's bounding sphere vector |
|---|
| 213 | @param b Box 2's bounding sphere vector |
|---|
| 214 | @param D Vector between Box 1 and Box 2's center points |
|---|
| 215 | @param c Pointer to array of dot products of the axes of Box 1 |
|---|
| 216 | and Box 2. |
|---|
| 217 | @param ca Pointer to array of unsigned dot products of the axes |
|---|
| 218 | of Box 1 and Box 2. |
|---|
| 219 | @param ad Pointer to array of dot products of Box 1 axes and D. |
|---|
| 220 | @param bd Pointer to array of dot products of Box 2 axes and D. |
|---|
| 221 | */ |
|---|
| 222 | static void fillSolidBoxSolidBoxInfo( |
|---|
| 223 | const Box & box1, |
|---|
| 224 | const Box & box2, |
|---|
| 225 | Vector3 & a, |
|---|
| 226 | Vector3 & b, |
|---|
| 227 | Vector3 & D, |
|---|
| 228 | double* c, |
|---|
| 229 | double* ca, |
|---|
| 230 | double* ad, |
|---|
| 231 | double* bd); |
|---|
| 232 | |
|---|
| 233 | /** |
|---|
| 234 | Performs a simple bounding sphere check between two boxes to determine |
|---|
| 235 | whether these boxes could <i>possibly</i> intersect. This is a very |
|---|
| 236 | cheap operation (three dot products, two sqrts and a few others). If |
|---|
| 237 | it returns true, an intersection is possible, but not necessarily |
|---|
| 238 | guaranteed. |
|---|
| 239 | |
|---|
| 240 | @param a Vector from box A's center to an outer vertex |
|---|
| 241 | @param b Vector from box B's center to an outer vertex |
|---|
| 242 | @param D Distance between the centers of the two boxes |
|---|
| 243 | |
|---|
| 244 | @return true - if possible intersection |
|---|
| 245 | @return false - otherwise (This does not guarantee an intersection) |
|---|
| 246 | */ |
|---|
| 247 | static bool conservativeBoxBoxTest( |
|---|
| 248 | const Vector3 & a, |
|---|
| 249 | const Vector3 & b, |
|---|
| 250 | const Vector3 & D); |
|---|
| 251 | |
|---|
| 252 | /** |
|---|
| 253 | Determines whether two fixed solid boxes intersect. |
|---|
| 254 | |
|---|
| 255 | @note To speed up collision detection, the lastSeparatingAxis from |
|---|
| 256 | the previous time step can be passed in and that plane can be |
|---|
| 257 | checked first. If the separating axis was not saved, or if the |
|---|
| 258 | two boxes intersected then lastSeparatingAxis should equal -1. |
|---|
| 259 | |
|---|
| 260 | @cite Adobted from David Eberly's papers, variables used in this function |
|---|
| 261 | correspond to variables used in pages 6 and 7 in the pdf |
|---|
| 262 | http://www.magic-software.com/Intersection.html |
|---|
| 263 | http://www.magic-software.com/Documentation/DynamicCollisionDetection.pdf |
|---|
| 264 | |
|---|
| 265 | @param box1 Box 1. |
|---|
| 266 | @param box2 Box 2. |
|---|
| 267 | @param lastSeparatingAxis Last separating axis. |
|---|
| 268 | (optimization - see note) |
|---|
| 269 | |
|---|
| 270 | @return true - Intersection. |
|---|
| 271 | @return false - otherwise. |
|---|
| 272 | */ |
|---|
| 273 | static bool fixedSolidBoxIntersectsFixedSolidBox( |
|---|
| 274 | const Box& box1, |
|---|
| 275 | const Box& box2, |
|---|
| 276 | const int lastSeparatingAxis = -1); |
|---|
| 277 | |
|---|
| 278 | /** |
|---|
| 279 | Calculates the closest points on two lines with each other. If the |
|---|
| 280 | lines are parallel then using the starting point, else calculate the |
|---|
| 281 | closest point on each line to the other. |
|---|
| 282 | |
|---|
| 283 | @note This is very similiar to calculating the intersection of two lines. |
|---|
| 284 | Logically then, the two points calculated would be identical if calculated |
|---|
| 285 | with inifinite precision, but with the finite precision of floating point |
|---|
| 286 | calculations, these values could (will) differ as the line slope approaches |
|---|
| 287 | zero or inifinity. |
|---|
| 288 | |
|---|
| 289 | @cite variables and algorithm based on derivation at the following website: |
|---|
| 290 | http://softsurfer.com/Archive/algorithm_0106/algorithm_0106.htm |
|---|
| 291 | |
|---|
| 292 | @param line1 Line 1. |
|---|
| 293 | @param line2 Line 2. |
|---|
| 294 | @param closest1 Closest point on line 1. |
|---|
| 295 | @param closest2 Closest point on line 2. |
|---|
| 296 | */ |
|---|
| 297 | static void closestPointsBetweenLineAndLine( |
|---|
| 298 | const Line & line1, |
|---|
| 299 | const Line & line2, |
|---|
| 300 | Vector3 & closest1, |
|---|
| 301 | Vector3 & closest2); |
|---|
| 302 | |
|---|
| 303 | /** |
|---|
| 304 | Calculates the depth of penetration between two fixed boxes. |
|---|
| 305 | Contact normal faces away from box1 and into box2. If there is |
|---|
| 306 | contact, only one contact point is returned. The minimally |
|---|
| 307 | violated separating plane is computed |
|---|
| 308 | - if the separating axis corresponds to a face |
|---|
| 309 | the contact point is half way between the deepest vertex |
|---|
| 310 | and the face |
|---|
| 311 | - if the separating axis corresponds to two edges |
|---|
| 312 | the contact point is the midpoint of the smallest line |
|---|
| 313 | segment between the two edge lines |
|---|
| 314 | |
|---|
| 315 | @note This is very similiar to calculating the intersection of two lines. |
|---|
| 316 | Logically then, the two points calculated would be identical if calculated |
|---|
| 317 | with inifinite precision, but with the finite precision of floating point |
|---|
| 318 | calculations, these values could (will) differ as the line slope approaches |
|---|
| 319 | zero or inifinity. |
|---|
| 320 | |
|---|
| 321 | @cite adobted from David Eberly's papers, variables used in this function |
|---|
| 322 | correspond to variables used in pages 6 and 7 in the pdf |
|---|
| 323 | http://www.magic-software.com/Intersection.html |
|---|
| 324 | http://www.magic-software.com/Documentation/DynamicCollisionDetection.pdf |
|---|
| 325 | |
|---|
| 326 | @param box1 Box 1 |
|---|
| 327 | @param box2 Box 2 |
|---|
| 328 | @param contactPoints Contact point between boxes. [Post Condition] |
|---|
| 329 | @param contactNormals Surface normal at contact point. [Post Condition] |
|---|
| 330 | @param lastSeparatingAxis Last separating axis. (Used for optimization) |
|---|
| 331 | |
|---|
| 332 | @return Depth of penetration between the two boxes. If there is no |
|---|
| 333 | intersection between the boxes, then a negative value is returned. |
|---|
| 334 | */ |
|---|
| 335 | static float penetrationDepthForFixedBoxFixedBox( |
|---|
| 336 | const Box& box1, |
|---|
| 337 | const Box& box2, |
|---|
| 338 | Array<Vector3>& contactPoints, |
|---|
| 339 | Array<Vector3>& contactNormals, |
|---|
| 340 | const int lastSeparatingAxis = -1); |
|---|
| 341 | |
|---|
| 342 | /** |
|---|
| 343 | Calculates the depth of penetration between two fixed spheres as well |
|---|
| 344 | as the deepest point of Sphere A that penetrates Sphere B. The normal |
|---|
| 345 | returned points <B>away</B> from the object A, although it may |
|---|
| 346 | represent a perpendicular to either the faces of object B or object A |
|---|
| 347 | depending on their relative orientations. |
|---|
| 348 | |
|---|
| 349 | @param sphereA Fixed Sphere A. |
|---|
| 350 | @param sphereB Fixed Sphere B. |
|---|
| 351 | @param contactPoints Sphere A's deepest point that penetrates Sphere B. |
|---|
| 352 | [Post Condition] |
|---|
| 353 | @param contactNormals Normal at penetration point. [Post Condition] |
|---|
| 354 | |
|---|
| 355 | @return Depth of penetration. If there is no intersection between the |
|---|
| 356 | objects then the depth will be a negative value. |
|---|
| 357 | */ |
|---|
| 358 | static float penetrationDepthForFixedSphereFixedSphere( |
|---|
| 359 | const class Sphere& sphereA, |
|---|
| 360 | const Sphere& sphereB, |
|---|
| 361 | Array<Vector3>& contactPoints, |
|---|
| 362 | Array<Vector3>& contactNormals = ignoreArray); |
|---|
| 363 | |
|---|
| 364 | /** |
|---|
| 365 | Calculates the depth of penetration between a fixed sphere and a fixed |
|---|
| 366 | box as well as the deepest point of the sphere that penetrates the box |
|---|
| 367 | and the normal at that intersection. |
|---|
| 368 | |
|---|
| 369 | @note There are three possible intersections between a sphere and box. |
|---|
| 370 | - Sphere completely contained in the box |
|---|
| 371 | - Sphere intersects one edge |
|---|
| 372 | - Sphere intersects one vertex |
|---|
| 373 | |
|---|
| 374 | The contact point and contact normal vary for each of these situations. |
|---|
| 375 | - Sphere contained in Box: |
|---|
| 376 | - Normal is based on side of least penetration (as is the depth calculation). |
|---|
| 377 | - Point is based on center of sphere |
|---|
| 378 | - Sphere intersects one edge |
|---|
| 379 | - Normal is based on vector from the box center to the point of depth. |
|---|
| 380 | - Point is closest point to the sphere on the line |
|---|
| 381 | - Sphere intersects one vertex |
|---|
| 382 | - Normal is based on vector from the box center to the vertex of penetration. |
|---|
| 383 | - Point is vertex of penetration. |
|---|
| 384 | |
|---|
| 385 | @cite Adapted from Jim Arvo's method in Graphics Gems |
|---|
| 386 | See also http://www.win.tue.nl/~gino/solid/gdc2001depth.pdf |
|---|
| 387 | |
|---|
| 388 | @param sphere Fixed Sphere. |
|---|
| 389 | @param box Fixed Box. |
|---|
| 390 | @param contactPoints Sphere point that penetrates the box. [Post Condition] |
|---|
| 391 | @param contactNormals Normal at the penetration point. [Post Condition] |
|---|
| 392 | |
|---|
| 393 | @return Depth of penetration. If there is no intersection between the |
|---|
| 394 | objects then the depth will be a negative value. |
|---|
| 395 | */ |
|---|
| 396 | static float penetrationDepthForFixedSphereFixedBox( |
|---|
| 397 | const Sphere& sphere, |
|---|
| 398 | const Box& box, |
|---|
| 399 | Array<Vector3>& contactPoints, |
|---|
| 400 | Array<Vector3>& contactNormals = ignoreArray); |
|---|
| 401 | |
|---|
| 402 | /** |
|---|
| 403 | Calculates the depth of penetration between a Fixed Sphere and a Fixed |
|---|
| 404 | Plane as well as the deepest point of the sphere that penetrates the plane |
|---|
| 405 | and the plane normal at that intersection. |
|---|
| 406 | |
|---|
| 407 | @param sphere Fixed Sphere. |
|---|
| 408 | @param plane Fixed Plane. |
|---|
| 409 | @param contactPoints Sphere point that penetrates the plane. |
|---|
| 410 | [Post Condition] |
|---|
| 411 | @param contactNormals Normal at penetration point. [Post Condition] |
|---|
| 412 | |
|---|
| 413 | @return Depth of penetration. If there is no intersection between the |
|---|
| 414 | objects then the depth will be a negative value. |
|---|
| 415 | */ |
|---|
| 416 | static float penetrationDepthForFixedSphereFixedPlane( |
|---|
| 417 | const Sphere& sphereA, |
|---|
| 418 | const class Plane& planeB, |
|---|
| 419 | Array<Vector3>& contactPoints, |
|---|
| 420 | Array<Vector3>& contactNormals = ignoreArray); |
|---|
| 421 | |
|---|
| 422 | /** |
|---|
| 423 | Calculates the depth of penetration between a fixed box and a fixed |
|---|
| 424 | plane as well as the vertexes of the box that penetrate the plane |
|---|
| 425 | and the plane normals at those intersections. |
|---|
| 426 | |
|---|
| 427 | @param box Fixed Box. |
|---|
| 428 | @param plane Fixed Plane. |
|---|
| 429 | @param contactPoints Box points that penetrate the plane. |
|---|
| 430 | [Post Condition] |
|---|
| 431 | @param contactNormals Normals at penetration points [Post Condition] |
|---|
| 432 | |
|---|
| 433 | @return Depth of penetration. If there is no intersection between the |
|---|
| 434 | objects then the depth will be a negative value. |
|---|
| 435 | */ |
|---|
| 436 | static float penetrationDepthForFixedBoxFixedPlane( |
|---|
| 437 | const Box& box, |
|---|
| 438 | const Plane& plane, |
|---|
| 439 | Array<Vector3>& contactPoints, |
|---|
| 440 | Array<Vector3>& contactNormals = ignoreArray); |
|---|
| 441 | |
|---|
| 442 | /** |
|---|
| 443 | Calculates time between the intersection of a moving point and a fixed |
|---|
| 444 | plane. |
|---|
| 445 | |
|---|
| 446 | @note This is only a one sided collision test. The side defined by |
|---|
| 447 | the plane's surface normal is the only one tested. For a two sided |
|---|
| 448 | collision, call the function once for each side's surface normal. |
|---|
| 449 | |
|---|
| 450 | @param point Moving point. |
|---|
| 451 | @param velocity Point's velocity. |
|---|
| 452 | @param plane Fixed plane. |
|---|
| 453 | @param location Location of collision. [Post Condition] |
|---|
| 454 | (Infinite vector on no collision) |
|---|
| 455 | @param outNormal Plane's surface normal. [Post Condition] |
|---|
| 456 | |
|---|
| 457 | @return Time til collision. If there is no collision then the return |
|---|
| 458 | value will be inf(). |
|---|
| 459 | */ |
|---|
| 460 | static float collisionTimeForMovingPointFixedPlane( |
|---|
| 461 | const Vector3& point, |
|---|
| 462 | const Vector3& velocity, |
|---|
| 463 | const class Plane& plane, |
|---|
| 464 | Vector3& outLocation, |
|---|
| 465 | Vector3& outNormal = ignore); |
|---|
| 466 | |
|---|
| 467 | /** |
|---|
| 468 | Calculates time between the intersection of a moving point and a fixed |
|---|
| 469 | triangle. |
|---|
| 470 | |
|---|
| 471 | @note This is only a one sided collision test. The side defined by |
|---|
| 472 | the triangle's surface normal is the only one tested. For a two sided |
|---|
| 473 | collision, call the function once for each side's surface normal. |
|---|
| 474 | |
|---|
| 475 | @param orig Moving point. |
|---|
| 476 | @param dir Point's velocity. |
|---|
| 477 | @param v0 Triangle vertex 1. |
|---|
| 478 | @param v1 Triangle vertex 2. |
|---|
| 479 | @param v2 Triangle vertex 3 |
|---|
| 480 | @param location Location of collision. [Post Condition] |
|---|
| 481 | (Infinite vector on no collision) |
|---|
| 482 | |
|---|
| 483 | @return Time til collision. If there is no collision then the return |
|---|
| 484 | value will be inf(). |
|---|
| 485 | */ |
|---|
| 486 | inline static float collisionTimeForMovingPointFixedTriangle( |
|---|
| 487 | const Vector3& orig, |
|---|
| 488 | const Vector3& dir, |
|---|
| 489 | const Vector3& v0, |
|---|
| 490 | const Vector3& v1, |
|---|
| 491 | const Vector3& v2) { |
|---|
| 492 | return Ray::fromOriginAndDirection(orig, dir).intersectionTime(v0, v1, v2); |
|---|
| 493 | } |
|---|
| 494 | |
|---|
| 495 | /** |
|---|
| 496 | Calculates time between the intersection of a moving point and a fixed |
|---|
| 497 | triangle. |
|---|
| 498 | |
|---|
| 499 | @note This is only a one sided collision test. The side defined by |
|---|
| 500 | the triangle's surface normal is the only one tested. For a two sided |
|---|
| 501 | collision, call the function once for each side's surface normal. |
|---|
| 502 | |
|---|
| 503 | @param orig Moving point. |
|---|
| 504 | @param dir Point's velocity. |
|---|
| 505 | @param v0 Triangle vertex 1. |
|---|
| 506 | @param v1 Triangle vertex 2. |
|---|
| 507 | @param v2 Triangle vertex 3 |
|---|
| 508 | @param location Location of collision. [Post Condition] |
|---|
| 509 | (Infinite vector on no collision) |
|---|
| 510 | |
|---|
| 511 | @return Time til collision. If there is no collision then the return |
|---|
| 512 | value will be inf(). |
|---|
| 513 | */ |
|---|
| 514 | inline static float collisionTimeForMovingPointFixedTriangle( |
|---|
| 515 | const Vector3& orig, |
|---|
| 516 | const Vector3& dir, |
|---|
| 517 | const Vector3& v0, |
|---|
| 518 | const Vector3& v1, |
|---|
| 519 | const Vector3& v2, |
|---|
| 520 | Vector3& location) { |
|---|
| 521 | float t = collisionTimeForMovingPointFixedTriangle(orig, dir, v0, v1, v2); |
|---|
| 522 | if (t < inf()) { |
|---|
| 523 | location = orig + dir * t; |
|---|
| 524 | } |
|---|
| 525 | return t; |
|---|
| 526 | } |
|---|
| 527 | |
|---|
| 528 | /** |
|---|
| 529 | Calculates time between the intersection of a moving point and a fixed |
|---|
| 530 | triangle. |
|---|
| 531 | |
|---|
| 532 | @note This is only a one sided collision test. The side defined by |
|---|
| 533 | the triangle's surface normal is the only one tested. For a two sided |
|---|
| 534 | collision, call the function once for each side's surface normal. |
|---|
| 535 | |
|---|
| 536 | @param orig Moving point. |
|---|
| 537 | @param dir Point's velocity. |
|---|
| 538 | @param tri Fixed triangle. |
|---|
| 539 | @param location Location of collision. [Post Condition] |
|---|
| 540 | (Infinite vector on no collision) |
|---|
| 541 | @param normal Triangle's surface normal. [Post Condition] |
|---|
| 542 | |
|---|
| 543 | @return Time til collision. If there is no collision then the return |
|---|
| 544 | value will be inf(). |
|---|
| 545 | */ |
|---|
| 546 | inline static float collisionTimeForMovingPointFixedTriangle( |
|---|
| 547 | const Vector3& orig, |
|---|
| 548 | const Vector3& dir, |
|---|
| 549 | const Triangle& tri, |
|---|
| 550 | Vector3& location = ignore, |
|---|
| 551 | Vector3& normal = ignore) { |
|---|
| 552 | |
|---|
| 553 | float t = collisionTimeForMovingPointFixedTriangle( |
|---|
| 554 | orig, dir, tri.vertex(0), tri.vertex(1), tri.vertex(2)); |
|---|
| 555 | |
|---|
| 556 | if ((t < inf()) && (&location != &ignore)) { |
|---|
| 557 | location = orig + dir * t; |
|---|
| 558 | normal = tri.normal(); |
|---|
| 559 | } |
|---|
| 560 | return t; |
|---|
| 561 | } |
|---|
| 562 | |
|---|
| 563 | /** |
|---|
| 564 | Calculates time between the intersection of a moving point and a fixed |
|---|
| 565 | triangle. |
|---|
| 566 | |
|---|
| 567 | @note This is only a one sided collision test. The side defined by |
|---|
| 568 | the triangle's surface normal is the only one tested. For a two sided |
|---|
| 569 | collision, call the function once for each side's surface normal. |
|---|
| 570 | |
|---|
| 571 | @param orig Moving point. |
|---|
| 572 | @param dir Point's velocity. |
|---|
| 573 | @param v0 Triangle vertex 1. |
|---|
| 574 | @param v1 Triangle vertex 2. |
|---|
| 575 | @param v2 Triangle vertex 3 |
|---|
| 576 | @param location Location of collision. [Post Condition] |
|---|
| 577 | (Infinite vector on no collision) |
|---|
| 578 | @param normal Triangle's surface normal. [Post Condition] |
|---|
| 579 | |
|---|
| 580 | @return Time til collision. If there is no collision then the return |
|---|
| 581 | value will be inf(). |
|---|
| 582 | */ |
|---|
| 583 | inline static float collisionTimeForMovingPointFixedTriangle( |
|---|
| 584 | const Vector3& orig, |
|---|
| 585 | const Vector3& dir, |
|---|
| 586 | const Vector3& v0, |
|---|
| 587 | const Vector3& v1, |
|---|
| 588 | const Vector3& v2, |
|---|
| 589 | Vector3& location, |
|---|
| 590 | Vector3& normal) { |
|---|
| 591 | float t = collisionTimeForMovingPointFixedTriangle(orig, dir, v0, v1, v2); |
|---|
| 592 | if (t < inf()) { |
|---|
| 593 | location = orig + dir * t; |
|---|
| 594 | normal = (v2 - v0).cross(v1 - v0).direction(); |
|---|
| 595 | } |
|---|
| 596 | return t; |
|---|
| 597 | } |
|---|
| 598 | |
|---|
| 599 | /** |
|---|
| 600 | Unlike other methods, does not support an output normal. |
|---|
| 601 | If the ray origin is inside the box, returns inf() but inside |
|---|
| 602 | is set to true. |
|---|
| 603 | <B>Beta API</B> |
|---|
| 604 | |
|---|
| 605 | @cite Andrew Woo, from "Graphics Gems", Academic Press, 1990 |
|---|
| 606 | @cite Optimized code by Pierre Terdiman, 2000 (~20-30% faster on my Celeron 500) |
|---|
| 607 | @cite Epsilon value added by Klaus Hartmann |
|---|
| 608 | @cite http://www.codercorner.com/RayAABB.cpp |
|---|
| 609 | */ |
|---|
| 610 | static float collisionTimeForMovingPointFixedAABox( |
|---|
| 611 | const Vector3& point, |
|---|
| 612 | const Vector3& velocity, |
|---|
| 613 | const class AABox& box, |
|---|
| 614 | Vector3& outLocation, |
|---|
| 615 | bool& inside = ignoreBool, |
|---|
| 616 | Vector3& outNormal = ignore); |
|---|
| 617 | |
|---|
| 618 | /** |
|---|
| 619 | Calculates time between the intersection of a moving point and a fixed |
|---|
| 620 | Axis-Aligned Box (AABox). |
|---|
| 621 | |
|---|
| 622 | @note Avoids the sqrt from collisionTimeForMovingPointFixedAABox. |
|---|
| 623 | |
|---|
| 624 | @param point Moving point. |
|---|
| 625 | @param velocity Sphere's velocity. |
|---|
| 626 | @param box Fixed AAbox. |
|---|
| 627 | @param location Location of collision. [Post Condition] |
|---|
| 628 | @param Inside Does the ray originate inside the box? [Post Condition] |
|---|
| 629 | @param normal Box's surface normal to collision [Post Condition] |
|---|
| 630 | |
|---|
| 631 | @return Time til collision. If there is no collision then the return |
|---|
| 632 | value will be inf(). |
|---|
| 633 | */ |
|---|
| 634 | static bool collisionLocationForMovingPointFixedAABox( |
|---|
| 635 | const Vector3& point, |
|---|
| 636 | const Vector3& velocity, |
|---|
| 637 | const class AABox& box, |
|---|
| 638 | Vector3& outLocation, |
|---|
| 639 | bool& inside = ignoreBool, |
|---|
| 640 | Vector3& normal = ignore); |
|---|
| 641 | |
|---|
| 642 | /** |
|---|
| 643 | Calculates time between the intersection of a moving point and a fixed |
|---|
| 644 | sphere. |
|---|
| 645 | |
|---|
| 646 | @note When ray is starts inside the rectangle, the exiting intersection |
|---|
| 647 | is detected. |
|---|
| 648 | |
|---|
| 649 | @param point Moving point. |
|---|
| 650 | @param velocity Point's velocity. |
|---|
| 651 | @param Sphere Fixed Sphere. |
|---|
| 652 | @param location Location of collision. [Post Condition] |
|---|
| 653 | @param outNormal Sphere's surface normal to collision [Post Condition] |
|---|
| 654 | |
|---|
| 655 | @return Time til collision. If there is no collision then the return |
|---|
| 656 | value will be inf(). |
|---|
| 657 | */ |
|---|
| 658 | static float collisionTimeForMovingPointFixedSphere( |
|---|
| 659 | const Vector3& point, |
|---|
| 660 | const Vector3& velocity, |
|---|
| 661 | const class Sphere& sphere, |
|---|
| 662 | Vector3& outLocation, |
|---|
| 663 | Vector3& outNormal = ignore); |
|---|
| 664 | |
|---|
| 665 | /** |
|---|
| 666 | Calculates time between the intersection of a moving point and a fixed |
|---|
| 667 | box. |
|---|
| 668 | |
|---|
| 669 | @note If the point is already inside the box, no collision: inf is returned. |
|---|
| 670 | |
|---|
| 671 | @param point Moving point. |
|---|
| 672 | @param velocity Sphere's velocity. |
|---|
| 673 | @param box Fixed box. |
|---|
| 674 | @param location Position of collision. [Post Condition] |
|---|
| 675 | @param outNormal Box's surface normal to collision [Post Condition] |
|---|
| 676 | |
|---|
| 677 | @return Time til collision. If there is no collision then the return |
|---|
| 678 | value will be inf(). |
|---|
| 679 | */ |
|---|
| 680 | static float collisionTimeForMovingPointFixedBox( |
|---|
| 681 | const Vector3& point, |
|---|
| 682 | const Vector3& velocity, |
|---|
| 683 | const class Box& box, |
|---|
| 684 | Vector3& outLocation, |
|---|
| 685 | Vector3& outNormal = ignore); |
|---|
| 686 | |
|---|
| 687 | /** |
|---|
| 688 | Calculates time between the intersection of a moving point and a fixed |
|---|
| 689 | rectangle defined by the points v0, v1, v2, & v3. |
|---|
| 690 | |
|---|
| 691 | @note This is only a one sided collision test. The side defined by |
|---|
| 692 | the rectangle's surface normal is the only one tested. For a two sided |
|---|
| 693 | collision, call the function once for each side's surface normal. |
|---|
| 694 | |
|---|
| 695 | @param point Moving point. |
|---|
| 696 | @param velocity Sphere's velocity. |
|---|
| 697 | @param v0 Rectangle vertex 1. |
|---|
| 698 | @param v1 Rectangle vertex 2. |
|---|
| 699 | @param v2 Rectangle vertex 3 |
|---|
| 700 | @param v3 Rectangle vertex 4. |
|---|
| 701 | @param location Location of collision [Post Condition] |
|---|
| 702 | @param outNormal Rectangle's surface normal. [Post Condition] |
|---|
| 703 | |
|---|
| 704 | @return Time til collision. If there is no collision then the return |
|---|
| 705 | value will be inf(). |
|---|
| 706 | */ |
|---|
| 707 | static float collisionTimeForMovingPointFixedRectangle( |
|---|
| 708 | const Vector3& point, |
|---|
| 709 | const Vector3& velocity, |
|---|
| 710 | const Vector3& v0, |
|---|
| 711 | const Vector3& v1, |
|---|
| 712 | const Vector3& v2, |
|---|
| 713 | const Vector3& v3, |
|---|
| 714 | Vector3& outLocation, |
|---|
| 715 | Vector3& outNormal = ignore); |
|---|
| 716 | |
|---|
| 717 | /** |
|---|
| 718 | Calculates time between the intersection of a moving point and a fixed |
|---|
| 719 | capsule. |
|---|
| 720 | |
|---|
| 721 | @param point Moving point. |
|---|
| 722 | @param velocity Point's velocity. |
|---|
| 723 | @param capsule Fixed capsule. |
|---|
| 724 | @param location Location of collision. [Post Condition] |
|---|
| 725 | @param outNormal Capsule's surface normal to collision [Post Condition] |
|---|
| 726 | |
|---|
| 727 | @return Time til collision. If there is no collision then the return |
|---|
| 728 | value will be inf(). |
|---|
| 729 | */ |
|---|
| 730 | static float collisionTimeForMovingPointFixedCapsule( |
|---|
| 731 | const Vector3& point, |
|---|
| 732 | const Vector3& velocity, |
|---|
| 733 | const class Capsule& capsule, |
|---|
| 734 | Vector3& outLocation, |
|---|
| 735 | Vector3& outNormal = ignore); |
|---|
| 736 | |
|---|
| 737 | /** |
|---|
| 738 | Calculates time between the intersection of a moving sphere and a fixed |
|---|
| 739 | triangle. |
|---|
| 740 | |
|---|
| 741 | @param sphere Moving sphere. |
|---|
| 742 | @param velocity Sphere's velocity. |
|---|
| 743 | @param plane Fixed Plane. |
|---|
| 744 | @param location Location of collision -- not center position of sphere |
|---|
| 745 | at the collision time. [Post Condition] |
|---|
| 746 | @param outNormal Box's surface normal to collision [Post Condition] |
|---|
| 747 | |
|---|
| 748 | @return Time til collision. If there is no collision then the return |
|---|
| 749 | value will be inf(). |
|---|
| 750 | */ |
|---|
| 751 | static float collisionTimeForMovingSphereFixedPlane( |
|---|
| 752 | const class Sphere& sphere, |
|---|
| 753 | const Vector3& velocity, |
|---|
| 754 | const class Plane& plane, |
|---|
| 755 | Vector3& outLocation, |
|---|
| 756 | Vector3& outNormal = ignore); |
|---|
| 757 | |
|---|
| 758 | /** |
|---|
| 759 | Calculates time between the intersection of a moving sphere and a fixed |
|---|
| 760 | triangle. |
|---|
| 761 | |
|---|
| 762 | @param sphere Moving sphere. |
|---|
| 763 | @param velocity Sphere's velocity. |
|---|
| 764 | @param triangle Fixed Triangle. |
|---|
| 765 | @param location Location of collision -- not center position of sphere |
|---|
| 766 | at the collision time. [Post Condition] |
|---|
| 767 | @param outNormal Box's surface normal to collision [Post Condition] |
|---|
| 768 | |
|---|
| 769 | @return Time til collision. If there is no collision then the return |
|---|
| 770 | value will be inf(). |
|---|
| 771 | */ |
|---|
| 772 | static float collisionTimeForMovingSphereFixedTriangle( |
|---|
| 773 | const class Sphere& sphere, |
|---|
| 774 | const Vector3& velocity, |
|---|
| 775 | const Triangle& triangle, |
|---|
| 776 | Vector3& outLocation, |
|---|
| 777 | Vector3& outNormal = ignore); |
|---|
| 778 | |
|---|
| 779 | /** |
|---|
| 780 | Calculates time between the intersection of a moving sphere and a fixed |
|---|
| 781 | rectangle defined by the points v0, v1, v2, & v3. |
|---|
| 782 | |
|---|
| 783 | @param sphere Moving sphere. |
|---|
| 784 | @param velocity Sphere's velocity. |
|---|
| 785 | @param v0 Rectangle vertex 1. |
|---|
| 786 | @param v1 Rectangle vertex 2. |
|---|
| 787 | @param v2 Rectangle vertex 3 |
|---|
| 788 | @param v3 Rectangle vertex 4. |
|---|
| 789 | @param location Location of collision -- not center position of sphere |
|---|
| 790 | at the collision time. [Post Condition] |
|---|
| 791 | @param outNormal Box's surface normal to collision [Post Condition] |
|---|
| 792 | |
|---|
| 793 | @return Time til collision. If there is no collision then the return |
|---|
| 794 | value will be inf(). |
|---|
| 795 | */ |
|---|
| 796 | static float collisionTimeForMovingSphereFixedRectangle( |
|---|
| 797 | const class Sphere& sphere, |
|---|
| 798 | const Vector3& velocity, |
|---|
| 799 | const Vector3& v0, |
|---|
| 800 | const Vector3& v1, |
|---|
| 801 | const Vector3& v2, |
|---|
| 802 | const Vector3& v3, |
|---|
| 803 | Vector3& outLocation, |
|---|
| 804 | Vector3& outNormal = ignore); |
|---|
| 805 | |
|---|
| 806 | /** |
|---|
| 807 | Calculates time between the intersection of a moving sphere and a fixed |
|---|
| 808 | box. |
|---|
| 809 | |
|---|
| 810 | @note This function will not detect an intersection between a moving object |
|---|
| 811 | that is already interpenetrating the fixed object. |
|---|
| 812 | |
|---|
| 813 | @param sphere Moving sphere. |
|---|
| 814 | @param velocity Sphere's velocity. |
|---|
| 815 | @param box Fixed box. |
|---|
| 816 | @param location Location of collision -- not center position of sphere |
|---|
| 817 | at the collision time. [Post Condition] |
|---|
| 818 | @param outNormal Box's surface normal to collision [Post Condition] |
|---|
| 819 | |
|---|
| 820 | @return Time til collision. If there is no collision then the return |
|---|
| 821 | value will be inf(). |
|---|
| 822 | */ |
|---|
| 823 | static float collisionTimeForMovingSphereFixedBox( |
|---|
| 824 | const class Sphere& sphere, |
|---|
| 825 | const Vector3& velocity, |
|---|
| 826 | const class Box& box, |
|---|
| 827 | Vector3& outLocation, |
|---|
| 828 | Vector3& outNormal = ignore); |
|---|
| 829 | |
|---|
| 830 | /** |
|---|
| 831 | Calculates time between the intersection of a moving sphere and a fixed |
|---|
| 832 | sphere. |
|---|
| 833 | |
|---|
| 834 | @note This won't detect a collision if the sphere is already interpenetrating |
|---|
| 835 | the fixed sphere. |
|---|
| 836 | |
|---|
| 837 | @param movingSphere Moving sphere. |
|---|
| 838 | @param velocity Sphere's velocity. |
|---|
| 839 | @param fixedSphere Fixed Sphere. |
|---|
| 840 | @param location Location of collision -- not center position of sphere |
|---|
| 841 | at the collision time. [Post Condition] |
|---|
| 842 | @param outNormal Sphere's surface normal to collision [Post Condition] |
|---|
| 843 | |
|---|
| 844 | @return Time til collision. If there is no collision then the return |
|---|
| 845 | value will be inf(). |
|---|
| 846 | */ |
|---|
| 847 | static float collisionTimeForMovingSphereFixedSphere( |
|---|
| 848 | const class Sphere& sphere, |
|---|
| 849 | const Vector3& velocity, |
|---|
| 850 | const class Sphere& fixedSphere, |
|---|
| 851 | Vector3& outLocation, |
|---|
| 852 | Vector3& outNormal = ignore); |
|---|
| 853 | |
|---|
| 854 | /** |
|---|
| 855 | Calculates time between the intersection of a moving sphere and a fixed |
|---|
| 856 | capsule. |
|---|
| 857 | |
|---|
| 858 | @note This won't detect a collision if the sphere is already |
|---|
| 859 | interpenetrating the capsule. |
|---|
| 860 | |
|---|
| 861 | @param sphere Moving sphere. |
|---|
| 862 | @param velocity Sphere's velocity. |
|---|
| 863 | @param capsule Fixed capsule. |
|---|
| 864 | @param location Location of collision -- not center position of sphere |
|---|
| 865 | at the collision time. [Post Condition] |
|---|
| 866 | @param outNormal Capsule's surface normal to the collision [Post Condition] |
|---|
| 867 | |
|---|
| 868 | @return Time til collision. If there is no collision then the return |
|---|
| 869 | value will be inf(). |
|---|
| 870 | */ |
|---|
| 871 | static float collisionTimeForMovingSphereFixedCapsule( |
|---|
| 872 | const class Sphere& sphere, |
|---|
| 873 | const Vector3& velocity, |
|---|
| 874 | const class Capsule& capsule, |
|---|
| 875 | Vector3& outLocation, |
|---|
| 876 | Vector3& outNormal = ignore); |
|---|
| 877 | |
|---|
| 878 | /** |
|---|
| 879 | Finds the direction of bounce that a sphere would have when it |
|---|
| 880 | intersects an object with the given time of collision, the |
|---|
| 881 | collision location and the collision normal. |
|---|
| 882 | |
|---|
| 883 | @note This function works like a pong style ball bounce. |
|---|
| 884 | |
|---|
| 885 | @param sphere Moving sphere. |
|---|
| 886 | @param velocity Sphere's velocity. |
|---|
| 887 | @param collisionTime Time of collision. |
|---|
| 888 | @param collisionLocation Collision location. |
|---|
| 889 | @param collisionNormal Surface collision normal. |
|---|
| 890 | |
|---|
| 891 | @return Direction of bounce. |
|---|
| 892 | */ |
|---|
| 893 | static Vector3 bounceDirection( |
|---|
| 894 | const class Sphere& sphere, |
|---|
| 895 | const Vector3& velocity, |
|---|
| 896 | const float collisionTime, |
|---|
| 897 | const Vector3& collisionLocation, |
|---|
| 898 | const Vector3& collisionNormal); |
|---|
| 899 | |
|---|
| 900 | /** |
|---|
| 901 | Finds the direction of slide given a moving sphere, its velocity, the |
|---|
| 902 | time of collision and the collision location. This function works as |
|---|
| 903 | if the sphere intersects the surface and continues to hug it. |
|---|
| 904 | |
|---|
| 905 | @note The result will work well for calculating the movement of a player |
|---|
| 906 | who collides with an object and continues moving along the object instead |
|---|
| 907 | of just bouncing off it. |
|---|
| 908 | |
|---|
| 909 | @param sphere Moving sphere. |
|---|
| 910 | @param velocity Sphere's velocity. |
|---|
| 911 | @param collisionTime Time of collision |
|---|
| 912 | @param collisionLocation Collision location. |
|---|
| 913 | |
|---|
| 914 | @return Direction of slide. |
|---|
| 915 | */ |
|---|
| 916 | static Vector3 slideDirection( |
|---|
| 917 | const class Sphere& sphere, |
|---|
| 918 | const Vector3& velocity, |
|---|
| 919 | const float collisionTime, |
|---|
| 920 | const Vector3& collisionLocation); |
|---|
| 921 | |
|---|
| 922 | /** |
|---|
| 923 | Finds the closest point on a line segment to a given point. |
|---|
| 924 | |
|---|
| 925 | @param v0 line vertex 1. |
|---|
| 926 | @param v1 line vertex 2. |
|---|
| 927 | @param point External point. |
|---|
| 928 | |
|---|
| 929 | @return Closests point to <code>point</code> on the line segment. |
|---|
| 930 | */ |
|---|
| 931 | static Vector3 closestPointOnLineSegment( |
|---|
| 932 | const Vector3& v0, |
|---|
| 933 | const Vector3& v1, |
|---|
| 934 | const Vector3& point); |
|---|
| 935 | |
|---|
| 936 | /** |
|---|
| 937 | Finds the closest point on a line segment to a given point. |
|---|
| 938 | |
|---|
| 939 | @note This is an optimization to closestPointOnLineSegment. Edge length |
|---|
| 940 | and direction can be used in this function if already pre-calculated. This |
|---|
| 941 | prevents doing the same work twice. |
|---|
| 942 | |
|---|
| 943 | @param v0 line vertex 1. |
|---|
| 944 | @param v1 line vertex 2. |
|---|
| 945 | @param edgeDirection The direction of the segment (unit length). |
|---|
| 946 | @param edgeLength The length of the segment. |
|---|
| 947 | @param point External point. |
|---|
| 948 | |
|---|
| 949 | @return Closests point to <code>point</code> on the line segment. |
|---|
| 950 | */ |
|---|
| 951 | static Vector3 closestPointOnLineSegment( |
|---|
| 952 | const Vector3& v0, |
|---|
| 953 | const Vector3& v1, |
|---|
| 954 | const Vector3& edgeDirection, |
|---|
| 955 | float edgeLength, |
|---|
| 956 | const Vector3& point); |
|---|
| 957 | |
|---|
| 958 | /** |
|---|
| 959 | Finds the closest point on the perimeter of the triangle to an external point; |
|---|
| 960 | given a triangle defined by three points v0, v1, & v2, and the external point. |
|---|
| 961 | |
|---|
| 962 | @param v0 Triangle vertex 1. |
|---|
| 963 | @param v1 Triangle vertex 2. |
|---|
| 964 | @param v2 Triangle vertex 3. |
|---|
| 965 | @param point External point. |
|---|
| 966 | |
|---|
| 967 | @return Closests point to <code>point</code> on the perimeter of the |
|---|
| 968 | triangle. |
|---|
| 969 | */ |
|---|
| 970 | static Vector3 closestPointToTrianglePerimeter( |
|---|
| 971 | const Vector3& v0, |
|---|
| 972 | const Vector3& v1, |
|---|
| 973 | const Vector3& v2, |
|---|
| 974 | const Vector3& point); |
|---|
| 975 | |
|---|
| 976 | /** |
|---|
| 977 | Finds the closest point on the perimeter of the triangle to an external point; |
|---|
| 978 | given a triangle defined by the array of points v, its edge directions and |
|---|
| 979 | their lengths, as well as the external point. |
|---|
| 980 | |
|---|
| 981 | @note This is an optimization to closestPointToTrianglePerimeter. Edge length |
|---|
| 982 | and direction can be used in this function if already pre-calculated. This |
|---|
| 983 | prevents doing the same work twice. |
|---|
| 984 | |
|---|
| 985 | @param v0 Triangle vertex 1. |
|---|
| 986 | @param v1 Triangle vertex 2. |
|---|
| 987 | @param v2 Triangle vertex 3. |
|---|
| 988 | @param point External point. |
|---|
| 989 | |
|---|
| 990 | @return Closests point to <code>point</code> on the perimeter of the |
|---|
| 991 | triangle. |
|---|
| 992 | */ |
|---|
| 993 | static Vector3 closestPointToTrianglePerimeter( |
|---|
| 994 | const Vector3 v[3], |
|---|
| 995 | const Vector3 edgeDirection[3], |
|---|
| 996 | const double edgeLength[3], |
|---|
| 997 | const Vector3& point); |
|---|
| 998 | |
|---|
| 999 | /** |
|---|
| 1000 | Tests whether a point is contained within the triangle defined by |
|---|
| 1001 | v0, v1, & v2 and its plane's normal. |
|---|
| 1002 | |
|---|
| 1003 | @param v0 Triangle vertex 1. |
|---|
| 1004 | @param v1 Triangle vertex 2. |
|---|
| 1005 | @param v2 Triangle vertex 3. |
|---|
| 1006 | @param normal Normal to triangle's plane. |
|---|
| 1007 | @param point The point in question. |
|---|
| 1008 | @param primaryAxis Primary axis of triangle. This will be detected |
|---|
| 1009 | if not given. This parameter is provided as an optimization. |
|---|
| 1010 | |
|---|
| 1011 | @return true - if point is inside the triangle. |
|---|
| 1012 | @return false - otherwise |
|---|
| 1013 | */ |
|---|
| 1014 | static bool isPointInsideTriangle( |
|---|
| 1015 | const Vector3& v0, |
|---|
| 1016 | const Vector3& v1, |
|---|
| 1017 | const Vector3& v2, |
|---|
| 1018 | const Vector3& normal, |
|---|
| 1019 | const Vector3& point, |
|---|
| 1020 | Vector3::Axis primaryAxis = Vector3::DETECT_AXIS); |
|---|
| 1021 | |
|---|
| 1022 | /** |
|---|
| 1023 | Tests for the intersection of a moving sphere and a fixed box in a |
|---|
| 1024 | given time limit. |
|---|
| 1025 | |
|---|
| 1026 | @note Returns true if any part of the sphere is inside the box |
|---|
| 1027 | during the time period (inf means "ever"). Useful for |
|---|
| 1028 | performing bounding-box collision detection. |
|---|
| 1029 | |
|---|
| 1030 | @param sphere Moving sphere. |
|---|
| 1031 | @param velocity Velocity of moving sphere. |
|---|
| 1032 | @param box Fixed box. |
|---|
| 1033 | @param timeLimit Time limit for intersection test. |
|---|
| 1034 | |
|---|
| 1035 | @return true - if the two objects will touch. |
|---|
| 1036 | @return false - if there is no intersection. |
|---|
| 1037 | */ |
|---|
| 1038 | static bool movingSpherePassesThroughFixedBox( |
|---|
| 1039 | const Sphere& sphere, |
|---|
| 1040 | const Vector3& velocity, |
|---|
| 1041 | const Box& box, |
|---|
| 1042 | double timeLimit = inf()); |
|---|
| 1043 | |
|---|
| 1044 | /** |
|---|
| 1045 | Tests for the intersection of a moving sphere and a fixed sphere in a |
|---|
| 1046 | given time limit. |
|---|
| 1047 | |
|---|
| 1048 | @note This function will not detect an intersection between a moving object |
|---|
| 1049 | that is already interpenetrating the fixed object. |
|---|
| 1050 | |
|---|
| 1051 | @param sphere Moving sphere. |
|---|
| 1052 | @param velocity Velocity of moving sphere. |
|---|
| 1053 | @param fixedSphere Fixed sphere. |
|---|
| 1054 | @param timeLimit Time limit for intersection test. |
|---|
| 1055 | |
|---|
| 1056 | @return true - if the two spheres will touch. |
|---|
| 1057 | @return false - if there is no intersection. |
|---|
| 1058 | */ |
|---|
| 1059 | static bool movingSpherePassesThroughFixedSphere( |
|---|
| 1060 | const Sphere& sphere, |
|---|
| 1061 | const Vector3& velocity, |
|---|
| 1062 | const Sphere& fixedSphere, |
|---|
| 1063 | double timeLimit = inf()); |
|---|
| 1064 | |
|---|
| 1065 | /** |
|---|
| 1066 | Tests for the intersection of two fixed spheres. |
|---|
| 1067 | |
|---|
| 1068 | @param sphere1 Fixed sphere 1. |
|---|
| 1069 | @param sphere2 Fixed sphere 2. |
|---|
| 1070 | |
|---|
| 1071 | @return true - if the two spheres touch. |
|---|
| 1072 | @return false - if there is no intersection. |
|---|
| 1073 | */ |
|---|
| 1074 | static bool fixedSolidSphereIntersectsFixedSolidSphere( |
|---|
| 1075 | const Sphere& sphere1, |
|---|
| 1076 | const Sphere& sphere2); |
|---|
| 1077 | |
|---|
| 1078 | /** |
|---|
| 1079 | Tests for the intersection of a fixed sphere and a fixed box. |
|---|
| 1080 | |
|---|
| 1081 | @param sphere Fixed sphere. |
|---|
| 1082 | @param box Fixed box. |
|---|
| 1083 | |
|---|
| 1084 | @return true - if the two objects touch. |
|---|
| 1085 | @return false - if there is no intersection. |
|---|
| 1086 | */ |
|---|
| 1087 | static bool fixedSolidSphereIntersectsFixedSolidBox( |
|---|
| 1088 | const Sphere& sphere, |
|---|
| 1089 | const Box& box); |
|---|
| 1090 | |
|---|
| 1091 | /** |
|---|
| 1092 | Tests whether a point is inside a rectangle defined by the vertexes |
|---|
| 1093 | v0, v1, v2, & v3, and the rectangle's plane normal. |
|---|
| 1094 | |
|---|
| 1095 | @param v0 Rectangle vertex 1. |
|---|
| 1096 | @param v1 Rectangle vertex 2. |
|---|
| 1097 | @param v2 Rectangle vertex 3. |
|---|
| 1098 | @param v3 Rectangle vertex 4. |
|---|
| 1099 | @param normal Normal to rectangle's plane. |
|---|
| 1100 | @param point The point in question. |
|---|
| 1101 | |
|---|
| 1102 | @return true - if point is inside the rectangle. |
|---|
| 1103 | @return false - otherwise |
|---|
| 1104 | */ |
|---|
| 1105 | static bool isPointInsideRectangle( |
|---|
| 1106 | const Vector3& v0, |
|---|
| 1107 | const Vector3& v1, |
|---|
| 1108 | const Vector3& v2, |
|---|
| 1109 | const Vector3& v3, |
|---|
| 1110 | const Vector3& normal, |
|---|
| 1111 | const Vector3& point); |
|---|
| 1112 | |
|---|
| 1113 | /** |
|---|
| 1114 | Finds the closest point on the perimeter of the rectangle to an |
|---|
| 1115 | external point; given a rectangle defined by four points v0, v1, |
|---|
| 1116 | v2, & v3, and the external point. |
|---|
| 1117 | |
|---|
| 1118 | @param v0 Rectangle vertex 1. |
|---|
| 1119 | @param v1 Rectangle vertex 2. |
|---|
| 1120 | @param v2 Rectangle vertex 3. |
|---|
| 1121 | @param v3 Rectangle vertex 4. |
|---|
| 1122 | @param point External point. |
|---|
| 1123 | |
|---|
| 1124 | @return Closests point to <code>point</code> on the perimeter of the |
|---|
| 1125 | rectangle. |
|---|
| 1126 | */ |
|---|
| 1127 | static Vector3 closestPointToRectanglePerimeter( |
|---|
| 1128 | const Vector3& v0, |
|---|
| 1129 | const Vector3& v1, |
|---|
| 1130 | const Vector3& v2, |
|---|
| 1131 | const Vector3& v3, |
|---|
| 1132 | const Vector3& point); |
|---|
| 1133 | |
|---|
| 1134 | /** |
|---|
| 1135 | Finds the closest point in the rectangle to an external point; Given |
|---|
| 1136 | a rectangle defined by four points v0, v1, v2, & v3, and the external |
|---|
| 1137 | point. |
|---|
| 1138 | |
|---|
| 1139 | @param v0 Rectangle vertex 1. |
|---|
| 1140 | @param v1 Rectangle vertex 2. |
|---|
| 1141 | @param v2 Rectangle vertex 3 |
|---|
| 1142 | @param v3 Rectangle vertex 4. |
|---|
| 1143 | @param point External point. |
|---|
| 1144 | |
|---|
| 1145 | @return Closet point in the rectangle to the external point. |
|---|
| 1146 | */ |
|---|
| 1147 | static Vector3 closestPointToRectangle( |
|---|
| 1148 | const Vector3& v0, |
|---|
| 1149 | const Vector3& v1, |
|---|
| 1150 | const Vector3& v2, |
|---|
| 1151 | const Vector3& v3, |
|---|
| 1152 | const Vector3& point); |
|---|
| 1153 | }; |
|---|
| 1154 | |
|---|
| 1155 | } // namespace |
|---|
| 1156 | |
|---|
| 1157 | #endif // G3D_COLLISIONDETECTION_H |
|---|