diff options
Diffstat (limited to 'Client/ThirdParty/Box2D/include/box2d/b2_collision.h')
-rw-r--r-- | Client/ThirdParty/Box2D/include/box2d/b2_collision.h | 283 |
1 files changed, 283 insertions, 0 deletions
diff --git a/Client/ThirdParty/Box2D/include/box2d/b2_collision.h b/Client/ThirdParty/Box2D/include/box2d/b2_collision.h new file mode 100644 index 0000000..4c45920 --- /dev/null +++ b/Client/ThirdParty/Box2D/include/box2d/b2_collision.h @@ -0,0 +1,283 @@ +// MIT License + +// Copyright (c) 2019 Erin Catto + +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +#ifndef B2_COLLISION_H +#define B2_COLLISION_H + +#include <limits.h> + +#include "b2_api.h" +#include "b2_math.h" + +/// @file +/// Structures and functions used for computing contact points, distance +/// queries, and TOI queries. + +class b2Shape; +class b2CircleShape; +class b2EdgeShape; +class b2PolygonShape; + +const uint8 b2_nullFeature = UCHAR_MAX; + +/// The features that intersect to form the contact point +/// This must be 4 bytes or less. +struct B2_API b2ContactFeature +{ + enum Type + { + e_vertex = 0, + e_face = 1 + }; + + uint8 indexA; ///< Feature index on shapeA + uint8 indexB; ///< Feature index on shapeB + uint8 typeA; ///< The feature type on shapeA + uint8 typeB; ///< The feature type on shapeB +}; + +/// Contact ids to facilitate warm starting. +union B2_API b2ContactID +{ + b2ContactFeature cf; + uint32 key; ///< Used to quickly compare contact ids. +}; + +/// A manifold point is a contact point belonging to a contact +/// manifold. It holds details related to the geometry and dynamics +/// of the contact points. +/// The local point usage depends on the manifold type: +/// -e_circles: the local center of circleB +/// -e_faceA: the local center of cirlceB or the clip point of polygonB +/// -e_faceB: the clip point of polygonA +/// This structure is stored across time steps, so we keep it small. +/// Note: the impulses are used for internal caching and may not +/// provide reliable contact forces, especially for high speed collisions. +struct B2_API b2ManifoldPoint +{ + b2Vec2 localPoint; ///< usage depends on manifold type + float normalImpulse; ///< the non-penetration impulse + float tangentImpulse; ///< the friction impulse + b2ContactID id; ///< uniquely identifies a contact point between two shapes +}; + +/// A manifold for two touching convex shapes. +/// Box2D supports multiple types of contact: +/// - clip point versus plane with radius +/// - point versus point with radius (circles) +/// The local point usage depends on the manifold type: +/// -e_circles: the local center of circleA +/// -e_faceA: the center of faceA +/// -e_faceB: the center of faceB +/// Similarly the local normal usage: +/// -e_circles: not used +/// -e_faceA: the normal on polygonA +/// -e_faceB: the normal on polygonB +/// We store contacts in this way so that position correction can +/// account for movement, which is critical for continuous physics. +/// All contact scenarios must be expressed in one of these types. +/// This structure is stored across time steps, so we keep it small. +struct B2_API b2Manifold +{ + enum Type + { + e_circles, + e_faceA, + e_faceB + }; + + b2ManifoldPoint points[b2_maxManifoldPoints]; ///< the points of contact + b2Vec2 localNormal; ///< not use for Type::e_points + b2Vec2 localPoint; ///< usage depends on manifold type + Type type; + int32 pointCount; ///< the number of manifold points +}; + +/// This is used to compute the current state of a contact manifold. +struct B2_API b2WorldManifold +{ + /// Evaluate the manifold with supplied transforms. This assumes + /// modest motion from the original state. This does not change the + /// point count, impulses, etc. The radii must come from the shapes + /// that generated the manifold. + void Initialize(const b2Manifold* manifold, + const b2Transform& xfA, float radiusA, + const b2Transform& xfB, float radiusB); + + b2Vec2 normal; ///< world vector pointing from A to B + b2Vec2 points[b2_maxManifoldPoints]; ///< world contact point (point of intersection) + float separations[b2_maxManifoldPoints]; ///< a negative value indicates overlap, in meters +}; + +/// This is used for determining the state of contact points. +enum b2PointState +{ + b2_nullState, ///< point does not exist + b2_addState, ///< point was added in the update + b2_persistState, ///< point persisted across the update + b2_removeState ///< point was removed in the update +}; + +/// Compute the point states given two manifolds. The states pertain to the transition from manifold1 +/// to manifold2. So state1 is either persist or remove while state2 is either add or persist. +B2_API void b2GetPointStates(b2PointState state1[b2_maxManifoldPoints], b2PointState state2[b2_maxManifoldPoints], + const b2Manifold* manifold1, const b2Manifold* manifold2); + +/// Used for computing contact manifolds. +struct B2_API b2ClipVertex +{ + b2Vec2 v; + b2ContactID id; +}; + +/// Ray-cast input data. The ray extends from p1 to p1 + maxFraction * (p2 - p1). +struct B2_API b2RayCastInput +{ + b2Vec2 p1, p2; + float maxFraction; +}; + +/// Ray-cast output data. The ray hits at p1 + fraction * (p2 - p1), where p1 and p2 +/// come from b2RayCastInput. +struct B2_API b2RayCastOutput +{ + b2Vec2 normal; + float fraction; +}; + +/// An axis aligned bounding box. +struct B2_API b2AABB +{ + /// Verify that the bounds are sorted. + bool IsValid() const; + + /// Get the center of the AABB. + b2Vec2 GetCenter() const + { + return 0.5f * (lowerBound + upperBound); + } + + /// Get the extents of the AABB (half-widths). + b2Vec2 GetExtents() const + { + return 0.5f * (upperBound - lowerBound); + } + + /// Get the perimeter length + float GetPerimeter() const + { + float wx = upperBound.x - lowerBound.x; + float wy = upperBound.y - lowerBound.y; + return 2.0f * (wx + wy); + } + + /// Combine an AABB into this one. + void Combine(const b2AABB& aabb) + { + lowerBound = b2Min(lowerBound, aabb.lowerBound); + upperBound = b2Max(upperBound, aabb.upperBound); + } + + /// Combine two AABBs into this one. + void Combine(const b2AABB& aabb1, const b2AABB& aabb2) + { + lowerBound = b2Min(aabb1.lowerBound, aabb2.lowerBound); + upperBound = b2Max(aabb1.upperBound, aabb2.upperBound); + } + + /// Does this aabb contain the provided AABB. + bool Contains(const b2AABB& aabb) const + { + bool result = true; + result = result && lowerBound.x <= aabb.lowerBound.x; + result = result && lowerBound.y <= aabb.lowerBound.y; + result = result && aabb.upperBound.x <= upperBound.x; + result = result && aabb.upperBound.y <= upperBound.y; + return result; + } + + bool RayCast(b2RayCastOutput* output, const b2RayCastInput& input) const; + + b2Vec2 lowerBound; ///< the lower vertex + b2Vec2 upperBound; ///< the upper vertex +}; + +/// Compute the collision manifold between two circles. +B2_API void b2CollideCircles(b2Manifold* manifold, + const b2CircleShape* circleA, const b2Transform& xfA, + const b2CircleShape* circleB, const b2Transform& xfB); + +/// Compute the collision manifold between a polygon and a circle. +B2_API void b2CollidePolygonAndCircle(b2Manifold* manifold, + const b2PolygonShape* polygonA, const b2Transform& xfA, + const b2CircleShape* circleB, const b2Transform& xfB); + +/// Compute the collision manifold between two polygons. +B2_API void b2CollidePolygons(b2Manifold* manifold, + const b2PolygonShape* polygonA, const b2Transform& xfA, + const b2PolygonShape* polygonB, const b2Transform& xfB); + +/// Compute the collision manifold between an edge and a circle. +B2_API void b2CollideEdgeAndCircle(b2Manifold* manifold, + const b2EdgeShape* polygonA, const b2Transform& xfA, + const b2CircleShape* circleB, const b2Transform& xfB); + +/// Compute the collision manifold between an edge and a polygon. +B2_API void b2CollideEdgeAndPolygon(b2Manifold* manifold, + const b2EdgeShape* edgeA, const b2Transform& xfA, + const b2PolygonShape* circleB, const b2Transform& xfB); + +/// Clipping for contact manifolds. +B2_API int32 b2ClipSegmentToLine(b2ClipVertex vOut[2], const b2ClipVertex vIn[2], + const b2Vec2& normal, float offset, int32 vertexIndexA); + +/// Determine if two generic shapes overlap. +B2_API bool b2TestOverlap( const b2Shape* shapeA, int32 indexA, + const b2Shape* shapeB, int32 indexB, + const b2Transform& xfA, const b2Transform& xfB); + +// ---------------- Inline Functions ------------------------------------------ + +inline bool b2AABB::IsValid() const +{ + b2Vec2 d = upperBound - lowerBound; + bool valid = d.x >= 0.0f && d.y >= 0.0f; + valid = valid && lowerBound.IsValid() && upperBound.IsValid(); + return valid; +} + +inline bool b2TestOverlap(const b2AABB& a, const b2AABB& b) +{ + b2Vec2 d1, d2; + d1 = b.lowerBound - a.upperBound; + d2 = a.lowerBound - b.upperBound; + + if (d1.x > 0.0f || d1.y > 0.0f) + return false; + + if (d2.x > 0.0f || d2.y > 0.0f) + return false; + + return true; +} + +#endif |