feat(core): S1 one CellStruct interpretation, installed-DAT scan, retire AP-234

Campaign OVERHAUL S1 chunk B.

- CellMesh.Build's render role is deleted; CellMesh.HasDrawableGeometry
  is the exact predicate (any sides_type candidate whose resolved surface
  passes the built-EnvCell (Surface.Type & 6) != 0 test), and the
  streaming build job consumes it. Core and Content no longer carry two
  CellStruct interpretations.
- Installed-DAT scan over the complete Environment corpus (5,346
  landblocks, 729,888 cells, 8,601,560 polygons, 8,608,746 candidates):
  3,197 old-rule admissions were untextured surfaces the NoPos proxy let
  through; zero new-only; zero unexplained; zero unknown sides values;
  counts pinned as goldens against the contract's DAT hashes.
- Canonical pins: 0xF4180104 has eight ST_DOUBLE clip-map polygons and 44
  drawable side calls; the canonical NoPos surfaces are type 0x11 and are
  constructed but skipped; two independent extractions of all ten
  canonical cells hash identically.
- AP-234 retired from the divergence register (161 active rows) with
  ConstructMesh 0x0059DFA0 / DrawEnvCell 0x0059F170 / DrawMesh 0x0059D4A0.
- StipplingSurfaceEquivalenceTests no longer claims a build-time NoPos
  skip; the cell half is report-only, the building half stays pinned.
- Inventory and policy remarks updated; plan ledger records chunk A and
  the capture kit.

Core Meshing+Conformance 95/95, Content 208/208 (Lane!=Timing,
Lane!=PreparedPackage), App EnvCell/LandblockBuild/Streaming 432/432,
Release solution build 0 warnings / 0 errors.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
Erik 2026-09-02 19:11:17 +02:00
parent acf172469e
commit b681717c30
9 changed files with 631 additions and 154 deletions

View file

@ -416,6 +416,32 @@ heap. Deterministic pressure tests exceed every configured ceiling and prove
zero-charge teardown. Connected evidence:
`docs/research/2026-07-24-slice-d-unified-residency-report.md`.
**OH2/S1 exact CellStruct surface-index construction (2026-09-02).** Bake
recipe 8 replaces `MeshExtractor.PrepareCellStructMeshData`'s NoPos-based
approximation with retail's exact `D3DPolyRender::ConstructMesh` (`0x0059DFA0`)
side/candidate table: side candidates come only from `CPolygon::sides_type`
(`AcDream.Core.Meshing.CellStructSideCandidates`); `NoPos`/`NoNeg` mean "this
side's UV-index array is absent" only (`CPolygon::UnPack` `0x00538650`), never
face suppression. The subset/material owner is the source surface-array
index, not the resolved Surface DID or texture format:
`TextureBatchData.SourceSurfaceIndex`/`RetailSurfaceMask`/`RawSurfaceType`/
`IsCellShell` carry that fact through the prepared package, and
`CellSurfaceSubsets.InAscendingSurfaceOrder` recovers the retail subset walk
order independent of the (Width,Height,Format) storage grouping the package
still uses for atlas dedup. Built-EnvCell draw admission is
`(Surface.Type & (BASE1_IMAGE|BASE1_CLIPMAP)) != 0`
(`RenderDeviceD3D::DrawEnvCell` `0x0059F170`
`D3DPolyRender::DrawMesh(..., arg4=1)` `0x0059D4A0`), applied after surface
resolution via `RetailUntexturedSurfacePolicy.IsUntextured`, not approximated
before it. `CellMesh.Build`'s render-production role is retired; the
streaming build job now calls `CellMesh.HasDrawableGeometry` — the identical
exact admission rule, evaluated as a predicate only, with no mesh retained —
to decide whether a CellStruct contributes drawable geometry. Fixed retail
`D3DCULL_CW` (`RenderMeshSubset` `0x0059CA10`) remains the raster cull for
every constructed cell-shell subset after fan expansion; the authored
`sides_type` is not read as GPU cull state. Retires AP-234. Contract:
`docs/research/2026-09-01-overhaul/oh2-cellstruct-surface-contract.md`.
**Workflow:** Before re-implementing any AC-specific rendering or dat-handling
algorithm, **check this inventory first**. If we already extracted it (🟢
sections), it's in `src/AcDream.App/Rendering/Wb/` — use our copy. If WB has