acdream/src/AcDream.Core/World/WbSceneryAdapter.cs
Erik 16bc10c99d feat(O-T2): extract pure stateless helpers to AcDream.Core.Rendering.Wb
Verbatim copy of 5 WorldBuilder files into src/AcDream.Core/Rendering/Wb/:
- TextureHelpers.cs (pixel-format decoders, Chorizite Lib)
- SceneryHelpers.cs (scenery transforms, Chorizite Lib)
- TerrainUtils.cs, TerrainEntry.cs, CellSplitDirection.cs (WB.Shared Landscape)

Namespace migrated from WorldBuilder.* / Chorizite.OpenGLSDLBackend.Lib
to AcDream.Core.Rendering.Wb per O-D11. [MemoryPackable] stripped from
TerrainEntry per O-D10 (we don't serialize the struct).

Updated 3 source files + 1 test file to import from the new namespace.

Verbatim discipline (O-D1): only namespace + MemoryPack attribute changed.
All algorithm bodies byte-identical to upstream.

Note: TextureHelpers omits IsAlphaFormat() and GetCompressedLayerSize()
because those reference Chorizite.Core.Render.Enums.TextureFormat, a type
that has no path into AcDream.Core without adding an unwanted NuGet dep.
Neither method is called from Core or the test suite; the omission is safe.

Verified on main checkout: dotnet build green (0 errors), dotnet test
green — Failed: 8, Passed: 1147, Skipped: 0, Total: 1155 (baseline maintained).
TextureDecodeConformanceTests (9/9) pass byte-for-byte after namespace swap.
AcDream.Core project alone builds green in this worktree (App-layer failures
are pre-existing, blocked by empty WB submodule, addressed in Tasks 3+4).

Spec: docs/superpowers/specs/2026-05-21-phase-o-dat-path-unification-design.md

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-21 15:13:26 +02:00

55 lines
2.3 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using AcDream.Core.Rendering.Wb;
using DatReaderWriter.DBObjs;
namespace AcDream.Core.World;
/// <summary>
/// Bridges acdream's dat types into WorldBuilder's data shapes for the
/// Phase N rendering migration. See
/// <c>docs/architecture/worldbuilder-inventory.md</c> for the full strategy.
/// </summary>
internal static class WbSceneryAdapter
{
private const int VerticesPerSide = 9;
private const int TerrainSize = VerticesPerSide * VerticesPerSide; // 81
/// <summary>
/// Builds a 9×9 = 81-entry <see cref="TerrainEntry"/> array from a
/// <see cref="LandBlock"/>'s packed terrain bits + height bytes. WB's
/// <c>TerrainUtils.OnRoad</c> / <c>GetNormal</c> / <c>GetHeight</c>
/// consume this shape.
///
/// Field mapping (<c>TerrainInfo</c> → <see cref="TerrainEntry"/>):
/// <c>TerrainInfo.Road</c> (bits 0-1) → <see cref="TerrainEntry.Road"/>
/// <c>TerrainInfo.Type</c> (bits 2-6) → <see cref="TerrainEntry.Type"/>
/// <c>TerrainInfo.Scenery</c> (bits 11-15) → <see cref="TerrainEntry.Scenery"/>
/// <c>LandBlock.Height[i]</c> → <see cref="TerrainEntry.Height"/>
/// </summary>
/// <remarks>
/// No runtime length guards are needed here because
/// <c>DatReaderWriter.DBObjs.LandBlock</c>'s default constructor
/// self-initializes both <c>Terrain</c> and <c>Height</c> to fixed-length
/// arrays of exactly 81 elements (9×9 vertices per landblock). Any caller
/// that constructs a synthetic <see cref="LandBlock"/> with partial arrays
/// will receive an <see cref="IndexOutOfRangeException"/> at the first
/// mis-sized index, which is the correct fast-fail behaviour for a
/// contract violation of this kind.
/// </remarks>
public static TerrainEntry[] BuildTerrainEntries(LandBlock block)
{
ArgumentNullException.ThrowIfNull(block);
var entries = new TerrainEntry[TerrainSize];
for (int i = 0; i < TerrainSize; i++)
{
var ti = block.Terrain[i];
entries[i] = new TerrainEntry(
height: block.Height[i],
texture: (byte)ti.Type,
scenery: ti.Scenery,
road: ti.Road,
encounters: null);
}
return entries;
}
}