UDocumentation UE5.7 10.02.2026 (Source)
API documentation for Unreal Engine 5.7
Distributions.h
Go to the documentation of this file.
1// Copyright Epic Games, Inc. All Rights Reserved.
2
3/*=============================================================================
4 Distributions.h: Declaration of distributions.
5=============================================================================*/
6
7#pragma once
8
9#include "CoreMinimal.h"
10#include "Math/RandomStream.h"
11
13#define checkDistribution check
14
25
30{
32 float TimeScale;
34 float TimeBias;
38 uint8 Op;
47
50 : TimeScale(0.0f)
51 , TimeBias(0.0f)
53 , EntryCount(0)
54 , EntryStride(0)
56 , LockFlag(0)
57 {}
58
62 void Empty()
63 {
65 EntryCount = 0;
66 EntryStride = 0;
68 TimeScale = 0.0f;
69 TimeBias = 0.0f;
70 LockFlag = 0;
71 }
72
76 inline bool IsEmpty() const
77 {
78 return Values.Num() == 0 || EntryCount == 0;
79 }
80
84 inline float GetValuesPerEntry() const
85 {
86 return (float)(EntryStride - SubEntryStride);
87 }
88
92 inline float GetValueCount() const
93 {
94 return (float)(Values.Num());
95 }
96
106 inline void GetEntry( float Time, const float*& Entry1, const float*& Entry2, float& LerpAlpha ) const
107 {
108 // make time relative to start time
109 Time -= TimeBias;
110 Time *= TimeScale;
111 Time = FMath::FloatSelect( Time, Time, 0.0f );
112
113 // calculate the alpha to lerp between entry1 and entry2
114 LerpAlpha = FMath::Fractional(Time);
115
116 // get the entries to lerp between
117 const uint32 Index = FMath::TruncToInt(Time);
118 const uint32 Index1 = FMath::Min<uint32>( Index + 0, EntryCount - 1 ) * EntryStride;
119 const uint32 Index2 = FMath::Min<uint32>( Index + 1, EntryCount - 1 ) * EntryStride;
120 Entry1 = &Values[Index1];
121 Entry2 = &Values[Index2];
122 }
123
130 void GetRange( float* OutMinValues, float* OutMaxValues )
131 {
132 if ( EntryCount > 0 )
133 {
135 const float* Entry = Values.GetData();
136
137 // Initialize to the first entry in the table.
138 for ( int32 ValueIndex = 0; ValueIndex < ValuesPerEntry; ++ValueIndex )
139 {
140 OutMinValues[ValueIndex] = Entry[ValueIndex];
141 OutMaxValues[ValueIndex] = Entry[ValueIndex + SubEntryStride];
142 }
143
144 // Iterate over each entry updating the minimum and maximum values.
145 for ( int32 EntryIndex = 1; EntryIndex < EntryCount; ++EntryIndex )
146 {
147 Entry += EntryStride;
148 for ( int32 ValueIndex = 0; ValueIndex < ValuesPerEntry; ++ValueIndex )
149 {
150 OutMinValues[ValueIndex] = FMath::Min( OutMinValues[ValueIndex], Entry[ValueIndex] );
151 OutMaxValues[ValueIndex] = FMath::Max( OutMaxValues[ValueIndex], Entry[ValueIndex + SubEntryStride] );
152 }
153 }
154 }
155 }
156};
157
158// Helper macro for retrieving random value
159#define DIST_GET_RANDOM_VALUE(RandStream) ((RandStream == NULL) ? FMath::SRand() : RandStream->GetFraction())
160
164struct FRawDistribution
165{
168 {
169 }
170
177
185 ENGINE_API void GetValue(float Time, float* Value, int32 NumCoords, int32 Extreme, struct FRandomStream* InRandomStream) const;
186
187 // prebaked versions of these
188 ENGINE_API void GetValue1(float Time, float* Value, int32 Extreme, struct FRandomStream* InRandomStream) const;
189 ENGINE_API void GetValue3(float Time, float* Value, int32 Extreme, struct FRandomStream* InRandomStream) const;
190 inline void GetValue1None(float Time, float* InValue) const
191 {
192 float* Value = InValue;
193 const float* Entry1;
194 const float* Entry2;
195 float LerpAlpha = 0.0f;
197 const float* NewEntry1 = Entry1;
198 const float* NewEntry2 = Entry2;
200 }
201 inline void GetValue3None(float Time, float* InValue) const
202 {
203 float* Value = InValue;
204 const float* Entry1;
205 const float* Entry2;
206 float LerpAlpha = 0.0f;
208 const float* NewEntry1 = Entry1;
209 const float* NewEntry2 = Entry2;
210 float T0 = FMath::Lerp(NewEntry1[0], NewEntry2[0], LerpAlpha);
211 float T1 = FMath::Lerp(NewEntry1[1], NewEntry2[1], LerpAlpha);
212 float T2 = FMath::Lerp(NewEntry1[2], NewEntry2[2], LerpAlpha);
213 Value[0] = T0;
214 Value[1] = T1;
215 Value[2] = T2;
216 }
217 ENGINE_API void GetValue1Extreme(float Time, float* Value, int32 Extreme, struct FRandomStream* InRandomStream) const;
218 ENGINE_API void GetValue3Extreme(float Time, float* Value, int32 Extreme, struct FRandomStream* InRandomStream) const;
219 ENGINE_API void GetValue1Random(float Time, float* Value, struct FRandomStream* InRandomStream) const;
220 ENGINE_API void GetValue3Random(float Time, float* Value, struct FRandomStream* InRandomStream) const;
221
222 inline bool IsSimple()
223 {
224 return LookupTable.Op == RDO_None;
225 }
226
236
237protected:
238
241};
242
243/*-----------------------------------------------------------------------------
244 Type safe distributions.
245
246 Like FRawDistribution but typesafe and not tied directly to UObjects.
247-----------------------------------------------------------------------------*/
248
253{
254public:
257
263 inline void GetValue( float Time, float* RESTRICT OutValue ) const
264 {
265 checkDistribution( LookupTable.GetValuesPerEntry() == 1 );
266
267 const float* Entry1;
268 const float* Entry2;
269 float Alpha;
270
271 LookupTable.GetEntry( Time, Entry1, Entry2, Alpha );
272 OutValue[0] = FMath::Lerp( Entry1[0], Entry2[0], Alpha );
273 }
274
281 inline void GetRandomValue( float Time, float* RESTRICT OutValue, FRandomStream& RandomStream ) const
282 {
283 checkDistribution( LookupTable.GetValuesPerEntry() == 1 );
284
285 const float* Entry1;
286 const float* Entry2;
287 float Alpha;
288 float RandomAlpha;
289 float MinValue, MaxValue;
290 const int32 SubEntryStride = LookupTable.SubEntryStride;
291
292 LookupTable.GetEntry( Time, Entry1, Entry2, Alpha );
293 MinValue = FMath::Lerp( Entry1[0], Entry2[0], Alpha );
294 MaxValue = FMath::Lerp( Entry1[SubEntryStride], Entry2[SubEntryStride], Alpha );
295 RandomAlpha = RandomStream.GetFraction();
296 OutValue[0] = FMath::Lerp( MinValue, MaxValue, RandomAlpha );
297 }
298
304 void GetRange( float* OutMin, float* OutMax )
305 {
306 LookupTable.GetRange( OutMin, OutMax );
307 }
308
309private:
311 FDistributionLookupTable LookupTable;
312
313 //@todo.CONSOLE: These are needed until we have a cooker/package in place!
316};
317
322{
323public:
326
332 inline void GetValue( float Time, float* RESTRICT OutValue ) const
333 {
334 checkDistribution( LookupTable.GetValuesPerEntry() == 3 );
335
336 const float* Entry1;
337 const float* Entry2;
338 float Alpha;
339
340 LookupTable.GetEntry( Time, Entry1, Entry2, Alpha );
341 OutValue[0] = FMath::Lerp( Entry1[0], Entry2[0], Alpha );
342 OutValue[1] = FMath::Lerp( Entry1[1], Entry2[1], Alpha );
343 OutValue[2] = FMath::Lerp( Entry1[2], Entry2[2], Alpha );
344 }
345
352 inline void GetRandomValue( float Time, float* RESTRICT OutValue, FRandomStream& RandomStream ) const
353 {
354 checkDistribution( LookupTable.GetValuesPerEntry() == 3 );
355
356 const float* Entry1;
357 const float* Entry2;
358 float Alpha;
359 float RandomAlpha[3];
360 float MinValue[3], MaxValue[3];
361 const int32 SubEntryStride = LookupTable.SubEntryStride;
362
363 LookupTable.GetEntry( Time, Entry1, Entry2, Alpha );
364
365 MinValue[0] = FMath::Lerp( Entry1[0], Entry2[0], Alpha );
366 MinValue[1] = FMath::Lerp( Entry1[1], Entry2[1], Alpha );
367 MinValue[2] = FMath::Lerp( Entry1[2], Entry2[2], Alpha );
368
369 MaxValue[0] = FMath::Lerp( Entry1[SubEntryStride + 0], Entry2[SubEntryStride + 0], Alpha );
370 MaxValue[1] = FMath::Lerp( Entry1[SubEntryStride + 1], Entry2[SubEntryStride + 1], Alpha );
371 MaxValue[2] = FMath::Lerp( Entry1[SubEntryStride + 2], Entry2[SubEntryStride + 2], Alpha );
372
373 RandomAlpha[0] = RandomStream.GetFraction();
374 RandomAlpha[1] = RandomStream.GetFraction();
375 RandomAlpha[2] = RandomStream.GetFraction();
376
377 OutValue[0] = FMath::Lerp( MinValue[0], MaxValue[0], RandomAlpha[0] );
378 OutValue[1] = FMath::Lerp( MinValue[1], MaxValue[1], RandomAlpha[1] );
379 OutValue[2] = FMath::Lerp( MinValue[2], MaxValue[2], RandomAlpha[2] );
380 }
381
388 {
389 LookupTable.GetRange((float*)OutMin, (float*)OutMax);
390 }
391
392 // LWC_TODO: Precision loss
400
401private:
403 FDistributionLookupTable LookupTable;
404
407};
408
413{
414public:
417
423 inline void GetValue( float Time, float* RESTRICT OutValue ) const
424 {
425 checkDistribution( LookupTable.GetValuesPerEntry() == 4 );
426
427 const float* Entry1;
428 const float* Entry2;
429 float Alpha;
430
431 LookupTable.GetEntry( Time, Entry1, Entry2, Alpha );
432 OutValue[0] = FMath::Lerp( Entry1[0], Entry2[0], Alpha );
433 OutValue[1] = FMath::Lerp( Entry1[1], Entry2[1], Alpha );
434 OutValue[2] = FMath::Lerp( Entry1[2], Entry2[2], Alpha );
435 OutValue[3] = FMath::Lerp( Entry1[3], Entry2[3], Alpha );
436 }
437
444 inline void GetRandomValue( float Time, float* RESTRICT OutValue, FRandomStream& RandomStream ) const
445 {
446 checkDistribution( LookupTable.GetValuesPerEntry() == 4 );
447
448 const float* Entry1;
449 const float* Entry2;
450 float Alpha;
451 float RandomAlpha[4];
452 float MinValue[4], MaxValue[4];
453 const int32 SubEntryStride = LookupTable.SubEntryStride;
454
455 LookupTable.GetEntry( Time, Entry1, Entry2, Alpha );
456
457 MinValue[0] = FMath::Lerp( Entry1[0], Entry2[0], Alpha );
458 MinValue[1] = FMath::Lerp( Entry1[1], Entry2[1], Alpha );
459 MinValue[2] = FMath::Lerp( Entry1[2], Entry2[2], Alpha );
460 MinValue[3] = FMath::Lerp( Entry1[3], Entry2[3], Alpha );
461
462 MaxValue[0] = FMath::Lerp( Entry1[SubEntryStride + 0], Entry2[SubEntryStride + 0], Alpha );
463 MaxValue[1] = FMath::Lerp( Entry1[SubEntryStride + 1], Entry2[SubEntryStride + 1], Alpha );
464 MaxValue[2] = FMath::Lerp( Entry1[SubEntryStride + 2], Entry2[SubEntryStride + 2], Alpha );
465 MaxValue[3] = FMath::Lerp( Entry1[SubEntryStride + 3], Entry2[SubEntryStride + 3], Alpha );
466
467 RandomAlpha[0] = RandomStream.GetFraction();
468 RandomAlpha[1] = RandomStream.GetFraction();
469 RandomAlpha[2] = RandomStream.GetFraction();
470 RandomAlpha[3] = RandomStream.GetFraction();
471
472 OutValue[0] = FMath::Lerp( MinValue[0], MaxValue[0], RandomAlpha[0] );
473 OutValue[1] = FMath::Lerp( MinValue[1], MaxValue[1], RandomAlpha[1] );
474 OutValue[2] = FMath::Lerp( MinValue[2], MaxValue[2], RandomAlpha[2] );
475 OutValue[3] = FMath::Lerp( MinValue[3], MaxValue[3], RandomAlpha[3] );
476 }
477
484 {
485 LookupTable.GetRange( (float*)OutMin, (float*)OutMax );
486 }
487
488 // LWC_TODO: Precision loss
496
497private:
499 FDistributionLookupTable LookupTable;
500
503};
504
505/*-----------------------------------------------------------------------------
506 Composable distributions.
507
508 These classes allow code to compose multiple distributions and produce a
509 final, optimized raw distribution.
510-----------------------------------------------------------------------------*/
511
512//#if WITH_EDITORONLY_DATA
513
519{
520public:
527
534
542
550 static void BuildVector4(
552 const class FComposableVectorDistribution& XY,
553 const class FComposableFloatDistribution& Z,
554 const class FComposableFloatDistribution& W );
555
564 static void BuildVector4(
566 const class FComposableFloatDistribution& X,
567 const class FComposableFloatDistribution& Y,
568 const class FComposableFloatDistribution& Z,
569 const class FComposableFloatDistribution& W );
570
577 static void QuantizeVector4(
581 const class FVector4Distribution& Distribution );
582
583protected:
586
589
592
598
601 {
602 LookupTable = Other.LookupTable;
603 return *this;
604 }
605};
606
611{
612public:
615
621
628
633
637 void InitializeWithConstant( float Value );
638
642 void ScaleByConstant( float Scale );
643
648
653
657 void Normalize( float* OutScale, float* OutBias );
658
662 void Resample( float MinIn, float MaxIn );
663};
664
666{
667public:
670
676
683
688
692 void InitializeWithConstant( const FVector& Value );
693
697 void ScaleByConstant( float Scale );
698
702 void ScaleByConstantVector( const FVector& Scale );
703
707 void AddConstantVector( const FVector& Value );
708
713
718
723
727 void Splat( int32 ChannelIndex );
728
732 void Resample( float MinIn, float MaxIn );
733};
734//#endif // #if WITH_EDITORONLY_DATA
FPlatformTypes::int32 int32
A 32-bit signed integer.
Definition Platform.h:1125
#define RESTRICT
Definition Platform.h:706
UE_FORCEINLINE_HINT TSharedRef< CastToType, Mode > StaticCastSharedRef(TSharedRef< CastFromType, Mode > const &InSharedRef)
Definition SharedPointer.h:127
ERawDistributionOperation
Definition Distributions.h:19
@ RDO_None
Definition Distributions.h:21
@ RDO_Uninitialized
Definition Distributions.h:20
@ RDO_Random
Definition Distributions.h:22
@ RDO_Extreme
Definition Distributions.h:23
#define checkDistribution
Definition Distributions.h:13
#define X(Name, Desc)
Definition FormatStringSan.h:47
UE::Math::TVector4< double > FVector4d
Definition MathFwd.h:62
UE::Math::TVector< double > FVector3d
Definition MathFwd.h:60
uint8_t uint8
Definition binka_ue_file_header.h:8
uint32_t uint32
Definition binka_ue_file_header.h:6
Definition Archive.h:1208
Definition Distributions.h:519
static void BuildVector(class FVectorDistribution &OutDistribution, const class FComposableVectorDistribution &XYZ)
Definition Distributions.cpp:1386
static void QuantizeVector4(TArray< FColor > &OutQuantizedSamples, FVector4 &OutScale, FVector4 &OutBias, const class FVector4Distribution &Distribution)
Definition Distributions.cpp:1442
FComposableDistribution(const FComposableDistribution &Other)
Definition Distributions.h:594
static void BuildFloat(class FFloatDistribution &OutDistribution, const class FComposableFloatDistribution &X)
Definition Distributions.cpp:1378
~FComposableDistribution()
Definition Distributions.h:591
FDistributionLookupTable LookupTable
Definition Distributions.h:585
static void BuildVector4(class FVector4Distribution &OutDistribution, const class FComposableVectorDistribution &XYZ, const class FComposableFloatDistribution &W)
Definition Distributions.cpp:1394
const FComposableDistribution & operator=(const FComposableDistribution &Other)
Definition Distributions.h:600
FComposableDistribution()
Definition Distributions.h:588
Definition Distributions.h:611
void Normalize(float *OutScale, float *OutBias)
Definition Distributions.cpp:1568
void ScaleByConstant(float Scale)
Definition Distributions.cpp:1533
FComposableFloatDistribution(const FComposableFloatDistribution &Other)
Definition Distributions.h:617
void ScaleByDistribution(const class UDistributionFloat *FloatDistribution)
Definition Distributions.cpp:1540
const FComposableFloatDistribution & operator=(const FComposableFloatDistribution &Other)
Definition Distributions.h:623
FComposableFloatDistribution()
Definition Distributions.cpp:1507
void AddDistribution(const class UDistributionFloat *FloatDistribution)
Definition Distributions.cpp:1556
void InitializeWithConstant(float Value)
Definition Distributions.cpp:1526
Definition Distributions.h:666
void ScaleByVectorDistribution(const class UDistributionVector *VectorDistribution)
Definition Distributions.cpp:1657
void ScaleByConstant(float Scale)
Definition Distributions.cpp:1618
void Splat(int32 ChannelIndex)
Definition Distributions.cpp:1685
void AddDistribution(const class UDistributionVector *VectorDistribution)
Definition Distributions.cpp:1673
FComposableVectorDistribution(const FComposableVectorDistribution &Other)
Definition Distributions.h:672
void InitializeWithConstant(const FVector &Value)
Definition Distributions.cpp:1610
void ScaleByConstantVector(const FVector &Scale)
Definition Distributions.cpp:1625
void ScaleByDistribution(const class UDistributionFloat *FloatDistribution)
Definition Distributions.cpp:1641
FComposableVectorDistribution()
Definition Distributions.cpp:1590
const FComposableVectorDistribution & operator=(const FComposableVectorDistribution &Other)
Definition Distributions.h:678
void AddConstantVector(const FVector &Value)
Definition Distributions.cpp:1633
Definition UnrealType.h:6306
Definition Array.h:670
UE_REWRITE SizeType Num() const
Definition Array.h:1144
UE_NODEBUG UE_FORCEINLINE_HINT ElementType * GetData() UE_LIFETIMEBOUND
Definition Array.h:1027
Definition DistributionFloat.h:103
Definition DistributionVector.h:148
Definition Object.h:95
U16 Index
Definition radfft.cpp:71
Definition Distribution.h:27
void Empty()
Definition Distributions.h:62
uint8 Op
Definition Distribution.h:38
float TimeScale
Definition Distribution.h:29
uint8 EntryCount
Definition Distribution.h:41
uint8 SubEntryStride
Definition Distribution.h:47
uint8 EntryStride
Definition Distribution.h:44
float GetValuesPerEntry() const
Definition Distributions.h:84
void GetEntry(float Time, const float *&Entry1, const float *&Entry2, float &LerpAlpha) const
Definition Distributions.h:106
float GetValueCount() const
Definition Distributions.h:92
float TimeBias
Definition Distribution.h:32
bool IsEmpty() const
Definition Distributions.h:76
FDistributionLookupTable()
Definition Distributions.h:49
void GetRange(float *OutMinValues, float *OutMaxValues)
Definition Distributions.h:130
TArray< float > Values
Definition Distribution.h:35
uint8 LockFlag
Definition Distribution.h:50
Definition DistributionFloat.h:19
void GetRange(float *OutMin, float *OutMax)
Definition Distributions.h:304
FFloatDistribution()
Definition Distributions.cpp:1360
void GetRandomValue(float Time, float *RESTRICT OutValue, FRandomStream &RandomStream) const
Definition Distributions.h:281
void GetValue(float Time, float *RESTRICT OutValue) const
Definition Distributions.h:263
static constexpr UE_FORCEINLINE_HINT T Lerp(const T &A, const T &B, const U &Alpha)
Definition UnrealMathUtility.h:1116
Definition RandomStream.h:20
Definition Distribution.h:58
FRawDistribution()
Definition Distributions.h:167
ENGINE_API void GetValue3(float Time, float *Value, int32 Extreme, struct FRandomStream *InRandomStream) const
Definition Distributions.cpp:702
static ENGINE_API UObject * TryGetDistributionObjectFromRawDistributionProperty(FStructProperty *Property, uint8 *Data)
Definition Distributions.cpp:851
ENGINE_API void GetValue1Extreme(float Time, float *Value, int32 Extreme, struct FRandomStream *InRandomStream) const
Definition Distributions.cpp:718
ENGINE_API void GetValue3Random(float Time, float *Value, struct FRandomStream *InRandomStream) const
Definition Distributions.cpp:768
ENGINE_API void GetValue1(float Time, float *Value, int32 Extreme, struct FRandomStream *InRandomStream) const
Definition Distributions.cpp:682
ENGINE_API bool Serialize(FArchive &Ar)
ENGINE_API void GetValue1Random(float Time, float *Value, struct FRandomStream *InRandomStream) const
Definition Distributions.cpp:752
FDistributionLookupTable LookupTable
Definition Distributions.h:240
ENGINE_API void GetValue(float Time, float *Value, int32 NumCoords, int32 Extreme, struct FRandomStream *InRandomStream) const
Definition Distributions.cpp:813
void GetValue3None(float Time, float *InValue) const
Definition Distributions.h:201
bool IsSimple()
Definition Distributions.h:222
void GetValue1None(float Time, float *InValue) const
Definition Distributions.h:190
ENGINE_API void GetValue3Extreme(float Time, float *Value, int32 Extreme, struct FRandomStream *InRandomStream) const
Definition Distributions.cpp:732
Definition DistributionVector.h:50
void GetValue(float Time, float *RESTRICT OutValue) const
Definition Distributions.h:423
void GetRange(FVector4d *OutMin, FVector4d *OutMax)
Definition Distributions.h:489
FVector4Distribution()
Definition Distributions.cpp:1372
void GetRange(FVector4f *OutMin, FVector4f *OutMax)
Definition Distributions.h:483
void GetRandomValue(float Time, float *RESTRICT OutValue, FRandomStream &RandomStream) const
Definition Distributions.h:444
Definition DistributionVector.h:39
void GetRange(FVector3f *OutMin, FVector3f *OutMax)
Definition Distributions.h:387
void GetRange(FVector3d *OutMin, FVector3d *OutMax)
Definition Distributions.h:393
void GetValue(float Time, float *RESTRICT OutValue) const
Definition Distributions.h:332
void GetRandomValue(float Time, float *RESTRICT OutValue, FRandomStream &RandomStream) const
Definition Distributions.h:352
FVectorDistribution()
Definition Distributions.cpp:1366