RapyutaSimulationPlugins
RRMathUtils.h
Go to the documentation of this file.
1 
15 #pragma once
16 
17 
18 
19 // Native
20 
21 #include "math.h"
22 
23 
24 
25 // UE
26 
27 #include "Kismet/BlueprintFunctionLibrary.h"
28 
29 #include "Kismet/KismetMathLibrary.h"
30 
31 #include "Math/RandomStream.h"
32 
33 //#include "Math/UnrealMath.h"
34 
35 //#include "GenericPlatform/GenericPlatformMath.h"
36 
37 
38 
39 #include "RRMathUtils.generated.h"
40 
41 
42 
43 
48 class RAPYUTASIMULATIONPLUGINS_API URRMathUtils : public UBlueprintFunctionLibrary
49 
50 {
51 
52 
53 
54 public:
55 
72  template<typename T>
73 
74  FORCEINLINE static void BitFlagsToStack(uint32 InBitFlags, TArray<T>& OutStack)
75 
76  {
77 
78  OutStack.Reset();
79 
80  while (InBitFlags != 0)
81 
82  {
83 
84  OutStack.Add((T)FBitSet::GetAndClearNextBit(InBitFlags));
85 
86  }
87 
88  }
89 
90 
91 
92  // VECTOR --
93 
94  // These are mostly for Velocity handling, which is inherently 3D FVector
95 
110  FORCEINLINE static bool IsVectorExceedingMaxMagnitude(const FVector& InVector, float InMaxMagnitude, bool b2D)
111 
112  {
113 
114  // Give 1% error tolerance, to account for numeric imprecision
115 
116  static constexpr float OVER_MAG_PERCENT = 1.01f;
117 
118  const float maxExtraMagnitude = OVER_MAG_PERCENT * FMath::Square(InMaxMagnitude);
119 
120  return (maxExtraMagnitude > 0.f) &&
121 
122  (b2D ? (InVector.SizeSquared2D() > maxExtraMagnitude) : (InVector.SizeSquared() > maxExtraMagnitude));
123 
124  }
125 
126 
127 
142  FORCEINLINE static void SetVectorClampedToMaxMagnitude(FVector& InVector, float InMaxMagnitude, bool b2D)
143 
144  {
145 
146  if (b2D)
147 
148  {
149 
150  InVector = InVector.GetClampedToMaxSize2D(InMaxMagnitude);
151 
152  }
153 
154  else
155 
156  {
157 
158  InVector = InVector.GetClampedToMaxSize(InMaxMagnitude);
159 
160  }
161 
162  }
163 
164 
165 
182  FORCEINLINE static bool ClampVectorToMaxMagnitude(FVector& InVector, float InMaxMagnitude, bool b2D)
183 
184  {
185 
186  if (IsVectorExceedingMaxMagnitude(InVector, InMaxMagnitude, b2D))
187 
188  {
189 
190  SetVectorClampedToMaxMagnitude(InVector, InMaxMagnitude, b2D);
191 
192  return true;
193 
194  }
195 
196  return false;
197 
198  }
199 
200 
201 
216  FORCEINLINE static void ClampRotatorToMaxAngles(FRotator& InRotator, const FRotator& InMaxAngles)
217 
218  {
219 
220  InRotator = FRotator(ClampAngle(InRotator.Pitch, InMaxAngles.Pitch),
221 
222  ClampAngle(InRotator.Yaw, InMaxAngles.Yaw),
223 
224  ClampAngle(InRotator.Roll, InMaxAngles.Roll));
225 
226  }
227 
228 
229 
244  template<typename T>
245 
246  FORCEINLINE static T ClampAngle(T InAngle, const T InMaxAngle)
247 
248  {
249 
250  // returns Angle in the range (-360,360)
251 
252  InAngle = FMath::Fmod(InAngle, 360.f);
253 
254  // Both FRotator::ClampAxis() and NormalizeAxis() could possible change the sign of InAngle so not used here
255 
256  return FMath::Clamp(InAngle, -InMaxAngle, InMaxAngle);
257 
258  }
259 
260 
261 
262  // RANDOM GENERATOR --
263 
272  static void InitializeRandomStream();
273 
274 
275 
290  template<typename T>
291 
292  FORCEINLINE static T GetRandomElement(const TArray<T>& InArray)
293 
294  {
295 
296  return (InArray.Num() > 0) ? InArray[GetRandomIntegerInRange(0, InArray.Num() - 1)] : T();
297 
298  }
299 
300 
301 
303 
314  FORCEINLINE static float GetRandomBias()
315 
316  {
317 
318  return RandomStream.GetFraction();
319 
320  }
321 
322 
323 
336  FORCEINLINE static bool IsBiased(float InBias)
337 
338  {
339 
340  const float bias = GetRandomBias();
341 
342  return (bias > 0.f) && (bias <= InBias);
343 
344  }
345 
346 
347 
362  FORCEINLINE static bool IsBiased(float InMinBias, float InMaxBias)
363 
364  {
365 
366  return FMath::IsWithin(GetRandomBias(), InMinBias, InMaxBias);
367 
368  }
369 
370 
371 
382  FORCEINLINE static bool GetRandomBool()
383 
384  {
385 
386  return (GetRandomBias() >= 0.5f);
387 
388  }
389 
390 
391 
406  FORCEINLINE static float GetRandomFloatInRange(float InValueA, float InValueB)
407 
408  {
409 
410  return RandomStream.FRandRange(InValueA, InValueB);
411 
412  }
413 
414 
415 
428  FORCEINLINE static float GetRandomFloatInRange(const FVector2f& InValueRange)
429 
430  {
431 
432  return RandomStream.FRandRange(InValueRange.X, InValueRange.Y);
433 
434  }
435 
436 
437 
452  FORCEINLINE static int32 GetRandomIntegerInRange(int32 InValueA, int32 InValueB)
453 
454  {
455 
456  return RandomStream.RandRange(InValueA, InValueB);
457 
458  }
459 
460 
461 
474  FORCEINLINE static int32 GetRandomIntegerInRange(int32 InValueMax)
475 
476  {
477 
478  return RandomStream.RandRange(0, InValueMax);
479 
480  }
481 
482 
483 
496  FORCEINLINE static int32 GetRandomIntegerInRange(const FIntPoint& InValueRange)
497 
498  {
499 
500  return RandomStream.RandRange(InValueRange.X, InValueRange.Y);
501 
502  }
503 
504 
505 
520  FORCEINLINE static FVector GetRandomLocation(const FVector& InLocationA, const FVector& InLocationB)
521 
522  {
523 
524  return FVector(GetRandomFloatInRange(InLocationA.X, InLocationB.X),
525 
526  GetRandomFloatInRange(InLocationA.Y, InLocationB.Y),
527 
528  GetRandomFloatInRange(InLocationA.Z, InLocationB.Z));
529 
530  }
531 
532 
533 
550  FORCEINLINE static FQuat GetRandomOrientation()
551 
552  {
553 
554  const float u1 = GetRandomBias();
555 
556  const float u2 = GetRandomFloatInRange(0.f, UE_TWO_PI);
557 
558  const float u3 = GetRandomFloatInRange(0.f, UE_TWO_PI);
559 
560  const float sqrt_u1 = FMath::Sqrt(u1);
561 
562  const float sqrt_1_u1 = FMath::Sqrt(1 - u1);
563 
564 
565 
566  const float w = sqrt_1_u1 * FMath::Sin(u2);
567 
568  const float x = sqrt_1_u1 * FMath::Cos(u2);
569 
570  const float y = sqrt_u1 * FMath::Sin(u3);
571 
572  const float z = sqrt_u1 * FMath::Cos(u3);
573 
574 
575 
576  return FQuat(x, y, z, w);
577 
578  }
579 
580 
581 
592  FORCEINLINE static float GetRandomYawInDegrees()
593 
594  {
595 
596  return GetRandomFloatInRange(0.f, 360.f);
597 
598  }
599 
600 
601 
616  FORCEINLINE static float GetRandomExtent(float InMaxExtent)
617 
618  {
619 
620  return GetRandomFloatInRange(-InMaxExtent, InMaxExtent);
621 
622  }
623 
624 
625 
642  static FVector GetRandomSphericalPosition(const FVector& InCenter,
643 
644  const FVector2f& InDistanceRange,
645 
646  const FVector2f& InHeightRange);
647 
648 
649 
660  FORCEINLINE static FLinearColor GetRandomColorFromHSV(const float InMin = 0.6f)
661 
662  {
663 
664  FLinearColor color(GetRandomYawInDegrees(), // Hue
665 
666  GetRandomBias(), // Saturation
667 
668  GetRandomFloatInRange(InMin, 1.f)); // Value
669 
670 
671 
672  return color.HSVToLinearRGB();
673 
674  }
675 
676 
677 
690  FORCEINLINE static FLinearColor GetRandomColorFromHSV(const TArray<FVector2D>& InHSVRange)
691 
692  {
693 
694  FLinearColor color(GetRandomFloatInRange(InHSVRange[0].X, InHSVRange[0].Y), // Hue
695 
696  GetRandomFloatInRange(InHSVRange[1].X, InHSVRange[1].Y), // Saturation
697 
698  GetRandomFloatInRange(InHSVRange[2].X, InHSVRange[2].Y)); // Value
699 
700 
701 
702  return color.HSVToLinearRGB();
703 
704  }
705 
706 
707 
718  FORCEINLINE static FLinearColor GetRandomColor()
719 
720  {
721 
722  return FLinearColor(GetRandomBias(), GetRandomBias(), GetRandomBias(), GetRandomBias());
723 
724  }
725 
726 
727 
744  FORCEINLINE static bool StepUpdate(double& current, const double target, const double step, const double tolerance)
745 
746  {
747 
748  bool reached = false;
749 
750  double diff = target - current;
751 
752  double absStep = FMath::Abs(step);
753 
754  double signedStep = diff > 0 ? absStep : -absStep;
755 
756  if (FMath::Abs(diff) <= absStep || //can reach target in step
757 
758  FMath::Abs(diff) <= FMath::Abs(tolerance) || //with in tolerance
759 
760  (signedStep > 0 && diff < 0) || (signedStep < 0 && diff > 0) //overshoot
761 
762  )
763 
764  {
765 
766  current = target;
767 
768  reached = true;
769 
770  }
771 
772  else
773 
774  {
775 
776  current += signedStep;
777 
778  }
779 
780 
781 
782  return reached;
783 
784  }
785 
786 
787 
804  FORCEINLINE static bool StepUpdateAngle(double& current, const double target, const double step, const double tolerance)
805 
806  {
807 
808  bool reached = false;
809 
810  double currentNormalized = FRotator::NormalizeAxis(current);
811 
812  const double targetNormalized = FRotator::NormalizeAxis(target);
813 
814  double diff = FRotator::NormalizeAxis(targetNormalized - currentNormalized);
815 
816  double absStep = FMath::Abs(step);
817 
818  double signedStep = diff > 0 ? absStep : -absStep;
819 
820  if (FMath::Abs(diff) <= absStep || //can reach target in step
821 
822  FMath::Abs(diff) <= FMath::Abs(tolerance) || //with in tolerance
823 
824  (signedStep > 0 && diff < 0) || (signedStep < 0 && diff > 0) //overshoot
825 
826  )
827 
828  {
829 
830  currentNormalized = targetNormalized;
831 
832  reached = true;
833 
834  }
835 
836  else
837 
838  {
839 
840  currentNormalized += signedStep;
841 
842  currentNormalized = FRotator::NormalizeAxis(currentNormalized);
843 
844  }
845 
846 
847 
848  current = currentNormalized;
849 
850  return reached;
851 
852  }
853 
854 
855 
875  static FRotator GetRotatorFromVectors(const FVector& Vector1, const FVector& Vector2)
876 
877  {
878 
879  float dot = FMath::RadiansToDegrees(FMath::Acos(FVector::DotProduct(Vector1, Vector2)));
880 
881  FVector cross = FVector::CrossProduct(Vector1, Vector2);
882 
883  return UKismetMathLibrary::RotatorFromAxisAndAngle(cross, dot);
884 
885  }
886 
887 
888 
889 private:
890 
891  static FRandomStream RandomStream;
892 
893 };
894 
URRMathUtils::IsBiased
static FORCEINLINE bool IsBiased(float InBias)
Check value get from GetRandomBias in [0, InBias].
Definition: RRMathUtils.h:336
URRMathUtils::GetRandomLocation
static FORCEINLINE FVector GetRandomLocation(const FVector &InLocationA, const FVector &InLocationB)
Get the Random Location between two vectors.
Definition: RRMathUtils.h:520
ERRJointAxisRotation::Y
@ Y
URRMathUtils::GetRandomYawInDegrees
static FORCEINLINE float GetRandomYawInDegrees()
Return a random number between [0, 360].
Definition: RRMathUtils.h:592
URRMathUtils::GetRandomFloatInRange
static FORCEINLINE float GetRandomFloatInRange(float InValueA, float InValueB)
Return an almost uniformly distributed float random number between 2 float values [Min,...
Definition: RRMathUtils.h:406
URRMathUtils::GetRandomIntegerInRange
static FORCEINLINE int32 GetRandomIntegerInRange(const FIntPoint &InValueRange)
Return an almost uniformly distributed int random number between FIntPoint.
Definition: RRMathUtils.h:496
URRMathUtils::GetRandomIntegerInRange
static FORCEINLINE int32 GetRandomIntegerInRange(int32 InValueMax)
Return an almost uniformly distributed Int random number between 2 int values [0, Max] by using.
Definition: RRMathUtils.h:474
URRMathUtils::GetRandomColorFromHSV
static FORCEINLINE FLinearColor GetRandomColorFromHSV(const float InMin=0.6f)
Get the Random Color From H S V object.
Definition: RRMathUtils.h:660
URRMathUtils::GetRandomColorFromHSV
static FORCEINLINE FLinearColor GetRandomColorFromHSV(const TArray< FVector2D > &InHSVRange)
Get the Random Color From H S V object.
Definition: RRMathUtils.h:690
URRMathUtils::StepUpdateAngle
static FORCEINLINE bool StepUpdateAngle(double &current, const double target, const double step, const double tolerance)
update current value with step to reach target within tolerance
Definition: RRMathUtils.h:804
URRMathUtils::GetRandomColor
static FORCEINLINE FLinearColor GetRandomColor()
Get the Random Color.
Definition: RRMathUtils.h:718
URRMathUtils::GetRandomIntegerInRange
static FORCEINLINE int32 GetRandomIntegerInRange(int32 InValueA, int32 InValueB)
Return an almost uniformly distributed int random number between FVector.
Definition: RRMathUtils.h:452
URRMathUtils::GetRandomBool
static FORCEINLINE bool GetRandomBool()
Check value get from GetRandomBias > 0.5.
Definition: RRMathUtils.h:382
URRMathUtils::IsBiased
static FORCEINLINE bool IsBiased(float InMinBias, float InMaxBias)
Check value get from GetRandomBias in [InMinBias, InMaxBias].
Definition: RRMathUtils.h:362
URRMathUtils::GetRandomElement
static FORCEINLINE T GetRandomElement(const TArray< T > &InArray)
Get the Random Element of given array.
Definition: RRMathUtils.h:292
URRMathUtils::GetRandomExtent
static FORCEINLINE float GetRandomExtent(float InMaxExtent)
Return a random number between [-InMaxExtent, InMaxExtent].
Definition: RRMathUtils.h:616
URRMathUtils::ClampAngle
static FORCEINLINE T ClampAngle(T InAngle, const T InMaxAngle)
Clamp an angle in a range [-InMaxAxisAngle, InMaxAxisAngle] with maximum values between (-360,...
Definition: RRMathUtils.h:246
URRMathUtils
Definition: RRMathUtils.h:48
URRMathUtils::SetVectorClampedToMaxMagnitude
static FORCEINLINE void SetVectorClampedToMaxMagnitude(FVector &InVector, float InMaxMagnitude, bool b2D)
Set a given vector's magnitude.
Definition: RRMathUtils.h:142
URRMathUtils::RandomStream
static FRandomStream RandomStream
Definition: RRMathUtils.h:891
URRMathUtils::GetRotatorFromVectors
static FRotator GetRotatorFromVectors(const FVector &Vector1, const FVector &Vector2)
Get the Rotator From Two vectors.
Definition: RRMathUtils.h:875
URRMathUtils::GetRandomBias
static FORCEINLINE float GetRandomBias()
Return an almost uniformly distributed float random number in [0, 1].
Definition: RRMathUtils.h:314
URRMathUtils::StepUpdate
static FORCEINLINE bool StepUpdate(double &current, const double target, const double step, const double tolerance)
update current value with step to reach target within tolerance
Definition: RRMathUtils.h:744
URRMathUtils::ClampVectorToMaxMagnitude
static FORCEINLINE bool ClampVectorToMaxMagnitude(FVector &InVector, float InMaxMagnitude, bool b2D)
Clamp a given vector's magnitude to its max magnitude.
Definition: RRMathUtils.h:182
URRMathUtils::IsVectorExceedingMaxMagnitude
static FORCEINLINE bool IsVectorExceedingMaxMagnitude(const FVector &InVector, float InMaxMagnitude, bool b2D)
Check if a vector's magnitude exceeds a given max value.
Definition: RRMathUtils.h:110
URRMathUtils::BitFlagsToStack
static FORCEINLINE void BitFlagsToStack(uint32 InBitFlags, TArray< T > &OutStack)
Convert uint32 BitFlags to TArray.
Definition: RRMathUtils.h:74
URRMathUtils::ClampRotatorToMaxAngles
static FORCEINLINE void ClampRotatorToMaxAngles(FRotator &InRotator, const FRotator &InMaxAngles)
Clamp a given rotator to its max axis angles.
Definition: RRMathUtils.h:216
URRMathUtils::GetRandomOrientation
static FORCEINLINE FQuat GetRandomOrientation()
Get uniformly distributed random quaternion.
Definition: RRMathUtils.h:550
ERRJointAxisRotation::X
@ X
URRMathUtils::GetRandomFloatInRange
static FORCEINLINE float GetRandomFloatInRange(const FVector2f &InValueRange)
Return an almost uniformly distributed float random number between FVector.
Definition: RRMathUtils.h:428