Files
UnrealEngine/Engine/Plugins/Experimental/GeometryCollectionPlugin/Source/GeometryCollectionNodes/Private/Dataflow/GeometryCollectionMathNodes.cpp
2025-05-18 13:04:45 +08:00

986 lines
30 KiB
C++

// Copyright Epic Games, Inc. All Rights Reserved.
#include "Dataflow/GeometryCollectionMathNodes.h"
#include "Math/BasicMathExpressionEvaluator.h"
#include "Dataflow/DataflowCore.h"
#include UE_INLINE_GENERATED_CPP_BY_NAME(GeometryCollectionMathNodes)
namespace UE::Dataflow
{
void GeometryCollectionMathNodes()
{
DATAFLOW_NODE_REGISTER_CREATION_FACTORY(FAddDataflowNode);
DATAFLOW_NODE_REGISTER_CREATION_FACTORY(FSubtractDataflowNode);
DATAFLOW_NODE_REGISTER_CREATION_FACTORY(FMultiplyDataflowNode);
DATAFLOW_NODE_REGISTER_CREATION_FACTORY(FSafeDivideDataflowNode);
DATAFLOW_NODE_REGISTER_CREATION_FACTORY(FDivideDataflowNode);
DATAFLOW_NODE_REGISTER_CREATION_FACTORY(FDivisionDataflowNode);
DATAFLOW_NODE_REGISTER_CREATION_FACTORY(FSafeReciprocalDataflowNode);
DATAFLOW_NODE_REGISTER_CREATION_FACTORY(FSquareDataflowNode);
DATAFLOW_NODE_REGISTER_CREATION_FACTORY(FSquareRootDataflowNode);
DATAFLOW_NODE_REGISTER_CREATION_FACTORY(FInverseSqrtDataflowNode);
DATAFLOW_NODE_REGISTER_CREATION_FACTORY(FCubeDataflowNode);
DATAFLOW_NODE_REGISTER_CREATION_FACTORY(FNegateDataflowNode);
DATAFLOW_NODE_REGISTER_CREATION_FACTORY(FAbsDataflowNode);
DATAFLOW_NODE_REGISTER_CREATION_FACTORY(FFloorDataflowNode);
DATAFLOW_NODE_REGISTER_CREATION_FACTORY(FCeilDataflowNode);
DATAFLOW_NODE_REGISTER_CREATION_FACTORY(FRoundDataflowNode);
DATAFLOW_NODE_REGISTER_CREATION_FACTORY(FTruncDataflowNode);
DATAFLOW_NODE_REGISTER_CREATION_FACTORY(FFracDataflowNode);
DATAFLOW_NODE_REGISTER_CREATION_FACTORY(FMinDataflowNode);
DATAFLOW_NODE_REGISTER_CREATION_FACTORY(FMaxDataflowNode);
DATAFLOW_NODE_REGISTER_CREATION_FACTORY(FMin3DataflowNode);
DATAFLOW_NODE_REGISTER_CREATION_FACTORY(FMax3DataflowNode);
DATAFLOW_NODE_REGISTER_CREATION_FACTORY(FSignDataflowNode);
DATAFLOW_NODE_REGISTER_CREATION_FACTORY(FClampDataflowNode);
DATAFLOW_NODE_REGISTER_CREATION_FACTORY(FFitDataflowNode);
DATAFLOW_NODE_REGISTER_CREATION_FACTORY(FEFitDataflowNode);
DATAFLOW_NODE_REGISTER_CREATION_FACTORY(FPowDataflowNode);
DATAFLOW_NODE_REGISTER_CREATION_FACTORY(FLogDataflowNode);
DATAFLOW_NODE_REGISTER_CREATION_FACTORY(FLogeDataflowNode);
DATAFLOW_NODE_REGISTER_CREATION_FACTORY(FLerpDataflowNode);
DATAFLOW_NODE_REGISTER_CREATION_FACTORY(FWrapDataflowNode);
DATAFLOW_NODE_REGISTER_CREATION_FACTORY(FExpDataflowNode);
DATAFLOW_NODE_REGISTER_CREATION_FACTORY(FSinDataflowNode);
DATAFLOW_NODE_REGISTER_CREATION_FACTORY(FArcSinDataflowNode);
DATAFLOW_NODE_REGISTER_CREATION_FACTORY(FCosDataflowNode);
DATAFLOW_NODE_REGISTER_CREATION_FACTORY(FArcCosDataflowNode);
DATAFLOW_NODE_REGISTER_CREATION_FACTORY(FTanDataflowNode);
DATAFLOW_NODE_REGISTER_CREATION_FACTORY(FArcTanDataflowNode);
DATAFLOW_NODE_REGISTER_CREATION_FACTORY(FArcTan2DataflowNode);
DATAFLOW_NODE_REGISTER_CREATION_FACTORY(FNormalizeToRangeDataflowNode);
DATAFLOW_NODE_REGISTER_CREATION_FACTORY(FScaleVectorDataflowNode);
DATAFLOW_NODE_REGISTER_CREATION_FACTORY(FDotProductDataflowNode);
DATAFLOW_NODE_REGISTER_CREATION_FACTORY(FCrossProductDataflowNode);
DATAFLOW_NODE_REGISTER_CREATION_FACTORY(FNormalizeDataflowNode);
DATAFLOW_NODE_REGISTER_CREATION_FACTORY(FLengthDataflowNode);
DATAFLOW_NODE_REGISTER_CREATION_FACTORY(FDistanceDataflowNode);
DATAFLOW_NODE_REGISTER_CREATION_FACTORY(FIsNearlyZeroDataflowNode);
DATAFLOW_NODE_REGISTER_CREATION_FACTORY(FRandomFloatDataflowNode);
DATAFLOW_NODE_REGISTER_CREATION_FACTORY(FRandomFloatInRangeDataflowNode);
DATAFLOW_NODE_REGISTER_CREATION_FACTORY(FRandomUnitVectorDataflowNode);
DATAFLOW_NODE_REGISTER_CREATION_FACTORY(FRandomUnitVectorInConeDataflowNode);
DATAFLOW_NODE_REGISTER_CREATION_FACTORY(FRadiansToDegreesDataflowNode);
DATAFLOW_NODE_REGISTER_CREATION_FACTORY(FDegreesToRadiansDataflowNode);
DATAFLOW_NODE_REGISTER_CREATION_FACTORY(FMathConstantsDataflowNode);
DATAFLOW_NODE_REGISTER_CREATION_FACTORY(FOneMinusDataflowNode);
DATAFLOW_NODE_REGISTER_CREATION_FACTORY(FFloatMathExpressionDataflowNode);
DATAFLOW_NODE_REGISTER_CREATION_FACTORY(FMathExpressionDataflowNode);
}
}
void FAddDataflowNode::Evaluate(UE::Dataflow::FContext& Context, const FDataflowOutput* Out) const
{
if (Out->IsA<float>(&ReturnValue))
{
const float InFloatA = GetValue<float>(Context, &FloatA, FloatA);
const float InFloatB = GetValue<float>(Context, &FloatB, FloatB);
const float Result = InFloatA + InFloatB;
SetValue(Context, Result, &ReturnValue);
}
}
void FSubtractDataflowNode::Evaluate(UE::Dataflow::FContext& Context, const FDataflowOutput* Out) const
{
if (Out->IsA<float>(&ReturnValue))
{
const float InFloatA = GetValue<float>(Context, &FloatA, FloatA);
const float InFloatB = GetValue<float>(Context, &FloatB, FloatB);
const float Result = InFloatA - InFloatB;
SetValue(Context, Result, &ReturnValue);
}
}
void FMultiplyDataflowNode::Evaluate(UE::Dataflow::FContext& Context, const FDataflowOutput* Out) const
{
if (Out->IsA<float>(&ReturnValue))
{
const float InFloatA = GetValue<float>(Context, &FloatA, FloatA);
const float InFloatB = GetValue<float>(Context, &FloatB, FloatB);
const float Result = InFloatA * InFloatB;
SetValue(Context, Result, &ReturnValue);
}
}
void FSafeDivideDataflowNode::Evaluate(UE::Dataflow::FContext& Context, const FDataflowOutput* Out) const
{
if (Out->IsA<float>(&ReturnValue))
{
const float InFloatA = GetValue<float>(Context, &FloatA, FloatA);
const float InFloatB = GetValue<float>(Context, &FloatB, FloatB);
float Result = 0.f;
if (InFloatB != 0.f)
{
Result = InFloatA / InFloatB;
SetValue(Context, Result, &ReturnValue);
}
else
{
SetError(Context, &ReturnValue, TEXT("Division by zero error"));
}
}
}
void FDivisionDataflowNode::Evaluate(UE::Dataflow::FContext& Context, const FDataflowOutput* Out) const
{
if (Out->IsA<float>(&Remainder) ||
Out->IsA<int32>(&ReturnValue))
{
const float InDividend = GetValue<float>(Context, &Dividend, Dividend);
const float InDivisor = GetValue<float>(Context, &Divisor, Divisor);
float ResultRemainder = 0.f;
int32 Result = 0;
if (InDivisor != 0.f)
{
Result = (int32)(InDividend / InDivisor);
ResultRemainder = InDividend - (float)Result * InDivisor;
}
SetValue(Context, ResultRemainder, &Remainder);
SetValue(Context, Result, &ReturnValue);
}
}
void FSafeReciprocalDataflowNode::Evaluate(UE::Dataflow::FContext& Context, const FDataflowOutput* Out) const
{
if (Out->IsA<float>(&ReturnValue))
{
const float InFloat = GetValue<float>(Context, &Float, Float);
float Result = 0.f;
if (InFloat != 0.f)
{
Result = 1.f / InFloat;
}
SetValue(Context, Result, &ReturnValue);
}
}
void FSquareDataflowNode::Evaluate(UE::Dataflow::FContext& Context, const FDataflowOutput* Out) const
{
if (Out->IsA<float>(&ReturnValue))
{
const float InFloat = GetValue<float>(Context, &Float, Float);
const float Result = InFloat * InFloat;
SetValue(Context, Result, &ReturnValue);
}
}
void FSquareRootDataflowNode::Evaluate(UE::Dataflow::FContext& Context, const FDataflowOutput* Out) const
{
if (Out->IsA<float>(&ReturnValue))
{
const float InFloat = GetValue<float>(Context, &Float, Float);
float Result = 0.f;
if (InFloat > 0.f)
{
Result = FMath::Sqrt(InFloat);
}
SetValue(Context, Result, &ReturnValue);
}
}
void FInverseSqrtDataflowNode::Evaluate(UE::Dataflow::FContext& Context, const FDataflowOutput* Out) const
{
if (Out->IsA<float>(&ReturnValue))
{
const float InFloat = GetValue<float>(Context, &Float, Float);
float Result = 0.f;
if (InFloat > 0.f)
{
Result = FMath::InvSqrt(InFloat);
}
SetValue(Context, Result, &ReturnValue);
}
}
void FCubeDataflowNode::Evaluate(UE::Dataflow::FContext& Context, const FDataflowOutput* Out) const
{
if (Out->IsA<float>(&ReturnValue))
{
const float InFloat = GetValue<float>(Context, &Float, Float);
const float Result = InFloat * InFloat * InFloat;
SetValue(Context, Result, &ReturnValue);
}
}
void FNegateDataflowNode::Evaluate(UE::Dataflow::FContext& Context, const FDataflowOutput* Out) const
{
if (Out->IsA<float>(&ReturnValue))
{
const float InFloat = GetValue<float>(Context, &Float, Float);
const float Result = -1.f * InFloat;
SetValue(Context, Result, &ReturnValue);
}
}
void FAbsDataflowNode::Evaluate(UE::Dataflow::FContext& Context, const FDataflowOutput* Out) const
{
if (Out->IsA<float>(&ReturnValue))
{
const float InFloat = GetValue<float>(Context, &Float, Float);
const float Result = FMath::Abs(InFloat);
SetValue(Context, Result, &ReturnValue);
}
}
void FFloorDataflowNode::Evaluate(UE::Dataflow::FContext& Context, const FDataflowOutput* Out) const
{
if (Out->IsA<float>(&ReturnValue))
{
const float InFloat = GetValue<float>(Context, &Float, Float);
const float Result = FMath::Floor(InFloat);
SetValue(Context, Result, &ReturnValue);
}
}
void FCeilDataflowNode::Evaluate(UE::Dataflow::FContext& Context, const FDataflowOutput* Out) const
{
if (Out->IsA<float>(&ReturnValue))
{
const float InFloat = GetValue<float>(Context, &Float, Float);
float Result = FMath::CeilToFloat(InFloat);
SetValue(Context, Result, &ReturnValue);
}
}
void FRoundDataflowNode::Evaluate(UE::Dataflow::FContext& Context, const FDataflowOutput* Out) const
{
if (Out->IsA<float>(&ReturnValue))
{
const float InFloat = GetValue<float>(Context, &Float, Float);
float Result = FMath::RoundToFloat(InFloat);
SetValue(Context, Result, &ReturnValue);
}
}
void FTruncDataflowNode::Evaluate(UE::Dataflow::FContext& Context, const FDataflowOutput* Out) const
{
if (Out->IsA<float>(&ReturnValue))
{
const float InFloat = GetValue<float>(Context, &Float, Float);
const float Result = FMath::TruncToFloat(InFloat);
SetValue(Context, Result, &ReturnValue);
}
}
void FFracDataflowNode::Evaluate(UE::Dataflow::FContext& Context, const FDataflowOutput* Out) const
{
if (Out->IsA<float>(&ReturnValue))
{
const float InFloat = GetValue<float>(Context, &Float, Float);
const float Result = FMath::Frac(InFloat);
SetValue(Context, Result, &ReturnValue);
}
}
void FMinDataflowNode::Evaluate(UE::Dataflow::FContext& Context, const FDataflowOutput* Out) const
{
if (Out->IsA<float>(&ReturnValue))
{
const float InFloatA = GetValue<float>(Context, &FloatA, FloatA);
const float InFloatB = GetValue<float>(Context, &FloatB, FloatB);
const float Result = FMath::Min(InFloatA, InFloatB);
SetValue(Context, Result, &ReturnValue);
}
}
void FMaxDataflowNode::Evaluate(UE::Dataflow::FContext& Context, const FDataflowOutput* Out) const
{
if (Out->IsA<float>(&ReturnValue))
{
const float InFloatA = GetValue<float>(Context, &FloatA, FloatA);
const float InFloatB = GetValue<float>(Context, &FloatB, FloatB);
const float Result = FMath::Max(InFloatA, InFloatB);
SetValue(Context, Result, &ReturnValue);
}
}
void FMin3DataflowNode::Evaluate(UE::Dataflow::FContext& Context, const FDataflowOutput* Out) const
{
if (Out->IsA<float>(&ReturnValue))
{
const float InFloatA = GetValue<float>(Context, &FloatA, FloatA);
const float InFloatB = GetValue<float>(Context, &FloatB, FloatB);
const float InFloatC = GetValue<float>(Context, &FloatC, FloatB);
const float Result = FMath::Min3(InFloatA, InFloatB, InFloatC);
SetValue(Context, Result, &ReturnValue);
}
}
void FMax3DataflowNode::Evaluate(UE::Dataflow::FContext& Context, const FDataflowOutput* Out) const
{
if (Out->IsA<float>(&ReturnValue))
{
const float InFloatA = GetValue<float>(Context, &FloatA, FloatA);
const float InFloatB = GetValue<float>(Context, &FloatB, FloatB);
const float InFloatC = GetValue<float>(Context, &FloatC, FloatB);
const float Result = FMath::Max3(InFloatA, InFloatB, InFloatC);
SetValue(Context, Result, &ReturnValue);
}
}
void FSignDataflowNode::Evaluate(UE::Dataflow::FContext& Context, const FDataflowOutput* Out) const
{
if (Out->IsA<float>(&ReturnValue))
{
const float InFloat = GetValue<float>(Context, &Float, Float);
const float Result = FMath::Sign(InFloat);
SetValue(Context, Result, &ReturnValue);
}
}
void FClampDataflowNode::Evaluate(UE::Dataflow::FContext& Context, const FDataflowOutput* Out) const
{
if (Out->IsA<float>(&ReturnValue))
{
const float InFloat = GetValue<float>(Context, &Float, Float);
const float InMin = GetValue<float>(Context, &Min, Min);
const float InMax = GetValue<float>(Context, &Max, Max);
const float Result = FMath::Clamp(InFloat, InMin, InMax);
SetValue(Context, Result, &ReturnValue);
}
}
void FFitDataflowNode::Evaluate(UE::Dataflow::FContext& Context, const FDataflowOutput* Out) const
{
if (Out->IsA<float>(&ReturnValue))
{
float InFloat = GetValue<float>(Context, &Float, Float);
const float InOldMin = GetValue<float>(Context, &OldMin, OldMin);
const float InOldMax = GetValue<float>(Context, &OldMax, OldMax);
const float InNewMin = GetValue<float>(Context, &NewMin, NewMin);
const float InNewMax = GetValue<float>(Context, &NewMax, NewMax);
float Result = InFloat;
if (InOldMax > InOldMin && InNewMax > InNewMin)
{
InFloat = FMath::Clamp(InFloat, InOldMin, InOldMax);
float Q = (InFloat - InOldMin) / (InOldMax - InOldMin);
Result = InNewMin + Q * (InNewMax - InNewMin);
}
SetValue(Context, Result, &ReturnValue);
}
}
void FEFitDataflowNode::Evaluate(UE::Dataflow::FContext& Context, const FDataflowOutput* Out) const
{
if (Out->IsA<float>(&ReturnValue))
{
const float InFloat = GetValue<float>(Context, &Float, Float);
const float InOldMin = GetValue<float>(Context, &OldMin, OldMin);
const float InOldMax = GetValue<float>(Context, &OldMax, OldMax);
const float InNewMin = GetValue<float>(Context, &NewMin, NewMin);
const float InNewMax = GetValue<float>(Context, &NewMax, NewMax);
float Result = InFloat;
if (InOldMax > InOldMin && InNewMax > InNewMin)
{
float Q = (InFloat - InOldMin) / (InOldMax - InOldMin);
Result = InNewMin + Q * (InNewMax - InNewMin);
}
SetValue(Context, Result, &ReturnValue);
}
}
void FPowDataflowNode::Evaluate(UE::Dataflow::FContext& Context, const FDataflowOutput* Out) const
{
if (Out->IsA<float>(&ReturnValue))
{
const float InBase = GetValue<float>(Context, &Base, Base);
const float InExp = GetValue<float>(Context, &Exp, Exp);
const float Result = FMath::Pow(InBase, InExp);
SetValue(Context, Result, &ReturnValue);
}
}
void FLogDataflowNode::Evaluate(UE::Dataflow::FContext& Context, const FDataflowOutput* Out) const
{
if (Out->IsA<float>(&ReturnValue))
{
const float InBase = GetValue<float>(Context, &Base, Base);
const float InA = GetValue<float>(Context, &A, A);
float Result = 0;
if (InBase > 0.f)
{
Result = FMath::LogX(InBase, A);
}
SetValue(Context, Result, &ReturnValue);
}
}
void FLogeDataflowNode::Evaluate(UE::Dataflow::FContext& Context, const FDataflowOutput* Out) const
{
if (Out->IsA<float>(&ReturnValue))
{
const float InA = GetValue<float>(Context, &A, A);
const float Result = FMath::Loge(A);
SetValue(Context, Result, &ReturnValue);
}
}
void FLerpDataflowNode::Evaluate(UE::Dataflow::FContext& Context, const FDataflowOutput* Out) const
{
if (Out->IsA(&ReturnValue))
{
const float InA = GetValue(Context, &A, A);
const float InB = GetValue(Context, &B, B);
const float InAlpha = GetValue(Context, &Alpha, Alpha);
float Result = InA;
Result = FMath::Lerp(InA, InB, InAlpha);
SetValue(Context, Result, &ReturnValue);
}
}
void FWrapDataflowNode::Evaluate(UE::Dataflow::FContext& Context, const FDataflowOutput* Out) const
{
if (Out->IsA<float>(&ReturnValue))
{
const float InFloat = GetValue<float>(Context, &Float, Float);
const float InMin = GetValue<float>(Context, &Min, Min);
const float InMax = GetValue<float>(Context, &Max, Max);
float Result = InFloat;
if (InMax > InMin)
{
Result = FMath::Wrap(InFloat, InMin, InMax);
}
SetValue(Context, Result, &ReturnValue);
}
}
void FExpDataflowNode::Evaluate(UE::Dataflow::FContext& Context, const FDataflowOutput* Out) const
{
if (Out->IsA<float>(&ReturnValue))
{
const float InFloat = GetValue<float>(Context, &Float, Float);
const float Result = FMath::Exp(InFloat);
SetValue(Context, Result, &ReturnValue);
}
}
void FSinDataflowNode::Evaluate(UE::Dataflow::FContext& Context, const FDataflowOutput* Out) const
{
if (Out->IsA<float>(&ReturnValue))
{
const float InFloat = GetValue<float>(Context, &Float, Float);
const float Result = FMath::Sin(InFloat);
SetValue(Context, Result, &ReturnValue);
}
}
void FArcSinDataflowNode::Evaluate(UE::Dataflow::FContext& Context, const FDataflowOutput* Out) const
{
if (Out->IsA<float>(&ReturnValue))
{
const float InFloat = GetValue<float>(Context, &Float, Float);
float Result = 0.f;
if (InFloat >= -1.f && InFloat <= 1.f)
{
Result = FMath::Asin(InFloat);
}
SetValue(Context, Result, &ReturnValue);
}
}
void FCosDataflowNode::Evaluate(UE::Dataflow::FContext& Context, const FDataflowOutput* Out) const
{
if (Out->IsA<float>(&ReturnValue))
{
const float InFloat = GetValue<float>(Context, &Float, Float);
const float Result = FMath::Cos(InFloat);
SetValue(Context, Result, &ReturnValue);
}
}
void FArcCosDataflowNode::Evaluate(UE::Dataflow::FContext& Context, const FDataflowOutput* Out) const
{
if (Out->IsA<float>(&ReturnValue))
{
const float InFloat = GetValue<float>(Context, &Float, Float);
float Result = 0.f;
if (InFloat >= -1.f && InFloat <= 1.f)
{
Result = FMath::Acos(InFloat);
}
SetValue(Context, Result, &ReturnValue);
}
}
void FTanDataflowNode::Evaluate(UE::Dataflow::FContext& Context, const FDataflowOutput* Out) const
{
if (Out->IsA<float>(&ReturnValue))
{
const float InFloat = GetValue<float>(Context, &Float, Float);
const float Result = FMath::Tan(InFloat);
SetValue(Context, Result, &ReturnValue);
}
}
void FArcTanDataflowNode::Evaluate(UE::Dataflow::FContext& Context, const FDataflowOutput* Out) const
{
if (Out->IsA<float>(&ReturnValue))
{
const float InFloat = GetValue<float>(Context, &Float, Float);
const float Result = FMath::Atan(InFloat);
SetValue(Context, Result, &ReturnValue);
}
}
void FArcTan2DataflowNode::Evaluate(UE::Dataflow::FContext& Context, const FDataflowOutput* Out) const
{
if (Out->IsA<float>(&ReturnValue))
{
const float InY = GetValue<float>(Context, &Y, Y);
const float InX = GetValue<float>(Context, &X, X);
const float Result = FMath::Atan2(InY, InX);
SetValue(Context, Result, &ReturnValue);
}
}
void FNormalizeToRangeDataflowNode::Evaluate(UE::Dataflow::FContext& Context, const FDataflowOutput* Out) const
{
if (Out->IsA<float>(&ReturnValue))
{
const float InFloat = GetValue<float>(Context, &Float, Float);
float IRangeMin = GetValue<float>(Context, &RangeMin, RangeMin);
float InRangeMax = GetValue<float>(Context, &RangeMax, RangeMax);
float Result;
if (IRangeMin == InRangeMax)
{
if (InFloat < IRangeMin)
{
Result = 0.f;
}
else
{
Result = 1.f;
}
}
if (IRangeMin > InRangeMax)
{
Swap(IRangeMin, InRangeMax);
}
Result = (InFloat - IRangeMin) / (InRangeMax - IRangeMin);
SetValue(Context, Result, &ReturnValue);
}
}
void FScaleVectorDataflowNode::Evaluate(UE::Dataflow::FContext& Context, const FDataflowOutput* Out) const
{
if (Out->IsA(&ScaledVector))
{
const FVector InVector = GetValue(Context, &Vector, Vector);
const float InScale = GetValue(Context, &Scale, Scale);
const FVector Result = InVector * InScale;
SetValue(Context, Result, &ScaledVector);
}
}
void FDotProductDataflowNode::Evaluate(UE::Dataflow::FContext& Context, const FDataflowOutput* Out) const
{
if (Out->IsA<float>(&ReturnValue))
{
const FVector InVectorA = GetValue<FVector>(Context, &VectorA, VectorA);
const FVector InVectorB = GetValue<FVector>(Context, &VectorB, VectorB);
const float Result = FVector::DotProduct(InVectorA, InVectorB);
SetValue(Context, Result, &ReturnValue);
}
}
void FCrossProductDataflowNode::Evaluate(UE::Dataflow::FContext& Context, const FDataflowOutput* Out) const
{
if (Out->IsA<FVector>(&ReturnValue))
{
const FVector InVectorA = GetValue<FVector>(Context, &VectorA, VectorA);
const FVector InVectorB = GetValue<FVector>(Context, &VectorB, VectorB);
const FVector Result = FVector::CrossProduct(InVectorA, InVectorB);
SetValue(Context, Result, &ReturnValue);
}
}
void FNormalizeDataflowNode::Evaluate(UE::Dataflow::FContext& Context, const FDataflowOutput* Out) const
{
if (Out->IsA<FVector>(&ReturnValue))
{
const FVector InVectorA = GetValue<FVector>(Context, &VectorA, VectorA);
const float InTolerance = GetValue<float>(Context, &Tolerance, Tolerance);
const FVector Result = InVectorA.GetSafeNormal(Tolerance);
SetValue(Context, Result, &ReturnValue);
}
}
void FLengthDataflowNode::Evaluate(UE::Dataflow::FContext& Context, const FDataflowOutput* Out) const
{
if (Out->IsA<float>(&ReturnValue))
{
const FVector InVector = GetValue<FVector>(Context, &Vector, Vector);
const float Result = InVector.Length();
SetValue(Context, Result, &ReturnValue);
}
}
void FDistanceDataflowNode::Evaluate(UE::Dataflow::FContext& Context, const FDataflowOutput* Out) const
{
if (Out->IsA<float>(&ReturnValue))
{
const FVector InPointA = GetValue<FVector>(Context, &PointA, PointA);
const FVector InPointB = GetValue<FVector>(Context, &PointB, PointB);
const float Result = (InPointB - InPointA).Length();
SetValue(Context, Result, &ReturnValue);
}
}
void FIsNearlyZeroDataflowNode::Evaluate(UE::Dataflow::FContext& Context, const FDataflowOutput* Out) const
{
if (Out->IsA<bool>(&ReturnValue))
{
const float InFloat = GetValue<float>(Context, &Float, Float);
const bool Result = FMath::IsNearlyZero(InFloat);
SetValue(Context, Result, &ReturnValue);
}
}
void FRandomFloatDataflowNode::Evaluate(UE::Dataflow::FContext& Context, const FDataflowOutput* Out) const
{
if (Out->IsA<float>(&ReturnValue))
{
if (bDeterministic)
{
const float RandomSeedVal = GetValue<float>(Context, &RandomSeed);
const FRandomStream Stream(RandomSeedVal);
SetValue(Context, Stream.FRand(), &ReturnValue);
}
else
{
SetValue(Context, FMath::FRand(), &ReturnValue);
}
}
}
void FRandomFloatInRangeDataflowNode::Evaluate(UE::Dataflow::FContext& Context, const FDataflowOutput* Out) const
{
if (Out->IsA<float>(&ReturnValue))
{
float MinVal = GetValue<float>(Context, &Min);
float MaxVal = GetValue<float>(Context, &Max);
if (bDeterministic)
{
const float RandomSeedVal = GetValue<float>(Context, &RandomSeed);
const FRandomStream Stream(RandomSeedVal);
SetValue(Context, (float)Stream.FRandRange(MinVal, MaxVal), &ReturnValue);
}
else
{
SetValue(Context, FMath::FRandRange(MinVal, MaxVal), &ReturnValue);
}
}
}
void FRandomUnitVectorDataflowNode::Evaluate(UE::Dataflow::FContext& Context, const FDataflowOutput* Out) const
{
if (Out->IsA<FVector>(&ReturnValue))
{
if (bDeterministic)
{
const float RandomSeedVal = GetValue<float>(Context, &RandomSeed);
const FRandomStream Stream(RandomSeedVal);
SetValue(Context, Stream.VRand(), &ReturnValue);
}
else
{
SetValue(Context, FMath::VRand(), &ReturnValue);
}
}
}
void FRandomUnitVectorInConeDataflowNode::Evaluate(UE::Dataflow::FContext& Context, const FDataflowOutput* Out) const
{
if (Out->IsA<FVector>(&ReturnValue))
{
FVector ConeDirectionVal = GetValue<FVector>(Context, &ConeDirection);
float ConeHalfAngleVal = GetValue<float>(Context, &ConeHalfAngle);
if (bDeterministic)
{
const float RandomSeedVal = GetValue<float>(Context, &RandomSeed);
const FRandomStream Stream(RandomSeedVal);
SetValue(Context, Stream.VRandCone(ConeDirectionVal, ConeHalfAngleVal), &ReturnValue);
}
else
{
SetValue(Context, FMath::VRandCone(ConeDirectionVal, ConeHalfAngleVal), &ReturnValue);
}
}
}
void FRadiansToDegreesDataflowNode::Evaluate(UE::Dataflow::FContext& Context, const FDataflowOutput* Out) const
{
if (Out->IsA<float>(&Degrees))
{
SetValue(Context, FMath::RadiansToDegrees(GetValue<float>(Context, &Radians)), &Degrees);
}
}
void FDegreesToRadiansDataflowNode::Evaluate(UE::Dataflow::FContext& Context, const FDataflowOutput* Out) const
{
if (Out->IsA<float>(&Radians))
{
SetValue(Context, FMath::DegreesToRadians(GetValue<float>(Context, &Degrees)), &Radians);
}
}
void FMathConstantsDataflowNode::Evaluate(UE::Dataflow::FContext& Context, const FDataflowOutput* Out) const
{
if (Out->IsA<float>(&ReturnValue))
{
if (Constant == EMathConstantsEnum::Dataflow_MathConstants_Pi)
{
SetValue(Context, FMathf::Pi, &ReturnValue);
}
else if (Constant == EMathConstantsEnum::Dataflow_MathConstants_HalfPi)
{
SetValue(Context, FMathf::HalfPi, &ReturnValue);
}
else if (Constant == EMathConstantsEnum::Dataflow_MathConstants_TwoPi)
{
SetValue(Context, FMathf::TwoPi, &ReturnValue);
}
else if (Constant == EMathConstantsEnum::Dataflow_MathConstants_FourPi)
{
SetValue(Context, FMathf::FourPi, &ReturnValue);
}
else if (Constant == EMathConstantsEnum::Dataflow_MathConstants_InvPi)
{
SetValue(Context, FMathf::InvPi, &ReturnValue);
}
else if (Constant == EMathConstantsEnum::Dataflow_MathConstants_InvTwoPi)
{
SetValue(Context, FMathf::InvTwoPi, &ReturnValue);
}
else if (Constant == EMathConstantsEnum::Dataflow_MathConstants_Sqrt2)
{
SetValue(Context, FMathf::Sqrt2, &ReturnValue);
}
else if (Constant == EMathConstantsEnum::Dataflow_MathConstants_InvSqrt2)
{
SetValue(Context, FMathf::InvSqrt2, &ReturnValue);
}
else if (Constant == EMathConstantsEnum::Dataflow_MathConstants_Sqrt3)
{
SetValue(Context, FMathf::Sqrt3, &ReturnValue);
}
else if (Constant == EMathConstantsEnum::Dataflow_MathConstants_InvSqrt3)
{
SetValue(Context, FMathf::InvSqrt3, &ReturnValue);
}
else if (Constant == EMathConstantsEnum::Dataflow_FloatToInt_Function_E)
{
SetValue(Context, 2.71828182845904523536f, &ReturnValue);
}
else if (Constant == EMathConstantsEnum::Dataflow_FloatToInt_Function_Gamma)
{
SetValue(Context, 0.577215664901532860606512090082f, &ReturnValue);
}
else if (Constant == EMathConstantsEnum::Dataflow_FloatToInt_Function_GoldenRatio)
{
SetValue(Context, 1.618033988749894f, &ReturnValue);
}
else if (Constant == EMathConstantsEnum::Dataflow_FloatToInt_Function_ZeroTolerance)
{
SetValue(Context, FMathf::ZeroTolerance, &ReturnValue);
}
}
}
void FOneMinusDataflowNode::Evaluate(UE::Dataflow::FContext& Context, const FDataflowOutput* Out) const
{
if (Out->IsA<float>(&ReturnValue))
{
const float InA = GetValue<float>(Context, &A, A);
const float Result = 1.f - InA;
SetValue(Context, Result, &ReturnValue);
}
}
FFloatMathExpressionDataflowNode::FFloatMathExpressionDataflowNode(const UE::Dataflow::FNodeParameters& InParam, FGuid InGuid)
: FDataflowNode(InParam, InGuid)
{
RegisterInputConnection(&A);
RegisterInputConnection(&B);
RegisterInputConnection(&C);
RegisterInputConnection(&D);
RegisterOutputConnection(&ReturnValue);
}
void FFloatMathExpressionDataflowNode::Evaluate(UE::Dataflow::FContext& Context, const FDataflowOutput* Out) const
{
check(Out->IsA(&ReturnValue));
float FloatResult = 0.0f;
FString ExpressionToEvaluate{ Expression };
ExpressionToEvaluate = ExpressionToEvaluate.TrimStartAndEnd();
if (!ExpressionToEvaluate.IsEmpty())
{
const FString VarA("{A}");
if (ExpressionToEvaluate.Contains(VarA))
{
const float InA = GetValue(Context, &A);
const FString StrA = FString::SanitizeFloat(InA);
ExpressionToEvaluate.ReplaceInline(*VarA, *StrA, ESearchCase::CaseSensitive);
}
const FString VarB("{B}");
if (ExpressionToEvaluate.Contains(VarB))
{
const float InB = GetValue(Context, &B);
const FString StrB = FString::SanitizeFloat(InB);
ExpressionToEvaluate.ReplaceInline(*VarB, *StrB, ESearchCase::CaseSensitive);
}
const FString VarC("{C}");
if (ExpressionToEvaluate.Contains(VarC))
{
const float InC = GetValue(Context, &C);
const FString StrC = FString::SanitizeFloat(InC);
ExpressionToEvaluate.ReplaceInline(*VarC, *StrC, ESearchCase::CaseSensitive);
}
const FString VarD("{D}");
if (ExpressionToEvaluate.Contains(VarD))
{
const float InD = GetValue(Context, &D);
const FString StrD = FString::SanitizeFloat(InD);
ExpressionToEvaluate.ReplaceInline(*VarD, *StrD, ESearchCase::CaseSensitive);
}
FBasicMathExpressionEvaluator Evaluator;
TValueOrError<double, FExpressionError> Result = Evaluator.Evaluate(*ExpressionToEvaluate);
if (Result.IsValid())
{
FloatResult = FMath::Clamp((float)Result.GetValue(), TNumericLimits<float>::Lowest(), TNumericLimits<float>::Max());
}
}
SetValue(Context, FloatResult, &ReturnValue);
}
FMathExpressionDataflowNode::FMathExpressionDataflowNode(const UE::Dataflow::FNodeParameters& InParam, FGuid InGuid)
: FDataflowNode(InParam, InGuid)
{
RegisterInputConnection(&A);
RegisterInputConnection(&B);
RegisterInputConnection(&C);
RegisterInputConnection(&D);
RegisterOutputConnection(&ReturnValue);
}
void FMathExpressionDataflowNode::Evaluate(UE::Dataflow::FContext& Context, const FDataflowOutput* Out) const
{
check(Out->IsA(&ReturnValue));
double Result = 0.0f;
FString ExpressionToEvaluate{ Expression };
ExpressionToEvaluate = ExpressionToEvaluate.TrimStartAndEnd();
if (!ExpressionToEvaluate.IsEmpty())
{
const FString VarA("{A}");
if (ExpressionToEvaluate.Contains(VarA))
{
const double InA = GetValue(Context, &A);
const FString StrA = FString::SanitizeFloat(InA);
ExpressionToEvaluate.ReplaceInline(*VarA, *StrA, ESearchCase::CaseSensitive);
}
const FString VarB("{B}");
if (ExpressionToEvaluate.Contains(VarB))
{
const double InB = GetValue(Context, &B);
const FString StrB = FString::SanitizeFloat(InB);
ExpressionToEvaluate.ReplaceInline(*VarB, *StrB, ESearchCase::CaseSensitive);
}
const FString VarC("{C}");
if (ExpressionToEvaluate.Contains(VarC))
{
const double InC = GetValue(Context, &C);
const FString StrC = FString::SanitizeFloat(InC);
ExpressionToEvaluate.ReplaceInline(*VarC, *StrC, ESearchCase::CaseSensitive);
}
const FString VarD("{D}");
if (ExpressionToEvaluate.Contains(VarD))
{
const double InD = GetValue(Context, &D);
const FString StrD = FString::SanitizeFloat(InD);
ExpressionToEvaluate.ReplaceInline(*VarD, *StrD, ESearchCase::CaseSensitive);
}
FBasicMathExpressionEvaluator Evaluator;
TValueOrError<double, FExpressionError> EvalResult = Evaluator.Evaluate(*ExpressionToEvaluate);
if (EvalResult.IsValid())
{
Result = FMath::Clamp((double)EvalResult.GetValue(), TNumericLimits<double>::Lowest(), TNumericLimits<double>::Max());
}
}
SetValue(Context, Result, &ReturnValue);
}