UDocumentation UE5.7 10.02.2026 (Source)
API documentation for Unreal Engine 5.7
PhysicsObjectCollisionInterface.h
Go to the documentation of this file.
1// Copyright Epic Games, Inc. All Rights Reserved.
2
3#pragma once
4
10
11namespace Chaos
12{
14 {
15 bool bSweepComplex = false;
16 bool bComputeMTD = false;
17 };
18
19 template<EThreadContext Id>
21 {
22 public:
26
27 // This function will not compute any overlap heuristic.
29
30 // Returns all the overlaps within A given a shape B.
31 template<typename TOverlapHit>
33 {
34 static_assert(std::is_same_v<TOverlapHit, ChaosInterface::TThreadOverlapHit<Id>>);
35 return PairwiseShapeOverlapHelper(
36 ObjectA,
38 ObjectB,
41 false,
43 [this, ObjectA, &OutOverlaps](const FShapeOverlapData& A, const FShapeOverlapData& B, const FMTDInfo&)
44 {
46 Overlap.Shape = A.Shape;
47 Overlap.Actor = Interface.GetParticle(ObjectA);
48 OutOverlaps.Add(Overlap);
49 return false;
50 }
51 );
52 }
53
54 // This function does the same as GetPhysicsObjectOverlap but also computes the MTD metric.
56
57 // This function does the same as GetPhysicsObjectOverlap but also computes the AABB overlap metric.
61
62 template<typename TRaycastHit>
64 {
65 static_assert(std::is_same_v<TRaycastHit, ChaosInterface::TThreadRaycastHit<Id>>);
66 bool bHit = false;
68
70 const FReal DeltaMag = Delta.Size();
71 if (DeltaMag < UE_KINDA_SMALL_NUMBER)
72 {
73 return false;
74 }
75
77
79 {
80 const FTransform WorldTM = Interface.GetTransform(Object);
81 const FVector LocalStart = WorldTM.InverseTransformPositionNoScale(WorldStart);
82 const FVector LocalDelta = WorldTM.InverseTransformVectorNoScale(Delta);
83
84 Interface.VisitEveryShape(
85 { &Object, 1 },
87 {
88 check(Shape);
89
90 FCollisionFilterData ShapeFilter = Shape->GetQueryData();
91 const bool bShapeIsComplex = (ShapeFilter.Word3 & static_cast<uint8>(EFilterFlags::ComplexCollision)) != 0;
92 const bool bShapeIsSimple = (ShapeFilter.Word3 & static_cast<uint8>(EFilterFlags::SimpleCollision)) != 0;
94 {
96 FVec3 LocalPosition;
99
100 const bool bRaycastHit = Shape->GetGeometry()->Raycast(
101 LocalStart,
102 LocalDelta / DeltaMag,
103 DeltaMag,
104 0,
105 Distance,
106 LocalPosition,
109 );
110
111 if (bRaycastHit)
112 {
113 if (Distance < OutBestHit.Distance)
114 {
115 bHit = true;
117 OutBestHit.Distance = static_cast<float>(Distance);
118 OutBestHit.WorldNormal = LocalNormal;
119 OutBestHit.WorldPosition = LocalPosition;
120 OutBestHit.Shape = Shape;
121 OutBestHit.Actor = Interface.GetParticle(IterObject);
122 OutBestHit.FaceIndex = FaceIndex;
123 }
124 }
125 }
126 return false;
127 }
128 );
129 }
130
131 if (bHit)
132 {
133 OutBestHit.WorldNormal = BestWorldTM.TransformVectorNoScale(OutBestHit.WorldNormal);
134 OutBestHit.WorldPosition = BestWorldTM.TransformPositionNoScale(OutBestHit.WorldPosition);
135 }
136
137 return bHit;
138 }
139
140 template<typename TOverlapHit>
145
146 template<typename TOverlapHit>
148 {
149 static_assert(std::is_same_v<TOverlapHit, ChaosInterface::TThreadOverlapHit<Id>>);
150 bool bHasOverlap = false;
152 {
153 const FTransform WorldTM = Interface.GetTransform(Object);
154
155 Interface.VisitEveryShape(
156 { &Object, 1 },
158 {
159 check(Shape);
161 InGeom,
163 [Shape, &WorldTM, MTD](const auto& Downcast, const auto& FullTransformB)
164 {
165 return Chaos::OverlapQuery(*Shape->GetGeometry(), WorldTM, Downcast, FullTransformB, 0, MTD);
166 }
167 );
168
169 if (bOverlap)
170 {
171 bHasOverlap = true;
172
174 Overlap.Shape = Shape;
175 Overlap.Actor = Interface.GetParticle(IterObject);
176 OutOverlaps.Add(Overlap);
177 }
178 return false;
179 }
180 );
181 }
182 return bHasOverlap;
183 }
184
185 template<typename TSweepHit>
187 {
188 static_assert(std::is_same_v<TSweepHit, ChaosInterface::TThreadSweepHit<Id>>);
189 bool bHit = false;
190 const FVector StartPos = StartTM.GetTranslation();
191 const FVector Delta = EndPos - StartPos;
192 const FReal DeltaMag = Delta.Size();
193
194 const bool bSweepHasLength = DeltaMag > 0.f;
195 const FVector Dir = bSweepHasLength ? (Delta / DeltaMag) : FVector(1, 0, 0);
196
199 {
200 const FTransform WorldTM = Interface.GetTransform(Object);
201
202 Interface.VisitEveryShape(
203 { &Object, 1 },
204 [this, &WorldTM, &InGeom, &StartTM, &bHit, &Delta, DeltaMag, &Dir, &OutBestHit, &Params](const FConstPhysicsObjectHandle IterObject, TThreadShapeInstance<Id>* Shape)
205 {
206 check(Shape);
207
208 FCollisionFilterData ShapeFilter = Shape->GetQueryData();
209 const bool bShapeIsComplex = (ShapeFilter.Word3 & static_cast<uint8>(EFilterFlags::ComplexCollision)) != 0;
210 const bool bShapeIsSimple = (ShapeFilter.Word3 & static_cast<uint8>(EFilterFlags::SimpleCollision)) != 0;
211 if ((Params.bSweepComplex && bShapeIsComplex) || (!Params.bSweepComplex && bShapeIsSimple))
212 {
214 FVec3 WorldNormal;
216 int32 FaceIdx;
217 FVec3 FaceNormal;
218
220 InGeom,
221 StartTM,
222 [Shape, &WorldTM, &Dir, DeltaMag, &Distance, &WorldPosition, &WorldNormal, &FaceIdx, &FaceNormal, &Params](const auto& Downcast, const auto& FullTransformB)
223 {
224 // Set bComputeMTD to true to better match internal SQ Visitor behavior.
225 return Chaos::SweepQuery(*Shape->GetGeometry(), WorldTM, Downcast, FullTransformB, Dir, DeltaMag, Distance, WorldPosition, WorldNormal, FaceIdx, FaceNormal, 0.f, Params.bComputeMTD);
226 }
227 );
228
229 const float FloatDistance = static_cast<float>(Distance);
230 if (bShapeHit && FloatDistance < OutBestHit.Distance)
231 {
232 bHit = true;
233
234 OutBestHit.Shape = Shape;
235 OutBestHit.WorldPosition = WorldPosition;
236 OutBestHit.WorldNormal = WorldNormal;
237 OutBestHit.Distance = FloatDistance;
238 OutBestHit.FaceIndex = FaceIdx;
239 OutBestHit.FaceNormal = FaceNormal;
240
241 // Always compute the best face index. This used to check for non-initial overlap hits, however there's no reason to do that as we should always have valid data.
242 const FVector LocalPosition = WorldTM.InverseTransformPositionNoScale(OutBestHit.WorldPosition);
243 const FVector LocalUnitDir = WorldTM.InverseTransformVectorNoScale(Dir);
244 OutBestHit.FaceIndex = Shape->GetGeometry()->FindMostOpposingFace(LocalPosition, LocalUnitDir, OutBestHit.FaceIndex, 1);
245
246 OutBestHit.Actor = Interface.GetParticle(IterObject);
247 }
248 }
249 return false;
250 }
251 );
252
253 // Previously, when a zero length sweep was performed, normal was scaled by the penetration.
254 // This preserves that old behavior until we determine if this is needed.
255 if (bHit && !bSweepHasLength)
256 {
257 OutBestHit.WorldNormal = OutBestHit.WorldNormal * -OutBestHit.Distance;
258 }
259 }
260 return bHit;
261 }
262
263
264 private:
266
267 struct FShapeOverlapData
268 {
271 };
272
276 CHAOS_API bool PairwiseShapeOverlapHelper(const FConstPhysicsObjectHandle ObjectA, const FTransform& InTransformA, const FConstPhysicsObjectHandle ObjectB, const FTransform& InTransformB, bool bTraceComplex, bool bComputeMTD, const FVector& Tolerance, const TFunction<bool(const FShapeOverlapData&, const FShapeOverlapData&, const FMTDInfo&)>& Lambda);
277 };
278
281}
#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 FVector
Definition IOSSystemIncludes.h:8
const bool bTraceComplex
Definition PhysicsInterfaceUtils.h:19
#define UE_KINDA_SMALL_NUMBER
Definition UnrealMathUtility.h:131
uint8_t uint8
Definition binka_ue_file_header.h:8
Definition ImplicitObject.h:111
Definition PhysicsObjectCollisionInterface.h:21
CHAOS_API bool PhysicsObjectOverlap(const FConstPhysicsObjectHandle ObjectA, const FTransform &InTransformA, const FConstPhysicsObjectHandle ObjectB, const FTransform &InTransformB, bool bTraceComplex)
Definition PhysicsObjectCollisionInterface.cpp:7
CHAOS_API bool PhysicsObjectOverlapWithAABBSize(const FConstPhysicsObjectHandle ObjectA, const FTransform &InTransformA, const FConstPhysicsObjectHandle ObjectB, const FTransform &InTransformB, bool bTraceComplex, const FVector &Tolerance, FVector &OutOverlapSize)
Definition PhysicsObjectCollisionInterface.cpp:60
bool LineTrace(TArrayView< const FConstPhysicsObjectHandle > InObjects, const FVector &WorldStart, const FVector &WorldEnd, bool bTraceComplex, TRaycastHit &OutBestHit)
Definition PhysicsObjectCollisionInterface.h:63
FPhysicsObjectCollisionInterface(FReadPhysicsObjectInterface< Id > &InInterface)
Definition PhysicsObjectCollisionInterface.h:23
CHAOS_API bool PhysicsObjectOverlapWithAABBIntersections(const FConstPhysicsObjectHandle ObjectA, const FTransform &InTransformA, const FConstPhysicsObjectHandle ObjectB, const FTransform &InTransformB, bool bTraceComplex, const FVector &Tolerance, TArray< FBox > &Intersections)
Definition PhysicsObjectCollisionInterface.cpp:82
bool ShapeSweep(TArrayView< const FConstPhysicsObjectHandle > InObjects, const Chaos::FImplicitObject &InGeom, const FTransform &StartTM, const FVector &EndPos, const FSweepParameters &Params, TSweepHit &OutBestHit)
Definition PhysicsObjectCollisionInterface.h:186
bool ShapeOverlap(TArrayView< const FConstPhysicsObjectHandle > InObjects, const Chaos::FImplicitObject &InGeom, const FTransform &GeomTransform, TArray< TOverlapHit > &OutOverlaps)
Definition PhysicsObjectCollisionInterface.h:141
bool PhysicsObjectOverlap(const FConstPhysicsObjectHandle ObjectA, const FTransform &InTransformA, const FConstPhysicsObjectHandle ObjectB, const FTransform &InTransformB, bool bTraceComplex, TArray< TOverlapHit > &OutOverlaps)
Definition PhysicsObjectCollisionInterface.h:32
CHAOS_API bool PhysicsObjectOverlapWithMTD(const FConstPhysicsObjectHandle ObjectA, const FTransform &InTransformA, const FConstPhysicsObjectHandle ObjectB, const FTransform &InTransformB, bool bTraceComplex, FMTDInfo &OutMTD)
Definition PhysicsObjectCollisionInterface.cpp:14
bool ShapeOverlapWithMTD(TArrayView< const FConstPhysicsObjectHandle > InObjects, const Chaos::FImplicitObject &InGeom, const FTransform &GeomTransform, TArray< TOverlapHit > &OutOverlaps, FMTDInfo *MTD)
Definition PhysicsObjectCollisionInterface.h:147
CHAOS_API bool PhysicsObjectOverlapWithAABB(const FConstPhysicsObjectHandle ObjectA, const FTransform &InTransformA, const FConstPhysicsObjectHandle ObjectB, const FTransform &InTransformB, bool bTraceComplex, const FVector &Tolerance, FBox &OutOverlap)
Definition PhysicsObjectCollisionInterface.cpp:38
Definition PhysicsObjectInterface.h:55
Definition ArrayView.h:139
Definition Array.h:670
UE_NODEBUG UE_FORCEINLINE_HINT SizeType Add(ElementType &&Item)
Definition Array.h:2696
Definition AndroidPlatformMisc.h:14
FORCEINLINE_DEBUGGABLE decltype(auto) CastHelper(const FImplicitObject &Geom, const Lambda &Func)
Definition CastingUtilities.h:21
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
FRealDouble FReal
Definition Real.h:22
const FPhysicsObject * FConstPhysicsObjectHandle
Definition PhysicsObject.h:19
std::conditional_t< Id==EThreadContext::External, FShapeInstanceProxy, FShapeInstance > TThreadShapeInstance
Definition ShapeInstanceFwd.h:33
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
Definition GeometryQueries.h:27
Definition PhysicsObjectInternal.h:16
Definition PhysicsObjectCollisionInterface.h:14
bool bComputeMTD
Definition PhysicsObjectCollisionInterface.h:16
bool bSweepComplex
Definition PhysicsObjectCollisionInterface.h:15
Definition CollisionFilterData.h:46
Definition NumericLimits.h:41
static CORE_API const TTransform< double > Identity
Definition TransformNonVectorized.h:58
TVector< T > GetTranslation() const
Definition TransformNonVectorized.h:1120
static TVector< double > Zero()
Definition Vector.h:112
T Size() const
Definition Vector.h:1716