UDocumentation UE5.7 10.02.2026 (Source)
API documentation for Unreal Engine 5.7
InstanceDataUpdateUtils.h
Go to the documentation of this file.
1// Copyright Epic Games, Inc. All Rights Reserved.
2
3#pragma once
4
5#include "CoreTypes.h"
6#include "HAL/UnrealMemory.h"
8#include "Containers/Array.h"
9#include "RenderingThread.h"
10#include "RenderTransform.h"
14
15#define INSTANCE_DATA_UPDATE_ENABLE_ASYNC_TASK 1
16
22template <typename DeltaType, typename ValueType, typename IndexRemapType>
24{
25 check(InSource.Num() == Delta.GetNumItems() * ElementStride);
26 if (Delta.IsDelta() || !IndexRemap.IsIdentity())
27 {
28 OutDest.SetNumUninitialized(DestNumElements * ElementStride);
29 for (auto It = Delta.GetIterator(); It; ++It)
30 {
31 int32 SrcIndex = It.GetItemIndex();
32 int32 DestIndex = It.GetIndex();
33
34 if (IndexRemap.Remap(SrcIndex, DestIndex))
35 {
36 FMemory::Memcpy(&OutDest[DestIndex * ElementStride], &InSource[SrcIndex * ElementStride], ElementStride * sizeof(ValueType));
37 }
38 }
39 }
40 else
41 {
42 check(InSource.Num() == DestNumElements * ElementStride);
44 }
45}
46
50template <typename DeltaType, typename ValueType, typename IndexRemapType>
51inline void Scatter(bool bHasData, const DeltaType& Delta, TArray<ValueType>& DestData, int32 NumOutElements, TArray<ValueType>&& InData, const IndexRemapType& IndexRemap, int32 ElementStride = 1)
52{
53 if (bHasData)
54 {
55 ::Scatter(Delta, DestData, NumOutElements, MoveTemp(InData), IndexRemap, ElementStride);
56 }
57 else
58 {
59 DestData.Reset();
60 }
61}
62
67template <typename DeltaType, typename ValueType, typename InValueArrayType>
69{
70 // strides & element count matches - just copy the data
71 if (InSource.Num() == Delta.GetNumItems() * ElementStride)
72 {
74 }
75 else if (Delta.IsEmpty())
76 {
77 OutDest.Reset();
78 }
79 else if (Delta.IsDelta() || ElementStride != 1)
80 {
81 OutDest.Reset(Delta.GetNumItems() * ElementStride);
82 for (auto It = Delta.GetIterator(); It; ++It)
83 {
84 check(OutDest.Num() < Delta.GetNumItems() * ElementStride);
85 OutDest.Append(&InSource[It.GetIndex() * ElementStride], ElementStride);
86 }
87 }
88}
89
93{
94 FORCEINLINE constexpr bool IsIdentity() const { return true; }
96 FORCEINLINE constexpr bool RemapDestIndex(int32 Index) const { return true; }
97 FORCEINLINE bool Remap(int32& SrcIndex, int32& DstIndex) const { return true; }
98};
99
104{
105 FORCEINLINE constexpr bool IsIdentity() const { return false; }
107 FORCEINLINE bool RemapDestIndex(int32& Index) const { return true;}
109 {
111 return true;
112 }
114};
115
119template<typename ValueType>
120void CondMove(bool bCondition, TArray<ValueType>& Data, int32 FromIndex, int32 ToIndex, int32 NumElements = 1)
121{
122 if (bCondition)
123 {
124 FMemory::Memcpy(&Data[ToIndex * NumElements], &Data[FromIndex * NumElements], NumElements * sizeof(ValueType));
125 }
126}
127
132{
137
139 {
140 // we can use unaligmed vectorized load since we know there is data beyond the three rows (the origin), so it is ok to load whatever into the 4th component.
141 R0 = VectorLoad(&RenderTransform.TransformRows[0].X);
142 R1 = VectorLoad(&RenderTransform.TransformRows[1].X);
143 R2 = VectorLoad(&RenderTransform.TransformRows[2].X);
144 // But not for the origin
146 }
147};
148
150{
151 FRenderTransform Result;
152
153 // First row of result (Matrix1[0] * Matrix2).
154 {
155 // we can use unaligmed vectorized load since we know there is data beyond the three rows (the origin), so it is ok to load whatever into the 4th component.
156 const VectorRegister4Float ARow = VectorLoad(&LocalToPrimitive.TransformRows[0].X);
157 VectorRegister4Float R0 = VectorMultiply(VectorReplicate(ARow, 0), PrimitiveToWorld.R0);
158 R0 = VectorMultiplyAdd(VectorReplicate(ARow, 1), PrimitiveToWorld.R1, R0);
159 R0 = VectorMultiplyAdd(VectorReplicate(ARow, 2), PrimitiveToWorld.R2, R0);
160
161 // We can use unaligmed vectorized store since we know there is data beyond the three floats that is written later
162 // Note: stomps the X of the TransformRows[1]
163 VectorStore(R0, &Result.TransformRows[0].X);
164 }
165
166 // Second row of result (Matrix1[1] * Matrix2).
167 {
168 // we can use unaligmed vectorized load since we know there is data beyond the three rows (the origin), so it is ok to load whatever into the 4th component.
169 const VectorRegister4Float ARow = VectorLoad(&LocalToPrimitive.TransformRows[1].X);
170 VectorRegister4Float R1 = VectorMultiply(VectorReplicate(ARow, 0), PrimitiveToWorld.R0);
171 R1 = VectorMultiplyAdd(VectorReplicate(ARow, 1), PrimitiveToWorld.R1, R1);
172 R1 = VectorMultiplyAdd(VectorReplicate(ARow, 2), PrimitiveToWorld.R2, R1);
173
174 // We can use unaligmed vectorized store since we know there is data beyond the three floats that is written later
175 // Note: stomps the X of the TransformRows[2]
176 VectorStore(R1, &Result.TransformRows[1].X);
177 }
178
179 // Third row of result (Matrix1[2] * Matrix2).
180 {
181 // we can use unaligmed vectorized load since we know there is data beyond the three rows (the origin), so it is ok to load whatever into the 4th component.
182 const VectorRegister4Float ARow = VectorLoad(&LocalToPrimitive.TransformRows[2].X);
183 VectorRegister4Float R2 = VectorMultiply(VectorReplicate(ARow, 0), PrimitiveToWorld.R0);
184 R2 = VectorMultiplyAdd(VectorReplicate(ARow, 1), PrimitiveToWorld.R1, R2);
185 R2 = VectorMultiplyAdd(VectorReplicate(ARow, 2), PrimitiveToWorld.R2, R2);
186
187 // We can use unaligmed vectorized store since we know there is data beyond the three floats that is written later
188 // Note: stomps the X of the Origin
189 VectorStore(R2, &Result.TransformRows[2].X);
190 }
191
192 // Fourth row of result (Matrix1[3] * Matrix2).
193 {
194 // can _NOT_ use VectorLoad, or we'll run off the end of the FRenderTransform struct.
195 const VectorRegister4Float ARow = VectorLoadFloat3(&LocalToPrimitive.Origin);
196
197 // Add B3 at once (instead of mult by 1.0 which would have been the fourth value in the 4x4 version of the matrix)
198 VectorRegister4Float R3 = VectorMultiplyAdd(VectorReplicate(ARow, 0), PrimitiveToWorld.R0, PrimitiveToWorld.Origin);
199 R3 = VectorMultiplyAdd(VectorReplicate(ARow, 1), PrimitiveToWorld.R1, R3);
200 R3 = VectorMultiplyAdd(VectorReplicate(ARow, 2), PrimitiveToWorld.R2, R3);
201
202 VectorStoreFloat3(R3, &Result.Origin);
203 }
204 return Result;
205}
206
207
212template <typename DeltaType, typename IndexRemapType>
214{
216
217 if (DeltaRange.IsEmpty())
218 {
219 return;
220 }
221
222 if (PrimitiveToRelativeWorld.IsScaleNonUniform())
223 {
225 for (auto It = DeltaRange.GetIterator(); It; ++It)
226 {
227 int32 ItemIndex = It.GetItemIndex();
228 int32 InstanceIndex = It.GetIndex();
229
230 if (IndexRemap.Remap(ItemIndex, InstanceIndex))
231 {
233 // Remove shear
234 LocalToPrimitiveRelativeWorld.Orthogonalize();
236 }
237 }
238 }
239 else
240 {
242 for (auto It = DeltaRange.GetIterator(); It; ++It)
243 {
244 int32 ItemIndex = It.GetItemIndex();
245 int32 InstanceIndex = It.GetIndex();
246
247 if (IndexRemap.Remap(ItemIndex, InstanceIndex))
248 {
249 OutInstanceToPrimitiveRelative[InstanceIndex] = VectorMatrixMultiply(InstanceTransforms[ItemIndex], PrimitiveToRelativeWorldVR);
250 }
251 }
252 }
253
254};
255
257{
258 if (FMath::Abs(PadAmount) < UE_SMALL_NUMBER)
259 {
261 }
262
263 FVector3f Scale = LocalToWorld.GetScale();
264 return FVector3f(
265 Scale.X > 0.0f ? PadAmount / Scale.X : 0.0f,
266 Scale.Y > 0.0f ? PadAmount / Scale.Y : 0.0f,
267 Scale.Z > 0.0f ? PadAmount / Scale.Z : 0.0f);
268}
269
270
271template <typename IndexRemapType>
273{
274 // update mapping, create explicit mapping if needed
275 if (ChangeSet.bIdentityIdMap && IndexRemap.IsIdentity())
276 {
277 // Reset to identity mapping with the new number of instances
278 OutInstanceIdIndexMap.Reset(ChangeSet.NumSourceInstances);
279 }
280 else
281 {
282 auto IndexDelta = ChangeSet.GetIndexChangedDelta();
283 bool bIsFull = !IndexDelta.IsDelta() || ChangeSet.NumSourceInstances == ChangeSet.IndexToIdMapDeltaData.Num();
284
285 // Efficient full-data update path if there is no index remap
286 if (bIsFull && IndexRemap.IsIdentity())
287 {
288 OutInstanceIdIndexMap.RebuildFromIndexToIdMap(MoveTemp(ChangeSet.IndexToIdMapDeltaData), ChangeSet.MaxInstanceId);
289 }
290 else
291 {
292 // General path that handles incremental removes and other updates.
293 OutInstanceIdIndexMap.ResizeExplicit(ChangeSet.NumSourceInstances, ChangeSet.MaxInstanceId);
294
295 // If any were removed, we need to clear the associated IDs _before_ updating (since they may have been added again)
296 for (TConstSetBitIterator<> It(ChangeSet.InstanceAttributeTracker.GetRemovedIterator()); It; ++It)
297 {
298 // There may be more bits set as things that are marked as removed may no longer be in the map
299 if (It.GetIndex() >= OutInstanceIdIndexMap.GetMaxInstanceId())
300 {
301 break;
302 }
303 OutInstanceIdIndexMap.SetInvalid(FPrimitiveInstanceId{It.GetIndex()});
304 }
305
306 // Update index mappings
307 for (auto It = IndexDelta.GetIterator(); It; ++It)
308 {
309 int32 NewInstanceIndex = It.GetIndex();
310 int32 ItemIndex = It.GetItemIndex();
311
312 IndexRemap.Remap(ItemIndex, NewInstanceIndex);
313
314 FPrimitiveInstanceId InstanceId = ChangeSet.bIdentityIdMap ? FPrimitiveInstanceId{ItemIndex} : ChangeSet.IndexToIdMapDeltaData[ItemIndex];
315 OutInstanceIdIndexMap.Update(InstanceId, NewInstanceIndex);
316 }
317 }
318 }
319}
320
321template <typename IndexRemapType>
323{
324 ChangeSet.GetCustomDataReader().Scatter(ProxyData.InstanceCustomData, IndexRemap);
325 ProxyData.NumCustomDataFloats = ChangeSet.NumCustomDataFloats;
326 check(ProxyData.Flags.bHasPerInstanceCustomData || ProxyData.NumCustomDataFloats == 0);
327 ChangeSet.GetSkinningDataReader().Scatter(ProxyData.InstanceSkinningData, IndexRemap);
328 ChangeSet.GetLightShadowUVBiasReader().Scatter(ProxyData.InstanceLightShadowUVBias, IndexRemap);
329
330#if WITH_EDITOR
331 ChangeSet.GetEditorDataReader().Scatter(ProxyData.InstanceEditorData, IndexRemap);
332#endif
333
334 // Delayed per instance random generation, moves it off the GT and RT, but still sucks
335 if (ChangeSet.Flags.bHasPerInstanceRandom)
336 {
337 // TODO: only need to process added instances? No help for ISM since the move path would be taken.
338 // TODO: OTOH for HISM there is no meaningful data, so just skipping and letting the SetNumZeroed fill in the blanks is fine.
339
340 // TODO: Move this to the caller, i.e., the update lambda?
341 ProxyData.InstanceRandomIDs.SetNumZeroed(ChangeSet.NumSourceInstances);
342 if (ChangeSet.GeneratePerInstanceRandomIds)
343 {
344 // NOTE: this is not super efficient(!)
346 TmpInstanceRandomIDs.SetNumZeroed(ChangeSet.NumSourceInstances);
347 ChangeSet.GeneratePerInstanceRandomIds(TmpInstanceRandomIDs);
349 Scatter(PerInstanceRandomDelta, ProxyData.InstanceRandomIDs, ChangeSet.NumSourceInstances, MoveTemp(TmpInstanceRandomIDs), IndexRemap);
350 }
351 //else
352 //{
353 // IndexRemap.Scatter(true, PerInstanceRandomDelta, ProxyData.InstanceRandomIDs, ChangeSet.NumSourceInstances, MoveTemp(ChangeSet.InstanceRandomIDs));
354 //}
355 }
356 else
357 {
358 ProxyData.InstanceRandomIDs.Reset();
359 }
360}
361
362template <typename TaskLambdaType>
364{
365 // Make sure any previous tasks are done.
366 InstanceDataUpdateTaskInfo.WaitForUpdateCompletion();
367 InstanceDataUpdateTaskInfo.InstanceDataBufferHeader = InInstanceDataBufferHeader;
368
369#if INSTANCE_DATA_UPDATE_ENABLE_ASYNC_TASK
370 InstanceDataUpdateTaskInfo.UpdateTaskHandle = UE::Tasks::Launch(TEXT("FInstanceDataUpdateTaskInfo::BeginUpdateTask"), MoveTemp(TaskLambda));
371#else
372 InstanceDataUpdateTaskInfo.UpdateTaskHandle = UE::Tasks::FTask();
373 TaskLambda();
374#endif
375}
376
377template <typename ProxyType, typename TaskLambdaType>
378void DispatchInstanceDataUpdateTask(bool bIsUnattached, const TSharedPtr<ProxyType, ESPMode::ThreadSafe>& InstanceDataProxy, const FInstanceDataBufferHeader& InstanceDataBufferHeader, TaskLambdaType&& TaskLambda)
379{
380 FInstanceDataUpdateTaskInfo *InstanceDataUpdateTaskInfo = InstanceDataProxy->GetUpdateTaskInfo();
381#if DO_CHECK
382 auto OuterTaskLambda = [InnerTaskLambda = MoveTemp(TaskLambda), InstanceDataBufferHeader, InstanceDataProxy = InstanceDataProxy]() mutable
383 {
384 FInstanceDataUpdateTaskInfo *InstanceDataUpdateTaskInfo = InstanceDataProxy->GetUpdateTaskInfo();
385 check(!InstanceDataUpdateTaskInfo || InstanceDataUpdateTaskInfo->GetHeader() == InstanceDataBufferHeader);
387 check(!InstanceDataUpdateTaskInfo || InstanceDataUpdateTaskInfo->GetHeader() == InstanceDataBufferHeader);
388 check(!InstanceDataUpdateTaskInfo || InstanceDataBufferHeader.NumInstances == InstanceDataProxy->GeInstanceSceneDataBuffers()->GetNumInstances());
389 // check(InstanceDataBufferHeader.Flags == InstanceDataProxy->GetData().GetFlags());
390 const FInstanceDataFlags HeaderFlags = InstanceDataBufferHeader.Flags;
391 const bool bHasAnyPayloadData = HeaderFlags.bHasPerInstanceHierarchyOffset
392 || HeaderFlags.bHasPerInstanceLocalBounds
393 || HeaderFlags.bHasPerInstanceDynamicData
394 || HeaderFlags.bHasPerInstanceLMSMUVBias
395 || HeaderFlags.bHasPerInstanceCustomData
396 || HeaderFlags.bHasPerInstancePayloadExtension
397 || HeaderFlags.bHasPerInstanceSkinningData
398 || HeaderFlags.bHasPerInstanceEditorData;
399 check(bHasAnyPayloadData || InstanceDataBufferHeader.PayloadDataStride == 0);
400 check(!bHasAnyPayloadData || InstanceDataBufferHeader.PayloadDataStride != 0);
401 };
402#else
403 TaskLambdaType OuterTaskLambda = MoveTemp(TaskLambda);
404#endif
405 // Dispatch from any thread.
406 if (bIsUnattached)
407 {
408 if (InstanceDataUpdateTaskInfo)
409 {
410 BeginInstanceDataUpdateTask(*InstanceDataUpdateTaskInfo, MoveTemp(OuterTaskLambda), InstanceDataBufferHeader);
411 }
412 else
413 {
415 }
416 }
417 else
418 {
419 // Mutating an existing data, must dispatch from RT (such that it does not happen mid-frame).
420 // (One could imagine other scheduling mechanisms)
422 [InstanceDataUpdateTaskInfo,
423 InstanceDataBufferHeader,
425 {
426 if (InstanceDataUpdateTaskInfo)
427 {
428 BeginInstanceDataUpdateTask(*InstanceDataUpdateTaskInfo, MoveTemp(OuterTaskLambda), InstanceDataBufferHeader);
429 }
430 else
431 {
433 }
434 });
435 }
436}
437
439{
440 template <typename ScalarType>
442 {
443 Ar << Item.Coord;
444 Ar << Item.Level;
445 return Ar;
446 }
447}
448
450{
451 Ar << Item.Location;
452 Ar << Item.NumInstances;
453
454 return Ar;
455}
456
457#if WITH_EDITOR
458
460{
461public:
463 {
465 int32 InstanceIndex;
466 };
467
468 template <typename GetWorldSpaceInstanceSphereFuncType>
470 {
471 int32 FirstLevel = MinLevel;
472
473 SortedInstances.Reserve(NumInstances);
474 for (int32 InstanceIndex = 0; InstanceIndex < NumInstances; ++InstanceIndex)
475 {
477
479
480 FSortedInstanceItem& Item = SortedInstances.AddDefaulted_GetRef();
481 Item.InstanceLoc = InstanceLoc;
482 Item.InstanceIndex = InstanceIndex;
483 }
484
485 // Sort the instances according to hash location (first level, then coordinate) and last on instance Index.
486 SortedInstances.Sort(
487 [](const FSortedInstanceItem& A, const FSortedInstanceItem& B) -> bool
488 {
489 if (A.InstanceLoc.Level != B.InstanceLoc.Level)
490 {
491 return A.InstanceLoc.Level < B.InstanceLoc.Level;
492 }
493 if (A.InstanceLoc.Coord.X != B.InstanceLoc.Coord.X)
494 {
495 return A.InstanceLoc.Coord.X < B.InstanceLoc.Coord.X;
496 }
497 if (A.InstanceLoc.Coord.Y != B.InstanceLoc.Coord.Y)
498 {
499 return A.InstanceLoc.Coord.Y < B.InstanceLoc.Coord.Y;
500 }
501 if (A.InstanceLoc.Coord.Z != B.InstanceLoc.Coord.Z)
502 {
503 return A.InstanceLoc.Coord.Z < B.InstanceLoc.Coord.Z;
504 }
505 return A.InstanceIndex < B.InstanceIndex;
506 }
507 );
508 }
509 TArray<FSortedInstanceItem> SortedInstances;
510};
511
512#endif //WITH_EDITOR
#define FORCEINLINE
Definition AndroidPlatform.h:140
#define check(expr)
Definition AssertionMacros.h:314
#define FORCEINLINE_DEBUGGABLE
Definition CoreMiscDefines.h:74
#define TEXT(x)
Definition Platform.h:1272
FPlatformTypes::int32 int32
A 32-bit signed integer.
Definition Platform.h:1125
UE_FORCEINLINE_HINT TSharedRef< CastToType, Mode > StaticCastSharedRef(TSharedRef< CastFromType, Mode > const &InSharedRef)
Definition SharedPointer.h:127
FORCEINLINE uint32 ToIndex(FHairStrandsTiles::ETileType Type)
Definition HairStrandsData.h:93
void Gather(const DeltaType &Delta, TArray< ValueType > &OutDest, const InValueArrayType &InSource, int32 ElementStride=1)
Definition InstanceDataUpdateUtils.h:68
void BeginInstanceDataUpdateTask(FInstanceDataUpdateTaskInfo &InstanceDataUpdateTaskInfo, TaskLambdaType &&TaskLambda, const FInstanceDataBufferHeader &InInstanceDataBufferHeader)
Definition InstanceDataUpdateUtils.h:363
FVector3f GetLocalBoundsPadExtent(const FRenderTransform &LocalToWorld, float PadAmount)
Definition InstanceDataUpdateUtils.h:256
FArchive & operator<<(FArchive &Ar, FInstanceSceneDataBuffers::FCompressedSpatialHashItem &Item)
Definition InstanceDataUpdateUtils.h:449
FORCEINLINE_DEBUGGABLE FRenderTransform VectorMatrixMultiply(const FRenderTransform &LocalToPrimitive, const FRenderTransformVectorRegister &PrimitiveToWorld)
Definition InstanceDataUpdateUtils.h:149
void ApplyAttributeChanges(FInstanceUpdateChangeSet &ChangeSet, const IndexRemapType &IndexRemap, FInstanceSceneDataBuffers::FWriteView &ProxyData)
Definition InstanceDataUpdateUtils.h:322
void UpdateIdMapping(FInstanceUpdateChangeSet &ChangeSet, const IndexRemapType &IndexRemap, FInstanceIdIndexMap &OutInstanceIdIndexMap)
Definition InstanceDataUpdateUtils.h:272
void Scatter(const DeltaType &Delta, TArray< ValueType > &OutDest, int32 DestNumElements, TArray< ValueType > &&InSource, const IndexRemapType &IndexRemap, int32 ElementStride=1)
Definition InstanceDataUpdateUtils.h:23
void CondMove(bool bCondition, TArray< ValueType > &Data, int32 FromIndex, int32 ToIndex, int32 NumElements=1)
Definition InstanceDataUpdateUtils.h:120
void DispatchInstanceDataUpdateTask(bool bIsUnattached, const TSharedPtr< ProxyType, ESPMode::ThreadSafe > &InstanceDataProxy, const FInstanceDataBufferHeader &InstanceDataBufferHeader, TaskLambdaType &&TaskLambda)
Definition InstanceDataUpdateUtils.h:378
FORCEINLINE void ApplyTransformUpdates(const DeltaType &DeltaRange, const IndexRemapType &IndexRemap, const FRenderTransform &PrimitiveToRelativeWorld, const TArray< FRenderTransform > &InstanceTransforms, int32 PostUpdateNumTransforms, TArray< FRenderTransform > &OutInstanceToPrimitiveRelative)
Definition InstanceDataUpdateUtils.h:213
UE::Math::TVector< float > FVector3f
Definition MathFwd.h:73
#define ENQUEUE_RENDER_COMMAND(Type)
Definition RenderingThread.h:1167
FORCEINLINE VectorRegister4Double VectorLoadFloat3(const double *Ptr)
Definition UnrealMathFPU.h:427
FORCEINLINE VectorRegister4Float VectorMultiply(const VectorRegister4Float &Vec1, const VectorRegister4Float &Vec2)
Definition UnrealMathFPU.h:758
FORCEINLINE VectorRegister4Float VectorMultiplyAdd(const VectorRegister4Float &Vec1, const VectorRegister4Float &Vec2, const VectorRegister4Float &Vec3)
Definition UnrealMathFPU.h:786
FORCEINLINE void VectorStore(const VectorRegister4Float &Vec, float *Dst)
Definition UnrealMathFPU.h:566
FORCEINLINE VectorRegister4Float VectorLoad(const float *Ptr)
Definition UnrealMathFPU.h:394
FORCEINLINE void VectorStoreFloat3(const VectorRegister4Float &Vec, float *Dst)
Definition UnrealMathFPU.h:594
#define VectorReplicate(Vec, ElementIndex)
Definition UnrealMathFPU.h:627
#define UE_SMALL_NUMBER
Definition UnrealMathUtility.h:130
UE_INTRINSIC_CAST UE_REWRITE constexpr std::remove_reference_t< T > && MoveTemp(T &&Obj) noexcept
Definition UnrealTemplate.h:520
if(Failed) console_printf("Failed.\n")
Definition Archive.h:1208
Definition InstanceUpdateChangeSet.h:16
Definition InstanceDataSceneProxy.h:425
ENGINE_API void WaitForUpdateCompletion()
Definition InstanceDataSceneProxy.cpp:284
const FInstanceDataBufferHeader & GetHeader() const
Definition InstanceDataSceneProxy.h:431
Definition InstanceDataSceneProxy.h:15
Definition InstanceUpdateChangeSet.h:298
Definition RHICommandList.h:3819
Definition Array.h:670
void SetNumZeroed(SizeType NewNum, EAllowShrinking AllowShrinking=UE::Core::Private::AllowShrinkingByDefault< AllocatorType >())
Definition Array.h:2340
void Reset(SizeType NewSize=0)
Definition Array.h:2246
Definition BitArray.h:1944
Definition SharedPointer.h:692
Definition InstanceDataUpdateUtils.h:439
FArchive & operator<<(FArchive &Ar, TLocation< ScalarType > &Item)
Definition InstanceDataUpdateUtils.h:441
FLocation64 CalcLevelAndLocationClamped(const FVector3d &Center, double Radius, int32 FirstLevel)
Definition RenderingSpatialHash.h:131
Private::FTaskHandle FTask
Definition Task.h:333
TTask< TInvokeResult_T< TaskBodyType > > Launch(const TCHAR *DebugName, TaskBodyType &&TaskBody, ETaskPriority Priority=ETaskPriority::Normal, EExtendedTaskPriority ExtendedPriority=EExtendedTaskPriority::None, ETaskFlags Flags=ETaskFlags::None)
Definition Task.h:266
U16 Index
Definition radfft.cpp:71
Definition InstanceDataUpdateUtils.h:93
FORCEINLINE constexpr bool RemapDestIndex(int32 Index) const
Definition InstanceDataUpdateUtils.h:96
FORCEINLINE constexpr bool IsIdentity() const
Definition InstanceDataUpdateUtils.h:94
FORCEINLINE int32 operator[](int32 InIndex) const
Definition InstanceDataUpdateUtils.h:95
FORCEINLINE bool Remap(int32 &SrcIndex, int32 &DstIndex) const
Definition InstanceDataUpdateUtils.h:97
Definition InstanceDataTypes.h:65
uint32 PayloadDataStride
Definition InstanceDataTypes.h:67
FInstanceDataFlags Flags
Definition InstanceDataTypes.h:68
int32 NumInstances
Definition InstanceDataTypes.h:66
Definition InstanceDataSceneProxy.h:215
RenderingSpatialHash::FLocation64 Location
Definition InstanceDataSceneProxy.h:217
int32 NumInstances
Definition InstanceDataSceneProxy.h:218
Definition InstanceDataSceneProxy.h:222
TArray< float > & InstanceRandomIDs
Definition InstanceDataSceneProxy.h:228
FInstanceDataFlags & Flags
Definition InstanceDataSceneProxy.h:243
int32 & NumCustomDataFloats
Definition InstanceDataSceneProxy.h:242
TArray< FVector4f > & InstanceLightShadowUVBias
Definition InstanceDataSceneProxy.h:229
TArray< float > & InstanceCustomData
Definition InstanceDataSceneProxy.h:227
TArray< uint32 > & InstanceSkinningData
Definition InstanceDataSceneProxy.h:230
static UE_FORCEINLINE_HINT void * Memcpy(void *Dest, const void *Src, SIZE_T Count)
Definition UnrealMemory.h:160
Definition InstanceDataTypes.h:19
Definition InstanceDataUpdateUtils.h:132
FORCEINLINE FRenderTransformVectorRegister(const FRenderTransform &RenderTransform)
Definition InstanceDataUpdateUtils.h:138
VectorRegister4f Origin
Definition InstanceDataUpdateUtils.h:136
VectorRegister4f R2
Definition InstanceDataUpdateUtils.h:135
VectorRegister4f R1
Definition InstanceDataUpdateUtils.h:134
VectorRegister4f R0
Definition InstanceDataUpdateUtils.h:133
Definition RenderTransform.h:23
bool IsScaleNonUniform() const
Definition RenderTransform.h:212
FVector3f GetScale() const
Definition RenderTransform.h:202
FVector3f TransformRows[3]
Definition RenderTransform.h:24
FVector3f Origin
Definition RenderTransform.h:25
Definition InstanceDataUpdateUtils.h:104
FORCEINLINE constexpr bool IsIdentity() const
Definition InstanceDataUpdateUtils.h:105
FORCEINLINE bool RemapDestIndex(int32 &Index) const
Definition InstanceDataUpdateUtils.h:107
FORCEINLINE bool Remap(int32 &SrcIndex, int32 &DstIndex) const
Definition InstanceDataUpdateUtils.h:108
const TArray< int32 > & IndexRemap
Definition InstanceDataUpdateUtils.h:113
FORCEINLINE FSrcIndexRemap(const TArray< int32 > &InIndexRemap)
Definition InstanceDataUpdateUtils.h:106
Definition RenderingSpatialHash.h:17
FIntVector3 Coord
Definition RenderingSpatialHash.h:19
int32 Level
Definition RenderingSpatialHash.h:20
static CORE_API const TVector< float > ZeroVector
Definition Vector.h:79
T X
Definition Vector.h:62
Definition UnrealMathFPU.h:20
Definition InstanceDataTypes.h:36
uint16 bHasPerInstanceDynamicData
Definition InstanceDataTypes.h:42
uint16 bHasPerInstancePayloadExtension
Definition InstanceDataTypes.h:47
uint16 bHasPerInstanceLocalBounds
Definition InstanceDataTypes.h:45
uint16 bHasPerInstanceLMSMUVBias
Definition InstanceDataTypes.h:44
uint16 bHasPerInstanceCustomData
Definition InstanceDataTypes.h:41
uint16 bHasPerInstanceHierarchyOffset
Definition InstanceDataTypes.h:46
uint16 bHasPerInstanceEditorData
Definition InstanceDataTypes.h:49
uint16 bHasPerInstanceSkinningData
Definition InstanceDataTypes.h:43