Campaign OVERHAUL S2 chunk 1 (Core half). ShadowObjectRegistry accepts the
object's whole visual part array as an optional registration input and
computes retail's CELLARRAY from it as a retained side product:
- route per CPhysicsObj::calc_cross_cells_static @0x00515160: cylsphere
(CObjCell::find_cell_list @0x0052b9f0 over the Setup's authored
cylspheres, carried as the Cylinder shapes of the COLLISION dispatch) when
(state & 0x10000) == 0 and a cylsphere exists, else the bbox route
(find_bbox_cell_list @0x00510fc0 via CellTransit.BuildShadowCellSetFromParts
over every visual part: physics sphere else drawing sphere, part box);
- per-cell part entries in array-then-part order for every part
(CPartArray::AddPartsShadow @0x00517e40), clip planes required iff the
array has more than one cell;
- Deregister clears everything (remove_shadows_from_cells @0x00511230);
UpdatePosition/CommitSetPosition recompute; ReplaceMultiPartPayload swaps
the part array without re-flooding.
_entityToCells and _cells are untouched; no production caller passes the
part array yet (chunk 1b), so this is a zero-behavior change. The lead
corrected the implementer's route decision, which had inspected the visual
part array for cylinders; retail's GetNumCylsphere reads Setup collision
data. Core Physics 2,202/2,202.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>