b2Collision.h
上传用户:gb3593
上传日期:2022-01-07
资源大小:3028k
文件大小:8k
源码类别:

游戏引擎

开发平台:

Visual C++

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