using System.Collections.Generic; using System.Numerics; namespace AcDream.App.Rendering.Wb; /// /// Phase A8 (2026-05-26): a logical building — one or more EnvCells linked /// via the dat-level LandBlockInfo.Buildings entry. Building shells (cottage /// walls, inn walls — IsBuildingShell=true entities) render unconditionally /// when the camera is inside this building's cells. The exit portal polygons /// are stencil-marked so outdoor visibility leaks through portal silhouettes /// only. /// /// Step 5 (cross-building visibility via 3-stencil-bit pipeline) uses /// the occlusion-query state to skip rendering when the building's portals /// weren't visible last frame. /// /// WB reference: WorldBuilder.Shared/Services/PortalService.cs /// (BuildingPortalGroup) and PortalRenderManager.cs step-5 lifecycle. /// Retail reference: docs/research/named-retail/acclient.h:32035 /// (BuildInfo) + 32094 (CBldPortal). /// public sealed class Building { /// Unique within a landblock; allocated sequentially by /// starting at 1 (0 is reserved for "no building" semantics on LoadedCell). public required uint BuildingId { get; init; } /// The EnvCells this building owns. Includes all cells reachable /// from the building's entry portals via interior portals (no exit portals). /// Populated by via BFS over /// . public required HashSet EnvCellIds { get; init; } /// Exit portal polygons in world space (each polygon is a triangle /// fan from vertex 0). Stencil-marked + far-depth-punched at Steps 1+2 of /// WB's RenderInsideOut pipeline (RR7). Collected during /// Step C by transforming cell-local portal /// polygon vertices via . public required IReadOnlyList ExitPortalPolygons { get; init; } // ------------------------------------------------------------------------- // Step 5 occlusion-query state (mutable, per-frame, RR9 scope). // ------------------------------------------------------------------------- /// GL query object handle; lazily created on first use by the /// Step 5 occlusion-query pass (RR9). 0 = not yet created. public uint QueryId; /// True after the first BeginQuery call; controls whether the /// read-back path is safe to execute on the next frame. public bool QueryStarted; /// Previous-frame query result. When false, the building's interior /// render is skipped (Step 5 early-out in RR9 + RR11). public bool WasVisible; }