Restore inspector rail and audio dock

This commit is contained in:
Meta Vens 2026-05-31 22:57:34 +01:00
commit 81b96f7e91
3 changed files with 46 additions and 29 deletions

View file

@ -45,12 +45,12 @@ Get-Content .\state\evidence.jsonl -Tail 8
- Fensalir owns production GPU fusion, UI, and Spout2 publication.
- `MimirSceneEditorState` is currently a 2D OBS-shaped program mixer owner, not
a camera/3D scene editor. Synced video buffers become program layers with
normalized placement; the Eve/CultUI surface is Video Sources plus
source-adjacent layer actions on the left, a chrome-free program canvas in
the center, and Audio Mix on the right. Camera/SDF/model editor affordances
and numeric transform inspector controls have no live UI authority, and
editor camera/SDF/spline output no longer contributes to the runtime frame.
Smoke with `--scene-editor-smoke`.
normalized placement; the Eve/CultUI surface is Video Sources on the left, a
chrome-free program canvas in the center, Audio Mixer docked underneath that
canvas, and a Unity-style Inspector on the right for the selected layer's
properties. Camera/SDF/model editor affordances have no live UI authority,
and editor camera/SDF/spline output no longer contributes to the runtime
frame. Smoke with `--scene-editor-smoke`.
- Live camera image buffers should use Fensalir-owned texture leases when they
are rendering inputs: Mimir asks the engine broker for a keyed D3D12
Texture2D/fence lease, writes decoded frames into that texture, commits the

View file

