checkpoint(render): preserve pre-overhaul investigation state

This commit is contained in:
Erik 2026-09-01 18:04:24 +02:00
parent e880860291
commit b3b7d922f1
45 changed files with 3168 additions and 619 deletions

View file

@ -161,6 +161,58 @@ launcher-confirmed full rebuilds with beside-active validation and atomic
promotion; overlays never cross a format boundary. Design and evidence:
`docs/plans/2026-08-27-pak-v2-resource-campaign.md`.
**Retail GfxObj view-sphere correction (2026-08-31).** Bake recipe 7
regenerates prepared GfxObj render records so their portal-view admission
uses the authored DrawingBSP root sphere retained by retail
`CGfxObj::Serialize`, rather than a sphere synthesized from the extracted
vertex AABB. The binary package format remains 2. Because this field affects
every GfxObj and the old records cannot be corrected without their source
DrawingBSP, migration 6→7 is an explicit full rebuild.
The production leaf follows retail `RenderDeviceD3D::DrawMesh` /
`DrawMeshInternal`: portal viewcones perform coarse authored-sphere
admission, but an admitted GfxObj is submitted once as a complete mesh.
Likewise `PView::DrawCells` calls `DrawEnvCell` once per admitted cell and
draws its complete constructed shell. Portal polygons are not GPU mesh clips;
pixel occlusion comes from the ordered walk and depth buffer.
**Retail static render-shadow cell membership (2026-08-31).** Indoor
statics are not rendered solely from their authored parent EnvCell. Retail's
`CEnvCell::init_static_objects` creates a `CPhysicsObj` for every static,
then `calc_cross_cells_static` + `CPartArray::AddPartsShadow` places every
visual part in each crossed cell's `shadow_part_list`, including decorative
GfxObjs that have no collision BSP. `WalkProductionWorldData` therefore owns
a distinct render-only per-cell index built from each MeshRef's prepared
visual AABB and the existing exact static part transit walk. This must not be
collapsed into `ShadowObjectRegistry`'s collision rows: the two retail lists
share transit math but have different membership. A primitive-only Setup may
reuse its already-authored cylsphere collision cell set; BSP-bearing and
pure-visual statics use the all-visual-part box walk. The Facility Hub stair
Setup `0x02000623` is the installed-DAT regression: its authored parent is
`0x8A02015F`, while its visual parts also register in `0x8A02015E` and the
adjoining vertical cells.
Moving multipart objects follow the sibling retail route rather than their
authored/feet cell alone: `CPhysicsObj::add_shadows_to_cells` installs every
`CPartArray` part in every cell of the object's retained `CELLARRAY`, and
`CPhysicsPart::Draw` stamps each part only after that part passes a cell's
portal test. `WalkProductionWorldData` therefore buckets live projections by
all `ShadowObjectRegistry.GetOwnerCells` rows, while the walk classifier owns
a projection+part drawn-pass stamp. Retail advances that stamp after
`LScape::draw` + `FlushAlphaList` and before the interior depth clear
(`PView::DrawCells` @0x005A4886), so a part may draw once in the landscape
pass and once again in the post-clear interior-cell pass; acdream re-arms the
classifier at that exact walk boundary. `add_shadows_to_cells` recursively
passes the root's same `CELLARRAY` to every attached child, so equipped-child render
projections resolve their accepted parent chain to the root's owner cells;
they do not fall back to one authored cell. Never replace the per-part stamp
with a whole-projection drawn-once gate: at a stair portal the torso may pass
in the first cell while head/hair fails and must retry through another crossed
cell. One binding exception is the local player: retail
`RenderDeviceD3D::DrawMeshInternal` bypasses `Get/SetDrawnThisFrame` when
`CPhysicsPart::IsPartOfPlayerObj` is true, repainting the player's parts at
every crossed-cell turn so later wall/depth ordering remains correct.
**Slice I3 prepared collision extension (2026-07-25).** At its introduction,
the package remained format 1 and retained mesh type values 13; bake-tool 4
appended typed GfxObj,