Skip to content

Trajectory viewer: flyover playback, LiDAR range filter and local-depth coloring - #543

Open
michalpelka wants to merge 8 commits into
mainfrom
mp/trajectory-viewer-flyover
Open

michalpelka wants to merge 8 commits into
mainfrom
mp/trajectory-viewer-flyover

Conversation

@michalpelka

@michalpelka michalpelka commented Sep 28, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Flyover (View → Flyover, Shift+F)

  • Moves the camera along the LiDAR trajectory. A bottom bar has a scrubbable timeline, play/pause, a real-time speed control and an option to keep the selected camera image in sync with the playhead.
  • The camera pose is a Hann-weighted average of the trajectory poses within ±N s of the playhead (default 1 s). This removes walking sway and hand shake without lag, and the same playhead time always gives the same view.
  • Level horizon (on by default) drops roll and keeps heading and pitch.
  • OrbitCamera::setViewPose() places the camera at a LiDAR-axes pose. Mouse orbit/pan/zoom don't apply while the flyover bar is open.

Point rendering

  • Each LIO chunk is its own GPU part in chunk-local coordinates, placed by its MRP pose at draw time.
  • The vertex shrinks from 28 to 24 bytes:
    • intensity as uint16
    • per-point LiDAR range as int16 cm (up to 327.67 m)
    • camera id as int32, where -2 = rejected by ROI/mask; this replaces the separate in-ROI float
  • Min/Max range (View menu) hides points by their distance from the LiDAR when they were captured, e.g. the operator or noisy far returns.
  • New Local depth color mode: jet over that range, with a color scale in the view's top-right corner.

calib_core

  • Trajectory::nearest returns std::optional<std::reference_wrapper<const TrajPose>> instead of a raw pointer, with a new nearest(float) overload.
  • New: Trajectory::timeAt, Trajectory::smoothedPose and calib::levelHorizon, with tests.

Notes

  • In ROI / mask mode: the mode is now derived from the camera id. With the ROI filter disabled, a point outside the ROI that still got colored now shows green; before, it showed red.
  • Level horizon: it keeps pitch, so a LiDAR mounted tilted down still looks down during a flyover.

Test plan

  • camera_lidar_trajectory_viewer, camera_lidar_calibration and core_raylib build, with no new warnings in TrajectoryViewer.cpp.
  • calib_core_tests: 51/51 pass, including new smoothing and level-horizon tests.
  • Point shaders compile and link at startup (raylib log).
  • clang-format 21 is clean on the changed apps/ files.
  • Load a session and check:
    • Flyover smoothness and Level horizon
    • Min/Max range
    • Local depth mode and its color scale
    • In ROI / mask colors

🤖 Generated with Claude Code

michalpelka and others added 8 commits September 28, 2026 13:32
View > Flyover moves the camera along the LiDAR trajectory, with a bottom
timeline to scrub, a real-time speed control, and an option to keep the
selected camera image in sync with the playhead. Trajectory::nearest now
returns an optional reference instead of a raw pointer.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Each LIO chunk is now its own GPU part in chunk-local coordinates, placed by
its MRP pose at draw time. The vertex shrinks from 28 to 24 bytes: intensity
as uint16, per-point LiDAR range as int16 cm, camera id as int32 (-2 marks
points the ROI/mask rejected, replacing the separate in-ROI float).

The range drives new Min/Max range filters and a Local depth color mode.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
The flyover camera now sits on a Hann-weighted average of the trajectory
poses within +/- a window of the playhead (default 1 s), which removes the
walking sway and hand shake without lag, and optionally drops roll to keep
the horizon level. Both are controls in the flyover bar.

The averaging (Trajectory::smoothedPose, Trajectory::timeAt) and
calib::levelHorizon live in calib_core, with tests.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
A jet bar from 0 m to Depth color max, with five labels, in the 3D view's
top-right corner while the Local depth color mode is active.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
The key and the View menu item share one toggle, and the shortcut is listed
in the help table.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Space plays/pauses while the flyover bar is open, sharing one function with
the bar's Play/Pause button, and is listed in the help table.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Loads the image mask at startup through the same path as File > Open Image
Mask, before the session and calibration so their status line stays last.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Export points carry the same int16 cm range the shader filters on, and one
passesRangeFilter() mirrors kVS's cull, so the LAZ holds what is on screen.
The status line reports how many points were filtered out.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
@michalpelka

Copy link
Copy Markdown
Contributor Author

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