Files
Misaki.HighPerformance/Misaki.HighPerformance.Mathematics.SPMD/Templates/MathV.Vector.gen.cs
Misaki 18a181f57a Add AllBitsSet, refactor WideLane, improve math paths
- Add static AllBitsSet property to ISPMDLane and implement in ScalarLane and WideLane
- Refactor WideLane shuffle table pointers and update usages
- Improve pointer safety and mask handling in CompressStore, Gather, and MaskLoad
- Enhance Sin, Cos, SinCos with fast-math and hardware fallback
- Add Newton-Raphson refinement for reciprocal/sqrt when not fast-math
- Optimize MathV.Vector vector loading (struct init, pointer ops)
- Update project file: version 1.3.4, content packaging, AOT settings
- Minor code cleanup and naming consistency fixes
2026-05-01 12:19:58 +09:00

1557 lines
65 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.Numerics;
using System.Runtime.CompilerServices;
namespace Misaki.HighPerformance.Mathematics.SPMD;
public static unsafe partial class MathV
{
# region Vector2
// Creation Functions
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector2<TLane, TNumber> Create<TLane, TNumber>(in TLane x, in TLane y)
where TLane : 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>
{
Unsafe.SkipInit(out TLane x);
var px = (TNumber*)&x;
Unsafe.SkipInit(out TLane y);
var py = (TNumber*)&y;
for (var i = 0; i < TLane.LaneWidth; i++)
{
px[i] = pSrc[i * 2 + 0];
py[i] = pSrc[i * 2 + 1];
}
return new Vector2<TLane, TNumber>
{
x = x,
y = y,
};
}
[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> 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, int scale)
where TLane : unmanaged, ISPMDLane<TLane, TNumber>
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
{
Unsafe.SkipInit(out TLane x);
var px = (TNumber*)&x;
Unsafe.SkipInit(out TLane y);
var py = (TNumber*)&y;
for (var i = 0; i < TLane.LaneWidth; i++)
{
var scalarIdx = int.CreateTruncating(indices[i]);
px[i] = pData[scalarIdx + 0 * scale];
py[i] = pData[scalarIdx + 1 * scale];
}
return new Vector2<TLane, TNumber>
{
x = x,
y = y,
};
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector2<TLane, TNumber> GatherVector2<TLane, TNumber>(TNumber* pData, int* pIndices, int scale)
where TLane : unmanaged, ISPMDLane<TLane, TNumber>
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
{
Unsafe.SkipInit(out TLane x);
var px = (TNumber*)&x;
Unsafe.SkipInit(out TLane y);
var py = (TNumber*)&y;
for (var i = 0; i < TLane.LaneWidth; i++)
{
var scalerIdx = pIndices[i];
px[i] = pData[scalerIdx + 0 * scale];
py[i] = pData[scalerIdx + 1 * scale];
}
return new Vector2<TLane, TNumber>
{
x = x,
y = y,
};
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector2<TLane, TNumber> GatherVector2<TLane, TNumber>(ref TNumber baseAddress, TLane indices, int scale)
where TLane : unmanaged, ISPMDLane<TLane, TNumber>
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
{
Unsafe.SkipInit(out TLane x);
var px = (TNumber*)&x;
Unsafe.SkipInit(out TLane y);
var py = (TNumber*)&y;
for (var i = 0; i < TLane.LaneWidth; i++)
{
var scalarIdx = int.CreateTruncating(indices[i]);
px[i] = Unsafe.Add(ref baseAddress, scalarIdx + 0 * scale);
py[i] = Unsafe.Add(ref baseAddress, scalarIdx + 1 * scale);
}
return new Vector2<TLane, TNumber>
{
x = x,
y = y,
};
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector2<TLane, TNumber> GatherVector2<TLane, TNumber>(ref TNumber baseAddress, ref int baseIndex, int scale)
where TLane : unmanaged, ISPMDLane<TLane, TNumber>
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
{
Unsafe.SkipInit(out TLane x);
var px = (TNumber*)&x;
Unsafe.SkipInit(out TLane y);
var py = (TNumber*)&y;
for (var i = 0; i < TLane.LaneWidth; i++)
{
var scalarIdx = Unsafe.Add(ref baseIndex, i);
px[i] = Unsafe.Add(ref baseAddress, scalarIdx + 0 * scale);
py[i] = Unsafe.Add(ref baseAddress, scalarIdx + 1 * scale);
}
return new Vector2<TLane, TNumber>
{
x = x,
y = y,
};
}
// 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> 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.Select(condition, b.x, a.x),
y = TLane.Select(condition, b.y, a.y),
};
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector2<TLane, TNumber> Select<TLane, TNumber>(Vector2<TLane, TNumber> condition, in Vector2<TLane, TNumber> a, in Vector2<TLane, TNumber> b)
where TLane : 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, b.x, a.x),
y = TLane.Select(condition.y, b.y, a.y),
};
}
# endregion
# region Vector3
// Creation Functions
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector3<TLane, TNumber> Create<TLane, TNumber>(in TLane x, in TLane y, in TLane z)
where TLane : 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>
{
Unsafe.SkipInit(out TLane x);
var px = (TNumber*)&x;
Unsafe.SkipInit(out TLane y);
var py = (TNumber*)&y;
Unsafe.SkipInit(out TLane z);
var pz = (TNumber*)&z;
for (var i = 0; i < TLane.LaneWidth; i++)
{
px[i] = pSrc[i * 3 + 0];
py[i] = pSrc[i * 3 + 1];
pz[i] = pSrc[i * 3 + 2];
}
return new Vector3<TLane, TNumber>
{
x = x,
y = y,
z = z,
};
}
[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> 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, int scale)
where TLane : unmanaged, ISPMDLane<TLane, TNumber>
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
{
Unsafe.SkipInit(out TLane x);
var px = (TNumber*)&x;
Unsafe.SkipInit(out TLane y);
var py = (TNumber*)&y;
Unsafe.SkipInit(out TLane z);
var pz = (TNumber*)&z;
for (var i = 0; i < TLane.LaneWidth; i++)
{
var scalarIdx = int.CreateTruncating(indices[i]);
px[i] = pData[scalarIdx + 0 * scale];
py[i] = pData[scalarIdx + 1 * scale];
pz[i] = pData[scalarIdx + 2 * scale];
}
return new Vector3<TLane, TNumber>
{
x = x,
y = y,
z = z,
};
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector3<TLane, TNumber> GatherVector3<TLane, TNumber>(TNumber* pData, int* pIndices, int scale)
where TLane : unmanaged, ISPMDLane<TLane, TNumber>
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
{
Unsafe.SkipInit(out TLane x);
var px = (TNumber*)&x;
Unsafe.SkipInit(out TLane y);
var py = (TNumber*)&y;
Unsafe.SkipInit(out TLane z);
var pz = (TNumber*)&z;
for (var i = 0; i < TLane.LaneWidth; i++)
{
var scalerIdx = pIndices[i];
px[i] = pData[scalerIdx + 0 * scale];
py[i] = pData[scalerIdx + 1 * scale];
pz[i] = pData[scalerIdx + 2 * scale];
}
return new Vector3<TLane, TNumber>
{
x = x,
y = y,
z = z,
};
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector3<TLane, TNumber> GatherVector3<TLane, TNumber>(ref TNumber baseAddress, TLane indices, int scale)
where TLane : unmanaged, ISPMDLane<TLane, TNumber>
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
{
Unsafe.SkipInit(out TLane x);
var px = (TNumber*)&x;
Unsafe.SkipInit(out TLane y);
var py = (TNumber*)&y;
Unsafe.SkipInit(out TLane z);
var pz = (TNumber*)&z;
for (var i = 0; i < TLane.LaneWidth; i++)
{
var scalarIdx = int.CreateTruncating(indices[i]);
px[i] = Unsafe.Add(ref baseAddress, scalarIdx + 0 * scale);
py[i] = Unsafe.Add(ref baseAddress, scalarIdx + 1 * scale);
pz[i] = Unsafe.Add(ref baseAddress, scalarIdx + 2 * scale);
}
return new Vector3<TLane, TNumber>
{
x = x,
y = y,
z = z,
};
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector3<TLane, TNumber> GatherVector3<TLane, TNumber>(ref TNumber baseAddress, ref int baseIndex, int scale)
where TLane : unmanaged, ISPMDLane<TLane, TNumber>
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
{
Unsafe.SkipInit(out TLane x);
var px = (TNumber*)&x;
Unsafe.SkipInit(out TLane y);
var py = (TNumber*)&y;
Unsafe.SkipInit(out TLane z);
var pz = (TNumber*)&z;
for (var i = 0; i < TLane.LaneWidth; i++)
{
var scalarIdx = Unsafe.Add(ref baseIndex, i);
px[i] = Unsafe.Add(ref baseAddress, scalarIdx + 0 * scale);
py[i] = Unsafe.Add(ref baseAddress, scalarIdx + 1 * scale);
pz[i] = Unsafe.Add(ref baseAddress, scalarIdx + 2 * scale);
}
return new Vector3<TLane, TNumber>
{
x = x,
y = y,
z = z,
};
}
// 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> 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.Select(condition, b.x, a.x),
y = TLane.Select(condition, b.y, a.y),
z = TLane.Select(condition, b.z, a.z),
};
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector3<TLane, TNumber> Select<TLane, TNumber>(Vector3<TLane, TNumber> condition, in Vector3<TLane, TNumber> a, in Vector3<TLane, TNumber> b)
where TLane : 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, b.x, a.x),
y = TLane.Select(condition.y, b.y, a.y),
z = TLane.Select(condition.z, b.z, a.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>
{
Unsafe.SkipInit(out TLane x);
var px = (TNumber*)&x;
Unsafe.SkipInit(out TLane y);
var py = (TNumber*)&y;
Unsafe.SkipInit(out TLane z);
var pz = (TNumber*)&z;
Unsafe.SkipInit(out TLane w);
var pw = (TNumber*)&w;
for (var i = 0; i < TLane.LaneWidth; i++)
{
px[i] = pSrc[i * 4 + 0];
py[i] = pSrc[i * 4 + 1];
pz[i] = pSrc[i * 4 + 2];
pw[i] = pSrc[i * 4 + 3];
}
return new Vector4<TLane, TNumber>
{
x = x,
y = y,
z = z,
w = w,
};
}
[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> 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, int scale)
where TLane : unmanaged, ISPMDLane<TLane, TNumber>
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
{
Unsafe.SkipInit(out TLane x);
var px = (TNumber*)&x;
Unsafe.SkipInit(out TLane y);
var py = (TNumber*)&y;
Unsafe.SkipInit(out TLane z);
var pz = (TNumber*)&z;
Unsafe.SkipInit(out TLane w);
var pw = (TNumber*)&w;
for (var i = 0; i < TLane.LaneWidth; i++)
{
var scalarIdx = int.CreateTruncating(indices[i]);
px[i] = pData[scalarIdx + 0 * scale];
py[i] = pData[scalarIdx + 1 * scale];
pz[i] = pData[scalarIdx + 2 * scale];
pw[i] = pData[scalarIdx + 3 * scale];
}
return new Vector4<TLane, TNumber>
{
x = x,
y = y,
z = z,
w = w,
};
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector4<TLane, TNumber> GatherVector4<TLane, TNumber>(TNumber* pData, int* pIndices, int scale)
where TLane : unmanaged, ISPMDLane<TLane, TNumber>
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
{
Unsafe.SkipInit(out TLane x);
var px = (TNumber*)&x;
Unsafe.SkipInit(out TLane y);
var py = (TNumber*)&y;
Unsafe.SkipInit(out TLane z);
var pz = (TNumber*)&z;
Unsafe.SkipInit(out TLane w);
var pw = (TNumber*)&w;
for (var i = 0; i < TLane.LaneWidth; i++)
{
var scalerIdx = pIndices[i];
px[i] = pData[scalerIdx + 0 * scale];
py[i] = pData[scalerIdx + 1 * scale];
pz[i] = pData[scalerIdx + 2 * scale];
pw[i] = pData[scalerIdx + 3 * scale];
}
return new Vector4<TLane, TNumber>
{
x = x,
y = y,
z = z,
w = w,
};
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector4<TLane, TNumber> GatherVector4<TLane, TNumber>(ref TNumber baseAddress, TLane indices, int scale)
where TLane : unmanaged, ISPMDLane<TLane, TNumber>
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
{
Unsafe.SkipInit(out TLane x);
var px = (TNumber*)&x;
Unsafe.SkipInit(out TLane y);
var py = (TNumber*)&y;
Unsafe.SkipInit(out TLane z);
var pz = (TNumber*)&z;
Unsafe.SkipInit(out TLane w);
var pw = (TNumber*)&w;
for (var i = 0; i < TLane.LaneWidth; i++)
{
var scalarIdx = int.CreateTruncating(indices[i]);
px[i] = Unsafe.Add(ref baseAddress, scalarIdx + 0 * scale);
py[i] = Unsafe.Add(ref baseAddress, scalarIdx + 1 * scale);
pz[i] = Unsafe.Add(ref baseAddress, scalarIdx + 2 * scale);
pw[i] = Unsafe.Add(ref baseAddress, scalarIdx + 3 * scale);
}
return new Vector4<TLane, TNumber>
{
x = x,
y = y,
z = z,
w = w,
};
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector4<TLane, TNumber> GatherVector4<TLane, TNumber>(ref TNumber baseAddress, ref int baseIndex, int scale)
where TLane : unmanaged, ISPMDLane<TLane, TNumber>
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
{
Unsafe.SkipInit(out TLane x);
var px = (TNumber*)&x;
Unsafe.SkipInit(out TLane y);
var py = (TNumber*)&y;
Unsafe.SkipInit(out TLane z);
var pz = (TNumber*)&z;
Unsafe.SkipInit(out TLane w);
var pw = (TNumber*)&w;
for (var i = 0; i < TLane.LaneWidth; i++)
{
var scalarIdx = Unsafe.Add(ref baseIndex, i);
px[i] = Unsafe.Add(ref baseAddress, scalarIdx + 0 * scale);
py[i] = Unsafe.Add(ref baseAddress, scalarIdx + 1 * scale);
pz[i] = Unsafe.Add(ref baseAddress, scalarIdx + 2 * scale);
pw[i] = Unsafe.Add(ref baseAddress, scalarIdx + 3 * scale);
}
return new Vector4<TLane, TNumber>
{
x = x,
y = y,
z = z,
w = w,
};
}
// 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> 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.Select(condition, b.x, a.x),
y = TLane.Select(condition, b.y, a.y),
z = TLane.Select(condition, b.z, a.z),
w = TLane.Select(condition, b.w, a.w),
};
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector4<TLane, TNumber> Select<TLane, TNumber>(Vector4<TLane, TNumber> condition, in Vector4<TLane, TNumber> a, in Vector4<TLane, TNumber> b)
where TLane : 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, b.x, a.x),
y = TLane.Select(condition.y, b.y, a.y),
z = TLane.Select(condition.z, b.z, a.z),
w = TLane.Select(condition.w, b.w, a.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
}