BabylonJS / BabylonJS/Babylon-Lite

Geospatial Camera (Orbital)

Open
#14 2 comments 0 reactions 1 assignee Claimed by @georginahalpern View on GitHub
enhancement sub-project
Dominant language
TypeScript
Stars
149
Forks
29
Avg merge
1d 5h
Merged PRs (30d)
106

Description

Owner: Georgie

Subproject for the GeospatialCamera (orbital camera) port. See [`docs/architecture/28-geospatial-camera.md`](../blob/main/docs/architecture/28-geospatial-camera.md) for the full design. Milestones are feature-oriented — each one is independently shippable and lands with the tests that validate it.

## Milestones

- [x] **Milestone 1 — Precursors**
Details

- Verify `gpu-picker.ts` + a CPU ray-vs-mesh path exist and are callable from camera controls (drag-plane needs fast ray-vs-plane intersection).
- _Validation_: code-only verification, no new tests.

- [x] **Milestone 2 — Pure-math foundations**
Details

- Port `ComputeLocalBasisToRefs(worldPos) → {east, north, up}` with pole-singularity fallback (`camera/geospatial-math.ts`).
- Port `ComputeLookAtFromYawPitchToRef(center, yaw, pitch, radius) → {position, lookAt}`.
- Port `ComputeYawPitchFromLookAtToRef(...)` preserving previous yaw at pitch≈0.
- Port `ClampCenterFromPolesInPlace(center)` enforcing `|sin(lat)| ≤ 0.998749218`.
- _Validation_: Mirror BJS's `geospatialCamera.test.ts` round-trip + basis-orthonormality cases as Vitest unit tests.

- [x] **Milestone 3 — Camera type, view matrix, limits & static parity scene** (first renderable)
Details

- Define `GeospatialCamera` interface (`camera/geospatial.ts`) mirroring `ArcRotateCamera`'s plain-data + push-based-dirty shape.
- `createGeospatialCamera({ planetRadius, center?, yaw?, pitch?, radius? })` factory with BJS default pose.
- World matrix via yaw/pitch helpers + `mat4LookAt` (left-handed).
- `GeospatialLimits` value object (`radiusMin/Max`, `pitchMin/Max`, `yawMin/Max`, `pitchDisabledRadiusScale`, `clampZoomDistance`, `getEffectivePitchMax`).
- `zoomToPoint` / `zoomAlongLookAt` pure setters.
- _Validation_: unit tests for world matrix at sample poses; BJS reference scene `lab/babylon-ref-sceneN.html` (PG `#BNOR48`) + Lite mirror with static pose; golden capture (with user approval); parity spec; bundle-size ceiling; `pnpm test` green.

- [x] **Milestone 4 — Inertia / movement pipeline**
Details

- Per-camera accumulators (pan/rotation/zoom) + per-axis speeds + inertias, with BJS defaults.
- Per-frame `computeCurrentFrameDeltas()` with frame-rate-independent decay `inertia ^ (dt/16.67)`.
- Latitude/altitude scaling: pan `sqrt(cos(lat))` reduced by altitude; zoom multiplier `0.01 × distance(camera, zoomTarget)`; disable zoom mid-drag.
- _Validation_: Vitest unit tests for frame-decay over varying `dt` and lat/altitude scaling at sample positions.

- [x] **Milestone 5 — Drag-plane + mouse/wheel input** (first interactive)
Details

- Skeleton `attachGeospatialControl(camera, canvas, scene)` following the `arc-rotate-controls.ts` pattern.
- Drag-plane: `startDrag` / `_recalculateDragPlaneHitPoint` / `handleDrag` / `stopDrag` with hit-point tangent plane and 10% delta clamp.
- Pointer/mouse: left = drag, right/middle = tilt, wheel = zoom toward cursor (raycast + altitude-scaled).
- Re-pick `center` each `_checkInputs` to keep it anchored on the globe surface.
- _Validation_: plumbing test under `tests/plumbing/` simulating pointer events to verify drag-plane anchor invariants (cursor stays glued to picked surface point).

- [x] **Milestone 6 — Touch + keyboard input**
Details

- Touch: single-touch = drag; pinch = zoom toward centroid (raycast); pinch-to-pan threshold = 20 px.
- Keyboard: arrows pan (simulate drag from canvas center), Ctrl+arrows tilt, +/- zoom along look vector.
- _Validation_: plumbing tests simulating touch + keyboard events to verify drag/zoom invariants across input modalities.

- [ ] **Milestone 7 — Optional / later** (deferred until concrete demand; each item lands with its own test)
Details

- `flyToAsync` / `flyToPointAsync` / `updateFlyToDestination` + `InterpolatingBehavior` (SLERP center + parabolic hop).
- `GeospatialClippingBehavior` (altitude-based near/far adjustment).
- Collision integration (`checkCollisions`, `perFrameCollisionOffset`).
- `calculateUpVectorFromPointToRef` override hook for non-spherical bodies.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.