CompoundShapeVisitors.h 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463
  1. // SPDX-FileCopyrightText: 2021 Jorrit Rouwe
  2. // SPDX-License-Identifier: MIT
  3. #pragma once
  4. #include <Physics/Collision/Shape/CompoundShape.h>
  5. #include <Physics/Collision/Shape/SubShapeID.h>
  6. #include <Physics/Collision/RayCast.h>
  7. #include <Physics/Collision/CastResult.h>
  8. #include <Physics/Collision/ShapeCast.h>
  9. #include <Physics/Collision/TransformedShape.h>
  10. #include <Physics/Collision/CollisionDispatch.h>
  11. #include <Geometry/RayAABox.h>
  12. #include <Geometry/AABox4.h>
  13. #include <Geometry/OrientedBox.h>
  14. namespace JPH {
  15. struct CompoundShape::CastRayVisitor
  16. {
  17. JPH_INLINE CastRayVisitor(const RayCast &inRay, const CompoundShape *inShape, const SubShapeIDCreator &inSubShapeIDCreator, RayCastResult &ioHit) :
  18. mRay(inRay),
  19. mHit(ioHit),
  20. mSubShapeIDCreator(inSubShapeIDCreator)
  21. {
  22. // Determine ray properties of cast
  23. mInvDirection.Set(inRay.mDirection);
  24. // Determine amount of bits for sub shape
  25. mSubShapeBits = inShape->GetSubShapeIDBits();
  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) :
  58. mRay(inRay),
  59. mCollector(ioCollector),
  60. mSubShapeIDCreator(inSubShapeIDCreator),
  61. mRayCastSettings(inRayCastSettings)
  62. {
  63. // Determine ray properties of cast
  64. mInvDirection.Set(inRay.mDirection);
  65. // Determine amount of bits for sub shape
  66. mSubShapeBits = inShape->GetSubShapeIDBits();
  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);
  87. }
  88. RayInvDirection mInvDirection;
  89. const RayCast & mRay;
  90. CastRayCollector & mCollector;
  91. SubShapeIDCreator mSubShapeIDCreator;
  92. uint mSubShapeBits;
  93. RayCastSettings mRayCastSettings;
  94. };
  95. struct CompoundShape::CollidePointVisitor
  96. {
  97. JPH_INLINE CollidePointVisitor(Vec3Arg inPoint, const CompoundShape *inShape, const SubShapeIDCreator &inSubShapeIDCreator, CollidePointCollector &ioCollector) :
  98. mPoint(inPoint),
  99. mSubShapeIDCreator(inSubShapeIDCreator),
  100. mCollector(ioCollector)
  101. {
  102. // Determine amount of bits for sub shape
  103. mSubShapeBits = inShape->GetSubShapeIDBits();
  104. }
  105. /// Returns true when collision detection should abort because it's not possible to find a better hit
  106. JPH_INLINE bool ShouldAbort() const
  107. {
  108. return mCollector.ShouldEarlyOut();
  109. }
  110. /// Test if point overlaps with 4 boxes, returns true for the ones that do
  111. JPH_INLINE UVec4 TestBounds(Vec4Arg inBoundsMinX, Vec4Arg inBoundsMinY, Vec4Arg inBoundsMinZ, Vec4Arg inBoundsMaxX, Vec4Arg inBoundsMaxY, Vec4Arg inBoundsMaxZ) const
  112. {
  113. return AABox4VsPoint(mPoint, inBoundsMinX, inBoundsMinY, inBoundsMinZ, inBoundsMaxX, inBoundsMaxY, inBoundsMaxZ);
  114. }
  115. /// Test the point against a single subshape
  116. JPH_INLINE void VisitShape(const SubShape &inSubShape, uint32 inSubShapeIndex)
  117. {
  118. // Create ID for sub shape
  119. SubShapeIDCreator shape2_sub_shape_id = mSubShapeIDCreator.PushID(inSubShapeIndex, mSubShapeBits);
  120. // Transform the point
  121. Mat44 transform = Mat44::sInverseRotationTranslation(inSubShape.GetRotation(), inSubShape.GetPositionCOM());
  122. inSubShape.mShape->CollidePoint(transform * mPoint, shape2_sub_shape_id, mCollector);
  123. }
  124. Vec3 mPoint;
  125. SubShapeIDCreator mSubShapeIDCreator;
  126. CollidePointCollector & mCollector;
  127. uint mSubShapeBits;
  128. };
  129. struct CompoundShape::CastShapeVisitor
  130. {
  131. 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) :
  132. mScale(inScale),
  133. mShapeCast(inShapeCast),
  134. mShapeCastSettings(inShapeCastSettings),
  135. mShapeFilter(inShapeFilter),
  136. mCollector(ioCollector),
  137. mCenterOfMassTransform2(inCenterOfMassTransform2),
  138. mSubShapeIDCreator1(inSubShapeIDCreator1),
  139. mSubShapeIDCreator2(inSubShapeIDCreator2)
  140. {
  141. // Determine ray properties of cast
  142. mInvDirection.Set(inShapeCast.mDirection);
  143. // Determine bounding box of cast shape
  144. mBoxCenter = inShapeCast.mShapeWorldBounds.GetCenter();
  145. mBoxExtent = inShapeCast.mShapeWorldBounds.GetExtent();
  146. // Determine amount of bits for sub shape
  147. mSubShapeBits = inShape->GetSubShapeIDBits();
  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::sCastShapeVsShape(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) :
  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. {
  203. // Determine amount of bits for sub shape
  204. mSubShapeBits = inShape->GetSubShapeIDBits();
  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);
  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. };
  241. struct CompoundShape::CollideCompoundVsShapeVisitor
  242. {
  243. 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) :
  244. mCollideShapeSettings(inCollideShapeSettings),
  245. mCollector(ioCollector),
  246. mShape2(inShape2),
  247. mScale1(inScale1),
  248. mScale2(inScale2),
  249. mTransform1(inCenterOfMassTransform1),
  250. mTransform2(inCenterOfMassTransform2),
  251. mSubShapeIDCreator1(inSubShapeIDCreator1),
  252. mSubShapeIDCreator2(inSubShapeIDCreator2)
  253. {
  254. // Get transform from shape 2 to shape 1
  255. Mat44 transform2_to_1 = inCenterOfMassTransform1.InversedRotationTranslation() * inCenterOfMassTransform2;
  256. // Convert bounding box of 2 into space of 1
  257. mBoundsOf2InSpaceOf1 = inShape2->GetLocalBounds().Scaled(inScale2).Transformed(transform2_to_1);
  258. // Determine amount of bits for sub shape
  259. mSubShapeBits = inShape1->GetSubShapeIDBits();
  260. }
  261. /// Returns true when collision detection should abort because it's not possible to find a better hit
  262. JPH_INLINE bool ShouldAbort() const
  263. {
  264. return mCollector.ShouldEarlyOut();
  265. }
  266. /// Tests the bounds of shape 2 vs 4 bounding boxes, returns true for the ones that intersect
  267. JPH_INLINE UVec4 TestBounds(Vec4Arg inBoundsMinX, Vec4Arg inBoundsMinY, Vec4Arg inBoundsMinZ, Vec4Arg inBoundsMaxX, Vec4Arg inBoundsMaxY, Vec4Arg inBoundsMaxZ) const
  268. {
  269. // Scale the bounding boxes
  270. Vec4 bounds_min_x, bounds_min_y, bounds_min_z, bounds_max_x, bounds_max_y, bounds_max_z;
  271. 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);
  272. // Test which boxes collide
  273. return AABox4VsBox(mBoundsOf2InSpaceOf1, bounds_min_x, bounds_min_y, bounds_min_z, bounds_max_x, bounds_max_y, bounds_max_z);
  274. }
  275. /// Test the shape against a single subshape
  276. JPH_INLINE void VisitShape(const SubShape &inSubShape, uint32 inSubShapeIndex)
  277. {
  278. // Get world transform of 1
  279. Mat44 transform1 = mTransform1 * inSubShape.GetLocalTransformNoScale(mScale1);
  280. // Create ID for sub shape
  281. SubShapeIDCreator shape1_sub_shape_id = mSubShapeIDCreator1.PushID(inSubShapeIndex, mSubShapeBits);
  282. CollisionDispatch::sCollideShapeVsShape(inSubShape.mShape, mShape2, inSubShape.TransformScale(mScale1), mScale2, transform1, mTransform2, shape1_sub_shape_id, mSubShapeIDCreator2, mCollideShapeSettings, mCollector);
  283. }
  284. const CollideShapeSettings & mCollideShapeSettings;
  285. CollideShapeCollector & mCollector;
  286. const Shape * mShape2;
  287. Vec3 mScale1;
  288. Vec3 mScale2;
  289. Mat44 mTransform1;
  290. Mat44 mTransform2;
  291. AABox mBoundsOf2InSpaceOf1;
  292. SubShapeIDCreator mSubShapeIDCreator1;
  293. SubShapeIDCreator mSubShapeIDCreator2;
  294. uint mSubShapeBits;
  295. };
  296. struct CompoundShape::CollideShapeVsCompoundVisitor
  297. {
  298. 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) :
  299. mCollideShapeSettings(inCollideShapeSettings),
  300. mCollector(ioCollector),
  301. mShape1(inShape1),
  302. mScale1(inScale1),
  303. mScale2(inScale2),
  304. mTransform1(inCenterOfMassTransform1),
  305. mTransform2(inCenterOfMassTransform2),
  306. mSubShapeIDCreator1(inSubShapeIDCreator1),
  307. mSubShapeIDCreator2(inSubShapeIDCreator2)
  308. {
  309. // Get transform from shape 1 to shape 2
  310. Mat44 transform1_to_2 = inCenterOfMassTransform2.InversedRotationTranslation() * inCenterOfMassTransform1;
  311. // Convert bounding box of 1 into space of 2
  312. mBoundsOf1InSpaceOf2 = inShape1->GetLocalBounds().Scaled(inScale1).Transformed(transform1_to_2);
  313. mBoundsOf1InSpaceOf2.ExpandBy(Vec3::sReplicate(inCollideShapeSettings.mMaxSeparationDistance));
  314. // Determine amount of bits for sub shape
  315. mSubShapeBits = inShape2->GetSubShapeIDBits();
  316. }
  317. /// Returns true when collision detection should abort because it's not possible to find a better hit
  318. JPH_INLINE bool ShouldAbort() const
  319. {
  320. return mCollector.ShouldEarlyOut();
  321. }
  322. /// Tests the bounds of shape 1 vs 4 bounding boxes, returns true for the ones that intersect
  323. JPH_INLINE UVec4 TestBounds(Vec4Arg inBoundsMinX, Vec4Arg inBoundsMinY, Vec4Arg inBoundsMinZ, Vec4Arg inBoundsMaxX, Vec4Arg inBoundsMaxY, Vec4Arg inBoundsMaxZ) const
  324. {
  325. // Scale the bounding boxes
  326. Vec4 bounds_min_x, bounds_min_y, bounds_min_z, bounds_max_x, bounds_max_y, bounds_max_z;
  327. 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);
  328. // Test which bounding boxes collide
  329. return AABox4VsBox(mBoundsOf1InSpaceOf2, bounds_min_x, bounds_min_y, bounds_min_z, bounds_max_x, bounds_max_y, bounds_max_z);
  330. }
  331. /// Test the shape against a single subshape
  332. JPH_INLINE void VisitShape(const SubShape &inSubShape, uint32 inSubShapeIndex)
  333. {
  334. // Create ID for sub shape
  335. SubShapeIDCreator shape2_sub_shape_id = mSubShapeIDCreator2.PushID(inSubShapeIndex, mSubShapeBits);
  336. // Get world transform of 2
  337. Mat44 transform2 = mTransform2 * inSubShape.GetLocalTransformNoScale(mScale2);
  338. CollisionDispatch::sCollideShapeVsShape(mShape1, inSubShape.mShape, mScale1, inSubShape.TransformScale(mScale2), mTransform1, transform2, mSubShapeIDCreator1, shape2_sub_shape_id, mCollideShapeSettings, mCollector);
  339. }
  340. const CollideShapeSettings & mCollideShapeSettings;
  341. CollideShapeCollector & mCollector;
  342. const Shape * mShape1;
  343. Vec3 mScale1;
  344. Vec3 mScale2;
  345. Mat44 mTransform1;
  346. Mat44 mTransform2;
  347. AABox mBoundsOf1InSpaceOf2;
  348. SubShapeIDCreator mSubShapeIDCreator1;
  349. SubShapeIDCreator mSubShapeIDCreator2;
  350. uint mSubShapeBits;
  351. };
  352. template <class BoxType>
  353. struct CompoundShape::GetIntersectingSubShapesVisitor
  354. {
  355. JPH_INLINE GetIntersectingSubShapesVisitor(const BoxType &inBox, uint *outSubShapeIndices, int inMaxSubShapeIndices) :
  356. mBox(inBox),
  357. mSubShapeIndices(outSubShapeIndices),
  358. mMaxSubShapeIndices(inMaxSubShapeIndices)
  359. {
  360. }
  361. /// Returns true when collision detection should abort because the buffer is full
  362. JPH_INLINE bool ShouldAbort() const
  363. {
  364. return mNumResults >= mMaxSubShapeIndices;
  365. }
  366. /// Tests the box vs 4 bounding boxes, returns true for the ones that intersect
  367. JPH_INLINE UVec4 TestBounds(Vec4Arg inBoundsMinX, Vec4Arg inBoundsMinY, Vec4Arg inBoundsMinZ, Vec4Arg inBoundsMaxX, Vec4Arg inBoundsMaxY, Vec4Arg inBoundsMaxZ) const
  368. {
  369. // Test which bounding boxes collide
  370. return AABox4VsBox(mBox, inBoundsMinX, inBoundsMinY, inBoundsMinZ, inBoundsMaxX, inBoundsMaxY, inBoundsMaxZ);
  371. }
  372. /// Records a hit
  373. JPH_INLINE void VisitShape(const SubShape &inSubShape, uint32 inSubShapeIndex)
  374. {
  375. JPH_ASSERT(mNumResults < mMaxSubShapeIndices);
  376. *mSubShapeIndices++ = inSubShapeIndex;
  377. mNumResults++;
  378. }
  379. /// Get the number of indices that were found
  380. JPH_INLINE int GetNumResults() const
  381. {
  382. return mNumResults;
  383. }
  384. private:
  385. BoxType mBox;
  386. uint * mSubShapeIndices;
  387. int mMaxSubShapeIndices;
  388. int mNumResults = 0;
  389. };
  390. } // JPH