// Ported from references/WorldBuilder/Chorizite.OpenGLSDLBackend/Lib/SceneryInstance.cs // Phase A8 extraction (2026-05-28). Verbatim port; adaptations: // - SceneryInstance -> EnvCellSceneryInstance (scope-narrow to env-cell rendering) // - ObjectLandblock -> EnvCellLandblock // - Namespace: AcDream.App.Rendering.Wb // - BoundingBox -> WbBoundingBox (defined in WbFrustum.cs) // - DisqualificationReason + SceneryDisqualificationReason dropped (editor-only) // - IsQueuedForUpload, IsTransformOnlyUpdate, ParticleEmitters, InstanceBufferOffset, // InstanceCount, MdiCommands dropped (editor-only / shared-MDI) using System.Collections.Generic; using System.Numerics; namespace AcDream.App.Rendering.Wb; /// /// Lightweight data for a single placed env-cell scenery object. /// Source: references/WorldBuilder/Chorizite.OpenGLSDLBackend/Lib/SceneryInstance.cs (lines 11-56) /// public struct EnvCellSceneryInstance { /// GfxObj or Setup ID from DAT. public ulong ObjectId; /// Unique instance index within the landblock (WB used a 128-bit editor ID; we use uint). public uint InstanceId; /// True for multi-part Setup objects, false for simple GfxObj. public bool IsSetup; /// True if this instance is a building. public bool IsBuilding; /// True if this is an interior cell connected directly to the landblock. public bool IsEntryCell; /// World-space position. public Vector3 WorldPosition; /// Local-space position (relative to landblock origin). public Vector3 LocalPosition; /// Rotation quaternion. public Quaternion Rotation; /// The current cell ID this instance is in (used for previewing moves between cells). public uint CurrentPreviewCellId; /// Scale (typically uniform). public Vector3 Scale; /// Pre-computed world transform matrix. public Matrix4x4 Transform; /// Local-space bounding box. public WbBoundingBox LocalBoundingBox; /// World-space bounding box. public WbBoundingBox BoundingBox; /// Rendering flags for this instance. public uint Flags; } /// /// Holds all EnvCell instances for a single landblock, ready for rendering. /// Shared by both scenery and static object render managers. /// Source: references/WorldBuilder/Chorizite.OpenGLSDLBackend/Lib/SceneryInstance.cs (lines 62-160) /// public class EnvCellLandblock { /// Grid X coordinate of this landblock. public int GridX { get; set; } /// Grid Y coordinate of this landblock. public int GridY { get; set; } public object Lock { get; } = new(); public List Instances { get; set; } = new(); /// /// Grouped bounding boxes for each EnvCell in this landblock. /// Key: CellID, Value: Composite bounding box of the cell and all its static objects. /// public Dictionary EnvCellBounds { get; set; } = new(); /// /// Set of EnvCell IDs in this landblock that have the SeenOutside flag. /// public HashSet SeenOutsideCells { get; set; } = new(); public List? PendingInstances { get; set; } /// /// Grouped bounding boxes for each EnvCell in this landblock (pending upload). /// public Dictionary? PendingEnvCellBounds { get; set; } /// /// Set of EnvCell IDs in this landblock that have the SeenOutside flag (pending upload). /// public HashSet? PendingSeenOutsideCells { get; set; } /// /// Grouped transforms for each GfxObj part for static objects, for efficient instanced rendering. /// Key: GfxObjId, Value: List of transforms /// public Dictionary> StaticPartGroups { get; set; } = new(); /// /// Grouped transforms for each GfxObj part for buildings, for efficient instanced rendering. /// Key: GfxObjId, Value: List of transforms /// public Dictionary> BuildingPartGroups { get; set; } = new(); /// /// World-space bounding box of this landblock. /// public WbBoundingBox BoundingBox { get; set; } /// /// Total bounding box covering all EnvCells in this landblock. /// public WbBoundingBox TotalEnvCellBounds { get; set; } /// /// Total bounding box covering all EnvCells in this landblock (pending upload). /// public WbBoundingBox PendingTotalEnvCellBounds { get; set; } /// /// Whether instances (positions/bounding boxes) have been generated. /// public bool InstancesReady { get; set; } /// /// Whether mesh data for all instances has been prepared (CPU-side). /// public bool MeshDataReady { get; set; } /// /// Whether GPU resources have been uploaded. /// public bool GpuReady { get; set; } }