test(p0): dat-backed conformance loader + characterized cottage-doorway topology
P0 (verbatim-spatial-pipeline-port) Tasks 1+2. ConformanceDats loads the cottage-doorway cells from the real dats with their real ContainmentBsp; CottageDoorwayCharacterizationTests maps the Holtburg 0140..017F indoor neighborhood and pins the master-plan threshold building (origin 161.93,7.50,94.00): 0xA9B40170 vestibule (exit portal 0xFFFF + portal to 0171), 0xA9B40171 room. Grid math confirms the outdoor side is landcell 0xA9B40031 -> the 0031<->0170<->0171 ping-pong is verified real. Verified interior points recorded for the point_in_cell/find_cell_list goldens. Plan: docs/superpowers/plans/2026-06-03-p0-conformance-apparatus.md Notes: docs/research/2026-06-03-p0-conformance-apparatus-notes.md Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
a859116d5f
commit
a90f34368f
4 changed files with 1000 additions and 0 deletions
66
tests/AcDream.Core.Tests/Conformance/ConformanceDats.cs
Normal file
66
tests/AcDream.Core.Tests/Conformance/ConformanceDats.cs
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
using System.Numerics;
|
||||
using AcDream.Core.Physics;
|
||||
using AcDream.Core.World.Cells;
|
||||
using DatReaderWriter;
|
||||
using DatReaderWriter.Options;
|
||||
using DatEnvCell = DatReaderWriter.DBObjs.EnvCell;
|
||||
using DatEnvironment = DatReaderWriter.DBObjs.Environment;
|
||||
using Env = System.Environment;
|
||||
|
||||
namespace AcDream.Core.Tests.Conformance;
|
||||
|
||||
/// <summary>
|
||||
/// P0 conformance apparatus — headless load of the real Holtburg dats.
|
||||
/// Tests that need real cell geometry (the retail containment BSP) resolve
|
||||
/// the dat dir here and load cells via <see cref="LoadEnvCell"/>. Returns
|
||||
/// null dat dir when the dats are absent (CI) so callers can skip cleanly,
|
||||
/// matching DoorBugTrajectoryReplayTests.ResolveDatDir.
|
||||
///
|
||||
/// Mirrors the proven dat-read pattern at
|
||||
/// DoorBugTrajectoryReplayTests.cs:184-219 + EnvCell.FromDat (EnvCell.cs:42-76).
|
||||
/// </summary>
|
||||
public static class ConformanceDats
|
||||
{
|
||||
private const uint EnvironmentFilePrefix = 0x0D000000u; // dat namespace for Environment files
|
||||
|
||||
/// <summary>The Holtburg landblock these fixtures live in.</summary>
|
||||
public const uint HoltburgLandblock = 0xA9B40000u;
|
||||
|
||||
/// <summary>Resolve the client dat directory, or null if unavailable (skip the test).</summary>
|
||||
public static string? ResolveDatDir()
|
||||
{
|
||||
var fromEnv = Env.GetEnvironmentVariable("ACDREAM_DAT_DIR");
|
||||
if (!string.IsNullOrWhiteSpace(fromEnv) && Directory.Exists(fromEnv))
|
||||
return fromEnv;
|
||||
var def = Path.Combine(
|
||||
Env.GetFolderPath(Env.SpecialFolder.UserProfile),
|
||||
"Documents", "Asheron's Call");
|
||||
return Directory.Exists(def) ? def : null;
|
||||
}
|
||||
|
||||
/// <summary>The physics-verbatim cell→world transform (no +2cm render lift).</summary>
|
||||
public static Matrix4x4 WorldTransform(DatEnvCell datCell) =>
|
||||
Matrix4x4.CreateFromQuaternion(datCell.Position.Orientation) *
|
||||
Matrix4x4.CreateTranslation(datCell.Position.Origin);
|
||||
|
||||
/// <summary>
|
||||
/// Load one EnvCell from the dats with its REAL containment BSP, and register
|
||||
/// it into <paramref name="cache"/> as a CellPhysics. Returns the high-level
|
||||
/// EnvCell (PointInCell) so a single load serves both membership predicates.
|
||||
/// </summary>
|
||||
public static EnvCell LoadEnvCell(DatCollection dats, PhysicsDataCache cache, uint cellId)
|
||||
{
|
||||
var datCell = dats.Get<DatEnvCell>(cellId)
|
||||
?? throw new InvalidOperationException($"EnvCell 0x{cellId:X8} not found in dats");
|
||||
var environment = dats.Get<DatEnvironment>(EnvironmentFilePrefix | datCell.EnvironmentId)
|
||||
?? throw new InvalidOperationException($"Environment 0x{datCell.EnvironmentId:X8} not found");
|
||||
if (!environment.Cells.TryGetValue(datCell.CellStructure, out var cellStruct) || cellStruct is null)
|
||||
throw new InvalidOperationException($"CellStruct {datCell.CellStructure} missing from environment");
|
||||
|
||||
var world = WorldTransform(datCell);
|
||||
cache.CacheCellStruct(cellId, datCell, cellStruct, world); // physics CellPhysics (real CellBSP)
|
||||
return EnvCell.FromDat(cellId, datCell, cellStruct, world); // render/containment EnvCell (real ContainmentBsp)
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue