Skip to content

feat(GlobeViewOp): add pitch, bearing, resolution, and touch rotation#415

Draft
charlieforward9 wants to merge 1 commit into
joby-aviation:mainfrom
NEW-HEAT:ai_globe-touch-controls-upstream
Draft

feat(GlobeViewOp): add pitch, bearing, resolution, and touch rotation#415
charlieforward9 wants to merge 1 commit into
joby-aviation:mainfrom
NEW-HEAT:ai_globe-touch-controls-upstream

Conversation

@charlieforward9

@charlieforward9 charlieforward9 commented Apr 13, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Add resolution, controller, bearing, and pitch fields to GlobeViewOp — supported by deck.gl's GlobeView but missing from the operator, so values were silently dropped
  • When controller is true, pass { touchRotate: true } to GlobeView, enabling two-finger rotation for pitch/bearing on mobile

Dependencies

Blocked on visgl/deck.gl#10207 — this PR relies on GlobeView pitch/bearing support landing in deck.gl first. The pitch and bearing viewState fields added here have no effect until that deck.gl PR is merged and released.

Context

deck.gl's GlobeView supports pitch and bearing (via visgl/deck.gl#10207), but the noodles GlobeViewOp only exposed latitude, longitude, and zoom in its viewState. This meant there was no gesture path to change pitch or bearing on touch devices — touchRotate defaults to false in deck.gl's base Controller.

Changes

  • resolution NumberField (default 10, controls mesh detail for flat-to-3D conversion)
  • controller BooleanField (default true, enables/disables interaction)
  • bearing NumberField in viewState (optional)
  • pitch NumberField in viewState (0-60, optional, matching GlobeView maxPitch)
  • execute() converts controller: true to { touchRotate: true } so mobile two-finger rotation works out of the box

Test plan

  • GlobeView renders with pitch/bearing values from nib definition
  • Two-finger rotate gesture changes pitch/bearing on mobile
  • Single-finger drag still pans the globe
  • Pinch-zoom still works
  • controller: false disables all interaction

… support

GlobeViewOp was missing fields that GlobeView supports — pitch, bearing,
resolution, and controller options. This meant nib definitions passing
these values had them silently dropped, and there was no way to enable
touch rotation for mobile devices.

- Add resolution NumberField (mesh detail for flat-to-3D conversion)
- Add controller BooleanField (enables/disables interaction)
- Add bearing and pitch to viewState CompoundPropsField
- Convert controller:true to { touchRotate: true } in execute(),
  enabling two-finger rotation for pitch/bearing on mobile

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@greptile-apps

greptile-apps Bot commented Apr 13, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR adds resolution, controller, bearing, and pitch fields to GlobeViewOp, and converts controller: true to { touchRotate: true } to enable mobile two-finger rotation. The structural change (field additions, destructuring) is clean and consistent with the rest of the view operator pattern.

  • P1: deck.gl's own docs state that for GlobeController, both touchRotate and dragRotate are "not effective, this view does not currently support rotation" — meaning the PR's primary feature (touch rotation for pitch/bearing) is a no-op with the current deck.gl GlobeView. bearing and pitch may set initial viewState orientation, but interactive rotation won't work as advertised.

Confidence Score: 4/5

Mergeable with caution — the structural changes are sound but the advertised mobile rotation feature won't work as deck.gl's GlobeController explicitly doesn't support rotation.

One P1 finding: touchRotate: true is a no-op per deck.gl docs, so the PR's primary stated feature won't function. The added fields and refactoring are otherwise correct. Score is 4 rather than 3 because the changes don't break existing behavior — they just add non-functional fields.

noodles-editor/src/noodles/operators.ts — GlobeViewOp.execute and createInputs

Important Files Changed

