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
9917 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
}
306
307
/// Returns true when collision detection should abort because it's not possible to find a better hit
308
JPH_INLINE bool ShouldAbort() const
309
{
310
return mCollector.ShouldEarlyOut();
311
}
312
313
/// Tests the bounds of shape 2 vs 4 bounding boxes, returns true for the ones that intersect
314
JPH_INLINE UVec4 TestBounds(Vec4Arg inBoundsMinX, Vec4Arg inBoundsMinY, Vec4Arg inBoundsMinZ, Vec4Arg inBoundsMaxX, Vec4Arg inBoundsMaxY, Vec4Arg inBoundsMaxZ) const
315
{
316
// Scale the bounding boxes
317
Vec4 bounds_min_x, bounds_min_y, bounds_min_z, bounds_max_x, bounds_max_y, bounds_max_z;
318
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);
319
320
// Test which boxes collide
321
return AABox4VsBox(mBoundsOf2InSpaceOf1, bounds_min_x, bounds_min_y, bounds_min_z, bounds_max_x, bounds_max_y, bounds_max_z);
322
}
323
324
/// Test the shape against a single subshape
325
JPH_INLINE void VisitShape(const SubShape &inSubShape, uint32 inSubShapeIndex)
326
{
327
// Get world transform of 1
328
Mat44 transform1 = mTransform1 * inSubShape.GetLocalTransformNoScale(mScale1);
329
330
// Create ID for sub shape
331
SubShapeIDCreator shape1_sub_shape_id = mSubShapeIDCreator1.PushID(inSubShapeIndex, mSubShapeBits);
332
333
CollisionDispatch::sCollideShapeVsShape(inSubShape.mShape, mShape2, inSubShape.TransformScale(mScale1), mScale2, transform1, mTransform2, shape1_sub_shape_id, mSubShapeIDCreator2, mCollideShapeSettings, mCollector, mShapeFilter);
334
}
335
336
const CollideShapeSettings & mCollideShapeSettings;
337
CollideShapeCollector & mCollector;
338
const Shape * mShape2;
339
Vec3 mScale1;
340
Vec3 mScale2;
341
Mat44 mTransform1;
342
Mat44 mTransform2;
343
AABox mBoundsOf2InSpaceOf1;
344
SubShapeIDCreator mSubShapeIDCreator1;
345
SubShapeIDCreator mSubShapeIDCreator2;
346
uint mSubShapeBits;
347
const ShapeFilter & mShapeFilter;
348
};
349
350
struct CompoundShape::CollideShapeVsCompoundVisitor
351
{
352
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) :
353
mCollideShapeSettings(inCollideShapeSettings),
354
mCollector(ioCollector),
355
mShape1(inShape1),
356
mScale1(inScale1),
357
mScale2(inScale2),
358
mTransform1(inCenterOfMassTransform1),
359
mTransform2(inCenterOfMassTransform2),
360
mSubShapeIDCreator1(inSubShapeIDCreator1),
361
mSubShapeIDCreator2(inSubShapeIDCreator2),
362
mSubShapeBits(inShape2->GetSubShapeIDBits()),
363
mShapeFilter(inShapeFilter)
364
{
365
// Get transform from shape 1 to shape 2
366
Mat44 transform1_to_2 = inCenterOfMassTransform2.InversedRotationTranslation() * inCenterOfMassTransform1;
367
368
// Convert bounding box of 1 into space of 2
369
mBoundsOf1InSpaceOf2 = inShape1->GetLocalBounds().Scaled(inScale1).Transformed(transform1_to_2);
370
mBoundsOf1InSpaceOf2.ExpandBy(Vec3::sReplicate(inCollideShapeSettings.mMaxSeparationDistance));
371
}
372
373
/// Returns true when collision detection should abort because it's not possible to find a better hit
374
JPH_INLINE bool ShouldAbort() const
375
{
376
return mCollector.ShouldEarlyOut();
377
}
378
379
/// Tests the bounds of shape 1 vs 4 bounding boxes, returns true for the ones that intersect
380
JPH_INLINE UVec4 TestBounds(Vec4Arg inBoundsMinX, Vec4Arg inBoundsMinY, Vec4Arg inBoundsMinZ, Vec4Arg inBoundsMaxX, Vec4Arg inBoundsMaxY, Vec4Arg inBoundsMaxZ) const
381
{
382
// Scale the bounding boxes
383
Vec4 bounds_min_x, bounds_min_y, bounds_min_z, bounds_max_x, bounds_max_y, bounds_max_z;
384
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);
385
386
// Test which bounding boxes collide
387
return AABox4VsBox(mBoundsOf1InSpaceOf2, bounds_min_x, bounds_min_y, bounds_min_z, bounds_max_x, bounds_max_y, bounds_max_z);
388
}
389
390
/// Test the shape against a single subshape
391
JPH_INLINE void VisitShape(const SubShape &inSubShape, uint32 inSubShapeIndex)
392
{
393
// Create ID for sub shape
394
SubShapeIDCreator shape2_sub_shape_id = mSubShapeIDCreator2.PushID(inSubShapeIndex, mSubShapeBits);
395
396
// Get world transform of 2
397
Mat44 transform2 = mTransform2 * inSubShape.GetLocalTransformNoScale(mScale2);
398
399
CollisionDispatch::sCollideShapeVsShape(mShape1, inSubShape.mShape, mScale1, inSubShape.TransformScale(mScale2), mTransform1, transform2, mSubShapeIDCreator1, shape2_sub_shape_id, mCollideShapeSettings, mCollector, mShapeFilter);
400
}
401
402
const CollideShapeSettings & mCollideShapeSettings;
403
CollideShapeCollector & mCollector;
404
const Shape * mShape1;
405
Vec3 mScale1;
406
Vec3 mScale2;
407
Mat44 mTransform1;
408
Mat44 mTransform2;
409
AABox mBoundsOf1InSpaceOf2;
410
SubShapeIDCreator mSubShapeIDCreator1;
411
SubShapeIDCreator mSubShapeIDCreator2;
412
uint mSubShapeBits;
413
const ShapeFilter & mShapeFilter;
414
};
415
416
template <class BoxType>
417
struct CompoundShape::GetIntersectingSubShapesVisitor
418
{
419
JPH_INLINE GetIntersectingSubShapesVisitor(const BoxType &inBox, uint *outSubShapeIndices, int inMaxSubShapeIndices) :
420
mBox(inBox),
421
mSubShapeIndices(outSubShapeIndices),
422
mMaxSubShapeIndices(inMaxSubShapeIndices)
423
{
424
}
425
426
/// Returns true when collision detection should abort because the buffer is full
427
JPH_INLINE bool ShouldAbort() const
428
{
429
return mNumResults >= mMaxSubShapeIndices;
430
}
431
432
/// Tests the box vs 4 bounding boxes, returns true for the ones that intersect
433
JPH_INLINE UVec4 TestBounds(Vec4Arg inBoundsMinX, Vec4Arg inBoundsMinY, Vec4Arg inBoundsMinZ, Vec4Arg inBoundsMaxX, Vec4Arg inBoundsMaxY, Vec4Arg inBoundsMaxZ) const
434
{
435
// Test which bounding boxes collide
436
return AABox4VsBox(mBox, inBoundsMinX, inBoundsMinY, inBoundsMinZ, inBoundsMaxX, inBoundsMaxY, inBoundsMaxZ);
437
}
438
439
/// Records a hit
440
JPH_INLINE void VisitShape([[maybe_unused]] const SubShape &inSubShape, uint32 inSubShapeIndex)
441
{
442
JPH_ASSERT(mNumResults < mMaxSubShapeIndices);
443
*mSubShapeIndices++ = inSubShapeIndex;
444
mNumResults++;
445
}
446
447
/// Get the number of indices that were found
448
JPH_INLINE int GetNumResults() const
449
{
450
return mNumResults;
451
}
452
453
private:
454
BoxType mBox;
455
uint * mSubShapeIndices;
456
int mMaxSubShapeIndices;
457
int mNumResults = 0;
458
};
459
460
JPH_NAMESPACE_END
461
462