// 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(&ReturnValue)) { const float InFloatA = GetValue(Context, &FloatA, FloatA); const float InFloatB = GetValue(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(&ReturnValue)) { const float InFloatA = GetValue(Context, &FloatA, FloatA); const float InFloatB = GetValue(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(&ReturnValue)) { const float InFloatA = GetValue(Context, &FloatA, FloatA); const float InFloatB = GetValue(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(&ReturnValue)) { const float InFloatA = GetValue(Context, &FloatA, FloatA); const float InFloatB = GetValue(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(&Remainder) || Out->IsA(&ReturnValue)) { const float InDividend = GetValue(Context, &Dividend, Dividend); const float InDivisor = GetValue(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(&ReturnValue)) { const float InFloat = GetValue(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(&ReturnValue)) { const float InFloat = GetValue(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(&ReturnValue)) { const float InFloat = GetValue(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(&ReturnValue)) { const float InFloat = GetValue(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(&ReturnValue)) { const float InFloat = GetValue(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(&ReturnValue)) { const float InFloat = GetValue(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(&ReturnValue)) { const float InFloat = GetValue(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(&ReturnValue)) { const float InFloat = GetValue(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(&ReturnValue)) { const float InFloat = GetValue(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(&ReturnValue)) { const float InFloat = GetValue(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(&ReturnValue)) { const float InFloat = GetValue(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(&ReturnValue)) { const float InFloat = GetValue(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(&ReturnValue)) { const float InFloatA = GetValue(Context, &FloatA, FloatA); const float InFloatB = GetValue(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(&ReturnValue)) { const float InFloatA = GetValue(Context, &FloatA, FloatA); const float InFloatB = GetValue(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(&ReturnValue)) { const float InFloatA = GetValue(Context, &FloatA, FloatA); const float InFloatB = GetValue(Context, &FloatB, FloatB); const float InFloatC = GetValue(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(&ReturnValue)) { const float InFloatA = GetValue(Context, &FloatA, FloatA); const float InFloatB = GetValue(Context, &FloatB, FloatB); const float InFloatC = GetValue(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(&ReturnValue)) { const float InFloat = GetValue(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(&ReturnValue)) { const float InFloat = GetValue(Context, &Float, Float); const float InMin = GetValue(Context, &Min, Min); const float InMax = GetValue(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(&ReturnValue)) { float InFloat = GetValue(Context, &Float, Float); const float InOldMin = GetValue(Context, &OldMin, OldMin); const float InOldMax = GetValue(Context, &OldMax, OldMax); const float InNewMin = GetValue(Context, &NewMin, NewMin); const float InNewMax = GetValue(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(&ReturnValue)) { const float InFloat = GetValue(Context, &Float, Float); const float InOldMin = GetValue(Context, &OldMin, OldMin); const float InOldMax = GetValue(Context, &OldMax, OldMax); const float InNewMin = GetValue(Context, &NewMin, NewMin); const float InNewMax = GetValue(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(&ReturnValue)) { const float InBase = GetValue(Context, &Base, Base); const float InExp = GetValue(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(&ReturnValue)) { const float InBase = GetValue(Context, &Base, Base); const float InA = GetValue(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(&ReturnValue)) { const float InA = GetValue(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(&ReturnValue)) { const float InFloat = GetValue(Context, &Float, Float); const float InMin = GetValue(Context, &Min, Min); const float InMax = GetValue(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(&ReturnValue)) { const float InFloat = GetValue(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(&ReturnValue)) { const float InFloat = GetValue(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(&ReturnValue)) { const float InFloat = GetValue(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(&ReturnValue)) { const float InFloat = GetValue(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(&ReturnValue)) { const float InFloat = GetValue(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(&ReturnValue)) { const float InFloat = GetValue(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(&ReturnValue)) { const float InFloat = GetValue(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(&ReturnValue)) { const float InY = GetValue(Context, &Y, Y); const float InX = GetValue(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(&ReturnValue)) { const float InFloat = GetValue(Context, &Float, Float); float IRangeMin = GetValue(Context, &RangeMin, RangeMin); float InRangeMax = GetValue(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(&ReturnValue)) { const FVector InVectorA = GetValue(Context, &VectorA, VectorA); const FVector InVectorB = GetValue(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(&ReturnValue)) { const FVector InVectorA = GetValue(Context, &VectorA, VectorA); const FVector InVectorB = GetValue(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(&ReturnValue)) { const FVector InVectorA = GetValue(Context, &VectorA, VectorA); const float InTolerance = GetValue(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(&ReturnValue)) { const FVector InVector = GetValue(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(&ReturnValue)) { const FVector InPointA = GetValue(Context, &PointA, PointA); const FVector InPointB = GetValue(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(&ReturnValue)) { const float InFloat = GetValue(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(&ReturnValue)) { if (bDeterministic) { const float RandomSeedVal = GetValue(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(&ReturnValue)) { float MinVal = GetValue(Context, &Min); float MaxVal = GetValue(Context, &Max); if (bDeterministic) { const float RandomSeedVal = GetValue(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(&ReturnValue)) { if (bDeterministic) { const float RandomSeedVal = GetValue(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(&ReturnValue)) { FVector ConeDirectionVal = GetValue(Context, &ConeDirection); float ConeHalfAngleVal = GetValue(Context, &ConeHalfAngle); if (bDeterministic) { const float RandomSeedVal = GetValue(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(&Degrees)) { SetValue(Context, FMath::RadiansToDegrees(GetValue(Context, &Radians)), &Degrees); } } void FDegreesToRadiansDataflowNode::Evaluate(UE::Dataflow::FContext& Context, const FDataflowOutput* Out) const { if (Out->IsA(&Radians)) { SetValue(Context, FMath::DegreesToRadians(GetValue(Context, &Degrees)), &Radians); } } void FMathConstantsDataflowNode::Evaluate(UE::Dataflow::FContext& Context, const FDataflowOutput* Out) const { if (Out->IsA(&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(&ReturnValue)) { const float InA = GetValue(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 Result = Evaluator.Evaluate(*ExpressionToEvaluate); if (Result.IsValid()) { FloatResult = FMath::Clamp((float)Result.GetValue(), TNumericLimits::Lowest(), TNumericLimits::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 EvalResult = Evaluator.Evaluate(*ExpressionToEvaluate); if (EvalResult.IsValid()) { Result = FMath::Clamp((double)EvalResult.GetValue(), TNumericLimits::Lowest(), TNumericLimits::Max()); } } SetValue(Context, Result, &ReturnValue); }