/// /// 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. /// using System.Diagnostics.CodeAnalysis; using System.Numerics; using System.Runtime.CompilerServices; using System.Runtime.Intrinsics; using System.Runtime.Intrinsics.Arm; using System.Runtime.Intrinsics.X86; namespace Misaki.HighPerformance.Mathematics.SPMD; public static unsafe partial class MathV { # region Vector2 // Creation Functions [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector2 Create(in TLane x, in TLane y) where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return new Vector2 { x = x, y = y, }; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector2 CreateVector2(in TLane value) where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return new Vector2 { x = value, y = value, }; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector2 LoadVector2(TNumber* pSrc) where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return new Vector2 { x = TLane.Load(pSrc + 0), y = TLane.Load(pSrc + 1), }; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector2 LoadVector2(ref TNumber src) where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return LoadVector2((TNumber*)Unsafe.AsPointer(ref src)); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector2 MaskLoadVector2(TNumber* pSrc, TLane mask) where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return new Vector2 { x = TLane.MaskLoad(pSrc + 0, mask), y = TLane.MaskLoad(pSrc + 1, mask), }; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector2 MaskLoadVector2(ref TNumber src, TLane mask) where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return MaskLoadVector2((TNumber*)Unsafe.AsPointer(ref src), mask); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector2 Load(TNumber* px, TNumber* py) where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return new Vector2 { x = TLane.Load(px), y = TLane.Load(py), }; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector2 Load(ref TNumber x, ref TNumber y) where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return new Vector2 { x = TLane.Load(ref x), y = TLane.Load(ref y), }; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector2 GatherVector2(TNumber* pData, TLane indices, [ConstantExpected(Min = (byte)(1), Max = (byte)(8))] byte scale) where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return new Vector2 { x = TLane.Gather(pData + 0, indices, scale), y = TLane.Gather(pData + 1, indices, scale), }; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector2 GatherVector2(TNumber* pData, int* pIndices, [ConstantExpected(Min = (byte)(1), Max = (byte)(8))] byte scale) where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return new Vector2 { x = TLane.Gather(pData + 0, pIndices, scale), y = TLane.Gather(pData + 1, pIndices, scale), }; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector2 GatherVector2(ref TNumber baseAddress, TLane indices, [ConstantExpected(Min = (byte)(1), Max = (byte)(8))] byte scale) where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return GatherVector2((TNumber*)Unsafe.AsPointer(ref baseAddress), indices, scale); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector2 GatherVector2(ref TNumber baseAddress, ref int baseIndex, [ConstantExpected(Min = (byte)(1), Max = (byte)(8))] byte scale) where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return GatherVector2((TNumber*)Unsafe.AsPointer(ref baseAddress), (int*)Unsafe.AsPointer(ref baseIndex), scale); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector2 MaskGatherVector2(TNumber* pData, TLane indices, TLane mask, [ConstantExpected(Min = (byte)(1), Max = (byte)(8))] byte scale) where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return new Vector2 { x = TLane.MaskGather(pData + 0, indices, mask, scale), y = TLane.MaskGather(pData + 1, indices, mask, scale), }; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector2 MaskGatherVector2(TNumber* pData, int* pIndices, TLane mask, [ConstantExpected(Min = (byte)(1), Max = (byte)(8))] byte scale) where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return new Vector2 { x = TLane.MaskGather(pData + 0, pIndices, mask, scale), y = TLane.MaskGather(pData + 1, pIndices, mask, scale), }; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector2 MaskGatherVector2(ref TNumber baseAddress, TLane indices, TLane mask, [ConstantExpected(Min = (byte)(1), Max = (byte)(8))] byte scale) where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return MaskGatherVector2((TNumber*)Unsafe.AsPointer(ref baseAddress), indices, mask, scale); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector2 MaskGatherVector2(ref TNumber baseAddress, ref int baseIndex, TLane mask, [ConstantExpected(Min = (byte)(1), Max = (byte)(8))] byte scale) where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return MaskGatherVector2((TNumber*)Unsafe.AsPointer(ref baseAddress), (int*)Unsafe.AsPointer(ref baseIndex), mask, scale); } // Math Functions [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector2 Abs(in Vector2 vector) where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return new Vector2 { x = TLane.Abs(vector.x), y = TLane.Abs(vector.y), }; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static TLane Dot(in Vector2 a, in Vector2 b) where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return a.x * b.x + a.y * b.y; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector2 Sin(in Vector2 vector) where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return new Vector2 { x = TLane.Sin(vector.x), y = TLane.Sin(vector.y), }; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector2 Cos(in Vector2 vector) where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return new Vector2 { x = TLane.Cos(vector.x), y = TLane.Cos(vector.y), }; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void SinCos(in Vector2 vector, out Vector2 sin, out Vector2 cos) where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { TLane.SinCos(vector.x, out sin.x, out cos.x); TLane.SinCos(vector.y, out sin.y, out cos.y); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector2 Sqrt(in Vector2 vector) where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return new Vector2 { x = TLane.Sqrt(vector.x), y = TLane.Sqrt(vector.y), }; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector2 Tan(in Vector2 vector) where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return new Vector2 { x = TLane.Tan(vector.x), y = TLane.Tan(vector.y), }; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector2 Asin(in Vector2 vector) where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return new Vector2 { x = TLane.Asin(vector.x), y = TLane.Asin(vector.y), }; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector2 Acos(in Vector2 vector) where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return new Vector2 { x = TLane.Acos(vector.x), y = TLane.Acos(vector.y), }; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector2 Atan(in Vector2 vector) where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return new Vector2 { x = TLane.Atan(vector.x), y = TLane.Atan(vector.y), }; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector2 Atan2(in Vector2 x, in Vector2 y) where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return new Vector2 { x = TLane.Atan2(x.x, y.x), y = TLane.Atan2(x.y, y.y), }; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector2 Rsqrt(in Vector2 vector) where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return new Vector2 { x = TLane.Rsqrt(vector.x), y = TLane.Rsqrt(vector.y), }; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector2 Normalize(in Vector2 vector) where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return vector * TLane.Rsqrt(Dot(vector, vector)); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector2 Reflect(in Vector2 incident, in Vector2 normal) where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { var dot = Dot(incident, normal); return incident - normal * (dot + dot); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector2 Min(in Vector2 a, in Vector2 b) where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return new Vector2 { x = TLane.Min(a.x, b.x), y = TLane.Min(a.y, b.y), }; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector2 Max(in Vector2 a, in Vector2 b) where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return new Vector2 { x = TLane.Max(a.x, b.x), y = TLane.Max(a.y, b.y), }; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector2 Clamp(in Vector2 value, in Vector2 min, in Vector2 max) where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return Min(Max(value, min), max); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector2 Saturate(in Vector2 value) where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return Clamp(value, CreateVector2(TLane.Zero), CreateVector2(TLane.One)); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector2 Lerp(in Vector2 a, in Vector2 b, TLane t) where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return a + (b - a) * t; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static TLane Length(in Vector2 vector) where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return TLane.Sqrt(Dot(vector, vector)); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static TLane LengthSquared(in Vector2 vector) where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return Dot(vector, vector); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static TLane Distance(in Vector2 a, in Vector2 b) where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { var diff = b - a; return TLane.Sqrt(Dot(diff, diff)); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static TLane DistanceSquared(in Vector2 a, in Vector2 b) where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { var diff = b - a; return Dot(diff, diff); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector2 Step(in Vector2 edge, in Vector2 value) where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return Select(value >= edge, Vector2.One, Vector2.Zero); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector2 Smoothstep(Vector2 xMin, Vector2 xMax, Vector2 x) where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { 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(three) - (CreateVector2(two) * t)); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector2 Select(TLane condition, in Vector2 isTrue, in Vector2 isFalse) where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return new Vector2 { x = TLane.Select(condition, isTrue.x, isFalse.x), y = TLane.Select(condition, isTrue.y, isFalse.y), }; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector2 Select(Vector2 condition, in Vector2 isTrue, in Vector2 isFalse) where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return new Vector2 { x = TLane.Select(condition.x, isTrue.x, isFalse.x), y = TLane.Select(condition.y, isTrue.y, isFalse.y), }; } # endregion # region Vector3 // Creation Functions [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector3 Create(in TLane x, in TLane y, in TLane z) where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return new Vector3 { x = x, y = y, z = z, }; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector3 CreateVector3(in TLane value) where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return new Vector3 { x = value, y = value, z = value, }; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector3 LoadVector3(TNumber* pSrc) where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return new Vector3 { x = TLane.Load(pSrc + 0), y = TLane.Load(pSrc + 1), z = TLane.Load(pSrc + 2), }; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector3 LoadVector3(ref TNumber src) where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return LoadVector3((TNumber*)Unsafe.AsPointer(ref src)); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector3 MaskLoadVector3(TNumber* pSrc, TLane mask) where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return new Vector3 { x = TLane.MaskLoad(pSrc + 0, mask), y = TLane.MaskLoad(pSrc + 1, mask), z = TLane.MaskLoad(pSrc + 2, mask), }; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector3 MaskLoadVector3(ref TNumber src, TLane mask) where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return MaskLoadVector3((TNumber*)Unsafe.AsPointer(ref src), mask); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector3 Load(TNumber* px, TNumber* py, TNumber* pz) where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return new Vector3 { x = TLane.Load(px), y = TLane.Load(py), z = TLane.Load(pz), }; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector3 Load(ref TNumber x, ref TNumber y, ref TNumber z) where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return new Vector3 { x = TLane.Load(ref x), y = TLane.Load(ref y), z = TLane.Load(ref z), }; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector3 GatherVector3(TNumber* pData, TLane indices, [ConstantExpected(Min = (byte)(1), Max = (byte)(8))] byte scale) where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return new Vector3 { x = TLane.Gather(pData + 0, indices, scale), y = TLane.Gather(pData + 1, indices, scale), z = TLane.Gather(pData + 2, indices, scale), }; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector3 GatherVector3(TNumber* pData, int* pIndices, [ConstantExpected(Min = (byte)(1), Max = (byte)(8))] byte scale) where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return new Vector3 { x = TLane.Gather(pData + 0, pIndices, scale), y = TLane.Gather(pData + 1, pIndices, scale), z = TLane.Gather(pData + 2, pIndices, scale), }; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector3 GatherVector3(ref TNumber baseAddress, TLane indices, [ConstantExpected(Min = (byte)(1), Max = (byte)(8))] byte scale) where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return GatherVector3((TNumber*)Unsafe.AsPointer(ref baseAddress), indices, scale); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector3 GatherVector3(ref TNumber baseAddress, ref int baseIndex, [ConstantExpected(Min = (byte)(1), Max = (byte)(8))] byte scale) where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return GatherVector3((TNumber*)Unsafe.AsPointer(ref baseAddress), (int*)Unsafe.AsPointer(ref baseIndex), scale); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector3 MaskGatherVector3(TNumber* pData, TLane indices, TLane mask, [ConstantExpected(Min = (byte)(1), Max = (byte)(8))] byte scale) where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return new Vector3 { x = TLane.MaskGather(pData + 0, indices, mask, scale), y = TLane.MaskGather(pData + 1, indices, mask, scale), z = TLane.MaskGather(pData + 2, indices, mask, scale), }; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector3 MaskGatherVector3(TNumber* pData, int* pIndices, TLane mask, [ConstantExpected(Min = (byte)(1), Max = (byte)(8))] byte scale) where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return new Vector3 { x = TLane.MaskGather(pData + 0, pIndices, mask, scale), y = TLane.MaskGather(pData + 1, pIndices, mask, scale), z = TLane.MaskGather(pData + 2, pIndices, mask, scale), }; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector3 MaskGatherVector3(ref TNumber baseAddress, TLane indices, TLane mask, [ConstantExpected(Min = (byte)(1), Max = (byte)(8))] byte scale) where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return MaskGatherVector3((TNumber*)Unsafe.AsPointer(ref baseAddress), indices, mask, scale); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector3 MaskGatherVector3(ref TNumber baseAddress, ref int baseIndex, TLane mask, [ConstantExpected(Min = (byte)(1), Max = (byte)(8))] byte scale) where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return MaskGatherVector3((TNumber*)Unsafe.AsPointer(ref baseAddress), (int*)Unsafe.AsPointer(ref baseIndex), mask, scale); } // Math Functions [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector3 Abs(in Vector3 vector) where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return new Vector3 { x = TLane.Abs(vector.x), y = TLane.Abs(vector.y), z = TLane.Abs(vector.z), }; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static TLane Dot(in Vector3 a, in Vector3 b) where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return a.x * b.x + a.y * b.y + a.z * b.z; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector3 Sin(in Vector3 vector) where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return new Vector3 { x = TLane.Sin(vector.x), y = TLane.Sin(vector.y), z = TLane.Sin(vector.z), }; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector3 Cos(in Vector3 vector) where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return new Vector3 { x = TLane.Cos(vector.x), y = TLane.Cos(vector.y), z = TLane.Cos(vector.z), }; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void SinCos(in Vector3 vector, out Vector3 sin, out Vector3 cos) where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { TLane.SinCos(vector.x, out sin.x, out cos.x); TLane.SinCos(vector.y, out sin.y, out cos.y); TLane.SinCos(vector.z, out sin.z, out cos.z); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector3 Sqrt(in Vector3 vector) where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return new Vector3 { x = TLane.Sqrt(vector.x), y = TLane.Sqrt(vector.y), z = TLane.Sqrt(vector.z), }; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector3 Tan(in Vector3 vector) where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return new Vector3 { x = TLane.Tan(vector.x), y = TLane.Tan(vector.y), z = TLane.Tan(vector.z), }; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector3 Asin(in Vector3 vector) where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return new Vector3 { x = TLane.Asin(vector.x), y = TLane.Asin(vector.y), z = TLane.Asin(vector.z), }; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector3 Acos(in Vector3 vector) where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return new Vector3 { x = TLane.Acos(vector.x), y = TLane.Acos(vector.y), z = TLane.Acos(vector.z), }; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector3 Atan(in Vector3 vector) where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return new Vector3 { x = TLane.Atan(vector.x), y = TLane.Atan(vector.y), z = TLane.Atan(vector.z), }; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector3 Atan2(in Vector3 x, in Vector3 y) where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return new Vector3 { x = TLane.Atan2(x.x, y.x), y = TLane.Atan2(x.y, y.y), z = TLane.Atan2(x.z, y.z), }; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector3 Rsqrt(in Vector3 vector) where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return new Vector3 { x = TLane.Rsqrt(vector.x), y = TLane.Rsqrt(vector.y), z = TLane.Rsqrt(vector.z), }; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector3 Normalize(in Vector3 vector) where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return vector * TLane.Rsqrt(Dot(vector, vector)); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector3 Reflect(in Vector3 incident, in Vector3 normal) where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { var dot = Dot(incident, normal); return incident - normal * (dot + dot); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector3 Min(in Vector3 a, in Vector3 b) where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return new Vector3 { 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 Max(in Vector3 a, in Vector3 b) where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return new Vector3 { 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 Clamp(in Vector3 value, in Vector3 min, in Vector3 max) where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return Min(Max(value, min), max); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector3 Saturate(in Vector3 value) where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return Clamp(value, CreateVector3(TLane.Zero), CreateVector3(TLane.One)); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector3 Lerp(in Vector3 a, in Vector3 b, TLane t) where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return a + (b - a) * t; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static TLane Length(in Vector3 vector) where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return TLane.Sqrt(Dot(vector, vector)); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static TLane LengthSquared(in Vector3 vector) where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return Dot(vector, vector); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static TLane Distance(in Vector3 a, in Vector3 b) where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { var diff = b - a; return TLane.Sqrt(Dot(diff, diff)); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static TLane DistanceSquared(in Vector3 a, in Vector3 b) where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { var diff = b - a; return Dot(diff, diff); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector3 Step(in Vector3 edge, in Vector3 value) where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return Select(value >= edge, Vector3.One, Vector3.Zero); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector3 Smoothstep(Vector3 xMin, Vector3 xMax, Vector3 x) where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { 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(three) - (CreateVector3(two) * t)); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector3 Select(TLane condition, in Vector3 isTrue, in Vector3 isFalse) where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return new Vector3 { x = TLane.Select(condition, isTrue.x, isFalse.x), y = TLane.Select(condition, isTrue.y, isFalse.y), z = TLane.Select(condition, isTrue.z, isFalse.z), }; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector3 Select(Vector3 condition, in Vector3 isTrue, in Vector3 isFalse) where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return new Vector3 { x = TLane.Select(condition.x, isTrue.x, isFalse.x), y = TLane.Select(condition.y, isTrue.y, isFalse.y), z = TLane.Select(condition.z, isTrue.z, isFalse.z), }; } # endregion # region Vector4 // Creation Functions [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 Create(in TLane x, in TLane y, in TLane z, in TLane w) where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return new Vector4 { x = x, y = y, z = z, w = w, }; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 CreateVector4(in TLane value) where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return new Vector4 { x = value, y = value, z = value, w = value, }; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 LoadVector4(TNumber* pSrc) where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return new Vector4 { x = TLane.Load(pSrc + 0), y = TLane.Load(pSrc + 1), z = TLane.Load(pSrc + 2), w = TLane.Load(pSrc + 3), }; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 LoadVector4(ref TNumber src) where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return LoadVector4((TNumber*)Unsafe.AsPointer(ref src)); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 MaskLoadVector4(TNumber* pSrc, TLane mask) where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return new Vector4 { x = TLane.MaskLoad(pSrc + 0, mask), y = TLane.MaskLoad(pSrc + 1, mask), z = TLane.MaskLoad(pSrc + 2, mask), w = TLane.MaskLoad(pSrc + 3, mask), }; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 MaskLoadVector4(ref TNumber src, TLane mask) where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return MaskLoadVector4((TNumber*)Unsafe.AsPointer(ref src), mask); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 Load(TNumber* px, TNumber* py, TNumber* pz, TNumber* pw) where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return new Vector4 { x = TLane.Load(px), y = TLane.Load(py), z = TLane.Load(pz), w = TLane.Load(pw), }; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 Load(ref TNumber x, ref TNumber y, ref TNumber z, ref TNumber w) where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return new Vector4 { x = TLane.Load(ref x), y = TLane.Load(ref y), z = TLane.Load(ref z), w = TLane.Load(ref w), }; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 GatherVector4(TNumber* pData, TLane indices, [ConstantExpected(Min = (byte)(1), Max = (byte)(8))] byte scale) where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return new Vector4 { x = TLane.Gather(pData + 0, indices, scale), y = TLane.Gather(pData + 1, indices, scale), z = TLane.Gather(pData + 2, indices, scale), w = TLane.Gather(pData + 3, indices, scale), }; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 GatherVector4(TNumber* pData, int* pIndices, [ConstantExpected(Min = (byte)(1), Max = (byte)(8))] byte scale) where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return new Vector4 { x = TLane.Gather(pData + 0, pIndices, scale), y = TLane.Gather(pData + 1, pIndices, scale), z = TLane.Gather(pData + 2, pIndices, scale), w = TLane.Gather(pData + 3, pIndices, scale), }; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 GatherVector4(ref TNumber baseAddress, TLane indices, [ConstantExpected(Min = (byte)(1), Max = (byte)(8))] byte scale) where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return GatherVector4((TNumber*)Unsafe.AsPointer(ref baseAddress), indices, scale); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 GatherVector4(ref TNumber baseAddress, ref int baseIndex, [ConstantExpected(Min = (byte)(1), Max = (byte)(8))] byte scale) where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return GatherVector4((TNumber*)Unsafe.AsPointer(ref baseAddress), (int*)Unsafe.AsPointer(ref baseIndex), scale); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 MaskGatherVector4(TNumber* pData, TLane indices, TLane mask, [ConstantExpected(Min = (byte)(1), Max = (byte)(8))] byte scale) where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return new Vector4 { x = TLane.MaskGather(pData + 0, indices, mask, scale), y = TLane.MaskGather(pData + 1, indices, mask, scale), z = TLane.MaskGather(pData + 2, indices, mask, scale), w = TLane.MaskGather(pData + 3, indices, mask, scale), }; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 MaskGatherVector4(TNumber* pData, int* pIndices, TLane mask, [ConstantExpected(Min = (byte)(1), Max = (byte)(8))] byte scale) where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return new Vector4 { x = TLane.MaskGather(pData + 0, pIndices, mask, scale), y = TLane.MaskGather(pData + 1, pIndices, mask, scale), z = TLane.MaskGather(pData + 2, pIndices, mask, scale), w = TLane.MaskGather(pData + 3, pIndices, mask, scale), }; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 MaskGatherVector4(ref TNumber baseAddress, TLane indices, TLane mask, [ConstantExpected(Min = (byte)(1), Max = (byte)(8))] byte scale) where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return MaskGatherVector4((TNumber*)Unsafe.AsPointer(ref baseAddress), indices, mask, scale); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 MaskGatherVector4(ref TNumber baseAddress, ref int baseIndex, TLane mask, [ConstantExpected(Min = (byte)(1), Max = (byte)(8))] byte scale) where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return MaskGatherVector4((TNumber*)Unsafe.AsPointer(ref baseAddress), (int*)Unsafe.AsPointer(ref baseIndex), mask, scale); } // Math Functions [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 Abs(in Vector4 vector) where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return new Vector4 { 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(in Vector4 a, in Vector4 b) where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return a.x * b.x + a.y * b.y + a.z * b.z + a.w * b.w; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 Sin(in Vector4 vector) where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return new Vector4 { x = TLane.Sin(vector.x), y = TLane.Sin(vector.y), z = TLane.Sin(vector.z), w = TLane.Sin(vector.w), }; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 Cos(in Vector4 vector) where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return new Vector4 { x = TLane.Cos(vector.x), y = TLane.Cos(vector.y), z = TLane.Cos(vector.z), w = TLane.Cos(vector.w), }; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void SinCos(in Vector4 vector, out Vector4 sin, out Vector4 cos) where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { TLane.SinCos(vector.x, out sin.x, out cos.x); TLane.SinCos(vector.y, out sin.y, out cos.y); TLane.SinCos(vector.z, out sin.z, out cos.z); TLane.SinCos(vector.w, out sin.w, out cos.w); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 Sqrt(in Vector4 vector) where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return new Vector4 { 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 Tan(in Vector4 vector) where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return new Vector4 { x = TLane.Tan(vector.x), y = TLane.Tan(vector.y), z = TLane.Tan(vector.z), w = TLane.Tan(vector.w), }; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 Asin(in Vector4 vector) where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return new Vector4 { x = TLane.Asin(vector.x), y = TLane.Asin(vector.y), z = TLane.Asin(vector.z), w = TLane.Asin(vector.w), }; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 Acos(in Vector4 vector) where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return new Vector4 { x = TLane.Acos(vector.x), y = TLane.Acos(vector.y), z = TLane.Acos(vector.z), w = TLane.Acos(vector.w), }; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 Atan(in Vector4 vector) where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return new Vector4 { x = TLane.Atan(vector.x), y = TLane.Atan(vector.y), z = TLane.Atan(vector.z), w = TLane.Atan(vector.w), }; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 Atan2(in Vector4 x, in Vector4 y) where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return new Vector4 { x = TLane.Atan2(x.x, y.x), y = TLane.Atan2(x.y, y.y), z = TLane.Atan2(x.z, y.z), w = TLane.Atan2(x.w, y.w), }; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 Rsqrt(in Vector4 vector) where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return new Vector4 { 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 Normalize(in Vector4 vector) where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return vector * TLane.Rsqrt(Dot(vector, vector)); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 Reflect(in Vector4 incident, in Vector4 normal) where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { var dot = Dot(incident, normal); return incident - normal * (dot + dot); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 Min(in Vector4 a, in Vector4 b) where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return new Vector4 { 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 Max(in Vector4 a, in Vector4 b) where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return new Vector4 { 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 Clamp(in Vector4 value, in Vector4 min, in Vector4 max) where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return Min(Max(value, min), max); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 Saturate(in Vector4 value) where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return Clamp(value, CreateVector4(TLane.Zero), CreateVector4(TLane.One)); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 Lerp(in Vector4 a, in Vector4 b, TLane t) where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return a + (b - a) * t; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static TLane Length(in Vector4 vector) where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return TLane.Sqrt(Dot(vector, vector)); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static TLane LengthSquared(in Vector4 vector) where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return Dot(vector, vector); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static TLane Distance(in Vector4 a, in Vector4 b) where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { var diff = b - a; return TLane.Sqrt(Dot(diff, diff)); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static TLane DistanceSquared(in Vector4 a, in Vector4 b) where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { var diff = b - a; return Dot(diff, diff); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 Step(in Vector4 edge, in Vector4 value) where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return Select(value >= edge, Vector4.One, Vector4.Zero); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 Smoothstep(Vector4 xMin, Vector4 xMax, Vector4 x) where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { 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(three) - (CreateVector4(two) * t)); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 Select(TLane condition, in Vector4 isTrue, in Vector4 isFalse) where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return new Vector4 { x = TLane.Select(condition, isTrue.x, isFalse.x), y = TLane.Select(condition, isTrue.y, isFalse.y), z = TLane.Select(condition, isTrue.z, isFalse.z), w = TLane.Select(condition, isTrue.w, isFalse.w), }; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector4 Select(Vector4 condition, in Vector4 isTrue, in Vector4 isFalse) where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return new Vector4 { x = TLane.Select(condition.x, isTrue.x, isFalse.x), y = TLane.Select(condition.y, isTrue.y, isFalse.y), z = TLane.Select(condition.z, isTrue.z, isFalse.z), w = TLane.Select(condition.w, isTrue.w, isFalse.w), }; } # endregion # region Vector3 Specific [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector3 Cross(in Vector3 a, in Vector3 b) where TLane : unmanaged, ISPMDLane where TNumber : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { return new Vector3 { x = a.y * b.z - a.z * b.y, y = a.z * b.x - a.x * b.z, z = a.x * b.y - a.y * b.x, }; } # endregion }