UDocumentation UE5.7 10.02.2026 (Source)
API documentation for Unreal Engine 5.7
ImplicitObjectTransformed.h
Go to the documentation of this file.
1// Copyright Epic Games, Inc. All Rights Reserved.
2#pragma once
3
4#include "Chaos/Box.h"
7#include "Chaos/Transform.h"
8#include "ChaosArchive.h"
10#include "Chaos/AABB.h"
11
12namespace Chaos
13{
14
19
24
26{
27 check(false);
28}
29
35template<class T, int d, bool bSerializable = true>
37{
39 using ObjectType = typename FStorage::PtrType;
40
41public:
43
44 UE_DEPRECATED(5.4, "Constructor no longer in use")
46 : FImplicitObject(EImplicitObject::HasBoundingBox, ImplicitObjectType::Transformed)
47 {
48 check(false);
49 }
50
55 : FImplicitObject(EImplicitObject::HasBoundingBox, ImplicitObjectType::Transformed)
56 , MObject(MoveTemp(Object))
57 , MTransform(InTransform)
58 {
59 this->MLocalBoundingBox = MObject->BoundingBox().TransformedAABB(InTransform);
60 this->bIsConvex = MObject->IsConvex();
61 this->bDoCollide = MObject->GetDoCollide();
62 }
63
68 : FImplicitObject(EImplicitObject::HasBoundingBox, ImplicitObjectType::Transformed)
69 , MObject(Object)
70 , MTransform(InTransform)
71 {
72 this->MLocalBoundingBox = MObject->BoundingBox().TransformedAABB(InTransform);
73 this->bIsConvex = MObject->IsConvex();
74 this->bDoCollide = MObject->GetDoCollide();
75 }
76
79 : FImplicitObject(EImplicitObject::HasBoundingBox, ImplicitObjectType::Transformed)
80 , MObject(Other.MObject)
81 , MTransform(Other.MTransform)
82 , MLocalBoundingBox(MoveTemp(Other.MLocalBoundingBox))
83 {
84 this->bIsConvex = Other.MObject->IsConvex();
85 this->bDoCollide = Other.MObject->GetDoCollide();
86 }
87
88
89 virtual EImplicitObjectType GetNestedType() const override
90 {
91 return MObject->GetNestedType();
92 }
93
95 {
96 // shallow copying this just requires a copy of the pointer, which is just "this" which will convert into TRefCountPtr<FImplicitObject>
97 // const_cast required here as the invasive ref count needs to be mutated
98 return const_cast<TImplicitObjectTransformed*>(this);
99 }
100
102 {
103 // This is a deep copy - we can't take a shallow copy of this and apply the scale without modifying all other instances
104 if(MObject)
105 {
106 //return MakeCopyWithScaleTransformed(MObjectOwner, MTransform, Scale);
107 // since we cannot have a { Scaled -- Transformed -- Shape } ( scaled can only directly reference concrete shapes )
108 // we need to scale the transform translation and set the Scaled on the shape itself like { (Adjusted)Transformed -- Scaled -- Shape }
110 AdjustedTransform.ScaleTranslation(Scale);
111
112 Chaos::FImplicitObjectPtr ScaledObject(MObject->CopyGeometryWithScale(Scale));
114 }
115 else
116 {
117 check(false);
118 return nullptr;
119 }
120 }
121
123 {
124 // Deep copy both the transformed wrapper, and the inner object
125 if(MObject)
126 {
127 Chaos::FImplicitObjectPtr ObjectCopy(MObject->DeepCopyGeometry());
129 }
130 else
131 {
132 check(false);
133 return nullptr;
134 }
135 }
136
138 {
139 if(MObject)
140 {
141 //return MakeCopyWithScaleTransformed(MObjectOwner, MTransform, Scale);
142 // since we cannot have a { Scaled -- Transformed -- Shape } ( scaled can only directly reference concrete shapes )
143 // we need to scale the transform translation and set the Scaled on the shape itself like { (Adjusted)Transformed -- Scaled -- Shape }
145 AdjustedTransform.ScaleTranslation(Scale);
146
147 Chaos::FImplicitObjectPtr ScaledObject(MObject->DeepCopyGeometryWithScale(Scale));
149 }
150 else
151 {
152 check(false);
153 return nullptr;
154 }
155 }
156
158
160 {
162 }
163
165 {
166 return MObject.GetReference();
167 }
168
169 virtual FReal GetMargin() const override
170 {
171 // If the inner shape is quadratic, we have no margin
172 return (MObject->GetRadiusf() > 0.0f) ? 0.0f : Margin;
173 }
174
175 virtual FReal GetRadius() const override
176 {
177 // If the inner shape is quadratic, so are we
178 return (MObject->GetRadiusf() > 0.0f) ? Margin : 0.0f;
179 }
180
181 bool GetDoCollide() const
182 {
183 return MObject->GetDoCollide();
184 }
185
186 virtual T PhiWithNormal(const TVector<T, d>& x, TVector<T, d>& Normal) const override
187 {
188 auto TransformedX = MTransform.InverseTransformPosition(x);
189 auto Phi = MObject->PhiWithNormal(TransformedX, Normal);
190 Normal = MTransform.TransformVector(Normal);
191 return Phi;
192 }
193
194 virtual bool Raycast(const TVector<T, d>& StartPoint, const TVector<T, d>& Dir, const T Length, const T Thickness, T& OutTime, TVector<T, d>& OutPosition, TVector<T, d>& OutNormal, int32& OutFaceIndex) const override
195 {
196 const TVector<T, d> LocalStart = MTransform.InverseTransformPosition(StartPoint);
197 const TVector<T, d> LocalDir = MTransform.InverseTransformVector(Dir);
198 TVector<T, d> LocalPosition;
200
201 if (MObject->Raycast(LocalStart, LocalDir, Length, Thickness, OutTime, LocalPosition, LocalNormal, OutFaceIndex))
202 {
203 if (OutTime != 0.0f)
204 {
205 OutPosition = MTransform.TransformPosition(LocalPosition);
206 OutNormal = MTransform.TransformVector(LocalNormal);
207 }
208 return true;
209 }
210
211 return false;
212 }
213
215 {
216 const TVector<T, d> LocalPosition = MTransform.InverseTransformPositionNoScale(Position);
217 const TVector<T, d> LocalDir = MTransform.InverseTransformVectorNoScale(UnitDir);
218 return MObject->FindMostOpposingFace(LocalPosition, LocalDir, HintFaceIndex, SearchDistance);
219 }
220
222 {
223 const TVector<T, d> LocalDenormDir = MTransform.InverseTransformVectorNoScale(DenormDir);
224 const TVector<T, d> LocalOriginalNormal = MTransform.InverseTransformVectorNoScale(OriginalNormal);
225 const TVector<T, d> LocalNormal = MObject->FindGeometryOpposingNormal(LocalDenormDir, FaceIndex, LocalOriginalNormal);
226 return MTransform.TransformVectorNoScale(LocalNormal);
227 }
228
229 virtual bool Overlap(const TVector<T, d>& Point, const T Thickness) const override
230 {
231 const TVector<T, d> LocalPoint = MTransform.InverseTransformPosition(Point);
232 return MObject->Overlap(LocalPoint, Thickness);
233 }
234
235 virtual Pair<TVector<T, d>, bool> FindClosestIntersectionImp(const TVector<T, d>& StartPoint, const TVector<T, d>& EndPoint, const T Thickness) const override
236 {
237 auto TransformedStart = MTransform.InverseTransformPosition(StartPoint);
238 auto TransformedEnd = MTransform.InverseTransformPosition(EndPoint);
239 auto ClosestIntersection = MObject->FindClosestIntersection(TransformedStart, TransformedEnd, Thickness);
240 if (ClosestIntersection.Second)
241 {
242 ClosestIntersection.First = MTransform.TransformPosition(ClosestIntersection.First);
243 }
244 return ClosestIntersection;
245 }
246
247 virtual int32 FindClosestFaceAndVertices(const FVec3& Position, TArray<FVec3>& FaceVertices, FReal SearchDist = 0.01f) const override
248 {
249 const FVec3 LocalPoint = MTransform.InverseTransformPosition(Position);
250 int32 FaceIndex = MObject->FindClosestFaceAndVertices(LocalPoint, FaceVertices, SearchDist);
251 if (FaceIndex != INDEX_NONE)
252 {
253 for (FVec3& Vec : FaceVertices)
254 {
255 Vec = MTransform.TransformPosition(Vec);
256 }
257 }
258 return FaceIndex;
259 }
260
261 const TRigidTransform<T, d>& GetTransform() const { return MTransform; }
263 {
264 MLocalBoundingBox = MObject->BoundingBox().TransformedAABB(InTransform);
265 MTransform = InTransform;
266 }
267
269 {
270 const TRigidTransform<T, d> NewTM = MTransform * ParentTM;
271 MObject->AccumulateAllImplicitObjects(Out, NewTM);
272 }
273
274 virtual void FindAllIntersectingObjects(TArray < Pair<const FImplicitObject*, TRigidTransform<T, d>>>& Out, const TAABB<T, d>& LocalBounds) const override
275 {
276 const TAABB<T, d> SubobjectBounds = LocalBounds.TransformedAABB(MTransform.Inverse());
277 int32 NumOut = Out.Num();
278 MObject->FindAllIntersectingObjects(Out, SubobjectBounds);
279 if (Out.Num() > NumOut)
280 {
281 Out[NumOut].Second = Out[NumOut].Second * MTransform;
282 }
283 }
284
285 virtual const TAABB<T, d> BoundingBox() const override { return MLocalBoundingBox; }
286
287 // Calculate the tight-fitting world-space bounding box
289 {
290 return MObject->CalculateTransformedBounds(FRigidTransform3::MultiplyNoScale(MTransform ,InTransform));
291 }
292
293 const FReal GetVolume() const
294 {
295 // TODO: More precise volume!
296 return BoundingBox().GetVolume();
297 }
298
300 {
301 // TODO: More precise inertia!
302 return BoundingBox().GetInertiaTensor(Mass);
303 }
304
305 const FVec3 GetCenterOfMass() const
306 {
307 // TODO: Actually compute this!
308 return BoundingBox().GetCenterOfMass();
309 }
310
311 UE_DEPRECATED(5.4, "Please use GetGeometry instead")
312 const ObjectType Object() const { return MObject; }
313
314 virtual void Serialize(FChaosArchive& Ar) override
315 {
320 Ar << MTransform;
321 TBox<T, d>::SerializeAsAABB(Ar, MLocalBoundingBox);
322
323 // NOTE: Not serializing SharedObject which is a temp fix and only used in the runtime
324 }
325
326 virtual uint32 GetTypeHash() const override
327 {
328 // Combine the hash from the inner, non transformed object with our transform
329 return HashCombine(MObject->GetTypeHash(), GetTypeHashHelper(MTransform));
330 }
331
332 virtual uint16 GetMaterialIndex(uint32 HintIndex) const override
333 {
334 return MObject->GetMaterialIndex(HintIndex);
335 }
336
338 {
339 return MObject.GetReference();
340 }
341
342 void SetGeometry(const Chaos::FImplicitObjectPtr& ImplicitObject)
343 {
344 MObject = ImplicitObject;
345 }
346
347protected:
349 {
350 // Include self
351 return 1 + MObject->CountObjectsInHierarchy();
352 }
353
355 {
356 // Do not include self
357 return MObject->CountLeafObjectsInHierarchyImpl();
358 }
359
361 const FAABB3& InLocalBounds,
363 const int32 RootObjectIndex,
364 int32& ObjectIndex,
366 const FImplicitHierarchyVisitor& VisitorFunc) const override final
367 {
368 // Skip self
369 ++ObjectIndex;
370
371 // Visit child
372 const FAABB3 LocalBounds = InLocalBounds.InverseTransformedAABB(MTransform);
373 MObject->VisitOverlappingLeafObjectsImpl(LocalBounds, MTransform * ObjectTransform, RootObjectIndex, ObjectIndex, LeafObjectIndex, VisitorFunc);
374 }
375
378 const int32 RootObjectIndex,
379 int32& ObjectIndex,
381 const FImplicitHierarchyVisitor& VisitorFunc) const override final
382 {
383 // Skip self
384 ++ObjectIndex;
385
386 // Visit child
387 MObject->VisitLeafObjectsImpl(MTransform * ObjectTransform, RootObjectIndex, ObjectIndex, LeafObjectIndex, VisitorFunc);
388 }
389
390 virtual bool VisitObjectsImpl(
392 const int32 RootObjectIndex,
393 int32& ObjectIndex,
395 const FImplicitHierarchyVisitorBool& VisitorFunc) const override final
396 {
397 // Visit self
398 bool bContinue = VisitorFunc(this, ObjectTransform, RootObjectIndex, ObjectIndex, INDEX_NONE);
399 ++ObjectIndex;
400
401 // Visit child
402 if (bContinue)
403 {
404 bContinue = MObject->VisitObjectsImpl(MTransform * ObjectTransform, RootObjectIndex, ObjectIndex, LeafObjectIndex, VisitorFunc);
405 }
406
407 return bContinue;
408 }
409
410 virtual bool IsOverlappingBoundsImpl(const FAABB3& InLocalBounds) const override final
411 {
412 const FAABB3 LocalBounds = InLocalBounds.InverseTransformedAABB(MTransform);
413 return MObject->IsOverlappingBoundsImpl(LocalBounds);
414 }
415
416private:
418 TRigidTransform<T, d> MTransform;
419 TAABB<T, d> MLocalBoundingBox;
420
422
423 //needed for serialization
424 TImplicitObjectTransformed() : FImplicitObject(EImplicitObject::HasBoundingBox, ImplicitObjectType::Transformed) {}
425
426 friend FImplicitObject; //needed for serialization
427};
428
429namespace Utilities
430{
431 UE_DEPRECATED(5.4, "Please use DuplicateGeometryWithTransform instead")
432 inline TUniquePtr<FImplicitObject> DuplicateImplicitWithTransform(const FImplicitObject* const InObject, FTransform NewTransform)
433 {
434 check(false);
435 return nullptr;
436 }
437 inline Chaos::FImplicitObjectPtr DuplicateGeometryWithTransform(const FImplicitObject* const InObject, FTransform NewTransform)
438 {
439 if(!InObject)
440 {
441 return nullptr;
442 }
443
444 const EImplicitObjectType OuterType = InObject->GetType();
445
447 {
448 // Take a deep copy here as we're modifying the transformed itself.
449 // #TODO - Deep copy the transformed wrapper but shallow copy the internal shape as that isn't modified.
450 // Likely need to expand the copy functions to handle deep copy wrappers but not concrete geoms
451 Chaos::FImplicitObjectPtr NewTransformed = InObject->DeepCopyGeometry();
453 InnerTransformed->SetTransform(NewTransform);
454
455 return MoveTemp(NewTransformed);
456 }
457 else
458 {
459 // Shallow copy the inner object and wrap it in a new transformed
460 Chaos::FImplicitObjectPtr NewInnerObject = InObject->CopyGeometry();
462 }
463 }
464}
465
466template <typename T, int d>
468
470
471}
#define check(expr)
Definition AssertionMacros.h:314
@ INDEX_NONE
Definition CoreMiscDefines.h:150
#define UE_DEPRECATED(Version, Message)
Definition CoreMiscDefines.h:302
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
UE_FORCEINLINE_HINT uint32 GetTypeHashHelper(const T &V)
Definition TypeHash.h:215
constexpr uint32 HashCombine(uint32 A, uint32 C)
Definition TypeHash.h:36
UE_INTRINSIC_CAST UE_REWRITE constexpr std::remove_reference_t< T > && MoveTemp(T &&Obj) noexcept
Definition UnrealTemplate.h:520
uint16_t uint16
Definition binka_ue_file_header.h:7
uint32_t uint32
Definition binka_ue_file_header.h:6
Definition ChaosArchive.h:364
Definition ChaosArchive.h:167
Definition ClusterUnionManager.h:159
Definition ImplicitObject.h:111
FRealSingle Margin
Definition ImplicitObject.h:571
bool HasBoundingBox() const
Definition ImplicitObject.h:275
bool bDoCollide
Definition ImplicitObject.h:573
bool IsConvex() const
Definition ImplicitObject.h:277
virtual FName GetTypeName() const
Definition ImplicitObject.h:414
CHAOS_API void SerializeImp(FArchive &Ar)
Definition ImplicitObject.cpp:337
bool bIsConvex
Definition ImplicitObject.h:572
Definition AABB.h:37
CHAOSCORE_API TAABB< T, d > InverseTransformedAABB(const Chaos::FRigidTransform3 &) const
Definition AABB.cpp:412
CHAOSCORE_API TAABB< T, d > TransformedAABB(const FTransform &) const
Definition AABB.cpp:385
static void SerializeAsAABB(FArchive &Ar, TAABB< T, d > &AABB)
Definition Box.h:467
Definition ImplicitObjectTransformed.h:37
virtual const TAABB< T, d > BoundingBox() const override
Definition ImplicitObjectTransformed.h:285
void SetTransform(const TRigidTransform< T, d > &InTransform)
Definition ImplicitObjectTransformed.h:262
virtual FReal GetRadius() const override
Definition ImplicitObjectTransformed.h:175
virtual uint16 GetMaterialIndex(uint32 HintIndex) const override
Definition ImplicitObjectTransformed.h:332
virtual FReal GetMargin() const override
Definition ImplicitObjectTransformed.h:169
virtual void AccumulateAllImplicitObjects(TArray< Pair< const FImplicitObject *, TRigidTransform< T, d > > > &Out, const TRigidTransform< T, d > &ParentTM) const override
Definition ImplicitObjectTransformed.h:268
virtual void VisitOverlappingLeafObjectsImpl(const FAABB3 &InLocalBounds, const FRigidTransform3 &ObjectTransform, const int32 RootObjectIndex, int32 &ObjectIndex, int32 &LeafObjectIndex, const FImplicitHierarchyVisitor &VisitorFunc) const override final
Definition ImplicitObjectTransformed.h:360
const ObjectType Object() const
Definition ImplicitObjectTransformed.h:312
virtual void FindAllIntersectingObjects(TArray< Pair< const FImplicitObject *, TRigidTransform< T, d > > > &Out, const TAABB< T, d > &LocalBounds) const override
Definition ImplicitObjectTransformed.h:274
virtual void Serialize(FChaosArchive &Ar) override
Definition ImplicitObjectTransformed.h:314
const Chaos::FImplicitObjectRef GetGeometry() const
Definition ImplicitObjectTransformed.h:337
virtual EImplicitObjectType GetNestedType() const override
Definition ImplicitObjectTransformed.h:89
virtual bool VisitObjectsImpl(const FRigidTransform3 &ObjectTransform, const int32 RootObjectIndex, int32 &ObjectIndex, int32 &LeafObjectIndex, const FImplicitHierarchyVisitorBool &VisitorFunc) const override final
Definition ImplicitObjectTransformed.h:390
virtual T PhiWithNormal(const TVector< T, d > &x, TVector< T, d > &Normal) const override
Definition ImplicitObjectTransformed.h:186
const FVec3 GetCenterOfMass() const
Definition ImplicitObjectTransformed.h:305
static constexpr EImplicitObjectType StaticType()
Definition ImplicitObjectTransformed.h:159
virtual int32 FindClosestFaceAndVertices(const FVec3 &Position, TArray< FVec3 > &FaceVertices, FReal SearchDist=0.01f) const override
Definition ImplicitObjectTransformed.h:247
virtual Chaos::FImplicitObjectPtr CopyGeometryWithScale(const FVec3 &Scale) const override
Definition ImplicitObjectTransformed.h:101
virtual FName GetTypeName() const
Definition ImplicitObject.h:414
virtual Chaos::FImplicitObjectPtr CopyGeometry() const
Definition ImplicitObjectTransformed.h:94
TImplicitObjectTransformed(const TImplicitObjectTransformed< T, d, bSerializable > &Other)=delete
const TRigidTransform< T, d > & GetTransform() const
Definition ImplicitObjectTransformed.h:261
virtual bool Overlap(const TVector< T, d > &Point, const T Thickness) const override
Definition ImplicitObjectTransformed.h:229
virtual FAABB3 CalculateTransformedBounds(const FRigidTransform3 &InTransform) const
Definition ImplicitObjectTransformed.h:288
void SetGeometry(const Chaos::FImplicitObjectPtr &ImplicitObject)
Definition ImplicitObjectTransformed.h:342
virtual TVector< T, 3 > FindGeometryOpposingNormal(const TVector< T, d > &DenormDir, int32 FaceIndex, const TVector< T, d > &OriginalNormal) const override
Definition ImplicitObjectTransformed.h:221
virtual uint32 GetTypeHash() const override
Definition ImplicitObjectTransformed.h:326
TImplicitObjectTransformed(Chaos::FImplicitObjectPtr &&Object, const TRigidTransform< T, d > &InTransform)
Definition ImplicitObjectTransformed.h:54
const FReal GetVolume() const
Definition ImplicitObjectTransformed.h:293
const FImplicitObject * GetTransformedObject() const
Definition ImplicitObjectTransformed.h:164
TImplicitObjectTransformed(const Chaos::FImplicitObjectPtr &Object, const TRigidTransform< T, d > &InTransform)
Definition ImplicitObjectTransformed.h:67
TImplicitObjectTransformed(TImplicitObjectTransformed< T, d, bSerializable > &&Other)
Definition ImplicitObjectTransformed.h:78
virtual void VisitLeafObjectsImpl(const FRigidTransform3 &ObjectTransform, const int32 RootObjectIndex, int32 &ObjectIndex, int32 &LeafObjectIndex, const FImplicitHierarchyVisitor &VisitorFunc) const override final
Definition ImplicitObjectTransformed.h:376
virtual Chaos::FImplicitObjectPtr DeepCopyGeometry() const
Definition ImplicitObjectTransformed.h:122
virtual bool Raycast(const TVector< T, d > &StartPoint, const TVector< T, d > &Dir, const T Length, const T Thickness, T &OutTime, TVector< T, d > &OutPosition, TVector< T, d > &OutNormal, int32 &OutFaceIndex) const override
Definition ImplicitObjectTransformed.h:194
const FMatrix33 GetInertiaTensor(const FReal Mass) const
Definition ImplicitObjectTransformed.h:299
virtual bool IsOverlappingBoundsImpl(const FAABB3 &InLocalBounds) const override final
Definition ImplicitObjectTransformed.h:410
~TImplicitObjectTransformed()
Definition ImplicitObjectTransformed.h:157
virtual int32 CountObjectsInHierarchyImpl() const override final
Definition ImplicitObjectTransformed.h:348
virtual int32 FindMostOpposingFace(const TVector< T, 3 > &Position, const TVector< T, 3 > &UnitDir, int32 HintFaceIndex, T SearchDistance) const override
Definition ImplicitObjectTransformed.h:214
virtual int32 CountLeafObjectsInHierarchyImpl() const override final
Definition ImplicitObjectTransformed.h:354
virtual Pair< TVector< T, d >, bool > FindClosestIntersectionImp(const TVector< T, d > &StartPoint, const TVector< T, d > &EndPoint, const T Thickness) const override
Definition ImplicitObjectTransformed.h:235
virtual Chaos::FImplicitObjectPtr DeepCopyGeometryWithScale(const FVec3 &Scale) const override
Definition ImplicitObjectTransformed.h:137
bool GetDoCollide() const
Definition ImplicitObjectTransformed.h:181
Definition Transform.h:115
Definition Serializable.h:10
Definition Array.h:670
Definition AssetRegistryState.h:50
UE_FORCEINLINE_HINT ReferencedType * GetReference() const
Definition RefCounting.h:584
Definition UniquePtr.h:107
@ Transformed
Definition ImplicitObjectType.h:17
Definition SkeletalMeshComponent.h:307
uint8 EImplicitObjectType
Definition ImplicitObjectType.h:41
void TImplicitObjectTransformSerializeHelper(FChaosArchive &Ar, FImplicitObjectPtr &Obj)
Definition ImplicitObjectTransformed.h:15
FRealDouble FReal
Definition Real.h:22
FORCEINLINE EImplicitObjectType GetInnerType(EImplicitObjectType Type)
Definition ImplicitObjectType.h:58
Definition Pair.h:8
Definition ImplicitObject.h:42