68 lines
3.1 KiB
Markdown
68 lines
3.1 KiB
Markdown
# Issue #178 — retail EnvCell shell culling (2026-08-28)
|
|
|
|
## Outcome
|
|
|
|
The Phase A8 `CullMode.Landblock -> CullMode.None` workaround is removed
|
|
from both production EnvCell draw paths. Constructed cell-shell batches now
|
|
use retail's clockwise cull state instead of drawing every ordinary shell
|
|
face twice. No PAK rebuild is required: the package already contains the
|
|
authored `sides_type` and the correctly expanded index geometry; this change
|
|
selects the correct GPU state when that geometry is drawn.
|
|
|
|
The source and installed-DAT gates are complete. The owner visual gate passed
|
|
2026-08-28 (“Ok looks good”) at the requested interior matrix; #178 is closed.
|
|
|
|
## Retail oracle
|
|
|
|
The misleading detail is that `DatReaderWriter.Enums.CullMode` is used for
|
|
the CellStruct polygon's `sides_type`; its values are not direct GPU cull
|
|
states.
|
|
|
|
- `D3DPolyRender::ConstructMesh @ 0x0059DFA0` expands `sides_type` 0 as the
|
|
positive face, type 1 as that face plus a reversed copy, and type 2 as the
|
|
positive and negative surfaces. Its polygon fan is `[0, i-1, i]`; the
|
|
reversed copy is `[i, i-1, 0]`.
|
|
- `D3DPolyRender::RenderMeshSubset @ 0x0059CA10` draws the constructed mesh
|
|
with `D3DCULL_CW` on the ordinary path.
|
|
- `RenderDeviceD3D::DrawEnvCell @ 0x0059F170` uses that constructed-mesh
|
|
route. The immediate-mode exception for a type-1 polygon does not apply to
|
|
the EnvCell mesh.
|
|
|
|
`MeshExtractor.PrepareCellStructMeshData` already reproduces retail's fan and
|
|
the required reversed geometry. The render policy therefore must be
|
|
clockwise culling for every constructed shell batch; mapping DAT value 0 to
|
|
`None` was the obsolete workaround, while mapping it to the generic
|
|
`Landblock` render state would cull the opposite side.
|
|
|
|
## Installed-DAT catalog
|
|
|
|
`A8CellAudit cell-winding-catalog` scanned the installed DATs:
|
|
|
|
- 772 environments and 3,168 CellStructs
|
|
- 38,189 polygons and 70,091 generated fan triangles
|
|
- 37,843 `Landblock(0)` polygons and 346 `None(1)` polygons
|
|
- no unknown or unsupported `sides_type` values
|
|
- no missing polygon vertices
|
|
|
|
Vertex-normal orientation was recorded as a diagnostic, not treated as a
|
|
contract: CellStruct vertex normals may be smoothed rather than geometric,
|
|
and retail submits the identical authored fan.
|
|
|
|
## Implementation and gates
|
|
|
|
- `EnvCellRenderer.ResolveRetailCellShellCullMode` documents and enforces the
|
|
constructed-mesh policy in both the main and shadow-receiver draw paths.
|
|
- Hermetic extraction tests pin the exact type-0 fan and type-1 reversed-face
|
|
expansion.
|
|
- Renderer tests pin all four source enum values to the retail clockwise
|
|
constructed-mesh state.
|
|
- Installed-DAT audit: passed.
|
|
- Canonical Release gate: 16,321 passed, 0 skipped, 0 failed across 14 test
|
|
assemblies; Release build completed with 0 warnings and 0 errors.
|
|
|
|
## Owner visual acceptance
|
|
|
|
In Holtburg buildings and the Facility Hub, rotate the camera through walls,
|
|
floors, ceilings, ramps, and stairs from their ordinary playable sides.
|
|
Nothing should vanish at any camera angle. Acceptance of that matrix closes
|
|
#178. The owner accepted this matrix on 2026-08-28 (“Ok looks good”).
|