diff --git a/Directory.Build.props b/Directory.Build.props index 7ed6fb6e8..190e89780 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -6,8 +6,8 @@ 45c2f4006f5f7dab357426cabd3197e8d0a17f66 $(CULTMATH_ROOT) $(CultLibRoot) - - 252e226c51826d626f4113673f31d96577b67ec9 + + 9c1b06cd703bfa44352050e819b0d0659cf5978a C:\Program Files\Git\cmd\git.exe git diff --git a/Packages/manifest.json b/Packages/manifest.json index a04f36e20..2dd2a3bb3 100644 --- a/Packages/manifest.json +++ b/Packages/manifest.json @@ -54,6 +54,6 @@ "com.unity.modules.xr": "1.0.0", "org.gamecult.caching.unity": "https://github.com/GameCult/CultLib.git?path=/src/GameCult.Unity/Assets/Caching#caching-unity-v1.4.0", "org.gamecult.cultlib": "https://github.com/GameCult/CultLib.git?path=/unity/org.gamecult.cultlib#cultlib-unity-v1.0.60", - "org.gamecult.cultmath": "https://github.com/GameCult/CultLib.git?path=/packages/cultmath/unity/org.gamecult.cultmath#cultmath-unity-v0.4.0" + "org.gamecult.cultmath": "https://github.com/GameCult/CultLib.git?path=/packages/cultmath/unity/org.gamecult.cultmath#cultmath-unity-v0.4.1" } } diff --git a/Packages/packages-lock.json b/Packages/packages-lock.json index f4c128708..5d26bd587 100644 --- a/Packages/packages-lock.json +++ b/Packages/packages-lock.json @@ -272,11 +272,11 @@ "hash": "45c2f4006f5f7dab357426cabd3197e8d0a17f66" }, "org.gamecult.cultmath": { - "version": "https://github.com/GameCult/CultLib.git?path=/packages/cultmath/unity/org.gamecult.cultmath#cultmath-unity-v0.4.0", + "version": "https://github.com/GameCult/CultLib.git?path=/packages/cultmath/unity/org.gamecult.cultmath#cultmath-unity-v0.4.1", "depth": 0, "source": "git", "dependencies": {}, - "hash": "252e226c51826d626f4113673f31d96577b67ec9" + "hash": "9c1b06cd703bfa44352050e819b0d0659cf5978a" }, "com.unity.modules.accessibility": { "version": "1.0.0", diff --git a/tests/Aetheria.Shared.Tests/ThrustAllocatorTests.cs b/tests/Aetheria.Shared.Tests/ThrustAllocatorTests.cs index 7e36f5569..228b2e630 100644 --- a/tests/Aetheria.Shared.Tests/ThrustAllocatorTests.cs +++ b/tests/Aetheria.Shared.Tests/ThrustAllocatorTests.cs @@ -265,6 +265,39 @@ public class ThrustAllocatorTests } } + // A cruiser-like hull, n thrusters each pushing along one body axis with a lever-arm yaw (the finding's fixture + // generator: Synthetic(8, 7005)). + static float3[] Synthetic(int n, int seed) + { + var rng = new System.Random(seed); + var cols = new float3[n]; + for (var i = 0; i < n; i++) + { + var a = 20f + 40f * (float)rng.NextDouble(); + var yaw = (float)(rng.NextDouble() * 2 - 1) * 120f; + var dir = rng.Next(10); + cols[i] = dir < 4 ? Col(0, a, yaw) : dir < 6 ? Col(0, -a, yaw) : dir < 8 ? Col(a, 0, yaw) : Col(-a, 0, yaw); + } + return cols; + } + + // Finding solver-converged-early: on this hull a fresh allocator's eighth intent of a seeded random walk stopped at a + // non-optimal point (throttle 7 at 1.0 against .922 warm). The answer is the same from a cold and from a warm start. + [Fact] + public void ColdAndWarmStartsAgreeOnTheHullThatStoppedEarly() + { + var hull = Synthetic(8, 7005); + var rng = new System.Random(5); + var warm = new ThrustAllocator(); + for (var step = 0; step < 8; step++) + { + float x = (float)rng.NextDouble() * 2 - 1, y = (float)rng.NextDouble() * 2 - 1, turn = (float)rng.NextDouble() * 2 - 1; + var fromWarm = Solve(warm, hull, x, y, turn); + var fromCold = Solve(hull, x, y, turn); + for (var i = 0; i < hull.Length; i++) Assert.True(MathF.Abs(fromWarm[i] - fromCold[i]) <= 1e-5f, $"step {step}: throttle {i} {fromCold[i]} cold vs {fromWarm[i]} warm"); + } + } + [Fact] public void EqualThrustersShareTheDemand() {