Skip to content

3D replay: auto theme default, speed + glide-ratio trail colours, camera continuity across backdrop switches#233

Merged
pokle merged 2 commits into
masterfrom
claude/3dvis-replay-metrics-cdj8nu
Jul 4, 2026
Merged

3D replay: auto theme default, speed + glide-ratio trail colours, camera continuity across backdrop switches#233
pokle merged 2 commits into
masterfrom
claude/3dvis-replay-metrics-cdj8nu

Conversation

@pokle

@pokle pokle commented Jul 4, 2026

Copy link
Copy Markdown
Owner

Follow-up to #230.

Auto is the default theme

With nothing stored, the replay now follows the OS colour scheme ('system') instead of defaulting to dark — and keeps following it live. Users who explicitly picked Dark or Light are unaffected (their stored choice wins).

New trail colouring: Speed

Colours the trail by ground speed — useful for reading strategy: thermalling drift vs cruise vs full-bar glides jump out at a glance.

  • Per-vertex smoothed ground speed is computed at load in assembleTracks (horizontal path length over the same ±3-fix window as the vario smoothing, via a per-pilot prefix sum — no inner loop), fed to the trail shader as a new aSpeed attribute shared by the line and points passes.
  • Rendered on the sequential ramp from SPEED_MIN = 18 km/h to SPEED_MAX = 108 km/h. The floor isn't 0 — nobody flies below stall speed, and anchoring the ramp at 0 wasted its bottom third and compressed the useful range (first cut did exactly that; re-ranged after eyeballing).

New trail colouring: Glide ratio

  • Red (poor) → yellow → green (good), scaled logarithmically over ratios 2…32 — ratios span a large range and a 4→8 improvement should read as strongly as 16→32 (t = log2(g/2)/log2(16) in the shader, from aSpeed / −aVario).
  • Climbing/level segments render flat in the themed vario-zero colour — glide is effectively infinite there, and the flat grey de-emphasises climbs so the glide quality between thermals carries the picture.

Both modes get colour-scale legends: speed in the user's preferred units (≤18 km/h … ≥108 km/h), glide as ratios with the geometric-mean midpoint (≤2 · 8 · ≥32 · climb = grey).

Camera continuity across backdrop (and theme) switches

Switching Abstract ↔ Map used to snap to each backend's default framing — a jarring loss of continuity. Both camera models reduce to the same five numbers, so rebuild() now captures a backend-agnostic ViewState from the outgoing backend and seeds the incoming one (setInitialView before mount(), applied instead of the default whole-task framing):

  • look-at point in local ENU (y = 0 from the map side — it has no elevated look-at),
  • bearingDeg (shared compass convention), pitchDeg (0 = straight down; abstract's polar angle maps 1:1, clamped to Mapbox's 85° max),
  • mpp — metres per pixel at the view centre, which carries the zoom without either side knowing the other's projection model: abstract camera distance = mpp·viewportH / (2·tan(fov/2)); map zoom = log2(40075016.686·cos(lat)/mpp) − 9, the exact inverse of its getMetresPerPixel.

Theme switches ride the same path, so they no longer reset the camera either.

Verification

  • bun run typecheck:all passes; replay unit tests 17/17 (terrain-follow, new terrain-view round-trip: applyView → getViewState recovers x/z/bearing/pitch/mpp exactly, pitch clamps at 85°, zoom accounts for latitude).
  • Playwright: auto default (light OS → light page, nothing stored; follows a live OS flip); Speed and Glide modes render with correct legends and no shader errors; camera continuity — after orbiting to bearing 63° and zooming, a backend rebuild preserves the compass bearing within 0.5° and the scale bar to the pixel; the full regression suite still passes.
  • Docs updated (docs/3d-flight-replay-notes.md §5.14b).

🤖 Generated with Claude Code

https://claude.ai/code/session_01DZpFYsCEyR7ck3bWmQNhCr

claude added 2 commits July 4, 2026 00:49
- Theme defaults to auto ('system') when nothing is stored — follows
  prefers-color-scheme live. Explicit dark/light choices are untouched.
- New 'Speed' trail colouring: per-vertex smoothed ground speed
  (prefix-sum path length over the same +/-3-fix window as vario,
  computed at load), rendered on the sequential ramp from SPEED_MIN to
  SPEED_MAX (18-108 km/h; the floor isn't 0 because nobody flies below
  stall speed, which would waste the ramp's bottom third). Useful for
  reading strategy: thermalling drift vs cruise vs full-bar glides.
- New 'Glide ratio' trail colouring: red (poor) -> yellow -> green
  (good), scaled logarithmically over 2..32 so a 4->8 improvement
  reads as strongly as 16->32. Climbing/level segments render flat in
  the themed vario-zero colour - glide is effectively infinite there.
- Colour-scale legend covers both modes (speed in the user's units;
  glide as ratios with the geometric-mean midpoint and a
  'climb = grey' note).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DZpFYsCEyR7ck3bWmQNhCr
Switching abstract <-> map snapped to each backend's default framing —
a jarring loss of continuity. Both camera models reduce to the same
five numbers, so rebuild() now captures a backend-agnostic ViewState
from the outgoing backend and seeds the incoming one (setInitialView
before mount, applied instead of the default whole-task framing):

- look-at point in local ENU (y = 0 from the map side — it has no
  elevated look-at),
- bearingDeg (shared compass convention),
- pitchDeg (0 = straight down; abstract's polar angle maps 1:1,
  clamped to Mapbox's 85 max),
- mpp — metres per pixel at the view centre, which carries the zoom
  without either side knowing the other's projection model:
  abstract distance = mpp*viewportH / (2*tan(fov/2));
  map zoom = log2(40075016.686*cos(lat)/mpp) - 9 (the exact inverse
  of its getMetresPerPixel).

Theme switches ride the same path, so they no longer reset the camera
either. Round-trip pinned by terrain-view.test.ts (mocked mapbox);
Playwright verifies bearing and scale-bar width survive a rebuild.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DZpFYsCEyR7ck3bWmQNhCr
@pokle pokle changed the title 3D replay: auto theme default + speed and glide-ratio trail colour modes 3D replay: auto theme default, speed + glide-ratio trail colours, camera continuity across backdrop switches Jul 4, 2026
@github-actions

github-actions Bot commented Jul 4, 2026

Copy link
Copy Markdown

Preview Deployment
https://ea70bd4f.glidecomp.pages.dev
Commit: 6ba3fce

@pokle pokle marked this pull request as ready for review July 4, 2026 01:44
@pokle pokle merged commit 2e00372 into master Jul 4, 2026
6 checks passed
@pokle pokle deleted the claude/3dvis-replay-metrics-cdj8nu branch July 4, 2026 01:44
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.

2 participants