706 lines
19 KiB
C++
706 lines
19 KiB
C++
// Copyright Epic Games, Inc. All Rights Reserved.
|
|
|
|
#include "Dataflow/GeometryCollectionArrayNodes.h"
|
|
#include "Dataflow/DataflowCore.h"
|
|
|
|
|
|
//#include UE_INLINE_GENERATED_CPP_BY_NAME(GeometryCollectionArrayNodes)
|
|
|
|
namespace UE::Dataflow
|
|
{
|
|
|
|
void GeometryCollectionArrayNodes()
|
|
{
|
|
DATAFLOW_NODE_REGISTER_CREATION_FACTORY(FFloatArrayToIntArrayDataflowNode);
|
|
DATAFLOW_NODE_REGISTER_CREATION_FACTORY(FBoolArrayToFaceSelectionDataflowNode);
|
|
DATAFLOW_NODE_REGISTER_CREATION_FACTORY(FFloatArrayToVertexSelectionDataflowNode);
|
|
DATAFLOW_NODE_REGISTER_CREATION_FACTORY(FFloatArrayNormalizeDataflowNode);
|
|
DATAFLOW_NODE_REGISTER_CREATION_FACTORY(FVectorArrayNormalizeDataflowNode);
|
|
DATAFLOW_NODE_REGISTER_CREATION_FACTORY(FUnionIntArraysDataflowNode);
|
|
DATAFLOW_NODE_REGISTER_CREATION_FACTORY(FRemoveFloatArrayElementDataflowNode);
|
|
DATAFLOW_NODE_REGISTER_CREATION_FACTORY(FFloatArrayComputeStatisticsDataflowNode);
|
|
DATAFLOW_NODE_REGISTER_CREATION_FACTORY(FRandomizeFloatArrayDataflowNode);
|
|
DATAFLOW_NODE_REGISTER_CREATION_FACTORY(FDataflowGetArraySizeNode);
|
|
DATAFLOW_NODE_REGISTER_CREATION_FACTORY(FDataflowGetArrayElementNode);
|
|
DATAFLOW_NODE_REGISTER_CREATION_FACTORY(FDataflowMakeManagedArrayCollectionArrayNode);
|
|
|
|
|
|
// Deprecated nodes
|
|
DATAFLOW_NODE_REGISTER_CREATION_FACTORY(FGetFloatArrayElementDataflowNode);
|
|
DATAFLOW_NODE_REGISTER_CREATION_FACTORY(FGetArrayElementDataflowNode);
|
|
DATAFLOW_NODE_REGISTER_CREATION_FACTORY(FGetNumArrayElementsDataflowNode);
|
|
}
|
|
}
|
|
|
|
void FGetFloatArrayElementDataflowNode::Evaluate(UE::Dataflow::FContext& Context, const FDataflowOutput* Out) const
|
|
{
|
|
if (Out->IsA(&FloatValue))
|
|
{
|
|
const TArray<float>& InArray = GetValue(Context, &FloatArray);
|
|
const int32& InIndex = GetValue(Context, &Index);
|
|
const float OutputValue = InArray.IsValidIndex(InIndex) ? InArray[InIndex] : 0.0f;
|
|
|
|
SetValue(Context, OutputValue, &FloatValue);
|
|
}
|
|
}
|
|
|
|
void FFloatArrayToIntArrayDataflowNode::Evaluate(UE::Dataflow::FContext& Context, const FDataflowOutput* Out) const
|
|
{
|
|
if (Out->IsA<TArray<int32>>(&IntArray))
|
|
{
|
|
TArray<float> FloatVal = GetValue<TArray<float>>(Context, &FloatArray);
|
|
TArray<int32> RetVal; RetVal.SetNumUninitialized(FloatVal.Num());
|
|
if (Function == EFloatArrayToIntArrayFunctionEnum::Dataflow_FloatToInt_Function_Floor)
|
|
{
|
|
for (int32 i = 0; i < FloatVal.Num(); i++)
|
|
{
|
|
RetVal[i] = FMath::FloorToInt32(FloatVal[i]);
|
|
}
|
|
}
|
|
else if (Function == EFloatArrayToIntArrayFunctionEnum::Dataflow_FloatToInt_Function_Ceil)
|
|
{
|
|
for (int32 i = 0; i < FloatVal.Num(); i++)
|
|
{
|
|
RetVal[i] = FMath::CeilToInt32(FloatVal[i]);
|
|
}
|
|
}
|
|
else if (Function == EFloatArrayToIntArrayFunctionEnum::Dataflow_FloatToInt_Function_Round)
|
|
{
|
|
for (int32 i = 0; i < FloatVal.Num(); i++)
|
|
{
|
|
RetVal[i] = FMath::RoundToInt32(FloatVal[i]);
|
|
}
|
|
}
|
|
else if (Function == EFloatArrayToIntArrayFunctionEnum::Dataflow_FloatToInt_Function_Truncate)
|
|
{
|
|
for (int32 i = 0; i < FloatVal.Num(); i++)
|
|
{
|
|
RetVal[i] = int32(FMath::TruncToFloat(FloatVal[i]));
|
|
}
|
|
}
|
|
|
|
else if (Function == EFloatArrayToIntArrayFunctionEnum::Dataflow_FloatToInt_NonZeroToIndex)
|
|
{
|
|
int32 RetValIndex = 0;
|
|
for (int32 i = 0; i < FloatVal.Num(); i++)
|
|
{
|
|
if (FloatVal[i] != 0.0)
|
|
{
|
|
RetVal[RetValIndex] = i;
|
|
RetValIndex++;
|
|
}
|
|
}
|
|
RetVal.SetNum(RetValIndex);
|
|
}
|
|
else if (Function == EFloatArrayToIntArrayFunctionEnum::Dataflow_FloatToInt_ZeroToIndex)
|
|
{
|
|
int32 RetValIndex = 0;
|
|
for (int32 i = 0; i < FloatVal.Num(); i++)
|
|
{
|
|
if (FloatVal[i] == 0.0)
|
|
{
|
|
RetVal[RetValIndex] = i;
|
|
RetValIndex++;
|
|
}
|
|
}
|
|
RetVal.SetNum(RetValIndex);
|
|
}
|
|
|
|
SetValue(Context, MoveTemp(RetVal), &IntArray);
|
|
}
|
|
}
|
|
|
|
void FGetArrayElementDataflowNode::Evaluate(UE::Dataflow::FContext& Context, const FDataflowOutput* Out) const
|
|
{
|
|
if (Out->IsA<FVector>(&Point))
|
|
{
|
|
const TArray<FVector>& Array = GetValue<TArray<FVector>>(Context, &Points);
|
|
if (Array.Num() > 0 && Index >= 0 && Index < Array.Num())
|
|
{
|
|
SetValue(Context, Array[Index], &Point);
|
|
return;
|
|
}
|
|
|
|
SetValue(Context, FVector(0.f), &Point);
|
|
}
|
|
}
|
|
|
|
void FGetNumArrayElementsDataflowNode::Evaluate(UE::Dataflow::FContext& Context, const FDataflowOutput* Out) const
|
|
{
|
|
if (Out->IsA<int32>(&NumElements))
|
|
{
|
|
if (IsConnected<TArray<float>>(&FloatArray))
|
|
{
|
|
SetValue(Context, GetValue<TArray<float>>(Context, &FloatArray).Num(), &NumElements);
|
|
return;
|
|
}
|
|
else if (IsConnected<TArray<int32>>(&IntArray))
|
|
{
|
|
SetValue(Context, GetValue<TArray<int32>>(Context, &IntArray).Num(), &NumElements);
|
|
return;
|
|
}
|
|
else if (IsConnected<TArray<FVector>>(&Points))
|
|
{
|
|
SetValue(Context, GetValue<TArray<FVector>>(Context, &Points).Num(), &NumElements);
|
|
return;
|
|
}
|
|
else if (IsConnected<TArray<FVector3f>>(&Vector3fArray))
|
|
{
|
|
SetValue(Context, GetValue<TArray<FVector3f>>(Context, &Vector3fArray).Num(), &NumElements);
|
|
return;
|
|
}
|
|
|
|
SetValue(Context, 0, &NumElements);
|
|
}
|
|
}
|
|
|
|
void FBoolArrayToFaceSelectionDataflowNode::Evaluate(UE::Dataflow::FContext& Context, const FDataflowOutput* Out) const
|
|
{
|
|
if (Out->IsA<FDataflowFaceSelection>(&FaceSelection))
|
|
{
|
|
const TArray<bool>& InBoolAttributeData = GetValue<TArray<bool>>(Context, &BoolAttributeData);
|
|
|
|
FDataflowFaceSelection NewFaceSelection;
|
|
NewFaceSelection.Initialize(InBoolAttributeData.Num(), false);
|
|
NewFaceSelection.SetFromArray(InBoolAttributeData);
|
|
|
|
SetValue(Context, MoveTemp(NewFaceSelection), &FaceSelection);
|
|
}
|
|
}
|
|
|
|
|
|
void FFloatArrayToVertexSelectionDataflowNode::Evaluate(UE::Dataflow::FContext& Context, const FDataflowOutput* Out) const
|
|
{
|
|
if (Out->IsA<FDataflowVertexSelection>(&VertexSelection))
|
|
{
|
|
const TArray<float>& InFloatArray = GetValue<TArray<float>>(Context, &FloatArray);
|
|
|
|
FDataflowVertexSelection NewVertexSelection;
|
|
NewVertexSelection.Initialize(InFloatArray.Num(), false);
|
|
|
|
for (int32 Idx = 0; Idx < InFloatArray.Num(); ++Idx)
|
|
{
|
|
if (Operation == ECompareOperation1Enum::Dataflow_Compare_Equal)
|
|
{
|
|
if (InFloatArray[Idx] == Threshold)
|
|
{
|
|
NewVertexSelection.SetSelected(Idx);
|
|
}
|
|
}
|
|
else if (Operation == ECompareOperation1Enum::Dataflow_Compare_Smaller)
|
|
{
|
|
if (InFloatArray[Idx] < Threshold)
|
|
{
|
|
NewVertexSelection.SetSelected(Idx);
|
|
}
|
|
}
|
|
else if (Operation == ECompareOperation1Enum::Dataflow_Compare_SmallerOrEqual)
|
|
{
|
|
if (InFloatArray[Idx] <= Threshold)
|
|
{
|
|
NewVertexSelection.SetSelected(Idx);
|
|
}
|
|
}
|
|
else if (Operation == ECompareOperation1Enum::Dataflow_Compare_Greater)
|
|
{
|
|
if (InFloatArray[Idx] > Threshold)
|
|
{
|
|
NewVertexSelection.SetSelected(Idx);
|
|
}
|
|
}
|
|
else if (Operation == ECompareOperation1Enum::Dataflow_Compare_GreaterOrEqual)
|
|
{
|
|
if (InFloatArray[Idx] >= Threshold)
|
|
{
|
|
NewVertexSelection.SetSelected(Idx);
|
|
}
|
|
}
|
|
}
|
|
|
|
SetValue(Context, MoveTemp(NewVertexSelection), &VertexSelection);
|
|
}
|
|
}
|
|
|
|
void FFloatArrayNormalizeDataflowNode::Evaluate(UE::Dataflow::FContext& Context, const FDataflowOutput* Out) const
|
|
{
|
|
if (Out->IsA<TArray<float>>(&OutFloatArray))
|
|
{
|
|
const TArray<float>& InInFloatArray = GetValue<TArray<float>>(Context, &InFloatArray);
|
|
const FDataflowVertexSelection& InSelection = GetValue<FDataflowVertexSelection>(Context, &Selection);
|
|
const float InMinRange = GetValue<float>(Context, &MinRange);
|
|
const float InMaxRange = GetValue<float>(Context, &MaxRange);
|
|
|
|
const int32 NumElems = InFloatArray.Num();
|
|
|
|
TArray<float> NewFloatArray;
|
|
NewFloatArray.Init(false, NumElems);
|
|
|
|
if (IsConnected<FDataflowVertexSelection>(&Selection))
|
|
{
|
|
if (InInFloatArray.Num() == InSelection.Num())
|
|
{
|
|
// Compute Min/Max
|
|
float MinValue = 1e9, MaxValue = 1e-9;
|
|
|
|
for (int32 Idx = 0; Idx < NumElems; ++Idx)
|
|
{
|
|
if (InSelection.IsSelected(Idx))
|
|
{
|
|
if (InInFloatArray[Idx] < MinValue)
|
|
{
|
|
MinValue = InInFloatArray[Idx];
|
|
}
|
|
|
|
if (InInFloatArray[Idx] > MaxValue)
|
|
{
|
|
MaxValue = InInFloatArray[Idx];
|
|
}
|
|
}
|
|
}
|
|
|
|
for (int32 Idx = 0; Idx < NumElems; ++Idx)
|
|
{
|
|
if (InSelection.IsSelected(Idx))
|
|
{
|
|
// Normalize it
|
|
NewFloatArray[Idx] = (NewFloatArray[Idx] - MinValue) / (MaxValue - MinValue);
|
|
|
|
// Transform it into (MinRange, MaxRange)
|
|
NewFloatArray[Idx] = InMinRange + NewFloatArray[Idx] * (InMaxRange - InMinRange);
|
|
}
|
|
}
|
|
|
|
SetValue(Context, MoveTemp(NewFloatArray), &OutFloatArray);
|
|
return;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// Compute Min/Max
|
|
float MinValue = 1e9, MaxValue = 1e-9;
|
|
|
|
for (int32 Idx = 0; Idx < NumElems; ++Idx)
|
|
{
|
|
if (InInFloatArray[Idx] < MinValue)
|
|
{
|
|
MinValue = InInFloatArray[Idx];
|
|
}
|
|
|
|
if (InInFloatArray[Idx] > MaxValue)
|
|
{
|
|
MaxValue = InInFloatArray[Idx];
|
|
}
|
|
}
|
|
|
|
for (int32 Idx = 0; Idx < NumElems; ++Idx)
|
|
{
|
|
// Normalize it
|
|
NewFloatArray[Idx] = (NewFloatArray[Idx] - MinValue) / (MaxValue - MinValue);
|
|
|
|
// Transform it into (MinRange, MaxRange)
|
|
NewFloatArray[Idx] = InMinRange + NewFloatArray[Idx] * (InMaxRange - InMinRange);
|
|
}
|
|
|
|
SetValue(Context, MoveTemp(NewFloatArray), &OutFloatArray);
|
|
return;
|
|
}
|
|
|
|
SetValue(Context, TArray<float>(), &OutFloatArray);
|
|
}
|
|
}
|
|
|
|
|
|
void FVectorArrayNormalizeDataflowNode::Evaluate(UE::Dataflow::FContext& Context, const FDataflowOutput* Out) const
|
|
{
|
|
if (Out->IsA<TArray<FVector>>(&OutVectorArray))
|
|
{
|
|
const TArray<FVector>& InInVectorArray = GetValue<TArray<FVector>>(Context, &InVectorArray);
|
|
const FDataflowVertexSelection& InSelection = GetValue<FDataflowVertexSelection>(Context, &Selection);
|
|
const float InMagnitude = GetValue<float>(Context, &Magnitude);
|
|
|
|
const int32 NumElems = InInVectorArray.Num();
|
|
|
|
TArray<FVector> NewVectorArray;
|
|
NewVectorArray.Init(FVector(0.f), NumElems);
|
|
|
|
if (IsConnected<FDataflowVertexSelection>(&Selection))
|
|
{
|
|
if (InInVectorArray.Num() == InSelection.Num())
|
|
{
|
|
for (int32 Idx = 0; Idx < NumElems; ++Idx)
|
|
{
|
|
FVector Vector = InInVectorArray[Idx];
|
|
|
|
if (InSelection.IsSelected(Idx))
|
|
{
|
|
Vector.Normalize();
|
|
Vector *= InMagnitude;
|
|
NewVectorArray[Idx] = Vector;
|
|
}
|
|
}
|
|
|
|
SetValue(Context, MoveTemp(NewVectorArray), &OutVectorArray);
|
|
return;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
for (int32 Idx = 0; Idx < NumElems; ++Idx)
|
|
{
|
|
FVector Vector = InInVectorArray[Idx];
|
|
|
|
Vector.Normalize();
|
|
Vector *= InMagnitude;
|
|
NewVectorArray[Idx] = Vector;
|
|
}
|
|
|
|
SetValue(Context, MoveTemp(NewVectorArray), &OutVectorArray);
|
|
return;
|
|
}
|
|
|
|
SetValue<TArray<FVector>>(Context, TArray<FVector>(), &OutVectorArray);
|
|
}
|
|
}
|
|
|
|
void FUnionIntArraysDataflowNode::Evaluate(UE::Dataflow::FContext& Context, const FDataflowOutput* Out) const
|
|
{
|
|
if (Out->IsA<TArray<int32>>(&OutArray))
|
|
{
|
|
TArray<int32> Array1 = GetValue<TArray<int32>>(Context, &InArray1);
|
|
TArray<int32> Array2 = GetValue<TArray<int32>>(Context, &InArray2);
|
|
TArray<int32> OutputArray;
|
|
for (int32 i = 0; i < Array1.Num(); i++)
|
|
{
|
|
OutputArray.AddUnique(Array1[i]);
|
|
}
|
|
for (int32 i = 0; i < Array2.Num(); i++)
|
|
{
|
|
OutputArray.AddUnique(Array2[i]);
|
|
}
|
|
SetValue(Context, MoveTemp(OutputArray), &OutArray);
|
|
}
|
|
}
|
|
|
|
void FRemoveFloatArrayElementDataflowNode::Evaluate(UE::Dataflow::FContext& Context, const FDataflowOutput* Out) const
|
|
{
|
|
if (Out->IsA(&FloatArray))
|
|
{
|
|
TArray<float> Array = GetValue<TArray<float>>(Context, &FloatArray);
|
|
if (Array.Num() > 0 && Array.IsValidIndex(Index))
|
|
{
|
|
if (bPreserveOrder)
|
|
{
|
|
Array.RemoveAt(Index);
|
|
}
|
|
else
|
|
{
|
|
Array.RemoveAtSwap(Index, EAllowShrinking::No);
|
|
}
|
|
|
|
SetValue(Context, Array, &FloatArray);
|
|
return;
|
|
}
|
|
|
|
SetValue(Context, Array, &FloatArray);
|
|
}
|
|
}
|
|
|
|
// -----------------------------------------------------------------------------------------------
|
|
|
|
static float ComputeMin(const TArray<float>& FloatArray, TArray<int32>& IndexArr)
|
|
{
|
|
float MinVal = TNumericLimits<float>::Max();
|
|
for (int32 Idx = 0; Idx < FloatArray.Num(); ++Idx)
|
|
{
|
|
if (FloatArray[Idx] < MinVal)
|
|
{
|
|
MinVal = FloatArray[Idx];
|
|
}
|
|
}
|
|
|
|
for (int32 Idx = 0; Idx < FloatArray.Num(); ++Idx)
|
|
{
|
|
if (FloatArray[Idx] == MinVal)
|
|
{
|
|
IndexArr.Add(Idx);
|
|
}
|
|
}
|
|
|
|
return MinVal;
|
|
}
|
|
|
|
static float ComputeMax(const TArray<float>& FloatArray, TArray<int32>& IndexArr)
|
|
{
|
|
float MaxVal = TNumericLimits<float>::Min();
|
|
for (int32 Idx = 0; Idx < FloatArray.Num(); ++Idx)
|
|
{
|
|
if (FloatArray[Idx] > MaxVal)
|
|
{
|
|
MaxVal = FloatArray[Idx];
|
|
}
|
|
}
|
|
|
|
for (int32 Idx = 0; Idx < FloatArray.Num(); ++Idx)
|
|
{
|
|
if (FloatArray[Idx] == MaxVal)
|
|
{
|
|
IndexArr.Add(Idx);
|
|
}
|
|
}
|
|
|
|
return MaxVal;
|
|
}
|
|
|
|
static float ComputeMean(const TArray<float>& FloatArray, TArray<int32>& IndexArr)
|
|
{
|
|
double SumVal = 0.f;
|
|
|
|
for (int32 Idx = 0; Idx < FloatArray.Num(); ++Idx)
|
|
{
|
|
SumVal += FloatArray[Idx];
|
|
}
|
|
|
|
return (float)(SumVal / (double)FloatArray.Num());
|
|
}
|
|
|
|
static float ComputeMedian(TArray<float> FloatArray, TArray<int32>& IndexArr)
|
|
{
|
|
FloatArray.Sort();
|
|
float MedianVal;
|
|
int32 NumElems = FloatArray.Num();
|
|
|
|
if (NumElems % 2 == 0)
|
|
{
|
|
MedianVal = (FloatArray[NumElems / 2 - 1] + FloatArray[NumElems / 2]) / 2.f;
|
|
|
|
IndexArr.Add(NumElems / 2 - 1);
|
|
IndexArr.Add(NumElems / 2);
|
|
}
|
|
else
|
|
{
|
|
MedianVal = FloatArray[(NumElems - 1) / 2];
|
|
|
|
IndexArr.Add((NumElems - 1) / 2);
|
|
}
|
|
|
|
return MedianVal;
|
|
}
|
|
|
|
static float ComputeMode(const TArray<float>& FloatArray, TArray<int32>& IndexArr)
|
|
{
|
|
float MaxVal = 0.f;
|
|
int32 MaxCount = 0;
|
|
|
|
for (int32 Idx1 = 0; Idx1 < FloatArray.Num(); ++Idx1)
|
|
{
|
|
int32 Count = 0;
|
|
|
|
for (int32 Idx2 = 0; Idx2 < FloatArray.Num(); ++Idx2)
|
|
{
|
|
if (FloatArray[Idx2] == FloatArray[Idx1])
|
|
{
|
|
Count++;
|
|
}
|
|
|
|
if (Count > MaxCount)
|
|
{
|
|
MaxCount = Count;
|
|
MaxVal = FloatArray[Idx1];
|
|
}
|
|
}
|
|
}
|
|
|
|
for (int32 Idx = 0; Idx < FloatArray.Num(); ++Idx)
|
|
{
|
|
if (FloatArray[Idx] == MaxVal)
|
|
{
|
|
IndexArr.Add(Idx);
|
|
}
|
|
}
|
|
|
|
return MaxVal;
|
|
}
|
|
|
|
static float ComputeSum(const TArray<float>& FloatArray, TArray<int32>& IndexArr)
|
|
{
|
|
double SumVal = 0.f;
|
|
|
|
for (int32 Idx = 0; Idx < FloatArray.Num(); ++Idx)
|
|
{
|
|
SumVal += FloatArray[Idx];
|
|
}
|
|
|
|
return (float)SumVal;
|
|
}
|
|
|
|
// -----------------------------------------------------------------------------------------------
|
|
|
|
void FFloatArrayComputeStatisticsDataflowNode::Evaluate(UE::Dataflow::FContext& Context, const FDataflowOutput* Out) const
|
|
{
|
|
if (Out->IsA(&Value) || Out->IsA(&Indices))
|
|
{
|
|
const TArray<float>& InFloatArray = GetValue(Context, &FloatArray);
|
|
const FDataflowTransformSelection& InTransformSelection = GetValue(Context, &TransformSelection);
|
|
|
|
TArray<float> Array;
|
|
if (IsConnected<FDataflowTransformSelection>(&TransformSelection) && InTransformSelection.Num() == InFloatArray.Num())
|
|
{
|
|
for (int32 Idx = 0; Idx < InFloatArray.Num(); ++Idx)
|
|
{
|
|
if (InTransformSelection.IsSelected(Idx))
|
|
{
|
|
Array.Add(InFloatArray[Idx]);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
for (int32 Idx = 0; Idx < InFloatArray.Num(); ++Idx)
|
|
{
|
|
Array.Add(InFloatArray[Idx]);
|
|
}
|
|
}
|
|
|
|
float OutValue;
|
|
TArray<int32> OutIndices;
|
|
|
|
switch (OperationName)
|
|
{
|
|
case EStatisticsOperationEnum::Dataflow_EStatisticsOperationEnum_Min:
|
|
OutValue = ComputeMin(Array, OutIndices);
|
|
break;
|
|
case EStatisticsOperationEnum::Dataflow_EStatisticsOperationEnum_Max:
|
|
OutValue = ComputeMax(Array, OutIndices);
|
|
break;
|
|
case EStatisticsOperationEnum::Dataflow_EStatisticsOperationEnum_Mean:
|
|
OutValue = ComputeMean(Array, OutIndices);
|
|
break;
|
|
case EStatisticsOperationEnum::Dataflow_EStatisticsOperationEnum_Median:
|
|
OutValue = ComputeMedian(Array, OutIndices);
|
|
break;
|
|
case EStatisticsOperationEnum::Dataflow_EStatisticsOperationEnum_Mode:
|
|
OutValue = ComputeMode(Array, OutIndices);
|
|
break;
|
|
case EStatisticsOperationEnum::Dataflow_EStatisticsOperationEnum_Sum:
|
|
OutValue = ComputeSum(Array, OutIndices);
|
|
break;
|
|
}
|
|
|
|
SetValue(Context, OutValue, &Value);
|
|
SetValue(Context, OutIndices, &Indices);
|
|
}
|
|
}
|
|
|
|
void FRandomizeFloatArrayDataflowNode::Evaluate(UE::Dataflow::FContext& Context, const FDataflowOutput* Out) const
|
|
{
|
|
if (Out->IsA(&FloatArray))
|
|
{
|
|
const TArray<float> InFloatArray = GetValue(Context, &FloatArray);
|
|
const float InRandomRangeMin = GetValue(Context, &RandomRangeMin);
|
|
const float InRandomRangeMax = GetValue(Context, &RandomRangeMax);
|
|
const int32 InRandomSeed = GetValue(Context, &RandomSeed);
|
|
TArray<float> OutFloatArray;
|
|
|
|
FRandomStream RandStream(InRandomSeed);
|
|
|
|
const int32 NumPoints = InFloatArray.Num();
|
|
if (NumPoints > 0)
|
|
{
|
|
OutFloatArray.Reserve(NumPoints);
|
|
for (int32 Idx = 0; Idx < NumPoints; ++Idx)
|
|
{
|
|
OutFloatArray.Emplace(RandStream.FRandRange(InRandomRangeMin, InRandomRangeMax));
|
|
}
|
|
}
|
|
|
|
SetValue(Context, MoveTemp(OutFloatArray), &FloatArray);
|
|
}
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
FDataflowGetArraySizeNode::FDataflowGetArraySizeNode(const UE::Dataflow::FNodeParameters& InParam, FGuid InGuid)
|
|
: FDataflowNode(InParam, InGuid)
|
|
{
|
|
RegisterInputConnection(&Array);
|
|
RegisterOutputConnection(&Size);
|
|
}
|
|
|
|
void FDataflowGetArraySizeNode::Evaluate(UE::Dataflow::FContext& Context, const FDataflowOutput* Out) const
|
|
{
|
|
if (Out->IsA(&Size))
|
|
{
|
|
SetArraySizeFromInput(Context, &Array, &Size);
|
|
}
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
FDataflowGetArrayElementNode::FDataflowGetArrayElementNode(const UE::Dataflow::FNodeParameters& InParam, FGuid InGuid)
|
|
: FDataflowNode(InParam, InGuid)
|
|
{
|
|
static FName ArrayElementDependencyGroup("ArrayElement");
|
|
|
|
RegisterInputConnection(&Array)
|
|
.SetTypeDependencyGroup(ArrayElementDependencyGroup);
|
|
RegisterInputConnection(&Index);
|
|
RegisterOutputConnection(&Array, &Array)
|
|
.SetTypeDependencyGroup(ArrayElementDependencyGroup);
|
|
RegisterOutputConnection(&Element)
|
|
.SetTypeDependencyGroup(ArrayElementDependencyGroup);
|
|
}
|
|
|
|
FName FDataflowGetArrayElementNode::GetDependentConnectionType(const FDataflowConnection& SourceConnection, const FDataflowConnection& DependentConnection) const
|
|
{
|
|
if (SourceConnection.IsA(&Array) && DependentConnection.IsA(&Element))
|
|
{
|
|
return FDataflowArrayTypePolicy::GetElementType(SourceConnection.GetType());
|
|
}
|
|
else if (SourceConnection.IsA(&Element) && DependentConnection.IsA(&Array))
|
|
{
|
|
return FDataflowArrayTypePolicy::GetArrayType(SourceConnection.GetType());
|
|
}
|
|
// default for all the rest
|
|
return FDataflowNode::GetDependentConnectionType(SourceConnection, DependentConnection);
|
|
}
|
|
|
|
void FDataflowGetArrayElementNode::Evaluate(UE::Dataflow::FContext& Context, const FDataflowOutput* Out) const
|
|
{
|
|
if (Out->IsA(&Array))
|
|
{
|
|
ForwardInput(Context, &Array, &Array);
|
|
}
|
|
else if (Out->IsA(&Element))
|
|
{
|
|
const int32 InIndex = GetValue(Context, &Index);
|
|
SetArrayElementFromInput(Context, &Array, InIndex, &Element);
|
|
}
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
FDataflowMakeManagedArrayCollectionArrayNode::FDataflowMakeManagedArrayCollectionArrayNode(const UE::Dataflow::FNodeParameters& InParam, FGuid InGuid)
|
|
: FDataflowNode(InParam, InGuid)
|
|
{
|
|
static FName ArrayElementDependencyGroup("ArrayElement");
|
|
|
|
RegisterInputConnection(&Array);
|
|
RegisterInputConnection(&Element);
|
|
RegisterOutputConnection(&Array, &Array);
|
|
}
|
|
|
|
void FDataflowMakeManagedArrayCollectionArrayNode::Evaluate(UE::Dataflow::FContext& Context, const FDataflowOutput* Out) const
|
|
{
|
|
if (Out->IsA(&Array))
|
|
{
|
|
if (IsConnected(&Element))
|
|
{
|
|
TArray<FManagedArrayCollection> OutArray = GetValue(Context, &Array);
|
|
OutArray.Emplace(GetValue(Context, &Element));
|
|
SetValue(Context, MoveTemp(OutArray), &Array);
|
|
return;
|
|
}
|
|
|
|
SafeForwardInput(Context, &Array, &Array);
|
|
}
|
|
} |