Skip to content

Viewer review: typed-array grids, faster hot paths, anchored pan, dead code removal (v1.383) - #2

Draft
ernop wants to merge 5 commits into
masterfrom
cursor/viewer-review-and-improvements-a2cd
Draft

Viewer review: typed-array grids, faster hot paths, anchored pan, dead code removal (v1.383)#2
ernop wants to merge 5 commits into
masterfrom
cursor/viewer-review-and-improvements-a2cd

Conversation

@ernop

@ernop ernop commented Jul 15, 2026

Copy link
Copy Markdown
Owner

Summary

Full review-and-repair pass over the viewer, requested as "test it, fix it up for efficiency, quality, resolution, and control schemes." Findings and open recommendations are recorded in the new REVIEW.md.

Efficiency

  • Elevation grids are now Float32Array rows with NaN as the single nodata encoding (previously nested JS arrays with null/undefined/NaN all in play). Bucketing is single-pass; derived slope/aspect grids are typed too. Cuts grid memory by roughly 8x and keeps hot loops monomorphic.
  • createBars writes instance matrices directly into instanceMatrix.array, skipping per-instance Object3D matrix composition on every terrain rebuild.
  • raycastToWorld intersects the y=0 ground plane analytically instead of raycasting the full InstancedMesh, so HUD mousemove cost went from O(instances) to O(1).
  • Bucket pregeneration runs one size per setTimeout slice instead of one synchronous burst.
  • Activity log capped at 400 DOM entries; console spam trimmed.

Controls

  • Left-drag is now an anchored grab-pan: the ground point under the cursor stays pinned under the cursor, with clamping near the horizon and a fallback to incremental pan.
  • Wheel zoom is exponential in a deltaMode-normalized delta, so trackpads and mouse wheels zoom at the same rate.
  • The camera URL parameter is applied on load; slider changes use replaceState so browser history is no longer flooded.
  • toggleKeyboardControls() was called from the HTML but never defined (silent ReferenceError); implemented it and wired the on-screen key buttons.

Side-by-side comparison (old vs new)

  • snapshot_baseline.py exports any git ref (default master) into snapshots/baseline/ and links the data directory in, so the untouched old viewer runs unmodified at its own URL beside the working tree.
  • compare.html loads both in two panes with the same parameters, shows each pane's version, and has Mirror buttons that copy the exact current view (camera, region, settings) from one pane to the other via the viewers' URL state. Each pane has an "open in tab" link for sequential full-window comparison.
  • Snapshots are gitignored; compare.html deploys with the site.

compare.html: v1.382 baseline (left) and v1.383 working tree (right), same view mirrored

Pipeline and data

  • src/pipeline.py rounds exported elevations to 2 decimals, roughly halving gzipped size for float DEMs; repack_regions.py (new) applies this to existing files.
  • fetch_sample_data.py (new) downloads manifest + regions from production so a fresh checkout can run locally without GIS dependencies (documented in install.md).

Removed

~700 net lines of dead code: the never-loaded js/bucketing.js, legacy mouse handlers, the orphaned HUD drag/persistence system, linearZoom_OLD, createBarsTerrain, barsDummy, and more.

Testing

Headless Chromium (Playwright) against a local server with California and Estonia production data: load, typed-array assertions, bucket-size changes (22ms rebucket + 26ms rebuild for Estonia at 9x), wheel zoom, anchored pan, HUD raycast timing (500 raycasts in 1.1ms), region switch, exaggeration + URL sync, history flood check, camera-scheme-from-URL, keyboard toggle. All passed with zero page errors.

The comparison page was tested the same way: both panes render (baseline reports v1.382, working tree v1.383, identical bar counts for identical params), and mirroring reproduces the exact URL state across panes. The only console errors are the pre-existing favicon 404s (favicons live on prod but are not committed; noted in REVIEW.md).

Estonia at bucket size 3
California after region switch

To show artifacts inline, enable in settings.

Open in Web Open in Cursor 

cursoragent and others added 5 commits July 15, 2026 00:40
…removal (v1.383)

- Elevation grids stored as Float32Array rows with NaN nodata; all
  consumers use Number.isFinite checks (single-pass bucketing, derived
  grids, shading, terrain, jumping camera).
- createBars writes instance matrices directly into instanceMatrix.array,
  skipping per-instance Object3D matrix composition.
- raycastToWorld intersects the y=0 ground plane instead of the full
  InstancedMesh (HUD mousemove now O(1)).
- Pregeneration computes one bucket size per setTimeout slice.
- URL: replaceState by default (pushState only for region changes),
  camera scheme applied from URL on load, cache-keyed region fetches.
- Removed dead code: bucketing.js module, legacy mouse handlers, HUD
  drag/persistence system, linearZoom_OLD, createBarsTerrain, barsDummy.
- Implemented toggleKeyboardControls + on-screen key buttons.
- Activity log capped at 400 entries; trimmed console spam.

Co-authored-by: Ernest French <ernestfrench@gmail.com>
- Left-drag records the ground point under the cursor and keeps it
  pinned there while panning, with clamping near the horizon; falls
  back to incremental pan when no ground point is available.
- Wheel zoom is exponential in a deltaMode-normalized delta so mouse
  wheels and trackpads zoom at the same rate.
- Updated camera-controls rule doc to match.

Co-authored-by: Ernest French <ernestfrench@gmail.com>
- pipeline.py rounds elevations to centimeter precision before JSON
  export, roughly halving gzipped size for float DEMs.
- repack_regions.py applies the same rounding to existing .json.gz
  files in place (supports --dry-run).
- fetch_sample_data.py downloads manifest, adjacency, and named regions
  from production so a fresh checkout can run the viewer locally;
  documented in install.md (Quick Start Without the Pipeline).

Co-authored-by: Ernest French <ernestfrench@gmail.com>
Co-authored-by: Ernest French <ernestfrench@gmail.com>
- snapshot_baseline.py exports any git ref into snapshots/<name>/ via
  git archive and links generated/ into it (symlink, junction on
  Windows, copy as fallback), so the untouched old viewer runs at its
  own URL next to the working tree.
- compare.html loads old and new in two panes with shared params,
  shows each pane's version, and offers Mirror buttons that copy the
  exact current view (camera, region, settings) across panes using the
  viewers' URL state.
- snapshots/ gitignored; compare.html allowed past the *.html ignore
  and added to the deploy list. Documented in install.md.

Co-authored-by: Ernest French <ernestfrench@gmail.com>
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