The JUCE cross-platform C++ framework, with DISTRHO/KXStudio specific changes
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

276 lines
9.1KB

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