Add Vector type in SPMD to total of load vector size * lane width of number into memory for simd calculation.
This commit is contained in:
@@ -0,0 +1,873 @@
|
||||
/// <auto-generated/>
|
||||
/// This code is automatically generated by a T4 template.
|
||||
/// Changes to this file may cause incorrect behavior and will be lost if the code is regenerated.
|
||||
/// </auto-generated>
|
||||
|
||||
using System.Numerics;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
namespace Misaki.HighPerformance.Mathematics.SPMD;
|
||||
|
||||
|
||||
public static unsafe partial class MathV
|
||||
{
|
||||
# region Vector2
|
||||
|
||||
// Creation Functions
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector2<TLane, TNumber> Create<TLane, TNumber>(in TLane x, in TLane y)
|
||||
where TLane : ISPMD<TLane, TNumber>
|
||||
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
|
||||
{
|
||||
return new Vector2<TLane, TNumber>
|
||||
{
|
||||
x = x,
|
||||
y = y,
|
||||
};
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector2<TLane, TNumber> CreateVector2<TLane, TNumber>(in TLane value)
|
||||
where TLane : ISPMD<TLane, TNumber>
|
||||
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
|
||||
{
|
||||
return new Vector2<TLane, TNumber>
|
||||
{
|
||||
x = value,
|
||||
y = value,
|
||||
};
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector2<TLane, TNumber> LoadVector2<TLane, TNumber>(TNumber* pSrc)
|
||||
where TLane : ISPMD<TLane, TNumber>
|
||||
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
|
||||
{
|
||||
var width = TLane.LaneWidth;
|
||||
|
||||
var x = stackalloc TNumber[width];
|
||||
var y = stackalloc TNumber[width];
|
||||
|
||||
for (var i = 0; i < width; i++)
|
||||
{
|
||||
x[i] = pSrc[i * 2 + 0];
|
||||
y[i] = pSrc[i * 2 + 1];
|
||||
}
|
||||
|
||||
return new Vector2<TLane, TNumber>
|
||||
{
|
||||
x = TLane.Load(x),
|
||||
y = TLane.Load(y),
|
||||
};
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector2<TLane, TNumber> LoadVector2<TLane, TNumber>(ref TNumber src)
|
||||
where TLane : ISPMD<TLane, TNumber>
|
||||
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
|
||||
{
|
||||
return LoadVector2<TLane, TNumber>((TNumber*)Unsafe.AsPointer(ref src));
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector2<TLane, TNumber> Load<TLane, TNumber>(TNumber* px, TNumber* py)
|
||||
where TLane : ISPMD<TLane, TNumber>
|
||||
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
|
||||
{
|
||||
return new Vector2<TLane, TNumber>
|
||||
{
|
||||
x = TLane.Load(px),
|
||||
y = TLane.Load(py),
|
||||
};
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector2<TLane, TNumber> Load<TLane, TNumber>(ref TNumber x, ref TNumber y)
|
||||
where TLane : ISPMD<TLane, TNumber>
|
||||
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
|
||||
{
|
||||
return new Vector2<TLane, TNumber>
|
||||
{
|
||||
x = TLane.Load(ref x),
|
||||
y = TLane.Load(ref y),
|
||||
};
|
||||
}
|
||||
|
||||
// Math Functions
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector2<TLane, TNumber> Abs<TLane, TNumber>(in Vector2<TLane, TNumber> vector)
|
||||
where TLane : ISPMD<TLane, TNumber>
|
||||
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
|
||||
{
|
||||
return new Vector2<TLane, TNumber>
|
||||
{
|
||||
x = TLane.Abs(vector.x),
|
||||
y = TLane.Abs(vector.y),
|
||||
};
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static TLane Dot<TLane, TNumber>(in Vector2<TLane, TNumber> a, in Vector2<TLane, TNumber> b)
|
||||
where TLane : ISPMD<TLane, TNumber>
|
||||
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
|
||||
{
|
||||
return a.x * b.x + a.y * b.y;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector2<TLane, TNumber> Sqrt<TLane, TNumber>(in Vector2<TLane, TNumber> vector)
|
||||
where TLane : ISPMD<TLane, TNumber>
|
||||
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
|
||||
{
|
||||
return new Vector2<TLane, TNumber>
|
||||
{
|
||||
x = TLane.Sqrt(vector.x),
|
||||
y = TLane.Sqrt(vector.y),
|
||||
};
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector2<TLane, TNumber> Rsqrt<TLane, TNumber>(in Vector2<TLane, TNumber> vector)
|
||||
where TLane : ISPMD<TLane, TNumber>
|
||||
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
|
||||
{
|
||||
return new Vector2<TLane, TNumber>
|
||||
{
|
||||
x = TLane.Rsqrt(vector.x),
|
||||
y = TLane.Rsqrt(vector.y),
|
||||
};
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector2<TLane, TNumber> Normalize<TLane, TNumber>(in Vector2<TLane, TNumber> vector)
|
||||
where TLane : ISPMD<TLane, TNumber>
|
||||
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
|
||||
{
|
||||
return vector * TLane.Rsqrt(Dot(vector, vector));
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector2<TLane, TNumber> Reflect<TLane, TNumber>(in Vector2<TLane, TNumber> incident, in Vector2<TLane, TNumber> normal)
|
||||
where TLane : ISPMD<TLane, TNumber>
|
||||
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
|
||||
{
|
||||
var dot = Dot(incident, normal);
|
||||
return incident - normal * (dot + dot);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector2<TLane, TNumber> Min<TLane, TNumber>(in Vector2<TLane, TNumber> a, in Vector2<TLane, TNumber> b)
|
||||
where TLane : ISPMD<TLane, TNumber>
|
||||
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
|
||||
{
|
||||
return new Vector2<TLane, TNumber>
|
||||
{
|
||||
x = TLane.Min(a.x, b.x),
|
||||
y = TLane.Min(a.y, b.y),
|
||||
};
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector2<TLane, TNumber> Max<TLane, TNumber>(in Vector2<TLane, TNumber> a, in Vector2<TLane, TNumber> b)
|
||||
where TLane : ISPMD<TLane, TNumber>
|
||||
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
|
||||
{
|
||||
return new Vector2<TLane, TNumber>
|
||||
{
|
||||
x = TLane.Max(a.x, b.x),
|
||||
y = TLane.Max(a.y, b.y),
|
||||
};
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector2<TLane, TNumber> Clamp<TLane, TNumber>(in Vector2<TLane, TNumber> value, in Vector2<TLane, TNumber> min, in Vector2<TLane, TNumber> max)
|
||||
where TLane : ISPMD<TLane, TNumber>
|
||||
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
|
||||
{
|
||||
return Min(Max(value, min), max);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector2<TLane, TNumber> Saturate<TLane, TNumber>(in Vector2<TLane, TNumber> value)
|
||||
where TLane : ISPMD<TLane, TNumber>
|
||||
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
|
||||
{
|
||||
return Clamp(value, CreateVector2<TLane, TNumber>(TLane.Zero), CreateVector2<TLane, TNumber>(TLane.One));
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector2<TLane, TNumber> Lerp<TLane, TNumber>(in Vector2<TLane, TNumber> a, in Vector2<TLane, TNumber> b, TLane t)
|
||||
where TLane : ISPMD<TLane, TNumber>
|
||||
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
|
||||
{
|
||||
return a + (b - a) * t;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static TLane Length<TLane, TNumber>(in Vector2<TLane, TNumber> vector)
|
||||
where TLane : ISPMD<TLane, TNumber>
|
||||
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
|
||||
{
|
||||
return TLane.Sqrt(Dot(vector, vector));
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static TLane LengthSquared<TLane, TNumber>(in Vector2<TLane, TNumber> vector)
|
||||
where TLane : ISPMD<TLane, TNumber>
|
||||
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
|
||||
{
|
||||
return Dot(vector, vector);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static TLane Distance<TLane, TNumber>(in Vector2<TLane, TNumber> a, in Vector2<TLane, TNumber> b)
|
||||
where TLane : ISPMD<TLane, TNumber>
|
||||
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
|
||||
{
|
||||
var diff = b - a;
|
||||
return TLane.Sqrt(Dot(diff, diff));
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static TLane DistanceSquared<TLane, TNumber>(in Vector2<TLane, TNumber> a, in Vector2<TLane, TNumber> b)
|
||||
where TLane : ISPMD<TLane, TNumber>
|
||||
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
|
||||
{
|
||||
var diff = b - a;
|
||||
return Dot(diff, diff);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector2<TLane, TNumber> Step<TLane, TNumber>(in Vector2<TLane, TNumber> edge, in Vector2<TLane, TNumber> value)
|
||||
where TLane : ISPMD<TLane, TNumber>
|
||||
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
|
||||
{
|
||||
return Select(value >= edge, Vector2<TLane, TNumber>.One, Vector2<TLane, TNumber>.Zero);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector2<TLane, TNumber> Smoothstep<TLane, TNumber>(Vector2<TLane, TNumber> xMin, Vector2<TLane, TNumber> xMax, Vector2<TLane, TNumber> x)
|
||||
where TLane : ISPMD<TLane, TNumber>
|
||||
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
|
||||
{
|
||||
var t = Saturate((x - xMin) / (xMax - xMin));
|
||||
var two = TLane.Create(TNumber.CreateTruncating(2));
|
||||
var three = TLane.Create(TNumber.CreateTruncating(3));
|
||||
|
||||
return t * t * (CreateVector2<TLane, TNumber>(three) - (CreateVector2<TLane, TNumber>(two) * t));
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector2<TLane, TNumber> Select<TLane, TNumber>(TLane condition, in Vector2<TLane, TNumber> a, in Vector2<TLane, TNumber> b)
|
||||
where TLane : ISPMD<TLane, TNumber>
|
||||
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
|
||||
{
|
||||
return new Vector2<TLane, TNumber>
|
||||
{
|
||||
x = TLane.Select(condition, b.x, a.x),
|
||||
y = TLane.Select(condition, b.y, a.y),
|
||||
};
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector2<TLane, TNumber> Select<TLane, TNumber>(Vector2<TLane, TNumber> condition, in Vector2<TLane, TNumber> a, in Vector2<TLane, TNumber> b)
|
||||
where TLane : ISPMD<TLane, TNumber>
|
||||
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
|
||||
{
|
||||
return new Vector2<TLane, TNumber>
|
||||
{
|
||||
x = TLane.Select(condition.x, b.x, a.x),
|
||||
y = TLane.Select(condition.y, b.y, a.y),
|
||||
};
|
||||
}
|
||||
|
||||
# endregion
|
||||
|
||||
# region Vector3
|
||||
|
||||
// Creation Functions
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector3<TLane, TNumber> Create<TLane, TNumber>(in TLane x, in TLane y, in TLane z)
|
||||
where TLane : ISPMD<TLane, TNumber>
|
||||
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
|
||||
{
|
||||
return new Vector3<TLane, TNumber>
|
||||
{
|
||||
x = x,
|
||||
y = y,
|
||||
z = z,
|
||||
};
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector3<TLane, TNumber> CreateVector3<TLane, TNumber>(in TLane value)
|
||||
where TLane : ISPMD<TLane, TNumber>
|
||||
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
|
||||
{
|
||||
return new Vector3<TLane, TNumber>
|
||||
{
|
||||
x = value,
|
||||
y = value,
|
||||
z = value,
|
||||
};
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector3<TLane, TNumber> LoadVector3<TLane, TNumber>(TNumber* pSrc)
|
||||
where TLane : ISPMD<TLane, TNumber>
|
||||
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
|
||||
{
|
||||
var width = TLane.LaneWidth;
|
||||
|
||||
var x = stackalloc TNumber[width];
|
||||
var y = stackalloc TNumber[width];
|
||||
var z = stackalloc TNumber[width];
|
||||
|
||||
for (var i = 0; i < width; i++)
|
||||
{
|
||||
x[i] = pSrc[i * 3 + 0];
|
||||
y[i] = pSrc[i * 3 + 1];
|
||||
z[i] = pSrc[i * 3 + 2];
|
||||
}
|
||||
|
||||
return new Vector3<TLane, TNumber>
|
||||
{
|
||||
x = TLane.Load(x),
|
||||
y = TLane.Load(y),
|
||||
z = TLane.Load(z),
|
||||
};
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector3<TLane, TNumber> LoadVector3<TLane, TNumber>(ref TNumber src)
|
||||
where TLane : ISPMD<TLane, TNumber>
|
||||
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
|
||||
{
|
||||
return LoadVector3<TLane, TNumber>((TNumber*)Unsafe.AsPointer(ref src));
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector3<TLane, TNumber> Load<TLane, TNumber>(TNumber* px, TNumber* py, TNumber* pz)
|
||||
where TLane : ISPMD<TLane, TNumber>
|
||||
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
|
||||
{
|
||||
return new Vector3<TLane, TNumber>
|
||||
{
|
||||
x = TLane.Load(px),
|
||||
y = TLane.Load(py),
|
||||
z = TLane.Load(pz),
|
||||
};
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector3<TLane, TNumber> Load<TLane, TNumber>(ref TNumber x, ref TNumber y, ref TNumber z)
|
||||
where TLane : ISPMD<TLane, TNumber>
|
||||
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
|
||||
{
|
||||
return new Vector3<TLane, TNumber>
|
||||
{
|
||||
x = TLane.Load(ref x),
|
||||
y = TLane.Load(ref y),
|
||||
z = TLane.Load(ref z),
|
||||
};
|
||||
}
|
||||
|
||||
// Math Functions
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector3<TLane, TNumber> Abs<TLane, TNumber>(in Vector3<TLane, TNumber> vector)
|
||||
where TLane : ISPMD<TLane, TNumber>
|
||||
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
|
||||
{
|
||||
return new Vector3<TLane, TNumber>
|
||||
{
|
||||
x = TLane.Abs(vector.x),
|
||||
y = TLane.Abs(vector.y),
|
||||
z = TLane.Abs(vector.z),
|
||||
};
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static TLane Dot<TLane, TNumber>(in Vector3<TLane, TNumber> a, in Vector3<TLane, TNumber> b)
|
||||
where TLane : ISPMD<TLane, TNumber>
|
||||
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
|
||||
{
|
||||
return a.x * b.x + a.y * b.y;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector3<TLane, TNumber> Sqrt<TLane, TNumber>(in Vector3<TLane, TNumber> vector)
|
||||
where TLane : ISPMD<TLane, TNumber>
|
||||
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
|
||||
{
|
||||
return new Vector3<TLane, TNumber>
|
||||
{
|
||||
x = TLane.Sqrt(vector.x),
|
||||
y = TLane.Sqrt(vector.y),
|
||||
z = TLane.Sqrt(vector.z),
|
||||
};
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector3<TLane, TNumber> Rsqrt<TLane, TNumber>(in Vector3<TLane, TNumber> vector)
|
||||
where TLane : ISPMD<TLane, TNumber>
|
||||
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
|
||||
{
|
||||
return new Vector3<TLane, TNumber>
|
||||
{
|
||||
x = TLane.Rsqrt(vector.x),
|
||||
y = TLane.Rsqrt(vector.y),
|
||||
z = TLane.Rsqrt(vector.z),
|
||||
};
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector3<TLane, TNumber> Normalize<TLane, TNumber>(in Vector3<TLane, TNumber> vector)
|
||||
where TLane : ISPMD<TLane, TNumber>
|
||||
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
|
||||
{
|
||||
return vector * TLane.Rsqrt(Dot(vector, vector));
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector3<TLane, TNumber> Reflect<TLane, TNumber>(in Vector3<TLane, TNumber> incident, in Vector3<TLane, TNumber> normal)
|
||||
where TLane : ISPMD<TLane, TNumber>
|
||||
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
|
||||
{
|
||||
var dot = Dot(incident, normal);
|
||||
return incident - normal * (dot + dot);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector3<TLane, TNumber> Min<TLane, TNumber>(in Vector3<TLane, TNumber> a, in Vector3<TLane, TNumber> b)
|
||||
where TLane : ISPMD<TLane, TNumber>
|
||||
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
|
||||
{
|
||||
return new Vector3<TLane, TNumber>
|
||||
{
|
||||
x = TLane.Min(a.x, b.x),
|
||||
y = TLane.Min(a.y, b.y),
|
||||
z = TLane.Min(a.z, b.z),
|
||||
};
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector3<TLane, TNumber> Max<TLane, TNumber>(in Vector3<TLane, TNumber> a, in Vector3<TLane, TNumber> b)
|
||||
where TLane : ISPMD<TLane, TNumber>
|
||||
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
|
||||
{
|
||||
return new Vector3<TLane, TNumber>
|
||||
{
|
||||
x = TLane.Max(a.x, b.x),
|
||||
y = TLane.Max(a.y, b.y),
|
||||
z = TLane.Max(a.z, b.z),
|
||||
};
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector3<TLane, TNumber> Clamp<TLane, TNumber>(in Vector3<TLane, TNumber> value, in Vector3<TLane, TNumber> min, in Vector3<TLane, TNumber> max)
|
||||
where TLane : ISPMD<TLane, TNumber>
|
||||
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
|
||||
{
|
||||
return Min(Max(value, min), max);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector3<TLane, TNumber> Saturate<TLane, TNumber>(in Vector3<TLane, TNumber> value)
|
||||
where TLane : ISPMD<TLane, TNumber>
|
||||
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
|
||||
{
|
||||
return Clamp(value, CreateVector3<TLane, TNumber>(TLane.Zero), CreateVector3<TLane, TNumber>(TLane.One));
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector3<TLane, TNumber> Lerp<TLane, TNumber>(in Vector3<TLane, TNumber> a, in Vector3<TLane, TNumber> b, TLane t)
|
||||
where TLane : ISPMD<TLane, TNumber>
|
||||
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
|
||||
{
|
||||
return a + (b - a) * t;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static TLane Length<TLane, TNumber>(in Vector3<TLane, TNumber> vector)
|
||||
where TLane : ISPMD<TLane, TNumber>
|
||||
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
|
||||
{
|
||||
return TLane.Sqrt(Dot(vector, vector));
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static TLane LengthSquared<TLane, TNumber>(in Vector3<TLane, TNumber> vector)
|
||||
where TLane : ISPMD<TLane, TNumber>
|
||||
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
|
||||
{
|
||||
return Dot(vector, vector);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static TLane Distance<TLane, TNumber>(in Vector3<TLane, TNumber> a, in Vector3<TLane, TNumber> b)
|
||||
where TLane : ISPMD<TLane, TNumber>
|
||||
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
|
||||
{
|
||||
var diff = b - a;
|
||||
return TLane.Sqrt(Dot(diff, diff));
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static TLane DistanceSquared<TLane, TNumber>(in Vector3<TLane, TNumber> a, in Vector3<TLane, TNumber> b)
|
||||
where TLane : ISPMD<TLane, TNumber>
|
||||
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
|
||||
{
|
||||
var diff = b - a;
|
||||
return Dot(diff, diff);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector3<TLane, TNumber> Step<TLane, TNumber>(in Vector3<TLane, TNumber> edge, in Vector3<TLane, TNumber> value)
|
||||
where TLane : ISPMD<TLane, TNumber>
|
||||
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
|
||||
{
|
||||
return Select(value >= edge, Vector3<TLane, TNumber>.One, Vector3<TLane, TNumber>.Zero);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector3<TLane, TNumber> Smoothstep<TLane, TNumber>(Vector3<TLane, TNumber> xMin, Vector3<TLane, TNumber> xMax, Vector3<TLane, TNumber> x)
|
||||
where TLane : ISPMD<TLane, TNumber>
|
||||
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
|
||||
{
|
||||
var t = Saturate((x - xMin) / (xMax - xMin));
|
||||
var two = TLane.Create(TNumber.CreateTruncating(2));
|
||||
var three = TLane.Create(TNumber.CreateTruncating(3));
|
||||
|
||||
return t * t * (CreateVector3<TLane, TNumber>(three) - (CreateVector3<TLane, TNumber>(two) * t));
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector3<TLane, TNumber> Select<TLane, TNumber>(TLane condition, in Vector3<TLane, TNumber> a, in Vector3<TLane, TNumber> b)
|
||||
where TLane : ISPMD<TLane, TNumber>
|
||||
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
|
||||
{
|
||||
return new Vector3<TLane, TNumber>
|
||||
{
|
||||
x = TLane.Select(condition, b.x, a.x),
|
||||
y = TLane.Select(condition, b.y, a.y),
|
||||
};
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector3<TLane, TNumber> Select<TLane, TNumber>(Vector3<TLane, TNumber> condition, in Vector3<TLane, TNumber> a, in Vector3<TLane, TNumber> b)
|
||||
where TLane : ISPMD<TLane, TNumber>
|
||||
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
|
||||
{
|
||||
return new Vector3<TLane, TNumber>
|
||||
{
|
||||
x = TLane.Select(condition.x, b.x, a.x),
|
||||
y = TLane.Select(condition.y, b.y, a.y),
|
||||
};
|
||||
}
|
||||
|
||||
# endregion
|
||||
|
||||
# region Vector4
|
||||
|
||||
// Creation Functions
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector4<TLane, TNumber> Create<TLane, TNumber>(in TLane x, in TLane y, in TLane z, in TLane w)
|
||||
where TLane : ISPMD<TLane, TNumber>
|
||||
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
|
||||
{
|
||||
return new Vector4<TLane, TNumber>
|
||||
{
|
||||
x = x,
|
||||
y = y,
|
||||
z = z,
|
||||
w = w,
|
||||
};
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector4<TLane, TNumber> CreateVector4<TLane, TNumber>(in TLane value)
|
||||
where TLane : ISPMD<TLane, TNumber>
|
||||
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
|
||||
{
|
||||
return new Vector4<TLane, TNumber>
|
||||
{
|
||||
x = value,
|
||||
y = value,
|
||||
z = value,
|
||||
w = value,
|
||||
};
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector4<TLane, TNumber> LoadVector4<TLane, TNumber>(TNumber* pSrc)
|
||||
where TLane : ISPMD<TLane, TNumber>
|
||||
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
|
||||
{
|
||||
var width = TLane.LaneWidth;
|
||||
|
||||
var x = stackalloc TNumber[width];
|
||||
var y = stackalloc TNumber[width];
|
||||
var z = stackalloc TNumber[width];
|
||||
var w = stackalloc TNumber[width];
|
||||
|
||||
for (var i = 0; i < width; i++)
|
||||
{
|
||||
x[i] = pSrc[i * 4 + 0];
|
||||
y[i] = pSrc[i * 4 + 1];
|
||||
z[i] = pSrc[i * 4 + 2];
|
||||
w[i] = pSrc[i * 4 + 3];
|
||||
}
|
||||
|
||||
return new Vector4<TLane, TNumber>
|
||||
{
|
||||
x = TLane.Load(x),
|
||||
y = TLane.Load(y),
|
||||
z = TLane.Load(z),
|
||||
w = TLane.Load(w),
|
||||
};
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector4<TLane, TNumber> LoadVector4<TLane, TNumber>(ref TNumber src)
|
||||
where TLane : ISPMD<TLane, TNumber>
|
||||
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
|
||||
{
|
||||
return LoadVector4<TLane, TNumber>((TNumber*)Unsafe.AsPointer(ref src));
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector4<TLane, TNumber> Load<TLane, TNumber>(TNumber* px, TNumber* py, TNumber* pz, TNumber* pw)
|
||||
where TLane : ISPMD<TLane, TNumber>
|
||||
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
|
||||
{
|
||||
return new Vector4<TLane, TNumber>
|
||||
{
|
||||
x = TLane.Load(px),
|
||||
y = TLane.Load(py),
|
||||
z = TLane.Load(pz),
|
||||
w = TLane.Load(pw),
|
||||
};
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector4<TLane, TNumber> Load<TLane, TNumber>(ref TNumber x, ref TNumber y, ref TNumber z, ref TNumber w)
|
||||
where TLane : ISPMD<TLane, TNumber>
|
||||
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
|
||||
{
|
||||
return new Vector4<TLane, TNumber>
|
||||
{
|
||||
x = TLane.Load(ref x),
|
||||
y = TLane.Load(ref y),
|
||||
z = TLane.Load(ref z),
|
||||
w = TLane.Load(ref w),
|
||||
};
|
||||
}
|
||||
|
||||
// Math Functions
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector4<TLane, TNumber> Abs<TLane, TNumber>(in Vector4<TLane, TNumber> vector)
|
||||
where TLane : ISPMD<TLane, TNumber>
|
||||
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
|
||||
{
|
||||
return new Vector4<TLane, TNumber>
|
||||
{
|
||||
x = TLane.Abs(vector.x),
|
||||
y = TLane.Abs(vector.y),
|
||||
z = TLane.Abs(vector.z),
|
||||
w = TLane.Abs(vector.w),
|
||||
};
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static TLane Dot<TLane, TNumber>(in Vector4<TLane, TNumber> a, in Vector4<TLane, TNumber> b)
|
||||
where TLane : ISPMD<TLane, TNumber>
|
||||
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
|
||||
{
|
||||
return a.x * b.x + a.y * b.y;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector4<TLane, TNumber> Sqrt<TLane, TNumber>(in Vector4<TLane, TNumber> vector)
|
||||
where TLane : ISPMD<TLane, TNumber>
|
||||
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
|
||||
{
|
||||
return new Vector4<TLane, TNumber>
|
||||
{
|
||||
x = TLane.Sqrt(vector.x),
|
||||
y = TLane.Sqrt(vector.y),
|
||||
z = TLane.Sqrt(vector.z),
|
||||
w = TLane.Sqrt(vector.w),
|
||||
};
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector4<TLane, TNumber> Rsqrt<TLane, TNumber>(in Vector4<TLane, TNumber> vector)
|
||||
where TLane : ISPMD<TLane, TNumber>
|
||||
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
|
||||
{
|
||||
return new Vector4<TLane, TNumber>
|
||||
{
|
||||
x = TLane.Rsqrt(vector.x),
|
||||
y = TLane.Rsqrt(vector.y),
|
||||
z = TLane.Rsqrt(vector.z),
|
||||
w = TLane.Rsqrt(vector.w),
|
||||
};
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector4<TLane, TNumber> Normalize<TLane, TNumber>(in Vector4<TLane, TNumber> vector)
|
||||
where TLane : ISPMD<TLane, TNumber>
|
||||
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
|
||||
{
|
||||
return vector * TLane.Rsqrt(Dot(vector, vector));
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector4<TLane, TNumber> Reflect<TLane, TNumber>(in Vector4<TLane, TNumber> incident, in Vector4<TLane, TNumber> normal)
|
||||
where TLane : ISPMD<TLane, TNumber>
|
||||
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
|
||||
{
|
||||
var dot = Dot(incident, normal);
|
||||
return incident - normal * (dot + dot);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector4<TLane, TNumber> Min<TLane, TNumber>(in Vector4<TLane, TNumber> a, in Vector4<TLane, TNumber> b)
|
||||
where TLane : ISPMD<TLane, TNumber>
|
||||
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
|
||||
{
|
||||
return new Vector4<TLane, TNumber>
|
||||
{
|
||||
x = TLane.Min(a.x, b.x),
|
||||
y = TLane.Min(a.y, b.y),
|
||||
z = TLane.Min(a.z, b.z),
|
||||
w = TLane.Min(a.w, b.w),
|
||||
};
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector4<TLane, TNumber> Max<TLane, TNumber>(in Vector4<TLane, TNumber> a, in Vector4<TLane, TNumber> b)
|
||||
where TLane : ISPMD<TLane, TNumber>
|
||||
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
|
||||
{
|
||||
return new Vector4<TLane, TNumber>
|
||||
{
|
||||
x = TLane.Max(a.x, b.x),
|
||||
y = TLane.Max(a.y, b.y),
|
||||
z = TLane.Max(a.z, b.z),
|
||||
w = TLane.Max(a.w, b.w),
|
||||
};
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector4<TLane, TNumber> Clamp<TLane, TNumber>(in Vector4<TLane, TNumber> value, in Vector4<TLane, TNumber> min, in Vector4<TLane, TNumber> max)
|
||||
where TLane : ISPMD<TLane, TNumber>
|
||||
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
|
||||
{
|
||||
return Min(Max(value, min), max);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector4<TLane, TNumber> Saturate<TLane, TNumber>(in Vector4<TLane, TNumber> value)
|
||||
where TLane : ISPMD<TLane, TNumber>
|
||||
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
|
||||
{
|
||||
return Clamp(value, CreateVector4<TLane, TNumber>(TLane.Zero), CreateVector4<TLane, TNumber>(TLane.One));
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector4<TLane, TNumber> Lerp<TLane, TNumber>(in Vector4<TLane, TNumber> a, in Vector4<TLane, TNumber> b, TLane t)
|
||||
where TLane : ISPMD<TLane, TNumber>
|
||||
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
|
||||
{
|
||||
return a + (b - a) * t;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static TLane Length<TLane, TNumber>(in Vector4<TLane, TNumber> vector)
|
||||
where TLane : ISPMD<TLane, TNumber>
|
||||
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
|
||||
{
|
||||
return TLane.Sqrt(Dot(vector, vector));
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static TLane LengthSquared<TLane, TNumber>(in Vector4<TLane, TNumber> vector)
|
||||
where TLane : ISPMD<TLane, TNumber>
|
||||
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
|
||||
{
|
||||
return Dot(vector, vector);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static TLane Distance<TLane, TNumber>(in Vector4<TLane, TNumber> a, in Vector4<TLane, TNumber> b)
|
||||
where TLane : ISPMD<TLane, TNumber>
|
||||
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
|
||||
{
|
||||
var diff = b - a;
|
||||
return TLane.Sqrt(Dot(diff, diff));
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static TLane DistanceSquared<TLane, TNumber>(in Vector4<TLane, TNumber> a, in Vector4<TLane, TNumber> b)
|
||||
where TLane : ISPMD<TLane, TNumber>
|
||||
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
|
||||
{
|
||||
var diff = b - a;
|
||||
return Dot(diff, diff);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector4<TLane, TNumber> Step<TLane, TNumber>(in Vector4<TLane, TNumber> edge, in Vector4<TLane, TNumber> value)
|
||||
where TLane : ISPMD<TLane, TNumber>
|
||||
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
|
||||
{
|
||||
return Select(value >= edge, Vector4<TLane, TNumber>.One, Vector4<TLane, TNumber>.Zero);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector4<TLane, TNumber> Smoothstep<TLane, TNumber>(Vector4<TLane, TNumber> xMin, Vector4<TLane, TNumber> xMax, Vector4<TLane, TNumber> x)
|
||||
where TLane : ISPMD<TLane, TNumber>
|
||||
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
|
||||
{
|
||||
var t = Saturate((x - xMin) / (xMax - xMin));
|
||||
var two = TLane.Create(TNumber.CreateTruncating(2));
|
||||
var three = TLane.Create(TNumber.CreateTruncating(3));
|
||||
|
||||
return t * t * (CreateVector4<TLane, TNumber>(three) - (CreateVector4<TLane, TNumber>(two) * t));
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector4<TLane, TNumber> Select<TLane, TNumber>(TLane condition, in Vector4<TLane, TNumber> a, in Vector4<TLane, TNumber> b)
|
||||
where TLane : ISPMD<TLane, TNumber>
|
||||
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
|
||||
{
|
||||
return new Vector4<TLane, TNumber>
|
||||
{
|
||||
x = TLane.Select(condition, b.x, a.x),
|
||||
y = TLane.Select(condition, b.y, a.y),
|
||||
};
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector4<TLane, TNumber> Select<TLane, TNumber>(Vector4<TLane, TNumber> condition, in Vector4<TLane, TNumber> a, in Vector4<TLane, TNumber> b)
|
||||
where TLane : ISPMD<TLane, TNumber>
|
||||
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
|
||||
{
|
||||
return new Vector4<TLane, TNumber>
|
||||
{
|
||||
x = TLane.Select(condition.x, b.x, a.x),
|
||||
y = TLane.Select(condition.y, b.y, a.y),
|
||||
};
|
||||
}
|
||||
|
||||
# endregion
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,327 @@
|
||||
<#@ template debug="false" hostspecific="false" language="C#" #>
|
||||
<#@ assembly name="System.Core" #>
|
||||
<#@ import namespace="System.Linq" #>
|
||||
<#@ import namespace="System.Text" #>
|
||||
<#@ import namespace="System.Collections.Generic" #>
|
||||
<#@ output extension=".gen.cs" #>
|
||||
/// <auto-generated/>
|
||||
/// This code is automatically generated by a T4 template.
|
||||
/// Changes to this file may cause incorrect behavior and will be lost if the code is regenerated.
|
||||
/// </auto-generated>
|
||||
|
||||
using System.Numerics;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
namespace Misaki.HighPerformance.Mathematics.SPMD;
|
||||
|
||||
<#
|
||||
const string TLane = "TLane";
|
||||
const string TNumber = "TNumber";
|
||||
const string GenericParameters = $"{TLane}, {TNumber}";
|
||||
|
||||
var dimensions = new int[] { 2, 3, 4 };
|
||||
var components = new char[] { 'x', 'y', 'z', 'w' };
|
||||
var TLaneRestrictions = $@"where {TLane} : ISPMD<{TLane}, {TNumber}>";
|
||||
var TNumberRestrictions = $@"where {TNumber} : unmanaged, INumber<{TNumber}>, IBinaryNumber<{TNumber}>, IMinMaxValue<{TNumber}>, IBitwiseOperators<{TNumber}, {TNumber}, {TNumber}>";
|
||||
#>
|
||||
|
||||
public static unsafe partial class MathV
|
||||
{
|
||||
<# foreach (int dimension in dimensions) {
|
||||
var vectorType = $"Vector{dimension}<{TLane}, {TNumber}>";
|
||||
#>
|
||||
# region Vector<#= dimension #>
|
||||
|
||||
// Creation Functions
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static <#= vectorType #> Create<<#= GenericParameters #>>(<#= ForEachDimension(dimension, i => $"in TLane {components[i]}") #>)
|
||||
<#= TLaneRestrictions #>
|
||||
<#= TNumberRestrictions #>
|
||||
{
|
||||
return new <#= vectorType #>
|
||||
{
|
||||
<# for (int i = 0; i < dimension; i++) { #>
|
||||
<#= components[i] #> = <#= components[i] #>,
|
||||
<# } #>
|
||||
};
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static <#= vectorType #> CreateVector<#= dimension #><<#= GenericParameters #>>(in TLane value)
|
||||
<#= TLaneRestrictions #>
|
||||
<#= TNumberRestrictions #>
|
||||
{
|
||||
return new <#= vectorType #>
|
||||
{
|
||||
<# for (int i = 0; i < dimension; i++) { #>
|
||||
<#= components[i] #> = value,
|
||||
<# } #>
|
||||
};
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static <#= vectorType #> LoadVector<#= dimension #><<#= GenericParameters #>>(TNumber* pSrc)
|
||||
<#= TLaneRestrictions #>
|
||||
<#= TNumberRestrictions #>
|
||||
{
|
||||
var width = TLane.LaneWidth;
|
||||
|
||||
<# for (int i = 0; i < dimension; i++) { #>
|
||||
var <#= components[i] #> = stackalloc TNumber[width];
|
||||
<# } #>
|
||||
|
||||
for (var i = 0; i < width; i++)
|
||||
{
|
||||
<# for (int i = 0; i < dimension; i++) { #>
|
||||
<#= components[i] #>[i] = pSrc[i * <#= dimension #> + <#= i #>];
|
||||
<# } #>
|
||||
}
|
||||
|
||||
return new <#= vectorType #>
|
||||
{
|
||||
<# for (int i = 0; i < dimension; i++) { #>
|
||||
<#= components[i] #> = <#= TLane #>.Load(<#= components[i] #>),
|
||||
<# } #>
|
||||
};
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static <#= vectorType #> LoadVector<#= dimension #><<#= GenericParameters #>>(ref TNumber src)
|
||||
<#= TLaneRestrictions #>
|
||||
<#= TNumberRestrictions #>
|
||||
{
|
||||
return LoadVector<#= dimension #><<#= GenericParameters #>>((TNumber*)Unsafe.AsPointer(ref src));
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static <#= vectorType #> Load<<#= GenericParameters #>>(<#= ForEachDimension(dimension, i => $"TNumber* p{components[i]}") #>)
|
||||
<#= TLaneRestrictions #>
|
||||
<#= TNumberRestrictions #>
|
||||
{
|
||||
return new <#= vectorType #>
|
||||
{
|
||||
<# for (int i = 0; i < dimension; i++) { #>
|
||||
<#= components[i] #> = <#= TLane #>.Load(p<#= components[i] #>),
|
||||
<# } #>
|
||||
};
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static <#= vectorType #> Load<<#= GenericParameters #>>(<#= ForEachDimension(dimension, i => $"ref TNumber {components[i]}") #>)
|
||||
<#= TLaneRestrictions #>
|
||||
<#= TNumberRestrictions #>
|
||||
{
|
||||
return new <#= vectorType #>
|
||||
{
|
||||
<# for (int i = 0; i < dimension; i++) { #>
|
||||
<#= components[i] #> = <#= TLane #>.Load(ref <#= components[i] #>),
|
||||
<# } #>
|
||||
};
|
||||
}
|
||||
|
||||
// Math Functions
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static <#= vectorType #> Abs<<#= GenericParameters #>>(in Vector<#= dimension #><TLane, TNumber> vector)
|
||||
<#= TLaneRestrictions #>
|
||||
<#= TNumberRestrictions #>
|
||||
{
|
||||
return new <#= vectorType #>
|
||||
{
|
||||
<# for (int i = 0; i < dimension; i++) { #>
|
||||
<#= components[i] #> = <#= TLane #>.Abs(vector.<#= components[i] #>),
|
||||
<# } #>
|
||||
};
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static <#= TLane #> Dot<<#= GenericParameters #>>(in <#= vectorType #> a, in <#= vectorType #> b)
|
||||
<#= TLaneRestrictions #>
|
||||
<#= TNumberRestrictions #>
|
||||
{
|
||||
return a.x * b.x + a.y * b.y;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static <#= vectorType #> Sqrt<<#= GenericParameters #>>(in <#= vectorType #> vector)
|
||||
<#= TLaneRestrictions #>
|
||||
<#= TNumberRestrictions #>
|
||||
{
|
||||
return new <#= vectorType #>
|
||||
{
|
||||
<# for (int i = 0; i < dimension; i++) { #>
|
||||
<#= components[i] #> = <#= TLane #>.Sqrt(vector.<#= components[i] #>),
|
||||
<# } #>
|
||||
};
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static <#= vectorType #> Rsqrt<<#= GenericParameters #>>(in <#= vectorType #> vector)
|
||||
<#= TLaneRestrictions #>
|
||||
<#= TNumberRestrictions #>
|
||||
{
|
||||
return new <#= vectorType #>
|
||||
{
|
||||
<# for (int i = 0; i < dimension; i++) { #>
|
||||
<#= components[i] #> = <#= TLane #>.Rsqrt(vector.<#= components[i] #>),
|
||||
<# } #>
|
||||
};
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static <#= vectorType #> Normalize<<#= GenericParameters #>>(in <#= vectorType #> vector)
|
||||
<#= TLaneRestrictions #>
|
||||
<#= TNumberRestrictions #>
|
||||
{
|
||||
return vector * <#= TLane #>.Rsqrt(Dot(vector, vector));
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static <#= vectorType #> Reflect<<#= GenericParameters #>>(in <#= vectorType #> incident, in <#= vectorType #> normal)
|
||||
<#= TLaneRestrictions #>
|
||||
<#= TNumberRestrictions #>
|
||||
{
|
||||
var dot = Dot(incident, normal);
|
||||
return incident - normal * (dot + dot);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static <#= vectorType #> Min<<#= GenericParameters #>>(in <#= vectorType #> a, in <#= vectorType #> b)
|
||||
<#= TLaneRestrictions #>
|
||||
<#= TNumberRestrictions #>
|
||||
{
|
||||
return new <#= vectorType #>
|
||||
{
|
||||
<# for (int i = 0; i < dimension; i++) { #>
|
||||
<#= components[i] #> = <#= TLane #>.Min(a.<#= components[i] #>, b.<#= components[i] #>),
|
||||
<# } #>
|
||||
};
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static <#= vectorType #> Max<<#= GenericParameters #>>(in <#= vectorType #> a, in <#= vectorType #> b)
|
||||
<#= TLaneRestrictions #>
|
||||
<#= TNumberRestrictions #>
|
||||
{
|
||||
return new <#= vectorType #>
|
||||
{
|
||||
<# for (int i = 0; i < dimension; i++) { #>
|
||||
<#= components[i] #> = <#= TLane #>.Max(a.<#= components[i] #>, b.<#= components[i] #>),
|
||||
<# } #>
|
||||
};
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static <#= vectorType #> Clamp<<#= GenericParameters #>>(in <#= vectorType #> value, in <#= vectorType #> min, in <#= vectorType #> max)
|
||||
<#= TLaneRestrictions #>
|
||||
<#= TNumberRestrictions #>
|
||||
{
|
||||
return Min(Max(value, min), max);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static <#= vectorType #> Saturate<<#= GenericParameters #>>(in <#= vectorType #> value)
|
||||
<#= TLaneRestrictions #>
|
||||
<#= TNumberRestrictions #>
|
||||
{
|
||||
return Clamp(value, CreateVector<#= dimension #><<#= GenericParameters #>>(<#= TLane #>.Zero), CreateVector<#= dimension #><<#= GenericParameters #>>(<#= TLane #>.One));
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static <#= vectorType #> Lerp<<#= GenericParameters #>>(in <#= vectorType #> a, in <#= vectorType #> b, <#= TLane #> t)
|
||||
<#= TLaneRestrictions #>
|
||||
<#= TNumberRestrictions #>
|
||||
{
|
||||
return a + (b - a) * t;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static <#= TLane #> Length<<#= GenericParameters #>>(in <#= vectorType #> vector)
|
||||
<#= TLaneRestrictions #>
|
||||
<#= TNumberRestrictions #>
|
||||
{
|
||||
return <#= TLane #>.Sqrt(Dot(vector, vector));
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static <#= TLane #> LengthSquared<<#= GenericParameters #>>(in <#= vectorType #> vector)
|
||||
<#= TLaneRestrictions #>
|
||||
<#= TNumberRestrictions #>
|
||||
{
|
||||
return Dot(vector, vector);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static <#= TLane #> Distance<<#= GenericParameters #>>(in <#= vectorType #> a, in <#= vectorType #> b)
|
||||
<#= TLaneRestrictions #>
|
||||
<#= TNumberRestrictions #>
|
||||
{
|
||||
var diff = b - a;
|
||||
return <#= TLane #>.Sqrt(Dot(diff, diff));
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static <#= TLane #> DistanceSquared<<#= GenericParameters #>>(in <#= vectorType #> a, in <#= vectorType #> b)
|
||||
<#= TLaneRestrictions #>
|
||||
<#= TNumberRestrictions #>
|
||||
{
|
||||
var diff = b - a;
|
||||
return Dot(diff, diff);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static <#= vectorType #> Step<<#= GenericParameters #>>(in <#= vectorType #> edge, in <#= vectorType #> value)
|
||||
<#= TLaneRestrictions #>
|
||||
<#= TNumberRestrictions #>
|
||||
{
|
||||
return Select(value >= edge, <#= vectorType #>.One, <#= vectorType #>.Zero);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static <#= vectorType #> Smoothstep<<#= GenericParameters #>>(<#= vectorType #> xMin, <#= vectorType #> xMax, <#= vectorType #> x)
|
||||
<#= TLaneRestrictions #>
|
||||
<#= TNumberRestrictions #>
|
||||
{
|
||||
var t = Saturate((x - xMin) / (xMax - xMin));
|
||||
var two = <#= TLane #>.Create(<#= TNumber #>.CreateTruncating(2));
|
||||
var three = <#= TLane #>.Create(<#= TNumber #>.CreateTruncating(3));
|
||||
|
||||
return t * t * (CreateVector<#= dimension #><<#= GenericParameters #>>(three) - (CreateVector<#= dimension #><<#= GenericParameters #>>(two) * t));
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static <#= vectorType #> Select<<#= GenericParameters #>>(<#= TLane #> condition, in <#= vectorType #> a, in <#= vectorType #> b)
|
||||
<#= TLaneRestrictions #>
|
||||
<#= TNumberRestrictions #>
|
||||
{
|
||||
return new <#= vectorType #>
|
||||
{
|
||||
x = <#= TLane #>.Select(condition, b.x, a.x),
|
||||
y = <#= TLane #>.Select(condition, b.y, a.y),
|
||||
};
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static <#= vectorType #> Select<<#= GenericParameters #>>(<#= vectorType #> condition, in <#= vectorType #> a, in <#= vectorType #> b)
|
||||
<#= TLaneRestrictions #>
|
||||
<#= TNumberRestrictions #>
|
||||
{
|
||||
return new <#= vectorType #>
|
||||
{
|
||||
x = <#= TLane #>.Select(condition.x, b.x, a.x),
|
||||
y = <#= TLane #>.Select(condition.y, b.y, a.y),
|
||||
};
|
||||
}
|
||||
|
||||
# endregion
|
||||
|
||||
<# } #>
|
||||
}
|
||||
|
||||
<#+
|
||||
public string ForEachDimension(int dimension, Func<int, string> action, string spliter = ", ")
|
||||
{
|
||||
return string.Join(spliter, Enumerable.Range(0, dimension).Select(i => action(i)));
|
||||
}
|
||||
#>
|
||||
417
Misaki.HighPerformance.Mathematics.SPMD/Templates/Vector2.gen.cs
Normal file
417
Misaki.HighPerformance.Mathematics.SPMD/Templates/Vector2.gen.cs
Normal file
@@ -0,0 +1,417 @@
|
||||
|
||||
using System.Diagnostics;
|
||||
using System.Numerics;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
namespace Misaki.HighPerformance.Mathematics.SPMD;
|
||||
|
||||
public unsafe struct Vector2<TLane, TNumber> : IEquatable<Vector2<TLane, TNumber>>
|
||||
where TLane : ISPMD<TLane, TNumber>
|
||||
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
|
||||
{
|
||||
public TLane x;
|
||||
public TLane y;
|
||||
|
||||
public static Vector2<TLane, TNumber> Zero
|
||||
{
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
get
|
||||
{
|
||||
return new Vector2<TLane, TNumber>
|
||||
{
|
||||
x = TLane.Zero,
|
||||
y = TLane.Zero,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public static Vector2<TLane, TNumber> One
|
||||
{
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
get
|
||||
{
|
||||
return new Vector2<TLane, TNumber>
|
||||
{
|
||||
x = TLane.One,
|
||||
y = TLane.One,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public TLane this[int index]
|
||||
{
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
get
|
||||
{
|
||||
RangeCheck(index);
|
||||
return Unsafe.Add(ref x, index);
|
||||
}
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
[Conditional("ENABLE_COLLECTION_CHECKS")]
|
||||
private static void RangeCheck(int index)
|
||||
{
|
||||
if (index < 0 || index >= 2)
|
||||
{
|
||||
throw new IndexOutOfRangeException($"Index {index} is out of range for Vector2.");
|
||||
}
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public void Store(TNumber* pDst)
|
||||
{
|
||||
var width = TLane.LaneWidth;
|
||||
|
||||
var x = stackalloc TNumber[width];
|
||||
var y = stackalloc TNumber[width];
|
||||
|
||||
this.x.Store(x);
|
||||
this.y.Store(y);
|
||||
|
||||
for (var i = 0; i < width; i++)
|
||||
{
|
||||
pDst[i * 2 + 0] = x[i];
|
||||
pDst[i * 2 + 1] = y[i];
|
||||
}
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public void Store(ref TNumber dst)
|
||||
{
|
||||
Store((TNumber*)Unsafe.AsPointer(ref dst));
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public void Store(TNumber* px, TNumber* py)
|
||||
{
|
||||
x.Store(px);
|
||||
y.Store(py);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public void Store(ref TNumber x, ref TNumber y)
|
||||
{
|
||||
this.x.Store(ref x);
|
||||
this.y.Store(ref y);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector2<TLane, TNumber> operator +(in Vector2<TLane, TNumber> left, in Vector2<TLane, TNumber> right)
|
||||
{
|
||||
return new Vector2<TLane, TNumber>
|
||||
{
|
||||
x = left.x + right.x,
|
||||
y = left.y + right.y,
|
||||
};
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector2<TLane, TNumber> operator +(in Vector2<TLane, TNumber> vector, TLane lane)
|
||||
{
|
||||
return new Vector2<TLane, TNumber>
|
||||
{
|
||||
x = vector.x + lane,
|
||||
y = vector.y + lane,
|
||||
};
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector2<TLane, TNumber> operator +(TLane lane, in Vector2<TLane, TNumber> vector)
|
||||
{
|
||||
return new Vector2<TLane, TNumber>
|
||||
{
|
||||
x = lane + vector.x,
|
||||
y = lane + vector.y,
|
||||
};
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector2<TLane, TNumber> operator -(in Vector2<TLane, TNumber> left, in Vector2<TLane, TNumber> right)
|
||||
{
|
||||
return new Vector2<TLane, TNumber>
|
||||
{
|
||||
x = left.x - right.x,
|
||||
y = left.y - right.y,
|
||||
};
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector2<TLane, TNumber> operator -(in Vector2<TLane, TNumber> vector, TLane lane)
|
||||
{
|
||||
return new Vector2<TLane, TNumber>
|
||||
{
|
||||
x = vector.x - lane,
|
||||
y = vector.y - lane,
|
||||
};
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector2<TLane, TNumber> operator -(TLane lane, in Vector2<TLane, TNumber> vector)
|
||||
{
|
||||
return new Vector2<TLane, TNumber>
|
||||
{
|
||||
x = lane - vector.x,
|
||||
y = lane - vector.y,
|
||||
};
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector2<TLane, TNumber> operator *(in Vector2<TLane, TNumber> left, in Vector2<TLane, TNumber> right)
|
||||
{
|
||||
return new Vector2<TLane, TNumber>
|
||||
{
|
||||
x = left.x * right.x,
|
||||
y = left.y * right.y,
|
||||
};
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector2<TLane, TNumber> operator *(in Vector2<TLane, TNumber> vector, TLane lane)
|
||||
{
|
||||
return new Vector2<TLane, TNumber>
|
||||
{
|
||||
x = vector.x * lane,
|
||||
y = vector.y * lane,
|
||||
};
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector2<TLane, TNumber> operator *(TLane lane, in Vector2<TLane, TNumber> vector)
|
||||
{
|
||||
return new Vector2<TLane, TNumber>
|
||||
{
|
||||
x = lane * vector.x,
|
||||
y = lane * vector.y,
|
||||
};
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector2<TLane, TNumber> operator /(in Vector2<TLane, TNumber> left, in Vector2<TLane, TNumber> right)
|
||||
{
|
||||
return new Vector2<TLane, TNumber>
|
||||
{
|
||||
x = left.x / right.x,
|
||||
y = left.y / right.y,
|
||||
};
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector2<TLane, TNumber> operator /(in Vector2<TLane, TNumber> vector, TLane lane)
|
||||
{
|
||||
return new Vector2<TLane, TNumber>
|
||||
{
|
||||
x = vector.x / lane,
|
||||
y = vector.y / lane,
|
||||
};
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector2<TLane, TNumber> operator /(TLane lane, in Vector2<TLane, TNumber> vector)
|
||||
{
|
||||
return new Vector2<TLane, TNumber>
|
||||
{
|
||||
x = lane / vector.x,
|
||||
y = lane / vector.y,
|
||||
};
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector2<TLane, TNumber> operator ==(in Vector2<TLane, TNumber> left, in Vector2<TLane, TNumber> right)
|
||||
{
|
||||
return new Vector2<TLane, TNumber>
|
||||
{
|
||||
x = left.x == right.x,
|
||||
y = left.y == right.y,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector2<TLane, TNumber> operator ==(in Vector2<TLane, TNumber> vector, TLane lane)
|
||||
{
|
||||
return new Vector2<TLane, TNumber>
|
||||
{
|
||||
x = vector.x == lane,
|
||||
y = vector.y == lane,
|
||||
};
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector2<TLane, TNumber> operator ==(TLane lane, in Vector2<TLane, TNumber> vector)
|
||||
{
|
||||
return new Vector2<TLane, TNumber>
|
||||
{
|
||||
x = lane == vector.x,
|
||||
y = lane == vector.y,
|
||||
};
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector2<TLane, TNumber> operator !=(in Vector2<TLane, TNumber> left, in Vector2<TLane, TNumber> right)
|
||||
{
|
||||
return new Vector2<TLane, TNumber>
|
||||
{
|
||||
x = left.x != right.x,
|
||||
y = left.y != right.y,
|
||||
};
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector2<TLane, TNumber> operator !=(in Vector2<TLane, TNumber> vector, TLane lane)
|
||||
{
|
||||
return new Vector2<TLane, TNumber>
|
||||
{
|
||||
x = vector.x != lane,
|
||||
y = vector.y != lane,
|
||||
};
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector2<TLane, TNumber> operator !=(TLane lane, in Vector2<TLane, TNumber> vector)
|
||||
{
|
||||
return new Vector2<TLane, TNumber>
|
||||
{
|
||||
x = lane != vector.x,
|
||||
y = lane != vector.y,
|
||||
};
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector2<TLane, TNumber> operator >(in Vector2<TLane, TNumber> left, in Vector2<TLane, TNumber> right)
|
||||
{
|
||||
return new Vector2<TLane, TNumber>
|
||||
{
|
||||
x = left.x > right.x,
|
||||
y = left.y > right.y,
|
||||
};
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector2<TLane, TNumber> operator >(in Vector2<TLane, TNumber> vector, TLane lane)
|
||||
{
|
||||
return new Vector2<TLane, TNumber>
|
||||
{
|
||||
x = vector.x > lane,
|
||||
y = vector.y > lane,
|
||||
};
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector2<TLane, TNumber> operator >(TLane lane, in Vector2<TLane, TNumber> vector)
|
||||
{
|
||||
return new Vector2<TLane, TNumber>
|
||||
{
|
||||
x = lane > vector.x,
|
||||
y = lane > vector.y,
|
||||
};
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector2<TLane, TNumber> operator >=(in Vector2<TLane, TNumber> left, in Vector2<TLane, TNumber> right)
|
||||
{
|
||||
return new Vector2<TLane, TNumber>
|
||||
{
|
||||
x = left.x >= right.x,
|
||||
y = left.y >= right.y,
|
||||
};
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector2<TLane, TNumber> operator >=(in Vector2<TLane, TNumber> vector, TLane lane)
|
||||
{
|
||||
return new Vector2<TLane, TNumber>
|
||||
{
|
||||
x = vector.x >= lane,
|
||||
y = vector.y >= lane,
|
||||
};
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector2<TLane, TNumber> operator >=(TLane lane, in Vector2<TLane, TNumber> vector)
|
||||
{
|
||||
return new Vector2<TLane, TNumber>
|
||||
{
|
||||
x = lane >= vector.x,
|
||||
y = lane >= vector.y,
|
||||
};
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector2<TLane, TNumber> operator <(in Vector2<TLane, TNumber> left, in Vector2<TLane, TNumber> right)
|
||||
{
|
||||
return new Vector2<TLane, TNumber>
|
||||
{
|
||||
x = left.x < right.x,
|
||||
y = left.y < right.y,
|
||||
};
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector2<TLane, TNumber> operator <(in Vector2<TLane, TNumber> vector, TLane lane)
|
||||
{
|
||||
return new Vector2<TLane, TNumber>
|
||||
{
|
||||
x = vector.x < lane,
|
||||
y = vector.y < lane,
|
||||
};
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector2<TLane, TNumber> operator <(TLane lane, in Vector2<TLane, TNumber> vector)
|
||||
{
|
||||
return new Vector2<TLane, TNumber>
|
||||
{
|
||||
x = lane < vector.x,
|
||||
y = lane < vector.y,
|
||||
};
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector2<TLane, TNumber> operator <=(in Vector2<TLane, TNumber> left, in Vector2<TLane, TNumber> right)
|
||||
{
|
||||
return new Vector2<TLane, TNumber>
|
||||
{
|
||||
x = left.x <= right.x,
|
||||
y = left.y <= right.y,
|
||||
};
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector2<TLane, TNumber> operator <=(in Vector2<TLane, TNumber> vector, TLane lane)
|
||||
{
|
||||
return new Vector2<TLane, TNumber>
|
||||
{
|
||||
x = vector.x <= lane,
|
||||
y = vector.y <= lane,
|
||||
};
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector2<TLane, TNumber> operator <=(TLane lane, in Vector2<TLane, TNumber> vector)
|
||||
{
|
||||
return new Vector2<TLane, TNumber>
|
||||
{
|
||||
x = lane <= vector.x,
|
||||
y = lane <= vector.y,
|
||||
};
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public readonly bool Equals(Vector2<TLane, TNumber> other)
|
||||
{
|
||||
return this.x.Equals(other.x) && this.y.Equals(other.y);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public override readonly bool Equals(object? obj)
|
||||
{
|
||||
return obj is Vector2<TLane, TNumber> other && Equals(other);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public override int GetHashCode()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
13
Misaki.HighPerformance.Mathematics.SPMD/Templates/Vector2.tt
Normal file
13
Misaki.HighPerformance.Mathematics.SPMD/Templates/Vector2.tt
Normal file
@@ -0,0 +1,13 @@
|
||||
<#@ template debug="false" hostspecific="false" language="C#" #>
|
||||
<#@ assembly name="System.Core" #>
|
||||
<#@ include file="Vector{T}Helper.ttinclude" #>
|
||||
<#@ output extension=".gen.cs" #>
|
||||
<#
|
||||
var code = GenerateVectorType(2);
|
||||
#>
|
||||
using System.Diagnostics;
|
||||
using System.Numerics;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
namespace Misaki.HighPerformance.Mathematics.SPMD;
|
||||
<#= code #>
|
||||
455
Misaki.HighPerformance.Mathematics.SPMD/Templates/Vector3.gen.cs
Normal file
455
Misaki.HighPerformance.Mathematics.SPMD/Templates/Vector3.gen.cs
Normal file
@@ -0,0 +1,455 @@
|
||||
|
||||
using System.Diagnostics;
|
||||
using System.Numerics;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
namespace Misaki.HighPerformance.Mathematics.SPMD;
|
||||
|
||||
public unsafe struct Vector3<TLane, TNumber> : IEquatable<Vector3<TLane, TNumber>>
|
||||
where TLane : ISPMD<TLane, TNumber>
|
||||
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
|
||||
{
|
||||
public TLane x;
|
||||
public TLane y;
|
||||
public TLane z;
|
||||
|
||||
public static Vector3<TLane, TNumber> Zero
|
||||
{
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
get
|
||||
{
|
||||
return new Vector3<TLane, TNumber>
|
||||
{
|
||||
x = TLane.Zero,
|
||||
y = TLane.Zero,
|
||||
z = TLane.Zero,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public static Vector3<TLane, TNumber> One
|
||||
{
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
get
|
||||
{
|
||||
return new Vector3<TLane, TNumber>
|
||||
{
|
||||
x = TLane.One,
|
||||
y = TLane.One,
|
||||
z = TLane.One,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public TLane this[int index]
|
||||
{
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
get
|
||||
{
|
||||
RangeCheck(index);
|
||||
return Unsafe.Add(ref x, index);
|
||||
}
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
[Conditional("ENABLE_COLLECTION_CHECKS")]
|
||||
private static void RangeCheck(int index)
|
||||
{
|
||||
if (index < 0 || index >= 3)
|
||||
{
|
||||
throw new IndexOutOfRangeException($"Index {index} is out of range for Vector2.");
|
||||
}
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public void Store(TNumber* pDst)
|
||||
{
|
||||
var width = TLane.LaneWidth;
|
||||
|
||||
var x = stackalloc TNumber[width];
|
||||
var y = stackalloc TNumber[width];
|
||||
var z = stackalloc TNumber[width];
|
||||
|
||||
this.x.Store(x);
|
||||
this.y.Store(y);
|
||||
this.z.Store(z);
|
||||
|
||||
for (var i = 0; i < width; i++)
|
||||
{
|
||||
pDst[i * 2 + 0] = x[i];
|
||||
pDst[i * 2 + 1] = y[i];
|
||||
pDst[i * 2 + 2] = z[i];
|
||||
}
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public void Store(ref TNumber dst)
|
||||
{
|
||||
Store((TNumber*)Unsafe.AsPointer(ref dst));
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public void Store(TNumber* px, TNumber* py, TNumber* pz)
|
||||
{
|
||||
x.Store(px);
|
||||
y.Store(py);
|
||||
z.Store(pz);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public void Store(ref TNumber x, ref TNumber y, ref TNumber z)
|
||||
{
|
||||
this.x.Store(ref x);
|
||||
this.y.Store(ref y);
|
||||
this.z.Store(ref z);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector3<TLane, TNumber> operator +(in Vector3<TLane, TNumber> left, in Vector3<TLane, TNumber> right)
|
||||
{
|
||||
return new Vector3<TLane, TNumber>
|
||||
{
|
||||
x = left.x + right.x,
|
||||
y = left.y + right.y,
|
||||
z = left.z + right.z,
|
||||
};
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector3<TLane, TNumber> operator +(in Vector3<TLane, TNumber> vector, TLane lane)
|
||||
{
|
||||
return new Vector3<TLane, TNumber>
|
||||
{
|
||||
x = vector.x + lane,
|
||||
y = vector.y + lane,
|
||||
z = vector.z + lane,
|
||||
};
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector3<TLane, TNumber> operator +(TLane lane, in Vector3<TLane, TNumber> vector)
|
||||
{
|
||||
return new Vector3<TLane, TNumber>
|
||||
{
|
||||
x = lane + vector.x,
|
||||
y = lane + vector.y,
|
||||
z = lane + vector.z,
|
||||
};
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector3<TLane, TNumber> operator -(in Vector3<TLane, TNumber> left, in Vector3<TLane, TNumber> right)
|
||||
{
|
||||
return new Vector3<TLane, TNumber>
|
||||
{
|
||||
x = left.x - right.x,
|
||||
y = left.y - right.y,
|
||||
z = left.z - right.z,
|
||||
};
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector3<TLane, TNumber> operator -(in Vector3<TLane, TNumber> vector, TLane lane)
|
||||
{
|
||||
return new Vector3<TLane, TNumber>
|
||||
{
|
||||
x = vector.x - lane,
|
||||
y = vector.y - lane,
|
||||
z = vector.z - lane,
|
||||
};
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector3<TLane, TNumber> operator -(TLane lane, in Vector3<TLane, TNumber> vector)
|
||||
{
|
||||
return new Vector3<TLane, TNumber>
|
||||
{
|
||||
x = lane - vector.x,
|
||||
y = lane - vector.y,
|
||||
z = lane - vector.z,
|
||||
};
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector3<TLane, TNumber> operator *(in Vector3<TLane, TNumber> left, in Vector3<TLane, TNumber> right)
|
||||
{
|
||||
return new Vector3<TLane, TNumber>
|
||||
{
|
||||
x = left.x * right.x,
|
||||
y = left.y * right.y,
|
||||
z = left.z * right.z,
|
||||
};
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector3<TLane, TNumber> operator *(in Vector3<TLane, TNumber> vector, TLane lane)
|
||||
{
|
||||
return new Vector3<TLane, TNumber>
|
||||
{
|
||||
x = vector.x * lane,
|
||||
y = vector.y * lane,
|
||||
z = vector.z * lane,
|
||||
};
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector3<TLane, TNumber> operator *(TLane lane, in Vector3<TLane, TNumber> vector)
|
||||
{
|
||||
return new Vector3<TLane, TNumber>
|
||||
{
|
||||
x = lane * vector.x,
|
||||
y = lane * vector.y,
|
||||
z = lane * vector.z,
|
||||
};
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector3<TLane, TNumber> operator /(in Vector3<TLane, TNumber> left, in Vector3<TLane, TNumber> right)
|
||||
{
|
||||
return new Vector3<TLane, TNumber>
|
||||
{
|
||||
x = left.x / right.x,
|
||||
y = left.y / right.y,
|
||||
z = left.z / right.z,
|
||||
};
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector3<TLane, TNumber> operator /(in Vector3<TLane, TNumber> vector, TLane lane)
|
||||
{
|
||||
return new Vector3<TLane, TNumber>
|
||||
{
|
||||
x = vector.x / lane,
|
||||
y = vector.y / lane,
|
||||
z = vector.z / lane,
|
||||
};
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector3<TLane, TNumber> operator /(TLane lane, in Vector3<TLane, TNumber> vector)
|
||||
{
|
||||
return new Vector3<TLane, TNumber>
|
||||
{
|
||||
x = lane / vector.x,
|
||||
y = lane / vector.y,
|
||||
z = lane / vector.z,
|
||||
};
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector3<TLane, TNumber> operator ==(in Vector3<TLane, TNumber> left, in Vector3<TLane, TNumber> right)
|
||||
{
|
||||
return new Vector3<TLane, TNumber>
|
||||
{
|
||||
x = left.x == right.x,
|
||||
y = left.y == right.y,
|
||||
z = left.z == right.z,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector3<TLane, TNumber> operator ==(in Vector3<TLane, TNumber> vector, TLane lane)
|
||||
{
|
||||
return new Vector3<TLane, TNumber>
|
||||
{
|
||||
x = vector.x == lane,
|
||||
y = vector.y == lane,
|
||||
z = vector.z == lane,
|
||||
};
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector3<TLane, TNumber> operator ==(TLane lane, in Vector3<TLane, TNumber> vector)
|
||||
{
|
||||
return new Vector3<TLane, TNumber>
|
||||
{
|
||||
x = lane == vector.x,
|
||||
y = lane == vector.y,
|
||||
z = lane == vector.z,
|
||||
};
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector3<TLane, TNumber> operator !=(in Vector3<TLane, TNumber> left, in Vector3<TLane, TNumber> right)
|
||||
{
|
||||
return new Vector3<TLane, TNumber>
|
||||
{
|
||||
x = left.x != right.x,
|
||||
y = left.y != right.y,
|
||||
z = left.z != right.z,
|
||||
};
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector3<TLane, TNumber> operator !=(in Vector3<TLane, TNumber> vector, TLane lane)
|
||||
{
|
||||
return new Vector3<TLane, TNumber>
|
||||
{
|
||||
x = vector.x != lane,
|
||||
y = vector.y != lane,
|
||||
z = vector.z != lane,
|
||||
};
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector3<TLane, TNumber> operator !=(TLane lane, in Vector3<TLane, TNumber> vector)
|
||||
{
|
||||
return new Vector3<TLane, TNumber>
|
||||
{
|
||||
x = lane != vector.x,
|
||||
y = lane != vector.y,
|
||||
z = lane != vector.z,
|
||||
};
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector3<TLane, TNumber> operator >(in Vector3<TLane, TNumber> left, in Vector3<TLane, TNumber> right)
|
||||
{
|
||||
return new Vector3<TLane, TNumber>
|
||||
{
|
||||
x = left.x > right.x,
|
||||
y = left.y > right.y,
|
||||
z = left.z > right.z,
|
||||
};
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector3<TLane, TNumber> operator >(in Vector3<TLane, TNumber> vector, TLane lane)
|
||||
{
|
||||
return new Vector3<TLane, TNumber>
|
||||
{
|
||||
x = vector.x > lane,
|
||||
y = vector.y > lane,
|
||||
z = vector.z > lane,
|
||||
};
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector3<TLane, TNumber> operator >(TLane lane, in Vector3<TLane, TNumber> vector)
|
||||
{
|
||||
return new Vector3<TLane, TNumber>
|
||||
{
|
||||
x = lane > vector.x,
|
||||
y = lane > vector.y,
|
||||
z = lane > vector.z,
|
||||
};
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector3<TLane, TNumber> operator >=(in Vector3<TLane, TNumber> left, in Vector3<TLane, TNumber> right)
|
||||
{
|
||||
return new Vector3<TLane, TNumber>
|
||||
{
|
||||
x = left.x >= right.x,
|
||||
y = left.y >= right.y,
|
||||
z = left.z >= right.z,
|
||||
};
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector3<TLane, TNumber> operator >=(in Vector3<TLane, TNumber> vector, TLane lane)
|
||||
{
|
||||
return new Vector3<TLane, TNumber>
|
||||
{
|
||||
x = vector.x >= lane,
|
||||
y = vector.y >= lane,
|
||||
z = vector.z >= lane,
|
||||
};
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector3<TLane, TNumber> operator >=(TLane lane, in Vector3<TLane, TNumber> vector)
|
||||
{
|
||||
return new Vector3<TLane, TNumber>
|
||||
{
|
||||
x = lane >= vector.x,
|
||||
y = lane >= vector.y,
|
||||
z = lane >= vector.z,
|
||||
};
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector3<TLane, TNumber> operator <(in Vector3<TLane, TNumber> left, in Vector3<TLane, TNumber> right)
|
||||
{
|
||||
return new Vector3<TLane, TNumber>
|
||||
{
|
||||
x = left.x < right.x,
|
||||
y = left.y < right.y,
|
||||
z = left.z < right.z,
|
||||
};
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector3<TLane, TNumber> operator <(in Vector3<TLane, TNumber> vector, TLane lane)
|
||||
{
|
||||
return new Vector3<TLane, TNumber>
|
||||
{
|
||||
x = vector.x < lane,
|
||||
y = vector.y < lane,
|
||||
z = vector.z < lane,
|
||||
};
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector3<TLane, TNumber> operator <(TLane lane, in Vector3<TLane, TNumber> vector)
|
||||
{
|
||||
return new Vector3<TLane, TNumber>
|
||||
{
|
||||
x = lane < vector.x,
|
||||
y = lane < vector.y,
|
||||
z = lane < vector.z,
|
||||
};
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector3<TLane, TNumber> operator <=(in Vector3<TLane, TNumber> left, in Vector3<TLane, TNumber> right)
|
||||
{
|
||||
return new Vector3<TLane, TNumber>
|
||||
{
|
||||
x = left.x <= right.x,
|
||||
y = left.y <= right.y,
|
||||
z = left.z <= right.z,
|
||||
};
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector3<TLane, TNumber> operator <=(in Vector3<TLane, TNumber> vector, TLane lane)
|
||||
{
|
||||
return new Vector3<TLane, TNumber>
|
||||
{
|
||||
x = vector.x <= lane,
|
||||
y = vector.y <= lane,
|
||||
z = vector.z <= lane,
|
||||
};
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector3<TLane, TNumber> operator <=(TLane lane, in Vector3<TLane, TNumber> vector)
|
||||
{
|
||||
return new Vector3<TLane, TNumber>
|
||||
{
|
||||
x = lane <= vector.x,
|
||||
y = lane <= vector.y,
|
||||
z = lane <= vector.z,
|
||||
};
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public readonly bool Equals(Vector3<TLane, TNumber> other)
|
||||
{
|
||||
return this.x.Equals(other.x) && this.y.Equals(other.y) && this.z.Equals(other.z);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public override readonly bool Equals(object? obj)
|
||||
{
|
||||
return obj is Vector3<TLane, TNumber> other && Equals(other);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public override int GetHashCode()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
13
Misaki.HighPerformance.Mathematics.SPMD/Templates/Vector3.tt
Normal file
13
Misaki.HighPerformance.Mathematics.SPMD/Templates/Vector3.tt
Normal file
@@ -0,0 +1,13 @@
|
||||
<#@ template debug="false" hostspecific="false" language="C#" #>
|
||||
<#@ assembly name="System.Core" #>
|
||||
<#@ include file="Vector{T}Helper.ttinclude" #>
|
||||
<#@ output extension=".gen.cs" #>
|
||||
<#
|
||||
var code = GenerateVectorType(3);
|
||||
#>
|
||||
using System.Diagnostics;
|
||||
using System.Numerics;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
namespace Misaki.HighPerformance.Mathematics.SPMD;
|
||||
<#= code #>
|
||||
493
Misaki.HighPerformance.Mathematics.SPMD/Templates/Vector4.gen.cs
Normal file
493
Misaki.HighPerformance.Mathematics.SPMD/Templates/Vector4.gen.cs
Normal file
@@ -0,0 +1,493 @@
|
||||
|
||||
using System.Diagnostics;
|
||||
using System.Numerics;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
namespace Misaki.HighPerformance.Mathematics.SPMD;
|
||||
|
||||
public unsafe struct Vector4<TLane, TNumber> : IEquatable<Vector4<TLane, TNumber>>
|
||||
where TLane : ISPMD<TLane, TNumber>
|
||||
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
|
||||
{
|
||||
public TLane x;
|
||||
public TLane y;
|
||||
public TLane z;
|
||||
public TLane w;
|
||||
|
||||
public static Vector4<TLane, TNumber> Zero
|
||||
{
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
get
|
||||
{
|
||||
return new Vector4<TLane, TNumber>
|
||||
{
|
||||
x = TLane.Zero,
|
||||
y = TLane.Zero,
|
||||
z = TLane.Zero,
|
||||
w = TLane.Zero,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public static Vector4<TLane, TNumber> One
|
||||
{
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
get
|
||||
{
|
||||
return new Vector4<TLane, TNumber>
|
||||
{
|
||||
x = TLane.One,
|
||||
y = TLane.One,
|
||||
z = TLane.One,
|
||||
w = TLane.One,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public TLane this[int index]
|
||||
{
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
get
|
||||
{
|
||||
RangeCheck(index);
|
||||
return Unsafe.Add(ref x, index);
|
||||
}
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
[Conditional("ENABLE_COLLECTION_CHECKS")]
|
||||
private static void RangeCheck(int index)
|
||||
{
|
||||
if (index < 0 || index >= 4)
|
||||
{
|
||||
throw new IndexOutOfRangeException($"Index {index} is out of range for Vector2.");
|
||||
}
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public void Store(TNumber* pDst)
|
||||
{
|
||||
var width = TLane.LaneWidth;
|
||||
|
||||
var x = stackalloc TNumber[width];
|
||||
var y = stackalloc TNumber[width];
|
||||
var z = stackalloc TNumber[width];
|
||||
var w = stackalloc TNumber[width];
|
||||
|
||||
this.x.Store(x);
|
||||
this.y.Store(y);
|
||||
this.z.Store(z);
|
||||
this.w.Store(w);
|
||||
|
||||
for (var i = 0; i < width; i++)
|
||||
{
|
||||
pDst[i * 2 + 0] = x[i];
|
||||
pDst[i * 2 + 1] = y[i];
|
||||
pDst[i * 2 + 2] = z[i];
|
||||
pDst[i * 2 + 3] = w[i];
|
||||
}
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public void Store(ref TNumber dst)
|
||||
{
|
||||
Store((TNumber*)Unsafe.AsPointer(ref dst));
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public void Store(TNumber* px, TNumber* py, TNumber* pz, TNumber* pw)
|
||||
{
|
||||
x.Store(px);
|
||||
y.Store(py);
|
||||
z.Store(pz);
|
||||
w.Store(pw);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public void Store(ref TNumber x, ref TNumber y, ref TNumber z, ref TNumber w)
|
||||
{
|
||||
this.x.Store(ref x);
|
||||
this.y.Store(ref y);
|
||||
this.z.Store(ref z);
|
||||
this.w.Store(ref w);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector4<TLane, TNumber> operator +(in Vector4<TLane, TNumber> left, in Vector4<TLane, TNumber> right)
|
||||
{
|
||||
return new Vector4<TLane, TNumber>
|
||||
{
|
||||
x = left.x + right.x,
|
||||
y = left.y + right.y,
|
||||
z = left.z + right.z,
|
||||
w = left.w + right.w,
|
||||
};
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector4<TLane, TNumber> operator +(in Vector4<TLane, TNumber> vector, TLane lane)
|
||||
{
|
||||
return new Vector4<TLane, TNumber>
|
||||
{
|
||||
x = vector.x + lane,
|
||||
y = vector.y + lane,
|
||||
z = vector.z + lane,
|
||||
w = vector.w + lane,
|
||||
};
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector4<TLane, TNumber> operator +(TLane lane, in Vector4<TLane, TNumber> vector)
|
||||
{
|
||||
return new Vector4<TLane, TNumber>
|
||||
{
|
||||
x = lane + vector.x,
|
||||
y = lane + vector.y,
|
||||
z = lane + vector.z,
|
||||
w = lane + vector.w,
|
||||
};
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector4<TLane, TNumber> operator -(in Vector4<TLane, TNumber> left, in Vector4<TLane, TNumber> right)
|
||||
{
|
||||
return new Vector4<TLane, TNumber>
|
||||
{
|
||||
x = left.x - right.x,
|
||||
y = left.y - right.y,
|
||||
z = left.z - right.z,
|
||||
w = left.w - right.w,
|
||||
};
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector4<TLane, TNumber> operator -(in Vector4<TLane, TNumber> vector, TLane lane)
|
||||
{
|
||||
return new Vector4<TLane, TNumber>
|
||||
{
|
||||
x = vector.x - lane,
|
||||
y = vector.y - lane,
|
||||
z = vector.z - lane,
|
||||
w = vector.w - lane,
|
||||
};
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector4<TLane, TNumber> operator -(TLane lane, in Vector4<TLane, TNumber> vector)
|
||||
{
|
||||
return new Vector4<TLane, TNumber>
|
||||
{
|
||||
x = lane - vector.x,
|
||||
y = lane - vector.y,
|
||||
z = lane - vector.z,
|
||||
w = lane - vector.w,
|
||||
};
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector4<TLane, TNumber> operator *(in Vector4<TLane, TNumber> left, in Vector4<TLane, TNumber> right)
|
||||
{
|
||||
return new Vector4<TLane, TNumber>
|
||||
{
|
||||
x = left.x * right.x,
|
||||
y = left.y * right.y,
|
||||
z = left.z * right.z,
|
||||
w = left.w * right.w,
|
||||
};
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector4<TLane, TNumber> operator *(in Vector4<TLane, TNumber> vector, TLane lane)
|
||||
{
|
||||
return new Vector4<TLane, TNumber>
|
||||
{
|
||||
x = vector.x * lane,
|
||||
y = vector.y * lane,
|
||||
z = vector.z * lane,
|
||||
w = vector.w * lane,
|
||||
};
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector4<TLane, TNumber> operator *(TLane lane, in Vector4<TLane, TNumber> vector)
|
||||
{
|
||||
return new Vector4<TLane, TNumber>
|
||||
{
|
||||
x = lane * vector.x,
|
||||
y = lane * vector.y,
|
||||
z = lane * vector.z,
|
||||
w = lane * vector.w,
|
||||
};
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector4<TLane, TNumber> operator /(in Vector4<TLane, TNumber> left, in Vector4<TLane, TNumber> right)
|
||||
{
|
||||
return new Vector4<TLane, TNumber>
|
||||
{
|
||||
x = left.x / right.x,
|
||||
y = left.y / right.y,
|
||||
z = left.z / right.z,
|
||||
w = left.w / right.w,
|
||||
};
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector4<TLane, TNumber> operator /(in Vector4<TLane, TNumber> vector, TLane lane)
|
||||
{
|
||||
return new Vector4<TLane, TNumber>
|
||||
{
|
||||
x = vector.x / lane,
|
||||
y = vector.y / lane,
|
||||
z = vector.z / lane,
|
||||
w = vector.w / lane,
|
||||
};
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector4<TLane, TNumber> operator /(TLane lane, in Vector4<TLane, TNumber> vector)
|
||||
{
|
||||
return new Vector4<TLane, TNumber>
|
||||
{
|
||||
x = lane / vector.x,
|
||||
y = lane / vector.y,
|
||||
z = lane / vector.z,
|
||||
w = lane / vector.w,
|
||||
};
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector4<TLane, TNumber> operator ==(in Vector4<TLane, TNumber> left, in Vector4<TLane, TNumber> right)
|
||||
{
|
||||
return new Vector4<TLane, TNumber>
|
||||
{
|
||||
x = left.x == right.x,
|
||||
y = left.y == right.y,
|
||||
z = left.z == right.z,
|
||||
w = left.w == right.w,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector4<TLane, TNumber> operator ==(in Vector4<TLane, TNumber> vector, TLane lane)
|
||||
{
|
||||
return new Vector4<TLane, TNumber>
|
||||
{
|
||||
x = vector.x == lane,
|
||||
y = vector.y == lane,
|
||||
z = vector.z == lane,
|
||||
w = vector.w == lane,
|
||||
};
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector4<TLane, TNumber> operator ==(TLane lane, in Vector4<TLane, TNumber> vector)
|
||||
{
|
||||
return new Vector4<TLane, TNumber>
|
||||
{
|
||||
x = lane == vector.x,
|
||||
y = lane == vector.y,
|
||||
z = lane == vector.z,
|
||||
w = lane == vector.w,
|
||||
};
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector4<TLane, TNumber> operator !=(in Vector4<TLane, TNumber> left, in Vector4<TLane, TNumber> right)
|
||||
{
|
||||
return new Vector4<TLane, TNumber>
|
||||
{
|
||||
x = left.x != right.x,
|
||||
y = left.y != right.y,
|
||||
z = left.z != right.z,
|
||||
w = left.w != right.w,
|
||||
};
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector4<TLane, TNumber> operator !=(in Vector4<TLane, TNumber> vector, TLane lane)
|
||||
{
|
||||
return new Vector4<TLane, TNumber>
|
||||
{
|
||||
x = vector.x != lane,
|
||||
y = vector.y != lane,
|
||||
z = vector.z != lane,
|
||||
w = vector.w != lane,
|
||||
};
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector4<TLane, TNumber> operator !=(TLane lane, in Vector4<TLane, TNumber> vector)
|
||||
{
|
||||
return new Vector4<TLane, TNumber>
|
||||
{
|
||||
x = lane != vector.x,
|
||||
y = lane != vector.y,
|
||||
z = lane != vector.z,
|
||||
w = lane != vector.w,
|
||||
};
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector4<TLane, TNumber> operator >(in Vector4<TLane, TNumber> left, in Vector4<TLane, TNumber> right)
|
||||
{
|
||||
return new Vector4<TLane, TNumber>
|
||||
{
|
||||
x = left.x > right.x,
|
||||
y = left.y > right.y,
|
||||
z = left.z > right.z,
|
||||
w = left.w > right.w,
|
||||
};
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector4<TLane, TNumber> operator >(in Vector4<TLane, TNumber> vector, TLane lane)
|
||||
{
|
||||
return new Vector4<TLane, TNumber>
|
||||
{
|
||||
x = vector.x > lane,
|
||||
y = vector.y > lane,
|
||||
z = vector.z > lane,
|
||||
w = vector.w > lane,
|
||||
};
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector4<TLane, TNumber> operator >(TLane lane, in Vector4<TLane, TNumber> vector)
|
||||
{
|
||||
return new Vector4<TLane, TNumber>
|
||||
{
|
||||
x = lane > vector.x,
|
||||
y = lane > vector.y,
|
||||
z = lane > vector.z,
|
||||
w = lane > vector.w,
|
||||
};
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector4<TLane, TNumber> operator >=(in Vector4<TLane, TNumber> left, in Vector4<TLane, TNumber> right)
|
||||
{
|
||||
return new Vector4<TLane, TNumber>
|
||||
{
|
||||
x = left.x >= right.x,
|
||||
y = left.y >= right.y,
|
||||
z = left.z >= right.z,
|
||||
w = left.w >= right.w,
|
||||
};
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector4<TLane, TNumber> operator >=(in Vector4<TLane, TNumber> vector, TLane lane)
|
||||
{
|
||||
return new Vector4<TLane, TNumber>
|
||||
{
|
||||
x = vector.x >= lane,
|
||||
y = vector.y >= lane,
|
||||
z = vector.z >= lane,
|
||||
w = vector.w >= lane,
|
||||
};
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector4<TLane, TNumber> operator >=(TLane lane, in Vector4<TLane, TNumber> vector)
|
||||
{
|
||||
return new Vector4<TLane, TNumber>
|
||||
{
|
||||
x = lane >= vector.x,
|
||||
y = lane >= vector.y,
|
||||
z = lane >= vector.z,
|
||||
w = lane >= vector.w,
|
||||
};
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector4<TLane, TNumber> operator <(in Vector4<TLane, TNumber> left, in Vector4<TLane, TNumber> right)
|
||||
{
|
||||
return new Vector4<TLane, TNumber>
|
||||
{
|
||||
x = left.x < right.x,
|
||||
y = left.y < right.y,
|
||||
z = left.z < right.z,
|
||||
w = left.w < right.w,
|
||||
};
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector4<TLane, TNumber> operator <(in Vector4<TLane, TNumber> vector, TLane lane)
|
||||
{
|
||||
return new Vector4<TLane, TNumber>
|
||||
{
|
||||
x = vector.x < lane,
|
||||
y = vector.y < lane,
|
||||
z = vector.z < lane,
|
||||
w = vector.w < lane,
|
||||
};
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector4<TLane, TNumber> operator <(TLane lane, in Vector4<TLane, TNumber> vector)
|
||||
{
|
||||
return new Vector4<TLane, TNumber>
|
||||
{
|
||||
x = lane < vector.x,
|
||||
y = lane < vector.y,
|
||||
z = lane < vector.z,
|
||||
w = lane < vector.w,
|
||||
};
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector4<TLane, TNumber> operator <=(in Vector4<TLane, TNumber> left, in Vector4<TLane, TNumber> right)
|
||||
{
|
||||
return new Vector4<TLane, TNumber>
|
||||
{
|
||||
x = left.x <= right.x,
|
||||
y = left.y <= right.y,
|
||||
z = left.z <= right.z,
|
||||
w = left.w <= right.w,
|
||||
};
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector4<TLane, TNumber> operator <=(in Vector4<TLane, TNumber> vector, TLane lane)
|
||||
{
|
||||
return new Vector4<TLane, TNumber>
|
||||
{
|
||||
x = vector.x <= lane,
|
||||
y = vector.y <= lane,
|
||||
z = vector.z <= lane,
|
||||
w = vector.w <= lane,
|
||||
};
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector4<TLane, TNumber> operator <=(TLane lane, in Vector4<TLane, TNumber> vector)
|
||||
{
|
||||
return new Vector4<TLane, TNumber>
|
||||
{
|
||||
x = lane <= vector.x,
|
||||
y = lane <= vector.y,
|
||||
z = lane <= vector.z,
|
||||
w = lane <= vector.w,
|
||||
};
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public readonly bool Equals(Vector4<TLane, TNumber> other)
|
||||
{
|
||||
return this.x.Equals(other.x) && this.y.Equals(other.y) && this.z.Equals(other.z) && this.w.Equals(other.w);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public override readonly bool Equals(object? obj)
|
||||
{
|
||||
return obj is Vector4<TLane, TNumber> other && Equals(other);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public override int GetHashCode()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
13
Misaki.HighPerformance.Mathematics.SPMD/Templates/Vector4.tt
Normal file
13
Misaki.HighPerformance.Mathematics.SPMD/Templates/Vector4.tt
Normal file
@@ -0,0 +1,13 @@
|
||||
<#@ template debug="false" hostspecific="false" language="C#" #>
|
||||
<#@ assembly name="System.Core" #>
|
||||
<#@ include file="Vector{T}Helper.ttinclude" #>
|
||||
<#@ output extension=".gen.cs" #>
|
||||
<#
|
||||
var code = GenerateVectorType(4);
|
||||
#>
|
||||
using System.Diagnostics;
|
||||
using System.Numerics;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
namespace Misaki.HighPerformance.Mathematics.SPMD;
|
||||
<#= code #>
|
||||
@@ -0,0 +1 @@
|
||||
|
||||
@@ -0,0 +1,420 @@
|
||||
<#@ import namespace="System.Text" #>
|
||||
<#+
|
||||
private const string TLane = "TLane";
|
||||
private const string TNumber = "TNumber";
|
||||
|
||||
private string TLaneRestrictions = $@"where {TLane} : ISPMD<{TLane}, {TNumber}>";
|
||||
private string TNumberRestrictions = $@"where {TNumber} : unmanaged, INumber<{TNumber}>, IBinaryNumber<{TNumber}>, IMinMaxValue<{TNumber}>, IBitwiseOperators<{TNumber}, {TNumber}, {TNumber}>";
|
||||
|
||||
private int[] dimensions = new int[] { 2, 3, 4 };
|
||||
private char[] components = new char[] { 'x', 'y', 'z', 'w' };
|
||||
|
||||
public string Indent(string str, int spaces)
|
||||
{
|
||||
var indent = new string(' ', spaces);
|
||||
return indent + str;
|
||||
}
|
||||
|
||||
private string ForEachDimension(int maxDimension, int indentation, string spliter, Action<int, StringBuilder> action, bool spliterOnFirst = true)
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
for (var dimension = 0; dimension < maxDimension; dimension++)
|
||||
{
|
||||
if ((dimension > 0 || spliterOnFirst) && indentation > 0)
|
||||
{
|
||||
sb.Append(new string(' ', indentation));
|
||||
}
|
||||
|
||||
action(dimension, sb);
|
||||
if (dimension < maxDimension - 1)
|
||||
{
|
||||
sb.Append(spliter);
|
||||
}
|
||||
}
|
||||
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
public StringBuilder GenerateVectorType(int dimension)
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
|
||||
var typeName = $"Vector{dimension}<{TLane}, {TNumber}>";
|
||||
|
||||
sb.AppendLine(@$"
|
||||
public unsafe struct {typeName} : IEquatable<{typeName}>
|
||||
{TLaneRestrictions}
|
||||
{TNumberRestrictions}
|
||||
{{
|
||||
{ForEachDimension(dimension, 4, Environment.NewLine, (dim, sb) => sb.Append($"public {TLane} {components[dim]};"))}
|
||||
|
||||
public static {typeName} Zero
|
||||
{{
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
get
|
||||
{{
|
||||
return new {typeName}
|
||||
{{
|
||||
{ForEachDimension(dimension, 16, Environment.NewLine, (dim, sb) => sb.Append($"{components[dim]} = {TLane}.Zero,"))}
|
||||
}};
|
||||
}}
|
||||
}}
|
||||
|
||||
public static {typeName} One
|
||||
{{
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
get
|
||||
{{
|
||||
return new {typeName}
|
||||
{{
|
||||
{ForEachDimension(dimension, 16, Environment.NewLine, (dim, sb) => sb.Append($"{components[dim]} = {TLane}.One,"))}
|
||||
}};
|
||||
}}
|
||||
}}
|
||||
|
||||
public {TLane} this[int index]
|
||||
{{
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
get
|
||||
{{
|
||||
RangeCheck(index);
|
||||
return Unsafe.Add(ref x, index);
|
||||
}}
|
||||
}}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
[Conditional(""ENABLE_COLLECTION_CHECKS"")]
|
||||
private static void RangeCheck(int index)
|
||||
{{
|
||||
if (index < 0 || index >= {dimension})
|
||||
{{
|
||||
throw new IndexOutOfRangeException($""Index {{index}} is out of range for Vector2."");
|
||||
}}
|
||||
}}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public void Store({TNumber}* pDst)
|
||||
{{
|
||||
var width = {TLane}.LaneWidth;
|
||||
|
||||
{ForEachDimension(dimension, 8, Environment.NewLine, (dim, sb) => sb.Append($"var {components[dim]} = stackalloc {TNumber}[width];"))}
|
||||
|
||||
{ForEachDimension(dimension, 8, Environment.NewLine, (dim, sb) => sb.Append($"this.{components[dim]}.Store({components[dim]});"))}
|
||||
|
||||
for (var i = 0; i < width; i++)
|
||||
{{
|
||||
{ForEachDimension(dimension, 12, Environment.NewLine, (dim, sb) => sb.Append($"pDst[i * 2 + {dim}] = {components[dim]}[i];"))}
|
||||
}}
|
||||
}}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public void Store(ref {TNumber} dst)
|
||||
{{
|
||||
Store(({TNumber}*)Unsafe.AsPointer(ref dst));
|
||||
}}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public void Store({ForEachDimension(dimension, 1, ", ", (dim, sb) => sb.Append($"{TNumber}* p{components[dim]}"), false)})
|
||||
{{
|
||||
{ForEachDimension(dimension, 8, Environment.NewLine, (dim, sb) => sb.Append($"{components[dim]}.Store(p{components[dim]});"))}
|
||||
}}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public void Store({ForEachDimension(dimension, 1, ", ", (dim, sb) => sb.Append($"ref {TNumber} {components[dim]}"), false)})
|
||||
{{
|
||||
{ForEachDimension(dimension, 8, Environment.NewLine, (dim, sb) => sb.Append($"this.{components[dim]}.Store(ref {components[dim]});"))}
|
||||
}}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static {typeName} operator +(in {typeName} left, in {typeName} right)
|
||||
{{
|
||||
return new {typeName}
|
||||
{{
|
||||
{ForEachDimension(dimension, 12, Environment.NewLine, (dim, sb) => sb.Append($"{components[dim]} = left.{components[dim]} + right.{components[dim]},"))}
|
||||
}};
|
||||
}}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static {typeName} operator +(in {typeName} vector, {TLane} lane)
|
||||
{{
|
||||
return new {typeName}
|
||||
{{
|
||||
{ForEachDimension(dimension, 12, Environment.NewLine, (dim, sb) => sb.Append($"{components[dim]} = vector.{components[dim]} + lane,"))}
|
||||
}};
|
||||
}}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static {typeName} operator +({TLane} lane, in {typeName} vector)
|
||||
{{
|
||||
return new {typeName}
|
||||
{{
|
||||
{ForEachDimension(dimension, 12, Environment.NewLine, (dim, sb) => sb.Append($"{components[dim]} = lane + vector.{components[dim]},"))}
|
||||
}};
|
||||
}}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static {typeName} operator -(in {typeName} left, in {typeName} right)
|
||||
{{
|
||||
return new {typeName}
|
||||
{{
|
||||
{ForEachDimension(dimension, 12, Environment.NewLine, (dim, sb) => sb.Append($"{components[dim]} = left.{components[dim]} - right.{components[dim]},"))}
|
||||
}};
|
||||
}}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static {typeName} operator -(in {typeName} vector, {TLane} lane)
|
||||
{{
|
||||
return new {typeName}
|
||||
{{
|
||||
{ForEachDimension(dimension, 12, Environment.NewLine, (dim, sb) => sb.Append($"{components[dim]} = vector.{components[dim]} - lane,"))}
|
||||
}};
|
||||
}}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static {typeName} operator -({TLane} lane, in {typeName} vector)
|
||||
{{
|
||||
return new {typeName}
|
||||
{{
|
||||
{ForEachDimension(dimension, 12, Environment.NewLine, (dim, sb) => sb.Append($"{components[dim]} = lane - vector.{components[dim]},"))}
|
||||
}};
|
||||
}}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static {typeName} operator *(in {typeName} left, in {typeName} right)
|
||||
{{
|
||||
return new {typeName}
|
||||
{{
|
||||
{ForEachDimension(dimension, 12, Environment.NewLine, (dim, sb) => sb.Append($"{components[dim]} = left.{components[dim]} * right.{components[dim]},"))}
|
||||
}};
|
||||
}}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static {typeName} operator *(in {typeName} vector, {TLane} lane)
|
||||
{{
|
||||
return new {typeName}
|
||||
{{
|
||||
{ForEachDimension(dimension, 12, Environment.NewLine, (dim, sb) => sb.Append($"{components[dim]} = vector.{components[dim]} * lane,"))}
|
||||
}};
|
||||
}}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static {typeName} operator *({TLane} lane, in {typeName} vector)
|
||||
{{
|
||||
return new {typeName}
|
||||
{{
|
||||
{ForEachDimension(dimension, 12, Environment.NewLine, (dim, sb) => sb.Append($"{components[dim]} = lane * vector.{components[dim]},"))}
|
||||
}};
|
||||
}}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static {typeName} operator /(in {typeName} left, in {typeName} right)
|
||||
{{
|
||||
return new {typeName}
|
||||
{{
|
||||
{ForEachDimension(dimension, 12, Environment.NewLine, (dim, sb) => sb.Append($"{components[dim]} = left.{components[dim]} / right.{components[dim]},"))}
|
||||
}};
|
||||
}}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static {typeName} operator /(in {typeName} vector, {TLane} lane)
|
||||
{{
|
||||
return new {typeName}
|
||||
{{
|
||||
{ForEachDimension(dimension, 12, Environment.NewLine, (dim, sb) => sb.Append($"{components[dim]} = vector.{components[dim]} / lane,"))}
|
||||
}};
|
||||
}}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static {typeName} operator /({TLane} lane, in {typeName} vector)
|
||||
{{
|
||||
return new {typeName}
|
||||
{{
|
||||
{ForEachDimension(dimension, 12, Environment.NewLine, (dim, sb) => sb.Append($"{components[dim]} = lane / vector.{components[dim]},"))}
|
||||
}};
|
||||
}}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static {typeName} operator ==(in {typeName} left, in {typeName} right)
|
||||
{{
|
||||
return new {typeName}
|
||||
{{
|
||||
{ForEachDimension(dimension, 12, Environment.NewLine, (dim, sb) => sb.Append($"{components[dim]} = left.{components[dim]} == right.{components[dim]},"))}
|
||||
}};
|
||||
}}
|
||||
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static {typeName} operator ==(in {typeName} vector, {TLane} lane)
|
||||
{{
|
||||
return new {typeName}
|
||||
{{
|
||||
{ForEachDimension(dimension, 12, Environment.NewLine, (dim, sb) => sb.Append($"{components[dim]} = vector.{components[dim]} == lane,"))}
|
||||
}};
|
||||
}}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static {typeName} operator ==({TLane} lane, in {typeName} vector)
|
||||
{{
|
||||
return new {typeName}
|
||||
{{
|
||||
{ForEachDimension(dimension, 12, Environment.NewLine, (dim, sb) => sb.Append($"{components[dim]} = lane == vector.{components[dim]},"))}
|
||||
}};
|
||||
}}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static {typeName} operator !=(in {typeName} left, in {typeName} right)
|
||||
{{
|
||||
return new {typeName}
|
||||
{{
|
||||
{ForEachDimension(dimension, 12, Environment.NewLine, (dim, sb) => sb.Append($"{components[dim]} = left.{components[dim]} != right.{components[dim]},"))}
|
||||
}};
|
||||
}}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static {typeName} operator !=(in {typeName} vector, {TLane} lane)
|
||||
{{
|
||||
return new {typeName}
|
||||
{{
|
||||
{ForEachDimension(dimension, 12, Environment.NewLine, (dim, sb) => sb.Append($"{components[dim]} = vector.{components[dim]} != lane,"))}
|
||||
}};
|
||||
}}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static {typeName} operator !=({TLane} lane, in {typeName} vector)
|
||||
{{
|
||||
return new {typeName}
|
||||
{{
|
||||
{ForEachDimension(dimension, 12, Environment.NewLine, (dim, sb) => sb.Append($"{components[dim]} = lane != vector.{components[dim]},"))}
|
||||
}};
|
||||
}}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static {typeName} operator >(in {typeName} left, in {typeName} right)
|
||||
{{
|
||||
return new {typeName}
|
||||
{{
|
||||
{ForEachDimension(dimension, 12, Environment.NewLine, (dim, sb) => sb.Append($"{components[dim]} = left.{components[dim]} > right.{components[dim]},"))}
|
||||
}};
|
||||
}}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static {typeName} operator >(in {typeName} vector, {TLane} lane)
|
||||
{{
|
||||
return new {typeName}
|
||||
{{
|
||||
{ForEachDimension(dimension, 12, Environment.NewLine, (dim, sb) => sb.Append($"{components[dim]} = vector.{components[dim]} > lane,"))}
|
||||
}};
|
||||
}}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static {typeName} operator >({TLane} lane, in {typeName} vector)
|
||||
{{
|
||||
return new {typeName}
|
||||
{{
|
||||
{ForEachDimension(dimension, 12, Environment.NewLine, (dim, sb) => sb.Append($"{components[dim]} = lane > vector.{components[dim]},"))}
|
||||
}};
|
||||
}}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static {typeName} operator >=(in {typeName} left, in {typeName} right)
|
||||
{{
|
||||
return new {typeName}
|
||||
{{
|
||||
{ForEachDimension(dimension, 12, Environment.NewLine, (dim, sb) => sb.Append($"{components[dim]} = left.{components[dim]} >= right.{components[dim]},"))}
|
||||
}};
|
||||
}}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static {typeName} operator >=(in {typeName} vector, {TLane} lane)
|
||||
{{
|
||||
return new {typeName}
|
||||
{{
|
||||
{ForEachDimension(dimension, 12, Environment.NewLine, (dim, sb) => sb.Append($"{components[dim]} = vector.{components[dim]} >= lane,"))}
|
||||
}};
|
||||
}}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static {typeName} operator >=({TLane} lane, in {typeName} vector)
|
||||
{{
|
||||
return new {typeName}
|
||||
{{
|
||||
{ForEachDimension(dimension, 12, Environment.NewLine, (dim, sb) => sb.Append($"{components[dim]} = lane >= vector.{components[dim]},"))}
|
||||
}};
|
||||
}}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static {typeName} operator <(in {typeName} left, in {typeName} right)
|
||||
{{
|
||||
return new {typeName}
|
||||
{{
|
||||
{ForEachDimension(dimension, 12, Environment.NewLine, (dim, sb) => sb.Append($"{components[dim]} = left.{components[dim]} < right.{components[dim]},"))}
|
||||
}};
|
||||
}}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static {typeName} operator <(in {typeName} vector, {TLane} lane)
|
||||
{{
|
||||
return new {typeName}
|
||||
{{
|
||||
{ForEachDimension(dimension, 12, Environment.NewLine, (dim, sb) => sb.Append($"{components[dim]} = vector.{components[dim]} < lane,"))}
|
||||
}};
|
||||
}}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static {typeName} operator <({TLane} lane, in {typeName} vector)
|
||||
{{
|
||||
return new {typeName}
|
||||
{{
|
||||
{ForEachDimension(dimension, 12, Environment.NewLine, (dim, sb) => sb.Append($"{components[dim]} = lane < vector.{components[dim]},"))}
|
||||
}};
|
||||
}}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static {typeName} operator <=(in {typeName} left, in {typeName} right)
|
||||
{{
|
||||
return new {typeName}
|
||||
{{
|
||||
{ForEachDimension(dimension, 12, Environment.NewLine, (dim, sb) => sb.Append($"{components[dim]} = left.{components[dim]} <= right.{components[dim]},"))}
|
||||
}};
|
||||
}}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static {typeName} operator <=(in {typeName} vector, {TLane} lane)
|
||||
{{
|
||||
return new {typeName}
|
||||
{{
|
||||
{ForEachDimension(dimension, 12, Environment.NewLine, (dim, sb) => sb.Append($"{components[dim]} = vector.{components[dim]} <= lane,"))}
|
||||
}};
|
||||
}}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static {typeName} operator <=({TLane} lane, in {typeName} vector)
|
||||
{{
|
||||
return new {typeName}
|
||||
{{
|
||||
{ForEachDimension(dimension, 12, Environment.NewLine, (dim, sb) => sb.Append($"{components[dim]} = lane <= vector.{components[dim]},"))}
|
||||
}};
|
||||
}}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public readonly bool Equals({typeName} other)
|
||||
{{
|
||||
return {ForEachDimension(dimension, 0, " && ", (dim, sb) => sb.Append($"this.{components[dim]}.Equals(other.{components[dim]})"), false)};
|
||||
}}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public override readonly bool Equals(object? obj)
|
||||
{{
|
||||
return obj is {typeName} other && Equals(other);
|
||||
}}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public override int GetHashCode()
|
||||
{{
|
||||
throw new NotImplementedException();
|
||||
}}
|
||||
}}");
|
||||
|
||||
return sb;
|
||||
}
|
||||
#>
|
||||
Reference in New Issue
Block a user