Skip to content

Add Model Ghost Preview extension (VIZ-3444) - #44

Closed
msadowski wants to merge 7 commits into
mainfrom
cursor/model-ghost-preview-extension-6c94
Closed

msadowski wants to merge 7 commits into
mainfrom
cursor/model-ghost-preview-extension-6c94

Conversation

@msadowski

@msadowski msadowski commented Oct 2, 2026 •

Copy link
Copy Markdown
Contributor

Prototype for VIZ-3444. It adds a Foxglove panel extension that draws a "ghost" of a 3D model at the time you hover on the timeline, even while playback is paused. The model at the current time is drawn alongside it, like the reference screenshot in the request.

Ghost preview

Why a custom panel

  • The panel needs two extension APIs: RenderState.previewTime gives the hovered seek-bar time, and subscribeMessageRange gives every pose in the recording. Together they let the panel look up the pose at any hovered time.
  • A message converter feeding the built-in 3D panel can't do this. Converters only run when a new input message arrives, and nothing arrives while paused, so the ghost could not follow the hover.
  • The panel renders its own three.js scene. Native support in the 3D panel is still the long-term answer; this prototypes the UX.

What's included (extensions/model_ghost_preview/)

  • The panel (extension/):
    • Pose topic support: foxglove.PoseInFrame, PosesInFrame, FrameTransform(s), ROS PoseStamped, Odometry, TFMessage and TransformStamped. TF-style topics pick a child frame, with autocomplete.
    • Poses are interpolated with lerp for position and slerp for orientation, or "previous sample" mode.
    • The model is a built-in procedural haul truck, or a glTF/GLB loaded from a URL.
    • Ghost style is wireframe, transparent or solid, with configurable colour and opacity, a per-panel Preview ON/OFF toggle, and a +Δt label.
    • The full path is drawn, and the segment between the current and preview poses is highlighted.
    • Hovering the path inside the panel sets the preview time for other panels; clicking it seeks.
    • Camera follow modes: off, current model, or ghost.
  • Demo data: demo/generate_demo_mcap.py uses the Foxglove SDK to write a truck on a winding haul road (/truck/pose, /tf, /scene/road).
  • Layout: foxglove_layouts/model_ghost_preview.json.
  • Unit tests (vitest, 37): pose extraction, timeline and interpolation, time normalisation, settings reducer, line geometry, truck geometry.
  • Browser harness (extension/dev/): mounts the real panel with a mock PanelExtensionContext and a fake timeline. It was used to capture the README screenshots.
  • Root README: .utils/generate_readme.py has a new "Foxglove Extensions" category, and the root README.md is regenerated.

How this was built

Grok implemented the plan, and Opus reviewed each round. There were five rounds, ending with Opus approving. Issues found and fixed along the way:

  • The truck's wheels were rotated 90°.
  • The layout used the wrong panel id.
  • TF child frames got interleaved on /tf.
  • The path was cut short by three.js caching the line's segment count.
  • The ground plane hid parts of the path and ghost.
  • Resources leaked, playback did more work than needed, and the demo truck pitched the wrong way.

Testing

  • npm run lint, npx tsc --noEmit, npm test, npm run build and npm run package all pass.
  • The demo generator was run and its MCAP checked: 1200 /truck/pose messages, 1200 /tf and 1 /scene/road.
  • The harness was checked in headless Chrome: the ghost follows the hover, hovering the path sets the preview time, clicking seeks, and an orbit drag doesn't seek.
  • Not yet tested in the real Foxglove app. In particular, the layout's panel id (Model Ghost Preview.Model Ghost Preview) was worked out from the Studio extension loader code. The README explains how to add the panel by hand if the layout shows it as unknown.

Known limitations

  • There is no TF tree. Poses are drawn in the topic's own frame.
  • Range loading is best effort and limited by memory.
  • Live sources have no future data, so there is nothing to preview ahead of the current time.

To show artifacts inline, enable in settings.

Open in Web Open in Cursor 

@linear-code

linear-code Bot commented Oct 2, 2026

Copy link
Copy Markdown

VIZ-3444

cursoragent and others added 5 commits October 2, 2026 17:06
…k, perf and resource leaks

Co-authored-by: mat <mat@foxglove.dev>
…autocomplete

Co-authored-by: mat <mat@foxglove.dev>
…llows pose

Co-authored-by: mat <mat@foxglove.dev>
…anged

Co-authored-by: mat <mat@foxglove.dev>
…ture behind flag

Co-authored-by: mat <mat@foxglove.dev>
@msadowski msadowski closed this Oct 5, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

2 participants