From 2f792f17b9bfb0ae164c69b61d63fcb93f7a92b0 Mon Sep 17 00:00:00 2001 From: Tornado Tech <54727692+Tornado-Technology@users.noreply.github.com> Date: Thu, 29 Aug 2024 08:35:17 +1000 Subject: [PATCH 01/15] Update vector2 Updating the vector according to the given pattern https://github.com/technologists-team/hypercube/issues/51 --- Hypercube.Mathematics/Vectors/Vector2.cs | 161 +++++++++++++++++++---- 1 file changed, 139 insertions(+), 22 deletions(-) diff --git a/Hypercube.Mathematics/Vectors/Vector2.cs b/Hypercube.Mathematics/Vectors/Vector2.cs index 68ac147..043793e 100644 --- a/Hypercube.Mathematics/Vectors/Vector2.cs +++ b/Hypercube.Mathematics/Vectors/Vector2.cs @@ -9,6 +9,8 @@ namespace Hypercube.Mathematics.Vectors; public readonly partial struct Vector2 : IEquatable { public static readonly Vector2 NaN = new(float.NaN, float.NaN); + public static readonly Vector2 PositiveInfinity = new(float.PositiveInfinity, float.PositiveInfinity); + public static readonly Vector2 NegativeInfinity = new(float.NegativeInfinity, float.NegativeInfinity); public static readonly Vector2 Zero = new(0, 0); public static readonly Vector2 One = new(1, 1); @@ -47,7 +49,33 @@ public float Angle [MethodImpl(MethodImplOptions.AggressiveInlining)] get => MathF.Atan2(Y, X); } + + public float Summation + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get => X + Y; + } + + public float Production + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get => X * Y; + } + public float this[int index] + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get + { + return index switch + { + 0 => X, + 1 => Y, + _ => throw new ArgumentOutOfRangeException() + }; + } + } + public Vector2(float x, float y) { X = x; @@ -90,29 +118,24 @@ public Vector2 WithY(float value) return new Vector2(X, value); } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public Vector2 Rotate(float angle) - { - var cos = MathF.Cos(angle); - var sin = MathF.Sin(angle); - - return new Vector2( - cos * X - sin * Y, - sin * X + cos * Y); - } - [MethodImpl(MethodImplOptions.AggressiveInlining)] public float DistanceSquared(Vector2 other) { return (this - other).LengthSquared; } - + [MethodImpl(MethodImplOptions.AggressiveInlining)] public float Distance(Vector2 other) { return MathF.Sqrt(DistanceSquared(this, other)); } - + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public float Cross(Vector2 other) + { + return Cross(this, other); + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public float Dot(Vector2 other) { @@ -120,11 +143,57 @@ public float Dot(Vector2 other) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public float Cross(Vector2 other) + public Vector2 Max(Vector2 other) { - return Cross(this, other); + return Max(this, other); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Vector2 Min(Vector2 other) + { + return Min(this, other); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Vector2 Abs() + { + return Abs(this); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Vector2 Round() + { + return Round(this); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Vector2 Round(int digits) + { + return Round(this, digits); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Vector2 Ceiling() + { + return Ceiling(this); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Vector2 Floor() + { + return Floor(this); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Vector2 Rotate(float angle) + { + var cos = MathF.Cos(angle); + var sin = MathF.Sin(angle); + return new Vector2( + cos * X - sin * Y, + sin * X + cos * Y); + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public bool Equals(Vector2 other) { @@ -251,7 +320,19 @@ public static float Distance(Vector2 a, Vector2 b) { return MathF.Sqrt(DistanceSquared(a, b)); } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static float Dot(Vector2 a, Vector2 b) + { + return a.X * b.X + a.Y * b.Y; + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static float Cross(Vector2 a, Vector2 b) + { + return a.X * b.Y - a.Y * b.X; + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector2 Max(Vector2 a, Vector2 b) { @@ -259,7 +340,7 @@ public static Vector2 Max(Vector2 a, Vector2 b) MathF.Max(a.X, b.X), MathF.Max(a.Y, b.Y)); } - + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector2 Min(Vector2 a, Vector2 b) { @@ -267,16 +348,52 @@ public static Vector2 Min(Vector2 a, Vector2 b) MathF.Min(a.X, b.X), MathF.Min(a.Y, b.Y)); } - + [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static float Dot(Vector2 a, Vector2 b) + public static Vector2 Abs(Vector2 vector) { - return a.X * b.X + a.Y * b.Y; + return new Vector2( + Math.Abs(vector.X), + Math.Abs(vector.Y)); } - + [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static float Cross(Vector2 a, Vector2 b) + public static Vector2 Round(Vector2 vector) { - return a.X * b.Y - a.Y * b.X; + return new Vector2( + Math.Round(vector.X), + Math.Round(vector.Y)); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector2 Round(Vector2 vector, int digits) + { + return new Vector2( + Math.Round(vector.X, digits), + Math.Round(vector.Y, digits)); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector2 Ceiling(Vector2 vector) + { + return new Vector2( + Math.Ceiling(vector.X), + Math.Ceiling(vector.Y)); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector2 Floor(Vector2 vector) + { + return new Vector2( + Math.Floor(vector.X), + Math.Floor(vector.Y)); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector2 Sign(Vector2 vector) + { + return new Vector2( + Math.Sign(vector.X), + Math.Sign(vector.Y)); } } \ No newline at end of file From df6a974d9786e385f9f768e5abba93bb9f50d6d7 Mon Sep 17 00:00:00 2001 From: Tornado Tech <54727692+Tornado-Technology@users.noreply.github.com> Date: Thu, 29 Aug 2024 08:41:39 +1000 Subject: [PATCH 02/15] Fix merge --- Hypercube.Client/Hypercube.Client.csproj | 1 + Hypercube.Mathematics/Vectors/Vector2.cs | 8 ++- Hypercube.UnitTests/Math/CompareToTest.cs | 79 +---------------------- 3 files changed, 10 insertions(+), 78 deletions(-) diff --git a/Hypercube.Client/Hypercube.Client.csproj b/Hypercube.Client/Hypercube.Client.csproj index eb18085..c62b34e 100644 --- a/Hypercube.Client/Hypercube.Client.csproj +++ b/Hypercube.Client/Hypercube.Client.csproj @@ -18,6 +18,7 @@ + diff --git a/Hypercube.Mathematics/Vectors/Vector2.cs b/Hypercube.Mathematics/Vectors/Vector2.cs index b7a8a1a..c24650b 100644 --- a/Hypercube.Mathematics/Vectors/Vector2.cs +++ b/Hypercube.Mathematics/Vectors/Vector2.cs @@ -6,7 +6,7 @@ namespace Hypercube.Mathematics.Vectors; [PublicAPI, StructLayout(LayoutKind.Sequential)] -public readonly partial struct Vector2 : IEquatable, IComparable +public readonly partial struct Vector2 : IEquatable, IComparable, IComparable { public static readonly Vector2 NaN = new(float.NaN, float.NaN); public static readonly Vector2 PositiveInfinity = new(float.PositiveInfinity, float.PositiveInfinity); @@ -199,6 +199,12 @@ public int CompareTo(Vector2 other) { return LengthSquared.CompareTo(other.LengthSquared); } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public int CompareTo(float other) + { + return LengthSquared.CompareTo(other * other); + } [MethodImpl(MethodImplOptions.AggressiveInlining)] public bool Equals(Vector2 other) diff --git a/Hypercube.UnitTests/Math/CompareToTest.cs b/Hypercube.UnitTests/Math/CompareToTest.cs index 6f716ee..9db32c0 100644 --- a/Hypercube.UnitTests/Math/CompareToTest.cs +++ b/Hypercube.UnitTests/Math/CompareToTest.cs @@ -1,6 +1,4 @@ -using System; -using Hypercube.Math.Vectors; -using NUnit.Framework; +using Hypercube.Mathematics.Vectors; namespace Hypercube.UnitTests.Math; @@ -18,79 +16,6 @@ public void CompareTo_LengthComparison_ReturnsExpectedResult() var result = vector1.CompareTo(vector2); // Assert - Assert.Less(result, 0); - } - - [Test] - public void CompareTo_XComponentComparison_ReturnsExpectedResult() - { - // Arrange - var vector1 = new Vector2(3, 4); - var vector2 = new Vector2(6, 4); - - // Act - var result = vector1.CompareTo(vector2, v => v.X); - - // Assert - Assert.Less(result, 0); // Expecting vector1 to be "less than" vector2 based on X component - } - - [Test] - public void CompareTo_YComponentComparison_ReturnsExpectedResult() - { - // Arrange - var vector1 = new Vector2(3, 4); - var vector2 = new Vector2(3, 2); - - // Act - var result = vector1.CompareTo(vector2, v => v.Y); - - // Assert - Assert.Greater(result, 0); // Expecting vector1 to be "greater than" vector2 based on Y component - } - - [Test] - public void CompareTo_AngleComparison_ReturnsExpectedResult() - { - // Arrange - var vector1 = new Vector2(0, 1); // Angle = π/2 (90 degrees) - var vector2 = new Vector2(1, 0); // Angle = 0 degrees - - // Act - var result = vector1.CompareTo(vector2, v => v.Angle); - - // Assert - Assert.Greater(result, 0); // Expecting vector1 to be "greater than" vector2 based on Angle - } - - [Test] - public void CompareTo_SameVectors_ReturnsZero() - { - // Arrange - var vector1 = new Vector2(3, 4); - var vector2 = new Vector2(3, 4); - - // Act & Assert - Assert.AreEqual(0, vector1.CompareTo(vector2)); - Assert.AreEqual(0, vector1.CompareTo(vector2, v => v.X)); - Assert.AreEqual(0, vector1.CompareTo(vector2, v => v.Y)); - Assert.AreEqual(0, vector1.CompareTo(vector2, v => v.Angle)); - } - - [Test] - public void CompareTo_DifferentComparisons_ReturnDifferentResults() - { - // Arrange - var vector1 = new Vector2(1, 2); - var vector2 = new Vector2(2, 1); - - // Act - var lengthComparison = vector1.CompareTo(vector2); - var xComponentComparison = vector1.CompareTo(vector2, v => v.X); - var yComponentComparison = vector1.CompareTo(vector2, v => v.Y); - - // Assert - Assert.AreNotEqual(lengthComparison, xComponentComparison); - Assert.AreNotEqual(xComponentComparison, yComponentComparison); + Assert.That(result, Is.LessThan(0)); } } \ No newline at end of file From c4d6b842d09192751f39300f444bfb085e33b961 Mon Sep 17 00:00:00 2001 From: Tornado Tech <54727692+Tornado-Technology@users.noreply.github.com> Date: Thu, 29 Aug 2024 09:08:10 +1000 Subject: [PATCH 03/15] Add lerp, clamp --- Hypercube.Mathematics/HyperMath.cs | 2 +- Hypercube.Mathematics/Vectors/Vector2.cs | 48 ++++++++++++++++++++++-- Hypercube.sln.DotSettings | 1 + 3 files changed, 47 insertions(+), 4 deletions(-) diff --git a/Hypercube.Mathematics/HyperMath.cs b/Hypercube.Mathematics/HyperMath.cs index 6b1c16a..e272ae5 100644 --- a/Hypercube.Mathematics/HyperMath.cs +++ b/Hypercube.Mathematics/HyperMath.cs @@ -2,7 +2,7 @@ public static class HyperMath { - public const double PI = System.Math.PI; + public const double PI = Math.PI; public const double PIOver2 = PI / 2; public const double PIOver4 = PI / 4; diff --git a/Hypercube.Mathematics/Vectors/Vector2.cs b/Hypercube.Mathematics/Vectors/Vector2.cs index c24650b..e312245 100644 --- a/Hypercube.Mathematics/Vectors/Vector2.cs +++ b/Hypercube.Mathematics/Vectors/Vector2.cs @@ -130,6 +130,12 @@ public float Distance(Vector2 other) return MathF.Sqrt(DistanceSquared(this, other)); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public float Dot(Vector2 other) + { + return Dot(this, other); + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public float Cross(Vector2 other) { @@ -137,11 +143,23 @@ public float Cross(Vector2 other) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public float Dot(Vector2 other) + public Vector2 Clamp(Vector2 min, Vector2 max) { - return Dot(this, other); + return Clamp(this, min, max); } - + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Vector2 Clamp(float min, float max) + { + return Clamp(this, min, max); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Vector2 Lerp(Vector2 vector, float amount) + { + return Lerp(this, vector, amount); + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public Vector2 Max(Vector2 other) { @@ -344,6 +362,30 @@ public static float Cross(Vector2 a, Vector2 b) { return a.X * b.Y - a.Y * b.X; } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector2 Lerp(Vector2 vectorA, Vector2 vectorB, float amount) + { + return new Vector2( + float.Lerp(vectorA.X, vectorB.X, amount), + float.Lerp(vectorA.Y, vectorB.Y, amount)); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector2 Clamp(Vector2 vector, Vector2 min, Vector2 max) + { + return new Vector2( + float.Clamp(vector.X, min.X, max.X), + float.Clamp(vector.Y, min.Y, max.Y)); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector2 Clamp(Vector2 vector, float min, float max) + { + return new Vector2( + float.Clamp(vector.X, min, max), + float.Clamp(vector.Y, min, max)); + } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector2 Max(Vector2 a, Vector2 b) diff --git a/Hypercube.sln.DotSettings b/Hypercube.sln.DotSettings index dd580fd..7aa78a7 100644 --- a/Hypercube.sln.DotSettings +++ b/Hypercube.sln.DotSettings @@ -1,2 +1,3 @@  + True True \ No newline at end of file From 858167cdb66b64c82bfa1d1588e94abe934d400a Mon Sep 17 00:00:00 2001 From: Tornado Tech <54727692+Tornado-Technology@users.noreply.github.com> Date: Thu, 29 Aug 2024 09:20:32 +1000 Subject: [PATCH 04/15] Add MoveTowards --- Hypercube.Mathematics/HyperMathF.cs | 7 +++++++ Hypercube.Mathematics/Vectors/Vector2.cs | 18 ++++++++++++++++-- 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/Hypercube.Mathematics/HyperMathF.cs b/Hypercube.Mathematics/HyperMathF.cs index 31aaa63..ffc547c 100644 --- a/Hypercube.Mathematics/HyperMathF.cs +++ b/Hypercube.Mathematics/HyperMathF.cs @@ -13,4 +13,11 @@ public static class HyperMathF public const float RadiansToDegrees = 180 / PI; public const float DegreesToRadians = PI / 180; + + public static float MoveTowards(float current, float target, float distance) + { + return current < target ? + MathF.Min(current + distance, target) : + MathF.Max(current - distance, target); + } } \ No newline at end of file diff --git a/Hypercube.Mathematics/Vectors/Vector2.cs b/Hypercube.Mathematics/Vectors/Vector2.cs index e312245..b0a06a3 100644 --- a/Hypercube.Mathematics/Vectors/Vector2.cs +++ b/Hypercube.Mathematics/Vectors/Vector2.cs @@ -202,6 +202,12 @@ public Vector2 Floor() return Floor(this); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Vector2 MoveTowards(Vector2 target, float distance) + { + return MoveTowards(this, target, distance); + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public Vector2 Rotate(float angle) { @@ -362,7 +368,15 @@ public static float Cross(Vector2 a, Vector2 b) { return a.X * b.Y - a.Y * b.X; } - + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector2 MoveTowards(Vector2 current, Vector2 target, float distance) + { + return new Vector2( + HyperMathF.MoveTowards(current.X, target.X, distance), + HyperMathF.MoveTowards(current.Y, target.Y, distance)); + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector2 Lerp(Vector2 vectorA, Vector2 vectorB, float amount) { @@ -370,7 +384,7 @@ public static Vector2 Lerp(Vector2 vectorA, Vector2 vectorB, float amount) float.Lerp(vectorA.X, vectorB.X, amount), float.Lerp(vectorA.Y, vectorB.Y, amount)); } - + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector2 Clamp(Vector2 vector, Vector2 min, Vector2 max) { From 4be4c0a774b05884149c9d4e136598367e07aa4a Mon Sep 17 00:00:00 2001 From: Tornado Tech <54727692+Tornado-Technology@users.noreply.github.com> Date: Thu, 29 Aug 2024 13:12:17 +1000 Subject: [PATCH 05/15] Update vector2 & add compare operators --- Hypercube.Mathematics/Vectors/Vector2.cs | 208 ++++++++++++++--------- 1 file changed, 128 insertions(+), 80 deletions(-) diff --git a/Hypercube.Mathematics/Vectors/Vector2.cs b/Hypercube.Mathematics/Vectors/Vector2.cs index b0a06a3..882d308 100644 --- a/Hypercube.Mathematics/Vectors/Vector2.cs +++ b/Hypercube.Mathematics/Vectors/Vector2.cs @@ -119,27 +119,27 @@ public Vector2 WithY(float value) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public float DistanceSquared(Vector2 other) + public float DistanceSquared(Vector2 value) { - return (this - other).LengthSquared; + return (this - value).LengthSquared; } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public float Distance(Vector2 other) + public float Distance(Vector2 value) { - return MathF.Sqrt(DistanceSquared(this, other)); + return MathF.Sqrt(DistanceSquared(this, value)); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public float Dot(Vector2 other) + public float Dot(Vector2 value) { - return Dot(this, other); + return Dot(this, value); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public float Cross(Vector2 other) + public float Cross(Vector2 value) { - return Cross(this, other); + return Cross(this, value); } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -155,21 +155,21 @@ public Vector2 Clamp(float min, float max) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public Vector2 Lerp(Vector2 vector, float amount) + public Vector2 Lerp(Vector2 value, float amount) { - return Lerp(this, vector, amount); + return Lerp(this, value, amount); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public Vector2 Max(Vector2 other) + public Vector2 Max(Vector2 value) { - return Max(this, other); + return Max(this, value); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public Vector2 Min(Vector2 other) + public Vector2 Min(Vector2 value) { - return Min(this, other); + return Min(this, value); } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -256,21 +256,21 @@ public override string ToString() } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Vector2 operator +(Vector2 a, Vector2 b) + public static Vector2 operator +(Vector2 a, Vector2 valueB) { - return new Vector2(a.X + b.X, a.Y + b.Y); + return new Vector2(a.X + valueB.X, a.Y + valueB.Y); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Vector2 operator +(float a, Vector2 b) + public static Vector2 operator +(float a, Vector2 valueB) { - return new Vector2(b.X + a, b.Y + a); + return new Vector2(valueB.X + a, valueB.Y + a); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Vector2 operator +(Vector2 a, float b) + public static Vector2 operator +(Vector2 a, float valueB) { - return new Vector2(a.X + b, a.Y + b); + return new Vector2(a.X + valueB, a.Y + valueB); } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -280,93 +280,141 @@ public override string ToString() } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Vector2 operator -(Vector2 a, Vector2 b) + public static Vector2 operator -(Vector2 a, Vector2 valueB) { - return new Vector2(a.X - b.X, a.Y - b.Y); + return new Vector2(a.X - valueB.X, a.Y - valueB.Y); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Vector2 operator -(float a, Vector2 b) + public static Vector2 operator -(float a, Vector2 valueB) { - return new Vector2(b.X - a, b.Y - a); + return new Vector2(valueB.X - a, valueB.Y - a); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Vector2 operator -(Vector2 a, float b) + public static Vector2 operator -(Vector2 a, float valueB) { - return new Vector2(a.X - b, a.Y - b); + return new Vector2(a.X - valueB, a.Y - valueB); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Vector2 operator *(Vector2 a, Vector2 b) + public static Vector2 operator *(Vector2 a, Vector2 valueB) { - return new Vector2(a.X * b.X, a.Y * b.Y); + return new Vector2(a.X * valueB.X, a.Y * valueB.Y); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Vector2 operator *(float a, Vector2 b) + public static Vector2 operator *(float a, Vector2 valueB) { - return new Vector2(b.X * a, b.Y * a); + return new Vector2(valueB.X * a, valueB.Y * a); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Vector2 operator *(Vector2 a, float b) + public static Vector2 operator *(Vector2 a, float valueB) { - return new Vector2(a.X * b, a.Y * b); + return new Vector2(a.X * valueB, a.Y * valueB); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Vector2 operator /(Vector2 a, Vector2 b) + public static Vector2 operator /(Vector2 a, Vector2 valueB) { - return new Vector2(a.X / b.X, a.Y / b.Y); + return new Vector2(a.X / valueB.X, a.Y / valueB.Y); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Vector2 operator /(float a, Vector2 b) + public static Vector2 operator /(float a, Vector2 valueB) { - return new Vector2(b.X / a, b.Y / a); + return new Vector2(valueB.X / a, valueB.Y / a); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Vector2 operator /(Vector2 a, float b) + public static Vector2 operator /(Vector2 a, float valueB) { - return new Vector2(a.X / b, a.Y / b); + return new Vector2(a.X / valueB, a.Y / valueB); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool operator ==(Vector2 a, Vector2 b) + public static bool operator ==(Vector2 a, Vector2 valueB) { - return a.Equals(b); + return a.Equals(valueB); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool operator !=(Vector2 a, Vector2 b) + public static bool operator !=(Vector2 a, Vector2 valueB) { - return !a.Equals(b); + return !a.Equals(valueB); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static float DistanceSquared(Vector2 a, Vector2 b) + public static bool operator <(Vector2 valueA, Vector2 valueB) { - return (a - b).LengthSquared; + return valueA.CompareTo(valueB) == -1; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool operator >(Vector2 valueA, Vector2 valueB) + { + return valueA.CompareTo(valueB) == 1; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool operator <=(Vector2 valueA, Vector2 valueB) + { + return valueA.CompareTo(valueB) is -1 or 0; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool operator >=(Vector2 valueA, Vector2 valueB) + { + return valueA.CompareTo(valueB) is 1 or 0; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool operator <(Vector2 valueA, int valueB) + { + return valueA.CompareTo(valueB) == -1; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool operator >(Vector2 valueA, int valueB) + { + return valueA.CompareTo(valueB) == 1; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool operator <=(Vector2 valueA, int valueB) + { + return valueA.CompareTo(valueB) is -1 or 0; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool operator >=(Vector2 valueA, int valueB) + { + return valueA.CompareTo(valueB) is 1 or 0; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static float DistanceSquared(Vector2 valueA, Vector2 valueB) + { + return (valueA - valueB).LengthSquared; } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static float Distance(Vector2 a, Vector2 b) + public static float Distance(Vector2 valueA, Vector2 valueB) { - return MathF.Sqrt(DistanceSquared(a, b)); + return MathF.Sqrt(DistanceSquared(valueA, valueB)); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static float Dot(Vector2 a, Vector2 b) + public static float Dot(Vector2 valueA, Vector2 valueB) { - return a.X * b.X + a.Y * b.Y; + return valueA.X * valueB.X + valueA.Y * valueB.Y; } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static float Cross(Vector2 a, Vector2 b) + public static float Cross(Vector2 valueA, Vector2 valueB) { - return a.X * b.Y - a.Y * b.X; + return valueA.X * valueB.Y - valueA.Y * valueB.X; } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -386,82 +434,82 @@ public static Vector2 Lerp(Vector2 vectorA, Vector2 vectorB, float amount) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Vector2 Clamp(Vector2 vector, Vector2 min, Vector2 max) + public static Vector2 Clamp(Vector2 value, Vector2 min, Vector2 max) { return new Vector2( - float.Clamp(vector.X, min.X, max.X), - float.Clamp(vector.Y, min.Y, max.Y)); + float.Clamp(value.X, min.X, max.X), + float.Clamp(value.Y, min.Y, max.Y)); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Vector2 Clamp(Vector2 vector, float min, float max) + public static Vector2 Clamp(Vector2 value, float min, float max) { return new Vector2( - float.Clamp(vector.X, min, max), - float.Clamp(vector.Y, min, max)); + float.Clamp(value.X, min, max), + float.Clamp(value.Y, min, max)); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Vector2 Max(Vector2 a, Vector2 b) + public static Vector2 Max(Vector2 valueA, Vector2 valueB) { return new Vector2( - MathF.Max(a.X, b.X), - MathF.Max(a.Y, b.Y)); + MathF.Max(valueA.X, valueB.X), + MathF.Max(valueA.Y, valueB.Y)); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Vector2 Min(Vector2 a, Vector2 b) + public static Vector2 Min(Vector2 valueA, Vector2 valueB) { return new Vector2( - MathF.Min(a.X, b.X), - MathF.Min(a.Y, b.Y)); + MathF.Min(valueA.X, valueB.X), + MathF.Min(valueA.Y, valueB.Y)); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Vector2 Abs(Vector2 vector) + public static Vector2 Abs(Vector2 value) { return new Vector2( - Math.Abs(vector.X), - Math.Abs(vector.Y)); + Math.Abs(value.X), + Math.Abs(value.Y)); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Vector2 Round(Vector2 vector) + public static Vector2 Round(Vector2 value) { return new Vector2( - Math.Round(vector.X), - Math.Round(vector.Y)); + Math.Round(value.X), + Math.Round(value.Y)); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Vector2 Round(Vector2 vector, int digits) + public static Vector2 Round(Vector2 value, int digits) { return new Vector2( - Math.Round(vector.X, digits), - Math.Round(vector.Y, digits)); + Math.Round(value.X, digits), + Math.Round(value.Y, digits)); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Vector2 Ceiling(Vector2 vector) + public static Vector2 Ceiling(Vector2 value) { return new Vector2( - Math.Ceiling(vector.X), - Math.Ceiling(vector.Y)); + Math.Ceiling(value.X), + Math.Ceiling(value.Y)); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Vector2 Floor(Vector2 vector) + public static Vector2 Floor(Vector2 value) { return new Vector2( - Math.Floor(vector.X), - Math.Floor(vector.Y)); + Math.Floor(value.X), + Math.Floor(value.Y)); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Vector2 Sign(Vector2 vector) + public static Vector2 Sign(Vector2 value) { return new Vector2( - Math.Sign(vector.X), - Math.Sign(vector.Y)); + Math.Sign(value.X), + Math.Sign(value.Y)); } } \ No newline at end of file From 7dd8017d41a60bdef91d6e2f37d996e0e1ad6d2e Mon Sep 17 00:00:00 2001 From: Tornado Tech <54727692+Tornado-Technology@users.noreply.github.com> Date: Thu, 29 Aug 2024 13:18:23 +1000 Subject: [PATCH 06/15] Added more vector2int properties --- Hypercube.Mathematics/Vectors/Vector2Int.cs | 50 +++++++++++++++++---- 1 file changed, 42 insertions(+), 8 deletions(-) diff --git a/Hypercube.Mathematics/Vectors/Vector2Int.cs b/Hypercube.Mathematics/Vectors/Vector2Int.cs index ab310c6..ae47f3f 100644 --- a/Hypercube.Mathematics/Vectors/Vector2Int.cs +++ b/Hypercube.Mathematics/Vectors/Vector2Int.cs @@ -19,7 +19,7 @@ namespace Hypercube.Mathematics.Vectors; public float AspectRatio { [MethodImpl(MethodImplOptions.AggressiveInlining)] - get => X / (float)Y; + get => X / (float) Y; } public float LengthSquared @@ -39,33 +39,67 @@ public Vector2Int Normalized [MethodImpl(MethodImplOptions.AggressiveInlining)] get => this / Length; } + + public float Angle + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get => MathF.Atan2(Y, X); + } - public Vector2Int(int x, int y) + public int Summation { - X = x; - Y = y; + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get => X + Y; + } + + public int Production + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get => X * Y; } - public Vector2Int(float x, float y) + public int this[int index] { - X = (int) x; - Y = (int) y; + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get + { + return index switch + { + 0 => X, + 1 => Y, + _ => throw new ArgumentOutOfRangeException() + }; + } } + public Vector2Int(int x, int y) + { + X = x; + Y = y; + } + public Vector2Int(int value) { X = value; Y = value; } + public Vector2Int(float x, float y) + { + X = (int) x; + Y = (int) y; + } + public Vector2Int(float value) { X = (int) value; Y = (int) value; } - public Vector2Int(Vector2Int vector2Int) : this(vector2Int.X, vector2Int.Y) + public Vector2Int(Vector2Int value) { + X = value.X; + Y = value.Y; } [MethodImpl(MethodImplOptions.AggressiveInlining)] From 4c31fa34bbfbf7594dcc0f242c0b187e5b2c7db3 Mon Sep 17 00:00:00 2001 From: Tornado Tech <54727692+Tornado-Technology@users.noreply.github.com> Date: Thu, 29 Aug 2024 13:24:18 +1000 Subject: [PATCH 07/15] Added more vector2int public & static methods --- Hypercube.Mathematics/Vectors/Vector2Int.cs | 158 +++++++++++++++++++- 1 file changed, 154 insertions(+), 4 deletions(-) diff --git a/Hypercube.Mathematics/Vectors/Vector2Int.cs b/Hypercube.Mathematics/Vectors/Vector2Int.cs index ae47f3f..477ab00 100644 --- a/Hypercube.Mathematics/Vectors/Vector2Int.cs +++ b/Hypercube.Mathematics/Vectors/Vector2Int.cs @@ -114,6 +114,76 @@ public Vector2Int WithY(int value) return new Vector2Int(X, value); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public float DistanceSquared(Vector2Int value) + { + return (this - value).LengthSquared; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public float Distance(Vector2Int value) + { + return MathF.Sqrt(DistanceSquared(this, value)); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public float Dot(Vector2Int value) + { + return Dot(this, value); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public float Cross(Vector2Int value) + { + return Cross(this, value); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Vector2Int Clamp(Vector2Int min, Vector2Int max) + { + return Clamp(this, min, max); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Vector2Int Clamp(int min, int max) + { + return Clamp(this, min, max); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Vector2Int Max(Vector2Int value) + { + return Max(this, value); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Vector2Int Min(Vector2Int value) + { + return Min(this, value); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Vector2Int Abs() + { + return Abs(this); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Vector2Int MoveTowards(Vector2Int target, int distance) + { + return MoveTowards(this, target, distance); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Vector2Int Rotate(float angle) + { + var cos = MathF.Cos(angle); + var sin = MathF.Sin(angle); + return new Vector2Int( + cos * X - sin * Y, + sin * X + cos * Y); + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public int CompareTo(int other) { @@ -194,9 +264,9 @@ public override string ToString() } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Vector2 operator *(Vector2Int a, float b) + public static Vector2Int operator *(Vector2Int a, float b) { - return new Vector2(a.X * b, a.Y * b); + return new Vector2Int(a.X * b, a.Y * b); } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -212,9 +282,9 @@ public override string ToString() } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Vector2 operator /(Vector2Int a, float b) + public static Vector2Int operator /(Vector2Int a, float b) { - return new Vector2(a.X / b, a.Y / b); + return new Vector2Int(a.X / b, a.Y / b); } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -276,4 +346,84 @@ public override string ToString() { return a.CompareTo(b) is 1 or 0; } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static float DistanceSquared(Vector2Int valueA, Vector2Int valueB) + { + return (valueA - valueB).LengthSquared; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static float Distance(Vector2Int valueA, Vector2Int valueB) + { + return MathF.Sqrt(DistanceSquared(valueA, valueB)); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static float Dot(Vector2Int valueA, Vector2Int valueB) + { + return valueA.X * valueB.X + valueA.Y * valueB.Y; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static float Cross(Vector2Int valueA, Vector2Int valueB) + { + return valueA.X * valueB.Y - valueA.Y * valueB.X; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector2Int MoveTowards(Vector2Int current, Vector2Int target, int distance) + { + return new Vector2Int( + HyperMathF.MoveTowards(current.X, target.X, distance), + HyperMathF.MoveTowards(current.Y, target.Y, distance)); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector2Int Clamp(Vector2Int value, Vector2Int min, Vector2Int max) + { + return new Vector2Int( + int.Clamp(value.X, min.X, max.X), + int.Clamp(value.Y, min.Y, max.Y)); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector2Int Clamp(Vector2Int value, int min, int max) + { + return new Vector2Int( + int.Clamp(value.X, min, max), + int.Clamp(value.Y, min, max)); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector2Int Max(Vector2Int valueA, Vector2Int valueB) + { + return new Vector2Int( + MathF.Max(valueA.X, valueB.X), + MathF.Max(valueA.Y, valueB.Y)); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector2Int Min(Vector2Int valueA, Vector2Int valueB) + { + return new Vector2Int( + MathF.Min(valueA.X, valueB.X), + MathF.Min(valueA.Y, valueB.Y)); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector2Int Abs(Vector2Int value) + { + return new Vector2Int( + Math.Abs(value.X), + Math.Abs(value.Y)); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector2Int Sign(Vector2Int value) + { + return new Vector2Int( + Math.Sign(value.X), + Math.Sign(value.Y)); + } } \ No newline at end of file From 8e8fc56ba91d562c6594fb535207c73170174259 Mon Sep 17 00:00:00 2001 From: Tornado Tech <54727692+Tornado-Technology@users.noreply.github.com> Date: Thu, 29 Aug 2024 14:41:28 +1000 Subject: [PATCH 08/15] Updated vectors & docs --- Hypercube.Mathematics/Matrices/Matrix4X4.cs | 49 ++--- Hypercube.Mathematics/Vectors/Vector2.cs | 112 ++++++++-- Hypercube.Mathematics/Vectors/Vector2Int.cs | 65 ++++-- Hypercube.Mathematics/Vectors/Vector3.cs | 232 ++++++++++++++++++-- Hypercube.Mathematics/Vectors/Vector4.cs | 196 ++++++++++++++--- Hypercube.sln.DotSettings | 2 + 6 files changed, 545 insertions(+), 111 deletions(-) diff --git a/Hypercube.Mathematics/Matrices/Matrix4X4.cs b/Hypercube.Mathematics/Matrices/Matrix4X4.cs index 2281851..687c290 100644 --- a/Hypercube.Mathematics/Matrices/Matrix4X4.cs +++ b/Hypercube.Mathematics/Matrices/Matrix4X4.cs @@ -320,38 +320,33 @@ public override string ToString() public static Matrix4X4 operator *(Matrix4X4 a, Matrix4X4 b) { - var result = Zero; - - result.M00 = (a.Row0 * b.Column0).Sum(); - result.M01 = (a.Row0 * b.Column1).Sum(); - result.M02 = (a.Row0 * b.Column2).Sum(); - result.M03 = (a.Row0 * b.Column3).Sum(); - - result.M10 = (a.Row1 * b.Column0).Sum(); - result.M11 = (a.Row1 * b.Column1).Sum(); - result.M12 = (a.Row1 * b.Column2).Sum(); - result.M13 = (a.Row1 * b.Column3).Sum(); - - result.M20 = (a.Row2 * b.Column0).Sum(); - result.M21 = (a.Row2 * b.Column1).Sum(); - result.M22 = (a.Row2 * b.Column2).Sum(); - result.M23 = (a.Row2 * b.Column3).Sum(); - - result.M30 = (a.Row3 * b.Column0).Sum(); - result.M31 = (a.Row3 * b.Column1).Sum(); - result.M32 = (a.Row3 * b.Column2).Sum(); - result.M33 = (a.Row3 * b.Column3).Sum(); - - return result; + return new Matrix4X4( + (a.Row0 * b.Column0).Summation, + (a.Row0 * b.Column1).Summation, + (a.Row0 * b.Column2).Summation, + (a.Row0 * b.Column3).Summation, + (a.Row1 * b.Column0).Summation, + (a.Row1 * b.Column1).Summation, + (a.Row1 * b.Column2).Summation, + (a.Row1 * b.Column3).Summation, + (a.Row2 * b.Column0).Summation, + (a.Row2 * b.Column1).Summation, + (a.Row2 * b.Column2).Summation, + (a.Row2 * b.Column3).Summation, + (a.Row3 * b.Column0).Summation, + (a.Row3 * b.Column1).Summation, + (a.Row3 * b.Column2).Summation, + (a.Row3 * b.Column3).Summation + ); } public static Vector4 operator *(Matrix4X4 a, Vector4 b) { return new Vector4( - (a.Row0 * b).Sum(), - (a.Row1 * b).Sum(), - (a.Row2 * b).Sum(), - (a.Row3 * b).Sum()); + (a.Row0 * b).Summation, + (a.Row1 * b).Summation, + (a.Row2 * b).Summation, + (a.Row3 * b).Summation); } public static bool operator ==(Matrix4X4 a, Matrix4X4 b) diff --git a/Hypercube.Mathematics/Vectors/Vector2.cs b/Hypercube.Mathematics/Vectors/Vector2.cs index 882d308..54707b6 100644 --- a/Hypercube.Mathematics/Vectors/Vector2.cs +++ b/Hypercube.Mathematics/Vectors/Vector2.cs @@ -1,43 +1,104 @@ -using System.Runtime.CompilerServices; +using System.Collections; +using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using Hypercube.Mathematics.Extensions; using JetBrains.Annotations; namespace Hypercube.Mathematics.Vectors; -[PublicAPI, StructLayout(LayoutKind.Sequential)] -public readonly partial struct Vector2 : IEquatable, IComparable, IComparable +/// +/// Represents a vector with two single-precision floating-point values. +/// +[PublicAPI, Serializable, StructLayout(LayoutKind.Sequential)] +public readonly partial struct Vector2 : IEquatable, IComparable, IComparable, IEnumerable { - public static readonly Vector2 NaN = new(float.NaN, float.NaN); - public static readonly Vector2 PositiveInfinity = new(float.PositiveInfinity, float.PositiveInfinity); - public static readonly Vector2 NegativeInfinity = new(float.NegativeInfinity, float.NegativeInfinity); - public static readonly Vector2 Zero = new(0, 0); - public static readonly Vector2 One = new(1, 1); - + /// + /// Vector (float.NaN, float.NaN). + /// + public static readonly Vector2 NaN = new(float.NaN); + + /// + /// Vector (float.PositiveInfinity, float.PositiveInfinity). + /// + public static readonly Vector2 PositiveInfinity = new(float.PositiveInfinity); + + /// + /// Vector (float.NegativeInfinity, float.NegativeInfinity). + /// + public static readonly Vector2 NegativeInfinity = new(float.NegativeInfinity); + + /// + /// Vector (0, 0). + /// + public static readonly Vector2 Zero = new(0); + + /// + /// Vector (1, 1). + /// + public static readonly Vector2 One = new(1); + + /// + /// Vector (1, 0). + /// public static readonly Vector2 UnitX = new(1, 0); + + /// + /// Vector (0, 1). + /// public static readonly Vector2 UnitY = new(0, 1); + /// + /// Vector X component. + /// public readonly float X; + + /// + /// Vector Y component. + /// public readonly float Y; + /// + /// Returns the ratio of X to Y. + /// public float AspectRatio { [MethodImpl(MethodImplOptions.AggressiveInlining)] get => X / Y; } + /// + /// Gets the square of the vector length (magnitude). + /// + /// + /// Allows you to avoid using the rather expensive sqrt operation. + /// (On ARM64 hardware may use the FRSQRTE instruction, which would take away this advantage). + /// + /// public float LengthSquared { [MethodImpl(MethodImplOptions.AggressiveInlining)] get => X * X + Y * Y; } + /// + /// Gets the length (magnitude) of the vector. + /// + /// + /// On ARM64 hardware this may use the FRSQRTE instruction + /// which performs a single Newton-Raphson iteration. + /// On hardware without specialized support + /// sqrt is used, which makes the method less fast. + /// + /// public float Length { [MethodImpl(MethodImplOptions.AggressiveInlining)] - get => MathF.Sqrt(LengthSquared); + get => 1f / MathF.ReciprocalSqrtEstimate(LengthSquared); } + /// + /// Copy of scaled to unit length. + /// public Vector2 Normalized { [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -50,12 +111,18 @@ public float Angle get => MathF.Atan2(Y, X); } + /// + /// Summation of all vector components. + /// public float Summation { [MethodImpl(MethodImplOptions.AggressiveInlining)] get => X + Y; } + /// + /// Production of all vector components. + /// public float Production { [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -127,7 +194,7 @@ public float DistanceSquared(Vector2 value) [MethodImpl(MethodImplOptions.AggressiveInlining)] public float Distance(Vector2 value) { - return MathF.Sqrt(DistanceSquared(this, value)); + return MathF.Sqrt(DistanceSquared(value)); } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -135,11 +202,11 @@ public float Dot(Vector2 value) { return Dot(this, value); } - + [MethodImpl(MethodImplOptions.AggressiveInlining)] - public float Cross(Vector2 value) + public Vector2 Reflect(Vector2 normal) { - return Cross(this, value); + return Reflect(this, normal); } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -230,6 +297,19 @@ public int CompareTo(float other) return LengthSquared.CompareTo(other * other); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public IEnumerator GetEnumerator() + { + yield return X; + yield return Y; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + IEnumerator IEnumerable.GetEnumerator() + { + return GetEnumerator(); + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public bool Equals(Vector2 other) { @@ -412,9 +492,9 @@ public static float Dot(Vector2 valueA, Vector2 valueB) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static float Cross(Vector2 valueA, Vector2 valueB) + public static Vector2 Reflect(Vector2 value, Vector2 normal) { - return valueA.X * valueB.Y - valueA.Y * valueB.X; + return value - 2.0f * (Dot(value, normal) * normal); } [MethodImpl(MethodImplOptions.AggressiveInlining)] diff --git a/Hypercube.Mathematics/Vectors/Vector2Int.cs b/Hypercube.Mathematics/Vectors/Vector2Int.cs index 477ab00..82795d2 100644 --- a/Hypercube.Mathematics/Vectors/Vector2Int.cs +++ b/Hypercube.Mathematics/Vectors/Vector2Int.cs @@ -1,19 +1,41 @@ -using System.Runtime.CompilerServices; +using System.Collections; +using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using JetBrains.Annotations; namespace Hypercube.Mathematics.Vectors; -[PublicAPI, StructLayout(LayoutKind.Sequential)] -public readonly partial struct Vector2Int : IEquatable, IComparable, IComparable +[PublicAPI, Serializable, StructLayout(LayoutKind.Sequential)] +public readonly partial struct Vector2Int : IEquatable, IComparable, IComparable, IEnumerable { - public static readonly Vector2Int Zero = new(0, 0); - public static readonly Vector2Int One = new(1, 1); - + /// + /// Vector (0, 0). + /// + public static readonly Vector2Int Zero = new(0); + + /// + /// Vector (1, 1). + /// + public static readonly Vector2Int One = new(1); + + /// + /// Vector (1, 0). + /// public static readonly Vector2Int UnitX = new(1, 0); + + /// + /// Vector (0, 1). + /// public static readonly Vector2Int UnitY = new(0, 1); + /// + /// Vector X component. + /// public readonly int X; + + /// + /// Vector Y component. + /// public readonly int Y; public float AspectRatio @@ -31,7 +53,7 @@ public float LengthSquared public float Length { [MethodImpl(MethodImplOptions.AggressiveInlining)] - get => MathF.Sqrt(LengthSquared); + get => 1f / MathF.ReciprocalSqrtEstimate(LengthSquared); } public Vector2Int Normalized @@ -131,13 +153,7 @@ public float Dot(Vector2Int value) { return Dot(this, value); } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public float Cross(Vector2Int value) - { - return Cross(this, value); - } - + [MethodImpl(MethodImplOptions.AggressiveInlining)] public Vector2Int Clamp(Vector2Int min, Vector2Int max) { @@ -196,6 +212,19 @@ public int CompareTo(Vector2Int other) return LengthSquared.CompareTo(other.LengthSquared); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public IEnumerator GetEnumerator() + { + yield return X; + yield return Y; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + IEnumerator IEnumerable.GetEnumerator() + { + return GetEnumerator(); + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public bool Equals(Vector2Int other) { @@ -220,7 +249,7 @@ public override string ToString() { return $"{X}, {Y}"; } - + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector2Int operator +(Vector2Int a, Vector2Int b) { @@ -364,12 +393,6 @@ public static float Dot(Vector2Int valueA, Vector2Int valueB) { return valueA.X * valueB.X + valueA.Y * valueB.Y; } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static float Cross(Vector2Int valueA, Vector2Int valueB) - { - return valueA.X * valueB.Y - valueA.Y * valueB.X; - } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector2Int MoveTowards(Vector2Int current, Vector2Int target, int distance) diff --git a/Hypercube.Mathematics/Vectors/Vector3.cs b/Hypercube.Mathematics/Vectors/Vector3.cs index 3847e5f..c740937 100644 --- a/Hypercube.Mathematics/Vectors/Vector3.cs +++ b/Hypercube.Mathematics/Vectors/Vector3.cs @@ -1,41 +1,135 @@ -using System.Runtime.CompilerServices; +using System.Collections; +using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using Hypercube.Mathematics.Extensions; +using JetBrains.Annotations; namespace Hypercube.Mathematics.Vectors; -[StructLayout(LayoutKind.Sequential)] -public readonly partial struct Vector3 : IEquatable +/// +/// Represents a vector with three single-precision floating-point values. +/// +[PublicAPI, Serializable, StructLayout(LayoutKind.Sequential)] +public readonly partial struct Vector3 : IEquatable, IComparable, IComparable, IEnumerable { + /// + /// Vector (float.NaN, float.NaN, float.NaN). + /// + public static readonly Vector3 NaN = new(float.NaN); + + /// + /// Vector (float.PositiveInfinity, float.PositiveInfinity, float.PositiveInfinity). + /// + public static readonly Vector3 PositiveInfinity = new(float.PositiveInfinity); + + /// + /// Vector (float.NegativeInfinity, float.NegativeInfinity, float.NegativeInfinity). + /// + public static readonly Vector3 NegativeInfinity = new(float.NegativeInfinity); + + /// + /// Vector (0, 0, 0). + /// public static readonly Vector3 Zero = new(0, 0, 0); + + /// + /// Vector (1, 1, 1). + /// public static readonly Vector3 One = new(1, 1, 1); + /// + /// Vector (1, 0, 0). + /// public static readonly Vector3 UnitX = new(1, 0, 0); + + /// + /// Vector (0, 1, 0). + /// public static readonly Vector3 UnitY = new(0, 1, 0); + + /// + /// Vector (0, 0, 1). + /// public static readonly Vector3 UnitZ = new(0, 0, 1); + /// + /// Vector X component. + /// public readonly float X; + + /// + /// Vector Y component. + /// public readonly float Y; + + /// + /// Vector Z component. + /// public readonly float Z; - + + /// + /// Gets the square of the vector length (magnitude). + /// + /// + /// Allows you to avoid using the rather expensive sqrt operation. + /// (On ARM64 hardware may use the FRSQRTE instruction, which would take away this advantage). + /// + /// public float LengthSquared { [MethodImpl(MethodImplOptions.AggressiveInlining)] get => X * X + Y * Y + Z * Z; } + /// + /// Gets the length (magnitude) of the vector. + /// + /// + /// On ARM64 hardware this may use the FRSQRTE instruction + /// which performs a single Newton-Raphson iteration. + /// On hardware without specialized support + /// sqrt is used, which makes the method less fast. + /// + /// public float Length { [MethodImpl(MethodImplOptions.AggressiveInlining)] - get => MathF.Sqrt(LengthSquared); + get => 1f / MathF.ReciprocalSqrtEstimate(LengthSquared); } + /// + /// Copy of scaled to unit length. + /// public Vector3 Normalized { [MethodImpl(MethodImplOptions.AggressiveInlining)] get => this / Length; } + /// + /// Summation of all vector components. + /// + public float Summation + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get => X + Y + Z; + } + + /// + /// Production of all vector components. + /// + public float Production + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get => X * Y * Z; + } + + public Vector2 XY + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get => new(X, Y); + } + public Vector3(float x, float y, float z) { X = x; @@ -43,26 +137,46 @@ public Vector3(float x, float y, float z) Z = z; } - public Vector3(float value) : this(value, value, value) + public Vector3(float value) { + X = value; + Y = value; + Z = value; } - public Vector3(Vector2 vector2) : this(vector2.X, vector2.Y, 0) + public Vector3(double x, double y, double z) { + X = (float) x; + Y = (float) y; + Z = (float) z; } - public Vector3(Vector2 vector2, float z) : this(vector2.X, vector2.Y, z) + public Vector3(double value) { + X = (float) value; + Y = (float) value; + Z = (float) value; } - - public Vector3(Vector3 vector3) : this(vector3.X, vector3.Y, vector3.Z) + + public Vector3(Vector2 value) + { + X = value.X; + Y = value.Y; + Z = 0; + } + + public Vector3(Vector2 value, float z) { + X = value.X; + Y = value.Y; + Z = z; } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public float Sum() + public Vector3(Vector3 value) { - return X + Y + Z; + X = value.X; + Y = value.Y; + Z = value.Z; } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -76,17 +190,67 @@ public Vector3 WithY(float value) { return new Vector3(X, value, Z); } - + [MethodImpl(MethodImplOptions.AggressiveInlining)] public Vector3 WithZ(float value) { return new Vector3(X, Y, value); - } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public float DistanceSquared(Vector3 value) + { + return (this - value).LengthSquared; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public float Distance(Vector3 value) + { + return MathF.Sqrt(DistanceSquared(value)); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Vector3 Cross(Vector3 value) + { + return Cross(this, value); + } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public Vector3 Cross(Vector3 other) + public float Dot(Vector3 value) + { + return Dot(this, value); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Vector3 Reflect(Vector3 normal) + { + return Reflect(this, normal); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public int CompareTo(Vector3 other) { - return Vector3.Cross(this, other); + return LengthSquared.CompareTo(other.LengthSquared); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public int CompareTo(float other) + { + return LengthSquared.CompareTo(other * other * other); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public IEnumerator GetEnumerator() + { + yield return X; + yield return Y; + yield return Z; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + IEnumerator IEnumerable.GetEnumerator() + { + return GetEnumerator(); } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -175,6 +339,12 @@ public override string ToString() return new Vector3(a.X * b, a.Y * b, a.Z * b); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector3 operator *(float a, Vector3 b) + { + return new Vector3(a * b.X, a * b.Y, a * b.Z); + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector3 operator /(Vector3 a, Vector3 b) { @@ -193,6 +363,12 @@ public override string ToString() return new Vector3(a.X / b, a.Y / b, a.Z / b); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector3 operator /(float a, Vector3 b) + { + return new Vector3(a / b.X, a / b.Y, a / b.Z); + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool operator ==(Vector3 a, Vector3 b) { @@ -204,13 +380,25 @@ public override string ToString() { return !a.Equals(b); } - + [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Vector3 Cross(Vector3 left, Vector3 right) + public static Vector3 Cross(Vector3 valueA, Vector3 valueB) { return new Vector3( - left.Y * right.Z - left.Z * right.Y, - left.Z * right.X - left.X * right.Z, - left.X * right.Y - left.Y * right.X); + valueA.Y * valueB.Z - valueA.Z * valueB.Y, + valueA.Z * valueB.X - valueA.X * valueB.Z, + valueA.X * valueB.Y - valueA.Y * valueB.X); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static float Dot(Vector3 valueA, Vector3 valueB) + { + return valueA.X * valueB.X + valueA.Y * valueB.Y + valueA.Z * valueB.Z; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector3 Reflect(Vector3 value, Vector3 normal) + { + return value - 2.0f * (Dot(value, normal) * normal); } } \ No newline at end of file diff --git a/Hypercube.Mathematics/Vectors/Vector4.cs b/Hypercube.Mathematics/Vectors/Vector4.cs index 4bf58cb..e58d662 100644 --- a/Hypercube.Mathematics/Vectors/Vector4.cs +++ b/Hypercube.Mathematics/Vectors/Vector4.cs @@ -1,46 +1,148 @@ -using System.Runtime.CompilerServices; +using System.Collections; +using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using Hypercube.Mathematics.Extensions; +using JetBrains.Annotations; namespace Hypercube.Mathematics.Vectors; -[StructLayout(LayoutKind.Sequential)] -public readonly partial struct Vector4 : IEquatable +[PublicAPI, Serializable, StructLayout(LayoutKind.Sequential)] +public readonly partial struct Vector4 : IEquatable, IComparable, IComparable, IEnumerable { - public static readonly Vector4 Zero = new(0, 0, 0, 0); - public static readonly Vector4 One = new(1, 1, 1, 1); - + /// + /// Vector (float.NaN, float.NaN, float.NaN, float.NaN). + /// + public static readonly Vector4 NaN = new(float.NaN); + + /// + /// Vector (float.PositiveInfinity, float.PositiveInfinity, float.PositiveInfinity, float.PositiveInfinity). + /// + public static readonly Vector4 PositiveInfinity = new(float.PositiveInfinity); + + /// + /// Vector (float.NegativeInfinity, float.NegativeInfinity, float.NegativeInfinity, float.NegativeInfinity). + /// + public static readonly Vector4 NegativeInfinity = new(float.NegativeInfinity); + + /// + /// Vector (0, 0, 0, 0). + /// + public static readonly Vector4 Zero = new(0); + + /// + /// Vector (1, 1, 1, 1). + /// + public static readonly Vector4 One = new(1); + + /// + /// Vector (1, 0, 0, 0). + /// public static readonly Vector4 UnitX = new(1, 0, 0, 0); + + /// + /// Vector (0, 1, 0, 0). + /// public static readonly Vector4 UnitY = new(0, 1, 0, 0); + + /// + /// Vector (0, 0, 1, 0). + /// public static readonly Vector4 UnitZ = new(0, 0, 1, 0); + + /// + /// Vector (0, 0, 0, 1). + /// public static readonly Vector4 UnitW = new(0, 0, 0, 1); + /// + /// Vector X component. + /// public readonly float X; + + /// + /// Vector Y component. + /// public readonly float Y; + + /// + /// Vector Z component. + /// public readonly float Z; + + /// + /// Vector W component. + /// public readonly float W; - public Vector2 XY => new(X, Y); - public Vector3 XYZ => new(X, Y, Z); + public Vector2 XY + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get => new(X, Y); + } + + public Vector3 XYZ + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get => new(X, Y, Z); + } + /// + /// Gets the square of the vector length (magnitude). + /// + /// + /// Allows you to avoid using the rather expensive sqrt operation. + /// (On ARM64 hardware may use the FRSQRTE instruction, which would take away this advantage). + /// + /// public float LengthSquared { [MethodImpl(MethodImplOptions.AggressiveInlining)] get => X * X + Y * Y + Z * Z + W * W; } + /// + /// Gets the length (magnitude) of the vector. + /// + /// + /// On ARM64 hardware this may use the FRSQRTE instruction + /// which performs a single Newton-Raphson iteration. + /// On hardware without specialized support + /// sqrt is used, which makes the method less fast. + /// + /// public float Length { [MethodImpl(MethodImplOptions.AggressiveInlining)] - get => MathF.Sqrt(LengthSquared); + get => 1f / MathF.ReciprocalSqrtEstimate(LengthSquared); } + /// + /// Copy of scaled to unit length. + /// public Vector4 Normalized { [MethodImpl(MethodImplOptions.AggressiveInlining)] get => this / Length; } + /// + /// Summation of all vector components. + /// + public float Summation + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get => X + Y + Z + W; + } + + /// + /// Production of all vector components. + /// + public float Production + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get => X * Y * Z * W; + } + public Vector4(float x, float y, float z, float w) { X = x; @@ -49,34 +151,52 @@ public Vector4(float x, float y, float z, float w) W = w; } - public Vector4(float value) : this(value, value, value, value) + public Vector4(float value) { + X = value; + Y = value; + Z = value; + W = value; } - public Vector4(Vector2 vector2, float z, float w) : this(vector2.X, vector2.Y, z, w) + public Vector4(double x, double y, double z, double w) { + X = (float) x; + Y = (float) y; + Z = (float) z; + W = (float) w; } - public Vector4(Vector3 vector3, float w) : this(vector3.X, vector3.Y, vector3.Z, w) + public Vector4(double value) { + X = (float) value; + Y = (float) value; + Z = (float) value; + W = (float) value; } - - public Vector4(Vector4 vector4, float w) : this(vector4.X, vector4.Y, vector4.Z, w) + + public Vector4(Vector2 value, float z, float w) { + X = value.X; + Y = value.Y; + Z = z; + W = w; } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public float Sum() + public Vector4(Vector3 value, float w) { - return X + Y + Z + W; + X = value.X; + Y = value.Y; + Z = value.Z; + W = w; } - - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public float Prod() + + public Vector4(Vector4 value) { - return X * Y * Z * W; + X = value.X; + Y = value.Y; + Z = value.Z; + W = value.W; } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -102,7 +222,34 @@ public Vector4 WithW(float value) { return new Vector4(X, Y, Z, value); } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public int CompareTo(Vector4 other) + { + return LengthSquared.CompareTo(other.LengthSquared); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public int CompareTo(float other) + { + return LengthSquared.CompareTo(other * other * other * other); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public IEnumerator GetEnumerator() + { + yield return X; + yield return Y; + yield return Z; + yield return W; + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + IEnumerator IEnumerable.GetEnumerator() + { + return GetEnumerator(); + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public bool Equals(Vector4 other) { @@ -111,14 +258,13 @@ public bool Equals(Vector4 other) Z.AboutEquals(other.Z) && W.AboutEquals(other.W); } - + [MethodImpl(MethodImplOptions.AggressiveInlining)] public override bool Equals(object? obj) { return obj is Vector4 other && Equals(other); } - [MethodImpl(MethodImplOptions.AggressiveInlining)] public override string ToString() { diff --git a/Hypercube.sln.DotSettings b/Hypercube.sln.DotSettings index 7aa78a7..316113c 100644 --- a/Hypercube.sln.DotSettings +++ b/Hypercube.sln.DotSettings @@ -1,3 +1,5 @@  + True True + True True \ No newline at end of file From 5fa189653113be0ff9dc583e6cdc64f1f8784982 Mon Sep 17 00:00:00 2001 From: Tornado Tech <54727692+Tornado-Technology@users.noreply.github.com> Date: Thu, 29 Aug 2024 15:52:49 +1000 Subject: [PATCH 09/15] Updated vector2, vector3 & fix unit tests --- Hypercube.Mathematics/Angle.cs | 10 +- Hypercube.Mathematics/Vectors/Vector2.cs | 69 +++++---- Hypercube.Mathematics/Vectors/Vector3.cs | 186 +++++++++++++++++++++++ Hypercube.UnitTests/Math/AngleTest.cs | 54 +++---- 4 files changed, 261 insertions(+), 58 deletions(-) diff --git a/Hypercube.Mathematics/Angle.cs b/Hypercube.Mathematics/Angle.cs index 9bcad14..d02940c 100644 --- a/Hypercube.Mathematics/Angle.cs +++ b/Hypercube.Mathematics/Angle.cs @@ -1,9 +1,12 @@ using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; using Hypercube.Mathematics.Extensions; using Hypercube.Mathematics.Vectors; +using JetBrains.Annotations; namespace Hypercube.Mathematics; +[PublicAPI, Serializable, StructLayout(LayoutKind.Sequential)] public readonly struct Angle : IEquatable, IEquatable { public static readonly Angle Zero = new(0); @@ -19,7 +22,7 @@ public double Degrees public Vector2 Vector { [MethodImpl(MethodImplOptions.AggressiveInlining)] - get => new((float)System.Math.Cos(Theta), (float)System.Math.Sin(Theta)); + get => new(MathF.Cos((float) Theta), MathF.Sin((float) Theta)); } public Angle(double theta) @@ -27,10 +30,9 @@ public Angle(double theta) Theta = theta; } - public Angle(Vector2 vector2) + public Angle(Vector2 value) { - vector2 = vector2.Normalized; - Theta = System.Math.Atan2(vector2.X, vector2.Y); + Theta = value.Angle; } [MethodImpl(MethodImplOptions.AggressiveInlining)] diff --git a/Hypercube.Mathematics/Vectors/Vector2.cs b/Hypercube.Mathematics/Vectors/Vector2.cs index 54707b6..840671b 100644 --- a/Hypercube.Mathematics/Vectors/Vector2.cs +++ b/Hypercube.Mathematics/Vectors/Vector2.cs @@ -1,4 +1,5 @@ using System.Collections; +using System.Diagnostics; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using Hypercube.Mathematics.Extensions; @@ -9,8 +10,8 @@ namespace Hypercube.Mathematics.Vectors; /// /// Represents a vector with two single-precision floating-point values. /// -[PublicAPI, Serializable, StructLayout(LayoutKind.Sequential)] -public readonly partial struct Vector2 : IEquatable, IComparable, IComparable, IEnumerable +[PublicAPI, Serializable, StructLayout(LayoutKind.Sequential), DebuggerDisplay("({X}, {Y})")] +public readonly partial struct Vector2 : IEquatable, IComparable, IComparable, IEnumerable, ISpanFormattable { /// /// Vector (float.NaN, float.NaN). @@ -209,82 +210,82 @@ public Vector2 Reflect(Vector2 normal) return Reflect(this, normal); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Vector2 MoveTowards(Vector2 target, float distance) + { + return MoveTowards(this, target, distance); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Vector2 Rotate(float angle) + { + var cos = MathF.Cos(angle); + var sin = MathF.Sin(angle); + return new Vector2( + cos * X - sin * Y, + sin * X + cos * Y); + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public Vector2 Clamp(Vector2 min, Vector2 max) { return Clamp(this, min, max); } - + [MethodImpl(MethodImplOptions.AggressiveInlining)] public Vector2 Clamp(float min, float max) { return Clamp(this, min, max); } - + [MethodImpl(MethodImplOptions.AggressiveInlining)] public Vector2 Lerp(Vector2 value, float amount) { return Lerp(this, value, amount); } - + [MethodImpl(MethodImplOptions.AggressiveInlining)] public Vector2 Max(Vector2 value) { return Max(this, value); } - + [MethodImpl(MethodImplOptions.AggressiveInlining)] public Vector2 Min(Vector2 value) { return Min(this, value); } - + [MethodImpl(MethodImplOptions.AggressiveInlining)] public Vector2 Abs() { return Abs(this); } - + [MethodImpl(MethodImplOptions.AggressiveInlining)] public Vector2 Round() { return Round(this); } - + [MethodImpl(MethodImplOptions.AggressiveInlining)] public Vector2 Round(int digits) { return Round(this, digits); } - + [MethodImpl(MethodImplOptions.AggressiveInlining)] public Vector2 Ceiling() { return Ceiling(this); } - + [MethodImpl(MethodImplOptions.AggressiveInlining)] public Vector2 Floor() { return Floor(this); } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public Vector2 MoveTowards(Vector2 target, float distance) - { - return MoveTowards(this, target, distance); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public Vector2 Rotate(float angle) - { - var cos = MathF.Cos(angle); - var sin = MathF.Sin(angle); - return new Vector2( - cos * X - sin * Y, - sin * X + cos * Y); - } - [MethodImpl(MethodImplOptions.AggressiveInlining)] public int CompareTo(Vector2 other) { @@ -328,13 +329,25 @@ public override int GetHashCode() { return HashCode.Combine(X, Y); } - + [MethodImpl(MethodImplOptions.AggressiveInlining)] public override string ToString() { return $"{X}, {Y}"; } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public string ToString(string? format, IFormatProvider? formatProvider) + { + return $"{X}, {Y}".ToString(formatProvider); + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool TryFormat(Span destination, out int charsWritten, ReadOnlySpan format, IFormatProvider? provider) + { + return destination.TryWrite(provider, $"{X}, {Y}", out charsWritten); + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector2 operator +(Vector2 a, Vector2 valueB) { diff --git a/Hypercube.Mathematics/Vectors/Vector3.cs b/Hypercube.Mathematics/Vectors/Vector3.cs index c740937..6df453a 100644 --- a/Hypercube.Mathematics/Vectors/Vector3.cs +++ b/Hypercube.Mathematics/Vectors/Vector3.cs @@ -226,6 +226,72 @@ public Vector3 Reflect(Vector3 normal) { return Reflect(this, normal); } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Vector3 MoveTowards(Vector3 target, float distance) + { + return MoveTowards(this, target, distance); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Vector3 Clamp(Vector3 min, Vector3 max) + { + return Clamp(this, min, max); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Vector3 Clamp(float min, float max) + { + return Clamp(this, min, max); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Vector3 Lerp(Vector3 value, float amount) + { + return Lerp(this, value, amount); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Vector3 Max(Vector3 value) + { + return Max(this, value); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Vector3 Min(Vector3 value) + { + return Min(this, value); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Vector3 Abs() + { + return Abs(this); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Vector3 Round() + { + return Round(this); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Vector3 Round(int digits) + { + return Round(this, digits); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Vector3 Ceiling() + { + return Ceiling(this); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Vector3 Floor() + { + return Floor(this); + } [MethodImpl(MethodImplOptions.AggressiveInlining)] public int CompareTo(Vector3 other) @@ -380,6 +446,18 @@ public override string ToString() { return !a.Equals(b); } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static float DistanceSquared(Vector2 valueA, Vector2 valueB) + { + return (valueA - valueB).LengthSquared; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static float Distance(Vector2 valueA, Vector2 valueB) + { + return MathF.Sqrt(DistanceSquared(valueA, valueB)); + } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector3 Cross(Vector3 valueA, Vector3 valueB) @@ -401,4 +479,112 @@ public static Vector3 Reflect(Vector3 value, Vector3 normal) { return value - 2.0f * (Dot(value, normal) * normal); } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector3 MoveTowards(Vector3 current, Vector3 target, float distance) + { + return new Vector3( + HyperMathF.MoveTowards(current.X, target.X, distance), + HyperMathF.MoveTowards(current.Y, target.Y, distance), + HyperMathF.MoveTowards(current.Z, target.Z, distance)); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector3 Clamp(Vector3 value, Vector3 min, Vector3 max) + { + return new Vector3( + float.Clamp(value.X, min.X, max.X), + float.Clamp(value.Y, min.Y, max.Y), + float.Clamp(value.Z, min.Z, max.Z)); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector3 Clamp(Vector3 value, float min, float max) + { + return new Vector3( + float.Clamp(value.X, min, max), + float.Clamp(value.Y, min, max), + float.Clamp(value.Z, min, max)); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector3 Lerp(Vector3 value, Vector3 target, float amount) + { + return new Vector3( + float.Lerp(value.X, target.X, amount), + float.Lerp(value.Y, target.Y, amount), + float.Lerp(value.Z, target.Z, amount)); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector3 Max(Vector3 valueA, Vector3 valueB) + { + return new Vector3( + MathF.Max(valueA.X, valueB.X), + MathF.Max(valueA.Y, valueB.Y), + MathF.Max(valueA.Z, valueB.Z)); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector3 Min(Vector3 valueA, Vector3 valueB) + { + return new Vector3( + MathF.Min(valueA.X, valueB.X), + MathF.Min(valueA.Y, valueB.Y), + MathF.Min(valueA.Z, valueB.Z)); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector3 Abs(Vector3 value) + { + return new Vector3( + Math.Abs(value.X), + Math.Abs(value.Y), + Math.Abs(value.Z)); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector3 Round(Vector3 value) + { + return new Vector3( + Math.Round(value.X), + Math.Round(value.Y), + Math.Round(value.Z)); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector3 Round(Vector3 value, int digits) + { + return new Vector3( + Math.Round(value.X, digits), + Math.Round(value.Y, digits), + Math.Round(value.Z, digits)); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector3 Ceiling(Vector3 value) + { + return new Vector3( + Math.Ceiling(value.X), + Math.Ceiling(value.Y), + Math.Ceiling(value.Z)); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector3 Floor(Vector3 value) + { + return new Vector3( + Math.Floor(value.X), + Math.Floor(value.Y), + Math.Floor(value.Z)); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector3 Sign(Vector3 value) + { + return new Vector3( + Math.Sign(value.X), + Math.Sign(value.Y), + Math.Sign(value.Z)); + } } \ No newline at end of file diff --git a/Hypercube.UnitTests/Math/AngleTest.cs b/Hypercube.UnitTests/Math/AngleTest.cs index ba4461e..8a28895 100644 --- a/Hypercube.UnitTests/Math/AngleTest.cs +++ b/Hypercube.UnitTests/Math/AngleTest.cs @@ -3,10 +3,20 @@ namespace Hypercube.UnitTests.Math; +[TestFixture] public static class AngleTest { + private static readonly Dictionary ConvertToVectorPairs = new() + { + { 0d, Vector2.UnitX }, + { HyperMath.PIOver2, Vector2.UnitY }, + { HyperMath.PIOver4, Vector2.One.Normalized }, + { HyperMath.PI, -Vector2.UnitX }, + { HyperMath.ThreePiOver2, -Vector2.UnitY }, + }; + [Test] - public static void Degrees() + public static void ConvertToDegrees() { Assert.Multiple(() => { @@ -14,41 +24,33 @@ public static void Degrees() Assert.That(new Angle(HyperMath.PIOver2).Degrees, Is.EqualTo(90d).Within(0.01d)); Assert.That(new Angle(HyperMath.PIOver4).Degrees, Is.EqualTo(45d).Within(0.01d)); Assert.That(new Angle(HyperMath.PIOver6).Degrees, Is.EqualTo(30d).Within(0.01d)); - + }); + } + + [Test] + public static void ConvertFromDegrees() + { + Assert.Multiple(() => + { Assert.That(Angle.FromDegrees(180d), Is.EqualTo(new Angle(HyperMath.PI))); Assert.That(Angle.FromDegrees(90d), Is.EqualTo(new Angle(HyperMath.PIOver2))); Assert.That(Angle.FromDegrees(45d), Is.EqualTo(new Angle(HyperMath.PIOver4))); Assert.That(Angle.FromDegrees(30d), Is.EqualTo(new Angle(HyperMath.PIOver6))); }); - - Assert.Pass($"{nameof(Angle)} degrees passed"); } [Test] - public static void Vector() + public static void ConvertToVector() { - Assert.Multiple(() => + foreach (var (angle, vector) in ConvertToVectorPairs) { - Assert.That(Angle.Zero.GetRoundVector(), Is.EqualTo(Vector2.UnitX)); - Assert.That(new Angle(HyperMath.PI).GetRoundVector(), Is.EqualTo(-Vector2.UnitX)); - Assert.That(new Angle(-HyperMath.PI).GetRoundVector(), Is.EqualTo(-Vector2.UnitX)); + var vectorA = new Angle(angle).Vector.Round(3); + var vectorB = vector.Round(3); + + if (vectorA.Equals(vectorB)) + continue; - Assert.That(new Angle(HyperMath.PIOver2).GetRoundVector(), Is.EqualTo(Vector2.UnitY)); - Assert.That(new Angle(HyperMath.ThreePiOver2).GetRoundVector(), Is.EqualTo(-Vector2.UnitY)); - Assert.That(new Angle(-HyperMath.PIOver2).GetRoundVector(), Is.EqualTo(-Vector2.UnitY)); - - Assert.That(new Angle(HyperMath.PIOver4).GetRoundVector(), Is.EqualTo(Vector2.One.Normalized)); - Assert.That(new Angle(HyperMath.ThreePiOver2 - HyperMath.PIOver4).GetRoundVector(), Is.EqualTo(-Vector2.One.Normalized)); - }); - - Assert.Pass($"{nameof(Angle)} vector passed"); - } - - private static Vector2 GetRoundVector(this Angle angle) - { - var vector = angle.Vector; - var x = MathF.Abs(vector.X) < 1e-15f ? 0 : vector.X; - var y = MathF.Abs(vector.Y) < 1e-15f ? 0 : vector.Y; - return new Vector2(x, y); + Assert.Fail($"Expected {vectorB}, but was {vectorA}"); + } } } \ No newline at end of file From 9250327e1ea1edf6677235c10ad834504fe02ab0 Mon Sep 17 00:00:00 2001 From: Tornado Tech <54727692+Tornado-Technology@users.noreply.github.com> Date: Thu, 29 Aug 2024 15:58:52 +1000 Subject: [PATCH 10/15] Renamed Vector2Int to Vector2i --- .../OpenGL/Texturing/TextureManager.cs | 2 +- .../Graphics/Viewports/Camera2D.cs | 4 +- .../Graphics/Viewports/CameraManager.cs | 4 +- .../Graphics/Viewports/ICamera.cs | 2 +- .../Graphics/Viewports/ICameraManager.cs | 2 +- .../GLFW/GlfwWindowManager.Monitors.cs | 2 +- .../GLFW/GlfwWindowManager.Window.cs | 6 +- .../Windows/Realisation/GLFW/GlfwWindowing.cs | 2 +- Hypercube.Graphics/Monitors/MonitorHandle.cs | 6 +- Hypercube.Graphics/Shaders/IShaderProgram.cs | 2 +- .../Texturing/ITextureManager.cs | 2 +- Hypercube.Graphics/Texturing/Texture.cs | 4 +- Hypercube.Graphics/Windowing/IWindowing.cs | 6 +- .../Windowing/WindowCreateSettings.cs | 2 +- Hypercube.Graphics/Windowing/WindowHandle.cs | 8 +- Hypercube.ImGui/IImGuiController.cs | 2 +- .../OpenGLImGuiController.Input.cs | 2 +- .../OpenGLImGuiController.Render.cs | 4 +- .../Vectors/Vector2.Compatibility.cs | 4 +- ...atibility.cs => Vector2i.Compatibility.cs} | 36 ++-- .../Vectors/{Vector2Int.cs => Vector2i.cs} | 158 +++++++++--------- .../Vectors/Vector3.Compatibility.cs | 4 +- Hypercube.OpenGL/Shaders/ShaderProgram.cs | 2 +- .../Utilities/Helpers/GLFWHelper.cs | 16 +- Hypercube.Shared/Physics/Chunk.cs | 4 +- 25 files changed, 144 insertions(+), 142 deletions(-) rename Hypercube.Mathematics/Vectors/{Vector2Int.Compatibility.cs => Vector2i.Compatibility.cs} (64%) rename Hypercube.Mathematics/Vectors/{Vector2Int.cs => Vector2i.cs} (65%) diff --git a/Hypercube.Client/Graphics/Realisation/OpenGL/Texturing/TextureManager.cs b/Hypercube.Client/Graphics/Realisation/OpenGL/Texturing/TextureManager.cs index 6aef9ac..2d2c0fc 100644 --- a/Hypercube.Client/Graphics/Realisation/OpenGL/Texturing/TextureManager.cs +++ b/Hypercube.Client/Graphics/Realisation/OpenGL/Texturing/TextureManager.cs @@ -14,7 +14,7 @@ public sealed class TextureManager : ITextureManager { [Dependency] private readonly IResourceLoader _resourceLoader = default!; - public ITexture CreateBlank(Vector2Int size, Color color) + public ITexture CreateBlank(Vector2i size, Color color) { var data = new byte[size.X * size.Y * 4]; diff --git a/Hypercube.Client/Graphics/Viewports/Camera2D.cs b/Hypercube.Client/Graphics/Viewports/Camera2D.cs index 2163d73..086d7a5 100644 --- a/Hypercube.Client/Graphics/Viewports/Camera2D.cs +++ b/Hypercube.Client/Graphics/Viewports/Camera2D.cs @@ -13,14 +13,14 @@ public sealed class Camera2D : ICamera public Vector3 Position => _transform.Position; public Vector3 Rotation => _transform.Rotation.ToEuler(); public Vector3 Scale => _transform.Scale; - public Vector2Int Size { get; private set; } + public Vector2i Size { get; private set; } private readonly float _zFar; private readonly float _zNear; private Transform3 _transform = new(); - public Camera2D(Vector2Int size, Vector2 position, float zNear, float zFar) + public Camera2D(Vector2i size, Vector2 position, float zNear, float zFar) { Size = size; _zNear = zNear; diff --git a/Hypercube.Client/Graphics/Viewports/CameraManager.cs b/Hypercube.Client/Graphics/Viewports/CameraManager.cs index db15412..e202430 100644 --- a/Hypercube.Client/Graphics/Viewports/CameraManager.cs +++ b/Hypercube.Client/Graphics/Viewports/CameraManager.cs @@ -61,12 +61,12 @@ public void SetMainCamera(ICamera camera) MainCamera = camera; } - public ICamera CreateCamera2D(Vector2Int size) + public ICamera CreateCamera2D(Vector2i size) { return CreateCamera2D(size, Vector2.Zero); } - public ICamera CreateCamera2D(Vector2Int size, Vector2 position, float zNear = 0.1f, float zFar = 100f) + public ICamera CreateCamera2D(Vector2i size, Vector2 position, float zNear = 0.1f, float zFar = 100f) { return new Camera2D(size, position, zNear, zFar); } diff --git a/Hypercube.Client/Graphics/Viewports/ICamera.cs b/Hypercube.Client/Graphics/Viewports/ICamera.cs index 8da3707..2a9cbf1 100644 --- a/Hypercube.Client/Graphics/Viewports/ICamera.cs +++ b/Hypercube.Client/Graphics/Viewports/ICamera.cs @@ -11,7 +11,7 @@ public interface ICamera Vector3 Position { get; } Vector3 Rotation { get; } Vector3 Scale { get; } - Vector2Int Size { get; } + Vector2i Size { get; } void SetPosition(Vector3 position); void SetRotation(Vector3 rotation); diff --git a/Hypercube.Client/Graphics/Viewports/ICameraManager.cs b/Hypercube.Client/Graphics/Viewports/ICameraManager.cs index cd15d43..3b79ce4 100644 --- a/Hypercube.Client/Graphics/Viewports/ICameraManager.cs +++ b/Hypercube.Client/Graphics/Viewports/ICameraManager.cs @@ -12,6 +12,6 @@ public interface ICameraManager void SetMainCamera(ICamera camera); - ICamera CreateCamera2D(Vector2Int size); + ICamera CreateCamera2D(Vector2i size); void UpdateInput(ICamera? camera, float delta); } \ No newline at end of file diff --git a/Hypercube.Client/Graphics/Windows/Realisation/GLFW/GlfwWindowManager.Monitors.cs b/Hypercube.Client/Graphics/Windows/Realisation/GLFW/GlfwWindowManager.Monitors.cs index 91ea592..1d93252 100644 --- a/Hypercube.Client/Graphics/Windows/Realisation/GLFW/GlfwWindowManager.Monitors.cs +++ b/Hypercube.Client/Graphics/Windows/Realisation/GLFW/GlfwWindowManager.Monitors.cs @@ -82,7 +82,7 @@ public sealed class GlfwMonitorRegistration : MonitorHandle public readonly Monitor* Pointer; - public GlfwMonitorRegistration(MonitorId id, string name, Vector2Int size, int refreshRate, VideoMode[] videoModes, Monitor* pointer) : base(id, name, size, refreshRate, videoModes) + public GlfwMonitorRegistration(MonitorId id, string name, Vector2i size, int refreshRate, VideoMode[] videoModes, Monitor* pointer) : base(id, name, size, refreshRate, videoModes) { Pointer = pointer; } diff --git a/Hypercube.Client/Graphics/Windows/Realisation/GLFW/GlfwWindowManager.Window.cs b/Hypercube.Client/Graphics/Windows/Realisation/GLFW/GlfwWindowManager.Window.cs index 8ab8b0c..696d686 100644 --- a/Hypercube.Client/Graphics/Windows/Realisation/GLFW/GlfwWindowManager.Window.cs +++ b/Hypercube.Client/Graphics/Windows/Realisation/GLFW/GlfwWindowManager.Window.cs @@ -206,7 +206,7 @@ public void WindowSetTitle(WindowHandle window, string title) public void WindowSetMonitor(WindowHandle window, MonitorHandle registration) { - WindowSetMonitor(window, registration, Vector2Int.Zero); + WindowSetMonitor(window, registration, Vector2i.Zero); } public void WindowRequestAttention(WindowHandle window) @@ -217,7 +217,7 @@ public void WindowRequestAttention(WindowHandle window) OpenTK.Windowing.GraphicsLibraryFramework.GLFW.RequestWindowAttention(glfwWindow); } - public void WindowSetSize(WindowHandle window, Vector2Int size) + public void WindowSetSize(WindowHandle window, Vector2i size) { if (window is not GlfwWindowHandle glfwWindow) return; @@ -247,7 +247,7 @@ public void WindowSetOpacity(WindowHandle window, float opacity) OpenTK.Windowing.GraphicsLibraryFramework.GLFW.SetWindowOpacity(glfwWindow, opacity); } - public void WindowSetPosition(WindowHandle window, Vector2Int position) + public void WindowSetPosition(WindowHandle window, Vector2i position) { if (window is not GlfwWindowHandle glfwWindow) return; diff --git a/Hypercube.Client/Graphics/Windows/Realisation/GLFW/GlfwWindowing.cs b/Hypercube.Client/Graphics/Windows/Realisation/GLFW/GlfwWindowing.cs index a3cc258..c1f5977 100644 --- a/Hypercube.Client/Graphics/Windows/Realisation/GLFW/GlfwWindowing.cs +++ b/Hypercube.Client/Graphics/Windows/Realisation/GLFW/GlfwWindowing.cs @@ -95,7 +95,7 @@ public nint GetProcAddress(string procName) return OpenTK.Windowing.GraphicsLibraryFramework.GLFW.GetProcAddress(procName); } - public void WindowSetMonitor(WindowHandle window, MonitorHandle monitor, Vector2Int vector) + public void WindowSetMonitor(WindowHandle window, MonitorHandle monitor, Vector2i vector) { if (monitor is not GlfwMonitorRegistration glfwMonitor) return; diff --git a/Hypercube.Graphics/Monitors/MonitorHandle.cs b/Hypercube.Graphics/Monitors/MonitorHandle.cs index e815926..2fa8bff 100644 --- a/Hypercube.Graphics/Monitors/MonitorHandle.cs +++ b/Hypercube.Graphics/Monitors/MonitorHandle.cs @@ -8,11 +8,11 @@ public class MonitorHandle { public MonitorId Id { get; } public string Name { get; } - public Vector2Int Size { get; } + public Vector2i Size { get; } public int RefreshRate { get; } public VideoMode[] VideoModes { get; } - public MonitorHandle(MonitorId id, string name, Vector2Int size, int refreshRate, VideoMode[] videoModes) + public MonitorHandle(MonitorId id, string name, Vector2i size, int refreshRate, VideoMode[] videoModes) { Id = id; Name = name; @@ -25,7 +25,7 @@ public MonitorHandle(MonitorId id, string name, int width, int height, int refre { Id = id; Name = name; - Size = new Vector2Int(width, height); + Size = new Vector2i(width, height); RefreshRate = refreshRate; VideoModes = videoModes; } diff --git a/Hypercube.Graphics/Shaders/IShaderProgram.cs b/Hypercube.Graphics/Shaders/IShaderProgram.cs index 8022afc..b6ff6ce 100644 --- a/Hypercube.Graphics/Shaders/IShaderProgram.cs +++ b/Hypercube.Graphics/Shaders/IShaderProgram.cs @@ -27,7 +27,7 @@ public interface IShaderProgram : IDisposable void SetUniform(string name, double value); void SetUniform(string name, Vector2 value); - void SetUniform(string name, Vector2Int value); + void SetUniform(string name, Vector2i value); void SetUniform(string name, Vector3 value); void SetUniform(string name, Matrix3X3 value, bool transpose = false); diff --git a/Hypercube.Graphics/Texturing/ITextureManager.cs b/Hypercube.Graphics/Texturing/ITextureManager.cs index 35f5b3a..4e6557c 100644 --- a/Hypercube.Graphics/Texturing/ITextureManager.cs +++ b/Hypercube.Graphics/Texturing/ITextureManager.cs @@ -9,7 +9,7 @@ namespace Hypercube.Graphics.Texturing; [PublicAPI] public interface ITextureManager { - ITexture CreateBlank(Vector2Int size, Color color); + ITexture CreateBlank(Vector2i size, Color color); ITexture CreateTexture(ResourcePath path); ITextureHandle CreateTextureHandle(ITexture texture); diff --git a/Hypercube.Graphics/Texturing/Texture.cs b/Hypercube.Graphics/Texturing/Texture.cs index c23e58a..d101fc3 100644 --- a/Hypercube.Graphics/Texturing/Texture.cs +++ b/Hypercube.Graphics/Texturing/Texture.cs @@ -11,7 +11,7 @@ namespace Hypercube.Graphics.Texturing; public const int PixelPerUnit = 32; public ResourcePath Path { get; } - public Vector2Int Size { get; } + public Vector2i Size { get; } public byte[] Data { get; } @@ -27,7 +27,7 @@ public Box2 Quad } } - public Texture(ResourcePath path, Vector2Int size, byte[] data) + public Texture(ResourcePath path, Vector2i size, byte[] data) { Path = path; Size = size; diff --git a/Hypercube.Graphics/Windowing/IWindowing.cs b/Hypercube.Graphics/Windowing/IWindowing.cs index fdb8312..bd258b0 100644 --- a/Hypercube.Graphics/Windowing/IWindowing.cs +++ b/Hypercube.Graphics/Windowing/IWindowing.cs @@ -33,12 +33,12 @@ public interface IWindowing : IDisposable void WindowDestroy(WindowHandle window); void WindowSetTitle(WindowHandle window, string title); void WindowSetMonitor(WindowHandle window, MonitorHandle monitor); - void WindowSetMonitor(WindowHandle window, MonitorHandle monitor, Vector2Int vector2Int); + void WindowSetMonitor(WindowHandle window, MonitorHandle monitor, Vector2i vector2I); void WindowRequestAttention(WindowHandle window); void WindowSetOpacity(WindowHandle window, float opacity); void WindowSetVisible(WindowHandle window, bool visible); - void WindowSetSize(WindowHandle window, Vector2Int size); - void WindowSetPosition(WindowHandle window, Vector2Int position); + void WindowSetSize(WindowHandle window, Vector2i size); + void WindowSetPosition(WindowHandle window, Vector2i position); void WindowSwapBuffers(WindowHandle window); void WindowSetIcons(WindowHandle window, List images); diff --git a/Hypercube.Graphics/Windowing/WindowCreateSettings.cs b/Hypercube.Graphics/Windowing/WindowCreateSettings.cs index 22861e2..4e10419 100644 --- a/Hypercube.Graphics/Windowing/WindowCreateSettings.cs +++ b/Hypercube.Graphics/Windowing/WindowCreateSettings.cs @@ -12,7 +12,7 @@ public sealed class WindowCreateSettings public int Height => Size.Y; public string Title { get; init; } = "Hypercube Window"; - public Vector2Int Size { get; init; } = new(1280, 720); + public Vector2i Size { get; init; } = new(1280, 720); public ITexture[]? WindowImages { get; init; } public MonitorHandle? Monitor { get; init; } diff --git a/Hypercube.Graphics/Windowing/WindowHandle.cs b/Hypercube.Graphics/Windowing/WindowHandle.cs index 9a230fc..ca1e5f1 100644 --- a/Hypercube.Graphics/Windowing/WindowHandle.cs +++ b/Hypercube.Graphics/Windowing/WindowHandle.cs @@ -13,8 +13,8 @@ public abstract class WindowHandle public bool DisposeOnClose { get; } public bool IsDisposed { get; } public float Ratio { get; init; } - public Vector2Int Size { get; set; } - public Vector2Int FramebufferSize { get; init; } + public Vector2i Size { get; set; } + public Vector2i FramebufferSize { get; init; } protected WindowHandle(WindowId id, nint pointer) { @@ -22,14 +22,14 @@ protected WindowHandle(WindowId id, nint pointer) Pointer = pointer; } - public void SetSize(Vector2Int size) + public void SetSize(Vector2i size) { Size = size; } public void SetSize(int width, int height) { - Size = new Vector2Int(width, height); + Size = new Vector2i(width, height); } public override string ToString() diff --git a/Hypercube.ImGui/IImGuiController.cs b/Hypercube.ImGui/IImGuiController.cs index 01feeb5..6282c32 100644 --- a/Hypercube.ImGui/IImGuiController.cs +++ b/Hypercube.ImGui/IImGuiController.cs @@ -14,7 +14,7 @@ public interface IImGuiController : IImGui void Render(); void InputFrame(); - void UpdateMousePosition(Vector2Int position); + void UpdateMousePosition(Vector2i position); void UpdateKey(Key key, KeyState state, KeyModifiers modifiers); void UpdateMouseButtons(MouseButton button, KeyState state, KeyModifiers modifiers); void UpdateMouseScroll(Vector2 offset); diff --git a/Hypercube.ImGui/Implementations/OpenGLImGuiController.Input.cs b/Hypercube.ImGui/Implementations/OpenGLImGuiController.Input.cs index c88bf67..331032a 100644 --- a/Hypercube.ImGui/Implementations/OpenGLImGuiController.Input.cs +++ b/Hypercube.ImGui/Implementations/OpenGLImGuiController.Input.cs @@ -14,7 +14,7 @@ public void InputFrame() { } - public void UpdateMousePosition(Vector2Int position) + public void UpdateMousePosition(Vector2i position) { _io.MousePos = position; } diff --git a/Hypercube.ImGui/Implementations/OpenGLImGuiController.Render.cs b/Hypercube.ImGui/Implementations/OpenGLImGuiController.Render.cs index b4024b3..1281b2c 100644 --- a/Hypercube.ImGui/Implementations/OpenGLImGuiController.Render.cs +++ b/Hypercube.ImGui/Implementations/OpenGLImGuiController.Render.cs @@ -25,7 +25,7 @@ private void Render(ImDrawDataPtr data) if (data.CmdListsCount == 0) return; - var frameBufferSize = new Vector2Int( + var frameBufferSize = new Vector2i( data.DisplaySize.X * data.FramebufferScale.X, data.DisplaySize.Y * data.FramebufferScale.Y); @@ -128,7 +128,7 @@ private void Render(ImDrawDataPtr data) GL.Disable(EnableCap.ScissorTest); } - private void SetupRender(ImDrawDataPtr data, Vector2Int frameBufferSize) + private void SetupRender(ImDrawDataPtr data, Vector2i frameBufferSize) { GL.Enable(EnableCap.Blend); GL.Enable(EnableCap.ScissorTest); diff --git a/Hypercube.Mathematics/Vectors/Vector2.Compatibility.cs b/Hypercube.Mathematics/Vectors/Vector2.Compatibility.cs index 56ced34..4fdfd63 100644 --- a/Hypercube.Mathematics/Vectors/Vector2.Compatibility.cs +++ b/Hypercube.Mathematics/Vectors/Vector2.Compatibility.cs @@ -9,9 +9,9 @@ public readonly partial struct Vector2 */ [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static implicit operator Vector2Int(Vector2 vector) + public static implicit operator Vector2i(Vector2 vector) { - return new Vector2Int((int)vector.X, (int)vector.Y); + return new Vector2i((int)vector.X, (int)vector.Y); } [MethodImpl(MethodImplOptions.AggressiveInlining)] diff --git a/Hypercube.Mathematics/Vectors/Vector2Int.Compatibility.cs b/Hypercube.Mathematics/Vectors/Vector2i.Compatibility.cs similarity index 64% rename from Hypercube.Mathematics/Vectors/Vector2Int.Compatibility.cs rename to Hypercube.Mathematics/Vectors/Vector2i.Compatibility.cs index e61341d..c9cd71d 100644 --- a/Hypercube.Mathematics/Vectors/Vector2Int.Compatibility.cs +++ b/Hypercube.Mathematics/Vectors/Vector2i.Compatibility.cs @@ -2,20 +2,20 @@ namespace Hypercube.Mathematics.Vectors; -public readonly partial struct Vector2Int +public readonly partial struct Vector2i { /* * Self Compatibility */ [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static implicit operator Vector2(Vector2Int vector) + public static implicit operator Vector2(Vector2i vector) { return new Vector2(vector.X, vector.Y); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static implicit operator Vector3(Vector2Int vector) + public static implicit operator Vector3(Vector2i vector) { return new Vector3(vector.X, vector.Y, 0f); } @@ -25,13 +25,13 @@ public static implicit operator Vector3(Vector2Int vector) */ [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static implicit operator Vector2Int((int x, int y) a) + public static implicit operator Vector2i((int x, int y) a) { - return new Vector2Int(a.x, a.y); + return new Vector2i(a.x, a.y); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static implicit operator (int x, int y)(Vector2Int a) + public static implicit operator (int x, int y)(Vector2i a) { return (a.X, a.Y); } @@ -41,13 +41,13 @@ public static implicit operator (int x, int y)(Vector2Int a) */ [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static implicit operator Vector2Int(System.Numerics.Vector2 vector) + public static implicit operator Vector2i(System.Numerics.Vector2 vector) { - return new Vector2Int((int)vector.X, (int)vector.Y); + return new Vector2i((int)vector.X, (int)vector.Y); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static implicit operator System.Numerics.Vector2(Vector2Int vector) + public static implicit operator System.Numerics.Vector2(Vector2i vector) { return new System.Numerics.Vector2(vector.X, vector.Y); } @@ -57,13 +57,13 @@ public static implicit operator System.Numerics.Vector2(Vector2Int vector) */ [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static implicit operator Vector2Int(System.Drawing.Size size) + public static implicit operator Vector2i(System.Drawing.Size size) { - return new Vector2Int(size.Width, size.Height); + return new Vector2i(size.Width, size.Height); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static implicit operator System.Drawing.Size(Vector2Int vector2) + public static implicit operator System.Drawing.Size(Vector2i vector2) { return new System.Drawing.Size(vector2.X, vector2.Y); } @@ -73,13 +73,13 @@ public static implicit operator System.Drawing.Size(Vector2Int vector2) */ [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static implicit operator Vector2Int(OpenTK.Mathematics.Vector2i vector) + public static implicit operator Vector2i(OpenTK.Mathematics.Vector2i vector) { - return new Vector2Int(vector.X, vector.Y); + return new Vector2i(vector.X, vector.Y); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static implicit operator OpenTK.Mathematics.Vector2i(Vector2Int vector) + public static implicit operator OpenTK.Mathematics.Vector2i(Vector2i vector) { return new OpenTK.Mathematics.Vector2i(vector.X, vector.Y); } @@ -89,13 +89,13 @@ public static implicit operator OpenTK.Mathematics.Vector2i(Vector2Int vector) */ [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static implicit operator Vector2Int(OpenToolkit.Mathematics.Vector2i vector) + public static implicit operator Vector2i(OpenToolkit.Mathematics.Vector2i vector) { - return new Vector2Int(vector.X, vector.Y); + return new Vector2i(vector.X, vector.Y); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static implicit operator OpenToolkit.Mathematics.Vector2i(Vector2Int vector) + public static implicit operator OpenToolkit.Mathematics.Vector2i(Vector2i vector) { return new OpenToolkit.Mathematics.Vector2i(vector.X, vector.Y); } diff --git a/Hypercube.Mathematics/Vectors/Vector2Int.cs b/Hypercube.Mathematics/Vectors/Vector2i.cs similarity index 65% rename from Hypercube.Mathematics/Vectors/Vector2Int.cs rename to Hypercube.Mathematics/Vectors/Vector2i.cs index 82795d2..f262840 100644 --- a/Hypercube.Mathematics/Vectors/Vector2Int.cs +++ b/Hypercube.Mathematics/Vectors/Vector2i.cs @@ -1,4 +1,5 @@ using System.Collections; +using System.Diagnostics.CodeAnalysis; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using JetBrains.Annotations; @@ -6,27 +7,28 @@ namespace Hypercube.Mathematics.Vectors; [PublicAPI, Serializable, StructLayout(LayoutKind.Sequential)] -public readonly partial struct Vector2Int : IEquatable, IComparable, IComparable, IEnumerable +[SuppressMessage("ReSharper", "InconsistentNaming")] +public readonly partial struct Vector2i : IEquatable, IComparable, IComparable, IEnumerable { /// /// Vector (0, 0). /// - public static readonly Vector2Int Zero = new(0); + public static readonly Vector2i Zero = new(0); /// /// Vector (1, 1). /// - public static readonly Vector2Int One = new(1); + public static readonly Vector2i One = new(1); /// /// Vector (1, 0). /// - public static readonly Vector2Int UnitX = new(1, 0); + public static readonly Vector2i UnitX = new(1, 0); /// /// Vector (0, 1). /// - public static readonly Vector2Int UnitY = new(0, 1); + public static readonly Vector2i UnitY = new(0, 1); /// /// Vector X component. @@ -56,7 +58,7 @@ public float Length get => 1f / MathF.ReciprocalSqrtEstimate(LengthSquared); } - public Vector2Int Normalized + public Vector2i Normalized { [MethodImpl(MethodImplOptions.AggressiveInlining)] get => this / Length; @@ -94,108 +96,108 @@ public int this[int index] } } - public Vector2Int(int x, int y) + public Vector2i(int x, int y) { X = x; Y = y; } - public Vector2Int(int value) + public Vector2i(int value) { X = value; Y = value; } - public Vector2Int(float x, float y) + public Vector2i(float x, float y) { X = (int) x; Y = (int) y; } - public Vector2Int(float value) + public Vector2i(float value) { X = (int) value; Y = (int) value; } - public Vector2Int(Vector2Int value) + public Vector2i(Vector2i value) { X = value.X; Y = value.Y; } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public Vector2Int WithX(int value) + public Vector2i WithX(int value) { - return new Vector2Int(value, Y); + return new Vector2i(value, Y); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public Vector2Int WithY(int value) + public Vector2i WithY(int value) { - return new Vector2Int(X, value); + return new Vector2i(X, value); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public float DistanceSquared(Vector2Int value) + public float DistanceSquared(Vector2i value) { return (this - value).LengthSquared; } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public float Distance(Vector2Int value) + public float Distance(Vector2i value) { return MathF.Sqrt(DistanceSquared(this, value)); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public float Dot(Vector2Int value) + public float Dot(Vector2i value) { return Dot(this, value); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public Vector2Int Clamp(Vector2Int min, Vector2Int max) + public Vector2i Clamp(Vector2i min, Vector2i max) { return Clamp(this, min, max); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public Vector2Int Clamp(int min, int max) + public Vector2i Clamp(int min, int max) { return Clamp(this, min, max); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public Vector2Int Max(Vector2Int value) + public Vector2i Max(Vector2i value) { return Max(this, value); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public Vector2Int Min(Vector2Int value) + public Vector2i Min(Vector2i value) { return Min(this, value); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public Vector2Int Abs() + public Vector2i Abs() { return Abs(this); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public Vector2Int MoveTowards(Vector2Int target, int distance) + public Vector2i MoveTowards(Vector2i target, int distance) { return MoveTowards(this, target, distance); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public Vector2Int Rotate(float angle) + public Vector2i Rotate(float angle) { var cos = MathF.Cos(angle); var sin = MathF.Sin(angle); - return new Vector2Int( + return new Vector2i( cos * X - sin * Y, sin * X + cos * Y); } @@ -207,7 +209,7 @@ public int CompareTo(int other) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public int CompareTo(Vector2Int other) + public int CompareTo(Vector2i other) { return LengthSquared.CompareTo(other.LengthSquared); } @@ -226,7 +228,7 @@ IEnumerator IEnumerable.GetEnumerator() } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public bool Equals(Vector2Int other) + public bool Equals(Vector2i other) { return X == other.X && Y == other.Y; @@ -235,7 +237,7 @@ public bool Equals(Vector2Int other) [MethodImpl(MethodImplOptions.AggressiveInlining)] public override bool Equals(object? obj) { - return obj is Vector2Int vector && Equals(vector); + return obj is Vector2i vector && Equals(vector); } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -251,201 +253,201 @@ public override string ToString() } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Vector2Int operator +(Vector2Int a, Vector2Int b) + public static Vector2i operator +(Vector2i a, Vector2i b) { - return new Vector2Int(a.X + b.X, a.Y + b.Y); + return new Vector2i(a.X + b.X, a.Y + b.Y); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Vector2Int operator +(Vector2Int a, int b) + public static Vector2i operator +(Vector2i a, int b) { - return new Vector2Int(a.X + b, a.Y + b); + return new Vector2i(a.X + b, a.Y + b); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Vector2Int operator -(Vector2Int a) + public static Vector2i operator -(Vector2i a) { - return new Vector2Int(-a.X, -a.Y); + return new Vector2i(-a.X, -a.Y); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Vector2Int operator -(Vector2Int a, Vector2Int b) + public static Vector2i operator -(Vector2i a, Vector2i b) { - return new Vector2Int(a.X - b.X, a.Y - b.Y); + return new Vector2i(a.X - b.X, a.Y - b.Y); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Vector2Int operator -(Vector2Int a, int b) + public static Vector2i operator -(Vector2i a, int b) { - return new Vector2Int(a.X - b, a.Y - b); + return new Vector2i(a.X - b, a.Y - b); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Vector2Int operator *(Vector2Int a, Vector2Int b) + public static Vector2i operator *(Vector2i a, Vector2i b) { - return new Vector2Int(a.X * b.X, a.Y * b.Y); + return new Vector2i(a.X * b.X, a.Y * b.Y); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Vector2Int operator *(Vector2Int a, int b) + public static Vector2i operator *(Vector2i a, int b) { - return new Vector2Int(a.X * b, a.Y * b); + return new Vector2i(a.X * b, a.Y * b); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Vector2Int operator *(Vector2Int a, float b) + public static Vector2i operator *(Vector2i a, float b) { - return new Vector2Int(a.X * b, a.Y * b); + return new Vector2i(a.X * b, a.Y * b); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Vector2Int operator /(Vector2Int a, Vector2Int b) + public static Vector2i operator /(Vector2i a, Vector2i b) { - return new Vector2Int(a.X / b.X, a.Y / b.Y); + return new Vector2i(a.X / b.X, a.Y / b.Y); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Vector2Int operator /(Vector2Int a, int b) + public static Vector2i operator /(Vector2i a, int b) { - return new Vector2Int(a.X / b, a.Y / b); + return new Vector2i(a.X / b, a.Y / b); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Vector2Int operator /(Vector2Int a, float b) + public static Vector2i operator /(Vector2i a, float b) { - return new Vector2Int(a.X / b, a.Y / b); + return new Vector2i(a.X / b, a.Y / b); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool operator ==(Vector2Int a, Vector2Int b) + public static bool operator ==(Vector2i a, Vector2i b) { return a.Equals(b); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool operator !=(Vector2Int a, Vector2Int b) + public static bool operator !=(Vector2i a, Vector2i b) { return !a.Equals(b); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool operator <(Vector2Int a, Vector2Int b) + public static bool operator <(Vector2i a, Vector2i b) { return a.CompareTo(b) == -1; } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool operator >(Vector2Int a, Vector2Int b) + public static bool operator >(Vector2i a, Vector2i b) { return a.CompareTo(b) == 1; } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool operator <=(Vector2Int a, Vector2Int b) + public static bool operator <=(Vector2i a, Vector2i b) { return a.CompareTo(b) is -1 or 0; } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool operator >=(Vector2Int a, Vector2Int b) + public static bool operator >=(Vector2i a, Vector2i b) { return a.CompareTo(b) is 1 or 0; } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool operator <(Vector2Int a, int b) + public static bool operator <(Vector2i a, int b) { return a.CompareTo(b) == -1; } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool operator >(Vector2Int a, int b) + public static bool operator >(Vector2i a, int b) { return a.CompareTo(b) == 1; } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool operator <=(Vector2Int a, int b) + public static bool operator <=(Vector2i a, int b) { return a.CompareTo(b) is -1 or 0; } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool operator >=(Vector2Int a, int b) + public static bool operator >=(Vector2i a, int b) { return a.CompareTo(b) is 1 or 0; } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static float DistanceSquared(Vector2Int valueA, Vector2Int valueB) + public static float DistanceSquared(Vector2i valueA, Vector2i valueB) { return (valueA - valueB).LengthSquared; } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static float Distance(Vector2Int valueA, Vector2Int valueB) + public static float Distance(Vector2i valueA, Vector2i valueB) { return MathF.Sqrt(DistanceSquared(valueA, valueB)); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static float Dot(Vector2Int valueA, Vector2Int valueB) + public static float Dot(Vector2i valueA, Vector2i valueB) { return valueA.X * valueB.X + valueA.Y * valueB.Y; } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Vector2Int MoveTowards(Vector2Int current, Vector2Int target, int distance) + public static Vector2i MoveTowards(Vector2i current, Vector2i target, int distance) { - return new Vector2Int( + return new Vector2i( HyperMathF.MoveTowards(current.X, target.X, distance), HyperMathF.MoveTowards(current.Y, target.Y, distance)); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Vector2Int Clamp(Vector2Int value, Vector2Int min, Vector2Int max) + public static Vector2i Clamp(Vector2i value, Vector2i min, Vector2i max) { - return new Vector2Int( + return new Vector2i( int.Clamp(value.X, min.X, max.X), int.Clamp(value.Y, min.Y, max.Y)); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Vector2Int Clamp(Vector2Int value, int min, int max) + public static Vector2i Clamp(Vector2i value, int min, int max) { - return new Vector2Int( + return new Vector2i( int.Clamp(value.X, min, max), int.Clamp(value.Y, min, max)); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Vector2Int Max(Vector2Int valueA, Vector2Int valueB) + public static Vector2i Max(Vector2i valueA, Vector2i valueB) { - return new Vector2Int( + return new Vector2i( MathF.Max(valueA.X, valueB.X), MathF.Max(valueA.Y, valueB.Y)); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Vector2Int Min(Vector2Int valueA, Vector2Int valueB) + public static Vector2i Min(Vector2i valueA, Vector2i valueB) { - return new Vector2Int( + return new Vector2i( MathF.Min(valueA.X, valueB.X), MathF.Min(valueA.Y, valueB.Y)); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Vector2Int Abs(Vector2Int value) + public static Vector2i Abs(Vector2i value) { - return new Vector2Int( + return new Vector2i( Math.Abs(value.X), Math.Abs(value.Y)); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Vector2Int Sign(Vector2Int value) + public static Vector2i Sign(Vector2i value) { - return new Vector2Int( + return new Vector2i( Math.Sign(value.X), Math.Sign(value.Y)); } diff --git a/Hypercube.Mathematics/Vectors/Vector3.Compatibility.cs b/Hypercube.Mathematics/Vectors/Vector3.Compatibility.cs index 053a786..50247b3 100644 --- a/Hypercube.Mathematics/Vectors/Vector3.Compatibility.cs +++ b/Hypercube.Mathematics/Vectors/Vector3.Compatibility.cs @@ -15,9 +15,9 @@ public static implicit operator Vector2(Vector3 vector) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static implicit operator Vector2Int(Vector3 vector) + public static implicit operator Vector2i(Vector3 vector) { - return new Vector2Int((int)vector.X, (int)vector.Y); + return new Vector2i((int)vector.X, (int)vector.Y); } /* diff --git a/Hypercube.OpenGL/Shaders/ShaderProgram.cs b/Hypercube.OpenGL/Shaders/ShaderProgram.cs index 298db1b..e6b3c1a 100644 --- a/Hypercube.OpenGL/Shaders/ShaderProgram.cs +++ b/Hypercube.OpenGL/Shaders/ShaderProgram.cs @@ -97,7 +97,7 @@ public void SetUniform(string name, Vector2 value) GL.Uniform2(_uniformLocations[name], value.X, value.Y); } - public void SetUniform(string name, Vector2Int value) + public void SetUniform(string name, Vector2i value) { GL.Uniform2(_uniformLocations[name], value.X, value.Y); } diff --git a/Hypercube.OpenGL/Utilities/Helpers/GLFWHelper.cs b/Hypercube.OpenGL/Utilities/Helpers/GLFWHelper.cs index 90e0caa..e065038 100644 --- a/Hypercube.OpenGL/Utilities/Helpers/GLFWHelper.cs +++ b/Hypercube.OpenGL/Utilities/Helpers/GLFWHelper.cs @@ -6,28 +6,28 @@ namespace Hypercube.OpenGL.Utilities.Helpers; public static unsafe class GLFWHelper { - public static void GetFramebufferSize(Window* window, out Vector2Int framebufferSize) + public static void GetFramebufferSize(Window* window, out Vector2i framebufferSize) { GLFW.GetFramebufferSize(window, out var x, out var y); - framebufferSize = new Vector2Int(x, y); + framebufferSize = new Vector2i(x, y); } - public static void GetFramebufferSize(nint window, out Vector2Int framebufferSize) + public static void GetFramebufferSize(nint window, out Vector2i framebufferSize) { GLFW.GetFramebufferSize((Window*)window, out var x, out var y); - framebufferSize = new Vector2Int(x, y); + framebufferSize = new Vector2i(x, y); } - public static void GetWindowSize(Window* window, out Vector2Int size) + public static void GetWindowSize(Window* window, out Vector2i size) { GLFW.GetWindowSize(window, out var x, out var y); - size = new Vector2Int(x, y); + size = new Vector2i(x, y); } - public static void GetWindowSize(nint window, out Vector2Int size) + public static void GetWindowSize(nint window, out Vector2i size) { GLFW.GetWindowSize((Window*)window, out var x, out var y); - size = new Vector2Int(x, y); + size = new Vector2i(x, y); } public static string FormatError(ErrorCode error, string description) diff --git a/Hypercube.Shared/Physics/Chunk.cs b/Hypercube.Shared/Physics/Chunk.cs index 8475262..9e35b24 100644 --- a/Hypercube.Shared/Physics/Chunk.cs +++ b/Hypercube.Shared/Physics/Chunk.cs @@ -10,14 +10,14 @@ namespace Hypercube.Shared.Physics; /// public sealed class Chunk { - public readonly Vector2Int Position; + public readonly Vector2i Position; private HashSet _bodies = new(); public IReadOnlySet Bodies => _bodies; public bool ContainBodes => _bodies.Count != 0; - public Chunk(Vector2Int position) + public Chunk(Vector2i position) { Position = position; } From cef46d21ea272477b7d113020e8be5e9b66bd180 Mon Sep 17 00:00:00 2001 From: Tornado Tech <54727692+Tornado-Technology@users.noreply.github.com> Date: Thu, 29 Aug 2024 16:14:31 +1000 Subject: [PATCH 11/15] Added vector3i --- Hypercube.Mathematics/HyperMath.cs | 7 + .../Vectors/Vector2i.Compatibility.cs | 4 +- Hypercube.Mathematics/Vectors/Vector3.cs | 2 +- .../Vectors/Vector3i.Compability.cs | 82 +++ Hypercube.Mathematics/Vectors/Vector3i.cs | 475 ++++++++++++++++++ Hypercube.Mathematics/Vectors/Vector4.cs | 2 +- 6 files changed, 569 insertions(+), 3 deletions(-) create mode 100644 Hypercube.Mathematics/Vectors/Vector3i.Compability.cs create mode 100644 Hypercube.Mathematics/Vectors/Vector3i.cs diff --git a/Hypercube.Mathematics/HyperMath.cs b/Hypercube.Mathematics/HyperMath.cs index e272ae5..685f4d7 100644 --- a/Hypercube.Mathematics/HyperMath.cs +++ b/Hypercube.Mathematics/HyperMath.cs @@ -13,4 +13,11 @@ public static class HyperMath public const double RadiansToDegrees = 180 / PI; public const double DegreesToRadians = PI / 180; + + public static int MoveTowards(int current, int target, int distance) + { + return current < target ? + Math.Min(current + distance, target) : + Math.Max(current - distance, target); + } } \ No newline at end of file diff --git a/Hypercube.Mathematics/Vectors/Vector2i.Compatibility.cs b/Hypercube.Mathematics/Vectors/Vector2i.Compatibility.cs index c9cd71d..1758147 100644 --- a/Hypercube.Mathematics/Vectors/Vector2i.Compatibility.cs +++ b/Hypercube.Mathematics/Vectors/Vector2i.Compatibility.cs @@ -1,7 +1,9 @@ -using System.Runtime.CompilerServices; +using System.Diagnostics.CodeAnalysis; +using System.Runtime.CompilerServices; namespace Hypercube.Mathematics.Vectors; +[SuppressMessage("ReSharper", "InconsistentNaming")] public readonly partial struct Vector2i { /* diff --git a/Hypercube.Mathematics/Vectors/Vector3.cs b/Hypercube.Mathematics/Vectors/Vector3.cs index 6df453a..29a6668 100644 --- a/Hypercube.Mathematics/Vectors/Vector3.cs +++ b/Hypercube.Mathematics/Vectors/Vector3.cs @@ -302,7 +302,7 @@ public int CompareTo(Vector3 other) [MethodImpl(MethodImplOptions.AggressiveInlining)] public int CompareTo(float other) { - return LengthSquared.CompareTo(other * other * other); + return LengthSquared.CompareTo(other * other); } [MethodImpl(MethodImplOptions.AggressiveInlining)] diff --git a/Hypercube.Mathematics/Vectors/Vector3i.Compability.cs b/Hypercube.Mathematics/Vectors/Vector3i.Compability.cs new file mode 100644 index 0000000..bafecab --- /dev/null +++ b/Hypercube.Mathematics/Vectors/Vector3i.Compability.cs @@ -0,0 +1,82 @@ +using System.Diagnostics.CodeAnalysis; +using System.Runtime.CompilerServices; + +namespace Hypercube.Mathematics.Vectors; + +[SuppressMessage("ReSharper", "InconsistentNaming")] +public readonly partial struct Vector3i +{ + /* + * Self Compatibility + */ + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static implicit operator Vector3(Vector3i value) + { + return new Vector3(value.X, value.Y, value.Z); + } + + /* + * Tuple Compatibility + */ + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static implicit operator Vector3i((int x, int y, int z) value) + { + return new Vector3i(value.x, value.y, value.z); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static implicit operator (int x, int y, int z)(Vector3i value) + { + return (value.X, value.Y, value.Z); + } + + /* + * System.Numerics Compatibility + */ + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static implicit operator Vector3i(System.Numerics.Vector3 value) + { + return new Vector3i((int) value.X, (int) value.Y, (int) value.Z); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static implicit operator System.Numerics.Vector3(Vector3i value) + { + return new System.Numerics.Vector3(value.X, value.Y, value.Z); + } + + /* + * OpenTK Compatibility + */ + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static implicit operator Vector3i(OpenTK.Mathematics.Vector3i value) + { + return new Vector3i(value.X, value.Y, value.Z); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static implicit operator OpenTK.Mathematics.Vector3i(Vector3i value) + { + return new OpenTK.Mathematics.Vector3i(value.X, value.Y, value.Z); + } + + /* + * OpenToolkit Compatibility + */ + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static implicit operator Vector3i(OpenToolkit.Mathematics.Vector3i vector) + { + return new Vector3i(vector.X, vector.Y, vector.Z); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static implicit operator OpenToolkit.Mathematics.Vector3i(Vector3i vector) + { + return new OpenToolkit.Mathematics.Vector3i(vector.X, vector.Y, vector.Z); + } +} \ No newline at end of file diff --git a/Hypercube.Mathematics/Vectors/Vector3i.cs b/Hypercube.Mathematics/Vectors/Vector3i.cs new file mode 100644 index 0000000..82aa87b --- /dev/null +++ b/Hypercube.Mathematics/Vectors/Vector3i.cs @@ -0,0 +1,475 @@ +using System.Collections; +using System.Diagnostics.CodeAnalysis; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using JetBrains.Annotations; + +namespace Hypercube.Mathematics.Vectors; + +[PublicAPI, Serializable, StructLayout(LayoutKind.Sequential)] +[SuppressMessage("ReSharper", "InconsistentNaming")] +public readonly partial struct Vector3i : IEquatable, IComparable, IComparable, IEnumerable +{ + /// + /// Vector (0, 0, 0). + /// + public static readonly Vector3i Zero = new(0, 0, 0); + + /// + /// Vector (1, 1, 1). + /// + public static readonly Vector3i One = new(1, 1, 1); + + /// + /// Vector (1, 0, 0). + /// + public static readonly Vector3i UnitX = new(1, 0, 0); + + /// + /// Vector (0, 1, 0). + /// + public static readonly Vector3i UnitY = new(0, 1, 0); + + /// + /// Vector (0, 0, 1). + /// + public static readonly Vector3i UnitZ = new(0, 0, 1); + + /// + /// Vector X component. + /// + public readonly int X; + + /// + /// Vector Y component. + /// + public readonly int Y; + + /// + /// Vector Z component. + /// + public readonly int Z; + + /// + /// Gets the square of the vector length (magnitude). + /// + /// + /// Allows you to avoid using the rather expensive sqrt operation. + /// (On ARM64 hardware may use the FRSQRTE instruction, which would take away this advantage). + /// + /// + public float LengthSquared + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get => X * X + Y * Y + Z * Z; + } + + /// + /// Gets the length (magnitude) of the vector. + /// + /// + /// On ARM64 hardware this may use the FRSQRTE instruction + /// which performs a single Newton-Raphson iteration. + /// On hardware without specialized support + /// sqrt is used, which makes the method less fast. + /// + /// + public float Length + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get => 1f / MathF.ReciprocalSqrtEstimate(LengthSquared); + } + + /// + /// Summation of all vector components. + /// + public int Summation + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get => X + Y + Z; + } + + /// + /// Production of all vector components. + /// + public int Production + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get => X * Y * Z; + } + + public Vector2i XY + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get => new(X, Y); + } + + public Vector3i(int x, int y, int z) + { + X = x; + Y = y; + Z = z; + } + + public Vector3i(int value) + { + X = value; + Y = value; + Z = value; + } + + public Vector3i(Vector2i value) + { + X = value.X; + Y = value.Y; + Z = 0; + } + + public Vector3i(Vector2i value, int z) + { + X = value.X; + Y = value.Y; + Z = z; + } + + public Vector3i(Vector3i value) + { + X = value.X; + Y = value.Y; + Z = value.Z; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Vector3i WithX(int value) + { + return new Vector3i(value, Y, Z); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Vector3i WithY(int value) + { + return new Vector3i(X, value, Z); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Vector3i WithZ(int value) + { + return new Vector3i(X, Y, value); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public float DistanceSquared(Vector3i value) + { + return (this - value).LengthSquared; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public float Distance(Vector3i value) + { + return MathF.Sqrt(DistanceSquared(value)); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Vector3i Cross(Vector3i value) + { + return Cross(this, value); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public float Dot(Vector3i value) + { + return Dot(this, value); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Vector3i Reflect(Vector3i normal) + { + return Reflect(this, normal); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Vector3i MoveTowards(Vector3i target, int distance) + { + return MoveTowards(this, target, distance); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Vector3i Clamp(Vector3i min, Vector3i max) + { + return Clamp(this, min, max); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Vector3i Clamp(int min, int max) + { + return Clamp(this, min, max); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Vector3i Max(Vector3i value) + { + return Max(this, value); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Vector3i Min(Vector3i value) + { + return Min(this, value); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Vector3i Abs() + { + return Abs(this); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public int CompareTo(int other) + { + return LengthSquared.CompareTo(other * other); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public int CompareTo(Vector3i other) + { + return LengthSquared.CompareTo(other.LengthSquared); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public IEnumerator GetEnumerator() + { + yield return X; + yield return Y; + yield return Z; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + IEnumerator IEnumerable.GetEnumerator() + { + return GetEnumerator(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool Equals(Vector3i other) + { + return X == other.X && + Y == other.Y && + Z == other.Z; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public override bool Equals(object? obj) + { + return obj is Vector3i other && Equals(other); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public override int GetHashCode() + { + return HashCode.Combine(X, Y, Z); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public override string ToString() + { + return $"{X}, {Y}, {Z}"; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector3i operator +(Vector3i a, Vector3i b) + { + return new Vector3i(a.X + b.X, a.Y + b.Y, a.Z + b.Z); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector3i operator +(Vector3i a, Vector2i b) + { + return new Vector3i(a.X + b.X, a.Y + b.Y, a.Z); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector3i operator +(Vector3i a, int b) + { + return new Vector3i(a.X + b, a.Y + b, a.Z + b); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector3i operator -(Vector3i a) + { + return new Vector3i(-a.X, -a.Y, -a.Z); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector3i operator -(Vector3i a, Vector3i b) + { + return new Vector3i(a.X - b.X, a.Y - b.Y, a.Z - b.Z); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector3i operator -(Vector3i a, Vector2i b) + { + return new Vector3i(a.X - b.X, a.Y - b.Y, a.Z); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector3i operator -(Vector3i a, int b) + { + return new Vector3i(a.X - b, a.Y - b, a.Z - b); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector3i operator *(Vector3i a, Vector3i b) + { + return new Vector3i(a.X * b.X, a.Y * b.Y, a.Z * b.Z); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector3i operator *(Vector3i a, Vector2i b) + { + return new Vector3i(a.X * b.X, a.Y * b.Y, a.Z); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector3i operator *(Vector3i a, int b) + { + return new Vector3i(a.X * b, a.Y * b, a.Z * b); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector3i operator *(int a, Vector3i b) + { + return new Vector3i(a * b.X, a * b.Y, a * b.Z); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector3i operator /(Vector3i a, Vector3i b) + { + return new Vector3i(a.X / b.X, a.Y / b.Y, a.Z / b.Z); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector3i operator /(Vector3i a, Vector2i b) + { + return new Vector3i(a.X / b.X, a.Y / b.Y, a.Z); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector3i operator /(Vector3i a, int b) + { + return new Vector3i(a.X / b, a.Y / b, a.Z / b); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector3i operator /(int a, Vector3i b) + { + return new Vector3i(a / b.X, a / b.Y, a / b.Z); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool operator ==(Vector3i a, Vector3i b) + { + return a.Equals(b); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool operator !=(Vector3i a, Vector3i b) + { + return !a.Equals(b); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static float DistanceSquared(Vector2 valueA, Vector2 valueB) + { + return (valueA - valueB).LengthSquared; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static float Distance(Vector2 valueA, Vector2 valueB) + { + return MathF.Sqrt(DistanceSquared(valueA, valueB)); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector3i Cross(Vector3i valueA, Vector3i valueB) + { + return new Vector3i( + valueA.Y * valueB.Z - valueA.Z * valueB.Y, + valueA.Z * valueB.X - valueA.X * valueB.Z, + valueA.X * valueB.Y - valueA.Y * valueB.X); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int Dot(Vector3i valueA, Vector3i valueB) + { + return valueA.X * valueB.X + valueA.Y * valueB.Y + valueA.Z * valueB.Z; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector3i Reflect(Vector3i value, Vector3i normal) + { + return value - 2 * (Dot(value, normal) * normal); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector3i MoveTowards(Vector3i current, Vector3i target, int distance) + { + return new Vector3i( + HyperMath.MoveTowards(current.X, target.X, distance), + HyperMath.MoveTowards(current.Y, target.Y, distance), + HyperMath.MoveTowards(current.Z, target.Z, distance)); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector3i Clamp(Vector3i value, Vector3i min, Vector3i max) + { + return new Vector3i( + int.Clamp(value.X, min.X, max.X), + int.Clamp(value.Y, min.Y, max.Y), + int.Clamp(value.Z, min.Z, max.Z)); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector3i Clamp(Vector3i value, int min, int max) + { + return new Vector3i( + int.Clamp(value.X, min, max), + int.Clamp(value.Y, min, max), + int.Clamp(value.Z, min, max)); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector3i Max(Vector3i valueA, Vector3i valueB) + { + return new Vector3i( + Math.Max(valueA.X, valueB.X), + Math.Max(valueA.Y, valueB.Y), + Math.Max(valueA.Z, valueB.Z)); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector3i Min(Vector3i valueA, Vector3i valueB) + { + return new Vector3i( + Math.Min(valueA.X, valueB.X), + Math.Min(valueA.Y, valueB.Y), + Math.Min(valueA.Z, valueB.Z)); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector3i Abs(Vector3i value) + { + return new Vector3i( + Math.Abs(value.X), + Math.Abs(value.Y), + Math.Abs(value.Z)); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector3i Sign(Vector3i value) + { + return new Vector3i( + Math.Sign(value.X), + Math.Sign(value.Y), + Math.Sign(value.Z)); + } +} \ No newline at end of file diff --git a/Hypercube.Mathematics/Vectors/Vector4.cs b/Hypercube.Mathematics/Vectors/Vector4.cs index e58d662..86762d1 100644 --- a/Hypercube.Mathematics/Vectors/Vector4.cs +++ b/Hypercube.Mathematics/Vectors/Vector4.cs @@ -232,7 +232,7 @@ public int CompareTo(Vector4 other) [MethodImpl(MethodImplOptions.AggressiveInlining)] public int CompareTo(float other) { - return LengthSquared.CompareTo(other * other * other * other); + return LengthSquared.CompareTo(other * other); } [MethodImpl(MethodImplOptions.AggressiveInlining)] From 73c57b854f7b9b4620bbee4de53f7cdf4374c3a4 Mon Sep 17 00:00:00 2001 From: Tornado Tech <54727692+Tornado-Technology@users.noreply.github.com> Date: Thu, 29 Aug 2024 16:16:22 +1000 Subject: [PATCH 12/15] Added this property --- Hypercube.Mathematics/Vectors/Vector3.cs | 15 +++++++++++++++ Hypercube.Mathematics/Vectors/Vector3i.cs | 15 +++++++++++++++ Hypercube.Mathematics/Vectors/Vector4.cs | 16 ++++++++++++++++ 3 files changed, 46 insertions(+) diff --git a/Hypercube.Mathematics/Vectors/Vector3.cs b/Hypercube.Mathematics/Vectors/Vector3.cs index 29a6668..a778ec3 100644 --- a/Hypercube.Mathematics/Vectors/Vector3.cs +++ b/Hypercube.Mathematics/Vectors/Vector3.cs @@ -130,6 +130,21 @@ public Vector2 XY get => new(X, Y); } + public float this[int index] + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get + { + return index switch + { + 0 => X, + 1 => Y, + 2 => Z, + _ => throw new ArgumentOutOfRangeException() + }; + } + } + public Vector3(float x, float y, float z) { X = x; diff --git a/Hypercube.Mathematics/Vectors/Vector3i.cs b/Hypercube.Mathematics/Vectors/Vector3i.cs index 82aa87b..b97e993 100644 --- a/Hypercube.Mathematics/Vectors/Vector3i.cs +++ b/Hypercube.Mathematics/Vectors/Vector3i.cs @@ -104,6 +104,21 @@ public Vector2i XY get => new(X, Y); } + public int this[int index] + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get + { + return index switch + { + 0 => X, + 1 => Y, + 2 => Z, + _ => throw new ArgumentOutOfRangeException() + }; + } + } + public Vector3i(int x, int y, int z) { X = x; diff --git a/Hypercube.Mathematics/Vectors/Vector4.cs b/Hypercube.Mathematics/Vectors/Vector4.cs index 86762d1..0262540 100644 --- a/Hypercube.Mathematics/Vectors/Vector4.cs +++ b/Hypercube.Mathematics/Vectors/Vector4.cs @@ -143,6 +143,22 @@ public float Production get => X * Y * Z * W; } + public float this[int index] + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get + { + return index switch + { + 0 => X, + 1 => Y, + 2 => Z, + 3 => W, + _ => throw new ArgumentOutOfRangeException() + }; + } + } + public Vector4(float x, float y, float z, float w) { X = x; From e648380e0dcaa3dadd3d6864786c917d6c2e72d2 Mon Sep 17 00:00:00 2001 From: Tornado Tech <54727692+Tornado-Technology@users.noreply.github.com> Date: Thu, 29 Aug 2024 16:18:33 +1000 Subject: [PATCH 13/15] Added sign to vector3i --- Hypercube.Mathematics/Vectors/Vector3i.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Hypercube.Mathematics/Vectors/Vector3i.cs b/Hypercube.Mathematics/Vectors/Vector3i.cs index b97e993..7419bc6 100644 --- a/Hypercube.Mathematics/Vectors/Vector3i.cs +++ b/Hypercube.Mathematics/Vectors/Vector3i.cs @@ -237,6 +237,12 @@ public Vector3i Abs() { return Abs(this); } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Vector3i Sign() + { + return Sign(this); + } [MethodImpl(MethodImplOptions.AggressiveInlining)] public int CompareTo(int other) From 52cd8d35d4590973af926bfa39b7b336c5df8333 Mon Sep 17 00:00:00 2001 From: Tornado Tech <54727692+Tornado-Technology@users.noreply.github.com> Date: Thu, 29 Aug 2024 16:20:16 +1000 Subject: [PATCH 14/15] Added DebuggerDisplay to vectors --- Hypercube.Mathematics/Vectors/Vector2i.cs | 3 ++- Hypercube.Mathematics/Vectors/Vector3.cs | 3 ++- Hypercube.Mathematics/Vectors/Vector3i.cs | 3 ++- Hypercube.Mathematics/Vectors/Vector4.cs | 3 ++- 4 files changed, 8 insertions(+), 4 deletions(-) diff --git a/Hypercube.Mathematics/Vectors/Vector2i.cs b/Hypercube.Mathematics/Vectors/Vector2i.cs index f262840..4c31f00 100644 --- a/Hypercube.Mathematics/Vectors/Vector2i.cs +++ b/Hypercube.Mathematics/Vectors/Vector2i.cs @@ -1,4 +1,5 @@ using System.Collections; +using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; @@ -6,7 +7,7 @@ namespace Hypercube.Mathematics.Vectors; -[PublicAPI, Serializable, StructLayout(LayoutKind.Sequential)] +[PublicAPI, Serializable, StructLayout(LayoutKind.Sequential), DebuggerDisplay("({X}, {Y})")] [SuppressMessage("ReSharper", "InconsistentNaming")] public readonly partial struct Vector2i : IEquatable, IComparable, IComparable, IEnumerable { diff --git a/Hypercube.Mathematics/Vectors/Vector3.cs b/Hypercube.Mathematics/Vectors/Vector3.cs index a778ec3..2b63edb 100644 --- a/Hypercube.Mathematics/Vectors/Vector3.cs +++ b/Hypercube.Mathematics/Vectors/Vector3.cs @@ -1,4 +1,5 @@ using System.Collections; +using System.Diagnostics; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using Hypercube.Mathematics.Extensions; @@ -9,7 +10,7 @@ namespace Hypercube.Mathematics.Vectors; /// /// Represents a vector with three single-precision floating-point values. /// -[PublicAPI, Serializable, StructLayout(LayoutKind.Sequential)] +[PublicAPI, Serializable, StructLayout(LayoutKind.Sequential), DebuggerDisplay("({X}, {Y}, {Z})")] public readonly partial struct Vector3 : IEquatable, IComparable, IComparable, IEnumerable { /// diff --git a/Hypercube.Mathematics/Vectors/Vector3i.cs b/Hypercube.Mathematics/Vectors/Vector3i.cs index 7419bc6..fdfbde0 100644 --- a/Hypercube.Mathematics/Vectors/Vector3i.cs +++ b/Hypercube.Mathematics/Vectors/Vector3i.cs @@ -1,4 +1,5 @@ using System.Collections; +using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; @@ -6,7 +7,7 @@ namespace Hypercube.Mathematics.Vectors; -[PublicAPI, Serializable, StructLayout(LayoutKind.Sequential)] +[PublicAPI, Serializable, StructLayout(LayoutKind.Sequential), DebuggerDisplay("({X}, {Y}, {Z})")] [SuppressMessage("ReSharper", "InconsistentNaming")] public readonly partial struct Vector3i : IEquatable, IComparable, IComparable, IEnumerable { diff --git a/Hypercube.Mathematics/Vectors/Vector4.cs b/Hypercube.Mathematics/Vectors/Vector4.cs index 0262540..47c5a25 100644 --- a/Hypercube.Mathematics/Vectors/Vector4.cs +++ b/Hypercube.Mathematics/Vectors/Vector4.cs @@ -1,4 +1,5 @@ using System.Collections; +using System.Diagnostics; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using Hypercube.Mathematics.Extensions; @@ -6,7 +7,7 @@ namespace Hypercube.Mathematics.Vectors; -[PublicAPI, Serializable, StructLayout(LayoutKind.Sequential)] +[PublicAPI, Serializable, StructLayout(LayoutKind.Sequential), DebuggerDisplay("({X}, {Y}, {Z}, {W})")] public readonly partial struct Vector4 : IEquatable, IComparable, IComparable, IEnumerable { /// From a6e45712a3791bc76cba008fad797bc3271fb537 Mon Sep 17 00:00:00 2001 From: Tornado Tech <54727692+Tornado-Technology@users.noreply.github.com> Date: Thu, 29 Aug 2024 16:40:22 +1000 Subject: [PATCH 15/15] Updated vector distance method --- Hypercube.Mathematics/Vectors/Vector2.cs | 6 +- Hypercube.Mathematics/Vectors/Vector2i.cs | 6 +- Hypercube.Mathematics/Vectors/Vector3.cs | 18 +- Hypercube.Mathematics/Vectors/Vector3i.cs | 10 +- Hypercube.Mathematics/Vectors/Vector4.cs | 285 +++++++++++++++++++++- 5 files changed, 299 insertions(+), 26 deletions(-) diff --git a/Hypercube.Mathematics/Vectors/Vector2.cs b/Hypercube.Mathematics/Vectors/Vector2.cs index 840671b..bb92c8f 100644 --- a/Hypercube.Mathematics/Vectors/Vector2.cs +++ b/Hypercube.Mathematics/Vectors/Vector2.cs @@ -189,13 +189,13 @@ public Vector2 WithY(float value) [MethodImpl(MethodImplOptions.AggressiveInlining)] public float DistanceSquared(Vector2 value) { - return (this - value).LengthSquared; + return DistanceSquared(this, value); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public float Distance(Vector2 value) { - return MathF.Sqrt(DistanceSquared(value)); + return Distance(this, value); } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -495,7 +495,7 @@ public static float DistanceSquared(Vector2 valueA, Vector2 valueB) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static float Distance(Vector2 valueA, Vector2 valueB) { - return MathF.Sqrt(DistanceSquared(valueA, valueB)); + return (valueA - valueB).Length; } [MethodImpl(MethodImplOptions.AggressiveInlining)] diff --git a/Hypercube.Mathematics/Vectors/Vector2i.cs b/Hypercube.Mathematics/Vectors/Vector2i.cs index 4c31f00..751c9cb 100644 --- a/Hypercube.Mathematics/Vectors/Vector2i.cs +++ b/Hypercube.Mathematics/Vectors/Vector2i.cs @@ -142,13 +142,13 @@ public Vector2i WithY(int value) [MethodImpl(MethodImplOptions.AggressiveInlining)] public float DistanceSquared(Vector2i value) { - return (this - value).LengthSquared; + return DistanceSquared(this, value); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public float Distance(Vector2i value) { - return MathF.Sqrt(DistanceSquared(this, value)); + return Distance(this, value); } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -388,7 +388,7 @@ public static float DistanceSquared(Vector2i valueA, Vector2i valueB) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static float Distance(Vector2i valueA, Vector2i valueB) { - return MathF.Sqrt(DistanceSquared(valueA, valueB)); + return (valueA - valueB).Length; } [MethodImpl(MethodImplOptions.AggressiveInlining)] diff --git a/Hypercube.Mathematics/Vectors/Vector3.cs b/Hypercube.Mathematics/Vectors/Vector3.cs index 2b63edb..1498dd9 100644 --- a/Hypercube.Mathematics/Vectors/Vector3.cs +++ b/Hypercube.Mathematics/Vectors/Vector3.cs @@ -216,13 +216,13 @@ public Vector3 WithZ(float value) [MethodImpl(MethodImplOptions.AggressiveInlining)] public float DistanceSquared(Vector3 value) { - return (this - value).LengthSquared; + return DistanceSquared(this, value); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public float Distance(Vector3 value) { - return MathF.Sqrt(DistanceSquared(value)); + return Distance(this, value); } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -379,6 +379,12 @@ public override string ToString() return new Vector3(a.X + b, a.Y + b, a.Z + b); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector3 operator +(float a, Vector3 b) + { + return new Vector3(a + b.X, a + b.Y, a + b.Z); + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector3 operator -(Vector3 a) { @@ -403,6 +409,12 @@ public override string ToString() return new Vector3(a.X - b, a.Y - b, a.Z - b); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector3 operator -(float a, Vector3 b) + { + return new Vector3(a - b.X, a - b.Y, a - b.Z); + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector3 operator *(Vector3 a, Vector3 b) { @@ -472,7 +484,7 @@ public static float DistanceSquared(Vector2 valueA, Vector2 valueB) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static float Distance(Vector2 valueA, Vector2 valueB) { - return MathF.Sqrt(DistanceSquared(valueA, valueB)); + return (valueA - valueB).Length; } [MethodImpl(MethodImplOptions.AggressiveInlining)] diff --git a/Hypercube.Mathematics/Vectors/Vector3i.cs b/Hypercube.Mathematics/Vectors/Vector3i.cs index fdfbde0..489db42 100644 --- a/Hypercube.Mathematics/Vectors/Vector3i.cs +++ b/Hypercube.Mathematics/Vectors/Vector3i.cs @@ -176,13 +176,13 @@ public Vector3i WithZ(int value) [MethodImpl(MethodImplOptions.AggressiveInlining)] public float DistanceSquared(Vector3i value) { - return (this - value).LengthSquared; + return DistanceSquared(this, value); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public float Distance(Vector3i value) { - return MathF.Sqrt(DistanceSquared(value)); + return Distance(this, value); } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -400,15 +400,15 @@ public override string ToString() } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static float DistanceSquared(Vector2 valueA, Vector2 valueB) + public static float DistanceSquared(Vector3i valueA, Vector3i valueB) { return (valueA - valueB).LengthSquared; } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static float Distance(Vector2 valueA, Vector2 valueB) + public static float Distance(Vector3i valueA, Vector3i valueB) { - return MathF.Sqrt(DistanceSquared(valueA, valueB)); + return (valueA - valueB).Length; } [MethodImpl(MethodImplOptions.AggressiveInlining)] diff --git a/Hypercube.Mathematics/Vectors/Vector4.cs b/Hypercube.Mathematics/Vectors/Vector4.cs index 47c5a25..6f2e875 100644 --- a/Hypercube.Mathematics/Vectors/Vector4.cs +++ b/Hypercube.Mathematics/Vectors/Vector4.cs @@ -75,18 +75,6 @@ namespace Hypercube.Mathematics.Vectors; /// public readonly float W; - public Vector2 XY - { - [MethodImpl(MethodImplOptions.AggressiveInlining)] - get => new(X, Y); - } - - public Vector3 XYZ - { - [MethodImpl(MethodImplOptions.AggressiveInlining)] - get => new(X, Y, Z); - } - /// /// Gets the square of the vector length (magnitude). /// @@ -144,6 +132,18 @@ public float Production get => X * Y * Z * W; } + public Vector2 XY + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get => new(X, Y); + } + + public Vector3 XYZ + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get => new(X, Y, Z); + } + public float this[int index] { [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -239,6 +239,96 @@ public Vector4 WithW(float value) { return new Vector4(X, Y, Z, value); } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public float DistanceSquared(Vector4 value) + { + return DistanceSquared(this, value); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public float Distance(Vector4 value) + { + return Distance(this, value); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public float Dot(Vector4 value) + { + return Dot(this, value); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Vector4 Reflect(Vector4 normal) + { + return Reflect(this, normal); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Vector4 MoveTowards(Vector4 target, float distance) + { + return MoveTowards(this, target, distance); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Vector4 Clamp(Vector4 min, Vector4 max) + { + return Clamp(this, min, max); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Vector4 Clamp(float min, float max) + { + return Clamp(this, min, max); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Vector4 Lerp(Vector4 value, float amount) + { + return Lerp(this, value, amount); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Vector4 Max(Vector4 value) + { + return Max(this, value); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Vector4 Min(Vector4 value) + { + return Min(this, value); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Vector4 Abs() + { + return Abs(this); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Vector4 Round() + { + return Round(this); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Vector4 Round(int digits) + { + return Round(this, digits); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Vector4 Ceiling() + { + return Ceiling(this); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Vector4 Floor() + { + return Floor(this); + } [MethodImpl(MethodImplOptions.AggressiveInlining)] public int CompareTo(Vector4 other) @@ -318,6 +408,12 @@ public override int GetHashCode() return new Vector4(a.X + b, a.Y + b, a.Z + b, a.W + b); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector4 operator +(float a, Vector4 b) + { + return new Vector4(a + b.X, a + b.Y, a + b.Z, a + b.W); + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 operator -(Vector4 a) { @@ -348,6 +444,12 @@ public override int GetHashCode() return new Vector4(a.X - b, a.Y - b, a.Z - b, a.W - b); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector4 operator -(float a, Vector4 b) + { + return new Vector4(a - b.X, a - b.Y, a - b.Z, a - b.W); + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 operator *(Vector4 a, Vector4 b) { @@ -372,6 +474,12 @@ public override int GetHashCode() return new Vector4(a.X * b, a.Y * b, a.Z * b, a.W * b); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector4 operator *(float a, Vector4 b) + { + return new Vector4(a * b.X, a * b.Y, a * b.Z, a * b.W); + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 operator /(Vector4 a, Vector4 b) { @@ -396,6 +504,12 @@ public override int GetHashCode() return new Vector4(a.X / b, a.Y / b, a.Z / b, a.W / b); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector4 operator /(float a, Vector4 b) + { + return new Vector4(a / b.X, a / b.Y, a / b.Z, a / b.W); + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool operator ==(Vector4 a, Vector4 b) { @@ -407,4 +521,151 @@ public override int GetHashCode() { return !a.Equals(b); } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static float DistanceSquared(Vector4 valueA, Vector4 valueB) + { + return (valueA - valueB).LengthSquared; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static float Distance(Vector4 valueA, Vector4 valueB) + { + return (valueA - valueB).Length; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static float Dot(Vector4 valueA, Vector4 valueB) + { + return valueA.X * valueB.X + + valueA.Y * valueB.Y + + valueA.Z * valueB.Z + + valueA.W * valueB.W; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector4 Reflect(Vector4 value, Vector4 normal) + { + return value - 2.0f * (Dot(value, normal) * normal); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector4 MoveTowards(Vector4 current, Vector4 target, float distance) + { + return new Vector4( + HyperMathF.MoveTowards(current.X, target.X, distance), + HyperMathF.MoveTowards(current.Y, target.Y, distance), + HyperMathF.MoveTowards(current.Z, target.Z, distance), + HyperMathF.MoveTowards(current.W, target.W, distance)); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector4 Clamp(Vector4 value, Vector4 min, Vector4 max) + { + return new Vector4( + float.Clamp(value.X, min.X, max.X), + float.Clamp(value.Y, min.Y, max.Y), + float.Clamp(value.Z, min.Z, max.Z), + float.Clamp(value.W, min.W, max.W)); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector4 Clamp(Vector4 value, float min, float max) + { + return new Vector4( + float.Clamp(value.X, min, max), + float.Clamp(value.Y, min, max), + float.Clamp(value.Z, min, max), + float.Clamp(value.W, min, max)); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector4 Lerp(Vector4 value, Vector4 target, float amount) + { + return new Vector4( + float.Lerp(value.X, target.X, amount), + float.Lerp(value.Y, target.Y, amount), + float.Lerp(value.Z, target.Z, amount), + float.Lerp(value.W, target.W, amount)); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector4 Max(Vector4 valueA, Vector4 valueB) + { + return new Vector4( + MathF.Max(valueA.X, valueB.X), + MathF.Max(valueA.Y, valueB.Y), + MathF.Max(valueA.Z, valueB.Z), + MathF.Max(valueA.W, valueB.W)); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector4 Min(Vector4 valueA, Vector4 valueB) + { + return new Vector4( + MathF.Min(valueA.X, valueB.X), + MathF.Min(valueA.Y, valueB.Y), + MathF.Min(valueA.Z, valueB.Z), + MathF.Min(valueA.W, valueB.W)); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector4 Abs(Vector4 value) + { + return new Vector4( + Math.Abs(value.X), + Math.Abs(value.Y), + Math.Abs(value.Z), + Math.Abs(value.W)); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector4 Round(Vector4 value) + { + return new Vector4( + Math.Round(value.X), + Math.Round(value.Y), + Math.Round(value.Z), + Math.Round(value.W)); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector4 Round(Vector4 value, int digits) + { + return new Vector4( + Math.Round(value.X, digits), + Math.Round(value.Y, digits), + Math.Round(value.Z, digits), + Math.Round(value.W, digits)); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector4 Ceiling(Vector4 value) + { + return new Vector4( + Math.Ceiling(value.X), + Math.Ceiling(value.Y), + Math.Ceiling(value.Z), + Math.Ceiling(value.W)); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector4 Floor(Vector4 value) + { + return new Vector4( + Math.Floor(value.X), + Math.Floor(value.Y), + Math.Floor(value.Z), + Math.Floor(value.W)); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector4 Sign(Vector4 value) + { + return new Vector4( + Math.Sign(value.X), + Math.Sign(value.Y), + Math.Sign(value.Z), + Math.Sign(value.W)); + } } \ No newline at end of file