diff --git a/GlitchyEngine/src/Math/FloatExtension.bf b/GlitchyEngine/src/Math/FloatExtension.bf new file mode 100644 index 0000000..ccfdb37 --- /dev/null +++ b/GlitchyEngine/src/Math/FloatExtension.bf @@ -0,0 +1,24 @@ +using GlitchyEngine.Math; + +namespace System +{ + extension Float + { + public float X + { + [Inline] + get => (float)this; + [Inline] + set mut => this = value; + } + + [Inline] + public Vector2 XX => Vector2((float)this); + + [Inline] + public Vector3 XXX => Vector3((float)this); + + [Inline] + public Vector4 XXXX => Vector4((float)this); + } +} diff --git a/GlitchyEngine/src/Math/IntExtension.bf b/GlitchyEngine/src/Math/IntExtension.bf new file mode 100644 index 0000000..508c8fa --- /dev/null +++ b/GlitchyEngine/src/Math/IntExtension.bf @@ -0,0 +1,24 @@ +using GlitchyEngine.Math; + +namespace System +{ + extension Int32 + { + public int32 X + { + [Inline] + get => (int32)this; + [Inline] + set mut => this = value; + } + + [Inline] + public Int32_2 XX => Int32_2((int32)this); + + [Inline] + public Int32_3 XXX => Int32_3((int32)this); + + [Inline] + public Int32_4 XXXX => Int32_4((int32)this); + } +} diff --git a/GlitchyEngine/src/Math/SwizzleVectorAttribute.bf b/GlitchyEngine/src/Math/SwizzleVectorAttribute.bf index 34523a1..7be1d26 100644 --- a/GlitchyEngine/src/Math/SwizzleVectorAttribute.bf +++ b/GlitchyEngine/src/Math/SwizzleVectorAttribute.bf @@ -12,9 +12,12 @@ namespace GlitchyEngine.Math public int VectorSize => _vectorSize; - this(int vectorSize) + private String _vectorTypeName; + + this(int vectorSize, String vectorTypeName) { _vectorSize = vectorSize; + _vectorTypeName = vectorTypeName; } /** @@ -70,7 +73,7 @@ namespace GlitchyEngine.Math //{(setterInvalid ? "[Error(\"Cannot assign multiple values to same component.\")]" : String.Empty)} String swizzleString = scope $""" - public Vector{swizzleCount} {swizzleName} + public {_vectorTypeName}{swizzleCount} {swizzleName} {{ get => .({swizzleConstructor}); set mut diff --git a/GlitchyEngine/src/Math/Vector2.bf b/GlitchyEngine/src/Math/Vector2.bf index f0a574e..79490a2 100644 --- a/GlitchyEngine/src/Math/Vector2.bf +++ b/GlitchyEngine/src/Math/Vector2.bf @@ -2,7 +2,7 @@ using System; namespace GlitchyEngine.Math { - [SwizzleVector(2)] + [SwizzleVector(2, "Vector")] public struct Vector2 { public const Vector2 Zero = .(0f, 0f); diff --git a/GlitchyEngine/src/Math/Vector3.bf b/GlitchyEngine/src/Math/Vector3.bf index 4480455..01ab2b2 100644 --- a/GlitchyEngine/src/Math/Vector3.bf +++ b/GlitchyEngine/src/Math/Vector3.bf @@ -2,7 +2,7 @@ using System; namespace GlitchyEngine.Math { - [SwizzleVector(3)] + [SwizzleVector(3, "Vector")] public struct Vector3 { public const Vector3 Zero = .(0f, 0f, 0f); diff --git a/GlitchyEngine/src/Math/Vector4.bf b/GlitchyEngine/src/Math/Vector4.bf index 5a9bef9..0384dbc 100644 --- a/GlitchyEngine/src/Math/Vector4.bf +++ b/GlitchyEngine/src/Math/Vector4.bf @@ -2,7 +2,7 @@ using System; namespace GlitchyEngine.Math { - [SwizzleVector(4)] + [SwizzleVector(4, "Vector")] public struct Vector4 { public const Vector4 Zero = .(0f, 0f, 0f, 0f); diff --git a/GlitchyEngine/src/Math/Vectors/Int32_2.bf b/GlitchyEngine/src/Math/Vectors/Int32_2.bf new file mode 100644 index 0000000..7da297e --- /dev/null +++ b/GlitchyEngine/src/Math/Vectors/Int32_2.bf @@ -0,0 +1,162 @@ +#pragma warning disable 4204 + +using System; +using System.Diagnostics; + +namespace GlitchyEngine.Math +{ + /** + * A Vector with two components of type int32. + */ + [SwizzleVector(2, "Int32_")] + public struct Int32_2 : IHashable + { + public const Int32_2 Zero = .(0, 0); + public const Int32_2 UnitX = .(1, 0); + public const Int32_2 UnitY = .(0, 1); + public const Int32_2 One = .(1, 1); + + public int32 X, Y; + + public this() => this = default; + + public this(int32 value) + { + X = value; + Y = value; + } + + public this(int value) + { + X = (.)value; + Y = (.)value; + } + + public this(int32 x, int32 y) + { + X = x; + Y = y; + } + + public this(int x, int y) + { + X = (.)x; + Y = (.)y; + } + + public ref int32 this[int index] + { + [Inline] + get + { +#if DEBUG + if(index < 0 || index >= 2) + Internal.ThrowIndexOutOfRange(1); +#endif + + return ref (&X)[index]; + } + } + + public int32 MagnitudeSquared() => X * X + Y * Y; + + public float Magnitude() => Math.Sqrt(X * X + Y * Y); + + public Int32_2 Abs() => .(Math.Abs(X), Math.Abs(Y)); + + // + // Assignment operators + // + + public void operator +=(Int32_2 value) mut + { + X += value.X; + Y += value.Y; + } + + public void operator +=(int32 value) mut + { + X += value; + Y += value; + } + + public void operator -=(Int32_2 value) mut + { + X -= value.X; + Y -= value.Y; + } + + public void operator -=(int32 value) mut + { + X -= value; + Y -= value; + } + + public void operator *=(Int32_2 value) mut + { + X *= value.X; + Y *= value.Y; + } + + public void operator *=(int32 value) mut + { + X *= value; + Y *= value; + } + + public void operator /=(Int32_2 value) mut + { + X /= value.X; + Y /= value.Y; + } + + public void operator /=(int32 value) mut + { + X /= value; + Y /= value; + } + + // Operators + + public static Int32_2 operator +(Int32_2 value) => value; + public static Int32_2 operator +(Int32_2 left, Int32_2 right) => .(left.X + right.X, left.Y + right.Y); + public static Int32_2 operator +(Int32_2 left, int32 right) => .(left.X + right, left.Y + right); + public static Int32_2 operator +(int32 left, Int32_2 right) => .(left + right.X, left + right.Y); + + public static Int32_2 operator -(Int32_2 value) => .(-value.X, -value.Y); + public static Int32_2 operator -(Int32_2 left, Int32_2 right) => .(left.X - right.X, left.Y - right.Y); + public static Int32_2 operator -(Int32_2 left, int32 right) => .(left.X - right, left.Y - right); + public static Int32_2 operator -(int32 left, Int32_2 right) => .(left - right.X, left - right.Y); + + public static Int32_2 operator *(Int32_2 left, Int32_2 right) => .(left.X * right.X, left.Y * right.Y); + public static Int32_2 operator *(Int32_2 left, int32 right) => .(left.X * right, left.Y * right); + public static Int32_2 operator *(int32 left, Int32_2 right) => .(left * right.X, left * right.Y); + + public static Int32_2 operator /(Int32_2 left, Int32_2 right) => .(left.X / right.X, left.Y / right.Y); + public static Int32_2 operator /(Int32_2 left, int32 right) => .(left.X / right, left.Y / right); + public static Int32_2 operator /(int32 left, Int32_2 right) => .(left / right.X, left / right.Y); + + public static Int32_2 operator %(Int32_2 left, Int32_2 right) => .(left.X % right.X, left.Y % right.Y); + public static Int32_2 operator %(Int32_2 left, int32 right) => .(left.X % right, left.Y % right); + public static Int32_2 operator %(int32 left, Int32_2 right) => .(left % right.X, left % right.Y); + + public static bool operator ==(Int32_2 left, Int32_2 right) => left.X == right.X && left.Y == right.Y; + public static bool operator ==(Int32_2 left, int32 right) => left.X == right && left.Y == right; + public static bool operator ==(int32 left, Int32_2 right) => left == right.X && left == right.Y; + + public static bool operator !=(Int32_2 left, Int32_2 right) => left.X != right.X || left.Y != right.Y; + public static bool operator !=(Int32_2 left, int32 right) => left.X != right || left.Y != right; + public static bool operator !=(int32 left, Int32_2 right) => left != right.X || left != right.Y; + + public override void ToString(String strBuffer) => strBuffer.AppendF($"X:{X} Y:{Y}"); + + public static explicit operator Vector2(Int32_2 point) => .(point.X, point.Y); + + public static explicit operator Int32_2(Vector2 point) => .((int32)point.X, (int32)point.Y); + + public int GetHashCode() + { + return (X * 39) ^ Y; + } + } +} diff --git a/GlitchyEngine/src/Math/Vectors/Int32_3.bf b/GlitchyEngine/src/Math/Vectors/Int32_3.bf new file mode 100644 index 0000000..0906c4b --- /dev/null +++ b/GlitchyEngine/src/Math/Vectors/Int32_3.bf @@ -0,0 +1,206 @@ +#pragma warning disable 4204 + +using System; +using System.Diagnostics; + +namespace GlitchyEngine.Math +{ + /** + * A Vector with three components of type int32. + */ + [SwizzleVector(3, "Int32_")] + public struct Int32_3 : IHashable + { + public const Int32_3 Zero = .(0, 0, 0); + public const Int32_3 UnitX = .(1, 0, 0); + public const Int32_3 UnitY = .(0, 1, 0); + public const Int32_3 UnitZ = .(0, 0, 1); + public const Int32_3 One = .(1, 1, 1); + + public int32 X, Y, Z; + + public this() => this = default; + + public this(int32 value) + { + X = value; + Y = value; + Z = value; + } + + public this(int value) + { + X = (.)value; + Y = (.)value; + Z = (.)value; + } + + public this(int32 x, int32 y, int32 z) + { + X = x; + Y = y; + Z = z; + } + + public this(Int32_2 xy, int32 z) + { + X = xy.X; + Y = xy.Y; + Z = z; + } + + public this(int32 x, Int32_2 yz) + { + X = x; + Y = yz.X; + Z = yz.Y; + } + + public this(int x, int y, int z) + { + X = (.)x; + Y = (.)y; + Z = (.)z; + } + + public this(Int32_2 xy, int z) + { + X = xy.X; + Y = xy.Y; + Z = (.)z; + } + + public this(int x, Int32_2 yz) + { + X = (.)x; + Y = yz.X; + Z = yz.Y; + } + + public ref int32 this[int index] + { + [Inline] + get + { +#if DEBUG + if(index < 0 || index >= 3) + Internal.ThrowIndexOutOfRange(1); +#endif + + return ref (&X)[index]; + } + } + + public int32 MagnitudeSquared() => X * X + Y * Y + Z * Z; + + public float Magnitude() => Math.Sqrt(X * X + Y * Y + Z * Z); + + public Int32_3 Abs() => .(Math.Abs(X), Math.Abs(Y), Math.Abs(Z)); + + // + // Assignment operators + // + + public void operator +=(Int32_3 value) mut + { + X += value.X; + Y += value.Y; + Z += value.Z; + } + + public void operator +=(int32 value) mut + { + X += value; + Y += value; + Z += value; + } + + public void operator -=(Int32_3 value) mut + { + X -= value.X; + Y -= value.Y; + Z -= value.Z; + } + + public void operator -=(int32 value) mut + { + X -= value; + Y -= value; + Z -= value; + } + + public void operator *=(Int32_3 value) mut + { + X *= value.X; + Y *= value.Y; + Z *= value.Z; + } + + public void operator *=(int32 value) mut + { + X *= value; + Y *= value; + Z *= value; + } + + public void operator /=(Int32_3 value) mut + { + X /= value.X; + Y /= value.Y; + Z /= value.Z; + } + + public void operator /=(int32 value) mut + { + X /= value; + Y /= value; + Z /= value; + } + + // Operators + + public static Int32_3 operator +(Int32_3 value) => value; + public static Int32_3 operator +(Int32_3 left, Int32_3 right) => .(left.X + right.X, left.Y + right.Y, left.Z + right.Z); + public static Int32_3 operator +(Int32_3 left, int32 right) => .(left.X + right, left.Y + right, left.Z + right); + public static Int32_3 operator +(int32 left, Int32_3 right) => .(left + right.X, left + right.Y, left + right.Z); + + public static Int32_3 operator -(Int32_3 value) => .(-value.X, -value.Y, -value.Z); + public static Int32_3 operator -(Int32_3 left, Int32_3 right) => .(left.X - right.X, left.Y - right.Y, left.Z - right.Z); + public static Int32_3 operator -(Int32_3 left, int32 right) => .(left.X - right, left.Y - right, left.Z- right); + public static Int32_3 operator -(int32 left, Int32_3 right) => .(left - right.X, left - right.Y, left - right.Z); + + public static Int32_3 operator *(Int32_3 left, Int32_3 right) => .(left.X * right.X, left.Y * right.Y, left.Z * right.Z); + public static Int32_3 operator *(Int32_3 left, int32 right) => .(left.X * right, left.Y * right, left.Z * right); + public static Int32_3 operator *(int32 left, Int32_3 right) => .(left * right.X, left * right.Y, left * right.Z); + + public static Int32_3 operator /(Int32_3 left, Int32_3 right) => .(left.X / right.X, left.Y / right.Y, left.Z / right.Z); + public static Int32_3 operator /(Int32_3 left, int32 right) => .(left.X / right, left.Y / right, left.Z / right); + public static Int32_3 operator /(int32 left, Int32_3 right) => .(left / right.X, left / right.Y, left / right.Z); + + public static Int32_3 operator %(Int32_3 left, Int32_3 right) => .(left.X % right.X, left.Y % right.Y, left.Z % right.Z); + public static Int32_3 operator %(Int32_3 left, int32 right) => .(left.X % right, left.Y % right, left.Z % right); + public static Int32_3 operator %(int32 left, Int32_3 right) => .(left % right.X, left % right.Y, left % right.Z); + + public static bool operator ==(Int32_3 left, Int32_3 right) => left.X == right.X && left.Y == right.Y && left.Z == right.Z; + public static bool operator ==(Int32_3 left, int32 right) => left.X == right && left.Y == right && left.Z == right; + public static bool operator ==(int32 left, Int32_3 right) => left == right.X && left == right.Y && left == right.Z; + + public static bool operator !=(Int32_3 left, Int32_3 right) => left.X != right.X || left.Y != right.Y || left.Z != right.Z; + public static bool operator !=(Int32_3 left, int32 right) => left.X != right || left.Y != right || left.Z != right; + public static bool operator !=(int32 left, Int32_3 right) => left != right.X || left != right.Y || left != right.Z; + + public override void ToString(String strBuffer) => strBuffer.AppendF($"X:{X} Y:{Y} Z:{Z}"); + + public static explicit operator Vector3(Int32_3 point) => .(point.X, point.Y, point.Z); + + public static explicit operator Int32_3(Vector3 point) => .((int32)point.X, (int32)point.Y, (int32)point.Z); + + [Inline] + public static explicit operator Int32_2(in Int32_3 point) => *(Int32_2*)&point; + + public int GetHashCode() + { + return (((X * 39) ^ Y) * 39) ^ Z; + } + } +} diff --git a/GlitchyEngine/src/Math/Vectors/Int32_4.bf b/GlitchyEngine/src/Math/Vectors/Int32_4.bf new file mode 100644 index 0000000..a1016e8 --- /dev/null +++ b/GlitchyEngine/src/Math/Vectors/Int32_4.bf @@ -0,0 +1,234 @@ +#pragma warning disable 4204 + +using System; +using System.Diagnostics; + +namespace GlitchyEngine.Math +{ + /** + * A Vector with four components of type int32. + */ + [SwizzleVector(4, "Int32_")] + public struct Int32_4 : IHashable + { + public const Int32_4 Zero = .(0, 0, 0, 0); + public const Int32_4 UnitX = .(1, 0, 0, 0); + public const Int32_4 UnitY = .(0, 1, 0, 0); + public const Int32_4 UnitZ = .(0, 0, 1, 0); + public const Int32_4 UnitW = .(0, 0, 0, 1); + public const Int32_4 One = .(1, 1, 1, 1); + + public int32 X, Y, Z, W; + + public this() => this = default; + + public this(int32 value) + { + X = value; + Y = value; + Z = value; + W = value; + } + + public this(int value) + { + X = (.)value; + Y = (.)value; + Z = (.)value; + W = (.)value; + } + + public this(int32 x, int32 y, int32 z, int32 w) + { + X = x; + Y = y; + Z = z; + W = w; + } + + public this(Int32_2 xy, int32 z, int32 w) + { + X = xy.X; + Y = xy.Y; + Z = z; + W = w; + } + + public this(int32 x, Int32_2 yz, int32 w) + { + X = x; + Y = yz.X; + Z = yz.Y; + W = w; + } + + public this(int32 x, int32 y, Int32_2 zw) + { + X = x; + Y = y; + Z = zw.X; + W = zw.Y; + } + + public this(Int32_2 xy, Int32_2 zw) + { + X = xy.X; + Y = xy.Y; + Z = zw.X; + W = zw.Y; + } + + public this(Int32_3 xyz, int32 w) + { + X = xyz.X; + Y = xyz.Y; + Z = xyz.Z; + W = w; + } + + public this(int32 x, Int32_3 yzw) + { + X = x; + Y = yzw.X; + Z = yzw.Y; + W = yzw.Z; + } + + public ref int32 this[int index] + { + [Inline] + get + { +#if DEBUG + if(index < 0 || index >= 3) + Internal.ThrowIndexOutOfRange(1); +#endif + + return ref (&X)[index]; + } + } + + public int32 MagnitudeSquared() => X * X + Y * Y + Z * Z + W * W; + + public float Magnitude() => Math.Sqrt(X * X + Y * Y + Z * Z + W * W); + + public Int32_4 Abs() => .(Math.Abs(X), Math.Abs(Y), Math.Abs(Z), Math.Abs(W)); + + // + // Assignment operators + // + + public void operator +=(Int32_4 value) mut + { + X += value.X; + Y += value.Y; + Z += value.Z; + W += value.W; + } + + public void operator +=(int32 value) mut + { + X += value; + Y += value; + Z += value; + W += value; + } + + public void operator -=(Int32_4 value) mut + { + X -= value.X; + Y -= value.Y; + Z -= value.Z; + W -= value.W; + } + + public void operator -=(int32 value) mut + { + X -= value; + Y -= value; + Z -= value; + W -= value; + } + + public void operator *=(Int32_4 value) mut + { + X *= value.X; + Y *= value.Y; + Z *= value.Z; + W *= value.W; + } + + public void operator *=(int32 value) mut + { + X *= value; + Y *= value; + Z *= value; + W *= value; + } + + public void operator /=(Int32_4 value) mut + { + X /= value.X; + Y /= value.Y; + Z /= value.Z; + W /= value.W; + } + + public void operator /=(int32 value) mut + { + X /= value; + Y /= value; + Z /= value; + W /= value; + } + + // Operators + + public static Int32_4 operator +(Int32_4 value) => value; + public static Int32_4 operator +(Int32_4 left, Int32_4 right) => .(left.X + right.X, left.Y + right.Y, left.Z + right.Z, left.W + right.W); + public static Int32_4 operator +(Int32_4 left, int32 right) => .(left.X + right, left.Y + right, left.Z + right, left.W + right); + public static Int32_4 operator +(int32 left, Int32_4 right) => .(left + right.X, left + right.Y, left + right.Z, left + right.W); + + public static Int32_4 operator -(Int32_4 value) => .(-value.X, -value.Y, -value.Z, -value.W); + public static Int32_4 operator -(Int32_4 left, Int32_4 right) => .(left.X - right.X, left.Y - right.Y, left.Z - right.Z, left.W - right.W); + public static Int32_4 operator -(Int32_4 left, int32 right) => .(left.X - right, left.Y - right, left.Z - right, left.W - right); + public static Int32_4 operator -(int32 left, Int32_4 right) => .(left - right.X, left - right.Y, left - right.Z, left - right.W); + + public static Int32_4 operator *(Int32_4 left, Int32_4 right) => .(left.X * right.X, left.Y * right.Y, left.Z * right.Z, left.W * right.W); + public static Int32_4 operator *(Int32_4 left, int32 right) => .(left.X * right, left.Y * right, left.Z * right, left.W * right); + public static Int32_4 operator *(int32 left, Int32_4 right) => .(left * right.X, left * right.Y, left * right.Z, left * right.W); + + public static Int32_4 operator /(Int32_4 left, Int32_4 right) => .(left.X / right.X, left.Y / right.Y, left.Z / right.Z, left.W / right.W); + public static Int32_4 operator /(Int32_4 left, int32 right) => .(left.X / right, left.Y / right, left.Z / right, left.W / right); + public static Int32_4 operator /(int32 left, Int32_4 right) => .(left / right.X, left / right.Y, left / right.Z, left / right.W); + + public static Int32_4 operator %(Int32_4 left, Int32_4 right) => .(left.X % right.X, left.Y % right.Y, left.Z % right.Z, left.W % right.W); + public static Int32_4 operator %(Int32_4 left, int32 right) => .(left.X % right, left.Y % right, left.Z % right, left.W % right); + public static Int32_4 operator %(int32 left, Int32_4 right) => .(left % right.X, left % right.Y, left % right.Z, left % right.W); + + public static bool operator ==(Int32_4 left, Int32_4 right) => left.X == right.X && left.Y == right.Y && left.Z == right.Z && left.W == right.W; + public static bool operator ==(Int32_4 left, int32 right) => left.X == right && left.Y == right && left.Z == right && left.W == right; + public static bool operator ==(int32 left, Int32_4 right) => left == right.X && left == right.Y && left == right.Z && left == right.W; + + public static bool operator !=(Int32_4 left, Int32_4 right) => left.X != right.X || left.Y != right.Y || left.Z != right.Z || left.W != right.W; + public static bool operator !=(Int32_4 left, int32 right) => left.X != right || left.Y != right || left.Z != right || left.W != right; + public static bool operator !=(int32 left, Int32_4 right) => left != right.X || left != right.Y || left != right.Z || left != right.W; + + public override void ToString(String strBuffer) => strBuffer.AppendF($"X:{X} Y:{Y} Z:{Z} W:{W}"); + + public static explicit operator Vector4(Int32_4 point) => .(point.X, point.Y, point.Z, point.W); + + public static explicit operator Int32_4(Vector4 point) => .((int32)point.X, (int32)point.Y, (int32)point.Z, (int32)point.W); + + [Inline] + public static explicit operator Int32_2(in Int32_4 point) => *(Int32_2*)&point; + + [Inline] + public static explicit operator Int32_3(in Int32_4 point) => *(Int32_3*)&point; + + public int GetHashCode() + { + return (((((X * 39) ^ Y) * 39) ^ Z) * 39) ^ W; + } + } +}