feat(physics): S2 chunk 3 - one flood per registration feeds collision rows and render entries
ShadowObjectRegistry computes the CELLARRAY once per registration under Contract A (cylsphere route from the Setup's collision cylspheres, else the bbox route over the whole visual part array) and derives BOTH products from it: the collision rows (_entityToCells/_cells, CShadowObj per cell via add_shadows_to_cells @0x00514ae0) and the per-part render entries (AddPartsShadow @0x00517e40). The second, independent collision flood is gone. A caller that supplies no part array floods from its collision shapes exactly as before, so every legacy expectation holds byte-for-byte. The staged SetPosition pipeline now carries the retail part array, cell array, route, and entries through TryCaptureOwnerState/InstallOwnerState and publishes them beside the collision cell replacements, honoring the keep-when-empty rule (SetPositionInternal num_cells gate, pc:283540) for both products together; two new tests pin a cross-cell move and the keep-when-empty case. Behavior change, retail-exact: an object with decorative non-BSP parts now has its collision shapes registered in every cell those parts reach (pinned by a two-cell fixture); all-BSP objects are unchanged. Movement paths still take collision cells from the transition and recompute the retail product separately; chunk 4 unifies them on the transition's array as retail does. No particle emitter reaches this registry. Gates (implementer's isolated worktree at identical content): Release build 0/0; Core 4,961/4,961; App hermetic 6,760/6,760; collision/InstalledDat fixtures 63/63; Runtime 1,884/1,884; Content 213/213. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
parent
d79058cec4
commit
afbd241016
4 changed files with 665 additions and 85 deletions
|
|
@ -177,27 +177,35 @@ 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; ownership moved
|
||||
to `ShadowObjectRegistry` by Campaign OVERHAUL S2 chunk 2).** 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. `ShadowObjectRegistry` owns this product
|
||||
as a retained per-entity retail CELLARRAY (`TryGetRetailCellArray`) plus
|
||||
per-cell part entries (`GetRetailPartEntriesInCell`), computed once at the
|
||||
SAME registration transaction as the collision flood
|
||||
(`RegisterMultiPart`/`Register`'s optional `partArray:` parameter) — not
|
||||
rebuilt per frame. `WalkProductionWorldData`'s indoor and outdoor static
|
||||
sweeps BORROW that array whole per record; they no longer recompute
|
||||
membership from each MeshRef's prepared visual AABB (the deleted
|
||||
`ResolveStaticRenderCells` / `ShadowObjectRegistry.ComputeStaticRenderCells`
|
||||
pair). The retail CELLARRAY remains distinct from `ShadowObjectRegistry`'s
|
||||
own collision rows (`GetOwnerCells`/`_entityToCells`) — the two retail lists
|
||||
share transit math but have different membership (collision cutover to the
|
||||
same CELLARRAY is S2 chunk 3) — until then, a record whose registry entry has
|
||||
no retail array yet (a streaming-window race between the static-projection
|
||||
journal and the physics publisher) falls back to its authored parent cell
|
||||
alone, counted by `WalkProductionWorldData.UnregisteredStaticRenderFallbackCount`.
|
||||
to `ShadowObjectRegistry` by Campaign OVERHAUL S2 chunk 2; collision cutover
|
||||
by S2 chunk 3, 2026-09-02).** 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 —
|
||||
one CELLARRAY flood feeds BOTH the collision `shadow_object_list` and the
|
||||
render `shadow_part_list` (Contract B). `ShadowObjectRegistry` now mirrors
|
||||
this exactly: `RegisterMultiPart`/`Register`'s optional `partArray:`
|
||||
parameter, when supplied (every production call site since chunk 1b), drives
|
||||
ONE Contract A flood (`ComputeContractACellArray`) whose result becomes BOTH
|
||||
`GetOwnerCells`/`_entityToCells`/`_cells` (collision) and the retained
|
||||
per-entity retail CELLARRAY (`TryGetRetailCellArray`) plus per-cell part
|
||||
entries (`GetRetailPartEntriesInCell`) — not two independent floods, and not
|
||||
rebuilt per frame. A caller that supplies no part array (only test/legacy
|
||||
call sites remain) keeps the pre-chunk-3 collision-only dispatch untouched.
|
||||
`WalkProductionWorldData`'s indoor and outdoor static sweeps BORROW the
|
||||
retail array whole per record; they no longer recompute membership from each
|
||||
MeshRef's prepared visual AABB (the deleted `ResolveStaticRenderCells` /
|
||||
`ShadowObjectRegistry.ComputeStaticRenderCells` pair). A structural
|
||||
consequence: an object mixing a colliding BSP part with a decorative
|
||||
non-BSP part now gets a collision row for its BSP part in every cell the
|
||||
combined CELLARRAY reaches, including cells the BSP part alone would not
|
||||
have crossed — membership is decided by the whole-part-array flood, not per
|
||||
part; the BSP polygon test still decides actual contact at query time. A
|
||||
record whose registry entry has no retail array yet (a streaming-window race
|
||||
between the static-projection journal and the physics publisher) falls back
|
||||
to its authored parent cell alone, counted by
|
||||
`WalkProductionWorldData.UnregisteredStaticRenderFallbackCount`.
|
||||
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
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue