27 #include "Kismet/BlueprintFunctionLibrary.h"
29 #include "Kismet/KismetMathLibrary.h"
31 #include "Math/RandomStream.h"
39 #include "RRMathUtils.generated.h"
48 class RAPYUTASIMULATIONPLUGINS_API
URRMathUtils :
public UBlueprintFunctionLibrary
80 while (InBitFlags != 0)
84 OutStack.Add((T)FBitSet::GetAndClearNextBit(InBitFlags));
116 static constexpr
float OVER_MAG_PERCENT = 1.01f;
118 const float maxExtraMagnitude = OVER_MAG_PERCENT * FMath::Square(InMaxMagnitude);
120 return (maxExtraMagnitude > 0.f) &&
122 (b2D ? (InVector.SizeSquared2D() > maxExtraMagnitude) : (InVector.SizeSquared() > maxExtraMagnitude));
150 InVector = InVector.GetClampedToMaxSize2D(InMaxMagnitude);
158 InVector = InVector.GetClampedToMaxSize(InMaxMagnitude);
186 if (IsVectorExceedingMaxMagnitude(InVector, InMaxMagnitude, b2D))
190 SetVectorClampedToMaxMagnitude(InVector, InMaxMagnitude, b2D);
220 InRotator = FRotator(ClampAngle(InRotator.Pitch, InMaxAngles.Pitch),
222 ClampAngle(InRotator.Yaw, InMaxAngles.Yaw),
224 ClampAngle(InRotator.Roll, InMaxAngles.Roll));
246 FORCEINLINE
static T
ClampAngle(T InAngle,
const T InMaxAngle)
252 InAngle = FMath::Fmod(InAngle, 360.f);
256 return FMath::Clamp(InAngle, -InMaxAngle, InMaxAngle);
272 static void InitializeRandomStream();
296 return (InArray.Num() > 0) ? InArray[GetRandomIntegerInRange(0, InArray.Num() - 1)] : T();
318 return RandomStream.GetFraction();
340 const float bias = GetRandomBias();
342 return (bias > 0.f) && (bias <= InBias);
362 FORCEINLINE
static bool IsBiased(
float InMinBias,
float InMaxBias)
366 return FMath::IsWithin(GetRandomBias(), InMinBias, InMaxBias);
386 return (GetRandomBias() >= 0.5f);
410 return RandomStream.FRandRange(InValueA, InValueB);
432 return RandomStream.FRandRange(InValueRange.X, InValueRange.Y);
456 return RandomStream.RandRange(InValueA, InValueB);
478 return RandomStream.RandRange(0, InValueMax);
500 return RandomStream.RandRange(InValueRange.X, InValueRange.Y);
520 FORCEINLINE
static FVector
GetRandomLocation(
const FVector& InLocationA,
const FVector& InLocationB)
524 return FVector(GetRandomFloatInRange(InLocationA.X, InLocationB.X),
526 GetRandomFloatInRange(InLocationA.Y, InLocationB.Y),
528 GetRandomFloatInRange(InLocationA.Z, InLocationB.Z));
554 const float u1 = GetRandomBias();
556 const float u2 = GetRandomFloatInRange(0.f, UE_TWO_PI);
558 const float u3 = GetRandomFloatInRange(0.f, UE_TWO_PI);
560 const float sqrt_u1 = FMath::Sqrt(u1);
562 const float sqrt_1_u1 = FMath::Sqrt(1 - u1);
566 const float w = sqrt_1_u1 * FMath::Sin(u2);
568 const float x = sqrt_1_u1 * FMath::Cos(u2);
570 const float y = sqrt_u1 * FMath::Sin(u3);
572 const float z = sqrt_u1 * FMath::Cos(u3);
576 return FQuat(x, y, z, w);
596 return GetRandomFloatInRange(0.f, 360.f);
620 return GetRandomFloatInRange(-InMaxExtent, InMaxExtent);
642 static FVector GetRandomSphericalPosition(
const FVector& InCenter,
644 const FVector2f& InDistanceRange,
646 const FVector2f& InHeightRange);
664 FLinearColor color(GetRandomYawInDegrees(),
668 GetRandomFloatInRange(InMin, 1.f));
672 return color.HSVToLinearRGB();
694 FLinearColor color(GetRandomFloatInRange(InHSVRange[0].
X, InHSVRange[0].
Y),
696 GetRandomFloatInRange(InHSVRange[1].
X, InHSVRange[1].
Y),
698 GetRandomFloatInRange(InHSVRange[2].
X, InHSVRange[2].
Y));
702 return color.HSVToLinearRGB();
722 return FLinearColor(GetRandomBias(), GetRandomBias(), GetRandomBias(), GetRandomBias());
744 FORCEINLINE
static bool StepUpdate(
double& current,
const double target,
const double step,
const double tolerance)
748 bool reached =
false;
750 double diff = target - current;
752 double absStep = FMath::Abs(step);
754 double signedStep = diff > 0 ? absStep : -absStep;
756 if (FMath::Abs(diff) <= absStep ||
758 FMath::Abs(diff) <= FMath::Abs(tolerance) ||
760 (signedStep > 0 && diff < 0) || (signedStep < 0 && diff > 0)
776 current += signedStep;
804 FORCEINLINE
static bool StepUpdateAngle(
double& current,
const double target,
const double step,
const double tolerance)
808 bool reached =
false;
810 double currentNormalized = FRotator::NormalizeAxis(current);
812 const double targetNormalized = FRotator::NormalizeAxis(target);
814 double diff = FRotator::NormalizeAxis(targetNormalized - currentNormalized);
816 double absStep = FMath::Abs(step);
818 double signedStep = diff > 0 ? absStep : -absStep;
820 if (FMath::Abs(diff) <= absStep ||
822 FMath::Abs(diff) <= FMath::Abs(tolerance) ||
824 (signedStep > 0 && diff < 0) || (signedStep < 0 && diff > 0)
830 currentNormalized = targetNormalized;
840 currentNormalized += signedStep;
842 currentNormalized = FRotator::NormalizeAxis(currentNormalized);
848 current = currentNormalized;
879 float dot = FMath::RadiansToDegrees(FMath::Acos(FVector::DotProduct(Vector1, Vector2)));
881 FVector cross = FVector::CrossProduct(Vector1, Vector2);
883 return UKismetMathLibrary::RotatorFromAxisAndAngle(cross, dot);