// 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; }
}