File indexing completed on 2024-05-19 14:56:21

0001 /*
0002 * Copyright (c) 2006-2009 Erin Catto http://www.box2d.org
0003 *
0004 * This software is provided 'as-is', without any express or implied
0005 * warranty.  In no event will the authors be held liable for any damages
0006 * arising from the use of this software.
0007 * Permission is granted to anyone to use this software for any purpose,
0008 * including commercial applications, and to alter it and redistribute it
0009 * freely, subject to the following restrictions:
0010 * 1. The origin of this software must not be misrepresented; you must not
0011 * claim that you wrote the original software. If you use this software
0012 * in a product, an acknowledgment in the product documentation would be
0013 * appreciated but is not required.
0014 * 2. Altered source versions must be plainly marked as such, and must not be
0015 * misrepresented as being the original software.
0016 * 3. This notice may not be removed or altered from any source distribution.
0017 */
0018 
0019 #ifndef B2_COLLISION_H
0020 #define B2_COLLISION_H
0021 
0022 #include <Box2D/Common/b2Math.h>
0023 #include <limits.h>
0024 
0025 /// @file
0026 /// Structures and functions used for computing contact points, distance
0027 /// queries, and TOI queries.
0028 
0029 class b2Shape;
0030 class b2CircleShape;
0031 class b2EdgeShape;
0032 class b2PolygonShape;
0033 
0034 const uint8 b2_nullFeature = UCHAR_MAX;
0035 
0036 /// The features that intersect to form the contact point
0037 /// This must be 4 bytes or less.
0038 struct b2ContactFeature
0039 {
0040     enum Type
0041     {
0042         e_vertex = 0,
0043         e_face = 1
0044     };
0045 
0046     uint8 indexA;       ///< Feature index on shapeA
0047     uint8 indexB;       ///< Feature index on shapeB
0048     uint8 typeA;        ///< The feature type on shapeA
0049     uint8 typeB;        ///< The feature type on shapeB
0050 };
0051 
0052 /// Contact ids to facilitate warm starting.
0053 union b2ContactID
0054 {
0055     b2ContactFeature cf;
0056     uint32 key;                 ///< Used to quickly compare contact ids.
0057 };
0058 
0059 /// A manifold point is a contact point belonging to a contact
0060 /// manifold. It holds details related to the geometry and dynamics
0061 /// of the contact points.
0062 /// The local point usage depends on the manifold type:
0063 /// -e_circles: the local center of circleB
0064 /// -e_faceA: the local center of cirlceB or the clip point of polygonB
0065 /// -e_faceB: the clip point of polygonA
0066 /// This structure is stored across time steps, so we keep it small.
0067 /// Note: the impulses are used for internal caching and may not
0068 /// provide reliable contact forces, especially for high speed collisions.
0069 struct b2ManifoldPoint
0070 {
0071     b2Vec2 localPoint;      ///< usage depends on manifold type
0072     float32 normalImpulse;  ///< the non-penetration impulse
0073     float32 tangentImpulse; ///< the friction impulse
0074     b2ContactID id;         ///< uniquely identifies a contact point between two shapes
0075 };
0076 
0077 /// A manifold for two touching convex shapes.
0078 /// Box2D supports multiple types of contact:
0079 /// - clip point versus plane with radius
0080 /// - point versus point with radius (circles)
0081 /// The local point usage depends on the manifold type:
0082 /// -e_circles: the local center of circleA
0083 /// -e_faceA: the center of faceA
0084 /// -e_faceB: the center of faceB
0085 /// Similarly the local normal usage:
0086 /// -e_circles: not used
0087 /// -e_faceA: the normal on polygonA
0088 /// -e_faceB: the normal on polygonB
0089 /// We store contacts in this way so that position correction can
0090 /// account for movement, which is critical for continuous physics.
0091 /// All contact scenarios must be expressed in one of these types.
0092 /// This structure is stored across time steps, so we keep it small.
0093 struct b2Manifold
0094 {
0095     enum Type
0096     {
0097         e_circles,
0098         e_faceA,
0099         e_faceB
0100     };
0101 
0102     b2ManifoldPoint points[b2_maxManifoldPoints];   ///< the points of contact
0103     b2Vec2 localNormal;                             ///< not use for Type::e_points
0104     b2Vec2 localPoint;                              ///< usage depends on manifold type
0105     Type type;
0106     int32 pointCount;                               ///< the number of manifold points
0107 };
0108 
0109 /// This is used to compute the current state of a contact manifold.
0110 struct b2WorldManifold
0111 {
0112     /// Evaluate the manifold with supplied transforms. This assumes
0113     /// modest motion from the original state. This does not change the
0114     /// point count, impulses, etc. The radii must come from the shapes
0115     /// that generated the manifold.
0116     void Initialize(const b2Manifold* manifold,
0117                     const b2Transform& xfA, float32 radiusA,
0118                     const b2Transform& xfB, float32 radiusB);
0119 
0120     b2Vec2 normal;                              ///< world vector pointing from A to B
0121     b2Vec2 points[b2_maxManifoldPoints];        ///< world contact point (point of intersection)
0122     float32 separations[b2_maxManifoldPoints];  ///< a negative value indicates overlap, in meters
0123 };
0124 
0125 /// This is used for determining the state of contact points.
0126 enum b2PointState
0127 {
0128     b2_nullState,       ///< point does not exist
0129     b2_addState,        ///< point was added in the update
0130     b2_persistState,    ///< point persisted across the update
0131     b2_removeState      ///< point was removed in the update
0132 };
0133 
0134 /// Compute the point states given two manifolds. The states pertain to the transition from manifold1
0135 /// to manifold2. So state1 is either persist or remove while state2 is either add or persist.
0136 void b2GetPointStates(b2PointState state1[b2_maxManifoldPoints], b2PointState state2[b2_maxManifoldPoints],
0137                       const b2Manifold* manifold1, const b2Manifold* manifold2);
0138 
0139 /// Used for computing contact manifolds.
0140 struct b2ClipVertex
0141 {
0142     b2Vec2 v;
0143     b2ContactID id;
0144 };
0145 
0146 /// Ray-cast input data. The ray extends from p1 to p1 + maxFraction * (p2 - p1).
0147 struct b2RayCastInput
0148 {
0149     b2Vec2 p1, p2;
0150     float32 maxFraction;
0151 };
0152 
0153 /// Ray-cast output data. The ray hits at p1 + fraction * (p2 - p1), where p1 and p2
0154 /// come from b2RayCastInput.
0155 struct b2RayCastOutput
0156 {
0157     b2Vec2 normal;
0158     float32 fraction;
0159 };
0160 
0161 /// An axis aligned bounding box.
0162 struct b2AABB
0163 {
0164     /// Verify that the bounds are sorted.
0165     bool IsValid() const;
0166 
0167     /// Get the center of the AABB.
0168     b2Vec2 GetCenter() const
0169     {
0170         return 0.5f * (lowerBound + upperBound);
0171     }
0172 
0173     /// Get the extents of the AABB (half-widths).
0174     b2Vec2 GetExtents() const
0175     {
0176         return 0.5f * (upperBound - lowerBound);
0177     }
0178 
0179     /// Get the perimeter length
0180     float32 GetPerimeter() const
0181     {
0182         float32 wx = upperBound.x - lowerBound.x;
0183         float32 wy = upperBound.y - lowerBound.y;
0184         return 2.0f * (wx + wy);
0185     }
0186 
0187     /// Combine an AABB into this one.
0188     void Combine(const b2AABB& aabb)
0189     {
0190         lowerBound = b2Min(lowerBound, aabb.lowerBound);
0191         upperBound = b2Max(upperBound, aabb.upperBound);
0192     }
0193 
0194     /// Combine two AABBs into this one.
0195     void Combine(const b2AABB& aabb1, const b2AABB& aabb2)
0196     {
0197         lowerBound = b2Min(aabb1.lowerBound, aabb2.lowerBound);
0198         upperBound = b2Max(aabb1.upperBound, aabb2.upperBound);
0199     }
0200 
0201     /// Does this aabb contain the provided AABB.
0202     bool Contains(const b2AABB& aabb) const
0203     {
0204         bool result = true;
0205         result = result && lowerBound.x <= aabb.lowerBound.x;
0206         result = result && lowerBound.y <= aabb.lowerBound.y;
0207         result = result && aabb.upperBound.x <= upperBound.x;
0208         result = result && aabb.upperBound.y <= upperBound.y;
0209         return result;
0210     }
0211 
0212     bool RayCast(b2RayCastOutput* output, const b2RayCastInput& input) const;
0213 
0214     b2Vec2 lowerBound;  ///< the lower vertex
0215     b2Vec2 upperBound;  ///< the upper vertex
0216 };
0217 
0218 /// Compute the collision manifold between two circles.
0219 void b2CollideCircles(b2Manifold* manifold,
0220                       const b2CircleShape* circleA, const b2Transform& xfA,
0221                       const b2CircleShape* circleB, const b2Transform& xfB);
0222 
0223 /// Compute the collision manifold between a polygon and a circle.
0224 void b2CollidePolygonAndCircle(b2Manifold* manifold,
0225                                const b2PolygonShape* polygonA, const b2Transform& xfA,
0226                                const b2CircleShape* circleB, const b2Transform& xfB);
0227 
0228 /// Compute the collision manifold between two polygons.
0229 void b2CollidePolygons(b2Manifold* manifold,
0230                        const b2PolygonShape* polygonA, const b2Transform& xfA,
0231                        const b2PolygonShape* polygonB, const b2Transform& xfB);
0232 
0233 /// Compute the collision manifold between an edge and a circle.
0234 void b2CollideEdgeAndCircle(b2Manifold* manifold,
0235                                const b2EdgeShape* polygonA, const b2Transform& xfA,
0236                                const b2CircleShape* circleB, const b2Transform& xfB);
0237 
0238 /// Compute the collision manifold between an edge and a circle.
0239 void b2CollideEdgeAndPolygon(b2Manifold* manifold,
0240                                const b2EdgeShape* edgeA, const b2Transform& xfA,
0241                                const b2PolygonShape* circleB, const b2Transform& xfB);
0242 
0243 /// Clipping for contact manifolds.
0244 int32 b2ClipSegmentToLine(b2ClipVertex vOut[2], const b2ClipVertex vIn[2],
0245                             const b2Vec2& normal, float32 offset, int32 vertexIndexA);
0246 
0247 /// Determine if two generic shapes overlap.
0248 bool b2TestOverlap( const b2Shape* shapeA, int32 indexA,
0249                     const b2Shape* shapeB, int32 indexB,
0250                     const b2Transform& xfA, const b2Transform& xfB);
0251 
0252 // ---------------- Inline Functions ------------------------------------------
0253 
0254 inline bool b2AABB::IsValid() const
0255 {
0256     b2Vec2 d = upperBound - lowerBound;
0257     bool valid = d.x >= 0.0f && d.y >= 0.0f;
0258     valid = valid && lowerBound.IsValid() && upperBound.IsValid();
0259     return valid;
0260 }
0261 
0262 inline bool b2TestOverlap(const b2AABB& a, const b2AABB& b)
0263 {
0264     b2Vec2 d1, d2;
0265     d1 = b.lowerBound - a.upperBound;
0266     d2 = a.lowerBound - b.upperBound;
0267 
0268     if (d1.x > 0.0f || d1.y > 0.0f)
0269         return false;
0270 
0271     if (d2.x > 0.0f || d2.y > 0.0f)
0272         return false;
0273 
0274     return true;
0275 }
0276 
0277 #endif