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