diff --git a/Source/Engine/Core/Math/Vector2.cs b/Source/Engine/Core/Math/Vector2.cs index 329253535..efbda7a42 100644 --- a/Source/Engine/Core/Math/Vector2.cs +++ b/Source/Engine/Core/Math/Vector2.cs @@ -832,7 +832,53 @@ namespace FlaxEngine value.Normalize(); return value; } - + + /// + /// Makes sure that Length of the output vector is always below max and above 0. + /// + /// Input Vector. + /// Max Length + public static Vector2 ClampLength(Vector2 vector, float max) + { + return ClampLength(vector, 0, max); + } + /// + /// Makes sure that Length of the output vector is always below max and above min. + /// + /// Input Vector. + /// Min Length + /// Max Length + public static Vector2 ClampLength(Vector2 vector, float min, float max) + { + ClampLength(ref vector, min, max, out Vector2 retVect); + return retVect; + } + /// + /// Makes sure that Length of the output vector is always below max and above min. + /// + /// Input Vector. + /// Min Length + /// Max Length + /// The Return Vector + public static void ClampLength(ref Vector2 vector, float min, float max, out Vector2 retVect) + { + retVect.X = vector.X; + retVect.Y = vector.Y; + + float lenSq = retVect.LengthSquared; + if (lenSq > max * max) + { + float scaleFactor = max / (float)Math.Sqrt(lenSq); + retVect.X = retVect.X * scaleFactor; + retVect.Y = retVect.Y * scaleFactor; + } + if (lenSq < min * min) + { + float scaleFactor = min / (float)Math.Sqrt(lenSq); + retVect.X = retVect.X * scaleFactor; + retVect.Y = retVect.Y * scaleFactor; + } + } /// /// Returns the vector with components rounded to the nearest integer. /// diff --git a/Source/Engine/Core/Math/Vector3.cs b/Source/Engine/Core/Math/Vector3.cs index e331142b9..b871c0642 100644 --- a/Source/Engine/Core/Math/Vector3.cs +++ b/Source/Engine/Core/Math/Vector3.cs @@ -991,7 +991,56 @@ namespace FlaxEngine value.Normalize(); return value; } - + + /// + /// Makes sure that Length of the output vector is always below max and above 0. + /// + /// Input Vector. + /// Max Length + public static Vector3 ClampLength(Vector3 vector, float max) + { + return ClampLength(vector, 0, max); + } + /// + /// Makes sure that Length of the output vector is always below max and above min. + /// + /// Input Vector. + /// Min Length + /// Max Length + public static Vector3 ClampLength(Vector3 vector, float min, float max) + { + ClampLength(ref vector, min, max, out Vector3 retVect); + return retVect; + } + /// + /// Makes sure that Length of the output vector is always below max and above min. + /// + /// Input Vector. + /// Min Length + /// Max Length + /// The Return Vector + public static void ClampLength(ref Vector3 vector, float min, float max, out Vector3 retVect) + { + retVect.X = vector.X; + retVect.Y = vector.Y; + retVect.Z = vector.Z; + + float lenSq = retVect.LengthSquared; + if (lenSq > max * max) + { + float scaleFactor = max / (float)Math.Sqrt(lenSq); + retVect.X = retVect.X * scaleFactor; + retVect.Y = retVect.Y * scaleFactor; + retVect.Z = retVect.Z * scaleFactor; + } + if (lenSq < min * min) + { + float scaleFactor = min / (float)Math.Sqrt(lenSq); + retVect.X = retVect.X * scaleFactor; + retVect.Y = retVect.Y * scaleFactor; + retVect.Z = retVect.Z * scaleFactor; + } + } /// /// Performs a linear interpolation between two vectors. /// diff --git a/Source/Engine/Core/Math/Vector4.cs b/Source/Engine/Core/Math/Vector4.cs index 38c77e705..d01214de3 100644 --- a/Source/Engine/Core/Math/Vector4.cs +++ b/Source/Engine/Core/Math/Vector4.cs @@ -792,6 +792,58 @@ namespace FlaxEngine return value; } + /// + /// Makes sure that Length of the output vector is always below max and above 0. + /// + /// Input Vector. + /// Max Length + public static Vector4 ClampLength(Vector4 vector, float max) + { + return ClampLength(vector, 0, max); + } + /// + /// Makes sure that Length of the output vector is always below max and above min. + /// + /// Input Vector. + /// Min Length + /// Max Length + public static Vector4 ClampLength(Vector4 vector, float min, float max) + { + ClampLength(ref vector, min, max, out Vector4 retVect); + return retVect; + } + /// + /// Makes sure that Length of the output vector is always below max and above min. + /// + /// Input Vector. + /// Min Length + /// Max Length + /// The Return Vector + public static void ClampLength(ref Vector4 vector, float min, float max, out Vector4 retVect) + { + retVect.X = vector.X; + retVect.Y = vector.Y; + retVect.Z = vector.Z; + retVect.W = vector.W; + + float lenSq = retVect.LengthSquared; + if (lenSq > max * max) + { + float scaleFactor = max / (float)Math.Sqrt(lenSq); + retVect.X = retVect.X * scaleFactor; + retVect.Y = retVect.Y * scaleFactor; + retVect.Z = retVect.Z * scaleFactor; + retVect.W = retVect.W * scaleFactor; + } + if (lenSq < min * min) + { + float scaleFactor = min / (float)Math.Sqrt(lenSq); + retVect.X = retVect.X * scaleFactor; + retVect.Y = retVect.Y * scaleFactor; + retVect.Z = retVect.Z * scaleFactor; + retVect.W = retVect.W * scaleFactor; + } + } /// /// Performs a linear interpolation between two vectors. ///