diff --git a/README.md b/README.md index 02d4775..d5cc137 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,8 @@ -# CultMath +# CultMath (archived) + +CultMath now lives in [`GameCult/CultLib`](https://github.com/GameCult/CultLib) +under `packages/cultmath`. This repository preserves pre-monorepo history and +release provenance; it is not the source or release authority. Clean-room math shaped for people who think in HLSL. @@ -84,7 +88,7 @@ CultMath's Unity 2021.3 surface is the tracked precompiled package at tree and does not require a consumer `csc.rsp` workaround. ```json -"org.gamecult.cultmath": "https://github.com/GameCult/CultMath.git?path=/unity/org.gamecult.cultmath" +"org.gamecult.cultmath": "https://github.com/GameCult/CultLib.git?path=/packages/cultmath/unity/org.gamecult.cultmath#cultmath-unity-v0.1.2" ``` The repository root is not a Unity package. Build the tracked package with @@ -102,7 +106,7 @@ CultMath keeps portable DXC outside git under `.tools/`: .\tools\compile-hlsl-spirv.ps1 ` -ShaderPath E:\Projects\Odin\crates\muninn-move-tracker\shaders\MoveSphereCandidate.comp.hlsl ` -OutputPath E:\Projects\Odin\crates\muninn-move-tracker\artifacts\shader\MoveSphereCandidate.comp.spv ` - -IncludePath E:\Projects\CultMath\shaders + -IncludePath E:\Projects\CultLib\packages\cultmath\shaders .\tools\compile-spirv-metal.ps1 ` -SpirvPath E:\Projects\Odin\crates\muninn-move-tracker\artifacts\shader\MoveSphereCandidate.comp.spv ` -OutputPath E:\Projects\Odin\crates\muninn-move-tracker\artifacts\shader\MoveSphereCandidate.comp.metal diff --git a/src/CultMath/CultMath.csproj b/src/CultMath/CultMath.csproj index 73b3fd5..54dc54b 100644 --- a/src/CultMath/CultMath.csproj +++ b/src/CultMath/CultMath.csproj @@ -8,10 +8,10 @@ CultMath CultMath CultMath - 0.1.0 + 0.1.2 Clean-room C# math shaped for HLSL-style renderer code. GameCult - https://github.com/GameCult/CultMath + https://github.com/GameCult/CultLib README.md $(NoWarn);CS8981 true diff --git a/src/CultMath/rect.cs b/src/CultMath/rect.cs new file mode 100644 index 0000000..51e05c1 --- /dev/null +++ b/src/CultMath/rect.cs @@ -0,0 +1,59 @@ +namespace CultMath; + +/// +/// Axis-aligned 2D bounds stored canonically as normalized minimum and maximum +/// corners. Point containment and intersection include the boundary. +/// +public readonly record struct rect +{ + public rect(float minX, float minY, float maxX, float maxY) + : this(new float2(minX, minY), new float2(maxX, maxY)) + { + } + + public rect(float2 min, float2 max) + { + this.min = new float2(MathF.Min(min.x, max.x), MathF.Min(min.y, max.y)); + this.max = new float2(MathF.Max(min.x, max.x), MathF.Max(min.y, max.y)); + } + + public float2 min { get; } + public float2 max { get; } + + public float width => max.x - min.x; + public float height => max.y - min.y; + public float2 size => max - min; + public float2 center => (min + max) * 0.5f; + public float area => width * height; + public bool isEmpty => width == 0.0f || height == 0.0f; + + public bool Contains(float2 point) => + point.x >= min.x && point.x <= max.x && + point.y >= min.y && point.y <= max.y; + + public bool Contains(rect other) => + other.min.x >= min.x && other.max.x <= max.x && + other.min.y >= min.y && other.max.y <= max.y; + + public bool Intersects(rect other) => + min.x <= other.max.x && max.x >= other.min.x && + min.y <= other.max.y && max.y >= other.min.y; + + public rect Intersection(rect other) + { + if (!Intersects(other)) + return new rect(0.0f, 0.0f, 0.0f, 0.0f); + + return new rect( + MathF.Max(min.x, other.min.x), + MathF.Max(min.y, other.min.y), + MathF.Min(max.x, other.max.x), + MathF.Min(max.y, other.max.y)); + } + + public rect Encapsulate(float2 point) => new( + MathF.Min(min.x, point.x), + MathF.Min(min.y, point.y), + MathF.Max(max.x, point.x), + MathF.Max(max.y, point.y)); +} diff --git a/src/CultMath/rect.cs.meta b/src/CultMath/rect.cs.meta new file mode 100644 index 0000000..0b04a5c --- /dev/null +++ b/src/CultMath/rect.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 5aab0d8e1ca94d42b85bba780a7ee449 diff --git a/tests/CultMath.Tests/MathTests.cs b/tests/CultMath.Tests/MathTests.cs index ad26821..8d42a0c 100644 --- a/tests/CultMath.Tests/MathTests.cs +++ b/tests/CultMath.Tests/MathTests.cs @@ -199,6 +199,41 @@ public sealed class MathTests Assert.Equal(new float2(2.0f, 0.0f), closest); } + [Fact] + public void RectNormalizesAndDerivesFromMinMax() + { + var bounds = new rect(8.0f, 6.0f, 2.0f, -2.0f); + + Assert.Equal(new float2(2.0f, -2.0f), bounds.min); + Assert.Equal(new float2(8.0f, 6.0f), bounds.max); + Assert.Equal(new float2(6.0f, 8.0f), bounds.size); + Assert.Equal(new float2(5.0f, 2.0f), bounds.center); + Assert.Equal(48.0f, bounds.area); + } + + [Fact] + public void RectContainmentIncludesBoundary() + { + var bounds = new rect(-2.0f, -1.0f, 4.0f, 3.0f); + + Assert.True(bounds.Contains(new float2(-2.0f, -1.0f))); + Assert.True(bounds.Contains(new float2(4.0f, 3.0f))); + Assert.True(bounds.Contains(new rect(-1.0f, 0.0f, 1.0f, 2.0f))); + Assert.False(bounds.Contains(new float2(4.001f, 3.0f))); + } + + [Fact] + public void RectIntersectionTreatsTouchingEdgesAsContact() + { + var left = new rect(0.0f, 0.0f, 4.0f, 4.0f); + var touching = new rect(4.0f, 1.0f, 8.0f, 3.0f); + var separate = new rect(4.001f, 1.0f, 8.0f, 3.0f); + + Assert.True(left.Intersects(touching)); + Assert.Equal(0.0f, left.Intersection(touching).area); + Assert.False(left.Intersects(separate)); + } + [Fact] public void FirstOrderInterceptSolvesSimpleClosingTarget() { diff --git a/unity/org.gamecult.cultmath/README.md b/unity/org.gamecult.cultmath/README.md index 223e16c..ad8af61 100644 --- a/unity/org.gamecult.cultmath/README.md +++ b/unity/org.gamecult.cultmath/README.md @@ -22,7 +22,7 @@ DLL/PDB and stable Unity metadata, and stages an inspectable package under Consume the repository package with: ```json -"org.gamecult.cultmath": "https://github.com/GameCult/CultMath.git?path=/unity/org.gamecult.cultmath" +"org.gamecult.cultmath": "https://github.com/GameCult/CultLib.git?path=/packages/cultmath/unity/org.gamecult.cultmath#cultmath-unity-v0.1.2" ``` Production consumers should pin that URL to a commit or release tag. diff --git a/unity/org.gamecult.cultmath/Runtime/Plugins/CultMath.dll b/unity/org.gamecult.cultmath/Runtime/Plugins/CultMath.dll index 91b51d8..379dad4 100644 Binary files a/unity/org.gamecult.cultmath/Runtime/Plugins/CultMath.dll and b/unity/org.gamecult.cultmath/Runtime/Plugins/CultMath.dll differ diff --git a/unity/org.gamecult.cultmath/Runtime/Plugins/CultMath.pdb b/unity/org.gamecult.cultmath/Runtime/Plugins/CultMath.pdb index 711cf76..223b4de 100644 Binary files a/unity/org.gamecult.cultmath/Runtime/Plugins/CultMath.pdb and b/unity/org.gamecult.cultmath/Runtime/Plugins/CultMath.pdb differ diff --git a/unity/org.gamecult.cultmath/package.json b/unity/org.gamecult.cultmath/package.json index e45d0a3..80cedda 100644 --- a/unity/org.gamecult.cultmath/package.json +++ b/unity/org.gamecult.cultmath/package.json @@ -1,7 +1,7 @@ { "name": "org.gamecult.cultmath", "displayName": "CultMath", - "version": "0.1.0", + "version": "0.1.2", "unity": "2021.3", "description": "Precompiled CultMath numeric primitives and matching HLSL semantics for GameCult Unity runtimes.", "license": "MPL-2.0",