diff --git a/Source/Engine/Core/Math/Vector2.cs b/Source/Engine/Core/Math/Vector2.cs index 3f63c4e9c..77c52035d 100644 --- a/Source/Engine/Core/Math/Vector2.cs +++ b/Source/Engine/Core/Math/Vector2.cs @@ -954,6 +954,33 @@ namespace FlaxEngine return result; } + /// + /// Performs a spherical linear interpolation between two vectors. + /// + /// Start vector. + /// End vector. + /// Value between 0 and 1 indicating the weight of . + /// >When the method completes, contains the linear interpolation of the two vectors. + public static void Slerp(ref Vector2 start, ref Vector2 end, float amount, out Vector2 result) + { + var dot = Mathr.Clamp(Dot(start, end), -1.0f, 1.0f); + var theta = Mathr.Acos(dot) * amount; + Vector2 relativeVector = (end - start * dot).Normalized; + result = ((start * Mathr.Cos(theta)) + (relativeVector * Mathr.Sin(theta))); + } + + /// + /// Performs a spherical linear interpolation between two vectors. + /// + /// Start vector. + /// End vector. + /// Value between 0 and 1 indicating the weight of . + public static Vector2 Slerp(Vector2 start, Vector2 end, float amount) + { + Slerp(ref start, ref end, amount, out Vector2 result); + return result; + } + /// /// Performs a gradual change of a vector towards a specified target over time /// diff --git a/Source/Engine/Core/Math/Vector2.h b/Source/Engine/Core/Math/Vector2.h index 34bd1a59c..cee013840 100644 --- a/Source/Engine/Core/Math/Vector2.h +++ b/Source/Engine/Core/Math/Vector2.h @@ -558,6 +558,24 @@ public: return result; } + // Performs a spherical linear interpolation between two vectors. + static void Slerp(const Vector2Base& start, const Vector2Base& end, T amount, Vector2Base& result) + { + T dot = Math::Clamp(Dot(start, end), -1.0f, 1.0f); + T theta = Math::Acos(dot) * amount; + Vector2Base relativeVector = end - start * dot; + relativeVector.Normalize(); + result = ((start * Math::Cos(theta)) + (relativeVector * Math::Sin(theta))); + } + + // Performs a spherical linear interpolation between two vectors. + static Vector2Base Slerp(const Vector2Base& start, const Vector2Base& end, T amount) + { + Vector2Base result; + Slerp(start, end, amount, result); + return result; + } + public: /// /// Calculates the area of the triangle. diff --git a/Source/Engine/Core/Math/Vector3.cs b/Source/Engine/Core/Math/Vector3.cs index 388317810..ce7492e55 100644 --- a/Source/Engine/Core/Math/Vector3.cs +++ b/Source/Engine/Core/Math/Vector3.cs @@ -1043,6 +1043,33 @@ namespace FlaxEngine return result; } + /// + /// Performs a spherical linear interpolation between two vectors. + /// + /// Start vector. + /// End vector. + /// Value between 0 and 1 indicating the weight of . + /// When the method completes, contains the linear interpolation of the two vectors. + public static void Slerp(ref Vector3 start, ref Vector3 end, float amount, out Vector3 result) + { + var dot = Mathr.Clamp(Dot(start, end), -1.0f, 1.0f); + var theta = Mathr.Acos(dot) * amount; + Vector3 relativeVector = (end - start * dot).Normalized; + result = ((start * Mathr.Cos(theta)) + (relativeVector * Mathr.Sin(theta))); + } + + /// + /// Performs a spherical linear interpolation between two vectors. + /// + /// Start vector. + /// End vector. + /// Value between 0 and 1 indicating the weight of . + public static Vector3 Slerp(Vector3 start, Vector3 end, float amount) + { + Slerp(ref start, ref end, amount, out var result); + return result; + } + /// /// Performs a gradual change of a vector towards a specified target over time /// diff --git a/Source/Engine/Core/Math/Vector3.h b/Source/Engine/Core/Math/Vector3.h index a19253b00..bf737877b 100644 --- a/Source/Engine/Core/Math/Vector3.h +++ b/Source/Engine/Core/Math/Vector3.h @@ -686,6 +686,24 @@ public: return result; } + // Performs a spherical linear interpolation between two vectors. + static void Slerp(const Vector3Base& start, const Vector3Base& end, T amount, Vector3Base& result) + { + T dot = Math::Clamp(Dot(start, end), -1.0f, 1.0f); + T theta = Math::Acos(dot) * amount; + Vector3Base relativeVector = end - start * dot; + relativeVector.Normalize(); + result = ((start * Math::Cos(theta)) + (relativeVector * Math::Sin(theta))); + } + + // Performs a spherical linear interpolation between two vectors. + static Vector3Base Slerp(const Vector3Base& start, const Vector3Base& end, T amount) + { + Vector3Base result; + Slerp(start, end, amount, result); + return result; + } + // Performs a cubic interpolation between two vectors. static void SmoothStep(const Vector3Base& start, const Vector3Base& end, T amount, Vector3Base& result) { diff --git a/Source/Engine/Core/Math/Vector4.cs b/Source/Engine/Core/Math/Vector4.cs index 776bbd3dc..b08a08f50 100644 --- a/Source/Engine/Core/Math/Vector4.cs +++ b/Source/Engine/Core/Math/Vector4.cs @@ -891,6 +891,33 @@ namespace FlaxEngine return result; } + /// + /// Performs a spherical linear interpolation between two vectors. + /// + /// Start vector. + /// End vector. + /// Value between 0 and 1 indicating the weight of . + /// When the method completes, contains the linear interpolation of the two vectors. + public static void Slerp(ref Vector4 start, ref Vector4 end, Real amount, out Vector4 result) + { + var dot = Mathr.Clamp(Dot(start, end), -1.0f, 1.0f); + var theta = Mathr.Acos(dot) * amount; + Vector4 relativeVector = (end - start * dot).Normalized; + result = ((start * Mathr.Cos(theta)) + (relativeVector * Mathr.Sin(theta))); + } + + /// + /// Performs a spherical linear interpolation between two vectors. + /// + /// Start vector. + /// End vector. + /// Value between 0 and 1 indicating the weight of . + public static Vector4 Slerp(Vector4 start, Vector4 end, Real amount) + { + Slerp(ref start, ref end, amount, out var result); + return result; + } + /// /// Performs a cubic interpolation between two vectors. /// diff --git a/Source/Engine/Core/Math/Vector4.h b/Source/Engine/Core/Math/Vector4.h index 91743ad73..5f5e436ad 100644 --- a/Source/Engine/Core/Math/Vector4.h +++ b/Source/Engine/Core/Math/Vector4.h @@ -566,6 +566,24 @@ public: return result; } + // Performs a spherical linear interpolation between two vectors. + static void Slerp(const Vector4Base& start, const Vector4Base& end, T amount, Vector4Base& result) + { + T dot = Math::Clamp(Dot(start, end), -1.0f, 1.0f); + T theta = Math::Acos(dot) * amount; + Vector4Base relativeVector = end - start * dot; + relativeVector.Normalize(); + result = ((start * Math::Cos(theta)) + (relativeVector * Math::Sin(theta))); + } + + // Performs a spherical linear interpolation between two vectors. + static Vector4Base Slerp(const Vector4Base& start, const Vector4Base& end, T amount) + { + Vector4Base result; + Slerp(start, end, amount, result); + return result; + } + FLAXENGINE_API static Vector4Base Transform(const Vector4Base& v, const Matrix& m); };