UDocumentation UE5.7 10.02.2026 (Source)
API documentation for Unreal Engine 5.7
CastingUtilities.h
Go to the documentation of this file.
1// Copyright Epic Games, Inc. All Rights Reserved.
2#pragma once
3
5
9#include "Chaos/Sphere.h"
10#include "Chaos/Capsule.h"
11#include "Chaos/Convex.h"
13#include "Chaos/Box.h"
14
15namespace Chaos
16{
17 namespace Utilities
18 {
19 // Call the lambda with concrete shape type. Unwraps shapes contained in Instanced (e.g., Instanced-Sphere will be called with Sphere. Note that this will effectively discard any instance properties like the margin)
20 template <typename Lambda>
21 FORCEINLINE_DEBUGGABLE decltype(auto) CastHelper(const FImplicitObject& Geom, const Lambda& Func)
22 {
23 const EImplicitObjectType Type = Geom.GetType();
24 switch (Type)
25 {
27 {
28 return Func(Geom.template GetObjectChecked<FSphere>());
29 }
31 {
32 return Func(Geom.template GetObjectChecked<TBox<FReal, 3>>());
33 }
35 {
36 return Func(Geom.template GetObjectChecked<FCapsule>());
37 }
39 {
40 return Func(Geom.template GetObjectChecked<FConvex>());
41 }
43 {
44 return Func(Geom.template GetObjectChecked<TImplicitObjectScaled<FSphere>>());
45 }
47 {
48 return Func(Geom.template GetObjectChecked< TImplicitObjectScaled<TBox<FReal, 3>>>());
49 }
51 {
52 return Func(Geom.template GetObjectChecked< TImplicitObjectScaled<FCapsule>>());
53 }
55 {
56 return Func(Geom.template GetObjectChecked< TImplicitObjectScaled<FConvex>>());
57 }
59 {
60 return Func(Geom.template GetObjectChecked< TImplicitObjectInstanced<FSphere>>().GetInstancedObject()->template GetObjectChecked<FSphere>());
61 }
63 {
64 return Func(Geom.template GetObjectChecked< TImplicitObjectInstanced<TBox<FReal, 3>>>().GetInstancedObject()->template GetObjectChecked<TBox<FReal, 3>>());
65 }
67 {
68 return Func(Geom.template GetObjectChecked< TImplicitObjectInstanced<FCapsule>>().GetInstancedObject()->template GetObjectChecked<FCapsule>());
69 }
71 {
72 return Func(Geom.template GetObjectChecked< TImplicitObjectInstanced<FConvex>>().GetInstancedObject()->template GetObjectChecked<FConvex>());
73 }
75 {
77 return CastHelper(*ImplicitObjectTransformed.GetTransformedObject(), Func);
78 }
79 default:
80 check(false);
81 }
82 return Func(Geom.template GetObjectChecked<FSphere>()); //needed for return type
83 }
84
85 // Call the lambda with concrete shape type. Unwraps shapes contained in Instanced (e.g., Instanced-Sphere will be called with Sphere. Note that this will effectively discard any instance properties like the margin)
86 template <typename Lambda>
87 FORCEINLINE_DEBUGGABLE decltype(auto) CastHelper(const FImplicitObject& Geom, const FRigidTransform3& TM, const Lambda& Func)
88 {
89 const EImplicitObjectType Type = Geom.GetType();
90 switch (Type)
91 {
92 case ImplicitObjectType::Sphere: return Func(Geom.template GetObjectChecked<FSphere>(), TM);
93 case ImplicitObjectType::Box: return Func(Geom.template GetObjectChecked<TBox<FReal, 3>>(), TM);
94 case ImplicitObjectType::Capsule: return Func(Geom.template GetObjectChecked<FCapsule>(), TM);
95 case ImplicitObjectType::Convex: return Func(Geom.template GetObjectChecked<FConvex>(), TM);
96 case ImplicitObjectType::IsScaled | ImplicitObjectType::Sphere: return Func(Geom.template GetObjectChecked<TImplicitObjectScaled<FSphere>>(), TM);
97 case ImplicitObjectType::IsScaled | ImplicitObjectType::Box: return Func(Geom.template GetObjectChecked< TImplicitObjectScaled<TBox<FReal, 3>>>(), TM);
98 case ImplicitObjectType::IsScaled | ImplicitObjectType::Capsule: return Func(Geom.template GetObjectChecked< TImplicitObjectScaled<FCapsule>>(), TM);
99 case ImplicitObjectType::IsScaled | ImplicitObjectType::Convex: return Func(Geom.template GetObjectChecked< TImplicitObjectScaled<FConvex>>(), TM);
101 {
102 return Func(Geom.template GetObjectChecked< TImplicitObjectInstanced<FSphere>>().GetInstancedObject()->template GetObjectChecked<FSphere>(), TM);
103 }
105 {
106 return Func(Geom.template GetObjectChecked< TImplicitObjectInstanced<TBox<FReal, 3>>>().GetInstancedObject()->template GetObjectChecked<TBox<FReal, 3>>(), TM);
107 }
109 {
110 return Func(Geom.template GetObjectChecked< TImplicitObjectInstanced<FCapsule>>().GetInstancedObject()->template GetObjectChecked<FCapsule>(), TM);
111 }
113 {
114 return Func(Geom.template GetObjectChecked< TImplicitObjectInstanced<FConvex>>().GetInstancedObject()->template GetObjectChecked<FConvex>(), TM);
115 }
117 {
119 return CastHelper(*ImplicitObjectTransformed.GetTransformedObject(), ImplicitObjectTransformed.GetTransform() * TM, Func);
120 }
121
122 default: check(false);
123 }
124 return Func(Geom.template GetObjectChecked<FSphere>(), TM); //needed for return type
125 }
126
127 // Call the lambda with concrete shape type. This version does NOT unwrap shapes contained in Instanced or Scaled.
128 template <typename Lambda>
129 FORCEINLINE_DEBUGGABLE decltype(auto) CastHelperNoUnwrap(const FImplicitObject& Geom, const FRigidTransform3& TM, const Lambda& Func)
130 {
131 const EImplicitObjectType Type = Geom.GetType();
132 switch (Type)
133 {
134 case ImplicitObjectType::Sphere: return Func(Geom.template GetObjectChecked<FSphere>(), TM);
135 case ImplicitObjectType::Box: return Func(Geom.template GetObjectChecked<TBox<FReal, 3>>(), TM);
136 case ImplicitObjectType::Capsule: return Func(Geom.template GetObjectChecked<FCapsule>(), TM);
137 case ImplicitObjectType::Convex: return Func(Geom.template GetObjectChecked<FConvex>(), TM);
138 case ImplicitObjectType::IsScaled | ImplicitObjectType::Sphere: return Func(Geom.template GetObjectChecked<TImplicitObjectScaled<FSphere>>(), TM);
139 case ImplicitObjectType::IsScaled | ImplicitObjectType::Box: return Func(Geom.template GetObjectChecked< TImplicitObjectScaled<TBox<FReal, 3>>>(), TM);
140 case ImplicitObjectType::IsScaled | ImplicitObjectType::Capsule: return Func(Geom.template GetObjectChecked< TImplicitObjectScaled<FCapsule>>(), TM);
141 case ImplicitObjectType::IsScaled | ImplicitObjectType::Convex: return Func(Geom.template GetObjectChecked< TImplicitObjectScaled<FConvex>>(), TM);
142 case ImplicitObjectType::IsInstanced | ImplicitObjectType::Sphere: return Func(Geom.template GetObjectChecked< TImplicitObjectInstanced<FSphere>>(), TM);
143 case ImplicitObjectType::IsInstanced | ImplicitObjectType::Box: return Func(Geom.template GetObjectChecked< TImplicitObjectInstanced<TBox<FReal, 3>>>(), TM);
144 case ImplicitObjectType::IsInstanced | ImplicitObjectType::Capsule: return Func(Geom.template GetObjectChecked< TImplicitObjectInstanced<FCapsule>>(), TM);
145 case ImplicitObjectType::IsInstanced | ImplicitObjectType::Convex: return Func(Geom.template GetObjectChecked< TImplicitObjectInstanced<FConvex>>(), TM);
147 {
149 return CastHelper(*ImplicitObjectTransformed.GetTransformedObject(), ImplicitObjectTransformed.GetTransform() * TM, Func);
150 }
151
152 default: check(false);
153 }
154 return Func(Geom.template GetObjectChecked<FSphere>(), TM); //needed for return type
155 }
156
157 template <typename Lambda>
158 FORCEINLINE_DEBUGGABLE decltype(auto) CastHelperNoUnwrap(const FImplicitObject& Geom, const FRigidTransform3& TM0, const FRigidTransform3& TM1, const Lambda& Func)
159 {
160 const EImplicitObjectType Type = Geom.GetType();
161 switch (Type)
162 {
163 case ImplicitObjectType::Sphere: return Func(Geom.template GetObjectChecked<FSphere>(), TM0, TM1);
164 case ImplicitObjectType::Box: return Func(Geom.template GetObjectChecked<TBox<FReal, 3>>(), TM0, TM1);
165 case ImplicitObjectType::Capsule: return Func(Geom.template GetObjectChecked<FCapsule>(), TM0, TM1);
166 case ImplicitObjectType::Convex: return Func(Geom.template GetObjectChecked<FConvex>(), TM0, TM1);
167 case ImplicitObjectType::IsScaled | ImplicitObjectType::Sphere: return Func(Geom.template GetObjectChecked<TImplicitObjectScaled<FSphere>>(), TM0, TM1);
168 case ImplicitObjectType::IsScaled | ImplicitObjectType::Box: return Func(Geom.template GetObjectChecked< TImplicitObjectScaled<TBox<FReal, 3>>>(), TM0, TM1);
169 case ImplicitObjectType::IsScaled | ImplicitObjectType::Capsule: return Func(Geom.template GetObjectChecked< TImplicitObjectScaled<FCapsule>>(), TM0, TM1);
170 case ImplicitObjectType::IsScaled | ImplicitObjectType::Convex: return Func(Geom.template GetObjectChecked< TImplicitObjectScaled<FConvex>>(), TM0, TM1);
171 case ImplicitObjectType::IsInstanced | ImplicitObjectType::Sphere: return Func(Geom.template GetObjectChecked< TImplicitObjectInstanced<FSphere>>(), TM0, TM1);
172 case ImplicitObjectType::IsInstanced | ImplicitObjectType::Box: return Func(Geom.template GetObjectChecked< TImplicitObjectInstanced<TBox<FReal, 3>>>(), TM0, TM1);
173 case ImplicitObjectType::IsInstanced | ImplicitObjectType::Capsule: return Func(Geom.template GetObjectChecked< TImplicitObjectInstanced<FCapsule>>(), TM0, TM1);
174 case ImplicitObjectType::IsInstanced | ImplicitObjectType::Convex: return Func(Geom.template GetObjectChecked< TImplicitObjectInstanced<FConvex>>(), TM0, TM1);
176 {
178 return CastHelperNoUnwrap(*ImplicitObjectTransformed.GetTransformedObject(), ImplicitObjectTransformed.GetTransform() * TM0, ImplicitObjectTransformed.GetTransform() * TM1, Func);
179 }
180
181 default: check(false);
182 }
183 return Func(Geom.template GetObjectChecked<FSphere>(), TM0, TM1); //needed for return type
184 }
185
186 inline
188 {
189 EImplicitObjectType ImplicitType = ImplicitObject->GetType();
191 {
192 return ImplicitObject->template GetObject<const TImplicitObjectTransformed<FReal, 3>>()->GetTransformedObject();
193 }
194
195 else if (ImplicitType == TImplicitObjectScaled<FConvex>::StaticType())
196 {
197 return ImplicitObject->template GetObject<const TImplicitObjectScaled<FConvex>>()->GetUnscaledObject();
198 }
199 else if (ImplicitType == TImplicitObjectScaled<TBox<FReal, 3>>::StaticType())
200 {
201 return ImplicitObject->template GetObject<const TImplicitObjectScaled<TBox<FReal, 3>>>()->GetUnscaledObject();
202 }
203 else if (ImplicitType == TImplicitObjectScaled<FCapsule>::StaticType())
204 {
205 return ImplicitObject->template GetObject<const TImplicitObjectScaled<FCapsule>>()->GetUnscaledObject();
206 }
207 else if (ImplicitType == TImplicitObjectScaled<FSphere>::StaticType())
208 {
209 return ImplicitObject->template GetObject<const TImplicitObjectScaled<FSphere>>()->GetUnscaledObject();
210 }
212 {
213 return ImplicitObject->template GetObject<const TImplicitObjectScaled<FTriangleMeshImplicitObject>>()->GetUnscaledObject();
214 }
215
216 else if (ImplicitType == TImplicitObjectInstanced<FConvex>::StaticType())
217 {
218 return ImplicitObject->template GetObject<const TImplicitObjectInstanced<FConvex>>()->GetInstancedObject();
219 }
220 else if (ImplicitType == TImplicitObjectInstanced<TBox<FReal, 3>>::StaticType())
221 {
222 return ImplicitObject->template GetObject<const TImplicitObjectInstanced<TBox<FReal, 3>>>()->GetInstancedObject();
223 }
224 else if (ImplicitType == TImplicitObjectInstanced<FCapsule>::StaticType())
225 {
226 return ImplicitObject->template GetObject<const TImplicitObjectInstanced<FCapsule>>()->GetInstancedObject();
227 }
228 else if (ImplicitType == TImplicitObjectInstanced<FSphere>::StaticType())
229 {
230 return ImplicitObject->template GetObject<const TImplicitObjectInstanced<FSphere>>()->GetInstancedObject();
231 }
233 {
234 return ImplicitObject->template GetObject<const TImplicitObjectInstanced<FTriangleMeshImplicitObject>>()->GetInstancedObject();
235 }
236 return nullptr;
237 }
238
243 template <typename T, typename Lambda>
244 FORCEINLINE_DEBUGGABLE decltype(auto) CastWrapped(const FImplicitObject& A, const Lambda& Func)
245 {
246 if (const TImplicitObjectScaled<T>* ScaledImplicit = A.template GetObject<TImplicitObjectScaled<T>>())
247 {
248 return Func(ScaledImplicit);
249 }
250 else if (const TImplicitObjectInstanced<T>* InstancedImplicit = A.template GetObject<TImplicitObjectInstanced<T>>())
251 {
252 return Func(InstancedImplicit);
253 }
254 else if(const T* RawImplicit = A.template GetObject<T>())
255 {
256 return Func(RawImplicit);
257 }
258 else
259 {
260 return Func((T*)nullptr);
261 }
262 }
263
264 template <typename Lambda, bool bRootObject>
265 FORCEINLINE_DEBUGGABLE void VisitConcreteObjectsImpl(const FImplicitObject& Geom, const Lambda& Func, int32 RootObjectIndex)
266 {
268 {
269 for (const FImplicitObjectPtr& ObjectPtr : Union->GetObjects())
270 {
271 if (const FImplicitObject* Object = ObjectPtr.GetReference())
272 {
273 VisitConcreteObjectsImpl<Lambda, false>(*Object, Func, RootObjectIndex);
274 }
275
276 if constexpr (bRootObject)
277 {
278 ++RootObjectIndex;
279 }
280 }
281 }
282 else
283 {
284 CastHelper(Geom, [&Func, RootObjectIndex](const auto& Concrete)
285 {
286 Func(Concrete, RootObjectIndex);
287 });
288 }
289 }
290
297 template <typename Lambda>
298 FORCEINLINE_DEBUGGABLE void VisitConcreteObjects(const FImplicitObject& Geom, const Lambda& Func)
299 {
301 }
302
303 } // namespace Utilities
304
305} // namespace Chaos
#define check(expr)
Definition AssertionMacros.h:314
#define FORCEINLINE_DEBUGGABLE
Definition CoreMiscDefines.h:74
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
Definition ImplicitObjectUnion.h:27
Definition ImplicitObject.h:111
const TargetType * AsA() const
Definition ImplicitObject.h:131
CHAOS_API EImplicitObjectType GetType() const
Definition ImplicitObject.cpp:67
Definition Box.h:23
Definition ImplicitObjectScaled.h:47
const TConcrete * GetInstancedObject() const
Definition ImplicitObjectScaled.h:108
Definition ImplicitObjectScaled.h:447
Definition ImplicitObjectTransformed.h:37
@ IsInstanced
Definition ImplicitObjectType.h:35
@ IsScaled
Definition ImplicitObjectType.h:36
@ Convex
Definition ImplicitObjectType.h:21
@ Box
Definition ImplicitObjectType.h:14
@ Capsule
Definition ImplicitObjectType.h:16
@ Sphere
Definition ImplicitObjectType.h:13
@ Transformed
Definition ImplicitObjectType.h:17
FORCEINLINE_DEBUGGABLE decltype(auto) CastHelper(const FImplicitObject &Geom, const Lambda &Func)
Definition CastingUtilities.h:21
FORCEINLINE_DEBUGGABLE decltype(auto) CastWrapped(const FImplicitObject &A, const Lambda &Func)
Given an ImplicitObject known to be of type T or a wrapper around T, call the Lambda with the concret...
Definition CastingUtilities.h:244
FORCEINLINE_DEBUGGABLE void VisitConcreteObjects(const FImplicitObject &Geom, const Lambda &Func)
Similar to FImplicitObject::VisitLeafObjects, but provides only the root object index (ie,...
Definition CastingUtilities.h:298
const FImplicitObject * ImplicitChildHelper(const FImplicitObject *ImplicitObject)
Definition CastingUtilities.h:187
FORCEINLINE_DEBUGGABLE decltype(auto) CastHelperNoUnwrap(const FImplicitObject &Geom, const FRigidTransform3 &TM, const Lambda &Func)
Definition CastingUtilities.h:129
FORCEINLINE_DEBUGGABLE void VisitConcreteObjectsImpl(const FImplicitObject &Geom, const Lambda &Func, int32 RootObjectIndex)
Definition CastingUtilities.h:265
Definition SkeletalMeshComponent.h:307
uint8 EImplicitObjectType
Definition ImplicitObjectType.h:41