BabylonJS / BabylonJS/Babylon-Lite
Geospatial Camera (Orbital)
- 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
Assessment
This issue has not been assessed yet.