2
* Copyright (c) 2006-2009 Erin Catto http://www.box2d.org
4
* This software is provided 'as-is', without any express or implied
5
* warranty. In no event will the authors be held liable for any damages
6
* arising from the use of this software.
7
* Permission is granted to anyone to use this software for any purpose,
8
* including commercial applications, and to alter it and redistribute it
9
* freely, subject to the following restrictions:
10
* 1. The origin of this software must not be misrepresented; you must not
11
* claim that you wrote the original software. If you use this software
12
* in a product, an acknowledgment in the product documentation would be
13
* appreciated but is not required.
14
* 2. Altered source versions must be plainly marked as such, and must not be
15
* misrepresented as being the original software.
16
* 3. This notice may not be removed or altered from any source distribution.
19
#ifndef B2_COLLISION_H
20
#define B2_COLLISION_H
22
#include <Box2D/Common/b2Math.h>
28
/// Structures and functions used for computing contact points, distance
29
/// queries, and TOI queries.
36
const uint8 b2_nullFeature = UCHAR_MAX;
38
/// The features that intersect to form the contact point
39
/// This must be 4 bytes or less.
40
struct b2ContactFeature
48
uint8 indexA; ///< Feature index on shapeA
49
uint8 indexB; ///< Feature index on shapeB
50
uint8 typeA; ///< The feature type on shapeA
51
uint8 typeB; ///< The feature type on shapeB
54
/// Contact ids to facilitate warm starting.
58
uint32 key; ///< Used to quickly compare contact ids.
61
/// A manifold point is a contact point belonging to a contact
62
/// manifold. It holds details related to the geometry and dynamics
63
/// of the contact points.
64
/// The local point usage depends on the manifold type:
65
/// -e_circles: the local center of circleB
66
/// -e_faceA: the local center of cirlceB or the clip point of polygonB
67
/// -e_faceB: the clip point of polygonA
68
/// This structure is stored across time steps, so we keep it small.
69
/// Note: the impulses are used for internal caching and may not
70
/// provide reliable contact forces, especially for high speed collisions.
71
struct b2ManifoldPoint
73
b2Vec2 localPoint; ///< usage depends on manifold type
74
float32 normalImpulse; ///< the non-penetration impulse
75
float32 tangentImpulse; ///< the friction impulse
76
b2ContactID id; ///< uniquely identifies a contact point between two shapes
79
/// A manifold for two touching convex shapes.
80
/// Box2D supports multiple types of contact:
81
/// - clip point versus plane with radius
82
/// - point versus point with radius (circles)
83
/// The local point usage depends on the manifold type:
84
/// -e_circles: the local center of circleA
85
/// -e_faceA: the center of faceA
86
/// -e_faceB: the center of faceB
87
/// Similarly the local normal usage:
88
/// -e_circles: not used
89
/// -e_faceA: the normal on polygonA
90
/// -e_faceB: the normal on polygonB
91
/// We store contacts in this way so that position correction can
92
/// account for movement, which is critical for continuous physics.
93
/// All contact scenarios must be expressed in one of these types.
94
/// This structure is stored across time steps, so we keep it small.
104
b2ManifoldPoint points[b2_maxManifoldPoints]; ///< the points of contact
105
b2Vec2 localNormal; ///< not use for Type::e_points
106
b2Vec2 localPoint; ///< usage depends on manifold type
108
int32 pointCount; ///< the number of manifold points
111
/// This is used to compute the current state of a contact manifold.
112
struct b2WorldManifold
114
/// Evaluate the manifold with supplied transforms. This assumes
115
/// modest motion from the original state. This does not change the
116
/// point count, impulses, etc. The radii must come from the shapes
117
/// that generated the manifold.
118
void Initialize(const b2Manifold* manifold,
119
const b2Transform& xfA, float32 radiusA,
120
const b2Transform& xfB, float32 radiusB);
122
b2Vec2 normal; ///< world vector pointing from A to B
123
b2Vec2 points[b2_maxManifoldPoints]; ///< world contact point (point of intersection)
126
/// This is used for determining the state of contact points.
129
b2_nullState, ///< point does not exist
130
b2_addState, ///< point was added in the update
131
b2_persistState, ///< point persisted across the update
132
b2_removeState ///< point was removed in the update
135
/// Compute the point states given two manifolds. The states pertain to the transition from manifold1
136
/// to manifold2. So state1 is either persist or remove while state2 is either add or persist.
137
void b2GetPointStates(b2PointState state1[b2_maxManifoldPoints], b2PointState state2[b2_maxManifoldPoints],
138
const b2Manifold* manifold1, const b2Manifold* manifold2);
140
/// Used for computing contact manifolds.
147
/// Ray-cast input data. The ray extends from p1 to p1 + maxFraction * (p2 - p1).
148
struct b2RayCastInput
154
/// Ray-cast output data. The ray hits at p1 + fraction * (p2 - p1), where p1 and p2
155
/// come from b2RayCastInput.
156
struct b2RayCastOutput
162
/// An axis aligned bounding box.
163
// emscripten - b2AABB: add constructor
168
/// Verify that the bounds are sorted.
169
bool IsValid() const;
171
/// Get the center of the AABB.
172
b2Vec2 GetCenter() const
174
return 0.5f * (lowerBound + upperBound);
177
/// Get the extents of the AABB (half-widths).
178
b2Vec2 GetExtents() const
180
return 0.5f * (upperBound - lowerBound);
183
/// Get the perimeter length
184
float32 GetPerimeter() const
186
float32 wx = upperBound.x - lowerBound.x;
187
float32 wy = upperBound.y - lowerBound.y;
188
return 2.0f * (wx + wy);
191
/// Combine an AABB into this one.
192
void Combine(const b2AABB& aabb)
194
lowerBound = b2Min(lowerBound, aabb.lowerBound);
195
upperBound = b2Max(upperBound, aabb.upperBound);
198
/// Combine two AABBs into this one.
199
void Combine(const b2AABB& aabb1, const b2AABB& aabb2)
201
lowerBound = b2Min(aabb1.lowerBound, aabb2.lowerBound);
202
upperBound = b2Max(aabb1.upperBound, aabb2.upperBound);
205
/// Does this aabb contain the provided AABB.
206
bool Contains(const b2AABB& aabb) const
209
result = result && lowerBound.x <= aabb.lowerBound.x;
210
result = result && lowerBound.y <= aabb.lowerBound.y;
211
result = result && aabb.upperBound.x <= upperBound.x;
212
result = result && aabb.upperBound.y <= upperBound.y;
216
bool RayCast(b2RayCastOutput* output, const b2RayCastInput& input) const;
218
b2Vec2 lowerBound; ///< the lower vertex
219
b2Vec2 upperBound; ///< the upper vertex
222
/// Compute the collision manifold between two circles.
223
void b2CollideCircles(b2Manifold* manifold,
224
const b2CircleShape* circleA, const b2Transform& xfA,
225
const b2CircleShape* circleB, const b2Transform& xfB);
227
/// Compute the collision manifold between a polygon and a circle.
228
void b2CollidePolygonAndCircle(b2Manifold* manifold,
229
const b2PolygonShape* polygonA, const b2Transform& xfA,
230
const b2CircleShape* circleB, const b2Transform& xfB);
232
/// Compute the collision manifold between two polygons.
233
void b2CollidePolygons(b2Manifold* manifold,
234
const b2PolygonShape* polygonA, const b2Transform& xfA,
235
const b2PolygonShape* polygonB, const b2Transform& xfB);
237
/// Compute the collision manifold between an edge and a circle.
238
void b2CollideEdgeAndCircle(b2Manifold* manifold,
239
const b2EdgeShape* polygonA, const b2Transform& xfA,
240
const b2CircleShape* circleB, const b2Transform& xfB);
242
/// Compute the collision manifold between an edge and a circle.
243
void b2CollideEdgeAndPolygon(b2Manifold* manifold,
244
const b2EdgeShape* edgeA, const b2Transform& xfA,
245
const b2PolygonShape* circleB, const b2Transform& xfB);
247
/// Clipping for contact manifolds.
248
int32 b2ClipSegmentToLine(b2ClipVertex vOut[2], const b2ClipVertex vIn[2],
249
const b2Vec2& normal, float32 offset, int32 vertexIndexA);
251
/// Determine if two generic shapes overlap.
252
bool b2TestOverlap( const b2Shape* shapeA, int32 indexA,
253
const b2Shape* shapeB, int32 indexB,
254
const b2Transform& xfA, const b2Transform& xfB);
256
// ---------------- Inline Functions ------------------------------------------
258
inline bool b2AABB::IsValid() const
260
b2Vec2 d = upperBound - lowerBound;
261
bool valid = d.x >= 0.0f && d.y >= 0.0f;
262
valid = valid && lowerBound.IsValid() && upperBound.IsValid();
266
inline bool b2TestOverlap(const b2AABB& a, const b2AABB& b)
269
d1 = b.lowerBound - a.upperBound;
270
d2 = a.lowerBound - b.upperBound;
272
if (d1.x > 0.0f || d1.y > 0.0f)
275
if (d2.x > 0.0f || d2.y > 0.0f)