Major namespace migration from SPMD to HPC across all code, templates, and projects. Introduced Misaki.HighPerformance.HPC.Generator with Roslyn-based source generators for SIMD code (e.g., AVX2), including attribute and method generators. Renamed MultipleAdd to MultiplyAdd in all lanes and updated usages. Added AVX2 utility methods via codegen. Updated tests, benchmarks, and project references to use the new framework. Improved SIMD memory utilities and modernized project files. Removed legacy SPMD project from the solution.
1484 lines
70 KiB
C#
1484 lines
70 KiB
C#
/// <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.Diagnostics.CodeAnalysis;
|
|
using System.Numerics;
|
|
using System.Runtime.CompilerServices;
|
|
using System.Runtime.Intrinsics;
|
|
using System.Runtime.Intrinsics.X86;
|
|
|
|
namespace Misaki.HighPerformance.HPC;
|
|
|
|
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 : unmanaged, ISPMDLane<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 : unmanaged, ISPMDLane<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 : unmanaged, ISPMDLane<TLane, TNumber>
|
|
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
|
|
{
|
|
return new Vector2<TLane, TNumber>
|
|
{
|
|
x = TLane.Load(pSrc + 0),
|
|
y = TLane.Load(pSrc + 1),
|
|
};
|
|
}
|
|
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
public static Vector2<TLane, TNumber> LoadVector2<TLane, TNumber>(ref TNumber src)
|
|
where TLane : unmanaged, ISPMDLane<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> MaskLoadVector2<TLane, TNumber>(TNumber* pSrc, TLane mask)
|
|
where TLane : unmanaged, ISPMDLane<TLane, TNumber>
|
|
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
|
|
{
|
|
return new Vector2<TLane, TNumber>
|
|
{
|
|
x = TLane.MaskLoad(pSrc + 0, mask),
|
|
y = TLane.MaskLoad(pSrc + 1, mask),
|
|
};
|
|
}
|
|
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
public static Vector2<TLane, TNumber> MaskLoadVector2<TLane, TNumber>(ref TNumber src, TLane mask)
|
|
where TLane : unmanaged, ISPMDLane<TLane, TNumber>
|
|
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
|
|
{
|
|
return MaskLoadVector2<TLane, TNumber>((TNumber*)Unsafe.AsPointer(ref src), mask);
|
|
}
|
|
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
public static Vector2<TLane, TNumber> Load<TLane, TNumber>(TNumber* px, TNumber* py)
|
|
where TLane : unmanaged, ISPMDLane<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 : unmanaged, ISPMDLane<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),
|
|
};
|
|
}
|
|
|
|
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
public static Vector2<TLane, TNumber> GatherVector2<TLane, TNumber>(TNumber* pData, TLane indices, [ConstantExpected(Min = (byte)(1), Max = (byte)(8))] byte scale)
|
|
where TLane : unmanaged, ISPMDLane<TLane, TNumber>
|
|
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
|
|
{
|
|
return new Vector2<TLane, TNumber>
|
|
{
|
|
x = TLane.Gather(pData + 0, indices, scale),
|
|
y = TLane.Gather(pData + 1, indices, scale),
|
|
};
|
|
}
|
|
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
public static Vector2<TLane, TNumber> GatherVector2<TLane, TNumber>(TNumber* pData, int* pIndices, [ConstantExpected(Min = (byte)(1), Max = (byte)(8))] byte scale)
|
|
where TLane : unmanaged, ISPMDLane<TLane, TNumber>
|
|
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
|
|
{
|
|
return new Vector2<TLane, TNumber>
|
|
{
|
|
x = TLane.Gather(pData + 0, pIndices, scale),
|
|
y = TLane.Gather(pData + 1, pIndices, scale),
|
|
};
|
|
}
|
|
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
public static Vector2<TLane, TNumber> GatherVector2<TLane, TNumber>(ref TNumber baseAddress, TLane indices, [ConstantExpected(Min = (byte)(1), Max = (byte)(8))] byte scale)
|
|
where TLane : unmanaged, ISPMDLane<TLane, TNumber>
|
|
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
|
|
{
|
|
return GatherVector2<TLane, TNumber>((TNumber*)Unsafe.AsPointer(ref baseAddress), indices, scale);
|
|
}
|
|
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
public static Vector2<TLane, TNumber> GatherVector2<TLane, TNumber>(ref TNumber baseAddress, ref int baseIndex, [ConstantExpected(Min = (byte)(1), Max = (byte)(8))] byte scale)
|
|
where TLane : unmanaged, ISPMDLane<TLane, TNumber>
|
|
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
|
|
{
|
|
return GatherVector2<TLane, TNumber>((TNumber*)Unsafe.AsPointer(ref baseAddress), (int*)Unsafe.AsPointer(ref baseIndex), scale);
|
|
}
|
|
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
public static Vector2<TLane, TNumber> MaskGatherVector2<TLane, TNumber>(TNumber* pData, TLane indices, TLane mask, [ConstantExpected(Min = (byte)(1), Max = (byte)(8))] byte scale)
|
|
where TLane : unmanaged, ISPMDLane<TLane, TNumber>
|
|
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
|
|
{
|
|
return new Vector2<TLane, TNumber>
|
|
{
|
|
x = TLane.MaskGather(pData + 0, indices, mask, scale),
|
|
y = TLane.MaskGather(pData + 1, indices, mask, scale),
|
|
};
|
|
}
|
|
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
public static Vector2<TLane, TNumber> MaskGatherVector2<TLane, TNumber>(TNumber* pData, int* pIndices, TLane mask, [ConstantExpected(Min = (byte)(1), Max = (byte)(8))] byte scale)
|
|
where TLane : unmanaged, ISPMDLane<TLane, TNumber>
|
|
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
|
|
{
|
|
return new Vector2<TLane, TNumber>
|
|
{
|
|
x = TLane.MaskGather(pData + 0, pIndices, mask, scale),
|
|
y = TLane.MaskGather(pData + 1, pIndices, mask, scale),
|
|
};
|
|
}
|
|
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
public static Vector2<TLane, TNumber> MaskGatherVector2<TLane, TNumber>(ref TNumber baseAddress, TLane indices, TLane mask, [ConstantExpected(Min = (byte)(1), Max = (byte)(8))] byte scale)
|
|
where TLane : unmanaged, ISPMDLane<TLane, TNumber>
|
|
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
|
|
{
|
|
return MaskGatherVector2<TLane, TNumber>((TNumber*)Unsafe.AsPointer(ref baseAddress), indices, mask, scale);
|
|
}
|
|
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
public static Vector2<TLane, TNumber> MaskGatherVector2<TLane, TNumber>(ref TNumber baseAddress, ref int baseIndex, TLane mask, [ConstantExpected(Min = (byte)(1), Max = (byte)(8))] byte scale)
|
|
where TLane : unmanaged, ISPMDLane<TLane, TNumber>
|
|
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
|
|
{
|
|
return MaskGatherVector2<TLane, TNumber>((TNumber*)Unsafe.AsPointer(ref baseAddress), (int*)Unsafe.AsPointer(ref baseIndex), mask, scale);
|
|
}
|
|
|
|
|
|
// Math Functions
|
|
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
public static Vector2<TLane, TNumber> Abs<TLane, TNumber>(in Vector2<TLane, TNumber> vector)
|
|
where TLane : unmanaged, ISPMDLane<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 : unmanaged, ISPMDLane<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> Sin<TLane, TNumber>(in Vector2<TLane, TNumber> vector)
|
|
where TLane : unmanaged, ISPMDLane<TLane, TNumber>
|
|
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
|
|
{
|
|
return new Vector2<TLane, TNumber>
|
|
{
|
|
x = TLane.Sin(vector.x),
|
|
y = TLane.Sin(vector.y),
|
|
};
|
|
}
|
|
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
public static Vector2<TLane, TNumber> Cos<TLane, TNumber>(in Vector2<TLane, TNumber> vector)
|
|
where TLane : unmanaged, ISPMDLane<TLane, TNumber>
|
|
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
|
|
{
|
|
return new Vector2<TLane, TNumber>
|
|
{
|
|
x = TLane.Cos(vector.x),
|
|
y = TLane.Cos(vector.y),
|
|
};
|
|
}
|
|
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
public static void SinCos<TLane, TNumber>(in Vector2<TLane, TNumber> vector, out Vector2<TLane, TNumber> sin, out Vector2<TLane, TNumber> cos)
|
|
where TLane : unmanaged, ISPMDLane<TLane, TNumber>
|
|
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
|
|
{
|
|
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<TLane, TNumber> Sqrt<TLane, TNumber>(in Vector2<TLane, TNumber> vector)
|
|
where TLane : unmanaged, ISPMDLane<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> Tan<TLane, TNumber>(in Vector2<TLane, TNumber> vector)
|
|
where TLane : unmanaged, ISPMDLane<TLane, TNumber>
|
|
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
|
|
{
|
|
return new Vector2<TLane, TNumber>
|
|
{
|
|
x = TLane.Tan(vector.x),
|
|
y = TLane.Tan(vector.y),
|
|
};
|
|
}
|
|
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
public static Vector2<TLane, TNumber> Asin<TLane, TNumber>(in Vector2<TLane, TNumber> vector)
|
|
where TLane : unmanaged, ISPMDLane<TLane, TNumber>
|
|
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
|
|
{
|
|
return new Vector2<TLane, TNumber>
|
|
{
|
|
x = TLane.Asin(vector.x),
|
|
y = TLane.Asin(vector.y),
|
|
};
|
|
}
|
|
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
public static Vector2<TLane, TNumber> Acos<TLane, TNumber>(in Vector2<TLane, TNumber> vector)
|
|
where TLane : unmanaged, ISPMDLane<TLane, TNumber>
|
|
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
|
|
{
|
|
return new Vector2<TLane, TNumber>
|
|
{
|
|
x = TLane.Acos(vector.x),
|
|
y = TLane.Acos(vector.y),
|
|
};
|
|
}
|
|
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
public static Vector2<TLane, TNumber> Atan<TLane, TNumber>(in Vector2<TLane, TNumber> vector)
|
|
where TLane : unmanaged, ISPMDLane<TLane, TNumber>
|
|
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
|
|
{
|
|
return new Vector2<TLane, TNumber>
|
|
{
|
|
x = TLane.Atan(vector.x),
|
|
y = TLane.Atan(vector.y),
|
|
};
|
|
}
|
|
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
public static Vector2<TLane, TNumber> Atan2<TLane, TNumber>(in Vector2<TLane, TNumber> x, in Vector2<TLane, TNumber> y)
|
|
where TLane : unmanaged, ISPMDLane<TLane, TNumber>
|
|
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
|
|
{
|
|
return new Vector2<TLane, TNumber>
|
|
{
|
|
x = TLane.Atan2(x.x, y.x),
|
|
y = TLane.Atan2(x.y, y.y),
|
|
};
|
|
}
|
|
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
public static Vector2<TLane, TNumber> Rsqrt<TLane, TNumber>(in Vector2<TLane, TNumber> vector)
|
|
where TLane : unmanaged, ISPMDLane<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 : unmanaged, ISPMDLane<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 : unmanaged, ISPMDLane<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 : unmanaged, ISPMDLane<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 : unmanaged, ISPMDLane<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 : unmanaged, ISPMDLane<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 : unmanaged, ISPMDLane<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 : unmanaged, ISPMDLane<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 : unmanaged, ISPMDLane<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 : unmanaged, ISPMDLane<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 : unmanaged, ISPMDLane<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 : unmanaged, ISPMDLane<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 : unmanaged, ISPMDLane<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 : unmanaged, ISPMDLane<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> isTrue, in Vector2<TLane, TNumber> isFalse)
|
|
where TLane : unmanaged, ISPMDLane<TLane, TNumber>
|
|
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
|
|
{
|
|
return new Vector2<TLane, TNumber>
|
|
{
|
|
x = TLane.Select(condition, isTrue.x, isFalse.x),
|
|
y = TLane.Select(condition, isTrue.y, isFalse.y),
|
|
};
|
|
}
|
|
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
public static Vector2<TLane, TNumber> Select<TLane, TNumber>(Vector2<TLane, TNumber> condition, in Vector2<TLane, TNumber> isTrue, in Vector2<TLane, TNumber> isFalse)
|
|
where TLane : unmanaged, ISPMDLane<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, isTrue.x, isFalse.x),
|
|
y = TLane.Select(condition.y, isTrue.y, isFalse.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 : unmanaged, ISPMDLane<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 : unmanaged, ISPMDLane<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 : unmanaged, ISPMDLane<TLane, TNumber>
|
|
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
|
|
{
|
|
return new Vector3<TLane, TNumber>
|
|
{
|
|
x = TLane.Load(pSrc + 0),
|
|
y = TLane.Load(pSrc + 1),
|
|
z = TLane.Load(pSrc + 2),
|
|
};
|
|
}
|
|
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
public static Vector3<TLane, TNumber> LoadVector3<TLane, TNumber>(ref TNumber src)
|
|
where TLane : unmanaged, ISPMDLane<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> MaskLoadVector3<TLane, TNumber>(TNumber* pSrc, TLane mask)
|
|
where TLane : unmanaged, ISPMDLane<TLane, TNumber>
|
|
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
|
|
{
|
|
return new Vector3<TLane, TNumber>
|
|
{
|
|
x = TLane.MaskLoad(pSrc + 0, mask),
|
|
y = TLane.MaskLoad(pSrc + 1, mask),
|
|
z = TLane.MaskLoad(pSrc + 2, mask),
|
|
};
|
|
}
|
|
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
public static Vector3<TLane, TNumber> MaskLoadVector3<TLane, TNumber>(ref TNumber src, TLane mask)
|
|
where TLane : unmanaged, ISPMDLane<TLane, TNumber>
|
|
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
|
|
{
|
|
return MaskLoadVector3<TLane, TNumber>((TNumber*)Unsafe.AsPointer(ref src), mask);
|
|
}
|
|
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
public static Vector3<TLane, TNumber> Load<TLane, TNumber>(TNumber* px, TNumber* py, TNumber* pz)
|
|
where TLane : unmanaged, ISPMDLane<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 : unmanaged, ISPMDLane<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),
|
|
};
|
|
}
|
|
|
|
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
public static Vector3<TLane, TNumber> GatherVector3<TLane, TNumber>(TNumber* pData, TLane indices, [ConstantExpected(Min = (byte)(1), Max = (byte)(8))] byte scale)
|
|
where TLane : unmanaged, ISPMDLane<TLane, TNumber>
|
|
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
|
|
{
|
|
return new Vector3<TLane, TNumber>
|
|
{
|
|
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<TLane, TNumber> GatherVector3<TLane, TNumber>(TNumber* pData, int* pIndices, [ConstantExpected(Min = (byte)(1), Max = (byte)(8))] byte scale)
|
|
where TLane : unmanaged, ISPMDLane<TLane, TNumber>
|
|
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
|
|
{
|
|
return new Vector3<TLane, TNumber>
|
|
{
|
|
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<TLane, TNumber> GatherVector3<TLane, TNumber>(ref TNumber baseAddress, TLane indices, [ConstantExpected(Min = (byte)(1), Max = (byte)(8))] byte scale)
|
|
where TLane : unmanaged, ISPMDLane<TLane, TNumber>
|
|
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
|
|
{
|
|
return GatherVector3<TLane, TNumber>((TNumber*)Unsafe.AsPointer(ref baseAddress), indices, scale);
|
|
}
|
|
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
public static Vector3<TLane, TNumber> GatherVector3<TLane, TNumber>(ref TNumber baseAddress, ref int baseIndex, [ConstantExpected(Min = (byte)(1), Max = (byte)(8))] byte scale)
|
|
where TLane : unmanaged, ISPMDLane<TLane, TNumber>
|
|
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
|
|
{
|
|
return GatherVector3<TLane, TNumber>((TNumber*)Unsafe.AsPointer(ref baseAddress), (int*)Unsafe.AsPointer(ref baseIndex), scale);
|
|
}
|
|
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
public static Vector3<TLane, TNumber> MaskGatherVector3<TLane, TNumber>(TNumber* pData, TLane indices, TLane mask, [ConstantExpected(Min = (byte)(1), Max = (byte)(8))] byte scale)
|
|
where TLane : unmanaged, ISPMDLane<TLane, TNumber>
|
|
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
|
|
{
|
|
return new Vector3<TLane, TNumber>
|
|
{
|
|
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<TLane, TNumber> MaskGatherVector3<TLane, TNumber>(TNumber* pData, int* pIndices, TLane mask, [ConstantExpected(Min = (byte)(1), Max = (byte)(8))] byte scale)
|
|
where TLane : unmanaged, ISPMDLane<TLane, TNumber>
|
|
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
|
|
{
|
|
return new Vector3<TLane, TNumber>
|
|
{
|
|
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<TLane, TNumber> MaskGatherVector3<TLane, TNumber>(ref TNumber baseAddress, TLane indices, TLane mask, [ConstantExpected(Min = (byte)(1), Max = (byte)(8))] byte scale)
|
|
where TLane : unmanaged, ISPMDLane<TLane, TNumber>
|
|
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
|
|
{
|
|
return MaskGatherVector3<TLane, TNumber>((TNumber*)Unsafe.AsPointer(ref baseAddress), indices, mask, scale);
|
|
}
|
|
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
public static Vector3<TLane, TNumber> MaskGatherVector3<TLane, TNumber>(ref TNumber baseAddress, ref int baseIndex, TLane mask, [ConstantExpected(Min = (byte)(1), Max = (byte)(8))] byte scale)
|
|
where TLane : unmanaged, ISPMDLane<TLane, TNumber>
|
|
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
|
|
{
|
|
return MaskGatherVector3<TLane, TNumber>((TNumber*)Unsafe.AsPointer(ref baseAddress), (int*)Unsafe.AsPointer(ref baseIndex), mask, scale);
|
|
}
|
|
|
|
|
|
// Math Functions
|
|
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
public static Vector3<TLane, TNumber> Abs<TLane, TNumber>(in Vector3<TLane, TNumber> vector)
|
|
where TLane : unmanaged, ISPMDLane<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 : unmanaged, ISPMDLane<TLane, TNumber>
|
|
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
|
|
{
|
|
return a.x * b.x + a.y * b.y + a.z * b.z;
|
|
}
|
|
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
public static Vector3<TLane, TNumber> Sin<TLane, TNumber>(in Vector3<TLane, TNumber> vector)
|
|
where TLane : unmanaged, ISPMDLane<TLane, TNumber>
|
|
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
|
|
{
|
|
return new Vector3<TLane, TNumber>
|
|
{
|
|
x = TLane.Sin(vector.x),
|
|
y = TLane.Sin(vector.y),
|
|
z = TLane.Sin(vector.z),
|
|
};
|
|
}
|
|
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
public static Vector3<TLane, TNumber> Cos<TLane, TNumber>(in Vector3<TLane, TNumber> vector)
|
|
where TLane : unmanaged, ISPMDLane<TLane, TNumber>
|
|
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
|
|
{
|
|
return new Vector3<TLane, TNumber>
|
|
{
|
|
x = TLane.Cos(vector.x),
|
|
y = TLane.Cos(vector.y),
|
|
z = TLane.Cos(vector.z),
|
|
};
|
|
}
|
|
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
public static void SinCos<TLane, TNumber>(in Vector3<TLane, TNumber> vector, out Vector3<TLane, TNumber> sin, out Vector3<TLane, TNumber> cos)
|
|
where TLane : unmanaged, ISPMDLane<TLane, TNumber>
|
|
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
|
|
{
|
|
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<TLane, TNumber> Sqrt<TLane, TNumber>(in Vector3<TLane, TNumber> vector)
|
|
where TLane : unmanaged, ISPMDLane<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> Tan<TLane, TNumber>(in Vector3<TLane, TNumber> vector)
|
|
where TLane : unmanaged, ISPMDLane<TLane, TNumber>
|
|
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
|
|
{
|
|
return new Vector3<TLane, TNumber>
|
|
{
|
|
x = TLane.Tan(vector.x),
|
|
y = TLane.Tan(vector.y),
|
|
z = TLane.Tan(vector.z),
|
|
};
|
|
}
|
|
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
public static Vector3<TLane, TNumber> Asin<TLane, TNumber>(in Vector3<TLane, TNumber> vector)
|
|
where TLane : unmanaged, ISPMDLane<TLane, TNumber>
|
|
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
|
|
{
|
|
return new Vector3<TLane, TNumber>
|
|
{
|
|
x = TLane.Asin(vector.x),
|
|
y = TLane.Asin(vector.y),
|
|
z = TLane.Asin(vector.z),
|
|
};
|
|
}
|
|
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
public static Vector3<TLane, TNumber> Acos<TLane, TNumber>(in Vector3<TLane, TNumber> vector)
|
|
where TLane : unmanaged, ISPMDLane<TLane, TNumber>
|
|
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
|
|
{
|
|
return new Vector3<TLane, TNumber>
|
|
{
|
|
x = TLane.Acos(vector.x),
|
|
y = TLane.Acos(vector.y),
|
|
z = TLane.Acos(vector.z),
|
|
};
|
|
}
|
|
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
public static Vector3<TLane, TNumber> Atan<TLane, TNumber>(in Vector3<TLane, TNumber> vector)
|
|
where TLane : unmanaged, ISPMDLane<TLane, TNumber>
|
|
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
|
|
{
|
|
return new Vector3<TLane, TNumber>
|
|
{
|
|
x = TLane.Atan(vector.x),
|
|
y = TLane.Atan(vector.y),
|
|
z = TLane.Atan(vector.z),
|
|
};
|
|
}
|
|
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
public static Vector3<TLane, TNumber> Atan2<TLane, TNumber>(in Vector3<TLane, TNumber> x, in Vector3<TLane, TNumber> y)
|
|
where TLane : unmanaged, ISPMDLane<TLane, TNumber>
|
|
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
|
|
{
|
|
return new Vector3<TLane, TNumber>
|
|
{
|
|
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<TLane, TNumber> Rsqrt<TLane, TNumber>(in Vector3<TLane, TNumber> vector)
|
|
where TLane : unmanaged, ISPMDLane<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 : unmanaged, ISPMDLane<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 : unmanaged, ISPMDLane<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 : unmanaged, ISPMDLane<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 : unmanaged, ISPMDLane<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 : unmanaged, ISPMDLane<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 : unmanaged, ISPMDLane<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 : unmanaged, ISPMDLane<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 : unmanaged, ISPMDLane<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 : unmanaged, ISPMDLane<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 : unmanaged, ISPMDLane<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 : unmanaged, ISPMDLane<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 : unmanaged, ISPMDLane<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 : unmanaged, ISPMDLane<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> isTrue, in Vector3<TLane, TNumber> isFalse)
|
|
where TLane : unmanaged, ISPMDLane<TLane, TNumber>
|
|
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
|
|
{
|
|
return new Vector3<TLane, TNumber>
|
|
{
|
|
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<TLane, TNumber> Select<TLane, TNumber>(Vector3<TLane, TNumber> condition, in Vector3<TLane, TNumber> isTrue, in Vector3<TLane, TNumber> isFalse)
|
|
where TLane : unmanaged, ISPMDLane<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, 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<TLane, TNumber> Create<TLane, TNumber>(in TLane x, in TLane y, in TLane z, in TLane w)
|
|
where TLane : unmanaged, ISPMDLane<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 : unmanaged, ISPMDLane<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 : unmanaged, ISPMDLane<TLane, TNumber>
|
|
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
|
|
{
|
|
return new Vector4<TLane, TNumber>
|
|
{
|
|
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<TLane, TNumber> LoadVector4<TLane, TNumber>(ref TNumber src)
|
|
where TLane : unmanaged, ISPMDLane<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> MaskLoadVector4<TLane, TNumber>(TNumber* pSrc, TLane mask)
|
|
where TLane : unmanaged, ISPMDLane<TLane, TNumber>
|
|
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
|
|
{
|
|
return new Vector4<TLane, TNumber>
|
|
{
|
|
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<TLane, TNumber> MaskLoadVector4<TLane, TNumber>(ref TNumber src, TLane mask)
|
|
where TLane : unmanaged, ISPMDLane<TLane, TNumber>
|
|
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
|
|
{
|
|
return MaskLoadVector4<TLane, TNumber>((TNumber*)Unsafe.AsPointer(ref src), mask);
|
|
}
|
|
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
public static Vector4<TLane, TNumber> Load<TLane, TNumber>(TNumber* px, TNumber* py, TNumber* pz, TNumber* pw)
|
|
where TLane : unmanaged, ISPMDLane<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 : unmanaged, ISPMDLane<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),
|
|
};
|
|
}
|
|
|
|
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
public static Vector4<TLane, TNumber> GatherVector4<TLane, TNumber>(TNumber* pData, TLane indices, [ConstantExpected(Min = (byte)(1), Max = (byte)(8))] byte scale)
|
|
where TLane : unmanaged, ISPMDLane<TLane, TNumber>
|
|
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
|
|
{
|
|
return new Vector4<TLane, TNumber>
|
|
{
|
|
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<TLane, TNumber> GatherVector4<TLane, TNumber>(TNumber* pData, int* pIndices, [ConstantExpected(Min = (byte)(1), Max = (byte)(8))] byte scale)
|
|
where TLane : unmanaged, ISPMDLane<TLane, TNumber>
|
|
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
|
|
{
|
|
return new Vector4<TLane, TNumber>
|
|
{
|
|
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<TLane, TNumber> GatherVector4<TLane, TNumber>(ref TNumber baseAddress, TLane indices, [ConstantExpected(Min = (byte)(1), Max = (byte)(8))] byte scale)
|
|
where TLane : unmanaged, ISPMDLane<TLane, TNumber>
|
|
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
|
|
{
|
|
return GatherVector4<TLane, TNumber>((TNumber*)Unsafe.AsPointer(ref baseAddress), indices, scale);
|
|
}
|
|
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
public static Vector4<TLane, TNumber> GatherVector4<TLane, TNumber>(ref TNumber baseAddress, ref int baseIndex, [ConstantExpected(Min = (byte)(1), Max = (byte)(8))] byte scale)
|
|
where TLane : unmanaged, ISPMDLane<TLane, TNumber>
|
|
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
|
|
{
|
|
return GatherVector4<TLane, TNumber>((TNumber*)Unsafe.AsPointer(ref baseAddress), (int*)Unsafe.AsPointer(ref baseIndex), scale);
|
|
}
|
|
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
public static Vector4<TLane, TNumber> MaskGatherVector4<TLane, TNumber>(TNumber* pData, TLane indices, TLane mask, [ConstantExpected(Min = (byte)(1), Max = (byte)(8))] byte scale)
|
|
where TLane : unmanaged, ISPMDLane<TLane, TNumber>
|
|
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
|
|
{
|
|
return new Vector4<TLane, TNumber>
|
|
{
|
|
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<TLane, TNumber> MaskGatherVector4<TLane, TNumber>(TNumber* pData, int* pIndices, TLane mask, [ConstantExpected(Min = (byte)(1), Max = (byte)(8))] byte scale)
|
|
where TLane : unmanaged, ISPMDLane<TLane, TNumber>
|
|
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
|
|
{
|
|
return new Vector4<TLane, TNumber>
|
|
{
|
|
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<TLane, TNumber> MaskGatherVector4<TLane, TNumber>(ref TNumber baseAddress, TLane indices, TLane mask, [ConstantExpected(Min = (byte)(1), Max = (byte)(8))] byte scale)
|
|
where TLane : unmanaged, ISPMDLane<TLane, TNumber>
|
|
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
|
|
{
|
|
return MaskGatherVector4<TLane, TNumber>((TNumber*)Unsafe.AsPointer(ref baseAddress), indices, mask, scale);
|
|
}
|
|
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
public static Vector4<TLane, TNumber> MaskGatherVector4<TLane, TNumber>(ref TNumber baseAddress, ref int baseIndex, TLane mask, [ConstantExpected(Min = (byte)(1), Max = (byte)(8))] byte scale)
|
|
where TLane : unmanaged, ISPMDLane<TLane, TNumber>
|
|
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
|
|
{
|
|
return MaskGatherVector4<TLane, TNumber>((TNumber*)Unsafe.AsPointer(ref baseAddress), (int*)Unsafe.AsPointer(ref baseIndex), mask, scale);
|
|
}
|
|
|
|
|
|
// Math Functions
|
|
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
public static Vector4<TLane, TNumber> Abs<TLane, TNumber>(in Vector4<TLane, TNumber> vector)
|
|
where TLane : unmanaged, ISPMDLane<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 : unmanaged, ISPMDLane<TLane, TNumber>
|
|
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
|
|
{
|
|
return a.x * b.x + a.y * b.y + a.z * b.z + a.w * b.w;
|
|
}
|
|
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
public static Vector4<TLane, TNumber> Sin<TLane, TNumber>(in Vector4<TLane, TNumber> vector)
|
|
where TLane : unmanaged, ISPMDLane<TLane, TNumber>
|
|
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
|
|
{
|
|
return new Vector4<TLane, TNumber>
|
|
{
|
|
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<TLane, TNumber> Cos<TLane, TNumber>(in Vector4<TLane, TNumber> vector)
|
|
where TLane : unmanaged, ISPMDLane<TLane, TNumber>
|
|
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
|
|
{
|
|
return new Vector4<TLane, TNumber>
|
|
{
|
|
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<TLane, TNumber>(in Vector4<TLane, TNumber> vector, out Vector4<TLane, TNumber> sin, out Vector4<TLane, TNumber> cos)
|
|
where TLane : unmanaged, ISPMDLane<TLane, TNumber>
|
|
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
|
|
{
|
|
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<TLane, TNumber> Sqrt<TLane, TNumber>(in Vector4<TLane, TNumber> vector)
|
|
where TLane : unmanaged, ISPMDLane<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> Tan<TLane, TNumber>(in Vector4<TLane, TNumber> vector)
|
|
where TLane : unmanaged, ISPMDLane<TLane, TNumber>
|
|
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
|
|
{
|
|
return new Vector4<TLane, TNumber>
|
|
{
|
|
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<TLane, TNumber> Asin<TLane, TNumber>(in Vector4<TLane, TNumber> vector)
|
|
where TLane : unmanaged, ISPMDLane<TLane, TNumber>
|
|
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
|
|
{
|
|
return new Vector4<TLane, TNumber>
|
|
{
|
|
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<TLane, TNumber> Acos<TLane, TNumber>(in Vector4<TLane, TNumber> vector)
|
|
where TLane : unmanaged, ISPMDLane<TLane, TNumber>
|
|
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
|
|
{
|
|
return new Vector4<TLane, TNumber>
|
|
{
|
|
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<TLane, TNumber> Atan<TLane, TNumber>(in Vector4<TLane, TNumber> vector)
|
|
where TLane : unmanaged, ISPMDLane<TLane, TNumber>
|
|
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
|
|
{
|
|
return new Vector4<TLane, TNumber>
|
|
{
|
|
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<TLane, TNumber> Atan2<TLane, TNumber>(in Vector4<TLane, TNumber> x, in Vector4<TLane, TNumber> y)
|
|
where TLane : unmanaged, ISPMDLane<TLane, TNumber>
|
|
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
|
|
{
|
|
return new Vector4<TLane, TNumber>
|
|
{
|
|
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<TLane, TNumber> Rsqrt<TLane, TNumber>(in Vector4<TLane, TNumber> vector)
|
|
where TLane : unmanaged, ISPMDLane<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 : unmanaged, ISPMDLane<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 : unmanaged, ISPMDLane<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 : unmanaged, ISPMDLane<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 : unmanaged, ISPMDLane<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 : unmanaged, ISPMDLane<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 : unmanaged, ISPMDLane<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 : unmanaged, ISPMDLane<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 : unmanaged, ISPMDLane<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 : unmanaged, ISPMDLane<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 : unmanaged, ISPMDLane<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 : unmanaged, ISPMDLane<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 : unmanaged, ISPMDLane<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 : unmanaged, ISPMDLane<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> isTrue, in Vector4<TLane, TNumber> isFalse)
|
|
where TLane : unmanaged, ISPMDLane<TLane, TNumber>
|
|
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
|
|
{
|
|
return new Vector4<TLane, TNumber>
|
|
{
|
|
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<TLane, TNumber> Select<TLane, TNumber>(Vector4<TLane, TNumber> condition, in Vector4<TLane, TNumber> isTrue, in Vector4<TLane, TNumber> isFalse)
|
|
where TLane : unmanaged, ISPMDLane<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, 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<TLane, TNumber> Cross<TLane, TNumber>(in Vector3<TLane, TNumber> a, in Vector3<TLane, TNumber> b)
|
|
where TLane : unmanaged, ISPMDLane<TLane, TNumber>
|
|
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
|
|
{
|
|
return new Vector3<TLane, TNumber>
|
|
{
|
|
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
|
|
}
|
|
|