phase(N.1): delete legacy scenery code path; WB is the only path

Phase N.1 step 8 (final code cleanup): now that ACDREAM_USE_WB_SCENERY
has been default-on (commit b84ecbd), remove the legacy in-line
algorithms so we don't accumulate dead-code drift.

Deleted:
- SceneryGenerator.UseWbScenery (feature flag)
- SceneryGenerator.IsOnRoad / DisplaceObject / RoadHalfWidth (legacy
  ports — Generate used to call them)
- The legacy in-line implementation in Generate()
- SceneryGeneratorTests.DisplaceObject_* (test the deleted method)
- SceneryWbConformanceTests.cs entirely (purpose served — proved
  equivalence pre-migration; would compare WB to WB after delete)

Renamed:
- GenerateViaWb -> GenerateInternal (it's the only path now)

Kept:
- Public IsRoadVertex predicate (small surface, useful)
- WbSceneryAdapter (consumed by GenerateInternal)
- All WbSceneryAdapterTests (still cover the adapter)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Erik 2026-05-08 10:37:55 +02:00
parent b84ecbda51
commit b0ec6deb50
3 changed files with 24 additions and 615 deletions

View file

@ -1,13 +1,14 @@
using System.Numerics;
using AcDream.Core.World;
using DatReaderWriter.Types;
namespace AcDream.Core.Tests.World;
/// <summary>
/// Tests for SceneryGenerator: road-exclusion, loop bounds, building
/// suppression, and slope filter. The full Generate() pipeline requires
/// real dat files so behavior is tested via internal helpers.
/// Tests for SceneryGenerator. As of Phase N.1 (commit b84ecbd / Task 8 final
/// commit), the displacement / road / slope / rotation / scale algorithms run
/// through WorldBuilder's helpers (SceneryHelpers + TerrainUtils). The only
/// our-side code remaining is the small <see cref="SceneryGenerator.IsRoadVertex"/>
/// predicate, which is what these tests cover.
/// </summary>
public class SceneryGeneratorTests
{
@ -47,63 +48,4 @@ public class SceneryGeneratorTests
$"raw=0x{raw:X4}: IsRoadVertex={actual} but TerrainInfo.Road={ti.Road}");
}
}
// --- Edge vertex displacement tests ---
// Retail iterates 9×9 vertices (0..8 on each axis). Vertices at x=8 or y=8
// have base positions at 192 (= 8 * 24), which is AT the landblock boundary.
// These produce valid scenery when displacement shifts them back into [0, 192).
[Fact]
public void DisplaceObject_EdgeVertex_CanProduceValidPosition()
{
// Vertex (3, 8): base_y = 8 * 24 = 192.
// With DisplaceY > 0, some LCG seeds will produce negative displacement,
// shifting the Y back below 192 into the valid range.
var obj = new ObjectDesc
{
DisplaceX = 12f,
DisplaceY = 12f,
BaseLoc = new Frame { Origin = new Vector3(0, 0, 0) }
};
// Search across a range of global cell coords to find at least one
// case where vertex y=8 displaces into [0, 192).
bool foundValid = false;
for (uint gx = 0; gx < 64 && !foundValid; gx++)
{
for (uint gy = 0; gy < 64 && !foundValid; gy++)
{
var localPos = SceneryGenerator.DisplaceObject(obj, gx, gy, 0);
// Vertex (3, 8): cell corner at (3*24, 8*24) = (72, 192)
float lx = 3 * 24f + localPos.X;
float ly = 8 * 24f + localPos.Y;
if (ly >= 0 && ly < 192f && lx >= 0 && lx < 192f)
foundValid = true;
}
}
Assert.True(foundValid,
"Expected at least one (globalCellX, globalCellY) where vertex y=8 " +
"displaces back into [0, 192) — retail's 9×9 loop relies on this");
}
[Fact]
public void DisplaceObject_InteriorVertex_AlwaysNearOrigin()
{
var obj = new ObjectDesc
{
DisplaceX = 12f,
DisplaceY = 12f,
BaseLoc = new Frame { Origin = new Vector3(0, 0, 0) }
};
// For interior vertices (x < 8, y < 8), displacement is bounded by
// DisplaceX/Y (max 12 units each), so the result stays within one
// cell of the origin.
var localPos = SceneryGenerator.DisplaceObject(obj, 100, 100, 0);
Assert.True(Math.Abs(localPos.X) <= 12f,
$"Interior displacement X={localPos.X} exceeds DisplaceX=12");
Assert.True(Math.Abs(localPos.Y) <= 12f,
$"Interior displacement Y={localPos.Y} exceeds DisplaceY=12");
}
}