-
Notifications
You must be signed in to change notification settings - Fork 0
/
CollisionUtils.h
103 lines (85 loc) · 3.53 KB
/
CollisionUtils.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
/////////////////////////////////////////////////////
// CollisionUtils.h
//
// Provides quick access to generally useful collision routines,
// implemented in an old-school fashion for the sake of efficiency and simplicity.
// Each routine has the following scheme:
//
// Returns: true if collision occured, false otherwise
// Output: optionally outputs the point of intersection
/////////////////////////////////////////////////////
#ifndef COLLISION_UTILS_H
#define COLLISION_UTILS_H
#include "Vector.h"
// PROTOTYPES
static bool SphereToSphere (Vector& center1, float radius1, Vector& center2, float radius2, Vector* vIntersection = 0);
static bool SphereToPoint (Vector& center, float radius, Vector& point, Vector* vIntersection = 0);
static bool SphereToPlane (Vector& center, float radius, Vector& normal, Vector& point, Vector* vIntersection = 0);
static bool SphereToLine (Vector& center, float radius, Vector& normal, Vector& point, Vector* vIntersection = 0);
static bool HalfSpaceTest (Vector& point, Vector& normal, Vector& planePoint);
///////////////// SPHERES ////////////////////////////
// Sphere to Sphere
bool SphereToSphere (Vector& center1, float radius1, Vector& center2, float radius2, Vector* vIntersection)
{
if ( (center2 - center1).LengthSquared() > (radius1 + radius2) * (radius1 + radius2) )
return false;
// collision succeeded, so output intersection if appropriate
if (vIntersection)
*vIntersection = center1 + ((center2 - center1)* (radius1 / (radius1 + radius2)));
return true;
}
// Sphere to Point
bool SphereToPoint (Vector& center, float radius, Vector& point, Vector* vIntersection)
{
return ( (point - center).LengthSquared() <= radius * radius);
}
// Sphere to Plane
// computes the point of intersection of a sphere with a plane
// CAUTION: it is assumed that the plane's normal vector has unit length
bool SphereToPlane (Vector& center, float radius, Vector& normal, Vector& point, Vector* vIntersection)
{
// check if the sphere is close enough
Vector unitNormal = normal.Normalize();
float fDistance = (center - point) * unitNormal;
if (ABS(fDistance) > radius)
return false;
// compute intersection
if (vIntersection)
{
(*vIntersection) = center - (unitNormal * fDistance);
}
return true;
}
// Sphere to Line
// calculates the point of intersection of a sphere with a line
// even if there is no intersection, vIntersection will store the point on the line closest to the sphere
bool SphereToLine (Vector& center, float radius, Vector& begin, Vector& end, Vector* vIntersection)
{
Vector vToSphere = center - begin;
Vector vLine = end - begin;
Vector vLineNormalized = vLine.Normalize();
float fDotProduct = vToSphere * vLineNormalized; //the distance of the closest point from the beginning of the line
// compute the closest point
Vector vClosestPoint = begin + vLineNormalized * fDotProduct;
if (vIntersection)
*vIntersection = vClosestPoint;
// determine whether collision occured
if (fDotProduct < 0 || fDotProduct * fDotProduct > vLine.LengthSquared())
return false;
return SphereToPoint (center, radius, vClosestPoint);
}
// PLANES
///////////////////////////////////////////////
// HALF SPACE TEST
// Determines whether a plane's normal vector points towards a given point
//
// Input:
// point: the point to run the half space test on
// normal: the normal vector of the plane
// planePoint: any point lying on the plane
///////////////////////////////////////////////
bool HalfSpaceTest (Vector& point, Vector& normal, Vector& planePoint)
{
return (planePoint - point) * normal >= 0;
}
#endif