diff --git a/src/AcDream.Core/Rendering/RenderingDiagnostics.cs b/src/AcDream.Core/Rendering/RenderingDiagnostics.cs new file mode 100644 index 0000000..ff0a32f --- /dev/null +++ b/src/AcDream.Core/Rendering/RenderingDiagnostics.cs @@ -0,0 +1,109 @@ +using System; + +namespace AcDream.Core.Rendering; + +/// +/// 2026-05-19 — runtime-toggleable diagnostic flags for the indoor cell +/// rendering pipeline. Initialized from env vars at process start; +/// flippable at runtime via the DebugPanel mirror. Log call sites read +/// these statics so a checkbox toggle takes effect on the next frame +/// without relaunching. +/// +/// +/// Mirrors the L.2a +/// pattern. The master toggle is the user's +/// common case — flipping it cascades to all five probe flags. +/// +/// +/// +/// Spec: docs/superpowers/specs/2026-05-19-indoor-cell-rendering-fix-design.md. +/// +/// +public static class RenderingDiagnostics +{ + /// + /// When true, WbDrawDispatcher.WalkVisibleEntities emits one + /// [indoor-walk] line per visible cell entity per second: + /// entity id, world position, parent cell id, landblock visible flag, + /// AABB-visible flag, "in visible cells" flag, drew flag. + /// Initial state from ACDREAM_PROBE_INDOOR_WALK=1. + /// + public static bool ProbeIndoorWalkEnabled { get; set; } = + Environment.GetEnvironmentVariable("ACDREAM_PROBE_INDOOR_WALK") == "1" + || Environment.GetEnvironmentVariable("ACDREAM_PROBE_INDOOR_ALL") == "1"; + + /// + /// When true, WbDrawDispatcher emits one [indoor-lookup] + /// line per visible cell entity per second: render-data hit/miss, + /// IsSetup flag, SetupParts count, parts-hit / parts-miss tallies. + /// Initial state from ACDREAM_PROBE_INDOOR_LOOKUP=1. + /// + public static bool ProbeIndoorLookupEnabled { get; set; } = + Environment.GetEnvironmentVariable("ACDREAM_PROBE_INDOOR_LOOKUP") == "1" + || Environment.GetEnvironmentVariable("ACDREAM_PROBE_INDOOR_ALL") == "1"; + + /// + /// When true, WbMeshAdapter emits two lines per EnvCell id: + /// [indoor-upload] requested on first IncrementRefCount and + /// [indoor-upload] completed when WB's staged drain produces + /// its ObjectMeshData. Missing "completed" lines indicate WB + /// silently returned null (hypothesis H1). + /// Initial state from ACDREAM_PROBE_INDOOR_UPLOAD=1. + /// + public static bool ProbeIndoorUploadEnabled { get; set; } = + Environment.GetEnvironmentVariable("ACDREAM_PROBE_INDOOR_UPLOAD") == "1" + || Environment.GetEnvironmentVariable("ACDREAM_PROBE_INDOOR_ALL") == "1"; + + /// + /// When true, WbDrawDispatcher emits one [indoor-xform] + /// line per visible cell entity per second: cell-geometry SetupPart's + /// composed world matrix translation. Disambiguates transform + /// double-apply (hypothesis H5). + /// Initial state from ACDREAM_PROBE_INDOOR_XFORM=1. + /// + public static bool ProbeIndoorXformEnabled { get; set; } = + Environment.GetEnvironmentVariable("ACDREAM_PROBE_INDOOR_XFORM") == "1" + || Environment.GetEnvironmentVariable("ACDREAM_PROBE_INDOOR_ALL") == "1"; + + /// + /// When true, WbDrawDispatcher.WalkVisibleEntities emits one + /// [indoor-cull] line per cell entity that gets culled, with + /// the reason (visibleCellIds-miss, frustum, landblock). Disambiguates + /// cull bugs (hypothesis H3). + /// Initial state from ACDREAM_PROBE_INDOOR_CULL=1. + /// + public static bool ProbeIndoorCullEnabled { get; set; } = + Environment.GetEnvironmentVariable("ACDREAM_PROBE_INDOOR_CULL") == "1" + || Environment.GetEnvironmentVariable("ACDREAM_PROBE_INDOOR_ALL") == "1"; + + /// + /// Master toggle. Reading reflects the AND of all five flags + /// (true only when every probe is on). Writing cascades — setting + /// to turns ALL five flags on; setting to + /// turns ALL five off. + /// + public static bool IndoorAll + { + get => ProbeIndoorWalkEnabled + && ProbeIndoorLookupEnabled + && ProbeIndoorUploadEnabled + && ProbeIndoorXformEnabled + && ProbeIndoorCullEnabled; + set + { + ProbeIndoorWalkEnabled = value; + ProbeIndoorLookupEnabled = value; + ProbeIndoorUploadEnabled = value; + ProbeIndoorXformEnabled = value; + ProbeIndoorCullEnabled = value; + } + } + + /// + /// Helper for probe call sites. Returns when + /// the low 16 bits of are ≥ 0x0100 — the AC + /// convention for EnvCell (indoor) cells, as opposed to outdoor cells + /// in the 8×8 landblock grid (0x0001–0x0040). + /// + public static bool IsEnvCellId(ulong id) => (id & 0xFFFFu) >= 0x0100u; +}