CompoundShapeVisitors.h 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460
  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 boundign 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. }
  262. /// Returns true when collision detection should abort because it's not possible to find a better hit
  263. JPH_INLINE bool ShouldAbort() const
  264. {
  265. return mCollector.ShouldEarlyOut();
  266. }
  267. /// Tests the bounds of shape 2 vs 4 bounding boxes, returns true for the ones that intersect
  268. JPH_INLINE UVec4 TestBounds(Vec4Arg inBoundsMinX, Vec4Arg inBoundsMinY, Vec4Arg inBoundsMinZ, Vec4Arg inBoundsMaxX, Vec4Arg inBoundsMaxY, Vec4Arg inBoundsMaxZ) const
  269. {
  270. // Scale the bounding boxes
  271. Vec4 bounds_min_x, bounds_min_y, bounds_min_z, bounds_max_x, bounds_max_y, bounds_max_z;
  272. 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);
  273. // Test which boxes collide
  274. return AABox4VsBox(mBoundsOf2InSpaceOf1, bounds_min_x, bounds_min_y, bounds_min_z, bounds_max_x, bounds_max_y, bounds_max_z);
  275. }
  276. /// Test the shape against a single subshape
  277. JPH_INLINE void VisitShape(const SubShape &inSubShape, uint32 inSubShapeIndex)
  278. {
  279. // Get world transform of 1
  280. Mat44 transform1 = mTransform1 * inSubShape.GetLocalTransformNoScale(mScale1);
  281. // Create ID for sub shape
  282. SubShapeIDCreator shape1_sub_shape_id = mSubShapeIDCreator1.PushID(inSubShapeIndex, mSubShapeBits);
  283. CollisionDispatch::sCollideShapeVsShape(inSubShape.mShape, mShape2, inSubShape.TransformScale(mScale1), mScale2, transform1, mTransform2, shape1_sub_shape_id, mSubShapeIDCreator2, mCollideShapeSettings, mCollector, mShapeFilter);
  284. }
  285. const CollideShapeSettings & mCollideShapeSettings;
  286. CollideShapeCollector & mCollector;
  287. const Shape * mShape2;
  288. Vec3 mScale1;
  289. Vec3 mScale2;
  290. Mat44 mTransform1;
  291. Mat44 mTransform2;
  292. AABox mBoundsOf2InSpaceOf1;
  293. SubShapeIDCreator mSubShapeIDCreator1;
  294. SubShapeIDCreator mSubShapeIDCreator2;
  295. uint mSubShapeBits;
  296. const ShapeFilter & mShapeFilter;
  297. };
  298. struct CompoundShape::CollideShapeVsCompoundVisitor
  299. {
  300. 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) :
  301. mCollideShapeSettings(inCollideShapeSettings),
  302. mCollector(ioCollector),
  303. mShape1(inShape1),
  304. mScale1(inScale1),
  305. mScale2(inScale2),
  306. mTransform1(inCenterOfMassTransform1),
  307. mTransform2(inCenterOfMassTransform2),
  308. mSubShapeIDCreator1(inSubShapeIDCreator1),
  309. mSubShapeIDCreator2(inSubShapeIDCreator2),
  310. mSubShapeBits(inShape2->GetSubShapeIDBits()),
  311. mShapeFilter(inShapeFilter)
  312. {
  313. // Get transform from shape 1 to shape 2
  314. Mat44 transform1_to_2 = inCenterOfMassTransform2.InversedRotationTranslation() * inCenterOfMassTransform1;
  315. // Convert bounding box of 1 into space of 2
  316. mBoundsOf1InSpaceOf2 = inShape1->GetLocalBounds().Scaled(inScale1).Transformed(transform1_to_2);
  317. mBoundsOf1InSpaceOf2.ExpandBy(Vec3::sReplicate(inCollideShapeSettings.mMaxSeparationDistance));
  318. }
  319. /// Returns true when collision detection should abort because it's not possible to find a better hit
  320. JPH_INLINE bool ShouldAbort() const
  321. {
  322. return mCollector.ShouldEarlyOut();
  323. }
  324. /// Tests the bounds of shape 1 vs 4 bounding boxes, returns true for the ones that intersect
  325. JPH_INLINE UVec4 TestBounds(Vec4Arg inBoundsMinX, Vec4Arg inBoundsMinY, Vec4Arg inBoundsMinZ, Vec4Arg inBoundsMaxX, Vec4Arg inBoundsMaxY, Vec4Arg inBoundsMaxZ) const
  326. {
  327. // Scale the bounding boxes
  328. Vec4 bounds_min_x, bounds_min_y, bounds_min_z, bounds_max_x, bounds_max_y, bounds_max_z;
  329. 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);
  330. // Test which bounding boxes collide
  331. return AABox4VsBox(mBoundsOf1InSpaceOf2, bounds_min_x, bounds_min_y, bounds_min_z, bounds_max_x, bounds_max_y, bounds_max_z);
  332. }
  333. /// Test the shape against a single subshape
  334. JPH_INLINE void VisitShape(const SubShape &inSubShape, uint32 inSubShapeIndex)
  335. {
  336. // Create ID for sub shape
  337. SubShapeIDCreator shape2_sub_shape_id = mSubShapeIDCreator2.PushID(inSubShapeIndex, mSubShapeBits);
  338. // Get world transform of 2
  339. Mat44 transform2 = mTransform2 * inSubShape.GetLocalTransformNoScale(mScale2);
  340. CollisionDispatch::sCollideShapeVsShape(mShape1, inSubShape.mShape, mScale1, inSubShape.TransformScale(mScale2), mTransform1, transform2, mSubShapeIDCreator1, shape2_sub_shape_id, mCollideShapeSettings, mCollector, mShapeFilter);
  341. }
  342. const CollideShapeSettings & mCollideShapeSettings;
  343. CollideShapeCollector & mCollector;
  344. const Shape * mShape1;
  345. Vec3 mScale1;
  346. Vec3 mScale2;
  347. Mat44 mTransform1;
  348. Mat44 mTransform2;
  349. AABox mBoundsOf1InSpaceOf2;
  350. SubShapeIDCreator mSubShapeIDCreator1;
  351. SubShapeIDCreator mSubShapeIDCreator2;
  352. uint mSubShapeBits;
  353. const ShapeFilter & mShapeFilter;
  354. };
  355. template <class BoxType>
  356. struct CompoundShape::GetIntersectingSubShapesVisitor
  357. {
  358. JPH_INLINE GetIntersectingSubShapesVisitor(const BoxType &inBox, uint *outSubShapeIndices, int inMaxSubShapeIndices) :
  359. mBox(inBox),
  360. mSubShapeIndices(outSubShapeIndices),
  361. mMaxSubShapeIndices(inMaxSubShapeIndices)
  362. {
  363. }
  364. /// Returns true when collision detection should abort because the buffer is full
  365. JPH_INLINE bool ShouldAbort() const
  366. {
  367. return mNumResults >= mMaxSubShapeIndices;
  368. }
  369. /// Tests the box vs 4 bounding boxes, returns true for the ones that intersect
  370. JPH_INLINE UVec4 TestBounds(Vec4Arg inBoundsMinX, Vec4Arg inBoundsMinY, Vec4Arg inBoundsMinZ, Vec4Arg inBoundsMaxX, Vec4Arg inBoundsMaxY, Vec4Arg inBoundsMaxZ) const
  371. {
  372. // Test which bounding boxes collide
  373. return AABox4VsBox(mBox, inBoundsMinX, inBoundsMinY, inBoundsMinZ, inBoundsMaxX, inBoundsMaxY, inBoundsMaxZ);
  374. }
  375. /// Records a hit
  376. JPH_INLINE void VisitShape([[maybe_unused]] const SubShape &inSubShape, uint32 inSubShapeIndex)
  377. {
  378. JPH_ASSERT(mNumResults < mMaxSubShapeIndices);
  379. *mSubShapeIndices++ = inSubShapeIndex;
  380. mNumResults++;
  381. }
  382. /// Get the number of indices that were found
  383. JPH_INLINE int GetNumResults() const
  384. {
  385. return mNumResults;
  386. }
  387. private:
  388. BoxType mBox;
  389. uint * mSubShapeIndices;
  390. int mMaxSubShapeIndices;
  391. int mNumResults = 0;
  392. };
  393. JPH_NAMESPACE_END