b2_collision.h 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283
  1. // MIT License
  2. // Copyright (c) 2019 Erin Catto
  3. // Permission is hereby granted, free of charge, to any person obtaining a copy
  4. // of this software and associated documentation files (the "Software"), to deal
  5. // in the Software without restriction, including without limitation the rights
  6. // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  7. // copies of the Software, and to permit persons to whom the Software is
  8. // furnished to do so, subject to the following conditions:
  9. // The above copyright notice and this permission notice shall be included in all
  10. // copies or substantial portions of the Software.
  11. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  12. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  13. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  14. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  15. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  16. // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  17. // SOFTWARE.
  18. #ifndef B2_COLLISION_H
  19. #define B2_COLLISION_H
  20. #include <limits.h>
  21. #include "b2_api.h"
  22. #include "b2_math.h"
  23. /// @file
  24. /// Structures and functions used for computing contact points, distance
  25. /// queries, and TOI queries.
  26. class b2Shape;
  27. class b2CircleShape;
  28. class b2EdgeShape;
  29. class b2PolygonShape;
  30. const uint8 b2_nullFeature = UCHAR_MAX;
  31. /// The features that intersect to form the contact point
  32. /// This must be 4 bytes or less.
  33. struct B2_API b2ContactFeature
  34. {
  35. enum Type
  36. {
  37. e_vertex = 0,
  38. e_face = 1
  39. };
  40. uint8 indexA; ///< Feature index on shapeA
  41. uint8 indexB; ///< Feature index on shapeB
  42. uint8 typeA; ///< The feature type on shapeA
  43. uint8 typeB; ///< The feature type on shapeB
  44. };
  45. /// Contact ids to facilitate warm starting.
  46. union B2_API b2ContactID
  47. {
  48. b2ContactFeature cf;
  49. uint32 key; ///< Used to quickly compare contact ids.
  50. };
  51. /// A manifold point is a contact point belonging to a contact
  52. /// manifold. It holds details related to the geometry and dynamics
  53. /// of the contact points.
  54. /// The local point usage depends on the manifold type:
  55. /// -e_circles: the local center of circleB
  56. /// -e_faceA: the local center of cirlceB or the clip point of polygonB
  57. /// -e_faceB: the clip point of polygonA
  58. /// This structure is stored across time steps, so we keep it small.
  59. /// Note: the impulses are used for internal caching and may not
  60. /// provide reliable contact forces, especially for high speed collisions.
  61. struct B2_API b2ManifoldPoint
  62. {
  63. b2Vec2 localPoint; ///< usage depends on manifold type
  64. float normalImpulse; ///< the non-penetration impulse
  65. float tangentImpulse; ///< the friction impulse
  66. b2ContactID id; ///< uniquely identifies a contact point between two shapes
  67. };
  68. /// A manifold for two touching convex shapes.
  69. /// Box2D supports multiple types of contact:
  70. /// - clip point versus plane with radius
  71. /// - point versus point with radius (circles)
  72. /// The local point usage depends on the manifold type:
  73. /// -e_circles: the local center of circleA
  74. /// -e_faceA: the center of faceA
  75. /// -e_faceB: the center of faceB
  76. /// Similarly the local normal usage:
  77. /// -e_circles: not used
  78. /// -e_faceA: the normal on polygonA
  79. /// -e_faceB: the normal on polygonB
  80. /// We store contacts in this way so that position correction can
  81. /// account for movement, which is critical for continuous physics.
  82. /// All contact scenarios must be expressed in one of these types.
  83. /// This structure is stored across time steps, so we keep it small.
  84. struct B2_API b2Manifold
  85. {
  86. enum Type
  87. {
  88. e_circles,
  89. e_faceA,
  90. e_faceB
  91. };
  92. b2ManifoldPoint points[b2_maxManifoldPoints]; ///< the points of contact
  93. b2Vec2 localNormal; ///< not use for Type::e_points
  94. b2Vec2 localPoint; ///< usage depends on manifold type
  95. Type type;
  96. int32 pointCount; ///< the number of manifold points
  97. };
  98. /// This is used to compute the current state of a contact manifold.
  99. struct B2_API b2WorldManifold
  100. {
  101. /// Evaluate the manifold with supplied transforms. This assumes
  102. /// modest motion from the original state. This does not change the
  103. /// point count, impulses, etc. The radii must come from the shapes
  104. /// that generated the manifold.
  105. void Initialize(const b2Manifold* manifold,
  106. const b2Transform& xfA, float radiusA,
  107. const b2Transform& xfB, float radiusB);
  108. b2Vec2 normal; ///< world vector pointing from A to B
  109. b2Vec2 points[b2_maxManifoldPoints]; ///< world contact point (point of intersection)
  110. float separations[b2_maxManifoldPoints]; ///< a negative value indicates overlap, in meters
  111. };
  112. /// This is used for determining the state of contact points.
  113. enum b2PointState
  114. {
  115. b2_nullState, ///< point does not exist
  116. b2_addState, ///< point was added in the update
  117. b2_persistState, ///< point persisted across the update
  118. b2_removeState ///< point was removed in the update
  119. };
  120. /// Compute the point states given two manifolds. The states pertain to the transition from manifold1
  121. /// to manifold2. So state1 is either persist or remove while state2 is either add or persist.
  122. B2_API void b2GetPointStates(b2PointState state1[b2_maxManifoldPoints], b2PointState state2[b2_maxManifoldPoints],
  123. const b2Manifold* manifold1, const b2Manifold* manifold2);
  124. /// Used for computing contact manifolds.
  125. struct B2_API b2ClipVertex
  126. {
  127. b2Vec2 v;
  128. b2ContactID id;
  129. };
  130. /// Ray-cast input data. The ray extends from p1 to p1 + maxFraction * (p2 - p1).
  131. struct B2_API b2RayCastInput
  132. {
  133. b2Vec2 p1, p2;
  134. float maxFraction;
  135. };
  136. /// Ray-cast output data. The ray hits at p1 + fraction * (p2 - p1), where p1 and p2
  137. /// come from b2RayCastInput.
  138. struct B2_API b2RayCastOutput
  139. {
  140. b2Vec2 normal;
  141. float fraction;
  142. };
  143. /// An axis aligned bounding box.
  144. struct B2_API b2AABB
  145. {
  146. /// Verify that the bounds are sorted.
  147. bool IsValid() const;
  148. /// Get the center of the AABB.
  149. b2Vec2 GetCenter() const
  150. {
  151. return 0.5f * (lowerBound + upperBound);
  152. }
  153. /// Get the extents of the AABB (half-widths).
  154. b2Vec2 GetExtents() const
  155. {
  156. return 0.5f * (upperBound - lowerBound);
  157. }
  158. /// Get the perimeter length
  159. float GetPerimeter() const
  160. {
  161. float wx = upperBound.x - lowerBound.x;
  162. float wy = upperBound.y - lowerBound.y;
  163. return 2.0f * (wx + wy);
  164. }
  165. /// Combine an AABB into this one.
  166. void Combine(const b2AABB& aabb)
  167. {
  168. lowerBound = b2Min(lowerBound, aabb.lowerBound);
  169. upperBound = b2Max(upperBound, aabb.upperBound);
  170. }
  171. /// Combine two AABBs into this one.
  172. void Combine(const b2AABB& aabb1, const b2AABB& aabb2)
  173. {
  174. lowerBound = b2Min(aabb1.lowerBound, aabb2.lowerBound);
  175. upperBound = b2Max(aabb1.upperBound, aabb2.upperBound);
  176. }
  177. /// Does this aabb contain the provided AABB.
  178. bool Contains(const b2AABB& aabb) const
  179. {
  180. bool result = true;
  181. result = result && lowerBound.x <= aabb.lowerBound.x;
  182. result = result && lowerBound.y <= aabb.lowerBound.y;
  183. result = result && aabb.upperBound.x <= upperBound.x;
  184. result = result && aabb.upperBound.y <= upperBound.y;
  185. return result;
  186. }
  187. bool RayCast(b2RayCastOutput* output, const b2RayCastInput& input) const;
  188. b2Vec2 lowerBound; ///< the lower vertex
  189. b2Vec2 upperBound; ///< the upper vertex
  190. };
  191. /// Compute the collision manifold between two circles.
  192. B2_API void b2CollideCircles(b2Manifold* manifold,
  193. const b2CircleShape* circleA, const b2Transform& xfA,
  194. const b2CircleShape* circleB, const b2Transform& xfB);
  195. /// Compute the collision manifold between a polygon and a circle.
  196. B2_API void b2CollidePolygonAndCircle(b2Manifold* manifold,
  197. const b2PolygonShape* polygonA, const b2Transform& xfA,
  198. const b2CircleShape* circleB, const b2Transform& xfB);
  199. /// Compute the collision manifold between two polygons.
  200. B2_API void b2CollidePolygons(b2Manifold* manifold,
  201. const b2PolygonShape* polygonA, const b2Transform& xfA,
  202. const b2PolygonShape* polygonB, const b2Transform& xfB);
  203. /// Compute the collision manifold between an edge and a circle.
  204. B2_API void b2CollideEdgeAndCircle(b2Manifold* manifold,
  205. const b2EdgeShape* polygonA, const b2Transform& xfA,
  206. const b2CircleShape* circleB, const b2Transform& xfB);
  207. /// Compute the collision manifold between an edge and a polygon.
  208. B2_API void b2CollideEdgeAndPolygon(b2Manifold* manifold,
  209. const b2EdgeShape* edgeA, const b2Transform& xfA,
  210. const b2PolygonShape* circleB, const b2Transform& xfB);
  211. /// Clipping for contact manifolds.
  212. B2_API int32 b2ClipSegmentToLine(b2ClipVertex vOut[2], const b2ClipVertex vIn[2],
  213. const b2Vec2& normal, float offset, int32 vertexIndexA);
  214. /// Determine if two generic shapes overlap.
  215. B2_API bool b2TestOverlap( const b2Shape* shapeA, int32 indexA,
  216. const b2Shape* shapeB, int32 indexB,
  217. const b2Transform& xfA, const b2Transform& xfB);
  218. // ---------------- Inline Functions ------------------------------------------
  219. inline bool b2AABB::IsValid() const
  220. {
  221. b2Vec2 d = upperBound - lowerBound;
  222. bool valid = d.x >= 0.0f && d.y >= 0.0f;
  223. valid = valid && lowerBound.IsValid() && upperBound.IsValid();
  224. return valid;
  225. }
  226. inline bool b2TestOverlap(const b2AABB& a, const b2AABB& b)
  227. {
  228. b2Vec2 d1, d2;
  229. d1 = b.lowerBound - a.upperBound;
  230. d2 = a.lowerBound - b.upperBound;
  231. if (d1.x > 0.0f || d1.y > 0.0f)
  232. return false;
  233. if (d2.x > 0.0f || d2.y > 0.0f)
  234. return false;
  235. return true;
  236. }
  237. #endif