diff --git a/src/AcDream.Core/World/Cells/CellGraph.cs b/src/AcDream.Core/World/Cells/CellGraph.cs index 8f19e59..3f97bd5 100644 --- a/src/AcDream.Core/World/Cells/CellGraph.cs +++ b/src/AcDream.Core/World/Cells/CellGraph.cs @@ -55,4 +55,24 @@ public sealed class CellGraph /// reserved for the OtherCellPtr neighbor cache (Stage 3); the lookup keys only on the portal. /// public ObjCell? Neighbor(ObjCell cell, in CellPortal portal) => GetVisible(portal.OtherCellId); + + /// + /// Retail CEnvCell::find_visible_child_cell @ 0x0052dc50 (pseudo_c:311397). + /// Walk 's StabList + the root itself, return the first + /// EnvCell whose is true for + /// . Used to resolve the camera cell in 3rd-person + /// from the physics cell graph rather than an independent AABB reclassification — + /// the root is the player cell, never a camera-eye AABB scan. + /// Returns null when no cell in the root's stab list (or the root itself) contains + /// the query point (caller falls back to the player cell as projection root). + /// + public EnvCell? FindVisibleChildCell(uint rootId, Vector3 worldPoint) + { + if (!_envCells.TryGetValue(rootId, out var root)) return null; + if (root.PointInCell(worldPoint)) return root; + foreach (var stabId in root.StabList) + if (_envCells.TryGetValue(stabId, out var stab) && stab.PointInCell(worldPoint)) + return stab; + return null; + } }