@ -863,22 +863,10 @@ public sealed class MimirRuntime : IAquariumRuntime, IAquariumRuntimeServicesRec
graph.Options("video.source-select", "Feed", () => presentationControls.SelectedVideoIndex, SelectVideoLayer, VideoFeedOptions());
graph.Text("video.program-summary", DescribeProgramVideo, "caption", weight: 0.75f);
graph.Text("video.layer-list", sceneEditor.DescribeHierarchy, "mono", weight: 3.8f);
graph.Row("video.source-state", state =>
graph.Row("video.nav", nav =>
{
state.Toggle("video.visible", "Visible", () => sceneEditor.SelectedNode?.Visible ?? false, SetSelectedVideoVisible);
state.Toggle("video.solo", "Solo", () => presentationControls.SelectedVideo?.Solo ?? false, SetSelectedVideoSolo);
});
graph.Slider("video.opacity", "Opacity", () => presentationControls.SelectedVideo?.Opacity ?? 1.0f, SetSelectedVideoOpacity, 0.0f, 1.0f, "0.00");
graph.Row("video.layer-fit", fit =>
{
fit.Button("video.center", "Center", sceneEditor.CenterSelectedProgramLayer);
fit.Button("video.fit", "Fit", sceneEditor.FitSelectedProgramLayer);
fit.Button("video.fill", "Fill", sceneEditor.FillSelectedProgramLayer);
});
graph.Row("video.layer-order", order =>
{
order.Button("video.layer-up", "Layer Up", () => MoveSelectedVideoLayer(-1));
order.Button("video.layer-down", "Layer Down", () => MoveSelectedVideoLayer(1));
nav.Button("video.previous", "Previous", sceneEditor.SelectPrevious);
nav.Button("video.next", "Next", sceneEditor.SelectNext);
});
graph.Text("video.selected", sceneEditor.DescribeSelection, "caption", weight: 1.2f);
}, weight: 0.85f);
@ -886,15 +874,43 @@ public sealed class MimirRuntime : IAquariumRuntime, IAquariumRuntimeServicesRec
shell.Vertical("mimir.editor-center", center =>
{
center.Preview("scene.view-preview", "", () => sceneEditor.PreviewItems, weight: 1.0f);
}, weight: 2.1f);
center.Pane("mimir.audio-mixer", "Audio Mixer", mixer =>
{
mixer.Options("audio.stem", "Stem", () => presentationControls.SelectedAudioIndex, SelectAudioStem, AudioFeedOptions());
mixer.Row("audio.toggles", toggles =>
{
toggles.Toggle("audio.mute", "Mute", () => presentationControls.SelectedAudio?.Muted ?? false, SetSelectedAudioMuted);
toggles.Toggle("audio.solo", "Solo", () => presentationControls.SelectedAudio?.Solo ?? false, SetSelectedAudioSolo);
});
mixer.Slider("audio.gain", "Gain", () => presentationControls.SelectedAudio?.Gain ?? 1.0f, SetSelectedAudioGain, 0.0f, 2.0f, "0.00");
mixer.Text("audio.program", DescribeProgramAudio, "caption", weight: 0.8f);
}, weight: 0.72f);
}, weight: 1.75f);
shell.Pane("mimir.audio-inspector", "Audio Mix", inspector =>
shell.Pane("mimir.inspector", "Inspector", inspector =>
{
inspector.Options("audio.stem", "Stem", () => presentationControls.SelectedAudioIndex, SelectAudioStem, AudioFeedOptions());
inspector.Toggle("audio.mute", "Mute", () => presentationControls.SelectedAudio?.Muted ?? false, SetSelectedAudioMuted);
inspector.Toggle("audio.solo", "Solo", () => presentationControls.SelectedAudio?.Solo ?? false, SetSelectedAudioSolo);
inspector.Slider("audio.gain", "Gain", () => presentationControls.SelectedAudio?.Gain ?? 1.0f, SetSelectedAudioGain, 0.0f, 2.0f, "0.00");
inspector.Text("audio.program", DescribeProgramAudio, "caption", weight: 1.2f);
inspector.Text("inspector.selection", sceneEditor.DescribeSelection, "strong");
inspector.Options("inspector.video-feed", "Feed", () => presentationControls.SelectedVideoIndex, SelectVideoLayer, VideoFeedOptions());
inspector.Toggle("video.visible", "Visible", () => sceneEditor.SelectedNode?.Visible ?? false, SetSelectedVideoVisible);
inspector.Toggle("video.solo", "Solo", () => presentationControls.SelectedVideo?.Solo ?? false, SetSelectedVideoSolo);
inspector.Slider("video.opacity", "Opacity", () => presentationControls.SelectedVideo?.Opacity ?? 1.0f, SetSelectedVideoOpacity, 0.0f, 1.0f, "0.00");
inspector.Text("inspector.program-placement", "Program Frame", "strong");
inspector.Slider("program.x", "X", () => sceneEditor.SelectedProgramX, sceneEditor.SetSelectedProgramX, 0.0f, 1.0f, "0.000");
inspector.Slider("program.y", "Y", () => sceneEditor.SelectedProgramY, sceneEditor.SetSelectedProgramY, 0.0f, 1.0f, "0.000");
inspector.Slider("program.w", "W", () => sceneEditor.SelectedProgramWidth, sceneEditor.SetSelectedProgramWidth, 0.01f, 1.0f, "0.000");
inspector.Slider("program.h", "H", () => sceneEditor.SelectedProgramHeight, sceneEditor.SetSelectedProgramHeight, 0.01f, 1.0f, "0.000");
inspector.Slider("program.rotation", "Rotation", () => sceneEditor.SelectedNode?.Transform.RotationRadians ?? 0.0f, sceneEditor.SetSelectedRotation, -MathF.PI, MathF.PI, "0.00");
inspector.Row("program.fit", fit =>
{
fit.Button("program.center", "Center", sceneEditor.CenterSelectedProgramLayer);
fit.Button("program.fit-selected", "Fit", sceneEditor.FitSelectedProgramLayer);
fit.Button("program.fill-selected", "Fill", sceneEditor.FillSelectedProgramLayer);
});
inspector.Row("program.order", order =>
{
order.Button("program.layer-up", "Layer Up", () => MoveSelectedVideoLayer(-1));
order.Button("program.layer-down", "Layer Down", () => MoveSelectedVideoLayer(1));
});
}, weight: 0.95f);
});
});

View file

