Home | History | Annotate | Download | only in Collision
      1 /*
      2 * Copyright (c) 2006-2009 Erin Catto http://www.box2d.org
      3 *
      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.
     17 */
     18 
     19 #ifndef B2_COLLISION_H
     20 #define B2_COLLISION_H
     21 
     22 #include <Box2D/Common/b2Math.h>
     23 #include <climits>
     24 
     25 /// @file
     26 /// Structures and functions used for computing contact points, distance
     27 /// queries, and TOI queries.
     28 
     29 class b2Shape;
     30 class b2CircleShape;
     31 class b2EdgeShape;
     32 class b2PolygonShape;
     33 
     34 const uint8 b2_nullFeature = UCHAR_MAX;
     35 
     36 /// The features that intersect to form the contact point
     37 /// This must be 4 bytes or less.
     38 struct b2ContactFeature
     39 {
     40 	enum Type
     41 	{
     42 		e_vertex = 0,
     43 		e_face = 1
     44 	};
     45 
     46 	uint8 indexA;		///< Feature index on shapeA
     47 	uint8 indexB;		///< Feature index on shapeB
     48 	uint8 typeA;		///< The feature type on shapeA
     49 	uint8 typeB;		///< The feature type on shapeB
     50 };
     51 
     52 /// Contact ids to facilitate warm starting.
     53 union b2ContactID
     54 {
     55 	b2ContactFeature cf;
     56 	uint32 key;					///< Used to quickly compare contact ids.
     57 };
     58 
     59 /// A manifold point is a contact point belonging to a contact
     60 /// manifold. It holds details related to the geometry and dynamics
     61 /// of the contact points.
     62 /// The local point usage depends on the manifold type:
     63 /// -e_circles: the local center of circleB
     64 /// -e_faceA: the local center of cirlceB or the clip point of polygonB
     65 /// -e_faceB: the clip point of polygonA
     66 /// This structure is stored across time steps, so we keep it small.
     67 /// Note: the impulses are used for internal caching and may not
     68 /// provide reliable contact forces, especially for high speed collisions.
     69 struct b2ManifoldPoint
     70 {
     71 	b2Vec2 localPoint;		///< usage depends on manifold type
     72 	float32 normalImpulse;	///< the non-penetration impulse
     73 	float32 tangentImpulse;	///< the friction impulse
     74 	b2ContactID id;			///< uniquely identifies a contact point between two shapes
     75 };
     76 
     77 /// A manifold for two touching convex shapes.
     78 /// Box2D supports multiple types of contact:
     79 /// - clip point versus plane with radius
     80 /// - point versus point with radius (circles)
     81 /// The local point usage depends on the manifold type:
     82 /// -e_circles: the local center of circleA
     83 /// -e_faceA: the center of faceA
     84 /// -e_faceB: the center of faceB
     85 /// Similarly the local normal usage:
     86 /// -e_circles: not used
     87 /// -e_faceA: the normal on polygonA
     88 /// -e_faceB: the normal on polygonB
     89 /// We store contacts in this way so that position correction can
     90 /// account for movement, which is critical for continuous physics.
     91 /// All contact scenarios must be expressed in one of these types.
     92 /// This structure is stored across time steps, so we keep it small.
     93 struct b2Manifold
     94 {
     95 	enum Type
     96 	{
     97 		e_circles,
     98 		e_faceA,
     99 		e_faceB
    100 	};
    101 
    102 	b2ManifoldPoint points[b2_maxManifoldPoints];	///< the points of contact
    103 	b2Vec2 localNormal;								///< not use for Type::e_points
    104 	b2Vec2 localPoint;								///< usage depends on manifold type
    105 	Type type;
    106 	int32 pointCount;								///< the number of manifold points
    107 };
    108 
    109 /// This is used to compute the current state of a contact manifold.
    110 struct b2WorldManifold
    111 {
    112 	/// Evaluate the manifold with supplied transforms. This assumes
    113 	/// modest motion from the original state. This does not change the
    114 	/// point count, impulses, etc. The radii must come from the shapes
    115 	/// that generated the manifold.
    116 	void Initialize(const b2Manifold* manifold,
    117 					const b2Transform& xfA, float32 radiusA,
    118 					const b2Transform& xfB, float32 radiusB);
    119 
    120 	b2Vec2 normal;								///< world vector pointing from A to B
    121 	b2Vec2 points[b2_maxManifoldPoints];		///< world contact point (point of intersection)
    122 	float32 separations[b2_maxManifoldPoints];	///< a negative value indicates overlap, in meters
    123 };
    124 
    125 /// This is used for determining the state of contact points.
    126 enum b2PointState
    127 {
    128 	b2_nullState,		///< point does not exist
    129 	b2_addState,		///< point was added in the update
    130 	b2_persistState,	///< point persisted across the update
    131 	b2_removeState		///< point was removed in the update
    132 };
    133 
    134 /// Compute the point states given two manifolds. The states pertain to the transition from manifold1
    135 /// to manifold2. So state1 is either persist or remove while state2 is either add or persist.
    136 void b2GetPointStates(b2PointState state1[b2_maxManifoldPoints], b2PointState state2[b2_maxManifoldPoints],
    137 					  const b2Manifold* manifold1, const b2Manifold* manifold2);
    138 
    139 /// Used for computing contact manifolds.
    140 struct b2ClipVertex
    141 {
    142 	b2Vec2 v;
    143 	b2ContactID id;
    144 };
    145 
    146 /// Ray-cast input data. The ray extends from p1 to p1 + maxFraction * (p2 - p1).
    147 struct b2RayCastInput
    148 {
    149 	b2Vec2 p1, p2;
    150 	float32 maxFraction;
    151 };
    152 
    153 /// Ray-cast output data. The ray hits at p1 + fraction * (p2 - p1), where p1 and p2
    154 /// come from b2RayCastInput.
    155 struct b2RayCastOutput
    156 {
    157 	b2Vec2 normal;
    158 	float32 fraction;
    159 };
    160 
    161 /// An axis aligned bounding box.
    162 struct b2AABB
    163 {
    164 	/// Verify that the bounds are sorted.
    165 	bool IsValid() const;
    166 
    167 	/// Get the center of the AABB.
    168 	b2Vec2 GetCenter() const
    169 	{
    170 		return 0.5f * (lowerBound + upperBound);
    171 	}
    172 
    173 	/// Get the extents of the AABB (half-widths).
    174 	b2Vec2 GetExtents() const
    175 	{
    176 		return 0.5f * (upperBound - lowerBound);
    177 	}
    178 
    179 	/// Get the perimeter length
    180 	float32 GetPerimeter() const
    181 	{
    182 		float32 wx = upperBound.x - lowerBound.x;
    183 		float32 wy = upperBound.y - lowerBound.y;
    184 		return 2.0f * (wx + wy);
    185 	}
    186 
    187 	/// Combine an AABB into this one.
    188 	void Combine(const b2AABB& aabb)
    189 	{
    190 		lowerBound = b2Min(lowerBound, aabb.lowerBound);
    191 		upperBound = b2Max(upperBound, aabb.upperBound);
    192 	}
    193 
    194 	/// Combine two AABBs into this one.
    195 	void Combine(const b2AABB& aabb1, const b2AABB& aabb2)
    196 	{
    197 		lowerBound = b2Min(aabb1.lowerBound, aabb2.lowerBound);
    198 		upperBound = b2Max(aabb1.upperBound, aabb2.upperBound);
    199 	}
    200 
    201 	/// Does this aabb contain the provided AABB.
    202 	bool Contains(const b2AABB& aabb) const
    203 	{
    204 		bool result = true;
    205 		result = result && lowerBound.x <= aabb.lowerBound.x;
    206 		result = result && lowerBound.y <= aabb.lowerBound.y;
    207 		result = result && aabb.upperBound.x <= upperBound.x;
    208 		result = result && aabb.upperBound.y <= upperBound.y;
    209 		return result;
    210 	}
    211 
    212 	bool RayCast(b2RayCastOutput* output, const b2RayCastInput& input) const;
    213 
    214 	b2Vec2 lowerBound;	///< the lower vertex
    215 	b2Vec2 upperBound;	///< the upper vertex
    216 };
    217 
    218 /// Compute the collision manifold between two circles.
    219 void b2CollideCircles(b2Manifold* manifold,
    220 					  const b2CircleShape* circleA, const b2Transform& xfA,
    221 					  const b2CircleShape* circleB, const b2Transform& xfB);
    222 
    223 /// Compute the collision manifold between a polygon and a circle.
    224 void b2CollidePolygonAndCircle(b2Manifold* manifold,
    225 							   const b2PolygonShape* polygonA, const b2Transform& xfA,
    226 							   const b2CircleShape* circleB, const b2Transform& xfB);
    227 
    228 /// Compute the collision manifold between two polygons.
    229 void b2CollidePolygons(b2Manifold* manifold,
    230 					   const b2PolygonShape* polygonA, const b2Transform& xfA,
    231 					   const b2PolygonShape* polygonB, const b2Transform& xfB);
    232 
    233 /// Compute the collision manifold between an edge and a circle.
    234 void b2CollideEdgeAndCircle(b2Manifold* manifold,
    235 							   const b2EdgeShape* polygonA, const b2Transform& xfA,
    236 							   const b2CircleShape* circleB, const b2Transform& xfB);
    237 
    238 /// Compute the collision manifold between an edge and a circle.
    239 void b2CollideEdgeAndPolygon(b2Manifold* manifold,
    240 							   const b2EdgeShape* edgeA, const b2Transform& xfA,
    241 							   const b2PolygonShape* circleB, const b2Transform& xfB);
    242 
    243 /// Clipping for contact manifolds.
    244 int32 b2ClipSegmentToLine(b2ClipVertex vOut[2], const b2ClipVertex vIn[2],
    245 							const b2Vec2& normal, float32 offset, int32 vertexIndexA);
    246 
    247 /// Determine if two generic shapes overlap.
    248 bool b2TestOverlap(	const b2Shape* shapeA, int32 indexA,
    249 					const b2Shape* shapeB, int32 indexB,
    250 					const b2Transform& xfA, const b2Transform& xfB);
    251 
    252 // ---------------- Inline Functions ------------------------------------------
    253 
    254 inline bool b2AABB::IsValid() const
    255 {
    256 	b2Vec2 d = upperBound - lowerBound;
    257 	bool valid = d.x >= 0.0f && d.y >= 0.0f;
    258 	valid = valid && lowerBound.IsValid() && upperBound.IsValid();
    259 	return valid;
    260 }
    261 
    262 inline bool b2TestOverlap(const b2AABB& a, const b2AABB& b)
    263 {
    264 	b2Vec2 d1, d2;
    265 	d1 = b.lowerBound - a.upperBound;
    266 	d2 = a.lowerBound - b.upperBound;
    267 
    268 	if (d1.x > 0.0f || d1.y > 0.0f)
    269 		return false;
    270 
    271 	if (d2.x > 0.0f || d2.y > 0.0f)
    272 		return false;
    273 
    274 	return true;
    275 }
    276 
    277 #endif
    278