Skip to content

feat(studio): a Graph panel of the scene graph - #94

Merged
kixelated merged 3 commits into
mainfrom
quest/m1/scene-graph
Nov 7, 2026
Merged

kixelated merged 3 commits into
mainfrom
quest/m1/scene-graph

Conversation

@kixelated

@kixelated kixelated commented Nov 7, 2026 •

Copy link
Copy Markdown
Contributor

Problem

quest/m1/scene-graph.md asked for a Graph panel: picture and audio scenes as nodes, wired to the sources and scenes they draw or send to, with each sound's volume, pan, and a live waveform on its node, and edges and node settings editable there. Planned 2026-11-05 with the maintainer: the live controls stay a mixer; this view is for building and inspecting routing, on the same data, with no second model.

Approach

  • Graph panel (rs/moq-studio/src/ui/graph.rs), a tab beside Preview. Each frame it builds the graph from the Collection, so undo, reloads, and other panels' edits show at once:
    • Nodes: every source with a picture or sound (a LUT is only a filter's, so it has none), each scene, the top layer, and each audio scene.
    • Wires: source to each scene or the top layer placing it (one wire per source, however many items), sound or audio scene to each audio scene holding it, and a fixed wire into each scene or clone source from what it shows.
    • A wire is dimmed when every item it stands for is hidden or its sound is muted.
  • Layout. Each node goes in the column after the longest chain of wires into it, so sources are on the left and everything they feed is further right. A wire that skips columns runs through a lane in each column it skips, so wires never pass under a node. Each column is ordered with one barycenter pass, pictures above sounds, so wires cross less.
  • Editing. Drag from a node's right edge onto a scene's, the top layer's, or an audio scene's left edge. While you drag, the inputs that would take the wire light up. Dropping a picture places the source filling the layer, as the Items panel's Add does; dropping a sound or audio scene sends it, as an Audio panel send does. Click a wire and press Remove to take it out. Every change is an ordinary Draft edit with the same labels as the other panels, so it lands in History and undoes there.
  • Node settings reuse the panels' code. A sound node shows the Audio panel's mute, gain, and delay through a new shared strip_controls. A scene node shows the Scenes panel's Publish and carried audio scene through scene_settings, applied by scene_action, which is extracted from the Scenes panel. An audio scene node has On program and Listen. Clicking a scene previews it, and clicking a source picks it for Filters.
  • Levels and waveforms (rs/moq-studio/src/ui/levels.rs). Levels takes every strip's and audio scene's level once per 50 ms step, keeps 4 s of history for the waveforms, and feeds the Audio panel's meters too. A waveform mirrors each step's peak (faint) and RMS (solid) on the meters' dB scale.
  • Bug fixed along the way. Mix::level takes and resets the meter, and the Audio panel called it twice per frame for each audio scene. The second meter, on the audio scene's own strip row, read silence. On main with a looping tone, the Program row at the top read full and the Program strip below read empty; on this branch both read full (screenshots on nixos).
  • Pan. Per-sound pan waits on moq's strip pan (quest/m0/audio-pan.md behind quest/m0/pin-audio-pan.md). Both panels draw a sound's controls with strip_controls, so a pan added there shows in the Audio panel and on the Graph node. This PR extends that quest's Goal to say so, and notes the seam in its Plan. There is no stub control.
  • README.md gains a Graph row in Panels and a Scene graph section. The quest is deleted.

Choices made without asking:

  • The Graph tab sits beside Preview, the one region large enough for a node view. A preview no tab shows is not drawn, as before.
  • The layout is automatic, with no hand placement or saved positions. That keeps one model: positions are view state the scene file should not hold.
  • Removing a picture wire removes every item of that source in that scene, in one undoable edit. Dropping a wire that already exists is refused rather than adding a second linked item; the Items panel still adds one.
  • One scene goes into another through a scene source node, as the data has it. A wire into a source is fixed and follows from that source.
  • The waveform is a level envelope (peak and RMS per 50 ms), not raw samples. Only mixes have sample readers, and a strip's level is what the meters already read.
  • Adding, renaming, reordering, and removing nodes stay in the Scenes and Sources panels.
  • A drag from an audio scene does not light an input that would make a loop, matching the Audio panel's disabled sends. A picture wire that would nest a scene in itself is refused on drop by validation, with its reason in the status bar.

Public API

None: the studio's UI only. The scene file format is unchanged.

Validation

  • just ci on nixos (Linux) at the head below: all checks and 284 tests passed. New unit tests cover the layout (columns, lanes, dimming, fixed wires) and the wire edits (place, remove every item, sends, refusals, audio loops).
  • By hand on nixos under Xvfb (release build): the graph of a scene file with a clone, a scene source, nested audio scenes, and a hidden item; dragging person onto the top layer placed it over program; picking that wire showed it with Remove; waveforms moved with a looping tone. The meter fix was compared against main as described above.
  • No Windows or macOS build; the change is platform-neutral egui.

Follow-ups

None beyond quest/m0/audio-pan.md, which now covers the Graph node's pan.

Review

Codex (gpt-6.1-sol, medium effort), round 1 of session 01a1b6d9-fbfb-7290-a157-5b84839d976d, reviewed head d0560b5b67c2263493fd604f3607f201f44d2c3f against origin/main a8ca56f: no findings.

(Written by Claude Opus 5.5)

🤖 Generated with Claude Code

Quest-Claim: 4c304ee980226ff0
@pullfrog

pullfrog Bot commented Nov 7, 2026

Copy link
Copy Markdown

Pullfrog  | Review this ➔

Sources, scenes, the top layer, and audio scenes as nodes, wired left to
right to what draws or holds them. Dragging from an output onto an input
places a source or sends a sound; a picked wire's Remove takes it out.
Sound nodes carry the Audio panel's strip controls and a live waveform;
scene nodes the Scenes panel's Publish and carried audio scene.

Levels are now taken once per 50 ms step for every panel, so the Audio
panel's second meter on each audio scene no longer reads near silence.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@kixelated kixelated changed the title Scene graph view feat(studio): a Graph panel of the scene graph Nov 7, 2026
@kixelated
kixelated marked this pull request as ready for review November 7, 2026 16:33
@coderabbitai

coderabbitai Bot commented Nov 7, 2026 •

Copy link
Copy Markdown

Warning

Review limit reached

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Next included review available in 24 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used the included review currently available.

Learn how review limits work.

Review configuration:

Run configuration

  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: Organization UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: a7c2510d-e81a-4bb7-81a5-2c5c1631ba75
Commits

Reviewing files that changed from the base of the PR and between a8ca56f and 9fbfa82.

Files selected for processing: 7

  • README.md
  • quest/m0/audio-pan.md
  • quest/m1/README.md
  • quest/m1/scene-graph.md
  • rs/moq-studio/src/ui.rs
  • rs/moq-studio/src/ui/graph.rs
  • rs/moq-studio/src/ui/levels.rs
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

Share

@kixelated kixelated left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Automated review by review (OpenAI)

Reviewed head 9fbfa82 against base a8ca56f.

No actionable findings. Checked graph construction and routing edits in ui/graph.rs, Collection/Draft validation and undo integration, the shared scene/audio controls in ui.rs, and the cached levels in ui/levels.rs. Picture removals preserve item-index tracking, fixed dependency wires stay read-only, and audio sends reject nesting loops. Reading each meter once per sampling step also avoids the previous duplicate reset.

Direction: deriving the graph from Collection and reusing the existing edit path keeps one routing model and avoids a separate graph state to reconcile.

The synchronization received during review only merged the updated base; all seven PR patches retain the reviewed added/removed lines.

Verification: GitHub-only static review, including repository guidance, surrounding callers and pinned audio meter implementation. No builds, tests, runtime UI checks or quest context execution; pinned quest context was read as source.

(Written by review (OpenAI))

@kixelated

Copy link
Copy Markdown
Contributor Author

Pick (/quest-complete, maintainer away under /afk, recommended option): ✅ Merge, keeping the choices made without asking: the tab beside Preview, the automatic layout with no saved positions, and one undoable removal per picture wire. Check passed and the OpenAI review found nothing. Merged main (#95), with no conflicts.

(Written by Claude Opus 5.5)

@kixelated
kixelated merged commit a461c84 into main Nov 7, 2026
3 checks passed
@kixelated
kixelated deleted the quest/m1/scene-graph branch November 7, 2026 16:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant