Skip to content

feat: navigable 3D embedding view - #217

Draft
somehowchris wants to merge 2 commits into
apple:mainfrom
somehowchris:feat/3d-embedding-view
Draft

feat: navigable 3D embedding view#217
somehowchris wants to merge 2 commits into
apple:mainfrom
somehowchris:feat/3d-embedding-view

Conversation

@somehowchris

Copy link
Copy Markdown

FYI, this has been fully vibe coded over a Sunday afternoon and only tested, only validated with own datasets.


AI generated overview:

Add end-to-end 3D support: points can carry a Z coordinate and render as a navigable 3D point cloud with orbit/pan/zoom, fog depth-cueing, and exact 3D picking, on both the WebGPU and WebGL2 backends.

Component

  • camera3d: orbit/pan/dolly camera with fit-to-bounds, plus frustum-aware downsampling (chunked, idle-scheduled, cancelable) bounded by downsampleMaxPoints so multi-million-point clouds stay responsive.
  • WebGPU + WebGL2 renderers: 3D billboard draw, depth-tested pick targets (r32uint / RGBA8), and fog.
  • EmbeddingViewImpl: orbit inertia, reset/focus tweens, 3D hover/selection, a status-bar reset-camera control, and a visible active-filter indicator while the brush outline is hidden in 3D (never a silent hidden filter).
  • EmbeddingViewMosaic: exact 3D pick-by-index resolution — rowid for base tables, the configured identifier (size-gated to stay bounded) for rowid-less views/joins, coordinate fallback only when no exact identity exists. Coordinated-selection predicates prefer the semantic identifier, then rowid, then coordinates, so a pick targets exactly the picked row.

Viewer

  • A "Z (optional)" projection-column selector; choosing a Z column opens a navigable 3D view that round-trips through saved charts.

Backend

  • --z to pass a precomputed Z column, and --umap-n-components 3 to generate a 3D projection.

Tests

  • camera3d, matrix, and mosaic_client (pick identity + predicate ordering) unit tests; backend CLI and projection coverage. Wires the component package into the JS test suite.

Add end-to-end 3D support: points can carry a Z coordinate and render as a
navigable 3D point cloud with orbit/pan/zoom, fog depth-cueing, and exact 3D
picking, on both the WebGPU and WebGL2 backends.

Component
- camera3d: orbit/pan/dolly camera with fit-to-bounds, plus frustum-aware
  downsampling (chunked, idle-scheduled, cancelable) bounded by
  downsampleMaxPoints so multi-million-point clouds stay responsive.
- WebGPU + WebGL2 renderers: 3D billboard draw, depth-tested pick targets
  (r32uint / RGBA8), and fog.
- EmbeddingViewImpl: orbit inertia, reset/focus tweens, 3D hover/selection,
  a status-bar reset-camera control, and a visible active-filter indicator
  while the brush outline is hidden in 3D (never a silent hidden filter).
- EmbeddingViewMosaic: exact 3D pick-by-index resolution — rowid for base
  tables, the configured identifier (size-gated to stay bounded) for
  rowid-less views/joins, coordinate fallback only when no exact identity
  exists. Coordinated-selection predicates prefer the semantic identifier,
  then rowid, then coordinates, so a pick targets exactly the picked row.

Viewer
- A "Z (optional)" projection-column selector; choosing a Z column opens a
  navigable 3D view that round-trips through saved charts.

Backend
- --z to pass a precomputed Z column, and --umap-n-components 3 to generate a
  3D projection.

Tests
- camera3d, matrix, and mosaic_client (pick identity + predicate ordering)
  unit tests; backend CLI and projection coverage. Wires the component
  package into the JS test suite.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@domoritz

Copy link
Copy Markdown
Member

Could you share a few screenshots and maybe a video? Would love to see this even though we obviously can't take on such a big maintenance commitment.

Follow-up pass on the navigable 3D view: fixes real robustness/pick bugs,
removes code that did not earn its place, and closes 2D/3D coherence gaps.

Correctness
- Guard pointsBounds3D against NaN/Inf coordinates so a null/NaN z can no
  longer poison the centroid into a blank-view camera.
- Stop a focus double-click from first clearing a hidden 3D filter; in 3D the
  filter now clears only on an empty-space click.
- Guard the rowid probe against a shadowing user column named `rowid`.
- Cast SUM/MAX(count) to BIGINT (overflow) and convert to Number at the JS
  boundary so density init never throws on bigint arithmetic.

Cleanup
- Delete the production-dead frustumSampleIndices/emitFrustumSample and
  matrix4_transform_point; fix the stale "Web Worker" comment.
- Remove the size-gated identifier-materialization pick tier; pick identity is
  now rowid -> coordinate+z. The coordinate fallback returns indeterminate when
  distinct identifiers collide at the exact rendered coordinates (COUNT DISTINCT),
  rather than selecting an arbitrary sibling.
- Refactor EmbeddingViewImpl to accept x/y/z/category as separate reactive props,
  dissolving ~10 shadow variables and the data-wrapper churn machinery.

3D UX parity
- Scroll zoom-to-cursor, density-adaptive point size, occlusion-aware tooltips,
  perspective-aware highlight ring.

Coherence & backend
- Expose and persist fogDensity in the viewer; export Camera3DState from the
  umbrella package; fix the stale points-3d Select value.
- Error on --umap-n-components 3 with precomputed --x/--y or --disable-projection;
  validate the --z column exists and is numeric.

Tests & docs
- 61 component tests (queryClosestPoint3D, rowid/BIGINT paths, bounds NaN,
  degenerate matrix) and backend CLI coverage; README/docs mention 3D.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.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