UDocumentation UE5.7 10.02.2026 (Source)
API documentation for Unreal Engine 5.7
SpatialAccelerationCollection.h
Go to the documentation of this file.
1// Copyright Epic Games, Inc. All Rights Reserved.
2#pragma once
4#include "Chaos/Box.h"
7#include "ChaosStats.h"
9#include "Misc/OutputDevice.h"
10
11#include <tuple>
12
14
15namespace Chaos
16{
17
18// Bucket inner indices define for specific use cases
20{
21 Default = 0, // If acceleration structures are not split up by body type, they end up in this bucket, otherwise static bodies will go here
22 Dynamic = 1, // For dynamic bodies if they use a separate acceleration structure
23 DefaultQueryOnly = 2, // Query only bodies if they are separated
24 DynamicQueryOnly = 3 // Dynamic Query only bodies if they are separated
25};
26
27template <typename T>
28void FreeObjHelper(T*& RawPtr)
29{
30 RawPtr = nullptr;
31}
32
33template <typename TPayloadType, typename T, int d>
51
52template <typename TPayloadType, typename T, int d>
54{
55 Ar << BucketEntry.Acceleration;
56 Ar << BucketEntry.TypeInnerIdx;
57 return Ar;
58}
59
60
61template <typename TPayloadType, typename T, int d>
66
67template <typename T>
68T CopyFromHelper(const T& Src)
69{
70 return Src;
71}
72
73template <typename TPayloadType, typename T, int d>
81
82
83template <typename TObj>
85{
91
94
95 int32 Add(TObj&& Obj)
96 {
97 uint16 Idx;
98 if (FreeIndices.Num())
99 {
100 Idx = FreeIndices.Pop();
101 Objects[Idx] = MoveTemp(Obj);
102 }
103 else
104 {
105 Idx = static_cast<uint16>(Objects.Add(MoveTemp(Obj)));
106 }
107
108 return Idx;
109 }
110
111 void UpdateOrAddAt(uint16 Idx, TObj&& Obj)
112 {
113 uint16 ObjectNum = static_cast<uint16>(Objects.Num());
114 if (ObjectNum <= Idx)
115 {
116 Objects.SetNum(Idx + 1);
117 for (uint16 FreeIndex = ObjectNum; FreeIndex < Idx - 1; FreeIndex++)
118 {
120 }
121 }
122 else
123 {
124 FreeIndices.Remove(Idx);
125 }
126
127 Objects[Idx] = MoveTemp(Obj);
128 }
129
130 void Remove(uint16 Idx)
131 {
132 if (Objects.Num() == Idx + 1)
133 {
135 }
136 else
137 {
139 FreeIndices.Add(Idx);
140 }
141 }
142
144 {
145 Objects.SetNum(Src.Objects.Num());
146 for (int32 ObjIdx = 0; ObjIdx < Objects.Num(); ++ObjIdx)
147 {
149 }
151 }
152
153};
154
155template <typename TObj>
157{
158 Ar << Bucket.Objects;
159 Ar << Bucket.FreeIndices;
160 return Ar;
161}
162
163template <typename... TRemaining>
165{
166};
167
168template <typename TAcceleration, typename... TRemaining>
179
180template<int Idx, typename ... Rest>
182{
183
184};
185
186template<int Idx, typename First, typename... Rest>
187struct TSpatialTypeTupleGetter<Idx, First, Rest...>
188{
190 static const auto& Get(const TSpatialTypeTuple<First, Rest...>& Types) { return TSpatialTypeTupleGetter<Idx - 1, Rest...>::Get(Types.Remaining); }
191};
192
193template<typename First, typename... Rest>
195{
196 static auto& Get(TSpatialTypeTuple<First, Rest...>& Types) { return Types.First; }
197 static const auto& Get(const TSpatialTypeTuple<First, Rest...>& Types) { return Types.First; }
198};
199
200
201// Gets a bucket of acceleration structure pointers
202template <int Idx, typename First, typename... Rest>
207
208template <int Idx, typename First, typename... Rest>
213
214template <int TypeIdx, int NumTypes, typename Tuple, typename TPayloadType, typename T, int d>
216{
217 template <typename SQVisitor>
218 static bool RaycastFast(const Tuple& Types, const TVector<T, d>& Start, FQueryFastData& CurData, SQVisitor& Visitor, const FVec3& Dir, const FVec3 InvDir, const bool bParallel[3])
219 {
220 const auto& Accelerations = GetAccelerationsPerType<TypeIdx>(Types).Objects;
221 for (const auto& Accelerator : Accelerations)
222 {
223 if (Accelerator && !Accelerator->RaycastFast(Start, CurData, Visitor, Dir, InvDir, bParallel))
224 {
225 return false;
226 }
227 }
228
229 constexpr int NextType = TypeIdx + 1;
230 if (NextType < NumTypes)
231 {
233 }
234
235 return true;
236 }
237
238 template <typename SQVisitor>
239 static bool SweepFast(const Tuple& Types, const TVector<T, d>& Start, FQueryFastData& CurData, const TVector<T, d> QueryHalfExtents, SQVisitor& Visitor, const FVec3& Dir, const FVec3 InvDir, const bool bParallel[3])
240 {
241 const auto& Accelerations = GetAccelerationsPerType<TypeIdx>(Types).Objects;
242 for (const auto& Accelerator : Accelerations)
243 {
244 if (Accelerator && !Accelerator->SweepFast(Start, CurData, QueryHalfExtents, Visitor, Dir, InvDir, bParallel))
245 {
246 return false;
247 }
248 }
249
250 constexpr int NextType = TypeIdx + 1;
251 if (NextType < NumTypes)
252 {
254 }
255
256 return true;
257 }
258
259 template <typename SQVisitor>
260 static bool OverlapFast(const Tuple& Types, const TAABB<T, d> QueryBounds, SQVisitor& Visitor)
261 {
262 const auto& Accelerations = GetAccelerationsPerType<TypeIdx>(Types).Objects;
263 for (const auto& Accelerator : Accelerations)
264 {
265 if (Accelerator && !Accelerator->OverlapFast(QueryBounds, Visitor))
266 {
267 return false;
268 }
269 }
270
271 constexpr int NextType = TypeIdx + 1;
272 if (NextType < NumTypes)
273 {
275 }
276
277 return true;
278 }
279
281 {
282 const auto& Accelerations = GetAccelerationsPerType<TypeIdx>(Types).Objects;
283 for (const auto& Accelerator : Accelerations)
284 {
285 if (Accelerator)
286 {
287 //todo: handle early out
288 ObjList.Append(Accelerator->GlobalObjects());
289 }
290 }
291
292 constexpr int NextType = TypeIdx + 1;
293 if (NextType < NumTypes)
294 {
296 }
297 }
298
311
312 static void Reset(const Tuple& Types)
313 {
314 auto& Accelerations = GetAccelerationsPerType<TypeIdx>(Types).Objects;
315 for (auto& Accelerator : Accelerations)
316 {
317 if (Accelerator)
318 {
319 Accelerator->Reset();
320 }
321 }
322
323 constexpr int NextType = TypeIdx + 1;
324 if (NextType < NumTypes)
325 {
327 }
328 }
329
331 static void CacheOverlappingLeaves(const Tuple& Types)
332 {
333 auto& Accelerations = GetAccelerationsPerType<TypeIdx>(Types).Objects;
334 for (auto& Accelerator : Accelerations)
335 {
336 if (Accelerator)
337 {
338 Accelerator->CacheOverlappingLeaves();
339 }
340 }
341 constexpr int NextType = TypeIdx + 1;
342 if (NextType < NumTypes)
343 {
345 }
346 }
347
348 static uint16 FindTypeIdx(const Tuple& Types, SpatialAccelerationType Type)
349 {
350 using AccelType = typename std::remove_pointer<typename decltype(GetAccelerationsPerType<TypeIdx>(Types).Objects)::ElementType>::type;
351 if (AccelType::StaticType == Type)
352 {
353 return TypeIdx;
354 }
355
356 constexpr int NextType = TypeIdx + 1;
357 if (NextType < NumTypes)
358 {
360 }
361 else
362 {
363 return NumTypes;
364 }
365 }
366};
367
368template <typename SpatialAccelerationCollection>
369typename std::enable_if_t<std::is_same_v<typename SpatialAccelerationCollection::TPayloadType, FAccelerationStructureHandle>, void> PBDComputeConstraintsLowLevel_Helper(FReal Dt, const SpatialAccelerationCollection& Accel, FSpatialAccelerationBroadPhase& BroadPhase, Private::FCollisionConstraintAllocator* Allocator, const FCollisionDetectorSettings& Settings, IResimCacheBase* ResimCache)
370{
371 BroadPhase.ProduceOverlaps(Dt, Accel, Allocator, Settings, ResimCache);
372}
373
374template <typename SpatialAccelerationCollection>
375typename std::enable_if_t<!std::is_same_v<typename SpatialAccelerationCollection::TPayloadType, FAccelerationStructureHandle>, void> PBDComputeConstraintsLowLevel_Helper(FReal Dt, const SpatialAccelerationCollection& Accel, FSpatialAccelerationBroadPhase& BroadPhase, Private::FCollisionConstraintAllocator* Allocator, const FCollisionDetectorSettings& Settings, IResimCacheBase* ResimCache)
376{
377}
378
379template <typename ... TSpatialAccelerationTypes>
381 ISpatialAccelerationCollection<typename std::tuple_element<0, std::tuple< TSpatialAccelerationTypes...>>::type::PayloadType,
382 typename std::tuple_element<0, std::tuple< TSpatialAccelerationTypes...>>::type::TType,
383 std::tuple_element<0, std::tuple< TSpatialAccelerationTypes...>>::type::D>
384{
385public:
386 using FirstAccelerationType = typename std::tuple_element<0, std::tuple< TSpatialAccelerationTypes...>>::type;
387 using TPayloadType = typename FirstAccelerationType::PayloadType;
388 using T = typename FirstAccelerationType::TType;
389 static constexpr int d = FirstAccelerationType::D;
392
396
398 {
399 check(BucketIdx < MaxBuckets);
401 Result.Bucket = BucketIdx;
402
406
407 const int32 TypeIdx = GetTypeIdx(AccelPtr);
408 switch (TypeIdx)
409 {
410 case 0: BucketEntry.TypeInnerIdx = static_cast<uint16>(GetAccelerationsPerType<0>(Types).Add(&AccelPtr->template AsChecked<typename std::tuple_element<0, std::tuple<TSpatialAccelerationTypes...>>::type>())); break;
411 case 1: BucketEntry.TypeInnerIdx = static_cast<uint16>(GetAccelerationsPerType<ClampedIdx(1)>(Types).Add(&AccelPtr->template AsChecked<typename std::tuple_element<ClampedIdx(1), std::tuple<TSpatialAccelerationTypes...>>::type>())); break;
412 case 2: BucketEntry.TypeInnerIdx = static_cast<uint16>(GetAccelerationsPerType<ClampedIdx(2)>(Types).Add(&AccelPtr->template AsChecked<typename std::tuple_element<ClampedIdx(2), std::tuple<TSpatialAccelerationTypes...>>::type>())); break;
413 case 3: BucketEntry.TypeInnerIdx = static_cast<uint16>(GetAccelerationsPerType<ClampedIdx(3)>(Types).Add(&AccelPtr->template AsChecked<typename std::tuple_element<ClampedIdx(3), std::tuple<TSpatialAccelerationTypes...>>::type>())); break;
414 case 4: BucketEntry.TypeInnerIdx = static_cast<uint16>(GetAccelerationsPerType<ClampedIdx(4)>(Types).Add(&AccelPtr->template AsChecked<typename std::tuple_element<ClampedIdx(4), std::tuple<TSpatialAccelerationTypes...>>::type>())); break;
415 case 5: BucketEntry.TypeInnerIdx = static_cast<uint16>(GetAccelerationsPerType<ClampedIdx(5)>(Types).Add(&AccelPtr->template AsChecked<typename std::tuple_element<ClampedIdx(5), std::tuple<TSpatialAccelerationTypes...>>::type>())); break;
416 case 6: BucketEntry.TypeInnerIdx = static_cast<uint16>(GetAccelerationsPerType<ClampedIdx(6)>(Types).Add(&AccelPtr->template AsChecked<typename std::tuple_element<ClampedIdx(6), std::tuple<TSpatialAccelerationTypes...>>::type>())); break;
417 case 7: BucketEntry.TypeInnerIdx = static_cast<uint16>(GetAccelerationsPerType<ClampedIdx(7)>(Types).Add(&AccelPtr->template AsChecked<typename std::tuple_element<ClampedIdx(7), std::tuple<TSpatialAccelerationTypes...>>::type>())); break;
418 }
419
420 this->ActiveBucketsMask |= (1 << BucketIdx);
421
422 Result.InnerIdx = BucketInnerIdx;
424
425 return Result;
426 }
427
429 virtual void CacheOverlappingLeaves() override
430 {
432 }
433
435 {
437 {
439 const int32 TypeIdx = GetTypeIdx(BucketEntry.Acceleration.Get());
440 switch (TypeIdx)
441 {
442 case 0: GetAccelerationsPerType<0>(Types).Remove(BucketEntry.TypeInnerIdx); break;
443 case 1: GetAccelerationsPerType<ClampedIdx(1)>(Types).Remove(BucketEntry.TypeInnerIdx); break;
444 case 2: GetAccelerationsPerType<ClampedIdx(2)>(Types).Remove(BucketEntry.TypeInnerIdx); break;
445 case 3: GetAccelerationsPerType<ClampedIdx(3)>(Types).Remove(BucketEntry.TypeInnerIdx); break;
446 case 4: GetAccelerationsPerType<ClampedIdx(4)>(Types).Remove(BucketEntry.TypeInnerIdx); break;
447 case 5: GetAccelerationsPerType<ClampedIdx(5)>(Types).Remove(BucketEntry.TypeInnerIdx); break;
448 case 6: GetAccelerationsPerType<ClampedIdx(6)>(Types).Remove(BucketEntry.TypeInnerIdx); break;
449 case 7: GetAccelerationsPerType<ClampedIdx(7)>(Types).Remove(BucketEntry.TypeInnerIdx); break;
450 }
451 Removed = MoveTemp(BucketEntry.Acceleration);
452 }
453 Buckets[Idx.Bucket].Remove(Idx.InnerIdx);
454 if (Buckets[Idx.Bucket].Objects.Num() == 0)
455 {
456 this->ActiveBucketsMask &= ~(1 << Idx.Bucket);
457 }
458 return Removed;
459 }
460
462 {
463 check(Idx.Bucket < MaxBuckets);
464 if (Buckets[Idx.Bucket].Objects.Num() > 0)
465 {
466 return Buckets[Idx.Bucket].Objects[Idx.InnerIdx].Acceleration.Get();
467 }
468
469 return nullptr;
470 }
471
473 {
474 using ThisType = decltype(this);
475 ThisType Other = static_cast<ThisType>(&InOther);
476
477 check(Idx.Bucket < MaxBuckets);
478 check(Idx.Bucket < Other->MaxBuckets);
479 check(Buckets[Idx.Bucket].Objects.Num() > Idx.InnerIdx);
480 check(Other->Buckets[Idx.Bucket].Objects.Num() > Idx.InnerIdx);
481
484
485 Other->AddSubstructure(MoveTemp(ThisSubStructure), Idx.Bucket, Idx.InnerIdx);
487 }
488
489 virtual void Reset() override
490 {
492 TSpatialAccelerationCollectionHelper<0, NumTypes, decltype(Types), TPayloadType, T, d>::Reset(Types);
493 }
494
495 virtual void Raycast(const TVector<T, d>& Start, const TVector<T, d>& Dir, const T Length, ISpatialVisitor<TPayloadType, T>& Visitor) const override
496 {
498 Raycast(Start, Dir, Length, ProxyVisitor);
499 }
500
501 template <typename SQVisitor>
502 void Raycast(const TVector<T, d>& Start, const TVector<T, d>& Dir, const T Length, SQVisitor& Visitor) const
503 {
504 FQueryFastData QueryFastData(Dir, Length);
505 TSpatialAccelerationCollectionHelper<0, NumTypes, decltype(Types), TPayloadType, T, d>::RaycastFast(Types, Start, QueryFastData, Visitor, QueryFastData.Dir, QueryFastData.InvDir, QueryFastData.bParallel);
506 }
507
508 void Sweep(const TVector<T, d>& Start, const TVector<T, d>& Dir, const T Length, const TVector<T, d> QueryHalfExtents, ISpatialVisitor<TPayloadType, T>& Visitor) const override
509 {
512 }
513
514 template <typename SQVisitor>
515 void Sweep(const TVector<T, d>& Start, const TVector<T, d>& Dir, const T Length, const TVector<T, d> QueryHalfExtents, SQVisitor& Visitor) const
516 {
517 FQueryFastData QueryFastData(Dir, Length);
518 TSpatialAccelerationCollectionHelper<0, NumTypes, decltype(Types), TPayloadType, T, d>::SweepFast(Types, Start, QueryFastData, QueryHalfExtents, Visitor, QueryFastData.Dir, QueryFastData.InvDir, QueryFastData.bParallel);
519 }
520
526
527 template <typename SQVisitor>
528 typename std::enable_if_t<!std::is_same_v<SQVisitor, typename Private::FSimOverlapVisitor>, void> Overlap(const TAABB<T, 3>& QueryBounds, SQVisitor& Visitor) const
529 {
530 TSpatialAccelerationCollectionHelper<0, NumTypes, decltype(Types), TPayloadType, T, d>::OverlapFast(Types, QueryBounds, Visitor);
531 }
532
533 template <typename SQVisitor>
534 typename std::enable_if_t<std::is_same_v<SQVisitor, typename Private::FSimOverlapVisitor>, void> Overlap(const TAABB<T, 3>& QueryBounds, SQVisitor& Visitor) const
535 {
536 const BucketType& Bucket = Buckets[0];
537 {
538 int BucketInnerIdx = 0;
539 for (const BucketEntryType& BucketEntry : Bucket.Objects)
540 {
542 {
545 }
547 }
548 }
549 }
550
557
558 // visitor signature is : void Visitor(FSpatialAccelerationIdx SpatialIdx)
559 template <typename TVisitor>
560 void VisitAllSpatialIndices(TVisitor Visitor) const
561 {
562 uint16 BucketIdx = 0;
563 for (const BucketType& Bucket : Buckets)
564 {
565 uint16 InnerIdx = 0;
566 for (const BucketEntryType& Entry : Bucket.Objects)
567 {
568 if (Entry.Acceleration)
569 {
570 Visitor(FSpatialAccelerationIdx{ BucketIdx, InnerIdx });
571 }
572 ++InnerIdx;
573 }
574 ++BucketIdx;
575 }
576 }
577
579 {
580 uint16 BucketIdx = 0;
583 [&Indices](FSpatialAccelerationIdx Idx)
584 {
585 Indices.Add(Idx);
586 }
587 );
588 return Indices;
589 }
590
591 // Returns true if the element was in fact removed from some SpatialIdx, otherwise returns false if the element was not found anywhere
592 virtual bool RemoveElementFrom(const TPayloadType& Payload, FSpatialAccelerationIdx SpatialIdx) override
593 {
594 const uint16 UseBucket = ((1 << SpatialIdx.Bucket) & this->ActiveBucketsMask) ? SpatialIdx.Bucket : 0;
595 bool bSuccess = Buckets[UseBucket].Objects[SpatialIdx.InnerIdx].Acceleration->RemoveElement(Payload);
596 if (!bSuccess)
597 {
598 // Make sure that we remove this Payload even if the SpatialIdx is wrong
600 [this, &Payload, &SpatialIdx, &bSuccess](FSpatialAccelerationIdx Idx)
601 {
602 if (!(Idx == SpatialIdx))
603 {
604 const uint16 Buckt = ((1 << Idx.Bucket) & this->ActiveBucketsMask) ? Idx.Bucket : 0;
605 const bool bRemoved = Buckets[Buckt].Objects[Idx.InnerIdx].Acceleration->RemoveElement(Payload);
606 bSuccess |= bRemoved;
607 }
608 }
609 );
610 }
611 return bSuccess;
612 }
613
614 virtual bool NeedUpdateElementIn(const TPayloadType& Payload, const TAABB<T, d>& NewBounds, FSpatialAccelerationIdx SpatialIdx)
615 {
616 const uint16 UseBucket = ((1 << SpatialIdx.Bucket) & this->ActiveBucketsMask) ? SpatialIdx.Bucket : 0;
617 return Buckets[UseBucket].Objects[SpatialIdx.InnerIdx].Acceleration->NeedUpdateElement(Payload, NewBounds);
618 }
619
620 // Returns true if the element was in fact updated or if it was moved from one SpatialIdx to another during the update or false if not found at any SpatialIdx
621 virtual bool UpdateElementIn(const TPayloadType& Payload, const TAABB<T, d>& NewBounds, bool bHasBounds, FSpatialAccelerationIdx SpatialIdx)
622 {
623 const uint16 UseBucket = ((1 << SpatialIdx.Bucket) & this->ActiveBucketsMask) ? SpatialIdx.Bucket : 0;
624 bool bElementExisted = Buckets[UseBucket].Objects[SpatialIdx.InnerIdx].Acceleration->UpdateElement(Payload, NewBounds, bHasBounds);
625 // In case spatial index changed, remove this element in all other substructures
626 if (!bElementExisted)
627 {
629 [this, &Payload, &SpatialIdx, &bElementExisted](FSpatialAccelerationIdx Idx)
630 {
631 if (!(Idx == SpatialIdx))
632 {
633 const uint16 Buckt = ((1 << Idx.Bucket) & this->ActiveBucketsMask) ? Idx.Bucket : 0;
634 const bool Removed = Buckets[Buckt].Objects[Idx.InnerIdx].Acceleration->RemoveElement(Payload);
636 }
637 });
638 }
639 return bElementExisted;
640 }
641
646
651
652#if !UE_BUILD_SHIPPING
654 {
655 for (const BucketType& Bucket : Buckets)
656 {
657 for (const BucketEntryType& Entry : Bucket.Objects)
658 {
659 if (Entry.Acceleration)
660 {
661 Entry.Acceleration->DebugDraw(InInterface);
662 }
663 }
664 }
665 }
666#endif
667
668 virtual void Serialize(FChaosArchive& Ar)
669 {
670 //todo: let user serialize out bucket params
671
672 //serialize out sub structures
673 for (int BucketIdx = 0; BucketIdx < MaxBuckets; ++BucketIdx)
674 {
675 Ar << Buckets[BucketIdx];
676
677 if (Ar.IsLoading())
678 {
679 for (const BucketEntryType& Entry : Buckets[BucketIdx].Objects)
680 {
681 ISpatialAcceleration<TPayloadType, T, d>* RawPtr = Entry.Acceleration.Get();
682 const int32 TypeIdx = GetTypeIdx(RawPtr);
683 switch (TypeIdx)
684 {
685 case 0: GetAccelerationsPerType<0>(Types).Objects[Entry.TypeInnerIdx] = &RawPtr->template AsChecked<typename std::tuple_element<0, std::tuple<TSpatialAccelerationTypes...>>::type>(); break;
686 case 1: GetAccelerationsPerType<ClampedIdx(1)>(Types).Objects[Entry.TypeInnerIdx] = &RawPtr->template AsChecked<typename std::tuple_element<ClampedIdx(1), std::tuple<TSpatialAccelerationTypes...>>::type>(); break;
687 case 2: GetAccelerationsPerType<ClampedIdx(2)>(Types).Objects[Entry.TypeInnerIdx] = &RawPtr->template AsChecked<typename std::tuple_element<ClampedIdx(2), std::tuple<TSpatialAccelerationTypes...>>::type>(); break;
688 case 3: GetAccelerationsPerType<ClampedIdx(3)>(Types).Objects[Entry.TypeInnerIdx] = &RawPtr->template AsChecked<typename std::tuple_element<ClampedIdx(3), std::tuple<TSpatialAccelerationTypes...>>::type>(); break;
689 case 4: GetAccelerationsPerType<ClampedIdx(4)>(Types).Objects[Entry.TypeInnerIdx] = &RawPtr->template AsChecked<typename std::tuple_element<ClampedIdx(4), std::tuple<TSpatialAccelerationTypes...>>::type>(); break;
690 case 5: GetAccelerationsPerType<ClampedIdx(5)>(Types).Objects[Entry.TypeInnerIdx] = &RawPtr->template AsChecked<typename std::tuple_element<ClampedIdx(5), std::tuple<TSpatialAccelerationTypes...>>::type>(); break;
691 case 6: GetAccelerationsPerType<ClampedIdx(6)>(Types).Objects[Entry.TypeInnerIdx] = &RawPtr->template AsChecked<typename std::tuple_element<ClampedIdx(6), std::tuple<TSpatialAccelerationTypes...>>::type>(); break;
692 case 7: GetAccelerationsPerType<ClampedIdx(7)>(Types).Objects[Entry.TypeInnerIdx] = &RawPtr->template AsChecked<typename std::tuple_element<ClampedIdx(7), std::tuple<TSpatialAccelerationTypes...>>::type>(); break;
693 }
694 }
695 }
696 }
697 }
698
699#if !UE_BUILD_SHIPPING
700 void DumpStats() const override
701 {
702 if(GLog)
703 {
705 }
706 }
707
708 void DumpStatsTo(FOutputDevice& Ar) const override
709 {
710 for(int BucketIdx = 0; BucketIdx < MaxBuckets; ++BucketIdx)
711 {
712 const BucketType& Bucket = Buckets[BucketIdx];
713 Ar.Logf(TEXT("Bucket %d (%d entries):"), BucketIdx, Bucket.Objects.Num());
714
715 for(int EntryIdx = 0; EntryIdx < Bucket.Objects.Num(); ++EntryIdx)
716 {
717 Ar.Logf(TEXT("\tEntry %d"), EntryIdx);
718 Bucket.Objects[EntryIdx].Acceleration->DumpStatsTo(Ar);
719 Ar.Logf(TEXT(""));
720 }
721 }
722 }
723#endif
724
725private:
726
728 {
729 //need to make a deep copy of the unique ptrs and then update raw ptrs
730 TSpatialAccelerationCollectionHelper<0, NumTypes, decltype(Types), TPayloadType, T, d>::SetNumFrom(Other.Types, Types);
732
733 for (int BucketIdx = 0; BucketIdx < MaxBuckets; ++BucketIdx)
734 {
735 Buckets[BucketIdx].CopyFrom(Other.Buckets[BucketIdx]);
736 bool bFirst = true;
737 for (const BucketEntryType& Entry : Buckets[BucketIdx].Objects)
738 {
739 ISpatialAcceleration<TPayloadType, T, d>* RawPtr = Entry.Acceleration.Get();
740 const int32 TypeIdx = GetTypeIdx(RawPtr);
741 switch (TypeIdx)
742 {
743 case 0: GetAccelerationsPerType<0>(Types).Objects[Entry.TypeInnerIdx] = &RawPtr->template AsChecked<typename std::tuple_element<0, std::tuple<TSpatialAccelerationTypes...>>::type>(); break;
744 case 1: GetAccelerationsPerType<ClampedIdx(1)>(Types).Objects[Entry.TypeInnerIdx] = &RawPtr->template AsChecked<typename std::tuple_element<ClampedIdx(1), std::tuple<TSpatialAccelerationTypes...>>::type>(); break;
745 case 2: GetAccelerationsPerType<ClampedIdx(2)>(Types).Objects[Entry.TypeInnerIdx] = &RawPtr->template AsChecked<typename std::tuple_element<ClampedIdx(2), std::tuple<TSpatialAccelerationTypes...>>::type>(); break;
746 case 3: GetAccelerationsPerType<ClampedIdx(3)>(Types).Objects[Entry.TypeInnerIdx] = &RawPtr->template AsChecked<typename std::tuple_element<ClampedIdx(3), std::tuple<TSpatialAccelerationTypes...>>::type>(); break;
747 case 4: GetAccelerationsPerType<ClampedIdx(4)>(Types).Objects[Entry.TypeInnerIdx] = &RawPtr->template AsChecked<typename std::tuple_element<ClampedIdx(4), std::tuple<TSpatialAccelerationTypes...>>::type>(); break;
748 case 5: GetAccelerationsPerType<ClampedIdx(5)>(Types).Objects[Entry.TypeInnerIdx] = &RawPtr->template AsChecked<typename std::tuple_element<ClampedIdx(5), std::tuple<TSpatialAccelerationTypes...>>::type>(); break;
749 case 6: GetAccelerationsPerType<ClampedIdx(6)>(Types).Objects[Entry.TypeInnerIdx] = &RawPtr->template AsChecked<typename std::tuple_element<ClampedIdx(6), std::tuple<TSpatialAccelerationTypes...>>::type>(); break;
750 case 7: GetAccelerationsPerType<ClampedIdx(7)>(Types).Objects[Entry.TypeInnerIdx] = &RawPtr->template AsChecked<typename std::tuple_element<ClampedIdx(7), std::tuple<TSpatialAccelerationTypes...>>::type>(); break;
751 }
752 }
753 }
754 }
755
757 virtual void DeepAssign(const ISpatialAcceleration<TPayloadType, FReal, 3>& Other) override
758 {
759 check(false); //not implemented
760 }
761
762 static constexpr uint32 ClampedIdx(uint32 Idx)
763 {
764 return Idx < NumTypes ? Idx : 0;
765 }
766
768 {
769 if (Accel->template As<typename std::tuple_element<0, std::tuple< TSpatialAccelerationTypes...>>::type> ())
770 {
771 return 0;
772 }
773
774 if (Accel->template As<typename std::tuple_element<ClampedIdx(1), std::tuple< TSpatialAccelerationTypes...>>::type> ())
775 {
776 return 1;
777 }
778
779 if (Accel->template As<typename std::tuple_element<ClampedIdx(2), std::tuple< TSpatialAccelerationTypes...>>::type> ())
780 {
781 return 2;
782 }
783
784 if (Accel->template As<typename std::tuple_element<ClampedIdx(3), std::tuple< TSpatialAccelerationTypes...>>::type> ())
785 {
786 return 3;
787 }
788
789 if (Accel->template As<typename std::tuple_element<ClampedIdx(4), std::tuple< TSpatialAccelerationTypes...>>::type> ())
790 {
791 return 4;
792 }
793
794 if (Accel->template As<typename std::tuple_element<ClampedIdx(5), std::tuple< TSpatialAccelerationTypes...>>::type> ())
795 {
796 return 5;
797 }
798
799 if (Accel->template As<typename std::tuple_element<ClampedIdx(6), std::tuple< TSpatialAccelerationTypes...>>::type> ())
800 {
801 return 6;
802 }
803
804 if (Accel->template As<typename std::tuple_element<ClampedIdx(7), std::tuple< TSpatialAccelerationTypes...>>::type> ())
805 {
806 return 7;
807 }
808
809 check(false); //Did you instantiate the collection with the right template arguments?
810 return 0;
811 }
812
813 static constexpr uint16 MaxBuckets = 8;
814 BucketType Buckets[MaxBuckets];
815 TSpatialTypeTuple< TSpatialAccelerationTypes...> Types; // Have buckets of acceleration structure pointers
816 static constexpr uint32 NumTypes = sizeof...(TSpatialAccelerationTypes);
817
818 friend ::FChaosVDDataWrapperUtils;
819};
820
821
822}
#define check(expr)
Definition AssertionMacros.h:314
bool bSuccess
Definition ConvexDecomposition3.cpp:819
#define GLog
Definition CoreGlobals.h:95
#define TEXT(x)
Definition Platform.h:1272
FPlatformTypes::int32 int32
A 32-bit signed integer.
Definition Platform.h:1125
#define SCOPE_CYCLE_COUNTER(Stat)
Definition Stats.h:650
UE_FORCEINLINE_HINT TSharedRef< CastToType, Mode > StaticCastSharedRef(TSharedRef< CastFromType, Mode > const &InSharedRef)
Definition SharedPointer.h:127
return true
Definition ExternalRpcRegistry.cpp:601
UE_INTRINSIC_CAST UE_REWRITE constexpr std::remove_reference_t< T > && MoveTemp(T &&Obj) noexcept
Definition UnrealTemplate.h:520
uint8_t uint8
Definition binka_ue_file_header.h:8
uint16_t uint16
Definition binka_ue_file_header.h:7
uint32_t uint32
Definition binka_ue_file_header.h:6
Definition ChaosArchive.h:167
Definition CollisionContext.h:17
Definition SpatialAccelerationBroadPhase.h:335
Definition ResimCacheBase.h:11
Definition ISpatialAcceleration.h:166
Definition ISpatialAccelerationCollection.h:23
Definition ISpatialAcceleration.h:267
TConcrete * As()
Definition ISpatialAcceleration.h:385
TConcrete & AsChecked()
Definition ISpatialAcceleration.h:397
Definition ISpatialAcceleration.h:120
An allocator and container of collision constraints that supports reuse of constraints from the previ...
Definition CollisionConstraintAllocator.h:234
Definition AABBTree.h:786
bool OverlapFast(const FAABB3 &QueryBounds, SQVisitor &Visitor) const
Definition AABBTree.h:1027
Definition AABB.h:37
Definition SpatialAccelerationCollection.h:384
virtual bool NeedUpdateElementIn(const TPayloadType &Payload, const TAABB< T, d > &NewBounds, FSpatialAccelerationIdx SpatialIdx)
Definition SpatialAccelerationCollection.h:614
virtual bool RemoveElementFrom(const TPayloadType &Payload, FSpatialAccelerationIdx SpatialIdx) override
Definition SpatialAccelerationCollection.h:592
virtual void SwapSubstructure(ISpatialAccelerationCollection< TPayloadType, T, d > &InOther, FSpatialAccelerationIdx Idx) override
Definition SpatialAccelerationCollection.h:472
TSpatialAccelerationBucketEntry< TPayloadType, T, d > BucketEntryType
Definition SpatialAccelerationCollection.h:390
std::enable_if_t< std::is_same_v< SQVisitor, typename Private::FSimOverlapVisitor >, void > Overlap(const TAABB< T, 3 > &QueryBounds, SQVisitor &Visitor) const
Definition SpatialAccelerationCollection.h:534
virtual void CacheOverlappingLeaves() override
Definition SpatialAccelerationCollection.h:429
TSpatialAccelerationCollection()
Definition SpatialAccelerationCollection.h:393
virtual TArray< FSpatialAccelerationIdx > GetAllSpatialIndices() const override
Definition SpatialAccelerationCollection.h:578
void Sweep(const TVector< T, d > &Start, const TVector< T, d > &Dir, const T Length, const TVector< T, d > QueryHalfExtents, ISpatialVisitor< TPayloadType, T > &Visitor) const override
Definition SpatialAccelerationCollection.h:508
virtual TUniquePtr< ISpatialAcceleration< TPayloadType, T, d > > RemoveSubstructure(FSpatialAccelerationIdx Idx) override
Definition SpatialAccelerationCollection.h:434
virtual void Overlap(const TAABB< T, d > &QueryBounds, ISpatialVisitor< TPayloadType, T > &Visitor) const override
Definition SpatialAccelerationCollection.h:521
typename FirstAccelerationType::PayloadType TPayloadType
Definition SpatialAccelerationCollection.h:387
typename std::tuple_element< 0, std::tuple< TSpatialAccelerationTypes... > >::type FirstAccelerationType
Definition SpatialAccelerationCollection.h:386
virtual TUniquePtr< ISpatialAcceleration< TPayloadType, T, d > > Copy() const
Definition SpatialAccelerationCollection.h:642
virtual void PBDComputeConstraintsLowLevel(T Dt, FSpatialAccelerationBroadPhase &BroadPhase, Private::FCollisionConstraintAllocator *Allocator, const FCollisionDetectorSettings &Settings, IResimCacheBase *ResimCache) const override
Definition SpatialAccelerationCollection.h:647
TSpatialCollectionBucket< BucketEntryType > BucketType
Definition SpatialAccelerationCollection.h:391
virtual FSpatialAccelerationIdx AddSubstructure(TUniquePtr< ISpatialAcceleration< TPayloadType, T, d > > &&Substructure, uint16 BucketIdx, uint16 BucketInnerIdx) override
Definition SpatialAccelerationCollection.h:397
static constexpr int d
Definition SpatialAccelerationCollection.h:389
std::enable_if_t<!std::is_same_v< SQVisitor, typename Private::FSimOverlapVisitor >, void > Overlap(const TAABB< T, 3 > &QueryBounds, SQVisitor &Visitor) const
Definition SpatialAccelerationCollection.h:528
virtual void DebugDraw(ISpacialDebugDrawInterface< T > *InInterface) const override
Definition SpatialAccelerationCollection.h:653
virtual void Raycast(const TVector< T, d > &Start, const TVector< T, d > &Dir, const T Length, ISpatialVisitor< TPayloadType, T > &Visitor) const override
Definition SpatialAccelerationCollection.h:495
void Raycast(const TVector< T, d > &Start, const TVector< T, d > &Dir, const T Length, SQVisitor &Visitor) const
Definition SpatialAccelerationCollection.h:502
void DumpStatsTo(FOutputDevice &Ar) const override
Definition SpatialAccelerationCollection.h:708
void Sweep(const TVector< T, d > &Start, const TVector< T, d > &Dir, const T Length, const TVector< T, d > QueryHalfExtents, SQVisitor &Visitor) const
Definition SpatialAccelerationCollection.h:515
TArray< TPayloadBoundsElement< TPayloadType, T > > GlobalObjects() const
Definition SpatialAccelerationCollection.h:551
virtual void Reset() override
Definition SpatialAccelerationCollection.h:489
void VisitAllSpatialIndices(TVisitor Visitor) const
Definition SpatialAccelerationCollection.h:560
virtual void Serialize(FChaosArchive &Ar)
Definition SpatialAccelerationCollection.h:668
void DumpStats() const override
Definition SpatialAccelerationCollection.h:700
virtual bool UpdateElementIn(const TPayloadType &Payload, const TAABB< T, d > &NewBounds, bool bHasBounds, FSpatialAccelerationIdx SpatialIdx)
Definition SpatialAccelerationCollection.h:621
typename FirstAccelerationType::TType T
Definition SpatialAccelerationCollection.h:388
virtual ISpatialAcceleration< TPayloadType, T, d > * GetSubstructure(FSpatialAccelerationIdx Idx) override
Definition SpatialAccelerationCollection.h:461
Definition ISpatialAcceleration.h:453
Definition Vector.h:41
UE_FORCEINLINE_HINT bool IsLoading() const
Definition Archive.h:236
Definition ChaosVDDataWrapperUtils.h:77
Definition OutputDevice.h:133
void Logf(const FmtType &Fmt)
Definition OutputDevice.h:234
Definition Array.h:670
SizeType Remove(const ElementType &Item)
Definition Array.h:3091
UE_REWRITE SizeType Num() const
Definition Array.h:1144
void SetNum(SizeType NewNum, EAllowShrinking AllowShrinking=UE::Core::Private::AllowShrinkingByDefault< AllocatorType >())
Definition Array.h:2308
UE_NODEBUG UE_FORCEINLINE_HINT SizeType Add(ElementType &&Item)
Definition Array.h:2696
ElementType Pop(EAllowShrinking AllowShrinking=UE::Core::Private::AllowShrinkingByDefault< AllocatorType >())
Definition Array.h:1196
Definition UniquePtr.h:107
Definition SkeletalMeshComponent.h:307
FChaosArchive & operator<<(FChaosArchive &Ar, FRigidParticleControlFlags &Flags)
Definition RigidParticleControlFlags.cpp:15
FRealDouble FReal
Definition Real.h:22
auto & GetAccelerationsPerType(TSpatialTypeTuple< First, Rest... > &Types)
Definition SpatialAccelerationCollection.h:203
uint8 SpatialAccelerationType
Definition ISpatialAcceleration.h:178
@ Raycast
Definition SimulationModuleBase.h:145
void FreeObjHelper(T *&RawPtr)
Definition SpatialAccelerationCollection.h:28
std::enable_if_t< std::is_same_v< typename SpatialAccelerationCollection::TPayloadType, FAccelerationStructureHandle >, void > PBDComputeConstraintsLowLevel_Helper(FReal Dt, const SpatialAccelerationCollection &Accel, FSpatialAccelerationBroadPhase &BroadPhase, Private::FCollisionConstraintAllocator *Allocator, const FCollisionDetectorSettings &Settings, IResimCacheBase *ResimCache)
Definition SpatialAccelerationCollection.h:369
T CopyFromHelper(const T &Src)
Definition SpatialAccelerationCollection.h:68
ESpatialAccelerationCollectionBucketInnerIdx
Definition SpatialAccelerationCollection.h:20
@ DefaultQueryOnly
Definition SpatialAccelerationCollection.h:23
@ Dynamic
Definition SpatialAccelerationCollection.h:22
@ DynamicQueryOnly
Definition SpatialAccelerationCollection.h:24
@ Default
Definition SpatialAccelerationCollection.h:21
@ NumTypes
Definition InputCoreTypes.h:783
Definition ISpatialAcceleration.h:14
const FVec3 & Dir
Definition ISpatialAcceleration.h:24
const FVec3 InvDir
Definition ISpatialAcceleration.h:25
const bool bParallel[3]
Definition ISpatialAcceleration.h:30
Definition GeometryParticlesfwd.h:59
uint16 InnerIdx
Definition GeometryParticlesfwd.h:61
uint16 Bucket
Definition GeometryParticlesfwd.h:60
Definition ISpatialAcceleration.h:226
Definition SpatialAccelerationCollection.h:35
void CopyFrom(TSpatialAccelerationBucketEntry< TPayloadType, T, d > &Src)
Definition SpatialAccelerationCollection.h:39
TUniquePtr< ISpatialAcceleration< TPayloadType, T, d > > Acceleration
Definition SpatialAccelerationCollection.h:36
TSpatialAccelerationBucketEntry< TPayloadType, T, d > & operator=(TSpatialAccelerationBucketEntry< TPayloadType, T, d > &Other)=delete
TSpatialAccelerationBucketEntry(TSpatialAccelerationBucketEntry< TPayloadType, T, d > &&Other)=default
TSpatialAccelerationBucketEntry< TPayloadType, T, d > & operator=(TSpatialAccelerationBucketEntry< TPayloadType, T, d > &&Other)=default
TSpatialAccelerationBucketEntry(const TSpatialAccelerationBucketEntry< TPayloadType, T, d > &Other)=delete
uint16 TypeInnerIdx
Definition SpatialAccelerationCollection.h:37
Definition SpatialAccelerationCollection.h:216
static void GlobalObjects(const Tuple &Types, TArray< TPayloadBoundsElement< TPayloadType, T > > &ObjList)
Definition SpatialAccelerationCollection.h:280
static bool OverlapFast(const Tuple &Types, const TAABB< T, d > QueryBounds, SQVisitor &Visitor)
Definition SpatialAccelerationCollection.h:260
static bool SweepFast(const Tuple &Types, const TVector< T, d > &Start, FQueryFastData &CurData, const TVector< T, d > QueryHalfExtents, SQVisitor &Visitor, const FVec3 &Dir, const FVec3 InvDir, const bool bParallel[3])
Definition SpatialAccelerationCollection.h:239
static bool RaycastFast(const Tuple &Types, const TVector< T, d > &Start, FQueryFastData &CurData, SQVisitor &Visitor, const FVec3 &Dir, const FVec3 InvDir, const bool bParallel[3])
Definition SpatialAccelerationCollection.h:218
static uint16 FindTypeIdx(const Tuple &Types, SpatialAccelerationType Type)
Definition SpatialAccelerationCollection.h:348
static void Reset(const Tuple &Types)
Definition SpatialAccelerationCollection.h:312
static void SetNumFrom(const Tuple &TypesSrc, Tuple &TypesDest)
Definition SpatialAccelerationCollection.h:299
static void CacheOverlappingLeaves(const Tuple &Types)
Definition SpatialAccelerationCollection.h:331
Definition SpatialAccelerationCollection.h:85
TSpatialCollectionBucket< TObj > & operator=(TSpatialCollectionBucket< TObj > &&Other)=default
TArray< TObj > Objects
Definition SpatialAccelerationCollection.h:92
TSpatialCollectionBucket< TObj > & operator=(const TSpatialCollectionBucket< TObj > &Other)=delete
TSpatialCollectionBucket(const TSpatialCollectionBucket< TObj > &Other)=delete
void UpdateOrAddAt(uint16 Idx, TObj &&Obj)
Definition SpatialAccelerationCollection.h:111
TSpatialCollectionBucket(TSpatialCollectionBucket< TObj > &&Other)=default
TArray< uint16 > FreeIndices
Definition SpatialAccelerationCollection.h:93
int32 Add(TObj &&Obj)
Definition SpatialAccelerationCollection.h:95
void CopyFrom(const TSpatialCollectionBucket &Src)
Definition SpatialAccelerationCollection.h:143
void Remove(uint16 Idx)
Definition SpatialAccelerationCollection.h:130
static auto & Get(TSpatialTypeTuple< First, Rest... > &Types)
Definition SpatialAccelerationCollection.h:196
static const auto & Get(const TSpatialTypeTuple< First, Rest... > &Types)
Definition SpatialAccelerationCollection.h:197
static const auto & Get(const TSpatialTypeTuple< First, Rest... > &Types)
Definition SpatialAccelerationCollection.h:190
static auto & Get(TSpatialTypeTuple< First, Rest... > &Types)
Definition SpatialAccelerationCollection.h:189
Definition SpatialAccelerationCollection.h:182
TSpatialTypeTuple< TRemaining... > Remaining
Definition SpatialAccelerationCollection.h:173
TSpatialCollectionBucket< TAcceleration * > First
Definition SpatialAccelerationCollection.h:172
TSpatialTypeTuple(const TSpatialTypeTuple< TAcceleration, TRemaining... > &Other)=delete
TAcceleration FirstType
Definition SpatialAccelerationCollection.h:171
Definition SpatialAccelerationCollection.h:165