221 lines
No EOL
5.3 KiB
C++
221 lines
No EOL
5.3 KiB
C++
// Copyright 2020 Phyronnaz
|
|
|
|
#pragma once
|
|
|
|
#include "CoreMinimal.h"
|
|
#include "VoxelNodeHelper.h"
|
|
#include "VoxelNodeHelperMacros.h"
|
|
#include "Curves/CurveFloat.h"
|
|
#include "VoxelOptimizationNodes.generated.h"
|
|
|
|
// Nodes before this won't be computed for range analysis
|
|
UCLASS(DisplayName = "Static Clamp", Category = "Optimization", meta = (Keywords = "range analysis"))
|
|
class VOXELGRAPH_API UVoxelNode_StaticClampFloat : public UVoxelNodeHelper
|
|
{
|
|
GENERATED_BODY()
|
|
GENERATED_VOXELNODE_BODY()
|
|
|
|
public:
|
|
UPROPERTY(EditAnywhere, Category = "Static Clamp")
|
|
float Min = 0;
|
|
|
|
UPROPERTY(EditAnywhere, Category = "Static Clamp")
|
|
float Max = 0;
|
|
|
|
UVoxelNode_StaticClampFloat();
|
|
|
|
//~ Begin UVoxelNode Interface
|
|
virtual FText GetTitle() const override;
|
|
//~ End UVoxelNode Interface
|
|
};
|
|
|
|
// Use this to debug the range of a value. Will plot the runtime values in a graph
|
|
UCLASS(DisplayName = "Range Analysis Debugger", Category = "Optimization")
|
|
class VOXELGRAPH_API UVoxelNode_RangeAnalysisDebuggerFloat : public UVoxelNodeHelper
|
|
{
|
|
GENERATED_BODY()
|
|
GENERATED_VOXELNODE_BODY()
|
|
|
|
public:
|
|
UPROPERTY(VisibleAnywhere, Category = "Bounds")
|
|
float Min = 0;
|
|
|
|
UPROPERTY(VisibleAnywhere, Category = "Bounds")
|
|
float Max = 0;
|
|
|
|
public:
|
|
UPROPERTY(EditAnywhere, Category = "Graph")
|
|
float GraphMin = -100;
|
|
|
|
UPROPERTY(EditAnywhere, Category = "Graph")
|
|
float GraphMax = 100;
|
|
|
|
UPROPERTY(EditAnywhere, Category = "Graph", meta = (ClampMin = 0.001))
|
|
float GraphStep = 1;
|
|
|
|
UPROPERTY(EditAnywhere, Category = "Graph")
|
|
FRuntimeFloatCurve Curve;
|
|
|
|
struct FVoxelBins
|
|
{
|
|
const float Min;
|
|
const float Max;
|
|
const float Step;
|
|
|
|
float MinValue = 0;
|
|
float MaxValue = 0;
|
|
bool bMinMaxInit = false;
|
|
TArray<uint64> Counts;
|
|
|
|
FVoxelBins(float Min, float Max, float Step)
|
|
: Min(Min)
|
|
, Max(Max)
|
|
, Step(Step)
|
|
{
|
|
const int32 Num = FMath::CeilToInt((Max - Min) / Step);
|
|
Counts.SetNum(Num);
|
|
}
|
|
FVoxelBins(const FVoxelBins& Other)
|
|
: FVoxelBins(Other.Min, Other.Max, Other.Step)
|
|
{
|
|
MinValue = Other.MinValue;
|
|
MaxValue = Other.MaxValue;
|
|
bMinMaxInit = Other.bMinMaxInit;
|
|
Counts = Other.Counts;
|
|
}
|
|
|
|
inline void AddStat(float Value)
|
|
{
|
|
FScopeLock Lock(&Section);
|
|
AddToMinMax(Value);
|
|
const int32 Bin = FMath::FloorToInt((Value - Min) / Step);
|
|
if (Counts.IsValidIndex(Bin))
|
|
{
|
|
Counts[Bin]++;
|
|
}
|
|
}
|
|
|
|
inline void AddOtherBins(const FVoxelBins& Other)
|
|
{
|
|
FScopeLock Lock(&Section);
|
|
if (!ensure(Min == Other.Min && Max == Other.Max && Step == Other.Step && Counts.Num() == Other.Counts.Num()))
|
|
{
|
|
return;
|
|
}
|
|
for (int32 Index = 0; Index < Counts.Num(); Index++)
|
|
{
|
|
Counts[Index] += Other.Counts[Index];
|
|
}
|
|
AddToMinMax(Other.MinValue);
|
|
AddToMinMax(Other.MaxValue);
|
|
}
|
|
|
|
inline void AddToCurve(FRichCurve& InCurve) const
|
|
{
|
|
for (int32 Index = 0; Index < Counts.Num(); Index++)
|
|
{
|
|
const float Value = Min + Index * Step;
|
|
InCurve.AddKey(Value, Counts[Index]);
|
|
}
|
|
}
|
|
|
|
public:
|
|
inline void AddToMinMax(float Value)
|
|
{
|
|
if (!bMinMaxInit)
|
|
{
|
|
bMinMaxInit = true;
|
|
MinValue = Value;
|
|
MaxValue = Value;
|
|
}
|
|
else
|
|
{
|
|
MinValue = FMath::Min(MinValue, Value);
|
|
MaxValue = FMath::Max(MaxValue, Value);
|
|
}
|
|
}
|
|
|
|
FCriticalSection Section;
|
|
};
|
|
|
|
TUniquePtr<FVoxelBins> Bins = MakeUnique<FVoxelBins>(GraphMin, GraphMax, GraphStep);
|
|
|
|
UVoxelNode_RangeAnalysisDebuggerFloat();
|
|
|
|
void UpdateFromBin();
|
|
void UpdateGraph();
|
|
void Reset();
|
|
|
|
#if WITH_EDITOR
|
|
virtual void PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent) override;
|
|
virtual void PostLoad() override;
|
|
#endif
|
|
};
|
|
|
|
// Runs a for loop
|
|
UCLASS(DisplayName = "Stress", Category = "Optimization")
|
|
class VOXELGRAPH_API UVoxelNode_Sleep : public UVoxelNodeHelper
|
|
{
|
|
GENERATED_BODY()
|
|
GENERATED_VOXELNODE_BODY()
|
|
|
|
UPROPERTY(EditAnywhere, Category = "Voxel")
|
|
int32 NumberOfLoops = 1000;
|
|
|
|
UVoxelNode_Sleep();
|
|
};
|
|
|
|
// In range analysis, does the union of the inputs ranges. In other modes, returns 0
|
|
UCLASS(DisplayName = "Range Union", Category = "Optimization")
|
|
class VOXELGRAPH_API UVoxelNode_RangeUnion : public UVoxelNodeHelper
|
|
{
|
|
GENERATED_BODY()
|
|
GENERATED_VOXELNODE_BODY()
|
|
|
|
UVoxelNode_RangeUnion();
|
|
};
|
|
|
|
// In range analysis, returns false if the condition can be true or false. In other modes, always returns true
|
|
UCLASS(DisplayName = "Is Single bool", Category = "Optimization")
|
|
class VOXELGRAPH_API UVoxelNode_IsSingleBool : public UVoxelNodeHelper
|
|
{
|
|
GENERATED_BODY()
|
|
GENERATED_VOXELNODE_BODY()
|
|
|
|
UVoxelNode_IsSingleBool();
|
|
};
|
|
|
|
// Get the range analysis value
|
|
UCLASS(DisplayName = "Get Range", Category = "Optimization", meta = (Keywords = "range analysis"))
|
|
class VOXELGRAPH_API UVoxelNode_GetRangeAnalysis : public UVoxelNodeHelper
|
|
{
|
|
GENERATED_BODY()
|
|
GENERATED_VOXELNODE_BODY()
|
|
|
|
UVoxelNode_GetRangeAnalysis();
|
|
|
|
//~ Begin UVoxelNode Interface
|
|
//~ End UVoxelNode Interface
|
|
};
|
|
|
|
UCLASS(DisplayName = "Smart Min", Category = "Optimization", meta = (Keywords = "smart range min fast"))
|
|
class VOXELGRAPH_API UVoxelNode_SmartMin : public UVoxelNodeHelper
|
|
{
|
|
GENERATED_BODY()
|
|
|
|
UVoxelNode_SmartMin();
|
|
|
|
//~ Begin UVoxelNode Interface
|
|
//~ End UVoxelNode Interface
|
|
};
|
|
|
|
UCLASS(DisplayName = "Smart Max", Category = "Optimization", meta = (Keywords = "smart range max fast"))
|
|
class VOXELGRAPH_API UVoxelNode_SmartMax : public UVoxelNodeHelper
|
|
{
|
|
GENERATED_BODY()
|
|
|
|
UVoxelNode_SmartMax();
|
|
|
|
//~ Begin UVoxelNode Interface
|
|
//~ End UVoxelNode Interface
|
|
}; |