Filename Overview
noodles-editor/src/noodles/operators.ts Adds resolution, controller, bearing, and pitch to GlobeViewOp — but touchRotate (the PR's primary mobile feature) is explicitly documented as a no-op in GlobeController.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[GlobeViewOp.execute] --> B{controller input}
    B -- true --> C["{ touchRotate: true }"]
    B -- false --> D["false (no interaction)"]
    C --> E["new GlobeView({ id, ...viewProps, controller })"]
    D --> E
    E --> F[GlobeController]
    F --> G["dragPan ✅ pan"]
    F --> H["scrollZoom ✅ zoom"]
    F --> I["touchRotate ⚠️ not effective per deck.gl docs"]
    F --> J["dragRotate ⚠️ not effective per deck.gl docs"]
    E --> K["viewState: { lat, lng, zoom, bearing?, pitch? }"]
Loading
Prompt To Fix All With AI
This is a comment left during a code review.
Path: noodles-editor/src/noodles/operators.ts
Line: 3726

Comment:
**`touchRotate` is documented as a no-op for GlobeController**

The deck.gl docs for `GlobeController` explicitly state:
> `touchRotate`: not effective, this view does not currently support rotation
> `dragRotate`: not effective, this view does not currently support rotation

Passing `{ touchRotate: true }` to the controller has no effect — the globe does not support pitch/bearing rotation at the controller level. The `bearing` and `pitch` viewState fields may set an initial orientation if deck.gl accepts them, but the two-finger-rotate gesture described in the PR test plan won't function. Worth verifying against the actual deck.gl version in use before adding these as advertised interactive features.

How can I resolve this? If you propose a fix, please make it concise.

---

This is a comment left during a code review.
Path: noodles-editor/src/noodles/operators.ts
Line: 3702

Comment:
**`resolution` scale is inverted relative to the field label**

Per deck.gl's docs, `resolution` is in *degrees*, and *smaller* numbers produce a more detailed mesh (default `10`). With `max: 90` the slider's high end yields only ~4 triangles across the globe — nearly invisible tessellation artifacts. A tighter upper bound (e.g. `max: 32`) and a `showByDefault: false` or tooltip noting "lower = finer mesh" would prevent accidental performance or quality surprises.

How can I resolve this? If you propose a fix, please make it concise.

Reviews (1): Last reviewed commit: "feat(GlobeViewOp): add pitch, bearing, r..." | Re-trigger Greptile

view: new GlobeView({
id: this.id,
...viewProps,
controller: controller ? { touchRotate: true } : false,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 touchRotate is documented as a no-op for GlobeController

The deck.gl docs for GlobeController explicitly state:

touchRotate: not effective, this view does not currently support rotation
dragRotate: not effective, this view does not currently support rotation

Passing { touchRotate: true } to the controller has no effect — the globe does not support pitch/bearing rotation at the controller level. The bearing and pitch viewState fields may set an initial orientation if deck.gl accepts them, but the two-finger-rotate gesture described in the PR test plan won't function. Worth verifying against the actual deck.gl version in use before adding these as advertised interactive features.

Prompt To Fix With AI
This is a comment left during a code review.
Path: noodles-editor/src/noodles/operators.ts
Line: 3726

Comment:
**`touchRotate` is documented as a no-op for GlobeController**

The deck.gl docs for `GlobeController` explicitly state:
> `touchRotate`: not effective, this view does not currently support rotation
> `dragRotate`: not effective, this view does not currently support rotation

Passing `{ touchRotate: true }` to the controller has no effect — the globe does not support pitch/bearing rotation at the controller level. The `bearing` and `pitch` viewState fields may set an initial orientation if deck.gl accepts them, but the two-finger-rotate gesture described in the PR test plan won't function. Worth verifying against the actual deck.gl version in use before adding these as advertised interactive features.

How can I resolve this? If you propose a fix, please make it concise.

return {
...createBaseViewFields(),
...createGeoViewFields(),
resolution: new NumberField(10, { min: 1, max: 90, step: 1 }),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 resolution scale is inverted relative to the field label

Per deck.gl's docs, resolution is in degrees, and smaller numbers produce a more detailed mesh (default 10). With max: 90 the slider's high end yields only ~4 triangles across the globe — nearly invisible tessellation artifacts. A tighter upper bound (e.g. max: 32) and a showByDefault: false or tooltip noting "lower = finer mesh" would prevent accidental performance or quality surprises.

Prompt To Fix With AI
This is a comment left during a code review.
Path: noodles-editor/src/noodles/operators.ts
Line: 3702

Comment:
**`resolution` scale is inverted relative to the field label**

Per deck.gl's docs, `resolution` is in *degrees*, and *smaller* numbers produce a more detailed mesh (default `10`). With `max: 90` the slider's high end yields only ~4 triangles across the globe — nearly invisible tessellation artifacts. A tighter upper bound (e.g. `max: 32`) and a `showByDefault: false` or tooltip noting "lower = finer mesh" would prevent accidental performance or quality surprises.

How can I resolve this? If you propose a fix, please make it concise.

@charlieforward9 charlieforward9 marked this pull request as draft April 13, 2026 17:03
@akre54

akre54 commented Apr 14, 2026

Copy link
Copy Markdown
Collaborator

Seems reasonable. @charlieforward9 what's the state of this pull? Anything holding back merge?

@charlieforward9

charlieforward9 commented Apr 14, 2026

Copy link
Copy Markdown
Contributor Author

visgl/deck.gl#10207 which Ib said is in @Pessimistress territory

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