CompoundShapeVisitors.h 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461
  1. // Jolt Physics Library (https://github.com/jrouwe/JoltPhysics)
  2. // SPDX-FileCopyrightText: 2021 Jorrit Rouwe
  3. // SPDX-License-Identifier: MIT
  4. #pragma once
  5. #include <Jolt/Physics/Collision/Shape/CompoundShape.h>
  6. #include <Jolt/Physics/Collision/Shape/SubShapeID.h>
  7. #include <Jolt/Physics/Collision/RayCast.h>
  8. #include <Jolt/Physics/Collision/CastResult.h>
  9. #include <Jolt/Physics/Collision/ShapeCast.h>
  10. #include <Jolt/Physics/Collision/TransformedShape.h>
  11. #include <Jolt/Physics/Collision/CollisionDispatch.h>
  12. #include <Jolt/Geometry/RayAABox.h>
  13. #include <Jolt/Geometry/AABox4.h>
  14. #include <Jolt/Geometry/OrientedBox.h>
  15. JPH_NAMESPACE_BEGIN
  16. struct CompoundShape::CastRayVisitor
  17. {
  18. JPH_INLINE CastRayVisitor(const RayCast &inRay, const CompoundShape *inShape, const SubShapeIDCreator &inSubShapeIDCreator, RayCastResult &ioHit) :
  19. mRay(inRay),
  20. mHit(ioHit),
  21. mSubShapeIDCreator(inSubShapeIDCreator),
  22. mSubShapeBits(inShape->GetSubShapeIDBits())
  23. {
  24. // Determine ray properties of cast
  25. mInvDirection.Set(inRay.mDirection);
  26. }
  27. /// Returns true when collision detection should abort because it's not possible to find a better hit
  28. JPH_INLINE bool ShouldAbort() const
  29. {
  30. return mHit.mFraction <= 0.0f;
  31. }
  32. /// Test ray against 4 bounding boxes and returns the distance where the ray enters the bounding box
  33. JPH_INLINE Vec4 TestBounds(Vec4Arg inBoundsMinX, Vec4Arg inBoundsMinY, Vec4Arg inBoundsMinZ, Vec4Arg inBoundsMaxX, Vec4Arg inBoundsMaxY, Vec4Arg inBoundsMaxZ) const
  34. {
  35. return RayAABox4(mRay.mOrigin, mInvDirection, inBoundsMinX, inBoundsMinY, inBoundsMinZ, inBoundsMaxX, inBoundsMaxY, inBoundsMaxZ);
  36. }
  37. /// Test the ray against a single subshape
  38. JPH_INLINE void VisitShape(const SubShape &inSubShape, uint32 inSubShapeIndex)
  39. {
  40. // Create ID for sub shape
  41. SubShapeIDCreator shape2_sub_shape_id = mSubShapeIDCreator.PushID(inSubShapeIndex, mSubShapeBits);
  42. // Transform the ray
  43. Mat44 transform = Mat44::sInverseRotationTranslation(inSubShape.GetRotation(), inSubShape.GetPositionCOM());
  44. RayCast ray = mRay.Transformed(transform);
  45. if (inSubShape.mShape->CastRay(ray, shape2_sub_shape_id, mHit))
  46. mReturnValue = true;
  47. }
  48. RayInvDirection mInvDirection;
  49. const RayCast & mRay;
  50. RayCastResult & mHit;
  51. SubShapeIDCreator mSubShapeIDCreator;
  52. uint mSubShapeBits;
  53. bool mReturnValue = false;
  54. };
  55. struct CompoundShape::CastRayVisitorCollector
  56. {
  57. JPH_INLINE CastRayVisitorCollector(const RayCast &inRay, const RayCastSettings &inRayCastSettings, const CompoundShape *inShape, const SubShapeIDCreator &inSubShapeIDCreator, CastRayCollector &ioCollector, const ShapeFilter &inShapeFilter) :
  58. mRay(inRay),
  59. mCollector(ioCollector),
  60. mSubShapeIDCreator(inSubShapeIDCreator),
  61. mSubShapeBits(inShape->GetSubShapeIDBits()),
  62. mRayCastSettings(inRayCastSettings),
  63. mShapeFilter(inShapeFilter)
  64. {
  65. // Determine ray properties of cast
  66. mInvDirection.Set(inRay.mDirection);
  67. }
  68. /// Returns true when collision detection should abort because it's not possible to find a better hit
  69. JPH_INLINE bool ShouldAbort() const
  70. {
  71. return mCollector.ShouldEarlyOut();
  72. }
  73. /// Test ray against 4 bounding boxes and returns the distance where the ray enters the bounding box
  74. JPH_INLINE Vec4 TestBounds(Vec4Arg inBoundsMinX, Vec4Arg inBoundsMinY, Vec4Arg inBoundsMinZ, Vec4Arg inBoundsMaxX, Vec4Arg inBoundsMaxY, Vec4Arg inBoundsMaxZ) const
  75. {
  76. return RayAABox4(mRay.mOrigin, mInvDirection, inBoundsMinX, inBoundsMinY, inBoundsMinZ, inBoundsMaxX, inBoundsMaxY, inBoundsMaxZ);
  77. }
  78. /// Test the ray against a single subshape
  79. JPH_INLINE void VisitShape(const SubShape &inSubShape, uint32 inSubShapeIndex)
  80. {
  81. // Create ID for sub shape
  82. SubShapeIDCreator shape2_sub_shape_id = mSubShapeIDCreator.PushID(inSubShapeIndex, mSubShapeBits);
  83. // Transform the ray
  84. Mat44 transform = Mat44::sInverseRotationTranslation(inSubShape.GetRotation(), inSubShape.GetPositionCOM());
  85. RayCast ray = mRay.Transformed(transform);
  86. inSubShape.mShape->CastRay(ray, mRayCastSettings, shape2_sub_shape_id, mCollector, mShapeFilter);
  87. }
  88. RayInvDirection mInvDirection;
  89. const RayCast & mRay;
  90. CastRayCollector & mCollector;
  91. SubShapeIDCreator mSubShapeIDCreator;
  92. uint mSubShapeBits;
  93. RayCastSettings mRayCastSettings;
  94. const ShapeFilter & mShapeFilter;
  95. };
  96. struct CompoundShape::CollidePointVisitor
  97. {
  98. JPH_INLINE CollidePointVisitor(Vec3Arg inPoint, const CompoundShape *inShape, const SubShapeIDCreator &inSubShapeIDCreator, CollidePointCollector &ioCollector, const ShapeFilter &inShapeFilter) :
  99. mPoint(inPoint),
  100. mSubShapeIDCreator(inSubShapeIDCreator),
  101. mCollector(ioCollector),
  102. mSubShapeBits(inShape->GetSubShapeIDBits()),
  103. mShapeFilter(inShapeFilter)
  104. {
  105. }
  106. /// Returns true when collision detection should abort because it's not possible to find a better hit
  107. JPH_INLINE bool ShouldAbort() const
  108. {
  109. return mCollector.ShouldEarlyOut();
  110. }
  111. /// Test if point overlaps with 4 boxes, returns true for the ones that do
  112. JPH_INLINE UVec4 TestBounds(Vec4Arg inBoundsMinX, Vec4Arg inBoundsMinY, Vec4Arg inBoundsMinZ, Vec4Arg inBoundsMaxX, Vec4Arg inBoundsMaxY, Vec4Arg inBoundsMaxZ) const
  113. {
  114. return AABox4VsPoint(mPoint, inBoundsMinX, inBoundsMinY, inBoundsMinZ, inBoundsMaxX, inBoundsMaxY, inBoundsMaxZ);
  115. }
  116. /// Test the point against a single subshape
  117. JPH_INLINE void VisitShape(const SubShape &inSubShape, uint32 inSubShapeIndex)
  118. {
  119. // Create ID for sub shape
  120. SubShapeIDCreator shape2_sub_shape_id = mSubShapeIDCreator.PushID(inSubShapeIndex, mSubShapeBits);
  121. // Transform the point
  122. Mat44 transform = Mat44::sInverseRotationTranslation(inSubShape.GetRotation(), inSubShape.GetPositionCOM());
  123. inSubShape.mShape->CollidePoint(transform * mPoint, shape2_sub_shape_id, mCollector, mShapeFilter);
  124. }
  125. Vec3 mPoint;
  126. SubShapeIDCreator mSubShapeIDCreator;
  127. CollidePointCollector & mCollector;
  128. uint mSubShapeBits;
  129. const ShapeFilter & mShapeFilter;
  130. };
  131. struct CompoundShape::CastShapeVisitor
  132. {
  133. JPH_INLINE CastShapeVisitor(const ShapeCast &inShapeCast, const ShapeCastSettings &inShapeCastSettings, const CompoundShape *inShape, Vec3Arg inScale, const ShapeFilter &inShapeFilter, Mat44Arg inCenterOfMassTransform2, const SubShapeIDCreator &inSubShapeIDCreator1, const SubShapeIDCreator &inSubShapeIDCreator2, CastShapeCollector &ioCollector) :
  134. mBoxCenter(inShapeCast.mShapeWorldBounds.GetCenter()),
  135. mBoxExtent(inShapeCast.mShapeWorldBounds.GetExtent()),
  136. mScale(inScale),
  137. mShapeCast(inShapeCast),
  138. mShapeCastSettings(inShapeCastSettings),
  139. mShapeFilter(inShapeFilter),
  140. mCollector(ioCollector),
  141. mCenterOfMassTransform2(inCenterOfMassTransform2),
  142. mSubShapeIDCreator1(inSubShapeIDCreator1),
  143. mSubShapeIDCreator2(inSubShapeIDCreator2),
  144. mSubShapeBits(inShape->GetSubShapeIDBits())
  145. {
  146. // Determine ray properties of cast
  147. mInvDirection.Set(inShapeCast.mDirection);
  148. }
  149. /// Returns true when collision detection should abort because it's not possible to find a better hit
  150. JPH_INLINE bool ShouldAbort() const
  151. {
  152. return mCollector.ShouldEarlyOut();
  153. }
  154. /// Tests the shape cast against 4 bounding boxes, returns the distance along the shape cast where the shape first enters the bounding box
  155. JPH_INLINE Vec4 TestBounds(Vec4Arg inBoundsMinX, Vec4Arg inBoundsMinY, Vec4Arg inBoundsMinZ, Vec4Arg inBoundsMaxX, Vec4Arg inBoundsMaxY, Vec4Arg inBoundsMaxZ) const
  156. {
  157. // Scale the bounding boxes
  158. Vec4 bounds_min_x, bounds_min_y, bounds_min_z, bounds_max_x, bounds_max_y, bounds_max_z;
  159. AABox4Scale(mScale, inBoundsMinX, inBoundsMinY, inBoundsMinZ, inBoundsMaxX, inBoundsMaxY, inBoundsMaxZ, bounds_min_x, bounds_min_y, bounds_min_z, bounds_max_x, bounds_max_y, bounds_max_z);
  160. // Enlarge them by the casted shape's box extents
  161. AABox4EnlargeWithExtent(mBoxExtent, bounds_min_x, bounds_min_y, bounds_min_z, bounds_max_x, bounds_max_y, bounds_max_z);
  162. // Test ray against the bounding boxes
  163. return RayAABox4(mBoxCenter, mInvDirection, bounds_min_x, bounds_min_y, bounds_min_z, bounds_max_x, bounds_max_y, bounds_max_z);
  164. }
  165. /// Test the cast shape against a single subshape
  166. JPH_INLINE void VisitShape(const SubShape &inSubShape, uint32 inSubShapeIndex)
  167. {
  168. JPH_ASSERT(inSubShape.IsValidScale(mScale));
  169. // Create ID for sub shape
  170. SubShapeIDCreator shape2_sub_shape_id = mSubShapeIDCreator2.PushID(inSubShapeIndex, mSubShapeBits);
  171. // Calculate the local transform for this sub shape
  172. Mat44 local_transform = Mat44::sRotationTranslation(inSubShape.GetRotation(), mScale * inSubShape.GetPositionCOM());
  173. // Transform the center of mass of 2
  174. Mat44 center_of_mass_transform2 = mCenterOfMassTransform2 * local_transform;
  175. // Transform the shape cast
  176. ShapeCast shape_cast = mShapeCast.PostTransformed(local_transform.InversedRotationTranslation());
  177. CollisionDispatch::sCastShapeVsShapeLocalSpace(shape_cast, mShapeCastSettings, inSubShape.mShape, inSubShape.TransformScale(mScale), mShapeFilter, center_of_mass_transform2, mSubShapeIDCreator1, shape2_sub_shape_id, mCollector);
  178. }
  179. RayInvDirection mInvDirection;
  180. Vec3 mBoxCenter;
  181. Vec3 mBoxExtent;
  182. Vec3 mScale;
  183. const ShapeCast & mShapeCast;
  184. const ShapeCastSettings & mShapeCastSettings;
  185. const ShapeFilter & mShapeFilter;
  186. CastShapeCollector & mCollector;
  187. Mat44 mCenterOfMassTransform2;
  188. SubShapeIDCreator mSubShapeIDCreator1;
  189. SubShapeIDCreator mSubShapeIDCreator2;
  190. uint mSubShapeBits;
  191. };
  192. struct CompoundShape::CollectTransformedShapesVisitor
  193. {
  194. JPH_INLINE CollectTransformedShapesVisitor(const AABox &inBox, const CompoundShape *inShape, Vec3Arg inPositionCOM, QuatArg inRotation, Vec3Arg inScale, const SubShapeIDCreator &inSubShapeIDCreator, TransformedShapeCollector &ioCollector, const ShapeFilter &inShapeFilter) :
  195. mBox(inBox),
  196. mLocalBox(Mat44::sInverseRotationTranslation(inRotation, inPositionCOM), inBox),
  197. mPositionCOM(inPositionCOM),
  198. mRotation(inRotation),
  199. mScale(inScale),
  200. mSubShapeIDCreator(inSubShapeIDCreator),
  201. mCollector(ioCollector),
  202. mSubShapeBits(inShape->GetSubShapeIDBits()),
  203. mShapeFilter(inShapeFilter)
  204. {
  205. }
  206. /// Returns true when collision detection should abort because it's not possible to find a better hit
  207. JPH_INLINE bool ShouldAbort() const
  208. {
  209. return mCollector.ShouldEarlyOut();
  210. }
  211. /// Tests 4 bounding boxes against the query box, returns true for the ones that collide
  212. JPH_INLINE UVec4 TestBounds(Vec4Arg inBoundsMinX, Vec4Arg inBoundsMinY, Vec4Arg inBoundsMinZ, Vec4Arg inBoundsMaxX, Vec4Arg inBoundsMaxY, Vec4Arg inBoundsMaxZ) const
  213. {
  214. // Scale the bounding boxes of this node
  215. Vec4 bounds_min_x, bounds_min_y, bounds_min_z, bounds_max_x, bounds_max_y, bounds_max_z;
  216. AABox4Scale(mScale, inBoundsMinX, inBoundsMinY, inBoundsMinZ, inBoundsMaxX, inBoundsMaxY, inBoundsMaxZ, bounds_min_x, bounds_min_y, bounds_min_z, bounds_max_x, bounds_max_y, bounds_max_z);
  217. // Test which nodes collide
  218. return AABox4VsBox(mLocalBox, bounds_min_x, bounds_min_y, bounds_min_z, bounds_max_x, bounds_max_y, bounds_max_z);
  219. }
  220. /// Collect the transformed sub shapes for a single subshape
  221. JPH_INLINE void VisitShape(const SubShape &inSubShape, uint32 inSubShapeIndex)
  222. {
  223. JPH_ASSERT(inSubShape.IsValidScale(mScale));
  224. // Create ID for sub shape
  225. SubShapeIDCreator sub_shape_id = mSubShapeIDCreator.PushID(inSubShapeIndex, mSubShapeBits);
  226. // Calculate world transform for sub shape
  227. Vec3 position = mPositionCOM + mRotation * (mScale * inSubShape.GetPositionCOM());
  228. Quat rotation = mRotation * inSubShape.GetRotation();
  229. // Recurse to sub shape
  230. inSubShape.mShape->CollectTransformedShapes(mBox, position, rotation, inSubShape.TransformScale(mScale), sub_shape_id, mCollector, mShapeFilter);
  231. }
  232. AABox mBox;
  233. OrientedBox mLocalBox;
  234. Vec3 mPositionCOM;
  235. Quat mRotation;
  236. Vec3 mScale;
  237. SubShapeIDCreator mSubShapeIDCreator;
  238. TransformedShapeCollector & mCollector;
  239. uint mSubShapeBits;
  240. const ShapeFilter & mShapeFilter;
  241. };
  242. struct CompoundShape::CollideCompoundVsShapeVisitor
  243. {
  244. JPH_INLINE CollideCompoundVsShapeVisitor(const CompoundShape *inShape1, const Shape *inShape2, Vec3Arg inScale1, Vec3Arg inScale2, Mat44Arg inCenterOfMassTransform1, Mat44Arg inCenterOfMassTransform2, const SubShapeIDCreator &inSubShapeIDCreator1, const SubShapeIDCreator &inSubShapeIDCreator2, const CollideShapeSettings &inCollideShapeSettings, CollideShapeCollector &ioCollector, const ShapeFilter &inShapeFilter) :
  245. mCollideShapeSettings(inCollideShapeSettings),
  246. mCollector(ioCollector),
  247. mShape2(inShape2),
  248. mScale1(inScale1),
  249. mScale2(inScale2),
  250. mTransform1(inCenterOfMassTransform1),
  251. mTransform2(inCenterOfMassTransform2),
  252. mSubShapeIDCreator1(inSubShapeIDCreator1),
  253. mSubShapeIDCreator2(inSubShapeIDCreator2),
  254. mSubShapeBits(inShape1->GetSubShapeIDBits()),
  255. mShapeFilter(inShapeFilter)
  256. {
  257. // Get transform from shape 2 to shape 1
  258. Mat44 transform2_to_1 = inCenterOfMassTransform1.InversedRotationTranslation() * inCenterOfMassTransform2;
  259. // Convert bounding box of 2 into space of 1
  260. mBoundsOf2InSpaceOf1 = inShape2->GetLocalBounds().Scaled(inScale2).Transformed(transform2_to_1);
  261. mBoundsOf2InSpaceOf1.ExpandBy(Vec3::sReplicate(inCollideShapeSettings.mMaxSeparationDistance));
  262. }
  263. /// Returns true when collision detection should abort because it's not possible to find a better hit
  264. JPH_INLINE bool ShouldAbort() const
  265. {
  266. return mCollector.ShouldEarlyOut();
  267. }
  268. /// Tests the bounds of shape 2 vs 4 bounding boxes, returns true for the ones that intersect
  269. JPH_INLINE UVec4 TestBounds(Vec4Arg inBoundsMinX, Vec4Arg inBoundsMinY, Vec4Arg inBoundsMinZ, Vec4Arg inBoundsMaxX, Vec4Arg inBoundsMaxY, Vec4Arg inBoundsMaxZ) const
  270. {
  271. // Scale the bounding boxes
  272. Vec4 bounds_min_x, bounds_min_y, bounds_min_z, bounds_max_x, bounds_max_y, bounds_max_z;
  273. AABox4Scale(mScale1, inBoundsMinX, inBoundsMinY, inBoundsMinZ, inBoundsMaxX, inBoundsMaxY, inBoundsMaxZ, bounds_min_x, bounds_min_y, bounds_min_z, bounds_max_x, bounds_max_y, bounds_max_z);
  274. // Test which boxes collide
  275. return AABox4VsBox(mBoundsOf2InSpaceOf1, bounds_min_x, bounds_min_y, bounds_min_z, bounds_max_x, bounds_max_y, bounds_max_z);
  276. }
  277. /// Test the shape against a single subshape
  278. JPH_INLINE void VisitShape(const SubShape &inSubShape, uint32 inSubShapeIndex)
  279. {
  280. // Get world transform of 1
  281. Mat44 transform1 = mTransform1 * inSubShape.GetLocalTransformNoScale(mScale1);
  282. // Create ID for sub shape
  283. SubShapeIDCreator shape1_sub_shape_id = mSubShapeIDCreator1.PushID(inSubShapeIndex, mSubShapeBits);
  284. CollisionDispatch::sCollideShapeVsShape(inSubShape.mShape, mShape2, inSubShape.TransformScale(mScale1), mScale2, transform1, mTransform2, shape1_sub_shape_id, mSubShapeIDCreator2, mCollideShapeSettings, mCollector, mShapeFilter);
  285. }
  286. const CollideShapeSettings & mCollideShapeSettings;
  287. CollideShapeCollector & mCollector;
  288. const Shape * mShape2;
  289. Vec3 mScale1;
  290. Vec3 mScale2;
  291. Mat44 mTransform1;
  292. Mat44 mTransform2;
  293. AABox mBoundsOf2InSpaceOf1;
  294. SubShapeIDCreator mSubShapeIDCreator1;
  295. SubShapeIDCreator mSubShapeIDCreator2;
  296. uint mSubShapeBits;
  297. const ShapeFilter & mShapeFilter;
  298. };
  299. struct CompoundShape::CollideShapeVsCompoundVisitor
  300. {
  301. JPH_INLINE CollideShapeVsCompoundVisitor(const Shape *inShape1, const CompoundShape *inShape2, Vec3Arg inScale1, Vec3Arg inScale2, Mat44Arg inCenterOfMassTransform1, Mat44Arg inCenterOfMassTransform2, const SubShapeIDCreator &inSubShapeIDCreator1, const SubShapeIDCreator &inSubShapeIDCreator2, const CollideShapeSettings &inCollideShapeSettings, CollideShapeCollector &ioCollector, const ShapeFilter &inShapeFilter) :
  302. mCollideShapeSettings(inCollideShapeSettings),
  303. mCollector(ioCollector),
  304. mShape1(inShape1),
  305. mScale1(inScale1),
  306. mScale2(inScale2),
  307. mTransform1(inCenterOfMassTransform1),
  308. mTransform2(inCenterOfMassTransform2),
  309. mSubShapeIDCreator1(inSubShapeIDCreator1),
  310. mSubShapeIDCreator2(inSubShapeIDCreator2),
  311. mSubShapeBits(inShape2->GetSubShapeIDBits()),
  312. mShapeFilter(inShapeFilter)
  313. {
  314. // Get transform from shape 1 to shape 2
  315. Mat44 transform1_to_2 = inCenterOfMassTransform2.InversedRotationTranslation() * inCenterOfMassTransform1;
  316. // Convert bounding box of 1 into space of 2
  317. mBoundsOf1InSpaceOf2 = inShape1->GetLocalBounds().Scaled(inScale1).Transformed(transform1_to_2);
  318. mBoundsOf1InSpaceOf2.ExpandBy(Vec3::sReplicate(inCollideShapeSettings.mMaxSeparationDistance));
  319. }
  320. /// Returns true when collision detection should abort because it's not possible to find a better hit
  321. JPH_INLINE bool ShouldAbort() const
  322. {
  323. return mCollector.ShouldEarlyOut();
  324. }
  325. /// Tests the bounds of shape 1 vs 4 bounding boxes, returns true for the ones that intersect
  326. JPH_INLINE UVec4 TestBounds(Vec4Arg inBoundsMinX, Vec4Arg inBoundsMinY, Vec4Arg inBoundsMinZ, Vec4Arg inBoundsMaxX, Vec4Arg inBoundsMaxY, Vec4Arg inBoundsMaxZ) const
  327. {
  328. // Scale the bounding boxes
  329. Vec4 bounds_min_x, bounds_min_y, bounds_min_z, bounds_max_x, bounds_max_y, bounds_max_z;
  330. AABox4Scale(mScale2, inBoundsMinX, inBoundsMinY, inBoundsMinZ, inBoundsMaxX, inBoundsMaxY, inBoundsMaxZ, bounds_min_x, bounds_min_y, bounds_min_z, bounds_max_x, bounds_max_y, bounds_max_z);
  331. // Test which bounding boxes collide
  332. return AABox4VsBox(mBoundsOf1InSpaceOf2, bounds_min_x, bounds_min_y, bounds_min_z, bounds_max_x, bounds_max_y, bounds_max_z);
  333. }
  334. /// Test the shape against a single subshape
  335. JPH_INLINE void VisitShape(const SubShape &inSubShape, uint32 inSubShapeIndex)
  336. {
  337. // Create ID for sub shape
  338. SubShapeIDCreator shape2_sub_shape_id = mSubShapeIDCreator2.PushID(inSubShapeIndex, mSubShapeBits);
  339. // Get world transform of 2
  340. Mat44 transform2 = mTransform2 * inSubShape.GetLocalTransformNoScale(mScale2);
  341. CollisionDispatch::sCollideShapeVsShape(mShape1, inSubShape.mShape, mScale1, inSubShape.TransformScale(mScale2), mTransform1, transform2, mSubShapeIDCreator1, shape2_sub_shape_id, mCollideShapeSettings, mCollector, mShapeFilter);
  342. }
  343. const CollideShapeSettings & mCollideShapeSettings;
  344. CollideShapeCollector & mCollector;
  345. const Shape * mShape1;
  346. Vec3 mScale1;
  347. Vec3 mScale2;
  348. Mat44 mTransform1;
  349. Mat44 mTransform2;
  350. AABox mBoundsOf1InSpaceOf2;
  351. SubShapeIDCreator mSubShapeIDCreator1;
  352. SubShapeIDCreator mSubShapeIDCreator2;
  353. uint mSubShapeBits;
  354. const ShapeFilter & mShapeFilter;
  355. };
  356. template <class BoxType>
  357. struct CompoundShape::GetIntersectingSubShapesVisitor
  358. {
  359. JPH_INLINE GetIntersectingSubShapesVisitor(const BoxType &inBox, uint *outSubShapeIndices, int inMaxSubShapeIndices) :
  360. mBox(inBox),
  361. mSubShapeIndices(outSubShapeIndices),
  362. mMaxSubShapeIndices(inMaxSubShapeIndices)
  363. {
  364. }
  365. /// Returns true when collision detection should abort because the buffer is full
  366. JPH_INLINE bool ShouldAbort() const
  367. {
  368. return mNumResults >= mMaxSubShapeIndices;
  369. }
  370. /// Tests the box vs 4 bounding boxes, returns true for the ones that intersect
  371. JPH_INLINE UVec4 TestBounds(Vec4Arg inBoundsMinX, Vec4Arg inBoundsMinY, Vec4Arg inBoundsMinZ, Vec4Arg inBoundsMaxX, Vec4Arg inBoundsMaxY, Vec4Arg inBoundsMaxZ) const
  372. {
  373. // Test which bounding boxes collide
  374. return AABox4VsBox(mBox, inBoundsMinX, inBoundsMinY, inBoundsMinZ, inBoundsMaxX, inBoundsMaxY, inBoundsMaxZ);
  375. }
  376. /// Records a hit
  377. JPH_INLINE void VisitShape([[maybe_unused]] const SubShape &inSubShape, uint32 inSubShapeIndex)
  378. {
  379. JPH_ASSERT(mNumResults < mMaxSubShapeIndices);
  380. *mSubShapeIndices++ = inSubShapeIndex;
  381. mNumResults++;
  382. }
  383. /// Get the number of indices that were found
  384. JPH_INLINE int GetNumResults() const
  385. {
  386. return mNumResults;
  387. }
  388. private:
  389. BoxType mBox;
  390. uint * mSubShapeIndices;
  391. int mMaxSubShapeIndices;
  392. int mNumResults = 0;
  393. };
  394. JPH_NAMESPACE_END