diff --git a/packages/cultmath/docs/design.md b/packages/cultmath/docs/design.md index 863b5efe..ee209fd4 100644 --- a/packages/cultmath/docs/design.md +++ b/packages/cultmath/docs/design.md @@ -37,6 +37,11 @@ That makes these HLSL rules, not options: products go through `mul` (`mul(m, v)` treats `v` as a column, `mul(v, m)` as a row). `*` on matrices would be component-wise in HLSL, so CultMath does not define it. +- `m[r][c] = v` writes through locals, array elements, fields of classes, and + ref locals. Through a readonly field, an `in` parameter, a property + (auto-properties included), or a static readonly value such as + `float3x3.identity`, C# takes a defensive copy: the write compiles and is + silently lost. Copy the matrix to a local, write to it, and assign it back. - Scalar/vector arithmetic and comparisons have explicit overloads on both sides rather than leaning on implicit scalar splat. - Intrinsics return HLSL's types and edge cases: `sign` returns `int`/`intN` diff --git a/packages/cultmath/src/CultMath/float2x2.cs b/packages/cultmath/src/CultMath/float2x2.cs index 9d5a2e54..bd8673ae 100644 --- a/packages/cultmath/src/CultMath/float2x2.cs +++ b/packages/cultmath/src/CultMath/float2x2.cs @@ -34,6 +34,7 @@ public struct float2x2 : IEquatable public float _m10 { readonly get => _row1.x; set => _row1.x = value; } public float _m11 { readonly get => _row1.y; set => _row1.y = value; } + /// Writes through a readonly field, in parameter, property, or identity hit a defensive copy and are lost; write to a local and assign it back. [UnscopedRef] public ref float2 this[int row] { diff --git a/packages/cultmath/src/CultMath/float3x3.cs b/packages/cultmath/src/CultMath/float3x3.cs index 4c052a50..d7aad21c 100644 --- a/packages/cultmath/src/CultMath/float3x3.cs +++ b/packages/cultmath/src/CultMath/float3x3.cs @@ -42,6 +42,7 @@ public struct float3x3 : IEquatable public float _m21 { readonly get => _row2.y; set => _row2.y = value; } public float _m22 { readonly get => _row2.z; set => _row2.z = value; } + /// Writes through a readonly field, in parameter, property, or identity hit a defensive copy and are lost; write to a local and assign it back. [UnscopedRef] public ref float3 this[int row] { diff --git a/packages/cultmath/unity/org.gamecult.cultmath/Runtime/Plugins/CultMath.dll b/packages/cultmath/unity/org.gamecult.cultmath/Runtime/Plugins/CultMath.dll index 1b4d8b07..28e9c939 100644 Binary files a/packages/cultmath/unity/org.gamecult.cultmath/Runtime/Plugins/CultMath.dll and b/packages/cultmath/unity/org.gamecult.cultmath/Runtime/Plugins/CultMath.dll differ diff --git a/packages/cultmath/unity/org.gamecult.cultmath/Runtime/Plugins/CultMath.pdb b/packages/cultmath/unity/org.gamecult.cultmath/Runtime/Plugins/CultMath.pdb index 4745e116..c2dc2446 100644 Binary files a/packages/cultmath/unity/org.gamecult.cultmath/Runtime/Plugins/CultMath.pdb and b/packages/cultmath/unity/org.gamecult.cultmath/Runtime/Plugins/CultMath.pdb differ