UDocumentation UE5.7 10.02.2026 (Source)
API documentation for Unreal Engine 5.7
AggregateGeom.h
Go to the documentation of this file.
1// Copyright Epic Games, Inc. All Rights Reserved.
2
3#pragma once
4
5#include "CoreMinimal.h"
16#include "Async/Mutex.h"
17#include "AggregateGeom.generated.h"
18
20
22USTRUCT()
24{
26
27 UPROPERTY(EditAnywhere, editfixedsize, Category = "Aggregate Geometry", meta = (DisplayName = "Spheres", TitleProperty = "Name"))
28 TArray<FKSphereElem> SphereElems;
29
30 UPROPERTY(EditAnywhere, editfixedsize, Category = "Aggregate Geometry", meta = (DisplayName = "Boxes", TitleProperty = "Name"))
31 TArray<FKBoxElem> BoxElems;
32
33 UPROPERTY(EditAnywhere, editfixedsize, Category = "Aggregate Geometry", meta = (DisplayName = "Capsules", TitleProperty = "Name"))
34 TArray<FKSphylElem> SphylElems;
35
36 UPROPERTY(EditAnywhere, editfixedsize, Category = "Aggregate Geometry", meta = (DisplayName = "Convex Elements", TitleProperty = "Name"))
37 TArray<FKConvexElem> ConvexElems;
38
39 UPROPERTY(EditAnywhere, editfixedsize, Category = "Aggregate Geometry", meta = (DisplayName = "Tapered Capsules", TitleProperty = "Name"))
40 TArray<FKTaperedCapsuleElem> TaperedCapsuleElems;
41
42 UPROPERTY(EditAnywhere, editfixedsize, Category = "Aggregate Geometry", meta = (DisplayName = "Level Sets", TitleProperty = "Name"))
43 TArray<FKLevelSetElem> LevelSetElems;
44
45 UPROPERTY(EditAnywhere, editfixedsize, Category = "Aggregate Geometry", meta = (DisplayName = "(Experimental) Skinned Level Sets", TitleProperty = "Name"), Experimental)
47
48 UPROPERTY(EditAnywhere, editfixedsize, Category = "Aggregate Geometry", meta = (DisplayName = "(Experimental) ML Level Sets", TitleProperty = "Name"), Experimental)
50
51 UPROPERTY(EditAnywhere, editfixedsize, Category = "Aggregate Geometry", meta = (DisplayName = "(Experimental) Skinned Triangle Meshes", TitleProperty = "Name"), Experimental)
53
55 : RenderInfoPtr(nullptr)
56 {
57 }
58
60 : RenderInfoPtr(nullptr)
61 {
62 CloneAgg(Other);
63 }
64
66 {
67 FreeRenderInfo();
68 CloneAgg(Other);
69 return *this;
70 }
71
73 {
74 return SphereElems.Num() + SphylElems.Num() + BoxElems.Num() + ConvexElems.Num() + TaperedCapsuleElems.Num() + LevelSetElems.Num() + SkinnedLevelSetElems.Num() + MLLevelSetElems.Num() + SkinnedTriangleMeshElems.Num();
75 }
76
77 ENGINE_API int32 GetElementCount(EAggCollisionShape::Type Type) const;
78
79 SIZE_T GetAllocatedSize() const { return SphereElems.GetAllocatedSize() + SphylElems.GetAllocatedSize() + BoxElems.GetAllocatedSize() + ConvexElems.GetAllocatedSize() + TaperedCapsuleElems.GetAllocatedSize() + LevelSetElems.GetAllocatedSize() + SkinnedLevelSetElems.GetAllocatedSize() + MLLevelSetElems.GetAllocatedSize() + SkinnedTriangleMeshElems.GetAllocatedSize(); }
80
81 template <typename Callable>
83 {
84 switch(InElement.GetShapeType())
85 {
87 return InCallable(static_cast<FKSphereElem&>(InElement), SphereElems);
89 return InCallable(static_cast<FKBoxElem&>(InElement), BoxElems);
91 return InCallable(static_cast<FKSphylElem&>(InElement), SphylElems);
93 return InCallable(static_cast<FKConvexElem&>(InElement), ConvexElems);
95 return InCallable(static_cast<FKTaperedCapsuleElem&>(InElement), TaperedCapsuleElems);
97 return InCallable(static_cast<FKLevelSetElem&>(InElement), LevelSetElems);
104 default:
105 check(false);
106 }
107
109 if constexpr(!std::is_same_v<RetType, void>)
110 {
111 return RetType{};
112 }
113 }
114
115 template <typename Callable>
117 {
118 switch(InElement.GetShapeType())
119 {
121 return InCallable(static_cast<const FKSphereElem&>(InElement), SphereElems);
123 return InCallable(static_cast<const FKBoxElem&>(InElement), BoxElems);
125 return InCallable(static_cast<const FKSphylElem&>(InElement), SphylElems);
127 return InCallable(static_cast<const FKConvexElem&>(InElement), ConvexElems);
129 return InCallable(static_cast<const FKTaperedCapsuleElem&>(InElement), TaperedCapsuleElems);
131 return InCallable(static_cast<const FKLevelSetElem&>(InElement), LevelSetElems);
135 return InCallable(static_cast<const FKMLLevelSetElem&>(InElement), MLLevelSetElems);
138 default:
139 check(false);
140 }
141
143 if constexpr(!std::is_same_v<RetType, void>)
144 {
145 return RetType{};
146 }
147 }
148
149 // Add a typed element to the appropriate container
150 template <typename T>
151 void AddElement(const T& Elem) requires (TIsDerivedFrom<T, FKShapeElem>::Value || std::is_same_v<T, FKShapeElem>)
152 {
153 VisitShapeAndContainer(Elem, [] <typename ElemType> (const ElemType& TypedElem, TArray<ElemType>& Container)
154 {
155 Container.Add(TypedElem);
156 });
157 }
158
160 {
161 switch (Type)
162 {
164 if (ensure(SphereElems.IsValidIndex(Index)))
165 {
166 return &SphereElems[Index];
167 }
168 break;
170 if (ensure(BoxElems.IsValidIndex(Index)))
171 {
172 return &BoxElems[Index];
173 }
174 break;
176 if (ensure(SphylElems.IsValidIndex(Index)))
177 {
178 return &SphylElems[Index];
179 }
180 break;
182 if (ensure(ConvexElems.IsValidIndex(Index)))
183 {
184 return &ConvexElems[Index];
185 }
186 break;
188 if (ensure(TaperedCapsuleElems.IsValidIndex(Index)))
189 {
190 return &TaperedCapsuleElems[Index];
191 }
192 break;
194 if (ensure(LevelSetElems.IsValidIndex(Index)))
195 {
196 return &LevelSetElems[Index];
197 }
198 break;
200 if (ensure(SkinnedLevelSetElems.IsValidIndex(Index)))
201 {
203 }
204 break;
206 if (ensure(MLLevelSetElems.IsValidIndex(Index)))
207 {
208 return &MLLevelSetElems[Index];
209 }
210 break;
212 if (ensure(SkinnedTriangleMeshElems.IsValidIndex(Index)))
213 {
215 }
216 break;
217 default:
218 ensure(false);
219 }
220 return nullptr;
221 }
222
224 {
225 switch (Type)
226 {
228 if (ensure(SphereElems.IsValidIndex(Index)))
229 {
230 return &SphereElems[Index];
231 }
232 break;
234 if (ensure(BoxElems.IsValidIndex(Index)))
235 {
236 return &BoxElems[Index];
237 }
238 break;
240 if (ensure(SphylElems.IsValidIndex(Index)))
241 {
242 return &SphylElems[Index];
243 }
244 break;
246 if (ensure(ConvexElems.IsValidIndex(Index)))
247 {
248 return &ConvexElems[Index];
249 }
250 break;
252 if (ensure(TaperedCapsuleElems.IsValidIndex(Index)))
253 {
254 return &TaperedCapsuleElems[Index];
255 }
256 break;
258 if (ensure(LevelSetElems.IsValidIndex(Index)))
259 {
260 return &LevelSetElems[Index];
261 }
262 break;
264 if (ensure(SkinnedLevelSetElems.IsValidIndex(Index)))
265 {
267 }
268 break;
270 if (ensure(MLLevelSetElems.IsValidIndex(Index)))
271 {
272 return &MLLevelSetElems[Index];
273 }
274 break;
276 if (ensure(SkinnedTriangleMeshElems.IsValidIndex(Index)))
277 {
279 }
280 break;
281 default:
282 ensure(false);
283 }
284 return nullptr;
285 }
286
288 {
289 int Index = InIndex;
290 if (SphereElems.IsValidIndex(Index))
291 {
292 return &SphereElems[Index];
293 }
294 Index -= SphereElems.Num();
295 if (BoxElems.IsValidIndex(Index))
296 {
297 return &BoxElems[Index];
298 }
299 Index -= BoxElems.Num();
300 if (SphylElems.IsValidIndex(Index))
301 {
302 return &SphylElems[Index];
303 }
304 Index -= SphylElems.Num();
305 if (ConvexElems.IsValidIndex(Index))
306 {
307 return &ConvexElems[Index];
308 }
309 Index -= ConvexElems.Num();
310 if (TaperedCapsuleElems.IsValidIndex(Index))
311 {
312 return &TaperedCapsuleElems[Index];
313 }
314 Index -= TaperedCapsuleElems.Num();
315 if (LevelSetElems.IsValidIndex(Index))
316 {
317 return &LevelSetElems[Index];
318 }
319 Index -= LevelSetElems.Num();
320 if (SkinnedLevelSetElems.IsValidIndex(Index))
321 {
323 }
325 if (MLLevelSetElems.IsValidIndex(Index))
326 {
327 return &MLLevelSetElems[Index];
328 }
329 Index -= MLLevelSetElems.Num();
330 if (SkinnedTriangleMeshElems.IsValidIndex(Index))
331 {
333 }
334 ensure(false);
335 return nullptr;
336 }
337
339 {
340 int Index = InIndex;
341 if (SphereElems.IsValidIndex(Index))
342 {
343 return &SphereElems[Index];
344 }
345 Index -= SphereElems.Num();
346 if (BoxElems.IsValidIndex(Index))
347 {
348 return &BoxElems[Index];
349 }
350 Index -= BoxElems.Num();
351 if (SphylElems.IsValidIndex(Index))
352 {
353 return &SphylElems[Index];
354 }
355 Index -= SphylElems.Num();
356 if (ConvexElems.IsValidIndex(Index))
357 {
358 return &ConvexElems[Index];
359 }
360 Index -= ConvexElems.Num();
361 if (TaperedCapsuleElems.IsValidIndex(Index))
362 {
363 return &TaperedCapsuleElems[Index];
364 }
365 Index -= TaperedCapsuleElems.Num();
366 if (LevelSetElems.IsValidIndex(Index))
367 {
368 return &LevelSetElems[Index];
369 }
370 Index -= LevelSetElems.Num();
371 if (SkinnedLevelSetElems.IsValidIndex(Index))
372 {
374 }
376 if (MLLevelSetElems.IsValidIndex(Index))
377 {
378 return &MLLevelSetElems[Index];
379 }
380 Index -= MLLevelSetElems.Num();
381 if (SkinnedTriangleMeshElems.IsValidIndex(Index))
382 {
384 }
385 ensure(false);
386 return nullptr;
387 }
388
389 const FKShapeElem* GetElementByName(const FName InName) const
390 {
392 {
393 return FoundSphereElem;
394 }
395 else if (const FKShapeElem* FoundBoxElem = GetElementByName<FKBoxElem>(MakeArrayView(BoxElems), InName))
396 {
397 return FoundBoxElem;
398 }
399 else if (const FKShapeElem* FoundSphylElem = GetElementByName<FKSphylElem>(MakeArrayView(SphylElems), InName))
400 {
401 return FoundSphylElem;
402 }
403 else if (const FKShapeElem* FoundConvexElem = GetElementByName<FKConvexElem>(MakeArrayView(ConvexElems), InName))
404 {
405 return FoundConvexElem;
406 }
407 else if (const FKShapeElem* FoundTaperedCapsuleElem = GetElementByName<FKTaperedCapsuleElem>(MakeArrayView(TaperedCapsuleElems), InName))
408 {
410 }
411 else if (const FKShapeElem* FoundLevelSetElem = GetElementByName<FKLevelSetElem>(MakeArrayView(LevelSetElems), InName))
412 {
413 return FoundLevelSetElem;
414 }
416 {
418 }
420 {
421 return FoundMLLevelSetElem;
422 }
424 {
426 }
427
428 return nullptr;
429 }
430
432 {
433 int32 FoundIndex = GetElementIndexByName<FKSphereElem>(MakeArrayView(SphereElems), InName);
434 int32 StartIndex = 0;
435 if (FoundIndex != INDEX_NONE)
436 {
437 return FoundIndex + StartIndex;
438 }
439 StartIndex += SphereElems.Num();
440
441 FoundIndex = GetElementIndexByName<FKBoxElem>(MakeArrayView(BoxElems), InName);
442 if (FoundIndex != INDEX_NONE)
443 {
444 return FoundIndex + StartIndex;
445 }
446 StartIndex += BoxElems.Num();
447
448 FoundIndex = GetElementIndexByName<FKSphylElem>(MakeArrayView(SphylElems), InName);
449 if (FoundIndex != INDEX_NONE)
450 {
451 return FoundIndex + StartIndex;
452 }
453 StartIndex += SphylElems.Num();
454
455 FoundIndex = GetElementIndexByName<FKConvexElem>(MakeArrayView(ConvexElems), InName);
456 if (FoundIndex != INDEX_NONE)
457 {
458 return FoundIndex + StartIndex;
459 }
460 StartIndex += ConvexElems.Num();
461
462 FoundIndex = GetElementIndexByName<FKTaperedCapsuleElem>(MakeArrayView(TaperedCapsuleElems), InName);
463 if (FoundIndex != INDEX_NONE)
464 {
465 return FoundIndex + StartIndex;
466 }
467 StartIndex += TaperedCapsuleElems.Num();
468
469 FoundIndex = GetElementIndexByName<FKLevelSetElem>(MakeArrayView(LevelSetElems), InName);
470 if (FoundIndex != INDEX_NONE)
471 {
472 return FoundIndex + StartIndex;
473 }
474 StartIndex += LevelSetElems.Num();
475
477 if (FoundIndex != INDEX_NONE)
478 {
479 return FoundIndex + StartIndex;
480 }
481
483 if (FoundIndex != INDEX_NONE)
484 {
485 return FoundIndex + StartIndex;
486 }
487
489 if (FoundIndex != INDEX_NONE)
490 {
491 return FoundIndex + StartIndex;
492 }
493
494 return INDEX_NONE;
495 }
496
497#if WITH_EDITORONLY_DATA
499 {
500 auto CleanUp = [](auto& Elems)
501 {
502 Elems.RemoveAllSwap([](const FKShapeElem& Elem)
503 {
504 return Elem.bIsGenerated == false;
505 });
506 };
507 CleanUp(BoxElems);
508 CleanUp(ConvexElems);
509 CleanUp(SphylElems);
510 CleanUp(SphereElems);
511 CleanUp(TaperedCapsuleElems);
512 CleanUp(LevelSetElems);
516
517 FreeRenderInfo();
518 }
519#endif
520
522 {
523 BoxElems.Empty();
524 ConvexElems.Empty();
525 SphylElems.Empty();
526 SphereElems.Empty();
527 TaperedCapsuleElems.Empty();
528 LevelSetElems.Empty();
529 SkinnedLevelSetElems.Empty();
530 MLLevelSetElems.Empty();
532 FreeRenderInfo();
533 }
534
535#if WITH_EDITORONLY_DATA
537#endif
538
539 ENGINE_API void GetAggGeom(const FTransform& Transform, const FColor Color, const FMaterialRenderProxy* MatInst, bool bPerHullColor, bool bDrawSolid, bool bOutputVelocity, int32 ViewIndex, class FMeshElementCollector& Collector) const;
540
542 ENGINE_API void FreeRenderInfo();
543
544 ENGINE_API FBox CalcAABB(const FTransform& Transform) const;
545
553 ENGINE_API void CalcBoxSphereBounds(FBoxSphereBounds& Output, const FTransform& LocalToWorld) const;
554
556 UE_DEPRECATED(5.1, "Changed to GetScaledVolume. Note that Volume calculation now includes non-uniform scale so values may have changed")
557 ENGINE_API FVector::FReal GetVolume(const FVector& Scale3D) const;
558
560 ENGINE_API FVector::FReal GetScaledVolume(const FVector& Scale3D) const;
561
562 ENGINE_API FGuid MakeDDCKey() const;
563
564private:
565
567 void CloneAgg(const FKAggregateGeom& Other)
568 {
569 SphereElems = Other.SphereElems;
570 BoxElems = Other.BoxElems;
571 SphylElems = Other.SphylElems;
572 ConvexElems = Other.ConvexElems;
573 TaperedCapsuleElems = Other.TaperedCapsuleElems;
574 LevelSetElems = Other.LevelSetElems;
575 SkinnedLevelSetElems = Other.SkinnedLevelSetElems;
576 MLLevelSetElems = Other.MLLevelSetElems;
577 SkinnedTriangleMeshElems = Other.SkinnedTriangleMeshElems;
578 }
579
580 template <class T>
581 const FKShapeElem* GetElementByName(TArrayView<const T> Elements, const FName InName) const
582 {
583 const FKShapeElem* FoundElem = Elements.FindByPredicate(
584 [InName](const T& Elem)
585 {
586 return InName == Elem.GetName();
587 });
588 return FoundElem;
589 }
590
591 template <class T>
592 int32 GetElementIndexByName(TArrayView<const T> Elements, const FName InName) const
593 {
594 int32 FoundIndex = Elements.IndexOfByPredicate(
595 [InName](const T& Elem)
596 {
597 return InName == Elem.GetName();
598 });
599 return FoundIndex;
600 }
601
602 // NOTE: RenderInfo is generated concurrently and lazily (hence being mutable)
603 mutable std::atomic<class FKConvexGeomRenderInfo*> RenderInfoPtr;
604 mutable UE::FMutex RenderInfoLock;
605};
constexpr auto MakeArrayView(OtherRangeType &&Other)
Definition ArrayView.h:873
#define check(expr)
Definition AssertionMacros.h:314
#define ensure( InExpression)
Definition AssertionMacros.h:464
@ INDEX_NONE
Definition CoreMiscDefines.h:150
#define UE_DEPRECATED(Version, Message)
Definition CoreMiscDefines.h:302
FPlatformTypes::SIZE_T SIZE_T
An unsigned integer the same size as a pointer, the same as UPTRINT.
Definition Platform.h:1150
FPlatformTypes::int32 int32
A 32-bit signed integer.
Definition Platform.h:1125
typename TInvokeResult< FuncType, ArgTypes... >::Type TInvokeResult_T
Definition Invoke.h:135
UE_FORCEINLINE_HINT TSharedRef< CastToType, Mode > StaticCastSharedRef(TSharedRef< CastFromType, Mode > const &InSharedRef)
Definition SharedPointer.h:127
@ Meshes
Definition HairStrandsInterface.h:193
#define UPROPERTY(...)
UObject definition macros.
Definition ObjectMacros.h:744
#define USTRUCT(...)
Definition ObjectMacros.h:746
#define GENERATED_USTRUCT_BODY(...)
Definition ObjectMacros.h:767
Definition Archive.h:1208
Definition MaterialRenderProxy.h:102
Definition MeshElementCollector.h:26
Definition NameTypes.h:617
Definition ArrayView.h:139
constexpr SizeType IndexOfByPredicate(Predicate Pred) const
Definition ArrayView.h:644
constexpr ElementType * FindByPredicate(Predicate Pred) const
Definition ArrayView.h:688
Definition Array.h:670
Definition Mutex.h:18
Type
Definition ShapeElem.h:17
@ Box
Definition ShapeElem.h:19
@ LevelSet
Definition ShapeElem.h:23
@ SkinnedTriangleMesh
Definition ShapeElem.h:26
@ SkinnedLevelSet
Definition ShapeElem.h:24
@ Convex
Definition ShapeElem.h:21
@ Sphyl
Definition ShapeElem.h:20
@ TaperedCapsule
Definition ShapeElem.h:22
@ MLLevelSet
Definition ShapeElem.h:25
@ Sphere
Definition ShapeElem.h:18
Definition RobinHoodHashTable.h:18
U16 Index
Definition radfft.cpp:71
Definition Color.h:486
Definition Guid.h:109
Definition AggregateGeom.h:24
auto VisitShapeAndContainer(const FKShapeElem &InElement, Callable &&InCallable)
Definition AggregateGeom.h:116
const FKShapeElem * GetElement(const int32 InIndex) const
Definition AggregateGeom.h:338
int32 GetElementCount() const
Definition AggregateGeom.h:72
void AddElement(const T &Elem)
Definition AggregateGeom.h:151
const FKShapeElem * GetElement(const EAggCollisionShape::Type Type, const int32 Index) const
Definition AggregateGeom.h:223
FKShapeElem * GetElement(const int32 InIndex)
Definition AggregateGeom.h:287
int32 GetElementIndexByName(const FName InName) const
Definition AggregateGeom.h:431
auto VisitShapeAndContainer(FKShapeElem &InElement, Callable &&InCallable)
Definition AggregateGeom.h:82
const FKShapeElem * GetElementByName(const FName InName) const
Definition AggregateGeom.h:389
void EmptyElements()
Definition AggregateGeom.h:521
const FKAggregateGeom & operator=(const FKAggregateGeom &Other)
Definition AggregateGeom.h:65
FKShapeElem * GetElement(const EAggCollisionShape::Type Type, const int32 Index)
Definition AggregateGeom.h:159
SIZE_T GetAllocatedSize() const
Definition AggregateGeom.h:79
FKAggregateGeom(const FKAggregateGeom &Other)
Definition AggregateGeom.h:59
Definition BoxElem.h:16
Definition ConvexElem.h:32
Definition LevelSetElem.h:17
Definition MLLevelSetElem.h:17
Definition ShapeElem.h:35
Definition SkinnedLevelSetElem.h:13
Definition SkinnedTriangleMeshElem.h:12
Definition SphereElem.h:15
Definition SphylElem.h:16
Definition TaperedCapsuleElem.h:16
Definition UnrealTypeTraits.h:40
Definition BoxSphereBounds.h:25