mirror of
https://github.com/aharabada/glitchy-engine-beef.git
synced 2026-09-05 13:01:52 +00:00
Added Vectors and Vector component swizzling
This commit is contained in:
@@ -1,13 +1,11 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
namespace GlitchyEngine.Math
|
namespace GlitchyEngine.Math
|
||||||
{
|
{
|
||||||
typealias Color = DirectX.Color;
|
typealias Color = DirectX.Color;
|
||||||
typealias ColorRGB = DirectX.ColorRGB;
|
typealias ColorRGB = DirectX.ColorRGB;
|
||||||
typealias ColorRGBA = DirectX.ColorRGBA;
|
typealias ColorRGBA = DirectX.ColorRGBA;
|
||||||
|
|
||||||
typealias Vector2 = DirectX.Math.Vector2;
|
|
||||||
typealias Vector3 = DirectX.Math.Vector3;
|
|
||||||
typealias Vector4 = DirectX.Math.Vector4;
|
|
||||||
|
|
||||||
typealias Matrix3x3 = DirectX.Math.Matrix3x3;
|
typealias Matrix3x3 = DirectX.Math.Matrix3x3;
|
||||||
typealias Matrix4x3 = DirectX.Math.Matrix4x3;
|
typealias Matrix4x3 = DirectX.Math.Matrix4x3;
|
||||||
typealias Matrix = DirectX.Math.Matrix;
|
typealias Matrix = DirectX.Math.Matrix;
|
||||||
|
|||||||
@@ -0,0 +1,88 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace GlitchyEngine.Math
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Generates component swizzle operators for a vector.
|
||||||
|
*/
|
||||||
|
[AttributeUsage(.Struct | .Class)]
|
||||||
|
struct SwizzleVectorAttribute : Attribute, IComptimeTypeApply
|
||||||
|
{
|
||||||
|
private int _vectorSize;
|
||||||
|
|
||||||
|
public int VectorSize => _vectorSize;
|
||||||
|
|
||||||
|
this(int vectorSize)
|
||||||
|
{
|
||||||
|
_vectorSize = vectorSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determines whether or not a swizzle operator can have a valid setter (e.g. no component assigned twice)
|
||||||
|
*/
|
||||||
|
static bool invalidSetter(int[4] cmp, int vecSize)
|
||||||
|
{
|
||||||
|
return cmp[0] == cmp[1] || (vecSize >= 3 && cmp[0] == cmp[2]) || (vecSize == 4 && cmp[0] == cmp[3]) ||
|
||||||
|
(vecSize >= 3 && cmp[1] == cmp[2]) || (vecSize == 4 && cmp[1] == cmp[3]) ||
|
||||||
|
(vecSize == 4 && cmp[2] == cmp[3]);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Comptime]
|
||||||
|
public void ApplyToType(Type type)
|
||||||
|
{
|
||||||
|
// TODO: report bug... sized array not working
|
||||||
|
String[] componentNames = scope String[]("X", "Y", "Z", "W");
|
||||||
|
|
||||||
|
for(int swizzleCount = 2; swizzleCount <= 4; swizzleCount++)
|
||||||
|
{
|
||||||
|
int[4] cmp = .();
|
||||||
|
|
||||||
|
int cmp2max = swizzleCount > 2 ? _vectorSize : 1;
|
||||||
|
int cmp3max = swizzleCount > 3 ? _vectorSize : 1;
|
||||||
|
|
||||||
|
for(cmp[0] = 0; cmp[0] < _vectorSize; cmp[0]++)
|
||||||
|
for(cmp[1] = 0; cmp[1] < _vectorSize; cmp[1]++)
|
||||||
|
for(cmp[2] = 0; cmp[2] < cmp2max; cmp[2]++)
|
||||||
|
for(cmp[3] = 0; cmp[3] < cmp3max; cmp[3]++)
|
||||||
|
{
|
||||||
|
String swizzleName = scope String(swizzleCount);
|
||||||
|
String swizzleConstructor = scope String(swizzleCount * 3);
|
||||||
|
String setter = scope String(128);
|
||||||
|
|
||||||
|
bool setterInvalid = invalidSetter(cmp, swizzleCount);
|
||||||
|
|
||||||
|
for(int c = 0; c < swizzleCount; c++)
|
||||||
|
{
|
||||||
|
swizzleName.Append(componentNames[cmp[c]]);
|
||||||
|
|
||||||
|
if(c != 0)
|
||||||
|
{
|
||||||
|
swizzleConstructor.Append(", ");
|
||||||
|
}
|
||||||
|
swizzleConstructor.Append(componentNames[cmp[c]]);
|
||||||
|
|
||||||
|
if(!setterInvalid && c < _vectorSize) //
|
||||||
|
{
|
||||||
|
setter.AppendF($"\n\t\t{componentNames[cmp[c]]} = value.{componentNames[c]};");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//{(setterInvalid ? "[Error(\"Cannot assign multiple values to same component.\")]" : String.Empty)}
|
||||||
|
|
||||||
|
String swizzleString = scope $"""
|
||||||
|
public Vector{swizzleCount} {swizzleName}
|
||||||
|
{{
|
||||||
|
get => .({swizzleConstructor});
|
||||||
|
set mut
|
||||||
|
{{{setter}
|
||||||
|
}}
|
||||||
|
}}
|
||||||
|
|
||||||
|
""";
|
||||||
|
|
||||||
|
Compiler.EmitTypeBody(type, swizzleString);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,227 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace GlitchyEngine.Math
|
||||||
|
{
|
||||||
|
[SwizzleVector(2)]
|
||||||
|
public struct Vector2
|
||||||
|
{
|
||||||
|
public const Vector2 Zero = .(0f, 0f);
|
||||||
|
public const Vector2 UnitX = .(1f, 0f);
|
||||||
|
public const Vector2 UnitY = .(0f, 1f);
|
||||||
|
public const Vector2 One = .(1f, 1f);
|
||||||
|
|
||||||
|
public const int Length = 2;
|
||||||
|
|
||||||
|
public float X, Y;
|
||||||
|
|
||||||
|
public this() => this = default;
|
||||||
|
|
||||||
|
public this(float value)
|
||||||
|
{
|
||||||
|
X = value;
|
||||||
|
Y = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public this(float x, float y)
|
||||||
|
{
|
||||||
|
X = x;
|
||||||
|
Y = y;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ref float this[int index]
|
||||||
|
{
|
||||||
|
[Checked]
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if(index < 0 || index >= Length)
|
||||||
|
Internal.ThrowIndexOutOfRange(1);
|
||||||
|
|
||||||
|
#unwarn
|
||||||
|
return ref (&X)[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
[Inline]
|
||||||
|
#unwarn
|
||||||
|
get => ref (&X)[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculates the magnitude (length) of this vector.
|
||||||
|
* @remarks MagnitudeSquared might be used if only the relative length is relevant.
|
||||||
|
*/
|
||||||
|
public float Magnitude()
|
||||||
|
{
|
||||||
|
return Math.Sqrt(X * X + Y * Y);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculates the squared magnitude (length) of this vector.
|
||||||
|
*/
|
||||||
|
public float MagnitudeSquared()
|
||||||
|
{
|
||||||
|
return X * X + Y * Y;
|
||||||
|
}
|
||||||
|
|
||||||
|
//TODO: Normalization interface is bad
|
||||||
|
[Checked]
|
||||||
|
public void Normalize() mut
|
||||||
|
{
|
||||||
|
if(this == .Zero)
|
||||||
|
return;
|
||||||
|
|
||||||
|
this /= Magnitude();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Normalize() mut
|
||||||
|
{
|
||||||
|
this /= Magnitude();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Vector2 Normalize(Vector2 v)
|
||||||
|
{
|
||||||
|
return v / v.Magnitude();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float Dot(Vector2 l, Vector2 r)
|
||||||
|
{
|
||||||
|
return l.X * r.X + l.Y * r.Y;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculates the projection of a onto b
|
||||||
|
*/
|
||||||
|
public Vector2 Project(Vector2 a, Vector2 b)
|
||||||
|
{
|
||||||
|
return (b * (Dot(a, b) / Dot(b, b)));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculates the rejection of a from b
|
||||||
|
*/
|
||||||
|
public Vector2 Reject(Vector2 a, Vector2 b)
|
||||||
|
{
|
||||||
|
return (a - b * (Dot(a, b) / Dot(b, b)));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// Assignment operators
|
||||||
|
//
|
||||||
|
|
||||||
|
// Addition
|
||||||
|
|
||||||
|
public void operator +=(Vector2 value) mut
|
||||||
|
{
|
||||||
|
X += value.X;
|
||||||
|
Y += value.Y;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void operator +=(float scalar) mut
|
||||||
|
{
|
||||||
|
X += scalar;
|
||||||
|
Y += scalar;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Subtraction
|
||||||
|
|
||||||
|
public void operator -=(Vector2 value) mut
|
||||||
|
{
|
||||||
|
X -= value.X;
|
||||||
|
Y -= value.Y;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void operator -=(float scalar) mut
|
||||||
|
{
|
||||||
|
X -= scalar;
|
||||||
|
Y -= scalar;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Multiplication
|
||||||
|
|
||||||
|
public void operator *=(Vector2 value) mut
|
||||||
|
{
|
||||||
|
X *= value.X;
|
||||||
|
Y *= value.Y;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void operator *=(float scalar) mut
|
||||||
|
{
|
||||||
|
X *= scalar;
|
||||||
|
Y *= scalar;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Division
|
||||||
|
|
||||||
|
public void operator /=(float scalar) mut
|
||||||
|
{
|
||||||
|
float f = 1.0f / scalar;
|
||||||
|
X *= f;
|
||||||
|
Y *= f;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void operator /=(Vector2 value) mut
|
||||||
|
{
|
||||||
|
X /= value.X;
|
||||||
|
Y /= value.Y;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// operators
|
||||||
|
//
|
||||||
|
|
||||||
|
// Addition
|
||||||
|
|
||||||
|
public static Vector2 operator +(Vector2 left, Vector2 right) => Vector2(left.X + right.X, left.Y + right.Y);
|
||||||
|
|
||||||
|
public static Vector2 operator +(Vector2 value, float scalar) => Vector2(value.X + scalar, value.Y + scalar);
|
||||||
|
|
||||||
|
public static Vector2 operator +(float scalar, Vector2 value) => Vector2(scalar + value.X, scalar + value.Y);
|
||||||
|
|
||||||
|
public static Vector2 operator +(Vector2 value) => value;
|
||||||
|
|
||||||
|
// Subtraction
|
||||||
|
|
||||||
|
public static Vector2 operator -(Vector2 left, Vector2 right) => Vector2(left.X - right.X, left.Y - right.Y);
|
||||||
|
|
||||||
|
public static Vector2 operator -(Vector2 value, float scalar) => Vector2(value.X - scalar, value.Y - scalar);
|
||||||
|
|
||||||
|
public static Vector2 operator -(float scalar, Vector2 value) => Vector2(scalar - value.X, scalar - value.Y);
|
||||||
|
|
||||||
|
public static Vector2 operator -(Vector2 value) => Vector2(-value.X, -value.Y);
|
||||||
|
|
||||||
|
// Multiplication
|
||||||
|
|
||||||
|
public static Vector2 operator *(Vector2 left, Vector2 right) => Vector2(left.X * right.X, left.Y * right.Y);
|
||||||
|
|
||||||
|
public static Vector2 operator *(Vector2 value, float scalar) => Vector2(value.X * scalar, value.Y * scalar);
|
||||||
|
|
||||||
|
public static Vector2 operator *(float scalar, Vector2 value) => Vector2(scalar * value.X, scalar * value.Y);
|
||||||
|
|
||||||
|
// Division
|
||||||
|
|
||||||
|
public static Vector2 operator /(Vector2 left, Vector2 right) => Vector2(left.X / right.X, left.Y / right.Y);
|
||||||
|
|
||||||
|
public static Vector2 operator /(Vector2 value, float scalar)
|
||||||
|
{
|
||||||
|
float inv = 1.0f / scalar;
|
||||||
|
return Vector2(value.X * inv, value.Y * inv);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Vector2 operator /(float scalar, Vector2 value) => Vector2(scalar / value.X, scalar / value.Y);
|
||||||
|
|
||||||
|
// Equality
|
||||||
|
|
||||||
|
public static bool operator ==(Vector2 left, Vector2 right) => left.X == right.X && left.Y == right.Y;
|
||||||
|
|
||||||
|
public static bool operator !=(Vector2 left, Vector2 right) => left.X != right.X || left.Y != right.Y;
|
||||||
|
|
||||||
|
public override void ToString(String strBuffer) => strBuffer.AppendF("X:{0} Y:{1}", X, Y);
|
||||||
|
|
||||||
|
// Todo: move to extension
|
||||||
|
[Inline]
|
||||||
|
public static implicit operator DirectX.Math.Vector2(in Self value) => *(DirectX.Math.Vector2*)&value;
|
||||||
|
|
||||||
|
[Inline]
|
||||||
|
public static implicit operator Self(in DirectX.Math.Vector2 value) => *(Self*)&value;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,258 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace GlitchyEngine.Math
|
||||||
|
{
|
||||||
|
[SwizzleVector(3)]
|
||||||
|
public struct Vector3
|
||||||
|
{
|
||||||
|
public const Vector3 Zero = .(0f, 0f, 0f);
|
||||||
|
public const Vector3 UnitX = .(1f, 0f, 0f);
|
||||||
|
public const Vector3 UnitY = .(0f, 1f, 0f);
|
||||||
|
public const Vector3 UnitZ = .(0f, 0f, 1f);
|
||||||
|
public const Vector3 One = .(1f, 1f, 1f);
|
||||||
|
|
||||||
|
public const Vector3 Forward = .(0f, 0f, 1f);
|
||||||
|
public const Vector3 Backward = .(0f, 0f, -1f);
|
||||||
|
public const Vector3 Left = .(-1f, 0f, 0f);
|
||||||
|
public const Vector3 Right = .(1f, 0f, 0f);
|
||||||
|
public const Vector3 Up = .(0f, 1f, 0f);
|
||||||
|
public const Vector3 Down = .(0f, -1f, 0f);
|
||||||
|
|
||||||
|
public float X, Y, Z;
|
||||||
|
|
||||||
|
public this() => this = default;
|
||||||
|
|
||||||
|
public this(float value)
|
||||||
|
{
|
||||||
|
X = value;
|
||||||
|
Y = value;
|
||||||
|
Z = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public this(Vector2 value, float z)
|
||||||
|
{
|
||||||
|
X = value.X;
|
||||||
|
Y = value.Y;
|
||||||
|
Z = z;
|
||||||
|
}
|
||||||
|
|
||||||
|
public this(float x, float y, float z)
|
||||||
|
{
|
||||||
|
X = x;
|
||||||
|
Y = y;
|
||||||
|
Z = z;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ref float this[int index]
|
||||||
|
{
|
||||||
|
[Checked]
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if(index < 0 || index > 2)
|
||||||
|
Internal.ThrowIndexOutOfRange();
|
||||||
|
|
||||||
|
#unwarn
|
||||||
|
return ref (&X)[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
[Inline]
|
||||||
|
#unwarn
|
||||||
|
get => ref (&X)[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculates the magnitude (length) of this vector.
|
||||||
|
* @remarks MagnitudeSquared might be used if only the relative length is relevant.
|
||||||
|
*/
|
||||||
|
public float Magnitude()
|
||||||
|
{
|
||||||
|
return Math.Sqrt(X * X + Y * Y + Z * Z);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculates the squared magnitude (length) of this vector.
|
||||||
|
*/
|
||||||
|
public float MagnitudeSquared()
|
||||||
|
{
|
||||||
|
return X * X + Y * Y + Z * Z;
|
||||||
|
}
|
||||||
|
|
||||||
|
[Checked]
|
||||||
|
public void Normalize() mut
|
||||||
|
{
|
||||||
|
if(this == .Zero)
|
||||||
|
return;
|
||||||
|
|
||||||
|
this /= Magnitude();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Normalize() mut
|
||||||
|
{
|
||||||
|
this /= Magnitude();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Vector3 Normalize(Vector3 v)
|
||||||
|
{
|
||||||
|
return v / v.Magnitude();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float Dot(Vector3 l, Vector3 r)
|
||||||
|
{
|
||||||
|
return l.X * r.X + l.Y * r.Y + l.Z * r.Z;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Vector3 Cross(Vector3 l, Vector3 r)
|
||||||
|
{
|
||||||
|
return .(l.Y * r.Z - l.Z * r.Y,
|
||||||
|
l.Z * r.X - l.X * r.Z,
|
||||||
|
l.X * r.Y - l.Y * r.X);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculates the projection of a onto b
|
||||||
|
*/
|
||||||
|
public static Vector3 Project(Vector3 a, Vector3 b)
|
||||||
|
{
|
||||||
|
return (b * (Dot(a, b) / Dot(b, b)));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculates the rejection of a from b
|
||||||
|
*/
|
||||||
|
public static Vector3 Reject(Vector3 a, Vector3 b)
|
||||||
|
{
|
||||||
|
return (a - b * (Dot(a, b) / Dot(b, b)));
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Assignment operators
|
||||||
|
//
|
||||||
|
|
||||||
|
// Addition
|
||||||
|
|
||||||
|
public void operator +=(Vector3 value) mut
|
||||||
|
{
|
||||||
|
X += value.X;
|
||||||
|
Y += value.Y;
|
||||||
|
Z += value.Z;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void operator +=(float scalar) mut
|
||||||
|
{
|
||||||
|
X += scalar;
|
||||||
|
Y += scalar;
|
||||||
|
Z += scalar;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Subtraction
|
||||||
|
|
||||||
|
|
||||||
|
public void operator -=(Vector3 value) mut
|
||||||
|
{
|
||||||
|
X -= value.X;
|
||||||
|
Y -= value.Y;
|
||||||
|
Z -= value.Z;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void operator -=(float scalar) mut
|
||||||
|
{
|
||||||
|
X -= scalar;
|
||||||
|
Y -= scalar;
|
||||||
|
Z -= scalar;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Multiplication
|
||||||
|
|
||||||
|
public void operator *=(Vector3 value) mut
|
||||||
|
{
|
||||||
|
X *= value.X;
|
||||||
|
Y *= value.Y;
|
||||||
|
Z *= value.Z;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void operator *=(float scalar) mut
|
||||||
|
{
|
||||||
|
X *= scalar;
|
||||||
|
Y *= scalar;
|
||||||
|
Z *= scalar;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Division
|
||||||
|
|
||||||
|
public void operator /=(Vector3 value) mut
|
||||||
|
{
|
||||||
|
X /= value.X;
|
||||||
|
Y /= value.Y;
|
||||||
|
Z /= value.Z;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void operator /=(float scalar) mut
|
||||||
|
{
|
||||||
|
float inv = 1.0f / scalar;
|
||||||
|
X *= inv;
|
||||||
|
Y *= inv;
|
||||||
|
Z *= inv;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// operators
|
||||||
|
//
|
||||||
|
|
||||||
|
// Addition
|
||||||
|
|
||||||
|
public static Vector3 operator +(Vector3 left, Vector3 right) => Vector3(left.X + right.X, left.Y + right.Y, left.Z + right.Z);
|
||||||
|
|
||||||
|
public static Vector3 operator +(Vector3 value, float scalar) => Vector3(value.X + scalar, value.Y + scalar, value.Z + scalar);
|
||||||
|
|
||||||
|
public static Vector3 operator +(float scalar, Vector3 value) => Vector3(scalar + value.X, scalar + value.Y, scalar + value.Z);
|
||||||
|
|
||||||
|
public static Vector3 operator +(Vector3 value) => value;
|
||||||
|
|
||||||
|
// Subtraction
|
||||||
|
|
||||||
|
public static Vector3 operator -(Vector3 left, Vector3 right) => Vector3(left.X - right.X, left.Y - right.Y, left.Z - right.Z);
|
||||||
|
|
||||||
|
public static Vector3 operator -(Vector3 value, float scalar) => Vector3(value.X - scalar, value.Y - scalar, value.Z - scalar);
|
||||||
|
|
||||||
|
public static Vector3 operator -(float scalar, Vector3 value) => Vector3(scalar - value.X, scalar - value.Y, scalar - value.Z);
|
||||||
|
|
||||||
|
public static Vector3 operator -(Vector3 value) => Vector3(-value.X, -value.Y, -value.Z);
|
||||||
|
|
||||||
|
// Multiplication
|
||||||
|
|
||||||
|
public static Vector3 operator *(Vector3 left, Vector3 right) => Vector3(left.X * right.X, left.Y * right.Y, left.Z * right.Z);
|
||||||
|
|
||||||
|
public static Vector3 operator *(Vector3 value, float scalar) => Vector3(value.X * scalar, value.Y * scalar, value.Z * scalar);
|
||||||
|
|
||||||
|
public static Vector3 operator *(float scalar, Vector3 value) => Vector3(scalar * value.X, scalar * value.Y, scalar * value.Z);
|
||||||
|
|
||||||
|
// Division
|
||||||
|
|
||||||
|
public static Vector3 operator /(Vector3 left, Vector3 right) => Vector3(left.X / right.X, left.Y / right.Y, left.Z / right.Z);
|
||||||
|
|
||||||
|
public static Vector3 operator /(Vector3 value, float scalar)
|
||||||
|
{
|
||||||
|
float inv = 1.0f / scalar;
|
||||||
|
return Vector3(value.X * inv, value.Y * inv, value.Z * inv);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Vector3 operator /(float scalar, Vector3 value) => Vector3(scalar / value.X, scalar / value.Y, scalar / value.Z);
|
||||||
|
|
||||||
|
// Equality
|
||||||
|
|
||||||
|
public static bool operator ==(Vector3 left, Vector3 right) => left.X == right.X && left.Y == right.Y && left.Z == right.Z;
|
||||||
|
|
||||||
|
public static bool operator !=(Vector3 left, Vector3 right) => left.X != right.X || left.Y != right.Y || left.Z != right.Z;
|
||||||
|
|
||||||
|
public override void ToString(String strBuffer) => strBuffer.AppendF("X:{0} Y:{1} Z:{2}", X, Y, Z);
|
||||||
|
|
||||||
|
// Todo: move to extension
|
||||||
|
|
||||||
|
[Inline]
|
||||||
|
public static implicit operator DirectX.Math.Vector3(in Self value) => *(DirectX.Math.Vector3*)&value;
|
||||||
|
|
||||||
|
[Inline]
|
||||||
|
public static implicit operator Self(in DirectX.Math.Vector3 value) => *(Self*)&value;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,278 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace GlitchyEngine.Math
|
||||||
|
{
|
||||||
|
[SwizzleVector(4)]
|
||||||
|
public struct Vector4
|
||||||
|
{
|
||||||
|
public const Vector4 Zero = .(0f, 0f, 0f, 0f);
|
||||||
|
public const Vector4 UnitX = .(1f, 0f, 0f, 0f);
|
||||||
|
public const Vector4 UnitY = .(0f, 1f, 0f, 0f);
|
||||||
|
public const Vector4 UnitZ = .(0f, 0f, 1f, 0f);
|
||||||
|
public const Vector4 UnitW = .(0f, 0f, 0f, 1f);
|
||||||
|
public const Vector4 One = .(1f, 1f, 1f, 1f);
|
||||||
|
|
||||||
|
public float X, Y, Z, W;
|
||||||
|
|
||||||
|
public this() => this = default;
|
||||||
|
|
||||||
|
public this(float value)
|
||||||
|
{
|
||||||
|
X = value;
|
||||||
|
Y = value;
|
||||||
|
Z = value;
|
||||||
|
W = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public this(Vector2 value, float z, float w)
|
||||||
|
{
|
||||||
|
X = value.X;
|
||||||
|
Y = value.Y;
|
||||||
|
Z = z;
|
||||||
|
W = w;
|
||||||
|
}
|
||||||
|
|
||||||
|
public this(Vector2 value1, Vector2 value2)
|
||||||
|
{
|
||||||
|
X = value1.X;
|
||||||
|
Y = value1.Y;
|
||||||
|
Z = value2.X;
|
||||||
|
W = value2.Y;
|
||||||
|
}
|
||||||
|
|
||||||
|
public this(Vector3 value, float w)
|
||||||
|
{
|
||||||
|
X = value.X;
|
||||||
|
Y = value.Y;
|
||||||
|
Z = value.Z;
|
||||||
|
W = w;
|
||||||
|
}
|
||||||
|
|
||||||
|
public this(float x, float y, float z, float w)
|
||||||
|
{
|
||||||
|
X = x;
|
||||||
|
Y = y;
|
||||||
|
Z = z;
|
||||||
|
W = w;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ref float this[int index]
|
||||||
|
{
|
||||||
|
[Checked]
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if(index < 0 || index > 3)
|
||||||
|
Internal.ThrowIndexOutOfRange();
|
||||||
|
#unwarn
|
||||||
|
return ref (&X)[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
[Inline]
|
||||||
|
#unwarn
|
||||||
|
get => ref (&X)[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculates the magnitude (length) of this vector.
|
||||||
|
* @remarks MagnitudeSquared might be used if only the relative length is relevant.
|
||||||
|
*/
|
||||||
|
public float Magnitude()
|
||||||
|
{
|
||||||
|
return Math.Sqrt(X * X + Y * Y + Z * Z + W * W);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculates the squared magnitude (length) of this vector.
|
||||||
|
*/
|
||||||
|
public float MagnitudeSquared()
|
||||||
|
{
|
||||||
|
return X * X + Y * Y + Z * Z + W * W;
|
||||||
|
}
|
||||||
|
|
||||||
|
[Checked]
|
||||||
|
public void Normalize() mut
|
||||||
|
{
|
||||||
|
if(this == .Zero)
|
||||||
|
return;
|
||||||
|
|
||||||
|
this /= Magnitude();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Normalize() mut
|
||||||
|
{
|
||||||
|
this /= Magnitude();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Vector4 Normalize(Vector4 v)
|
||||||
|
{
|
||||||
|
if(v == .Zero)
|
||||||
|
return .Zero;
|
||||||
|
|
||||||
|
return v / v.Magnitude();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Unchecked]
|
||||||
|
public static Vector4 Normalize(Vector4 v)
|
||||||
|
{
|
||||||
|
return v / v.Magnitude();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float Dot(Vector4 l, Vector4 r)
|
||||||
|
{
|
||||||
|
return l.X * r.X + l.Y * r.Y + l.Z * r.Z + l.W * r.W;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculates the projection of a onto b
|
||||||
|
*/
|
||||||
|
public static Vector4 Project(Vector4 a, Vector4 b)
|
||||||
|
{
|
||||||
|
return (b * (Dot(a, b) / Dot(b, b)));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculates the rejection of a from b
|
||||||
|
*/
|
||||||
|
public static Vector4 Reject(Vector4 a, Vector4 b)
|
||||||
|
{
|
||||||
|
return (a - b * (Dot(a, b) / Dot(b, b)));
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Assignment operators
|
||||||
|
//
|
||||||
|
|
||||||
|
// Addition
|
||||||
|
|
||||||
|
public void operator +=(Vector4 value) mut
|
||||||
|
{
|
||||||
|
X += value.X;
|
||||||
|
Y += value.Y;
|
||||||
|
Z += value.Z;
|
||||||
|
W += value.W;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void operator +=(float scalar) mut
|
||||||
|
{
|
||||||
|
X += scalar;
|
||||||
|
Y += scalar;
|
||||||
|
Z += scalar;
|
||||||
|
W += scalar;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Subtraction
|
||||||
|
|
||||||
|
public void operator -=(Vector4 value) mut
|
||||||
|
{
|
||||||
|
X -= value.X;
|
||||||
|
Y -= value.Y;
|
||||||
|
Z -= value.Z;
|
||||||
|
W -= value.W;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void operator -=(float scalar) mut
|
||||||
|
{
|
||||||
|
X -= scalar;
|
||||||
|
Y -= scalar;
|
||||||
|
Z -= scalar;
|
||||||
|
W -= scalar;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Multiplication
|
||||||
|
|
||||||
|
public void operator *=(Vector4 value) mut
|
||||||
|
{
|
||||||
|
X *= value.X;
|
||||||
|
Y *= value.Y;
|
||||||
|
Z *= value.Z;
|
||||||
|
W *= value.W;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void operator *=(float scalar) mut
|
||||||
|
{
|
||||||
|
X *= scalar;
|
||||||
|
Y *= scalar;
|
||||||
|
Z *= scalar;
|
||||||
|
W *= scalar;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Division
|
||||||
|
|
||||||
|
public void operator /=(float scalar) mut
|
||||||
|
{
|
||||||
|
float f = 1.0f / scalar;
|
||||||
|
X *= f;
|
||||||
|
Y *= f;
|
||||||
|
Z *= f;
|
||||||
|
W *= f;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void operator /=(Vector4 value) mut
|
||||||
|
{
|
||||||
|
X /= value.X;
|
||||||
|
Y /= value.Y;
|
||||||
|
Z /= value.Z;
|
||||||
|
W /= value.W;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// operators
|
||||||
|
//
|
||||||
|
|
||||||
|
// Addition
|
||||||
|
|
||||||
|
public static Vector4 operator +(Vector4 left, Vector4 right) => Vector4(left.X + right.X, left.Y + right.Y, left.Z + right.Z, left.W + right.W);
|
||||||
|
|
||||||
|
public static Vector4 operator +(Vector4 value, float scalar) => Vector4(value.X + scalar, value.Y + scalar, value.Z + scalar, value.W + scalar);
|
||||||
|
|
||||||
|
public static Vector4 operator +(float scalar, Vector4 value) => Vector4(scalar + value.X, scalar + value.Y, scalar + value.Z, scalar + value.W);
|
||||||
|
|
||||||
|
public static Vector4 operator +(Vector4 value) => value;
|
||||||
|
|
||||||
|
// Subtraction
|
||||||
|
|
||||||
|
public static Vector4 operator -(Vector4 left, Vector4 right) => Vector4(left.X - right.X, left.Y - right.Y, left.Z - right.Z, left.W - right.W);
|
||||||
|
|
||||||
|
public static Vector4 operator -(Vector4 value, float scalar) => Vector4(value.X - scalar, value.Y - scalar, value.Z - scalar, value.W - scalar);
|
||||||
|
|
||||||
|
public static Vector4 operator -(float scalar, Vector4 value) => Vector4(scalar - value.X, scalar - value.Y, scalar - value.Z, scalar - value.W);
|
||||||
|
|
||||||
|
public static Vector4 operator -(Vector4 value) => Vector4(-value.X, -value.Y, -value.Z, -value.W);
|
||||||
|
|
||||||
|
// Multiplication
|
||||||
|
|
||||||
|
public static Vector4 operator *(Vector4 left, Vector4 right) => Vector4(left.X * right.X, left.Y * right.Y, left.Z * right.Z, left.W * right.W);
|
||||||
|
|
||||||
|
public static Vector4 operator *(Vector4 value, float scalar) => Vector4(value.X * scalar, value.Y * scalar, value.Z * scalar, value.W * scalar);
|
||||||
|
|
||||||
|
public static Vector4 operator *(float scalar, Vector4 value) => Vector4(scalar * value.X, scalar * value.Y, scalar * value.Z, scalar * value.W);
|
||||||
|
|
||||||
|
// Division
|
||||||
|
|
||||||
|
public static Vector4 operator /(Vector4 left, Vector4 right) => Vector4(left.X / right.X, left.Y / right.Y, left.Z / right.Z, left.W / right.W);
|
||||||
|
|
||||||
|
public static Vector4 operator /(Vector4 value, float scalar)
|
||||||
|
{
|
||||||
|
float inv = 1.0f / scalar;
|
||||||
|
return Vector4(value.X * inv, value.Y * inv, value.Z * inv, value.W * inv);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Vector4 operator /(float scalar, Vector4 value) => Vector4(scalar / value.X, scalar / value.Y, scalar / value.Z, scalar / value.W);
|
||||||
|
|
||||||
|
// Equality
|
||||||
|
|
||||||
|
public static bool operator ==(Vector4 left, Vector4 right) => left.X == right.X && left.Y == right.Y && left.Z == right.Z && left.W == right.W;
|
||||||
|
|
||||||
|
public static bool operator !=(Vector4 left, Vector4 right) => left.X != right.X || left.Y != right.Y || left.Z != right.Z || left.W != right.W;
|
||||||
|
|
||||||
|
public override void ToString(String strBuffer) => strBuffer.AppendF("X:{0} Y:{1} Z:{2} W:{3}", X, Y, Z, W);
|
||||||
|
|
||||||
|
// Todo: move to extension
|
||||||
|
|
||||||
|
[Inline]
|
||||||
|
public static implicit operator DirectX.Math.Vector4(in Self value) => *(DirectX.Math.Vector4*)&value;
|
||||||
|
|
||||||
|
[Inline]
|
||||||
|
public static implicit operator Self(in DirectX.Math.Vector4 value) => *(Self*)&value;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
#pragma warning disable 4204
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace GlitchyEngine.Math
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
extension Vector2
|
||||||
|
{
|
||||||
|
[Inline]
|
||||||
|
public static implicit operator DirectX.Math.Vector2(in Self value) => *(DirectX.Math.Vector2*)&value;
|
||||||
|
|
||||||
|
[Inline]
|
||||||
|
public static implicit operator Self(in DirectX.Math.Vector2 value) => *(Self*)&value;
|
||||||
|
}
|
||||||
|
|
||||||
|
extension Vector3
|
||||||
|
{
|
||||||
|
[Inline]
|
||||||
|
public static implicit operator DirectX.Math.Vector3(in Self value) => *(DirectX.Math.Vector3*)&value;
|
||||||
|
|
||||||
|
[Inline]
|
||||||
|
public static implicit operator Self(in DirectX.Math.Vector3 value) => *(Self*)&value;
|
||||||
|
}
|
||||||
|
|
||||||
|
extension Vector4
|
||||||
|
{
|
||||||
|
[Inline]
|
||||||
|
public static implicit operator DirectX.Math.Vector4(in Self value) => *(DirectX.Math.Vector4*)&value;
|
||||||
|
|
||||||
|
[Inline]
|
||||||
|
public static implicit operator Self(in DirectX.Math.Vector4 value) => *(Self*)&value;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user