using System; using System.Numerics; namespace AcDream.Core.Lighting; /// /// Retail light-source kinds (r13 §12.1). /// public enum LightKind { Directional = 0, // sun, moon — no position, infinite range Point = 1, // torch, fireplace, spell aura Spot = 2, // cone-shaped (rare in AC, used for a few specific lamps) } /// /// Per-frame light record. Used by and fed to /// the shader UBO on every draw call. /// /// /// Retail semantics (r13 §10.2): /// /// /// Hard cutoff at — no smoothstep, no distance /// attenuation inside the range. "Crisp bubble of illumination." /// /// /// Max 8 active lights (), /// ranked by distance-to-viewer. Slot 0 is reserved for the sun. /// /// /// latches the SetLightHook value so /// animations can toggle a light on/off (torch being lit, light /// crystal activating). /// /// /// /// public sealed class LightSource { public LightKind Kind; public Vector3 WorldPosition; public Vector3 WorldForward; // for Spot/Directional public Vector3 ColorLinear = Vector3.One; // R,G,B in [0,1], pre-brightness public float Intensity = 1f; public float Range = 10f; // metres, hard cutoff public float ConeAngle = 0f; // radians, Spot only public uint OwnerId; // attached entity id; 0 = world-global public uint CellId; // owning cell id (0xLLLLNNNN); 0 = cell-less/global (viewer fill, sun). // Retail carries this on the RenderLight (insert_light arg6, +0x6c) for the // cross-cell block-offset distance math. #176 correction (2026-07-06): it is // NOT a pool filter — retail collects from ALL resident cells // (CEnvCell::visible_cell_table = the loaded-cell registry, not the flood); // acdream keeps the tag for probes ([indoor-light]/[seam-*]) + future parity. public bool IsLit = true; // SetLightHook latch public bool IsDynamic; // #143: true = D3D hardware path (1/d att, range×1.5); // false = static dat-baked bake (1/d³, range×1.3) // Cached each frame by LightManager. public float DistSq; } /// /// Per-cell ambient + sun state. For outdoor cells this comes from the /// R12 sky state; for indoor cells the EnvCell dat carries a per-cell /// ambient override (r13 §3). /// public readonly record struct CellAmbientState( Vector3 AmbientColor, Vector3 SunColor, Vector3 SunDirection);