UDocumentation UE5.7 10.02.2026 (Source)
API documentation for Unreal Engine 5.7
RewindData.h
Go to the documentation of this file.
1// Copyright Epic Games, Inc. All Rights Reserved.
2#pragma once
3#include "Chaos/Core.h"
10
11#ifndef VALIDATE_REWIND_DATA
12#define VALIDATE_REWIND_DATA 0
13#endif
14
15#ifndef DEBUG_REWIND_DATA
16#define DEBUG_REWIND_DATA 0
17#endif
18
19#ifndef DEBUG_NETWORK_PHYSICS
20#define DEBUG_NETWORK_PHYSICS 0
21#endif
22
23namespace Chaos
24{
25 namespace Private
26 {
27 class FPBDIsland;
28 }
29
32{
34
37
40
42 virtual void Initialize() { }
43
46
48 FORCEINLINE virtual bool HasValidData(const int32 ValidFrame) const { return false; }
49
55 FORCEINLINE virtual int32 CountValidData(const uint32 StartFrame, const uint32 EndFrame, const bool bIncludeUnimportant = true, const bool bIncludeImportant = false) { return 0; }
56
58 FORCEINLINE virtual int32 CountAlteredData(const bool bIncludeUnimportant = true, const bool bIncludeImportant = false) { return 0; }
59
62 FORCEINLINE virtual void SetImportant(const bool bImportant, const int32 Frame = INDEX_NONE) {}
63
65 FORCEINLINE virtual bool ExtractData(const int32 ExtractFrame, const bool bResetSolver, void* HistoryData, const bool bExactFrame = false) { return true; }
66
68 FORCEINLINE virtual void ApplyDataRange(const int32 FromFrame, const int32 ToFrame, void* ActorComponent, const bool bOnlyImportant = false) {}
69
71 FORCEINLINE virtual void MergeData(const int32 FromFrame, void* ToData) {}
72
74 FORCEINLINE virtual bool RecordData(const int32 RecordFrame, const void* HistoryData) { return true; }
75
77 FORCEINLINE virtual bool RecordDataGrowingOrdered(const void* HistoryData) { return true; }
78
81
85 virtual bool CopyAllData(Chaos::FBaseRewindHistory& OutHistory, bool bIncludeUnimportant = true, bool bIncludeImportant = false) { return false; }
86
90 virtual bool CopyAlteredData(Chaos::FBaseRewindHistory& OutHistory, bool bIncludeUnimportant = true, bool bIncludeImportant = false) { return false; }
91
97 virtual bool CopyData(Chaos::FBaseRewindHistory& OutHistory, const uint32 StartFrame, const uint32 EndFrame, bool bIncludeUnimportant = true, bool bIncludeImportant = false) { return false; }
98
101
105 virtual TUniquePtr<FBaseRewindHistory> CopyFramesWithOffset(const uint32 StartFrame, const uint32 EndFrame, const int32 FrameOffset) = 0;
106
110 virtual int32 ReceiveNewData(FBaseRewindHistory& NewData, const int32 FrameOffset, const bool CompareDataForRewind = false, const bool bImportant = false, int32 TryInjectAtFrame = INDEX_NONE) { return INDEX_NONE; }
111
112 UE_DEPRECATED(5.7, "Deprecated, use the ReceiveNewData call with parameter InjectAtFrameIfEmpty, pass in nullptr to opt out of implementing a function.")
113 virtual int32 ReceiveNewData(FBaseRewindHistory& NewData, const int32 FrameOffset, const bool CompareDataForRewind = false, const bool bImportant = false)
114 {
115 return ReceiveNewData(NewData, FrameOffset, CompareDataForRewind, bImportant, INDEX_NONE);
116 }
117
119 UE_DEPRECATED(5.6, "Deprecated, use the NetSerialize call with parameter that takes a function DataSetupFunction, pass in nullptr to opt out of implementing a function.")
120 virtual void NetSerialize(FArchive& Ar, UPackageMap* PackageMap) { NetSerialize(Ar, PackageMap, [](void* Data, const int32 DataIndex){}); }
121
123 virtual void NetSerialize(FArchive& Ar, UPackageMap* PackageMap, TUniqueFunction<void(void* Data, const int32 DataIndex)> DataSetupFunction) {}
124
126 virtual void ValidateDataInHistory(const void* ActorComponent) {}
127
129 FORCEINLINE virtual void DebugData(const FString& DebugText) { }
130
133
135 UE_DEPRECATED(5.6, "Deprecated, RewindStates is no longer viable. Any custom states can be applied during IRewindCallback::ProcessInputs_Internal during resimulation. Example FNetworkPhysicsCallback")
136 FORCEINLINE virtual bool RewindStates(const int32 RewindFrame, const bool bResetSolver) { return false; }
137
139 UE_DEPRECATED(5.6, "Deprecated, ApplyInputs is no longer viable. Any custom inputs can be applied during IRewindCallback::ProcessInputs_Internal during resimulation. Example FNetworkPhysicsCallback")
140 FORCEINLINE virtual bool ApplyInputs(const int32 ApplyFrame, const bool bResetSolver) { return false; }
141
143 virtual const int32 GetLatestFrame() const { return INDEX_NONE; }
144
146 virtual const int32 GetEarliestFrame() const { return INT_MAX; }
147
149 virtual const int32 GetHistorySize() const { return 0; }
150
152 virtual const bool HasDataInHistory() const { return false; }
153
156
158 virtual void ResetFast() {}
159};
160
162template<typename DataType>
164{
170
177
179 virtual void Initialize()
180 {
182 // Iterate over current data to find latest frame
183 for (int32 FrameIndex = 0; FrameIndex < NumFrames; ++FrameIndex)
184 {
185 LatestFrame = FMath::Max(LatestFrame, DataHistory[FrameIndex].LocalFrame);
186 }
187 }
188
189protected:
190
193 {
195 for (int32 FrameIndex = 0; FrameIndex < NumFrames; ++FrameIndex)
196 {
197 const int32 ValidFrame = bMinData ? FMath::Max(0, DataFrame - FrameIndex) : DataFrame + FrameIndex;
199
200 if (DataHistory[ValidIndex].LocalFrame == ValidFrame)
201 {
203 break;
204 }
205 }
206 return ClosestIndex;
207 }
208
209public :
210
212 FORCEINLINE virtual bool HasValidData(const int32 ValidFrame) const override
213 {
215 return ValidFrame == DataHistory[ValidIndex].LocalFrame;
216 }
217
219 FORCEINLINE virtual bool ExtractData(const int32 ExtractFrame, const bool bResetSolver, void* HistoryData, const bool bExactFrame = false) override
220 {
221 // Early out if we are trying to extract data later than latest frame but the latest data is more than the whole buffer size old, don't extrapolate that far.
223 {
224 return false;
225 }
226
228 if (ExtractFrame == DataHistory[ExtractIndex].LocalFrame)
229 {
232 *static_cast<DataType*>(HistoryData) = DataHistory[CurrentIndex];
233 return true;
234 }
235 else if(!bExactFrame)
236 {
237#if DEBUG_NETWORK_PHYSICS
238 if (bResetSolver)
239 {
240 UE_LOG(LogChaos, Warning, TEXT(" Unable to extract data at frame %d while rewinding the simulation"), ExtractFrame);
241 }
242#endif
245
247 {
248 DataType& ExtractedData = *static_cast<DataType*>(HistoryData);
250
251 const int32 DeltaFrame = FMath::Abs(ExtractFrame - DataHistory[MinFrameIndex].LocalFrame);
252
253 ExtractedData.LocalFrame = ExtractFrame;
254 ExtractedData.ServerFrame += DeltaFrame;
255 ExtractedData.bDataAltered = true; // This history entry is now altered and doesn't correspond to the source entry
256
260
261#if DEBUG_NETWORK_PHYSICS
262 UE_LOG(LogChaos, Log, TEXT(" Interpolating data between frame %d and %d - > [%d]"), DataHistory[MinFrameIndex].LocalFrame, DataHistory[MaxFrameIndex].LocalFrame, ExtractedData.LocalFrame);
263#endif
264 return true;
265 }
266 else if (MinFrameIndex != INDEX_NONE)
267 {
268 DataType& ExtractedData = *static_cast<DataType*>(HistoryData);
270
271 const int32 DeltaFrame = FMath::Abs(ExtractFrame - DataHistory[MinFrameIndex].LocalFrame);
272
273 ExtractedData.LocalFrame = ExtractFrame;
274 ExtractedData.ServerFrame += DeltaFrame;
275 ExtractedData.bDataAltered = true; // This history entry is now altered and doesn't correspond to the source entry
276
277#if DEBUG_NETWORK_PHYSICS
278 UE_LOG(LogChaos, Log, TEXT(" Setting data to frame %d"), DataHistory[MinFrameIndex].LocalFrame);
279#endif
280 return true;
281 }
282 else
283 {
284#if DEBUG_NETWORK_PHYSICS
285 UE_LOG(LogChaos, Log, TEXT(" Failed to find data bounds : Min = %d | Max = %d"), MinFrameIndex, MaxFrameIndex);
286#endif
287 return false;
288 }
289 }
290 return false;
291 }
292
293 FORCEINLINE virtual void MergeData(int32 FromFrame, void* ToData) override
294 {
295 const int32 ToFrame = static_cast<DataType*>(ToData)->LocalFrame;
296 for (; FromFrame < ToFrame; FromFrame++)
297 {
298 const int32 FromIndex = GetFrameIndex(FromFrame);
299 if (FromFrame == DataHistory[FromIndex].LocalFrame)
300 {
301 static_cast<DataType*>(ToData)->MergeData(DataHistory[FromIndex]);
302 static_cast<DataType*>(ToData)->bDataAltered = true; // This history entry is now altered and doesn't correspond to the source entry
303 }
304 }
305 }
306
309 {
310 const int32 LoadIndex = GetFrameIndex(LoadFrame);
312 CurrentIndex = LoadIndex;
313 return true;
314 }
315
318 {
320 if (EvalFrame == DataHistory[EvalIndex].LocalFrame)
321 {
324 return true;
325 }
326 return false;
327 }
328
329 FORCEINLINE virtual bool RecordData(const int32 RecordFrame, const void* HistoryData) override
330 {
331 LoadData(RecordFrame);
332
333 const DataType* HistoryDataCast = static_cast<const DataType*>(HistoryData);
334
335 // If incremental recording, early out if currently cached data is newer than the data to record
336 if (bIncremental && DataHistory[CurrentIndex].LocalFrame >= HistoryDataCast->LocalFrame)
337 {
338 return false;
339 }
340
342
343 LatestFrame = FMath::Max(LatestFrame, DataHistory[CurrentIndex].LocalFrame);
344 return true;
345 }
346
347 FORCEINLINE virtual bool RecordDataGrowingOrdered(const void* HistoryData) override
348 {
349 const DataType* HistoryDataCast = static_cast<const DataType*>(HistoryData);
350
351 int32 InsertAtIdx = 0;
352 int32 StoredFrame = 0;
353
354 if (NumFrames > 0)
355 {
356 for (int32 Idx = CurrentIndex; Idx >= 0; Idx--)
357 {
358 StoredFrame = DataHistory[Idx].LocalFrame;
359 if (StoredFrame == HistoryDataCast->LocalFrame)
360 {
361 // Data for frame already stored
362 return false;
363 }
364 else if (StoredFrame < HistoryDataCast->LocalFrame)
365 {
366 // Found index where earlier data is stored, insert newer data on the next index
367 InsertAtIdx = Idx + 1;
368 break;
369 }
370 }
371 }
372
374
375 NumFrames++;
377 LatestFrame = FMath::Max(LatestFrame, HistoryDataCast->LocalFrame);
378
379 return true;
380 }
381
382 FORCEINLINE virtual void SetRecordDataIncremental(const bool bInIncremental) override
383 {
385 }
386
388 {
390 bool bHasCopiedData = false;
391
392 for (int32 CopyIndex = 0; CopyIndex < NumFrames; ++CopyIndex)
393 {
395 }
396 return bHasCopiedData;
397 }
398
400 DataType& GetCurrentData() { return DataHistory[CurrentIndex]; }
401
402 const DataType& GetCurrentData() const { return DataHistory[CurrentIndex]; }
403
406 {
408 for (int32 FrameIndex = 0; FrameIndex < NumFrames; ++FrameIndex)
409 {
410 DataType& Data = DataHistory[FrameIndex];
411 if (Data.LocalFrame > INDEX_NONE && Data.LocalFrame < EarliestFrame)
412 {
413 CurrentIndex = FrameIndex;
414 CurrentFrame = Data.LocalFrame;
416 }
417 }
418
419 return GetCurrentData();
420 }
421
424 {
425 if (NumFrames > 0)
426 {
427 const int32 NextIndex = GetFrameIndex(CurrentIndex + 1);
428 if (DataHistory[NextIndex].LocalFrame > CurrentFrame)
429 {
430 CurrentIndex = NextIndex;
431 CurrentFrame = DataHistory[NextIndex].LocalFrame;
432
433 return &DataHistory[NextIndex];
434 }
435 }
436
437 return nullptr;
438 }
439
441 FORCEINLINE uint32 NumValidData(const uint32 StartFrame, const uint32 EndFrame) const
442 {
443 uint32 NumData = 0;
444 for (uint32 ValidFrame = StartFrame; ValidFrame < EndFrame; ++ValidFrame)
445 {
447 if (ValidFrame == DataHistory[ValidIndex].LocalFrame)
448 {
449 ++NumData;
450 }
451 }
452 return NumData;
453 }
454
457
459 virtual const int32 GetLatestFrame() const override
460 {
461 return LatestFrame;
462 }
463
465 virtual const int32 GetEarliestFrame() const override
466 {
468
469 for (int32 FrameIndex = 0; FrameIndex < NumFrames; ++FrameIndex)
470 {
471 if (DataHistory[FrameIndex].LocalFrame > INDEX_NONE)
472 {
473 EarliestFrame = FMath::Min(EarliestFrame, DataHistory[FrameIndex].LocalFrame);
474 }
475 }
476
477 return EarliestFrame;
478 }
479
481 virtual const int32 GetHistorySize() const
482 {
483 return NumFrames;
484 }
485
486 virtual const bool HasDataInHistory() const
487 {
488 return LatestFrame > INDEX_NONE;
489 }
490
493 {
494 if (NumFrames != FrameCount)
495 {
496 NumFrames = FrameCount;
499 }
500 }
501
504 {
505 if (NumFrames <= 0)
506 {
507 return 0u;
508 }
509
510 int32 Idx = Frame % NumFrames;
511 if (Idx < 0)
512 {
513 Idx = Idx + NumFrames;
514 }
515
516 return static_cast<uint32>(Idx);
517 }
518
519 FORCEINLINE virtual void ResetFast()
520 {
522 CurrentFrame = 0;
523 CurrentIndex = 0;
524 }
525
526protected :
527
530
533
536
539
542
545
548};
549
551{
553 {
554 //The particle state before PushData, server state update, or any sim callbacks are processed
555 //This is the results of the previous frame before any GT modifications are made in this frame
556 //This is what the server state should be compared against
557 //This is what we rewind to before a resim
559
560 //The particle state after PushData is applied, but before any server state is applied
562
563 //The particle state after sim callbacks are applied.
564 //This is used to detect desync of particles before simulation itself is run (these desyncs can come from server state or the sim callback itself)
566
568 };
569
572
573 bool operator<(const FFrameAndPhase& Other) const
574 {
575 return Frame < Other.Frame || (Frame == Other.Frame && Phase < Other.Phase);
576 }
577
578 bool operator<=(const FFrameAndPhase& Other) const
579 {
580 return Frame < Other.Frame || (Frame == Other.Frame && Phase <= Other.Phase);
581 }
582
583 bool operator==(const FFrameAndPhase& Other) const
584 {
585 return Frame == Other.Frame && Phase == Other.Phase;
586 }
587};
588
589template <typename THandle, typename T, bool bNoEntryIsHead>
591{
592 static bool Helper(const THandle& Handle)
593 {
594 //nothing written so we're pointing to the particle which means it's in sync
595 return true;
596 }
597};
598
599template <typename THandle, typename T>
601{
602 static bool Helper(const THandle& Handle)
603 {
604 //nothing written so compare to zero
605 T HeadVal;
606 HeadVal.CopyFrom(Handle);
607 return HeadVal == T::ZeroValue();
608 }
609};
610
616
617template <typename TData, typename TObj>
618void CopyDataFromObject(TData& Data, const TObj& Obj)
619{
620 Data.CopyFrom(Obj);
621}
622
624{
625 Data = Joint.GetSettings();
626}
627
628template <typename T, EChaosProperty PropName, bool bNoEntryIsHead = true>
630{
631public:
633 : Next(0)
634 , NumValid(0)
635 , Capacity(InCapacity)
636 {
637 }
638
640 : Next(Other.Next)
641 , NumValid(Other.NumValid)
642 , Capacity(Other.Capacity)
643 , Buffer(MoveTemp(Other.Buffer))
644 {
645 Other.NumValid = 0;
646 Other.Next = 0;
647 }
648
650
652 {
653 //Need to explicitly cleanup before destruction using Release (release back into the pool)
654 ensure(Buffer.Num() == 0);
655 }
656
657 //Gets access into buffer in monotonically increasing FrameAndPhase order: x_{n+1} > x_n
659 {
660 return *WriteAccessImp<true>(FrameAndPhase, Manager);
661 }
662
663 //Gets access into buffer in non-decreasing FrameAndPhase order: x_{n+1} >= x_n
664 //If x_{n+1} == x_n we return null to inform the user (usefull when a single phase can have multiple writes)
666 {
667 return WriteAccessImp<false>(FrameAndPhase, Manager);
668 }
669
670 //Searches in reverse order for interval that contains FrameAndPhase
671 const T* Read(const FFrameAndPhase FrameAndPhase, const FDirtyPropertiesPool& Manager) const
672 {
673 const int32 Idx = FindIdx(FrameAndPhase);
674 return Idx != INDEX_NONE ? &GetPool(Manager).GetElement(Buffer[Idx].Ref) : nullptr;
675 }
676
677 //Get the FrameAndPhase of the head / last entry
679 {
680 if (NumValid)
681 {
682 const int32 Prev = Next == 0 ? Buffer.Num() - 1 : Next - 1;
683 OutFrameAndPhase = Buffer[Prev].FrameAndPhase;
684 return true;
685 }
686 return false;
687 }
688
689 //Releases data back into the pool
691 {
692 TPropertyPool<T>& Pool = GetPool(Manager);
693 for(FPropertyInterval& Interval : Buffer)
694 {
695 Pool.RemoveElement(Interval.Ref);
696 }
697
698 Buffer.Empty();
699 NumValid = 0;
700 }
701
702 void Reset()
703 {
704 NumValid = 0;
705 }
706
707 bool IsEmpty() const
708 {
709 return NumValid == 0;
710 }
711
712 void ClearEntryAndFuture(const FFrameAndPhase FrameAndPhase)
713 {
714 //Move next backwards until FrameAndPhase and anything more future than it is gone
715 while (NumValid)
716 {
717 const int32 PotentialNext = Next - 1 >= 0 ? Next - 1 : Buffer.Num() - 1;
718
719 if (Buffer[PotentialNext].FrameAndPhase < FrameAndPhase)
720 {
721 break;
722 }
723
724 Next = PotentialNext;
725 --NumValid;
726 }
727 }
728
729 void ExtractBufferState(int32& ValidCount, int32& NextIterator) const
730 {
731 ValidCount = NumValid;
732 NextIterator = Next;
733 }
734
735 void RestoreBufferState(const int32& ValidCount, const int32& NextIterator)
736 {
737 NumValid = ValidCount;
738 Next = NextIterator;
739 }
740
741 bool IsClean(const FFrameAndPhase FrameAndPhase) const
742 {
743 return FindIdx(FrameAndPhase) == INDEX_NONE;
744 }
745
746 template <typename THandle>
747 bool IsInSync(const THandle& Handle, const FFrameAndPhase FrameAndPhase, const FDirtyPropertiesPool& Pool) const
748 {
749 if (const T* Val = Read(FrameAndPhase, Pool))
750 {
751 T HeadVal;
753 return *Val == HeadVal;
754 }
755
757 }
758
759 T& Insert(const FFrameAndPhase FrameAndPhase, FDirtyPropertiesPool& Manager)
760 {
761 T* Result = nullptr;
762
763 int32 FrameIndex = FindIdx(FrameAndPhase);
764 if (FrameIndex != INDEX_NONE)
765 {
766 Result = &GetPool(Manager).GetElement(Buffer[FrameIndex].Ref);
767 }
768 else
769 {
770 FPropertyIdx ElementRef;
771 if (Next >= Buffer.Num())
772 {
773 GetPool(Manager).AddElement(ElementRef);
774 Buffer.Add({ ElementRef, FrameAndPhase });
775 }
776 else
777 {
778 ElementRef = Buffer[Next].Ref;
779 }
780 Result = &GetPool(Manager).GetElement(ElementRef);
781
782 int32 PrevFrame = Next;
783 int32 NextFrame = PrevFrame;
784 for (int32 Count = 0; Count < NumValid; ++Count)
785 {
786 NextFrame = PrevFrame;
787
788 --PrevFrame;
789 if (PrevFrame < 0) { PrevFrame = Buffer.Num() - 1; }
790
792 if (PrevInterval.FrameAndPhase < FrameAndPhase)
793 {
794 Buffer[NextFrame].FrameAndPhase = FrameAndPhase;
795 Buffer[NextFrame].Ref = ElementRef;
796 break;
797 }
798 else
799 {
800 Buffer[NextFrame] = Buffer[PrevFrame];
801
802 if (Count == NumValid - 1)
803 {
804 // If we shift back and reach the end of the buffer, insert here
805 Buffer[PrevFrame].FrameAndPhase = FrameAndPhase;
806 Buffer[PrevFrame].Ref = ElementRef;
807 }
808 }
809 }
810
811 ++Next;
812 if (Next == Capacity) { Next = 0; }
813
814 NumValid = FMath::Min(++NumValid, Capacity);
815 }
816 return *Result;
817 }
818
819private:
820
821 const int32 FindIdx(const FFrameAndPhase FrameAndPhase) const
822 {
823 int32 Cur = Next; //go in reverse order because hopefully we don't rewind too far back
824 int32 Result = INDEX_NONE;
825 for (int32 Count = 0; Count < NumValid; ++Count)
826 {
827 --Cur;
828 if (Cur < 0) { Cur = Buffer.Num() - 1; }
829
830 const FPropertyInterval& Interval = Buffer[Cur];
831
832 if (Interval.FrameAndPhase < FrameAndPhase)
833 {
834 //no reason to keep searching, frame is bigger than everything before this
835 break;
836 }
837 else
838 {
839 Result = Cur;
840 }
841 }
842
843 if (bNoEntryIsHead || Result == INDEX_NONE)
844 {
845 //in this mode we consider the entire interval as one entry
846 return Result;
847 }
848 else
849 {
850 //in this mode each interval just represents the frame the property was dirtied on
851 //so in that case we have to check for equality
852 return Buffer[Result].FrameAndPhase == FrameAndPhase ? Result : INDEX_NONE;
853 }
854 }
855
856 TPropertyPool<T>& GetPool(FDirtyPropertiesPool& Manager) { return Manager.GetPool<T, PropName>(); }
857 const TPropertyPool<T>& GetPool(const FDirtyPropertiesPool& Manager) const { return Manager.GetPool<T, PropName>(); }
858
859 //Gets access into buffer in FrameAndPhase order.
860 //It's assumed FrameAndPhase is monotonically increasing: x_{n+1} > x_n
861 //If bEnsureMonotonic is true we will always return a valid access (unless assert fires)
862 //If bEnsureMonotonic is false we will ensure x_{n+1} >= x_n. If x_{n+1} == x_n we return null to inform the user (can be useful when multiple writes happen in same phase)
863 template <bool bEnsureMonotonic>
864 T* WriteAccessImp(const FFrameAndPhase FrameAndPhase, FDirtyPropertiesPool& Manager)
865 {
866 if (NumValid)
867 {
868 const int32 Prev = Next == 0 ? Buffer.Num() - 1 : Next - 1;
869 const FFrameAndPhase& LatestFrameAndPhase = Buffer[Prev].FrameAndPhase;
871 {
872 //Must write in monotonic growing order so that x_{n+1} > x_n
873 ensureMsgf(LatestFrameAndPhase < FrameAndPhase, TEXT("WriteAccessImp<bEnsureMonotonic = true> trying to write to already written FrameAndPhase: %d/%d >= %d/%d"), LatestFrameAndPhase.Frame, LatestFrameAndPhase.Phase, FrameAndPhase.Frame, FrameAndPhase.Phase);
874 }
875 else
876 {
877 //Must write in growing order so that x_{n+1} >= x_n
878 ensureMsgf(LatestFrameAndPhase <= FrameAndPhase, TEXT("WriteAccessImp<bEnsureMonotonic = false> trying to write to already written FrameAndPhase: %d/%d > %d/%d"), LatestFrameAndPhase.Frame, LatestFrameAndPhase.Phase, FrameAndPhase.Frame, FrameAndPhase.Phase);
879 if (LatestFrameAndPhase == FrameAndPhase)
880 {
881 //Already wrote once for this FrameAndPhase so skip
882 return nullptr;
883 }
884 }
885
886 ValidateOrder();
887 }
888
889 T* Result;
890
891 if (Next < Buffer.Num())
892 {
893 //reuse
894 FPropertyInterval& Interval = Buffer[Next];
895 Interval.FrameAndPhase = FrameAndPhase;
896 Result = &GetPool(Manager).GetElement(Interval.Ref);
897 }
898 else
899 {
900 //no reuse yet so can just push
902 Result = &GetPool(Manager).AddElement(NewIdx);
903 Buffer.Add({NewIdx, FrameAndPhase });
904 }
905
906 ++Next;
907 if (Next == Capacity) { Next = 0; }
908
909 NumValid = FMath::Min(++NumValid, Capacity);
910
911 return Result;
912 }
913
914 void ValidateOrder()
915 {
916#if VALIDATE_REWIND_DATA
917 int32 Val = Next;
918 FFrameAndPhase PrevVal;
919 for (int32 Count = 0; Count < NumValid; ++Count)
920 {
921 --Val;
922 if (Val < 0) { Val = Buffer.Num() - 1; }
923 if (Count == 0)
924 {
925 PrevVal = Buffer[Val].FrameAndPhase;
926 }
927 else
928 {
929 ensureMsgf(Buffer[Val].FrameAndPhase < PrevVal, TEXT("ValidateOrder Idx: %d TailFrame: %d/%d, HeadFrame: %d/%d"), Val, Buffer[Val].FrameAndPhase.Frame, Buffer[Val].FrameAndPhase.Phase, PrevVal.Frame, PrevVal.Phase);
930 PrevVal = Buffer[Val].FrameAndPhase;
931 }
932 }
933#endif
934 }
935
936private:
937 int32 Next;
938 int32 NumValid;
939 int32 Capacity;
941};
942
943
945{
946 InSync, //both have entries and are identical, or both have no entries
947 Desync, //both have entries but they are different
948 NeedInfo //one of the entries is missing. Need more context to determine whether desynced
950
951// Wraps FDirtyPropertiesManager and its DataIdx to avoid confusion between Source and offset Dest indices
960
969
970template <typename T, EShapeProperty PropName>
972{
973public:
974 const T& Read() const
975 {
976 check(bSet);
977 return Val;
978 }
979
980 void Write(const T& InVal)
981 {
982 bSet = true;
983 Val = InVal;
984 }
985
986 bool IsSet() const
987 {
988 return bSet;
989 }
990
991private:
992 T Val;
993 bool bSet = false;
994};
995
997{
1000
1001 //helper functions for shape API
1002 template <typename TParticle>
1003 static const FCollisionFilterData& GetQueryData(const FPerShapeDataStateBase* State, const TParticle& Particle, int32 ShapeIdx)
1004 {
1006 return State && State->CollisionData.IsSet() ? State->CollisionData.Read().GetQueryData() : Particle.ShapesArray()[ShapeIdx]->GetQueryData();
1008 }
1009};
1010
1012{
1013public:
1015 : State(InState)
1016 , Particle(InParticle)
1017 , ShapeIdx(InShapeIdx)
1018 {
1019 }
1020
1021 const FCollisionFilterData& GetQueryData() const { return FPerShapeDataStateBase::GetQueryData(State, Particle, ShapeIdx); }
1022private:
1023 const FPerShapeDataStateBase* State;
1024 const FGeometryParticleHandle& Particle;
1025 const int32 ShapeIdx;
1026
1027};
1028
1030{
1032
1034 {
1035 if(ShapeIdx >= PerShapeData.Num())
1036 {
1037 const int32 NumNeededToAdd = ShapeIdx + 1 - PerShapeData.Num();
1038 PerShapeData.AddDefaulted(NumNeededToAdd);
1039 }
1040 return PerShapeData[ShapeIdx];
1041
1042 }
1043};
1044
1045template <typename T>
1046FString ToStringHelper(const T& Val)
1047{
1048 return Val.ToString();
1049}
1050
1051template <typename T>
1053{
1054 return FString::Printf(TEXT("(%s, %s)"), *Val[0].ToString(), *Val[1].ToString());
1055}
1056
1057inline FString ToStringHelper(void* Val)
1058{
1059 // We don't print pointers because they will always be different in diff, need this function so we will compile
1060 // when using property .inl macros.
1061 return FString();
1062}
1063
1064inline FString ToStringHelper(const FReal Val)
1065{
1066 return FString::Printf(TEXT("%f"), Val);
1067}
1068
1069inline FString ToStringHelper(const FRealSingle Val)
1070{
1071 return FString::Printf(TEXT("%f"), Val);
1072}
1073
1075{
1076 return FString::Printf(TEXT("%d"), Val);
1077}
1078
1080{
1081 return FString::Printf(TEXT("%d"), Val);
1082}
1083
1085{
1086 return FString::Printf(TEXT("%d"), Val);
1087}
1088
1090{
1091 return FString::Printf(TEXT("%d"), Val);
1092}
1093
1094inline FString ToStringHelper(const bool Val)
1095{
1096 return FString::Printf(TEXT("%d"), Val);
1097}
1098
1099inline FString ToStringHelper(const int32 Val)
1100{
1101 return FString::Printf(TEXT("%d"), Val);
1102}
1103
1104
1105template <typename TParticle>
1107{
1108public:
1110 : Particle(InParticle)
1111 , State(InState)
1112 {}
1113
1114 FPerShapeDataState operator[](const int32 ShapeIdx) const { return FPerShapeDataState{ State && ShapeIdx < State->PerShapeData.Num() ? &State->PerShapeData[ShapeIdx] : nullptr, Particle, ShapeIdx }; }
1115private:
1116 const TParticle& Particle;
1117 const FShapesArrayStateBase* State;
1118};
1119
1120#define REWIND_CHAOS_PARTICLE_PROPERTY(PROP, NAME)\
1121 const auto Data = State ? State->PROP.Read(FrameAndPhase, Pool) : nullptr;\
1122 return Data ? Data->NAME() : Head.NAME();\
1123
1124#define REWIND_CHAOS_ZERO_PARTICLE_PROPERTY(PROP, NAME)\
1125 const auto Data = State ? State->PROP.Read(FrameAndPhase, Pool) : nullptr;\
1126 return Data ? Data->NAME() : ZeroVector;\
1127
1128#define REWIND_PARTICLE_STATIC_PROPERTY(PROP, NAME)\
1129 decltype(auto) NAME() const\
1130 {\
1131 auto& Head = Particle;\
1132 REWIND_CHAOS_PARTICLE_PROPERTY(PROP, NAME);\
1133 }\
1134
1135#define REWIND_PARTICLE_KINEMATIC_PROPERTY(PROP, NAME)\
1136 decltype(auto) NAME() const\
1137 {\
1138 auto& Head = *Particle.CastToKinematicParticle();\
1139 REWIND_CHAOS_PARTICLE_PROPERTY(PROP, NAME);\
1140 }\
1141
1142#define REWIND_PARTICLE_RIGID_PROPERTY(PROP, NAME)\
1143 decltype(auto) NAME() const\
1144 {\
1145 auto& Head = *Particle.CastToRigidParticle();\
1146 REWIND_CHAOS_PARTICLE_PROPERTY(PROP, NAME);\
1147 }\
1148
1149#define REWIND_PARTICLE_ZERO_PROPERTY(PROP, NAME)\
1150 decltype(auto) NAME() const\
1151 {\
1152 auto& Head = *Particle.CastToRigidParticle();\
1153 REWIND_CHAOS_ZERO_PARTICLE_PROPERTY(PROP, NAME);\
1154 }\
1155
1156#define REWIND_JOINT_PROPERTY(PROP, FUNC_NAME, NAME)\
1157 decltype(auto) Get##FUNC_NAME() const\
1158 {\
1159 const auto Data = State ? State->PROP.Read(FrameAndPhase, Pool) : nullptr;\
1160 return Data ? Data->NAME : Head.Get##PROP().NAME;\
1161 }\
1162
1163inline int32 ComputeCircularSize(int32 NumFrames) { return NumFrames * FFrameAndPhase::NumPhases; }
1164
1166{
1168 UE_DEPRECATED(5.6, "Use the constructor that takes a @param bCacheOnePhase")
1172 , Velocities(ComputeCircularSize(NumFrames))
1173 , Dynamics(ComputeCircularSize(NumFrames))
1174 , DynamicsMisc(ComputeCircularSize(NumFrames))
1175 , MassProps(ComputeCircularSize(NumFrames))
1179 , TargetStates(ComputeCircularSize(NumFrames))
1180 {
1181 }
1182
1185 , NonFrequentData(bCacheOnePhase ? NumFrames : ComputeCircularSize(NumFrames))
1186 , Velocities(bCacheOnePhase ? NumFrames : ComputeCircularSize(NumFrames))
1187 , Dynamics(bCacheOnePhase ? NumFrames : ComputeCircularSize(NumFrames))
1188 , DynamicsMisc(bCacheOnePhase ? NumFrames : ComputeCircularSize(NumFrames))
1189 , MassProps(bCacheOnePhase ? NumFrames : ComputeCircularSize(NumFrames))
1190 , KinematicTarget(bCacheOnePhase ? NumFrames : ComputeCircularSize(NumFrames))
1191 , TargetPositions(NumFrames)
1192 , TargetVelocities(NumFrames)
1193 , TargetStates(NumFrames)
1194 {
1195 }
1196
1200
1201 // Can be removed when Deprecations are removed
1203 // Can be removed when Deprecations are removed
1205 // Can be removed when Deprecations are removed
1208
1210 {
1211 ParticlePositionRotation.Release(Manager);
1212 NonFrequentData.Release(Manager);
1213 Velocities.Release(Manager);
1214 Dynamics.Release(Manager);
1215 DynamicsMisc.Release(Manager);
1216 MassProps.Release(Manager);
1217 KinematicTarget.Release(Manager);
1218 TargetPositions.Release(Manager);
1219 TargetVelocities.Release(Manager);
1220 TargetStates.Release(Manager);
1221 }
1222
1223 void Reset()
1224 {
1226 NonFrequentData.Reset();
1227 Velocities.Reset();
1228 Dynamics.Reset();
1229 DynamicsMisc.Reset();
1230 MassProps.Reset();
1232 TargetVelocities.Reset();
1233 TargetPositions.Reset();
1234 TargetStates.Reset();
1235 }
1236
1237 void ClearEntryAndFuture(const FFrameAndPhase FrameAndPhase)
1238 {
1239 ParticlePositionRotation.ClearEntryAndFuture(FrameAndPhase);
1240 NonFrequentData.ClearEntryAndFuture(FrameAndPhase);
1241 Velocities.ClearEntryAndFuture(FrameAndPhase);
1242 Dynamics.ClearEntryAndFuture(FrameAndPhase);
1243 DynamicsMisc.ClearEntryAndFuture(FrameAndPhase);
1244 MassProps.ClearEntryAndFuture(FrameAndPhase);
1245 KinematicTarget.ClearEntryAndFuture(FrameAndPhase);
1246 }
1247
1253
1259
1260 bool IsClean(const FFrameAndPhase FrameAndPhase) const
1261 {
1262 return IsCleanExcludingDynamics(FrameAndPhase) && Dynamics.IsClean(FrameAndPhase);
1263 }
1264
1265 bool IsCleanExcludingDynamics(const FFrameAndPhase FrameAndPhase) const
1266 {
1267 return ParticlePositionRotation.IsClean(FrameAndPhase) &&
1268 NonFrequentData.IsClean(FrameAndPhase) &&
1269 Velocities.IsClean(FrameAndPhase) &&
1270 DynamicsMisc.IsClean(FrameAndPhase) &&
1271 MassProps.IsClean(FrameAndPhase) &&
1272 KinematicTarget.IsClean(FrameAndPhase);
1273 }
1274
1275 template <bool bSkipDynamics = false>
1276 bool IsInSync(const FGeometryParticleHandle& Handle, const FFrameAndPhase FrameAndPhase, const FDirtyPropertiesPool& Pool) const;
1277
1278 template <typename TParticle>
1280 {
1281 return TShapesArrayState<TParticle>{ Particle, State ? &State->ShapesArrayState : nullptr };
1282 }
1283
1286
1287 template<typename TParticle>
1288 UE_DEPRECATED(5.6, "Deprecated, use FRewindData::CachePreResimState instead. Not all moving particles are marked as dirty, for example GeometryCollection children of a ClusterUnion.")
1290 {
1291 PreCorrectionXR.SetX(Particle.GetX());
1292 PreCorrectionXR.SetR(Particle.GetR());
1293 }
1294
1301 TParticlePropertyBuffer<FParticleDynamics,EChaosProperty::Dynamics, /*bNoEntryIsHead=*/false> Dynamics;
1304 TParticlePropertyBuffer<FKinematicTarget, EChaosProperty::KinematicTarget, /*bNoEntryIsHead=*/false> KinematicTarget;
1305
1306 TParticlePropertyBuffer<FParticlePositionRotation, EChaosProperty::XR, /*bNoEntryIsHead=*/false> TargetPositions;
1307 TParticlePropertyBuffer<FParticleVelocities, EChaosProperty::Velocities, /*bNoEntryIsHead=*/false> TargetVelocities;
1308 TParticlePropertyBuffer<FParticleDynamicMisc, EChaosProperty::DynamicMisc, /*bNoEntryIsHead=*/false> TargetStates;
1309
1311
1312 UE_DEPRECATED(5.6, "Deprecated, use FRewindData::DirtyParticlePreResimState")
1314};
1315
1317{
1318public:
1319
1321 : Particle(InParticle)
1322 , Pool(InPool)
1323 , FrameAndPhase{0,0}
1324 {
1325 }
1326
1328 : Particle(InParticle)
1329 , Pool(InPool)
1330 , State(InState)
1331 , FrameAndPhase(InFrameAndPhase)
1332 {
1333 }
1334
1335
1338
1341
1346 REWIND_PARTICLE_RIGID_PROPERTY(DynamicsMisc, InitialOverlapDepenetrationVelocity)
1347 REWIND_PARTICLE_RIGID_PROPERTY(DynamicsMisc, SleepThresholdMultiplier)
1351
1357
1361#if CHAOS_DEBUG_NAME
1363#endif
1364
1366 REWIND_PARTICLE_ZERO_PROPERTY(Dynamics, AngularAcceleration)
1367 REWIND_PARTICLE_ZERO_PROPERTY(Dynamics, LinearImpulseVelocity)
1368 REWIND_PARTICLE_ZERO_PROPERTY(Dynamics, AngularImpulseVelocity)
1369
1374
1376 {
1377 return Particle;
1378 }
1379
1381 {
1382 State = InState;
1383 }
1384
1385 FString ToString() const
1386 {
1387#undef REWIND_PARTICLE_TO_STR
1388#define REWIND_PARTICLE_TO_STR(PropName) Out += FString::Printf(TEXT(#PropName":%s\n"), *ToStringHelper(PropName()));
1389 //TODO: use macro to define api and the to string
1390 FString Out = FString::Printf(TEXT("ParticleID:[Global: %d Local: %d]\n"), Particle.ParticleID().GlobalID, Particle.ParticleID().LocalID);
1391
1394 //REWIND_PARTICLE_TO_STR(Geometry)
1395 //REWIND_PARTICLE_TO_STR(UniqueIdx)
1396 //REWIND_PARTICLE_TO_STR(SpatialIdx)
1397
1398 if(Particle.CastToKinematicParticle())
1399 {
1402 }
1403
1404 if(Particle.CastToRigidParticle())
1405 {
1406 REWIND_PARTICLE_TO_STR(LinearEtherDrag)
1407 REWIND_PARTICLE_TO_STR(AngularEtherDrag)
1408 REWIND_PARTICLE_TO_STR(MaxLinearSpeedSq)
1409 REWIND_PARTICLE_TO_STR(MaxAngularSpeedSq)
1410 REWIND_PARTICLE_TO_STR(InitialOverlapDepenetrationVelocity)
1411 REWIND_PARTICLE_TO_STR(SleepThresholdMultiplier)
1412
1413 REWIND_PARTICLE_TO_STR(ObjectState)
1414 REWIND_PARTICLE_TO_STR(CollisionGroup)
1415 REWIND_PARTICLE_TO_STR(ControlFlags)
1416
1418 REWIND_PARTICLE_TO_STR(RotationOfMass)
1422
1424 REWIND_PARTICLE_TO_STR(AngularAcceleration)
1425 REWIND_PARTICLE_TO_STR(LinearImpulseVelocity)
1426 REWIND_PARTICLE_TO_STR(AngularImpulseVelocity)
1427 }
1428
1429 return Out;
1430 }
1431
1432private:
1433 const FGeometryParticleHandle& Particle;
1434 const FDirtyPropertiesPool& Pool;
1435 const FGeometryParticleStateBase* State = nullptr;
1436 const FFrameAndPhase FrameAndPhase;
1437
1438 CHAOS_API static FVec3 ZeroVector;
1439
1440 };
1441
1442
1444{
1445 UE_DEPRECATED(5.6, "Use the constructor that takes a @param bCacheOnePhase")
1446 explicit FJointStateBase(int32 NumFrames)
1447 : JointSettings(ComputeCircularSize(NumFrames))
1448 , JointProxies(ComputeCircularSize(NumFrames))
1449 {
1450 }
1451
1452 explicit FJointStateBase(int32 NumFrames, bool bCacheOnePhase)
1453 : JointSettings(bCacheOnePhase ? NumFrames : ComputeCircularSize(NumFrames))
1454 , JointProxies(bCacheOnePhase ? NumFrames : ComputeCircularSize(NumFrames))
1455 {
1456 }
1457
1460 ~FJointStateBase() = default;
1461
1463 {
1464 JointSettings.Release(Manager);
1465 JointProxies.Release(Manager);
1466 }
1467
1468 void Reset()
1469 {
1470 JointSettings.Reset();
1471 JointProxies.Reset();
1472 }
1473
1474 void ClearEntryAndFuture(const FFrameAndPhase FrameAndPhase)
1475 {
1476 JointSettings.ClearEntryAndFuture(FrameAndPhase);
1477 JointProxies.ClearEntryAndFuture(FrameAndPhase);
1478 }
1479
1480 bool IsClean(const FFrameAndPhase FrameAndPhase) const
1481 {
1482 return JointSettings.IsClean(FrameAndPhase) && JointProxies.IsClean(FrameAndPhase);
1483 }
1484
1485 template <bool bSkipDynamics>
1486 bool IsInSync(const FPBDJointConstraintHandle& Handle, const FFrameAndPhase FrameAndPhase, const FDirtyPropertiesPool& Pool) const;
1487
1490};
1491
1493{
1494public:
1496 : Head(InJoint)
1497 , Pool(InPool)
1498 {
1499 }
1500
1502 : Head(InJoint)
1503 , Pool(InPool)
1504 , State(InState)
1505 , FrameAndPhase(InFrameAndPhase)
1506 {
1507 }
1508
1509 //See JointProperties for API
1510 //Each CHAOS_INNER_JOINT_PROPERTY entry will have a Get*
1511#define CHAOS_INNER_JOINT_PROPERTY(OuterProp, FuncName, Inner, InnerType) REWIND_JOINT_PROPERTY(OuterProp, FuncName, Inner);
1513
1514
1515 FString ToString() const
1516 {
1517 TVector<FGeometryParticleHandle*, 2> Particles = Head.GetConstrainedParticles();
1518 FString Out = FString::Printf(TEXT("Joint: Particle0 ID:[Global: %d Local: %d] Particle1 ID:[Global: %d Local: %d]\n"), Particles[0]->ParticleID().GlobalID, Particles[0]->ParticleID().LocalID, Particles[1]->ParticleID().GlobalID, Particles[1]->ParticleID().LocalID);
1519
1520#define CHAOS_INNER_JOINT_PROPERTY(OuterProp, FuncName, Inner, InnerType) Out += FString::Printf(TEXT(#FuncName":%s\n"), *ToStringHelper(Get##FuncName()));
1522#undef CHAOS_INNER_JOINT_PROPERTY
1523
1524 return Out;
1525 }
1526
1527private:
1528 const FPBDJointConstraintHandle& Head;
1529 const FDirtyPropertiesPool& Pool;
1530 const FJointStateBase* State = nullptr;
1531 const FFrameAndPhase FrameAndPhase = { 0,0 };
1532};
1533
1534template <typename T>
1535const T* ConstifyHelper(T* Ptr) { return Ptr; }
1536
1537
1538template <typename T>
1539T NoRefHelper(const T& Ref) { return Ref; }
1540
1541template <typename TVal>
1543{
1544public:
1545 using TKey = decltype(ConstifyHelper(
1546 ((TVal*)0)->GetObjectPtr()
1547 ));
1548
1549 TVal& Add(const TKey Key, TVal&& Val)
1550 {
1551 if(int32* ExistingIdx = KeyToIdx.Find(Key))
1552 {
1553 ensure(false); //Item alread exists, shouldn't be adding again
1554 return DenseVals[*ExistingIdx];
1555 }
1556 else
1557 {
1558 const int32 Idx = DenseVals.Emplace(MoveTemp(Val));
1559 KeyToIdx.Add(Key, Idx);
1560 return DenseVals[Idx];
1561 }
1562 }
1563
1564 const TVal& FindChecked(const TKey Key) const
1565 {
1566 const int32 Idx = KeyToIdx.FindChecked(Key);
1567 return DenseVals[Idx];
1568 }
1569
1571 {
1572 const int32 Idx = KeyToIdx.FindChecked(Key);
1573 return DenseVals[Idx];
1574 }
1575
1576 const TVal* Find(const TKey Key) const
1577 {
1578 if (const int32* Idx = KeyToIdx.Find(Key))
1579 {
1580 return &DenseVals[*Idx];
1581 }
1582
1583 return nullptr;
1584 }
1585
1586 TVal* Find(const TKey Key)
1587 {
1588 if (const int32* Idx = KeyToIdx.Find(Key))
1589 {
1590 return &DenseVals[*Idx];
1591 }
1592
1593 return nullptr;
1594 }
1595
1597 {
1598 if (const int32* Idx = KeyToIdx.Find(Key))
1599 {
1600 constexpr int32 Count = 1;
1601 DenseVals.RemoveAtSwap(*Idx, Count, AllowShrinking);
1602
1603 if(*Idx < DenseVals.Num())
1604 {
1605 const TKey SwappedKey = DenseVals[*Idx].GetObjectPtr();
1606 KeyToIdx.FindChecked(SwappedKey) = *Idx;
1607 }
1608
1609 KeyToIdx.Remove(Key);
1610 }
1611 }
1613 FORCEINLINE void Remove(const TKey Key, const bool bAllowShrinking)
1614 {
1615 Remove(Key, bAllowShrinking ? EAllowShrinking::Yes : EAllowShrinking::No);
1616 }
1617
1618 void Shrink()
1619 {
1620 DenseVals.Shrink();
1621 }
1622
1623 void Reset()
1624 {
1625 DenseVals.Reset();
1626 KeyToIdx.Reset();
1627 }
1628
1629 int32 Num() const { return DenseVals.Num(); }
1630
1631 auto begin() { return DenseVals.begin(); }
1632 auto end() { return DenseVals.end(); }
1633
1634 auto cbegin() const { return DenseVals.begin(); }
1635 auto cend() const { return DenseVals.end(); }
1636
1637 const TVal& GetDenseAt(const int32 Idx) const { return DenseVals[Idx]; }
1638 TVal& GetDenseAt(const int32 Idx) { return DenseVals[Idx]; }
1639
1640private:
1641 TMap<TKey, int32> KeyToIdx;
1642 TArray<TVal> DenseVals;
1643};
1644
1646
1647class FPBDRigidsSolver;
1648
1650{
1651public:
1654
1656 {
1657 Solver = InSolver;
1658 CurFrame = InCurrentFrame;
1659 LatestFrame = InCurrentFrame;
1660 bRewindDataOptimization = InRewindDataOptimization;
1661 LatestTargetFrame = 0;
1662 Managers = TCircularBuffer<FFrameManagerInfo>(NumFrames + 1);
1663
1664 RegisterEvolutionCallbacks();
1665 }
1666
1668 {
1669 Solver = InSolver;
1670 CurFrame = InCurrentFrame;
1671 LatestFrame = InCurrentFrame;
1672 LatestTargetFrame = 0;
1673 Managers = TCircularBuffer<FFrameManagerInfo>(NumFrames + 1);
1674
1675 RegisterEvolutionCallbacks();
1676 }
1677
1678private:
1679 void RegisterEvolutionCallbacks();
1680
1681public:
1682 int32 Capacity() const { return Managers.Capacity(); }
1683 int32 CurrentFrame() const { return CurFrame; }
1684 int32 GetLatestFrame() const { return LatestFrame; }
1685 int32 GetFramesSaved() const { return FramesSaved; }
1686
1688 {
1689 ensure(Managers[Frame].FrameCreatedFor == Frame);
1690 return Managers[Frame].DeltaTime;
1691 }
1692
1694 {
1695 DirtyParticles.Remove(Particle, AllowShrinking);
1696 }
1697 UE_ALLOWSHRINKING_BOOL_DEPRECATED("RemoveObject")
1698 FORCEINLINE void RemoveObject(const FGeometryParticleHandle* Particle, const bool bAllowShrinking)
1699 {
1700 RemoveObject(Particle, bAllowShrinking ? EAllowShrinking::Yes : EAllowShrinking::No);
1701 }
1702
1707 UE_ALLOWSHRINKING_BOOL_DEPRECATED("RemoveObject")
1708 FORCEINLINE void RemoveObject(const FPBDJointConstraintHandle* Joint, const bool bAllowShrinking)
1709 {
1711 }
1712
1713 int32 GetEarliestFrame_Internal() const { return CurFrame - FramesSaved; }
1714
1715 /* Extend the current history size to be sure to include the given frame */
1716 void CHAOS_API ExtendHistoryWithFrame(const int32 Frame);
1717
1718 /* Clear all the simulation history after Frame */
1720
1721 /* Push a physics state in the rewind data at specified frame */
1723 const FVector& LinVelocity, const FVector& AngVelocity, const bool bShouldSleep);
1724
1726 const FVector& Position, const FQuat& Quaternion, const FVector& LinVelocity, const FVector& AngVelocity, const bool bShouldSleep);
1727
1734
1737 {
1738 FDirtyParticleInfo& Info = FindOrAddDirtyObj(Handle);
1740 }
1741
1742 /* Query the state of particles from the past. Can only be used when not already resimming*/
1743 FGeometryParticleState CHAOS_API GetPastStateAtFrame(const FGeometryParticleHandle& Handle, int32 Frame, FFrameAndPhase::EParticleHistoryPhase Phase = FFrameAndPhase::EParticleHistoryPhase::PostPushData) const;
1744
1745 /* Query the state of joints from the past. Can only be used when not already resimming*/
1746 FJointState CHAOS_API GetPastJointStateAtFrame(const FPBDJointConstraintHandle& Handle, int32 Frame, FFrameAndPhase::EParticleHistoryPhase Phase = FFrameAndPhase::EParticleHistoryPhase::PostPushData) const;
1747
1749 {
1750 return Managers[CurFrame].ExternalResimCache.Get();
1751 }
1752
1753 void CHAOS_API DumpHistory_Internal(const int32 FramePrintOffset, const FString& Filename = FString(TEXT("Dump")));
1754
1756 bool GetUseCollisionResimCache() const;
1757
1759 template <typename CreateCache>
1761 {
1763 Managers[CurFrame].DeltaTime = DeltaTime;
1764 Managers[CurFrame].FrameCreatedFor = CurFrame;
1765 TUniquePtr<IResimCacheBase>& ResimCache = Managers[CurFrame].ExternalResimCache;
1766
1767 if (GetUseCollisionResimCache())
1768 {
1769 if (IsResim())
1770 {
1771 if (ResimCache)
1772 {
1773 ResimCache->SetResimming(true);
1774 }
1775 }
1776 else
1777 {
1778 if (ResimCache)
1779 {
1780 ResimCache->ResetCache();
1781 }
1782 else
1783 {
1785 }
1786 ResimCache->SetResimming(false);
1787 }
1788 }
1789 else
1790 {
1791 ResimCache.Reset();
1792 }
1793
1794 AdvanceFrameImp(ResimCache.Get());
1795 }
1796
1797 void FinishFrame();
1798
1799 bool IsResim() const
1800 {
1801 return CurFrame < LatestFrame;
1802 }
1803
1804 bool IsFinalResim() const
1805 {
1806 return (CurFrame + 1) == LatestFrame;
1807 }
1808
1809 //Number of particles that we're currently storing history for
1810 int32 GetNumDirtyParticles() const { return DirtyParticles.Num(); }
1811
1813 void PushGTDirtyData(const FDirtyPropertiesManager& SrcManager,const int32 SrcDataIdx,const FDirtyProxy& Dirty, const FShapeDirtyData* ShapeDirtyData);
1814
1816 void PushPTDirtyData(TPBDRigidParticleHandle<FReal,3>& Rigid,const int32 SrcDataIdx);
1817
1819 void CHAOS_API MarkDirtyFromPT(FGeometryParticleHandle& Handle);
1820
1822 void CHAOS_API MarkDirtyJointFromPT(FPBDJointConstraintHandle& Handle);
1823
1824 void CHAOS_API SpawnProxyIfNeeded(FSingleParticlePhysicsProxy& Proxy);
1825
1828 {
1829 InputHistories.AddUnique(InputHistory.ToWeakPtr());
1830 }
1831
1834 {
1835 InputHistories.Remove(InputHistory.ToWeakPtr());
1836 }
1837
1840 {
1841 AddInputHistory(InputHistory);
1842 if (Particle != nullptr)
1843 {
1844 InputParticleHistories.Add(Particle, InputHistory.ToWeakPtr());
1845 }
1846 }
1847
1850 {
1851 RemoveInputHistory(InputHistory);
1852 if (Particle != nullptr)
1853 {
1854 InputParticleHistories.Remove(Particle);
1855 }
1856 }
1857
1860 {
1861 StateHistories.AddUnique(StateHistory.ToWeakPtr());
1862 }
1863
1866 {
1867 StateHistories.Remove(StateHistory.ToWeakPtr());
1868 }
1869
1872 {
1873 AddStateHistory(StateHistory);
1874 if (Particle != nullptr)
1875 {
1876 StateParticleHistories.Add(Particle, StateHistory.ToWeakPtr());
1877 }
1878 }
1879
1882 {
1883 RemoveStateHistory(StateHistory);
1884 if (Particle != nullptr)
1885 {
1886 StateParticleHistories.Remove(Particle);
1887 }
1888 }
1889
1891 UE_DEPRECATED(5.6, "Deprecated, ApplyInputs is no longer viable. Any custom states can be applied during IRewindCallback::ProcessInputs_Internal during resimulation. Example FNetworkPhysicsCallback")
1892 void ApplyInputs(const int32 ApplyFrame, const bool bResetSolver);
1893
1895 UE_DEPRECATED(5.6, "Deprecated, RewindStates is no longer viable. Any custom states can be applied during IRewindCallback::ProcessInputs_Internal during resimulation. Example FNetworkPhysicsCallback")
1896 void RewindStates(const int32 RewindFrame, const bool bResetSolver);
1897
1899 void BufferPhysicsResults(TMap<const IPhysicsProxyBase*, struct FDirtyRigidParticleReplicationErrorData>& DirtyRigidErrors);
1900
1902 const FPBDRigidsSolver* GetSolver() const { return Solver; }
1903
1905 int32 CHAOS_API FindValidResimFrame(const int32 RequestedFrame);
1906
1908 const int32 GetResimFrame() const { return ResimFrame; }
1909 void SetResimFrame(int32 Frame) { ResimFrame = Frame; }
1910
1912 bool IsFrameWithinRewindHistory(int32 Frame) { return Frame < CurrentFrame() && Frame >= GetEarliestFrame_Internal(); }
1913
1916 void CHAOS_API RequestResimulation(int32 RequestedFrame, Chaos::FGeometryParticleHandle* Particle = nullptr);
1917
1919 void BlockResim();
1920
1922 const int32 GetBlockedResimFrame() const { return BlockResimFrame; }
1923
1927
1931 const int32 CHAOS_API CompareTargetsToLastFrame();
1932
1933 static bool CHAOS_API CheckVectorThreshold(FVec3 A, FVec3 B, float Threshold);
1934 static bool CHAOS_API CheckQuaternionThreshold(FQuat A, FQuat B, float ThresholdDegrees);
1935
1936private:
1937 friend class FPBDRigidsSolver;
1938
1939 void CHAOS_API AdvanceFrameImp(IResimCacheBase* ResimCache);
1940
1942 void ProcessDirtyPTParticles(const TParticleView<TPBDRigidParticles<FReal, 3>>& DirtyPTParticles);
1943
1945 void ProcessDirtyKinematicTargets(const TParticleView<TPBDRigidParticles<FReal, 3>>& ActiveKinematicParticles);
1946
1948 void CacheKinematicTarget(TPBDRigidParticleHandle<FReal, 3>& Rigid);
1949
1952 void CacheDirtyParticleData(FGeometryParticleHandle* Geometry, const FFrameAndPhase::EParticleHistoryPhase& CurrentPhase, const bool& bDirty);
1953
1956 void CacheDirtyJointData(FPBDJointConstraintHandle* Joint, const FFrameAndPhase::EParticleHistoryPhase& CurrentPhase, const bool& bDirty);
1957
1960 void CacheCurrentDirtyData(const FFrameAndPhase::EParticleHistoryPhase& CurrentPhase);
1961
1962 struct FFrameManagerInfo
1963 {
1964 TUniquePtr<IResimCacheBase> ExternalResimCache;
1965
1966 //Note that this is not exactly the same as which frame this manager represents.
1967 //A manager can have data for two frames at once, the important part is just knowing which frame it was created on so we know whether the physics data can rely on it
1968 //Consider the case where nothing is dirty from GT and then an object moves from the simulation, in that case it needs a manager to record the data into
1969 int32 FrameCreatedFor = INDEX_NONE;
1970 FReal DeltaTime;
1971 };
1972
1973 template <typename THistoryType, typename TObj>
1974 struct TDirtyObjectInfo
1975 {
1976 private:
1977 THistoryType History;
1978 TObj* ObjPtr;
1979 FDirtyPropertiesPool* PropertiesPool;
1980 public:
1981 int32 DirtyDynamics = INDEX_NONE; //Only used by particles, indicates the dirty properties was written to.
1982 int32 LastDirtyFrame; //Track how recently this was made dirty
1983 int32 InitializedOnStep = INDEX_NONE; //if not INDEX_NONE, it indicates we saw initialization during rewind history window
1984 bool bResimAsFollower = true; //Indicates the particle will always resim in the exact same way from game thread data
1985 bool bNeedsResim = false; //This particle needs resimulation, should have a higher priority when checking for valid rewind frames
1986
1987 TDirtyObjectInfo(FDirtyPropertiesPool& InPropertiesPool, TObj& InObj, const int32 CurFrame, const int32 NumFrames, const bool bCacheOnePhase)
1988 : History(NumFrames, bCacheOnePhase)
1989 , ObjPtr(&InObj)
1990 , PropertiesPool(&InPropertiesPool)
1991 , LastDirtyFrame(CurFrame)
1992 {
1993 }
1994
1995 TDirtyObjectInfo(TDirtyObjectInfo&& Other)
1996 : History(MoveTemp(Other.History))
1997 , ObjPtr(Other.ObjPtr)
1998 , PropertiesPool(Other.PropertiesPool)
1999 , LastDirtyFrame(Other.LastDirtyFrame)
2000 , InitializedOnStep(Other.InitializedOnStep)
2001 , bResimAsFollower(Other.bResimAsFollower)
2002 , bNeedsResim(Other.bNeedsResim)
2003 {
2004 Other.PropertiesPool = nullptr;
2005 }
2006
2007 ~TDirtyObjectInfo()
2008 {
2009 if (PropertiesPool)
2010 {
2011 History.Release(*PropertiesPool);
2012 }
2013 }
2014
2015 TDirtyObjectInfo(const TDirtyObjectInfo& Other) = delete;
2016
2017 TObj* GetObjectPtr() const { return ObjPtr; }
2018
2019 UE_DEPRECATED(5.7, "Deprecated, Use GetHistory() and MarkDirty() individually instead")
2020 THistoryType& AddFrame(const int32 Frame)
2021 {
2022 LastDirtyFrame = Frame;
2023 return History;
2024 }
2025
2026 void ClearPhaseAndFuture(const FFrameAndPhase FrameAndPhase)
2027 {
2028 History.ClearEntryAndFuture(FrameAndPhase);
2029 }
2030
2031 const THistoryType& GetHistory() const
2032 {
2033 return History;
2034 }
2035
2036 THistoryType& GetHistory()
2037 {
2038 return History;
2039 }
2040
2041 void MarkDirty(const int32 Frame)
2042 {
2043 LastDirtyFrame = Frame;
2044 }
2045 };
2046
2049
2050 struct FDirtyParticleErrorInfo
2051 {
2052 private:
2053 FGeometryParticleHandle* HandlePtr;
2054 FVec3 ErrorX = { 0,0,0 };
2055 FQuat ErrorR = FQuat::Identity;
2056
2057 public:
2058 FDirtyParticleErrorInfo(FGeometryParticleHandle& InHandle) : HandlePtr(&InHandle)
2059 { }
2060
2061 void AccumulateError(FVec3 NewErrorX, FQuat NewErrorR)
2062 {
2063 ErrorX += NewErrorX;
2064 ErrorR *= NewErrorR;
2065 }
2066
2067 FGeometryParticleHandle* GetObjectPtr() const { return HandlePtr; }
2068 FVec3 GetErrorX() const { return ErrorX; }
2069 FQuat GetErrorR() const { return ErrorR; }
2070 };
2071
2072 template <typename TDirtyObjs, typename TObj>
2073 auto* FindDirtyObjImp(TDirtyObjs& DirtyObjs, TObj& Handle)
2074 {
2075 return DirtyObjs.Find(&Handle);
2076 }
2077
2078 FDirtyParticleInfo* FindDirtyObj(const FGeometryParticleHandle& Handle)
2079 {
2080 return FindDirtyObjImp(DirtyParticles, Handle);
2081 }
2082
2083 FDirtyJointInfo* FindDirtyObj(const FPBDJointConstraintHandle& Handle)
2084 {
2085 return FindDirtyObjImp(DirtyJoints, Handle);
2086 }
2087
2088 template <typename TDirtyObjs, typename TObj>
2089 auto& FindOrAddDirtyObjImp(TDirtyObjs & DirtyObjs, TObj & Handle, const int32 InitializedOnFrame = INDEX_NONE)
2090 {
2091 if (auto Info = DirtyObjs.Find(&Handle))
2092 {
2093 return *Info;
2094 }
2095
2096 using TDirtyObj = decltype(NoRefHelper(DirtyObjs.GetDenseAt(0)));
2097 TDirtyObj& Info = DirtyObjs.Add(&Handle, TDirtyObj(PropertiesPool, Handle, CurFrame, Managers.Capacity(), bRewindDataOptimization));
2098 Info.InitializedOnStep = InitializedOnFrame;
2099 return Info;
2100 }
2101
2102 FDirtyParticleInfo& FindOrAddDirtyObj(FGeometryParticleHandle& Handle, const int32 InitializedOnFrame = INDEX_NONE)
2103 {
2104 return FindOrAddDirtyObjImp(DirtyParticles, Handle, InitializedOnFrame);
2105 }
2106
2107 FDirtyJointInfo& FindOrAddDirtyObj(FPBDJointConstraintHandle& Handle, const int32 InitializedOnFrame = INDEX_NONE)
2108 {
2109 return FindOrAddDirtyObjImp(DirtyJoints, Handle, InitializedOnFrame);
2110 }
2111
2112 template <typename TObjState, typename TDirtyObjs, typename TObj>
2113 auto GetPastStateAtFrameImp(const TDirtyObjs& DirtyObjs, const TObj& Handle, int32 Frame, FFrameAndPhase::EParticleHistoryPhase Phase) const
2114 {
2115 ensure(!IsResim());
2116 ensure(Frame >= GetEarliestFrame_Internal()); //can't get state from before the frame we rewound to
2117
2118 const auto* Info = DirtyObjs.Find(&Handle);
2119 const auto* State = Info ? &Info->GetHistory() : nullptr;
2120 return TObjState(State, Handle, PropertiesPool, { Frame, Phase });
2121 }
2122
2124 bool RewindToFrame(int32 RewindFrame);
2125
2127 void ApplyTargets(const int32 Frame, const bool bResetSimulation);
2128
2130 void StepNonResimParticles(const int32 Frame);
2131
2132 template <typename TDirtyInfo>
2133 static void DesyncObject(TDirtyInfo& Info, const FFrameAndPhase FrameAndPhase)
2134 {
2135 Info.ClearPhaseAndFuture(FrameAndPhase);
2136 Info.GetObjectPtr()->SetSyncState(ESyncState::HardDesync);
2137 }
2138
2140 FDirtyPropertiesPool PropertiesPool; //must come before DirtyParticles since it relies on it (and used in destruction)
2141
2142 TDirtyObjects<FDirtyParticleInfo> DirtyParticles;
2143 TDirtyObjects<FDirtyJointInfo> DirtyJoints;
2144 TDirtyObjects<FDirtyParticleErrorInfo> DirtyParticlePreResimState;
2145 TDirtyObjects<FDirtyParticleErrorInfo> DirtyParticleErrors;
2146
2147 TArray<TWeakPtr<FBaseRewindHistory>> InputHistories; // Todo, deprecate in favor of Particle->Input map?
2148 TArray<TWeakPtr<FBaseRewindHistory>> StateHistories; // Todo, deprecate in favor of Particle->State map?
2149
2152
2153 FPBDRigidsSolver* Solver;
2154 int32 CurFrame;
2155 int32 LatestFrame;
2156 int32 FramesSaved;
2157 int32 DataIdxOffset;
2158 bool bNeedsSave; //Indicates that some data is pointing at head and requires saving before a rewind
2159 bool bRewindDataOptimization;
2160 int32 ResimFrame = INDEX_NONE;
2161 int32 LatestTargetFrame;
2162
2163 // Used to block rewinding past a physics change we currently don't handle
2164 int32 BlockResimFrame = INDEX_NONE;
2165
2166 // Properties for EResimFrameValidation::IslandValidation logic
2167 TArray<const Private::FPBDIsland*> IslandValidationIslands;
2168 TArray<const FGeometryParticleHandle*> IslandValidationIslandParticles;
2169
2170 template <typename TObj>
2171 bool IsResimAndInSync(const TObj& Handle) const { return IsResim() && Handle.SyncState() == ESyncState::InSync; }
2172
2173 template <bool bSkipDynamics, typename TDirtyInfo>
2174 void DesyncIfNecessary(TDirtyInfo& Info, const FFrameAndPhase FrameAndPhase);
2175
2176 void CachePreResimState(FGeometryParticleHandle& Handle);
2177
2178 template<typename TObj>
2179 void AccumulateErrorIfNecessary(TObj& Handle, const FFrameAndPhase FrameAndPhase) { }
2180};
2181
2183{
2184 double ResimTime = 0.0;
2185};
2186
2189{
2190public:
2191 virtual ~IRewindCallback() = default;
2195 virtual void ProcessInputs_Internal(int32 PhysicsStep, const TArray<FSimCallbackInputAndObject>& SimCallbackInputs){}
2196
2198 virtual void ApplyCallbacks_Internal(int32 PhysicsStep, const TArray<ISimCallbackObject*>& SimCallbackObjects) {}
2199
2204 virtual void ProcessInputs_External(int32 PhysicsStep, const TArray<FSimCallbackInputAndObject>& SimCallbackInputs) {}
2205
2211 virtual void InjectInputs_External(int32 PhysicsStep, int32 NumSteps){}
2212
2218
2222 virtual void PreResimStep_Internal(int32 PhysicsStep, bool bFirstStep){}
2223
2227 virtual void PostResimStep_Internal(int32 PhysicsStep) {}
2228
2231
2234
2237
2239 Chaos::FRewindData* RewindData = nullptr;
2240};
2241}
OODEFFUNC typedef void(OODLE_CALLBACK t_fp_OodleCore_Plugin_Free)(void *ptr)
EAllowShrinking
Definition AllowShrinking.h:10
#define UE_ALLOWSHRINKING_BOOL_DEPRECATED(FunctionName)
Definition AllowShrinking.h:31
#define FORCEINLINE
Definition AndroidPlatform.h:140
#define check(expr)
Definition AssertionMacros.h:314
#define ensureMsgf( InExpression, InFormat,...)
Definition AssertionMacros.h:465
#define ensure( InExpression)
Definition AssertionMacros.h:464
#define PRAGMA_DISABLE_INTERNAL_WARNINGS
Definition CoreMiscDefines.h:346
@ INDEX_NONE
Definition CoreMiscDefines.h:150
#define PRAGMA_ENABLE_INTERNAL_WARNINGS
Definition CoreMiscDefines.h:347
#define UE_DEPRECATED(Version, Message)
Definition CoreMiscDefines.h:302
#define TEXT(x)
Definition Platform.h:1272
FPlatformTypes::int32 int32
A 32-bit signed integer.
Definition Platform.h:1125
#define QUICK_SCOPE_CYCLE_COUNTER(Stat)
Definition Stats.h:652
UE_FORCEINLINE_HINT TSharedRef< CastToType, Mode > StaticCastSharedRef(TSharedRef< CastFromType, Mode > const &InSharedRef)
Definition SharedPointer.h:127
#define PRAGMA_ENABLE_DEPRECATION_WARNINGS
Definition GenericPlatformCompilerPreSetup.h:12
#define PRAGMA_DISABLE_DEPRECATION_WARNINGS
Definition GenericPlatformCompilerPreSetup.h:8
const Chaos::FPhysicsSolver * GetSolver(const AGeometryCollectionActor &GeomCollectionActor)
Definition GeometryCollectionActor.cpp:49
@ Rigid
Definition HairStrandsInterface.h:200
#define UE_LOG(CategoryName, Verbosity, Format,...)
Definition LogMacros.h:270
#define REWIND_PARTICLE_RIGID_PROPERTY(PROP, NAME)
Definition RewindData.h:1142
#define REWIND_PARTICLE_ZERO_PROPERTY(PROP, NAME)
Definition RewindData.h:1149
#define REWIND_PARTICLE_TO_STR(PropName)
#define REWIND_PARTICLE_STATIC_PROPERTY(PROP, NAME)
Definition RewindData.h:1128
#define REWIND_PARTICLE_KINEMATIC_PROPERTY(PROP, NAME)
Definition RewindData.h:1135
float Val(const FString &Value)
Definition UnrealMath.cpp:3163
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
uint32_t uint32
Definition binka_ue_file_header.h:6
Definition ParticleDirtyFlags.h:1129
Definition ParticleDirtyFlags.h:1039
Definition ParticleDirtyFlags.h:1350
Definition RewindData.h:1317
void SetState(const FGeometryParticleStateBase *InState)
Definition RewindData.h:1380
FGeometryParticleState(const FGeometryParticleStateBase *InState, const FGeometryParticleHandle &InParticle, const FDirtyPropertiesPool &InPool, const FFrameAndPhase InFrameAndPhase)
Definition RewindData.h:1327
FString ToString() const
Definition RewindData.h:1385
const FGeometryParticleHandle & GetHandle() const
Definition RewindData.h:1375
FGeometryParticleState(const FGeometryParticleHandle &InParticle, const FDirtyPropertiesPool &InPool)
Definition RewindData.h:1320
Definition RewindData.h:1493
FJointState(const FJointStateBase *InState, const FPBDJointConstraintHandle &InJoint, const FDirtyPropertiesPool &InPool, const FFrameAndPhase InFrameAndPhase)
Definition RewindData.h:1501
FJointState(const FPBDJointConstraintHandle &InJoint, const FDirtyPropertiesPool &InPool)
Definition RewindData.h:1495
FString ToString() const
Definition RewindData.h:1515
Definition KinematicTargets.h:34
Definition PBDJointConstraints.h:28
Definition PBDJointConstraintTypes.h:114
Definition PBDRigidsSolver.h:84
Definition ParticleDirtyFlags.h:368
Definition ParticleDirtyFlags.h:177
Definition ParticleDirtyFlags.h:60
void SetR(const FRotation3 &InR)
Definition ParticleDirtyFlags.h:103
void SetX(const FVec3 &InX)
Definition ParticleDirtyFlags.h:99
Definition ParticleDirtyFlags.h:118
Definition RewindData.h:1012
const FCollisionFilterData & GetQueryData() const
Definition RewindData.h:1021
FPerShapeDataState(const FPerShapeDataStateBase *InState, const FGeometryParticleHandle &InParticle, const int32 InShapeIdx)
Definition RewindData.h:1014
Definition RewindData.h:1650
void AdvanceFrame(FReal DeltaTime, const CreateCache &CreateCacheFunc)
Definition RewindData.h:1760
int32 GetLatestFrame() const
Definition RewindData.h:1684
void RestoreHistoryState(FGeometryParticleHandle &Handle, const int32 &PositionValidCount, const int32 &VelocityValidCount, const int32 &PositionNextIterator, const int32 &VelocityNextIterator)
Definition RewindData.h:1736
void Init(FPBDRigidsSolver *InSolver, int32 NumFrames, bool InRewindDataOptimization, int32 InCurrentFrame)
Definition RewindData.h:1655
void RemoveObject(const FGeometryParticleHandle *Particle, const EAllowShrinking AllowShrinking=EAllowShrinking::Default)
Definition RewindData.h:1693
int32 Capacity() const
Definition RewindData.h:1682
void SetResimFrame(int32 Frame)
Definition RewindData.h:1909
int32 GetEarliestFrame_Internal() const
Definition RewindData.h:1713
void AddInputHistory(const TSharedPtr< FBaseRewindHistory > &InputHistory)
Definition RewindData.h:1827
void RemoveInputHistory(const TSharedPtr< FBaseRewindHistory > &InputHistory, Chaos::FGeometryParticleHandle *Particle)
Definition RewindData.h:1849
const int32 GetResimFrame() const
Definition RewindData.h:1908
void RemoveStateHistory(const TSharedPtr< FBaseRewindHistory > &StateHistory, Chaos::FGeometryParticleHandle *Particle)
Definition RewindData.h:1881
const int32 GetBlockedResimFrame() const
Definition RewindData.h:1922
void AddStateHistory(const TSharedPtr< FBaseRewindHistory > &StateHistory)
Definition RewindData.h:1859
void AddStateHistory(const TSharedPtr< FBaseRewindHistory > &StateHistory, Chaos::FGeometryParticleHandle *Particle)
Definition RewindData.h:1871
void SetRewindDataOptimization(bool InRewindDataOptimization)
Definition RewindData.h:1926
void RemoveStateHistory(const TSharedPtr< FBaseRewindHistory > &StateHistory)
Definition RewindData.h:1865
bool IsFinalResim() const
Definition RewindData.h:1804
void ExtractHistoryState(FGeometryParticleHandle &Handle, int32 &PositionValidCount, int32 &VelocityValidCount, int32 &PositionNextIterator, int32 &VelocityNextIterator)
Definition RewindData.h:1729
void Init(FPBDRigidsSolver *InSolver, int32 NumFrames, int32 InCurrentFrame)
Definition RewindData.h:1667
void RemoveObject(const FPBDJointConstraintHandle *Joint, const EAllowShrinking AllowShrinking=EAllowShrinking::Default)
Definition RewindData.h:1703
int32 GetFramesSaved() const
Definition RewindData.h:1685
bool IsFrameWithinRewindHistory(int32 Frame)
Definition RewindData.h:1912
FReal GetDeltaTimeForFrame(int32 Frame) const
Definition RewindData.h:1687
bool IsResim() const
Definition RewindData.h:1799
void AddInputHistory(const TSharedPtr< FBaseRewindHistory > &InputHistory, Chaos::FGeometryParticleHandle *Particle)
Definition RewindData.h:1839
IResimCacheBase * GetCurrentStepResimCache() const
Definition RewindData.h:1748
int32 GetNumDirtyParticles() const
Definition RewindData.h:1810
void RemoveInputHistory(const TSharedPtr< FBaseRewindHistory > &InputHistory)
Definition RewindData.h:1833
int32 CurrentFrame() const
Definition RewindData.h:1683
Definition ParticleDirtyFlags.h:1228
Definition SingleParticlePhysicsProxy.h:58
Definition ResimCacheBase.h:11
Definition RewindData.h:2189
virtual int32 TriggerRewindIfNeeded_Internal(int32 LatestStepCompleted)
Definition RewindData.h:2217
virtual void ApplyCallbacks_Internal(int32 PhysicsStep, const TArray< ISimCallbackObject * > &SimCallbackObjects)
Definition RewindData.h:2198
virtual void ProcessInputs_Internal(int32 PhysicsStep, const TArray< FSimCallbackInputAndObject > &SimCallbackInputs)
Definition RewindData.h:2195
virtual void PostResimStep_Internal(int32 PhysicsStep)
Definition RewindData.h:2227
virtual void PreResimStep_Internal(int32 PhysicsStep, bool bFirstStep)
Definition RewindData.h:2222
virtual void ProcessInputs_External(int32 PhysicsStep, const TArray< FSimCallbackInputAndObject > &SimCallbackInputs)
Definition RewindData.h:2204
virtual void UnregisterRewindableSimCallback_Internal(ISimCallbackObject *Callback)
Definition RewindData.h:2233
virtual void InjectInputs_External(int32 PhysicsStep, int32 NumSteps)
Definition RewindData.h:2211
virtual ~IRewindCallback()=default
virtual void SetResimDebugInfo_Internal(const FResimDebugInfo &ResimDebugInfo)
Definition RewindData.h:2236
virtual void RegisterRewindableSimCallback_Internal(ISimCallbackObject *Callback)
Definition RewindData.h:2230
Definition SimCallbackObject.h:68
Definition RewindData.h:1543
const TVal & FindChecked(const TKey Key) const
Definition RewindData.h:1564
auto cend() const
Definition RewindData.h:1635
void Reset()
Definition RewindData.h:1623
decltype(ConstifyHelper(((TVal *) 0) ->GetObjectPtr())) TKey
Definition RewindData.h:1547
auto end()
Definition RewindData.h:1632
TVal & GetDenseAt(const int32 Idx)
Definition RewindData.h:1638
TVal * Find(const TKey Key)
Definition RewindData.h:1586
int32 Num() const
Definition RewindData.h:1629
auto cbegin() const
Definition RewindData.h:1634
void Remove(const TKey Key, const EAllowShrinking AllowShrinking)
Definition RewindData.h:1596
auto begin()
Definition RewindData.h:1631
TVal & Add(const TKey Key, TVal &&Val)
Definition RewindData.h:1549
const TVal * Find(const TKey Key) const
Definition RewindData.h:1576
void Shrink()
Definition RewindData.h:1618
const TVal & GetDenseAt(const int32 Idx) const
Definition RewindData.h:1637
TVal & FindChecked(const TKey Key)
Definition RewindData.h:1570
Definition ParticleHandle.h:436
Definition Handles.h:93
Definition ParticleHandle.h:987
Definition PBDRigidParticles.h:22
Definition RewindData.h:630
bool IsEmpty() const
Definition RewindData.h:707
const bool GetHeadFrameAndPhase(FFrameAndPhase &OutFrameAndPhase) const
Definition RewindData.h:678
bool IsClean(const FFrameAndPhase FrameAndPhase) const
Definition RewindData.h:741
T & Insert(const FFrameAndPhase FrameAndPhase, FDirtyPropertiesPool &Manager)
Definition RewindData.h:759
bool IsInSync(const THandle &Handle, const FFrameAndPhase FrameAndPhase, const FDirtyPropertiesPool &Pool) const
Definition RewindData.h:747
void Reset()
Definition RewindData.h:702
void ClearEntryAndFuture(const FFrameAndPhase FrameAndPhase)
Definition RewindData.h:712
const T * Read(const FFrameAndPhase FrameAndPhase, const FDirtyPropertiesPool &Manager) const
Definition RewindData.h:671
TParticlePropertyBuffer(const TParticlePropertyBuffer< T, PropName > &Other)=delete
~TParticlePropertyBuffer()
Definition RewindData.h:651
TParticlePropertyBuffer(TParticlePropertyBuffer< T, PropName > &&Other)
Definition RewindData.h:639
TParticlePropertyBuffer(int32 InCapacity)
Definition RewindData.h:632
void Release(FDirtyPropertiesPool &Manager)
Definition RewindData.h:690
T & WriteAccessMonotonic(const FFrameAndPhase FrameAndPhase, FDirtyPropertiesPool &Manager)
Definition RewindData.h:658
void RestoreBufferState(const int32 &ValidCount, const int32 &NextIterator)
Definition RewindData.h:735
void ExtractBufferState(int32 &ValidCount, int32 &NextIterator) const
Definition RewindData.h:729
T * WriteAccessNonDecreasing(const FFrameAndPhase FrameAndPhase, FDirtyPropertiesPool &Manager)
Definition RewindData.h:665
Definition ParticleIterator.h:639
Definition RewindData.h:972
const T & Read() const
Definition RewindData.h:974
bool IsSet() const
Definition RewindData.h:986
void Write(const T &InVal)
Definition RewindData.h:980
Definition ParticleDirtyFlags.h:1303
void RemoveElement(const FPropertyIdx Idx)
Definition ParticleDirtyFlags.h:1320
Definition RewindData.h:1107
TShapesArrayState(const TParticle &InParticle, const FShapesArrayStateBase *InState)
Definition RewindData.h:1109
FPerShapeDataState operator[](const int32 ShapeIdx) const
Definition RewindData.h:1114
Definition Vector.h:41
Definition Archive.h:1208
Definition PhysicsProxyBase.h:97
Definition Array.h:670
void SetNum(SizeType NewNum, EAllowShrinking AllowShrinking=UE::Core::Private::AllowShrinkingByDefault< AllocatorType >())
Definition Array.h:2308
SizeType Insert(std::initializer_list< ElementType > InitList, const SizeType InIndex)
Definition Array.h:1875
Definition CircularBuffer.h:18
Definition UnrealString.h.inl:34
Definition SharedPointer.h:692
UE_FORCEINLINE_HINT TWeakPtr< ObjectType, Mode > ToWeakPtr() const
Definition SharedPointer.h:1055
Definition FunctionFwd.h:19
Definition UniquePtr.h:107
Definition CoreNet.h:191
Definition SkeletalMeshComponent.h:307
FString ToStringHelper(const T &Val)
Definition RewindData.h:1046
EPlasticityType
Definition PBDJointConstraintTypes.h:36
const T * ConstifyHelper(T *Ptr)
Definition RewindData.h:1535
int32 ComputeCircularSize(int32 NumFrames)
Definition RewindData.h:1163
FRealDouble FReal
Definition Real.h:22
EJointForceMode
Definition PBDJointConstraintTypes.h:30
EObjectStateType
Definition ObjectState.h:10
int32 FPropertyIdx
Definition ParticleDirtyFlags.h:1299
float FRealSingle
Definition Real.h:14
TVector< FReal, 3 > FVec3
Definition Core.h:17
TGeometryParticleHandle< FReal, 3 > FGeometryParticleHandle
Definition ParticleHandleFwd.h:24
T NoRefHelper(const T &Ref)
Definition RewindData.h:1539
CHAOS_API int32 SkipDesyncTest
Definition RewindData.cpp:830
FPBDRigidsSolver FPBDRigidsSolver
Definition PBDRigidsEvolutionFwd.h:15
EJointMotionType
Definition PBDJointConstraintTypes.h:23
void CopyDataFromObject(TData &Data, const TObj &Obj)
Definition RewindData.h:618
EDesyncResult
Definition RewindData.h:945
@ InSync
Definition RewindData.h:946
@ Desync
Definition RewindData.h:947
@ NeedInfo
Definition RewindData.h:948
Definition OverriddenPropertySet.cpp:45
State
Definition PacketHandler.h:88
void MarkDirty(UE::Net::FReplicationStateHeader &InternalState, FNetBitArrayView &MemberChangeMask, const FReplicationStateMemberChangeMaskDescriptor &ChangeMaskInfo)
Definition ReplicationStateUtil.h:76
UE_STRING_CLASS Result(Forward< LhsType >(Lhs), RhsLen)
Definition String.cpp.inl:732
@ false
Definition radaudio_common.h:23
Definition RewindData.h:32
virtual bool CopyAlteredData(Chaos::FBaseRewindHistory &OutHistory, bool bIncludeUnimportant=true, bool bIncludeImportant=false)
Definition RewindData.h:90
virtual TUniquePtr< FBaseRewindHistory > Clone() const =0
virtual FORCEINLINE ~FBaseRewindHistory()
Definition RewindData.h:33
virtual FORCEINLINE void DebugData(const Chaos::FBaseRewindHistory &NewData, TArray< int32 > &LocalFrames, TArray< int32 > &ServerFrames, TArray< int32 > &InputFrames)
Definition RewindData.h:132
virtual FORCEINLINE bool ExtractData(const int32 ExtractFrame, const bool bResetSolver, void *HistoryData, const bool bExactFrame=false)
Definition RewindData.h:65
virtual const bool HasDataInHistory() const
Definition RewindData.h:152
virtual const int32 GetEarliestFrame() const
Definition RewindData.h:146
virtual bool CopyAllData(Chaos::FBaseRewindHistory &OutHistory, bool bIncludeUnimportant=true, bool bIncludeImportant=false)
Definition RewindData.h:85
virtual const int32 GetHistorySize() const
Definition RewindData.h:149
virtual FORCEINLINE void DebugData(const FString &DebugText)
Definition RewindData.h:129
virtual FORCEINLINE void ApplyDataRange(const int32 FromFrame, const int32 ToFrame, void *ActorComponent, const bool bOnlyImportant=false)
Definition RewindData.h:68
virtual bool CopyData(Chaos::FBaseRewindHistory &OutHistory, const uint32 StartFrame, const uint32 EndFrame, bool bIncludeUnimportant=true, bool bIncludeImportant=false)
Definition RewindData.h:97
virtual FORCEINLINE bool HasValidData(const int32 ValidFrame) const
Definition RewindData.h:48
virtual TUniquePtr< FBaseRewindHistory > CopyFramesWithOffset(const uint32 StartFrame, const uint32 EndFrame, const int32 FrameOffset)=0
virtual FORCEINLINE int32 CountAlteredData(const bool bIncludeUnimportant=true, const bool bIncludeImportant=false)
Definition RewindData.h:58
virtual FORCEINLINE void SetRecordDataIncremental(const bool bInIncremental)
Definition RewindData.h:80
virtual FORCEINLINE int32 CountValidData(const uint32 StartFrame, const uint32 EndFrame, const bool bIncludeUnimportant=true, const bool bIncludeImportant=false)
Definition RewindData.h:55
virtual int32 ReceiveNewData(FBaseRewindHistory &NewData, const int32 FrameOffset, const bool CompareDataForRewind=false, const bool bImportant=false, int32 TryInjectAtFrame=INDEX_NONE)
Definition RewindData.h:110
virtual void NetSerialize(FArchive &Ar, UPackageMap *PackageMap, TUniqueFunction< void(void *Data, const int32 DataIndex)> DataSetupFunction)
Definition RewindData.h:123
virtual FORCEINLINE bool ApplyInputs(const int32 ApplyFrame, const bool bResetSolver)
Definition RewindData.h:140
virtual FORCEINLINE void SetImportant(const bool bImportant, const int32 Frame=INDEX_NONE)
Definition RewindData.h:62
virtual FORCEINLINE void MergeData(const int32 FromFrame, void *ToData)
Definition RewindData.h:71
virtual bool CopyAllDataGrowingOrdered(Chaos::FBaseRewindHistory &OutHistory)
Definition RewindData.h:100
virtual void NetSerialize(FArchive &Ar, UPackageMap *PackageMap)
Definition RewindData.h:120
virtual FORCEINLINE void SetPackageMap(class UPackageMap *InPackageMap)
Definition RewindData.h:45
virtual FORCEINLINE bool RecordDataGrowingOrdered(const void *HistoryData)
Definition RewindData.h:77
virtual FORCEINLINE bool RewindStates(const int32 RewindFrame, const bool bResetSolver)
Definition RewindData.h:136
virtual FORCEINLINE bool RecordData(const int32 RecordFrame, const void *HistoryData)
Definition RewindData.h:74
virtual const int32 GetLatestFrame() const
Definition RewindData.h:143
virtual TUniquePtr< FBaseRewindHistory > CreateNew() const =0
virtual void ValidateDataInHistory(const void *ActorComponent)
Definition RewindData.h:126
virtual void ResetFast()
Definition RewindData.h:158
virtual void Initialize()
Definition RewindData.h:42
virtual void ResizeDataHistory(const int32 FrameCount, const EAllowShrinking AllowShrinking=EAllowShrinking::Default)
Definition RewindData.h:155
Definition RewindData.h:962
FConstDirtyPropData(const FDirtyPropertiesManager *InManager, int32 InDataIdx)
Definition RewindData.h:963
int32 DataIdx
Definition RewindData.h:967
const FDirtyPropertiesManager * Ptr
Definition RewindData.h:966
Definition RewindData.h:953
int32 DataIdx
Definition RewindData.h:958
FDirtyPropertiesManager * Ptr
Definition RewindData.h:957
FDirtyPropData(FDirtyPropertiesManager *InManager, int32 InDataIdx)
Definition RewindData.h:954
Definition ChaosMarshallingManager.h:21
Definition PullPhysicsDataImp.h:62
Definition RewindData.h:551
uint32 Phase
Definition RewindData.h:571
bool operator<(const FFrameAndPhase &Other) const
Definition RewindData.h:573
bool operator<=(const FFrameAndPhase &Other) const
Definition RewindData.h:578
EParticleHistoryPhase
Definition RewindData.h:553
@ PostCallbacks
Definition RewindData.h:565
@ NumPhases
Definition RewindData.h:567
@ PostPushData
Definition RewindData.h:561
@ PrePushData
Definition RewindData.h:558
bool operator==(const FFrameAndPhase &Other) const
Definition RewindData.h:583
int32 Frame
Definition RewindData.h:570
Definition RewindData.h:1166
bool IsCleanExcludingDynamics(const FFrameAndPhase FrameAndPhase) const
Definition RewindData.h:1265
void Reset()
Definition RewindData.h:1223
TParticlePropertyBuffer< FParticleVelocities, EChaosProperty::Velocities > Velocities
Definition RewindData.h:1300
TParticlePropertyBuffer< FParticleDynamicMisc, EChaosProperty::DynamicMisc, false > TargetStates
Definition RewindData.h:1308
FShapesArrayStateBase ShapesArrayState
Definition RewindData.h:1310
void SyncDirtyDynamics(FDirtyPropData &DestManager, const FDirtyChaosProperties &Dirty, const FConstDirtyPropData &SrcManager)
Definition RewindData.cpp:54
TParticlePropertyBuffer< FParticleVelocities, EChaosProperty::Velocities, false > TargetVelocities
Definition RewindData.h:1307
TParticlePropertyBuffer< FParticlePositionRotation, EChaosProperty::XR > ParticlePositionRotation
Definition RewindData.h:1298
TParticlePropertyBuffer< FParticlePositionRotation, EChaosProperty::XR, false > TargetPositions
Definition RewindData.h:1306
TParticlePropertyBuffer< FParticleDynamics, EChaosProperty::Dynamics, false > Dynamics
Definition RewindData.h:1301
void SyncSimWritablePropsFromSim(FDirtyPropData Manager, const TPBDRigidParticleHandle< FReal, 3 > &Rigid)
Definition RewindData.cpp:20
PRAGMA_ENABLE_DEPRECATION_WARNINGS void Release(FDirtyPropertiesPool &Manager)
Definition RewindData.h:1209
FGeometryParticleStateBase(const FGeometryParticleStateBase &Other)=delete
FParticlePositionRotation PreCorrectionXR
Definition RewindData.h:1313
static TShapesArrayState< TParticle > ShapesArray(const FGeometryParticleStateBase *State, const TParticle &Particle)
Definition RewindData.h:1279
bool IsClean(const FFrameAndPhase FrameAndPhase) const
Definition RewindData.h:1260
void RestoreHistoryState(const int32 &PositionValidCount, const int32 &VelocityValidCount, const int32 &PositionNextIterator, const int32 &VelocityNextIterator)
Definition RewindData.h:1254
TParticlePropertyBuffer< FKinematicTarget, EChaosProperty::KinematicTarget, false > KinematicTarget
Definition RewindData.h:1304
FGeometryParticleStateBase & operator=(const FGeometryParticleStateBase &)=delete
bool IsInSync(const FGeometryParticleHandle &Handle, const FFrameAndPhase FrameAndPhase, const FDirtyPropertiesPool &Pool) const
Definition RewindData.cpp:74
FGeometryParticleStateBase(int32 NumFrames, bool bCacheOnePhase)
Definition RewindData.h:1183
void ClearEntryAndFuture(const FFrameAndPhase FrameAndPhase)
Definition RewindData.h:1237
TParticlePropertyBuffer< FParticleDynamicMisc, EChaosProperty::DynamicMisc > DynamicsMisc
Definition RewindData.h:1302
FGeometryParticleStateBase & operator=(FGeometryParticleStateBase &&)=delete
FGeometryParticleStateBase(FGeometryParticleStateBase &&Other)=default
void ExtractHistoryState(int32 &PositionValidCount, int32 &VelocityValidCount, int32 &PositionNextIterator, int32 &VelocityNextIterator) const
Definition RewindData.h:1248
TParticlePropertyBuffer< FParticleNonFrequentData, EChaosProperty::NonFrequentData > NonFrequentData
Definition RewindData.h:1299
void CachePreCorrectionState(const TParticle &Particle)
Definition RewindData.h:1289
TParticlePropertyBuffer< FParticleMassProps, EChaosProperty::MassProps > MassProps
Definition RewindData.h:1303
Definition RewindData.h:1444
void Release(FDirtyPropertiesPool &Manager)
Definition RewindData.h:1462
bool IsClean(const FFrameAndPhase FrameAndPhase) const
Definition RewindData.h:1480
FJointStateBase(const FJointStateBase &Other)=delete
TParticlePropertyBuffer< FProxyBasePairProperty, EChaosProperty::JointParticleProxies > JointProxies
Definition RewindData.h:1489
void Reset()
Definition RewindData.h:1468
FJointStateBase(FJointStateBase &&Other)=default
FJointStateBase(int32 NumFrames, bool bCacheOnePhase)
Definition RewindData.h:1452
TParticlePropertyBuffer< FPBDJointSettings, EChaosProperty::JointSettings > JointSettings
Definition RewindData.h:1488
void ClearEntryAndFuture(const FFrameAndPhase FrameAndPhase)
Definition RewindData.h:1474
Definition RewindData.h:997
static const FCollisionFilterData & GetQueryData(const FPerShapeDataStateBase *State, const TParticle &Particle, int32 ShapeIdx)
Definition RewindData.h:1003
TPerShapeDataStateProperty< FCollisionData, EShapeProperty::CollisionData > CollisionData
Definition RewindData.h:998
TPerShapeDataStateProperty< FMaterialData, EShapeProperty::Materials > MaterialData
Definition RewindData.h:999
Definition RewindData.h:612
FFrameAndPhase FrameAndPhase
Definition RewindData.h:614
FPropertyIdx Ref
Definition RewindData.h:613
Definition RewindData.h:2183
Definition RewindData.h:1030
TArray< FPerShapeDataStateBase > PerShapeData
Definition RewindData.h:1031
FPerShapeDataStateBase & FindOrAdd(const int32 ShapeIdx)
Definition RewindData.h:1033
static bool Helper(const THandle &Handle)
Definition RewindData.h:602
Definition RewindData.h:591
static bool Helper(const THandle &Handle)
Definition RewindData.h:592
Definition RewindData.h:164
virtual FORCEINLINE bool ExtractData(const int32 ExtractFrame, const bool bResetSolver, void *HistoryData, const bool bExactFrame=false) override
Definition RewindData.h:219
DataType & GetAndLoadEarliestData()
Definition RewindData.h:405
int32 LatestFrame
Definition RewindData.h:538
int32 CurrentFrame
Definition RewindData.h:541
FORCEINLINE void ResizeDataHistory(const int32 FrameCount, const EAllowShrinking AllowShrinking=EAllowShrinking::Default) override
Definition RewindData.h:492
DataType & GetCurrentData()
Definition RewindData.h:400
FORCEINLINE TDataRewindHistory(const int32 FrameCount, const bool bIsHistoryLocal)
Definition RewindData.h:165
virtual const bool HasDataInHistory() const
Definition RewindData.h:486
virtual FORCEINLINE void SetRecordDataIncremental(const bool bInIncremental) override
Definition RewindData.h:382
virtual const int32 GetHistorySize() const
Definition RewindData.h:481
int32 NumFrames
Definition RewindData.h:547
const TArray< DataType > & GetDataHistoryConst() const
Definition RewindData.h:456
virtual void Initialize()
Definition RewindData.h:179
virtual FORCEINLINE void MergeData(int32 FromFrame, void *ToData) override
Definition RewindData.h:293
bool bIncremental
Definition RewindData.h:532
TArray< DataType > DataHistory
Definition RewindData.h:535
virtual bool CopyAllDataGrowingOrdered(Chaos::FBaseRewindHistory &OutHistory) override
Definition RewindData.h:387
int32 CurrentIndex
Definition RewindData.h:544
virtual FORCEINLINE ~TDataRewindHistory()
Definition RewindData.h:176
TArray< DataType > & GetDataHistory()
Definition RewindData.h:455
FORCEINLINE const uint32 GetFrameIndex(const int32 Frame) const
Definition RewindData.h:503
virtual FORCEINLINE void ResetFast()
Definition RewindData.h:519
FORCEINLINE bool EvalData(const int32 EvalFrame)
Definition RewindData.h:317
const DataType & GetCurrentData() const
Definition RewindData.h:402
virtual const int32 GetEarliestFrame() const override
Definition RewindData.h:465
FORCEINLINE int32 ClosestData(const int32 DataFrame, const bool bMinData)
Definition RewindData.h:192
virtual const int32 GetLatestFrame() const override
Definition RewindData.h:459
virtual FORCEINLINE bool HasValidData(const int32 ValidFrame) const override
Definition RewindData.h:212
virtual FORCEINLINE bool RecordData(const int32 RecordFrame, const void *HistoryData) override
Definition RewindData.h:329
bool bIsLocalHistory
Definition RewindData.h:529
DataType * GetAndLoadNextIncrementalData()
Definition RewindData.h:423
FORCEINLINE TDataRewindHistory(const int32 FrameCount)
Definition RewindData.h:171
FORCEINLINE bool LoadData(const int32 LoadFrame)
Definition RewindData.h:308
virtual FORCEINLINE bool RecordDataGrowingOrdered(const void *HistoryData) override
Definition RewindData.h:347
FORCEINLINE uint32 NumValidData(const uint32 StartFrame, const uint32 EndFrame) const
Definition RewindData.h:441
Definition CollisionFilterData.h:46
Definition NetworkPhysicsComponent.h:680
static CORE_API const TQuat< double > Identity
Definition Quat.h:63