tools/generate-swizzles.ps1 writes the checked-in src/CultMath/Swizzles.g.cs as partial structs plus a partial math: for float2/3/4, int2/3/4 and bool2/3/4 every swizzle of length 2-4 including repeats, in xyzw and rgba naming, with setters only on non-repeating masks, plus single-component r/g/b/a. double2/3 get lengths 2-3 (there is no double4). Every HLSL mixed constructor (float4(float2, float2), float4(float, float2, float), copy forms, ...) exists as a struct constructor and, for float/int/bool, a math function. The hand-written swizzles and mixed constructors it supersedes are deleted. Matrices store private rows and return ref float2/float3 from the row indexer ([UnscopedRef], polyfilled for netstandard2.1), so m[1][2] = s compiles as in HLSL; _mRC are get/set properties over the rows. Equality and hashing stay value-based. Intrinsics follow HLSL: sign returns int/intN and yields 0 for NaN; step is x >= y ? 1 : 0 so NaN yields 0; any/all accept float and int vectors; min/max/abs on int vectors return int vectors, and abs(int) returns int. Strips the UTF-8 BOMs this branch added to math.cs, CultMath.csproj and HlslSemanticsTests.cs. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
68 lines
3.2 KiB
C#
68 lines
3.2 KiB
C#
using System;
|
|
|
|
namespace CultMath;
|
|
|
|
public partial struct int4 : IEquatable<int4>
|
|
{
|
|
public static readonly int4 zero = new(0, 0, 0, 0);
|
|
public static readonly int4 one = new(1, 1, 1, 1);
|
|
|
|
public int x;
|
|
public int y;
|
|
public int z;
|
|
public int w;
|
|
|
|
public int4(int x, int y, int z, int w)
|
|
{
|
|
this.x = x;
|
|
this.y = y;
|
|
this.z = z;
|
|
this.w = w;
|
|
}
|
|
|
|
public int this[int index]
|
|
{
|
|
readonly get => index switch
|
|
{
|
|
0 => x,
|
|
1 => y,
|
|
2 => z,
|
|
3 => w,
|
|
_ => throw new ArgumentOutOfRangeException(nameof(index)),
|
|
};
|
|
set
|
|
{
|
|
switch (index)
|
|
{
|
|
case 0: x = value; break;
|
|
case 1: y = value; break;
|
|
case 2: z = value; break;
|
|
case 3: w = value; break;
|
|
default: throw new ArgumentOutOfRangeException(nameof(index));
|
|
}
|
|
}
|
|
}
|
|
|
|
public static implicit operator int4(int value) => new(value, value, value, value);
|
|
public static implicit operator float4(int4 value) => new(value.x, value.y, value.z, value.w);
|
|
|
|
public static int4 operator +(int4 value) => value;
|
|
public static int4 operator -(int4 value) => new(-value.x, -value.y, -value.z, -value.w);
|
|
public static int4 operator +(int4 left, int4 right) => new(left.x + right.x, left.y + right.y, left.z + right.z, left.w + right.w);
|
|
public static int4 operator -(int4 left, int4 right) => new(left.x - right.x, left.y - right.y, left.z - right.z, left.w - right.w);
|
|
public static int4 operator *(int4 left, int4 right) => new(left.x * right.x, left.y * right.y, left.z * right.z, left.w * right.w);
|
|
public static int4 operator /(int4 left, int4 right) => new(left.x / right.x, left.y / right.y, left.z / right.z, left.w / right.w);
|
|
public static int4 operator %(int4 left, int4 right) => new(left.x % right.x, left.y % right.y, left.z % right.z, left.w % right.w);
|
|
|
|
public static bool4 operator <(int4 left, int4 right) => new(left.x < right.x, left.y < right.y, left.z < right.z, left.w < right.w);
|
|
public static bool4 operator >(int4 left, int4 right) => new(left.x > right.x, left.y > right.y, left.z > right.z, left.w > right.w);
|
|
public static bool4 operator <=(int4 left, int4 right) => new(left.x <= right.x, left.y <= right.y, left.z <= right.z, left.w <= right.w);
|
|
public static bool4 operator >=(int4 left, int4 right) => new(left.x >= right.x, left.y >= right.y, left.z >= right.z, left.w >= right.w);
|
|
public static bool4 operator ==(int4 left, int4 right) => new(left.x == right.x, left.y == right.y, left.z == right.z, left.w == right.w);
|
|
public static bool4 operator !=(int4 left, int4 right) => new(left.x != right.x, left.y != right.y, left.z != right.z, left.w != right.w);
|
|
|
|
public readonly bool Equals(int4 other) => x == other.x && y == other.y && z == other.z && w == other.w;
|
|
public override readonly bool Equals(object? obj) => obj is int4 other && Equals(other);
|
|
public override readonly int GetHashCode() => HashCode.Combine(x, y, z, w);
|
|
public override readonly string ToString() => FormattableString.Invariant($"int4({x}, {y}, {z}, {w})");
|
|
}
|