UDocumentation UE5.7 10.02.2026 (Source)
API documentation for Unreal Engine 5.7
SimSweep.h
Go to the documentation of this file.
1// Copyright Epic Games, Inc. All Rights Reserved.
2#pragma once
3
8
9namespace Chaos
10{
11 namespace Private
12 {
18 {
19 public:
21 : HitParticle(nullptr)
22 {
23 }
24
25 void Init()
26 {
27 HitParticle = nullptr;
28 }
29
30 bool IsHit() const
31 {
32 return HitParticle != nullptr;
33 }
34
35 // The particle that we hit, or null
37
38 // The shape that we hit (or uninitialized)
40
41 // The geometry that we hit (or uninitialized)
43
44 // The contact position (or uninitialized)
46
47 // The contact normal for HitDistance >= 0, or MTD direction for HitDistance < 0 (or uninitialized)
49
50 // The normal of the face we hit, if HitFaceIndex is set (or uninitialized)
52
53 // The distance along the sweep at the hit, or the seperation if negative (i.e., -Penetration) (or uninitialized)
55
56 // Time of impact [0,1] (or uninitialized)
58
59 // The face index of the shape we hit, or INDEX_NONE (or uninitialized)
61 };
62
67 {
68 public:
72
73 // The particle that we hit, or null
75
76 // The shape that we hit (or uninitialized)
78
79 // The world-space transform of the geometry that was hit
81 };
82
86 template<typename TVisitor>
87 class TSimSweepSQVisitor : public ISpatialVisitor<FAccelerationStructureHandle, FReal>
88 {
89 public:
91
93 : Visitor(InVisitor)
94 {
95 }
96
97 virtual bool Overlap(const FVisitorData& Instance) override final
98 {
99 return CallVisitor(Instance);
100 }
101
102 virtual bool Sweep(const FVisitorData& Instance, FQueryFastData& CurData) override final
103 {
104 return CallVisitor(Instance);
105 }
106
107 virtual bool Raycast(const FVisitorData& Instance, FQueryFastData& CurData) override final
108 {
109 return CallVisitor(Instance);
110 }
111 private:
112 bool CallVisitor(const FVisitorData& Instance)
113 {
114 FGeometryParticleHandle* Particle = Instance.Payload.GetGeometryParticleHandle_PhysicsThread();
115 Visitor(Particle);
116 return true;
117 }
118
119 const TVisitor& Visitor;
120 };
121
131 template<typename TParticleFilter, typename TShapeFilter, typename TOverlapCollector>
134 const FAABB3& QueryBounds,
138 {
140
141 // Functor: Process a particle encountered by the overla through the spatial acceleration
142 const auto& ProcessParticle =
145 -> void
146 {
147 // Check the particle filter to see if we should process this particle pair
149 {
150 // The particle transform
151 const FRigidTransform3 OtherWorldTransform = OtherParticle->GetTransformXR();
152 for (const TUniquePtr<FPerShapeData>& OtherShape : OtherParticle->ShapesArray())
153 {
154 const FImplicitObject* OtherImplicit = OtherShape->GetLeafGeometry();
155
156 // Check the filter to see if we want to process this shape pair
158
159 if (bOverlapShape)
160 {
162
163 const bool bOverlapHit = OverlapQuery(
166 QueryBox,
167 FRigidTransform3::Identity,
168 0/*Thickness*/,
169 nullptr);
170
171 // If we have a hit, pass it to the collector
172 if (bOverlapHit)
173 {
176 Overlap.HitShape = OtherShape.Get();
177 Overlap.ShapeWorldTransform = OtherShapeWorldTransform;
178
180 }
181 }
182 }
183 }
184 };
185
186 // Generate the set of objects that overlap the bounds
188 SpatialAcceleration->Overlap(QueryBounds, SpatialAcclerationVisitor);
189 }
190
214 template<typename TShapeFilter, typename THitCollector>
218 const FVec3& StartPos,
219 const FRotation3& Rot,
220 const FVec3& Dir,
221 const FReal Length,
224 {
225 // The particle transforms
227 const FRigidTransform3 OtherWorldTransform = OtherParticle->GetTransformXR();
228
229 // Storage for the next hit result in the sweep (we only need one at a time)
232
233 // Visit all shape pairs and run a sweep (if they pass a filter check)
234 for (const TUniquePtr<FPerShapeData>& SweptShape : SweptParticle->ShapesArray())
235 {
236 const FImplicitObject* SweptImplicit = SweptShape->GetLeafGeometry();
238
239 for (const TUniquePtr<FPerShapeData>& OtherShape : OtherParticle->ShapesArray())
240 {
241 const FImplicitObject* OtherImplicit = OtherShape->GetLeafGeometry();
242
243 // Check the filter to see if we want to process this shape pair
245
246 if (bSweepShape)
247 {
249
250 const bool bSweepHit = SweepQuery(
255 Dir,
256 Length,
257 Hit.HitDistance,
258 Hit.HitPosition,
259 Hit.HitNormal,
260 Hit.HitFaceIndex,
261 Hit.HitFaceNormal,
262 0/*Thickness*/,
263 true/*bComputeMTD*/);
264
265 // If we have a hit, pass it to the collector
266 if (bSweepHit)
267 {
268 // Fill in the hit data that wasn't filled in by SweepQuery
269 Hit.HitTOI = (Hit.HitDistance > 0) ? (Hit.HitDistance / Length) : 0;
270
271 HitCollector(Dir, Length, Hit);
272 }
273 }
274 }
275 }
276 }
277
304 template<typename TParticleFilter, typename TShapeFilter, typename THitCollector>
308 const FVec3& StartPos,
309 const FRotation3& Rot,
310 const FVec3& Dir,
311 const FReal Length,
315 {
316 // Cannot sweep infinite particles (they are all static anyway)
317 if (!SweptParticle->HasBounds())
318 {
319 return;
320 }
321
322 // @todo(chaos): do we need to generate a hit for no sweep?
324 {
325 return;
326 }
327
328 // Functor: Process a particle encountered by the sweep through the spatial acceleration
329 // by sweeping all shapes of the swept particle against all shapes of the other particle.
330 const auto& ProcessParticlePair =
331 [SweptParticle, &StartPos, &Dir, &Length, &Rot, &ParticleFilter, &ShapeFilter, &HitCollector]
333 -> void
334 {
335 // We cannot hit ourself
337 {
338 // Check the particle filter to see if we should process this particle pair
340 {
341 // Do the sweep
343 }
344 }
345 };
346
347 // Calculate the ray start/end and extents for the spatial acceleration sweep
348 // (the sweep through the spatial acceleration requires a ray centered on the bounds)
349 const FAABB3 TransformedParticleBounds = SweptParticle->GetGeometry()->CalculateTransformedBounds(FRigidTransform3(StartPos, Rot));
350 const FVec3 BoundsExtents = FReal(0.5) * TransformedParticleBounds.Extents();
352
353 // Sweep our bounds through the spatial acceleration structure and then sweep the shapes of our particle
354 // against those of any particles that our bounds sweep encounters.
357 }
358
359
365 {
366 public:
371
376
377 private:
378 FIgnoreCollisionManager* IgnoreCollisionManager;
379 };
380
396
403 {
404 public:
417
421 bool operator()(const FVec3& Dir, const FReal Length, const FSimSweepParticleHit& InHit)
422 {
423 ProcessHit(Dir, Length, InHit);
424 return true;
425 }
426
427 void Init()
428 {
429 FirstHit.Init();
430 }
431
432 bool IsHit() const
433 {
434 return FirstHit.IsHit();
435 }
436
438 {
439 check(IsHit());
440 return FirstHit;
441 }
442
443 private:
444 void ProcessHit(const FVec3& Dir, const FReal Length, const FSimSweepParticleHit& InHit)
445 {
446 if (!FirstHit.IsHit() || (InHit.HitDistance < FirstHit.HitDistance + HitDistanceEqualTolerance))
447 {
448 // If the distance is very close to the existing hit, keep the one with the most opposing normal.
449 if (FirstHit.IsHit() && FMath::IsNearlyEqual(InHit.HitDistance, FirstHit.HitDistance))
450 {
451 const FReal ExistingDotNormal = FVec3::DotProduct(Dir, FirstHit.HitNormal);
452 const FReal NewDotNormal = FVec3::DotProduct(Dir, InHit.HitNormal);
454 {
455 FirstHit = InHit;
456 }
457 return;
458 }
459
460 // If this is a closer hit we will take it unless we are already moving out of contact.
461 // NOTE: we will only ever get an outward pointing normal for initial overlaps (HitDistance <= 0).
462 if ((InHit.HitDistance > 0) || (FVec3::DotProduct(InHit.HitNormal, Dir) < 0))
463 {
464 FirstHit = InHit;
465 return;
466 }
467 }
468 }
469
470 FSimSweepParticleHit& FirstHit;
471 FReal HitDistanceEqualTolerance;
472 };
473
494 extern bool SimSweepParticleFirstHit(
496 FIgnoreCollisionManager* IgnoreCollisionManager,
498 const FVec3& StartPos,
499 const FRotation3& Rot,
500 const FVec3& Dir,
501 const FReal Length,
502 FSimSweepParticleHit& OutHit,
504
509 extern bool SimOverlapBoundsAll(
511 const FAABB3& QueryBounds,
513 }
514
515}
#define check(expr)
Definition AssertionMacros.h:314
FPlatformTypes::int32 int32
A 32-bit signed integer.
Definition Platform.h:1125
UE_FORCEINLINE_HINT TSharedRef< CastToType, Mode > StaticCastSharedRef(TSharedRef< CastFromType, Mode > const &InSharedRef)
Definition SharedPointer.h:127
#define UE_SMALL_NUMBER
Definition UnrealMathUtility.h:130
#define UE_KINDA_SMALL_NUMBER
Definition UnrealMathUtility.h:131
Definition CollisionConstraintFlags.h:33
Definition ImplicitObject.h:111
Definition ShapeInstance.h:36
Definition ISpatialAcceleration.h:267
virtual void Overlap(const FAABB3 &QueryBounds, ISpatialVisitor< TPayloadType, FReal > &Visitor) const
Definition ISpatialAcceleration.h:298
virtual void Sweep(const FVec3 &Start, const FVec3 &Dir, const FReal Length, const FVec3 QueryHalfExtents, ISpatialVisitor< TPayloadType, FReal > &Visitor) const
Definition ISpatialAcceleration.h:297
Definition ISpatialAcceleration.h:120
FRigidTransform3 ShapeWorldTransform
Definition SimSweep.h:80
const FPerShapeData * HitShape
Definition SimSweep.h:77
FSimOverlapParticleShape()
Definition SimSweep.h:69
const FGeometryParticleHandle * HitParticle
Definition SimSweep.h:74
bool operator()(const FVec3 &Dir, const FReal Length, const FSimSweepParticleHit &InHit)
Definition SimSweep.h:421
FSimSweepCollectorFirstHit(const FReal InHitDistanceEqualTolerance, FSimSweepParticleHit &OutFirstHit)
Definition SimSweep.h:411
const FSimSweepParticleHit & GetFirstHit() const
Definition SimSweep.h:437
void Init()
Definition SimSweep.h:427
bool IsHit() const
Definition SimSweep.h:432
FSimSweepParticleFilterBroadPhase(FIgnoreCollisionManager *InIgnoreCollisionManager)
Definition SimSweep.h:367
bool operator()(const FGeometryParticleHandle *SweptParticle, const FGeometryParticleHandle *OtherParticle)
Definition SimSweep.h:372
Definition SimSweep.h:18
const FImplicitObject * HitGeometry
Definition SimSweep.h:42
FReal HitDistance
Definition SimSweep.h:54
const FPerShapeData * HitShape
Definition SimSweep.h:39
bool IsHit() const
Definition SimSweep.h:30
int32 HitFaceIndex
Definition SimSweep.h:60
FSimSweepParticleHit()
Definition SimSweep.h:20
FReal HitTOI
Definition SimSweep.h:57
FVec3 HitPosition
Definition SimSweep.h:45
FVec3 HitFaceNormal
Definition SimSweep.h:51
void Init()
Definition SimSweep.h:25
const FGeometryParticleHandle * HitParticle
Definition SimSweep.h:36
FVec3 HitNormal
Definition SimSweep.h:48
bool operator()(const FPerShapeData *SweptShape, const FImplicitObject *SweptImplicit, const FPerShapeData *OtherShape, const FImplicitObject *OtherImplicit)
Definition SimSweep.h:388
Definition SimSweep.h:88
TSpatialVisitorData< FAccelerationStructureHandle > FVisitorData
Definition SimSweep.h:90
virtual bool Overlap(const FVisitorData &Instance) override final
Definition SimSweep.h:97
TSimSweepSQVisitor(const TVisitor &InVisitor)
Definition SimSweep.h:92
virtual bool Sweep(const FVisitorData &Instance, FQueryFastData &CurData) override final
Definition SimSweep.h:102
virtual bool Raycast(const FVisitorData &Instance, FQueryFastData &CurData) override final
Definition SimSweep.h:107
Definition ParticleHandle.h:436
Definition Array.h:670
Definition UniquePtr.h:107
@ Unknown
Definition ImplicitObjectType.h:20
void SimSweepParticle(ISpatialAcceleration< FAccelerationStructureHandle, FReal, 3 > *SpatialAcceleration, const FGeometryParticleHandle *SweptParticle, const FVec3 &StartPos, const FRotation3 &Rot, const FVec3 &Dir, const FReal Length, TParticleFilter &ParticleFilter, TShapeFilter &ShapeFilter, THitCollector &HitCollector)
Definition SimSweep.h:305
void SimSweepParticlePair(const FGeometryParticleHandle *SweptParticle, const FGeometryParticleHandle *OtherParticle, const FVec3 &StartPos, const FRotation3 &Rot, const FVec3 &Dir, const FReal Length, TShapeFilter &ShapeFilter, THitCollector &HitCollector)
Definition SimSweep.h:215
void SimOverlapBounds(ISpatialAcceleration< FAccelerationStructureHandle, FReal, 3 > *SpatialAcceleration, const FAABB3 &QueryBounds, TParticleFilter &ParticleFilter, TShapeFilter &ShapeFilter, TOverlapCollector &OverlapCollector)
Definition SimSweep.h:132
bool SimOverlapBoundsAll(ISpatialAcceleration< FAccelerationStructureHandle, FReal, 3 > *SpatialAcceleration, const FAABB3 &QueryBounds, TArray< FSimOverlapParticleShape > &Overlaps)
Definition SimSweep.cpp:29
bool SimSweepParticleFirstHit(ISpatialAcceleration< FAccelerationStructureHandle, FReal, 3 > *SpatialAcceleration, FIgnoreCollisionManager *InIgnoreCollisionManager, const FGeometryParticleHandle *SweptParticle, const FVec3 &StartPos, const FRotation3 &Rot, const FVec3 &Dir, const FReal Length, FSimSweepParticleHit &OutHit, const FReal InHitDistanceEqualTolerance)
Definition SimSweep.cpp:9
Definition SkeletalMeshComponent.h:307
bool SweepQuery(const FImplicitObject &A, const FRigidTransform3 &ATM, const SweptGeometry &B, const FRigidTransform3 &BTM, const FVec3 &Dir, const FReal Length, FReal &OutTime, FVec3 &OutPosition, FVec3 &OutNormal, int32 &OutFaceIndex, FVec3 &OutFaceNormal, const FReal Thickness, const bool bComputeMTD)
Definition GeometryQueries.h:252
TRigidTransform< FReal, 3 > FRigidTransform3
Definition Core.h:22
uint8 EImplicitObjectType
Definition ImplicitObjectType.h:41
FRealDouble FReal
Definition Real.h:22
TRotation< FReal, 3 > FRotation3
Definition Core.h:19
TVector< FReal, 3 > FVec3
Definition Core.h:17
TGeometryParticleHandle< FReal, 3 > FGeometryParticleHandle
Definition ParticleHandleFwd.h:24
bool ParticlePairBroadPhaseFilter(const FGeometryParticleHandle *Particle1, const FGeometryParticleHandle *Particle2, const FIgnoreCollisionManager *IgnoreCollisionManager)
Definition CollisionFilter.h:22
bool OverlapQuery(const FImplicitObject &A, const FRigidTransform3 &ATM, const QueryGeometry &B, const FRigidTransform3 &BTM, const FReal Thickness=0, FMTDInfo *OutMTD=nullptr)
Definition GeometryQueries.h:34
bool ShapePairNarrowPhaseFilter(EImplicitObjectType Implicit0Type, const FPerShapeData *Shape0, EImplicitObjectType Implicit1Type, const FPerShapeData *Shape1)
Definition CollisionFilter.h:179
FORCEINLINE EImplicitObjectType GetInnerType(EImplicitObjectType Type)
Definition ImplicitObjectType.h:58
TAABB< FReal, 3 > FAABB3
Definition ImplicitObject.h:34
Definition OverriddenPropertySet.cpp:45
Definition ISpatialAcceleration.h:14
Definition ISpatialAcceleration.h:99
static UE_FORCEINLINE_HINT bool IsNearlyEqual(float A, float B, float ErrorTolerance=UE_SMALL_NUMBER)
Definition UnrealMathUtility.h:388