Collision System
Intersection \ Distance Tests
|
Sweep \ Penetration Tests
|
Each source file (.cpp) contains the mathematical development for the corresponding collision routine, as time permitted. This should help in understanding the implementation as well as allow for verification of the results.
The nomenclature for the functions can be daunting at first but I promise you that it is fairly simple and logical once the core syntax is understood. For reasons that would bore you, I tend to use a short naming convention using an abbreviated Hungarian notation.
(1) Templates: Functions and Parameters.
I felt that the required word-noise that is needed when using templates was causing ambiguity in the function definitions. I use a pre-processor definition sequence to generate the required type definitions while keeping the function declaration/definition compact and thus, making it clear to understand. Specifically, the definitions are used with template<typename TYPE, int DIM> and are as follows:
| •(CLASS) | TTg[CLASS]<TYPE,DIM> | C•(CLASS) | const TTg[CLASS]<TYPE,DIM> |
| P•(CLASS) | TTg[CLASS]<TYPE,DIM> * | PC•(CLASS) | TTg[CLASS]<TYPE,DIM> * const |
| PCU•(CLASS) | TTg[CLASS]<TYPE,DIM> * const __restrict | PU•(CLASS) | TTg[CLASS]<TYPE,DIM> * __restrict |
| CP•(CLASS) | const TTg[CLASS]<TYPE,DIM> * | CPC•(CLASS) | const TTg[CLASS]<TYPE,DIM> * const |
| CPCU•(CLASS) | const TTg[CLASS]<TYPE,DIM> * const __restrict | CPU•(CLASS) | const TTg[CLASS]<TYPE,DIM> * __restrict |
| R•(CLASS) | TTg[CLASS]<TYPE,DIM> & | CR•(CLASS) | const TTg[CLASS]<TYPE,DIM> & |
| PR•(CLASS) | TTg[CLASS]<TYPE,DIM>*& | CPR•(CLASS) | const TTg[CLASS]<TYPE,DIM>*& |
| PP•(CLASS) | TTg[CLASS]<TYPE,DIM>** |
P: Pointer, C: Const, U: Restrict, R: Reference - Prefix is in order. Thus, for instance, CR•(VECTOR) is just a const reference template vector.
(2) Function naming system:
- tgDistSq: Returns the distance square between two primitives. Will return negative type max is they are interesting/penetrating.
- tgClosestSq: Returns the distance square between two primitives. Will return negative type max is they are interesting/penetrating. There are two version of this function. The outputs are always listed first, and they will be either floats or vectors. If they're vectors they represent the points of closest proximity on each of the two primitives. If they’re floats they represent the parametric values required to generate to point given the definition of the primitive. For instance for a line, it will be the scalar multiple along the direction vector from the origin; in the case of a triangle it will be the barycentric values.
- tgClip: Like tgClosestSq this function often has two possible definitions. One takes a clip structure in which it returns the legal points, and the second returns back the two float values for a line. In the case of an open primitive its assumed that the object is scaled to infinity along its primary axis (for instance along the long axis of a tube).
- tgContact_Penetrate: This is the first function where parameter order has an impact on the resolution. The values returned will be points on the second primitive describing the penetration of the first primitive.
- tgContact_Sweep: Its assumed that the first primitive is static and the second primitive is moving along the sweep path.
(3) Parameter Nomenclature:
Each primitive type is assigned a simple two letter short form. The exception are points/vectors which sometimes has more definitions based on usage (point vs directions). Hungarian notation is tv: vector, tg: structure/class. # represents an arbitrary number for multiple usages of the same type in the same context. An underscore used as a prefix represents a return (output) value and is used when I felt that its was not self-evident by the context or name of the variable. An underscore used in the middle of a variable often describes a dot product.
| tyT#: Parametric Value | tvS#: Point | tvD#: Direction | tgPC#: Particle | tgLN#: Line |
| tgRY#: Ray | tgSG#: Segment | tgCI#: Circle | tgDK#: Disk | tgEL#: Ellipse |
| tgPE#: Parallelogram | tgPN#: Plane | tgRT#: Rectangle | tgPT#: Point Triangle | tgET#: Edge Triangle |
| tgCY#: Cylinder | tgMS#: Mesh Simple | tgMA#: Mesh AABB | tgMB#: Mesh BVT | tgSP#: Sphere |
| tgTR#: Torus | tgTU#: Tube |
A point triangle is one described using only the three vertices and a normal to the plane. An edge triangle adds a clockwise edge definition. A collision triangle augments an edge triangle with feature reduction information (for instance if a particular edge should be considered during collision). Finally, a space triangle adds edge plane definition to a collision triangle.
WARNING: I have not had time yet to verify the accuracy of these routines. Please report any issues - and I will quickly remedy the issue.
| Disk | |
| TgS Collision - Disk.h | |
| TgS Collision - Disk-Point.inl | |
| TgS Collision - Disk-Point.cpp | TgS Collision - Disk.cpp |
I came to collision with a very solid mathematical background but with little actual experience in the field. The following are some of the books and web sites I used to help educate myself and to pick up methods and systems to approach a collision problem. They are all useful – however, in looking at actual implementation care must be taken since many of them are either inaccurate or simply faulty.
Real-Time Rendering: ISBN 1568811829. This is one of the “bibles” I use when working. It is a very complete and thorough discussion on rendering and associated technologies. They keep an active page on intersection tests at www.realtimerendering.com/int
Geometric Tools: ISBN 1558605940. David Eberly has written a few works on collision and game engine technology. I find this work to be the best since it its both exhaustive in regards to most regular geometric forms – and most importantly – discusses the solution methods from a mathematical point of view. Thus, it is a great text book to teach yourself how to solve similar problems – and the different solution techniques available. I found the strictly mathematically solutions to be correct –however, the short cuts taken sometimes proved to be wrong. Look at it as a teaching aid – not the absolute truth to finding a solution to a problem. Current source – the current implementation of his own engine project – and a list of his other books can all be found at: www.geometrictools.com