@ -289,5 +289,6 @@
{"ts": "2026-05-31T22:30:36+01:00", "type": "verification", "status": "partial", "note": "Added sync_sweep.py plus stdlib-only Nightwing witness helpers. Live receipt artifacts/runtime/sync-sweep-hints-live proved Nightwing owns Eye/Move localization locally: nw-eye-0 and nw-eye-1 each captured about 1874 frames at 320x240@187 with zero sequence gaps and emitted 8/8 compact mimir.move_controller_observation_state.v1 hints, while Starfire analyzed its own ASIO/DShow/Kiyo streams. Nightwing builtin mic capture works but the cheap local chirp hint is not yet reliable enough to score as a timing witness."}
{"ts":"2026-05-31T22:45:00+01:00","type":"implementation","status":"ok","note":"Mimir editor authority was cut back to a 2D OBS-shaped program mixer. SceneEditorState no longer creates default SDF/model content, preview items are video-feed-only, runtime editor camera/SDF/spline output is silent, and the Eve/CultUI surface is Video Sources with source-adjacent layer actions left, chrome-free program canvas center, and Audio Mix right. Numeric transform inspector controls were removed from the live surface. `--scene-editor-smoke` now verifies only camera+video feed nodes, video-only preview items, and normalized program placement.","files":["src/Mimir.Runtime/MimirRuntime.cs","src/Mimir.Runtime/Synchronization/MimirSceneEditorState.cs","src/Mimir.BufferSmoke/Program.cs"],"source":"dotnet build src/Mimir.Runtime/Mimir.Runtime.csproj; dotnet build src/Mimir.BufferSmoke/Mimir.BufferSmoke.csproj; dotnet run --no-build --project src/Mimir.BufferSmoke/Mimir.BufferSmoke.csproj -- --scene-editor-smoke; Mimir.App --headless --headless-width 1280 --headless-height 720 --capture-frame artifacts/runtime/mimir-editor-flat-2d-program-mixer-headless.png"}
{"ts": "2026-05-31T22:46:40+01:00", "type": "implementation", "status": "ok", "note": "Added the first Starfire-owned camera frustum solve. MimirCameraFrustumCalibrationSolver consumes stable LED/marker correspondences, scene-space marker points, and seed frustums, then emits position, rotation, horizontal/vertical tangent half-FOV, correspondence count, clipspace reprojection residual, and confidence. BufferSmoke --frustum-calibration-smoke solves five synthetic frustums for ps3-eye-0, ps3-eye-1, kiyo-pro-rgb, leap-stereo-ir, and eve-camera with mean clip error 0.000000; room calibration lock still passes. Eve is now modeled like Nightwing as eve-local-sensor-witness/eve-local-sensors: it owns local camera/mic flash and chirp solves and ships typed hints, not raw placement authority."}
{"ts":"2026-05-31T23:05:00+01:00","type":"implementation","status":"ok","note":"Corrected the Mimir editor layout ownership after the flat-canvas pass: the center remains a chrome-free program compositor canvas, Audio Mixer is docked underneath that center canvas, and the right rail is again a Unity-style Inspector for the selected video layer's properties. Video Sources on the left now selects and navigates sources rather than carrying the property surface.","files":["src/Mimir.Runtime/MimirRuntime.cs","notes/fresh-workspace-handoff.md"],"source":"dotnet build src/Mimir.App/Mimir.App.csproj; dotnet run --no-build --project src/Mimir.BufferSmoke/Mimir.BufferSmoke.csproj -- --scene-editor-smoke; Mimir.App --headless --headless-width 1280 --headless-height 720 --capture-frame artifacts/runtime/mimir-editor-unity-inspector-audio-bottom-headless.png"}
{"ts": "2026-05-31T22:52:47+01:00", "type": "implementation", "status": "ok", "note": "Extended MimirCameraFrustumCalibrationSolver beyond LED strips: it now also consumes MimirFeatureTrackFieldCandidate plus scene-space TrackId anchors, so PS Move sphere histories, sparse Eye tracks, and Eve-local marker tracks enter the same Starfire-owned frustum authority. BufferSmoke --frustum-calibration-smoke now proves five LED-spline frustums and five feature-track frustums for ps3-eye-0, ps3-eye-1, kiyo-pro-rgb, leap-stereo-ir, and eve-camera with mean clip error 0.000000."}
{"ts": "2026-05-31T22:55:38+01:00", "type": "implementation", "status": "ok", "note": "Added mimir.local_frustum_hint_state.v1 as the CultMesh document for local witness frustum solves. It carries producer node, calibration id, candidate key, marker set id, per-camera pose/frustum snapshots, residuals, point counts, and confidence, so Eve/Nightwing can publish compact solved hints while Starfire remains canonical global placement authority."}