feat(render) Campaign FW1: street fixture retail-exact except flood depth
Three pinned corrections close the outdoor frame: (1) the camera basis RE-pinned to +Y-forward - the terrace-edge fixture EXTERNAL ground truth (the ledge faces the F518 vista, east) overrules the walkabout motion sweep, whose camera was mouse-turned off the run line; (2) alwaysDrawObjects (.data default 1 @0x00820ed4) drawn into the DrawSortCell gate - cell contents draw for every cell of an in-view block; (3) the building portal side decode data-pinned as the INVERSE of the cell 0x2 bit (the sweep winning arm). Street result: all 13 buildings in retail exact order (a9b3003c in, aab50002 correctly absent), punches at exactly 001a and 0022 opening the exact first cells 16e/164. SOLE remaining delta: look-in flood depth (mine 1 cell, retail 3-4) - the doorway-still fixture adjudicates the interior flood in isolation next. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
5f18ba5507
commit
28475d0544
4 changed files with 30 additions and 19 deletions
|
|
@ -50,6 +50,11 @@ public sealed class RetailFrameWalk
|
|||
public WalkPView InteriorPView => _interiorPView;
|
||||
public WalkPView OutdoorPView => _outdoorPView;
|
||||
|
||||
/// <summary>Retail global <c>alwaysDrawObjects</c> (.data default 1
|
||||
/// @0x00820ed4): cell contents draw for every cell of an in-view block
|
||||
/// regardless of per-cell visibility.</summary>
|
||||
public bool AlwaysDrawObjects = true;
|
||||
|
||||
/// <summary>The per-frame root (<c>SmartBox::RenderNormalMode</c>).
|
||||
/// <paramref name="cameraCell"/> may be null only when the camera is
|
||||
/// outdoors.</summary>
|
||||
|
|
@ -115,10 +120,15 @@ public sealed class RetailFrameWalk
|
|||
for (int k = 0; k < cellCount; k++)
|
||||
{
|
||||
int cellIndex = block.DrawArray[k];
|
||||
// DrawSortCell runs for in-view cells (alwaysDrawObjects
|
||||
// default 0); terrain (DrawLandCell) emits no walk event.
|
||||
if (block.CellInView[cellIndex] == WalkBoundingType.Outside)
|
||||
// RenderDeviceD3D::DrawBlock @0x005a19d9: DrawSortCell runs
|
||||
// when alwaysDrawObjects != 0 (retail .data default 1
|
||||
// @0x00820ed4) OR the cell IsInView; terrain (DrawLandCell)
|
||||
// emits no walk event.
|
||||
if (!AlwaysDrawObjects
|
||||
&& block.CellInView[cellIndex] == WalkBoundingType.Outside)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (block.CellBuildings[cellIndex] is WalkBuilding building)
|
||||
DrawBuilding(building, activeViews, ctx, sink);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,14 +24,11 @@ public sealed class WalkLookInGateSweepTests
|
|||
public void Emit(in WalkEvent walkEvent) => Events.Add(walkEvent);
|
||||
}
|
||||
|
||||
[Fact(Skip = "FW1 adjudication driver (2026-08-30 final state): with the "
|
||||
+ "exact get_degrade rule (slack 100, ideal thresholds, sort-center "
|
||||
+ "distance) the level-0 set is correct — the residual divergence is "
|
||||
+ "the per-portal side/clip gate: my arms punch {0017,001e,0026,0036}, "
|
||||
+ "retail punched exactly {001a,0022} — a near-complement suggesting "
|
||||
+ "one more polarity at the building-portal gate. Next instrument: "
|
||||
+ "per-portal dump for 001a (retail punches) vs 001e (retail doesn't): "
|
||||
+ "side values, plane orientation, eye side, clip result per arm.")]
|
||||
[Fact(Skip = "FW1 near-win state (2026-08-30): with +Y-forward, alwaysDrawObjects, "
|
||||
+ "the exact degrade rule and side mode 1, the street fixture matches retail "
|
||||
+ "EXCEPT look-in flood depth (mine D[16e]/D[164]; retail D[16e,16a,16c]/"
|
||||
+ "D[164,162,167,169]) - adjudicate the interior flood propagation next "
|
||||
+ "(the doorway-still fixture tests it in isolation).")]
|
||||
public void Sweep_the_lookin_gate_decodes_against_the_street_fixture()
|
||||
{
|
||||
string? datDir = CornerFloodReplayTests.ResolveDatDir();
|
||||
|
|
|
|||
|
|
@ -53,14 +53,16 @@ public sealed class WalkTraceReplayContext : IWalkFrameContext, IRetailFrameWalk
|
|||
_cells = cells;
|
||||
WorldViewpoint = pose.Origin;
|
||||
var rotation = new Quaternion(pose.Q1, pose.Q2, pose.Q3, pose.Q0);
|
||||
// Convention pinned against the moving fixtures (2026-08-30 sweep:
|
||||
// storage w,x,y,z; the facing direction is the rotated +X axis —
|
||||
// mean 20.8° vs motion headings, every alternative ≥52°). The
|
||||
// consistent right-handed triple is then right = −rot(+Y),
|
||||
// forward = rot(+X), up = rot(+Z).
|
||||
Vector3 forward = Vector3.Transform(Vector3.UnitX, rotation);
|
||||
// Basis convention RE-pinned 2026-08-30 (second pass): storage
|
||||
// w,x,y,z; forward = rotated +Y — the retail Frame convention. The
|
||||
// motion sweep briefly favored +X, but the walkabout camera was
|
||||
// mouse-turned off the run direction; the terrace-edge fixture's
|
||||
// EXTERNAL ground truth (the ledge faces the F518 vista, east)
|
||||
// decodes east ONLY under +Y-forward, and +Y makes the street
|
||||
// fixture's punch on/off-screen pattern match retail 4-for-4.
|
||||
Vector3 forward = Vector3.Transform(Vector3.UnitY, rotation);
|
||||
Vector3 up = Vector3.Transform(Vector3.UnitZ, rotation);
|
||||
Vector3 right = -Vector3.Transform(Vector3.UnitY, rotation);
|
||||
Vector3 right = Vector3.Transform(Vector3.UnitX, rotation);
|
||||
|
||||
// The exact retail frustum: tan(halfFovY) = ty/vdst, aspect = tx/ty.
|
||||
float fovY = 2f * MathF.Atan(RetailTy / RetailVdst);
|
||||
|
|
|
|||
|
|
@ -242,7 +242,9 @@ public static class WalkWorldDatAdapter
|
|||
/// <summary>Adjudication toggle: the BuildingPortal side-flag decode.
|
||||
/// 0 = (Flags & 0x2), 1 = inverted 0x2, 2 = (Flags & 0x1),
|
||||
/// 3 = inverted 0x1.</summary>
|
||||
public static int BuildingSideMode;
|
||||
public static int BuildingSideMode = 1; // data-pinned 2026-08-30: building
|
||||
// portal_side = the INVERSE of the cell decode's 0x2 bit (the sweep's
|
||||
// winning arm - punches land at retail's exact buildings/cells with it).
|
||||
|
||||
private static int DecodeBuildingSide(ushort flags) => BuildingSideMode switch
|
||||
{
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue