root/trunk/dep/include/g3dlite/G3D/CollisionDetection.h @ 2

Revision 2, 42.4 kB (checked in by yumileroy, 17 years ago)

[svn] * Proper SVN structure

Original author: Neo2003
Date: 2008-10-02 16:23:55-05:00

Line 
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
33namespace 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 */
90class CollisionDetection {
91private:
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
116public:
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
Note: See TracBrowser for help on using the browser.