Skip to content

Commit 006b114

Browse files
authored
Merge branch 'master' into kyle/tileset2d-generic-tileindex
2 parents b4f3e5b + 6795cc9 commit 006b114

172 files changed

Lines changed: 3575 additions & 682 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

AGENTS.md

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
# Repository Guidance
2+
3+
This file applies to the entire `deck.gl` repository. More specific `AGENTS.md` files in
4+
subdirectories may add local guidance.
5+
6+
## Setup Commands
7+
8+
- Install dependencies from the repo root: `yarn`
9+
- Build packages: `yarn build`
10+
- Run lint: `yarn lint`
11+
- Run all tests: `yarn test`
12+
- Run headless tests: `yarn test-headless`
13+
- Run render tests: `yarn test-render`
14+
- Run browser tests: `yarn test-browser`
15+
- Run website checks: `yarn test-website`
16+
- Use the exact script names from `package.json`; do not substitute spaced forms such as
17+
`yarn test headless`.
18+
19+
## Before Committing
20+
21+
- Run the most relevant tests for the changed packages, integrations, examples, or docs.
22+
- Run `yarn lint` for JavaScript and TypeScript changes. If lint failures are unrelated existing
23+
issues, call that out explicitly instead of hiding it.
24+
- If dependencies or package metadata changed, run `yarn` in the repo root and include any
25+
`yarn.lock` updates.
26+
- Do not reformat files you are not otherwise changing. Keep formatting-only churn separate from
27+
logic changes when practical.
28+
29+
## Ready For Merge
30+
31+
When asked to "get ready for merge", do a full merge-readiness pass:
32+
33+
- Audit the public API surface touched by the change. Add or update TSDoc for every new or changed
34+
public class, function, method, property, and type.
35+
- Do a documentation pass when behavior, public API, examples, or migration guidance changed.
36+
Include relevant module docs, examples, sidebars, `docs/whats-new.md`, and upgrade or migration
37+
guide content.
38+
- Keep upgrade guides focused on breaking changes, removals, and deprecations. Put new-feature
39+
notes in the appropriate module docs or release notes instead.
40+
- Run `yarn` in the repo root so workspace metadata and `yarn.lock` are up to date, especially
41+
after any `package.json` change.
42+
- Run `yarn build` as the repo-wide type, declaration, and package build gate.
43+
- Run `yarn lint` for the final lint and formatting gate, then review the resulting diff.
44+
- Run the relevant tests for the changed packages, examples, integrations, and docs/website wiring.
45+
Typical commands are `yarn test`, `yarn test-headless`, `yarn test-render`, `yarn test-browser`,
46+
and `yarn test-website`.
47+
- For website or docs changes, run the website check from the repo root with `yarn test-website`.
48+
- Prepare a copyable Markdown PR description based on the branch diff compared to `master`. Start
49+
with the PR goals, then list the actual changes and validation.
50+
- In the final handoff, call out which merge-readiness gates passed, which were not run, and any
51+
remaining risk or unrelated pre-existing failures.
52+
53+
## Code Style
54+
55+
- Prefer TypeScript and ES module syntax.
56+
- Match the surrounding file style. In source files, use single quotes and semicolons.
57+
- Never abbreviate variable names. Use camelCase for variables, functions, and fields; PascalCase
58+
for types and classes; and CAPITAL_CASE for constants.
59+
- Prefer verb-noun names for functions and methods.
60+
- File names should be kebab-case unless an existing local convention differs.
61+
62+
## Dependencies
63+
64+
- Be conservative with new external dependencies. Add one only when it provides meaningful
65+
capability, not just a small utility.
66+
- Prefer vis.gl ecosystem packages when they fit the layering. Lower-level math or utility modules
67+
should not depend on deck.gl.
68+
- Prefer math.gl modules for math helpers.
69+
- Avoid lodash-style dependencies for simple operations.
70+
71+
## Investigation
72+
73+
- Do not fix problems by adding caches. Investigate why the problem occurs and address the root
74+
cause.

docs/api-reference/core/deck.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,8 @@ The canvas to render into. Can be either a HTMLCanvasElement or the element id.
5252

5353
luma.gl Device used to manage the application's connection with the GPU. Will be auto-created if not supplied.
5454

55+
When a `Device` is supplied, Deck does not destroy it when finalized. While the `Deck` instance is active, Deck owns the `device.props.onResize` callback for the active render canvas context; use `DeckProps.onResize` to observe Deck canvas resizes.
56+
5557
#### `deviceProps` ([DeviceProps](https://luma.gl/docs/api-reference/core/device#deviceprops) | [WebGLDeviceProps](https://luma.gl/docs/api-reference/webgl/#webgldeviceprops)) {#deviceprops}
5658

5759
Options used for creating a new luma.gl GPU [Device](https://luma.gl/docs/api-reference/core/device).
@@ -551,6 +553,7 @@ Receives arguments:
551553
* `size`
552554
- `width` (number) - the new width of the deck canvas, in client pixels
553555
- `height` (number) - the new height of the deck canvas, in client pixels
556+
* `canvasContext` ([CanvasContext](https://luma.gl/docs/api-reference/core/canvas-context), optional) - the luma.gl canvas context that reported the resize
554557
555558
556559
#### `onBeforeRender` (Function) {#onbeforerender}
@@ -773,7 +776,7 @@ Parameters:
773776
* `y` (number) - y position in pixels
774777
* `radius` (number, optional) - radius of tolerance in pixels. Default `0`.
775778
* `layerIds` (string[], optional) - a list of layer ids to query from. If not specified, then all pickable and visible layers are queried.
776-
* `depth` - Specifies the max number of objects to return. Default `10`.
779+
* `depth` - Specifies the max number of objects to return. Default `10`. For layers without explicit picking index buffers, only the default depth of 10 unique objects per layer is guaranteed; higher custom depths may return duplicate results for these layers.
777780
* `unproject3D` (boolean, optional) - if `true`, `info.coordinate` will be a 3D point by unprojecting the `x, y` screen coordinates onto the picked geometry. Default `false`.
778781
779782
Returns:
@@ -783,6 +786,7 @@ Returns:
783786
Notes:
784787
785788
* Deep picking is implemented as a sequence of simpler picking operations and can have a performance impact. Should this become a concern, you can use the `depth` parameter to limit the number of matches that can be returned, and thus the maximum number of picking operations.
789+
* Layers that provide explicit picking index buffers support buffer mutation between picking passes and are not subject to the default-depth unique-object guarantee.
786790
787791
788792
#### `pickObjects` {#pickobjects}

docs/api-reference/core/globe-controller.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,9 +38,10 @@ new Deck({
3838
Supports all [Controller options](./controller.md#options) with the following default behavior:
3939

4040
- `dragPan`: default `'pan'` (drag to pan)
41-
- `dragRotate`: not effective, this view does not currently support rotation
42-
- `touchRotate`: not effective, this view does not currently support rotation
41+
- `dragRotate`: shift+drag or right-click drag to change bearing and pitch
42+
- `touchRotate`: multi-touch rotate to change bearing
4343
- `keyboard`: arrow keys to pan, +/- to zoom
44+
- `inertia`: when set to a number (milliseconds), the globe continues spinning after a fling gesture with exponential decay
4445
- `maxBounds` - constrains the viewport to the specified bounding box `[[minLng, minLat], [maxLng, maxLat]]`
4546

4647
## Custom GlobeController

docs/api-reference/core/globe-view.md

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,7 @@ It's recommended that you read the [Views and Projections guide](../../developer
1818
## Limitations
1919

2020
The goal of `GlobeView` is to provide a generic solution to rendering and navigating data in the 3D space.
21-
In the initial release, this class mainly addresses the need to render an overview of the entire globe. The following limitations apply, as features are still under development:
2221

23-
- No support for rotation (`pitch` or `bearing`). The camera always points towards the center of the earth, with north up.
2422
- No high-precision rendering at high zoom levels (> 12). Features at the city-block scale may not be rendered accurately.
2523
- Only supports `'lnglat'` (the default value of the `coordinateSystem` prop).
2624
- Known rendering issues when using multiple views mixing `GlobeView` and `MapView`, or switching between the two.
@@ -72,8 +70,14 @@ To render, `GlobeView` needs to be used together with a `viewState` with the fol
7270
- `longitude` (number) - longitude at the viewport center
7371
- `latitude` (number) - latitude at the viewport center
7472
- `zoom` (number) - zoom level
73+
- `bearing` (number, optional) - bearing angle in degrees. Default `0` (north up).
74+
- `pitch` (number, optional) - pitch angle in degrees. `0` looks straight down at the earth. Default `0`.
7575
- `maxZoom` (number, optional) - max zoom level. Default `20`.
7676
- `minZoom` (number, optional) - min zoom level. Default `0`.
77+
- `maxPitch` (number, optional) - max pitch angle. Default `60`.
78+
- `minPitch` (number, optional) - min pitch angle. Default `0`.
79+
80+
When `bearing` is `0` (the default), north is always kept pointing up and the globe behaves like a traditional desk globe — horizontal drag changes longitude, vertical drag changes latitude, and the polar axis stays fixed. When the user changes the bearing (via shift+drag or right-click drag), the globe enters free rotation mode where bearing evolves naturally to avoid orientation discontinuities near the poles.
7781

7882

7983
## Controller

docs/api-reference/core/globe-viewport.md

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# GlobeViewport (Experimental)
22

3-
The `GlobeViewport` class takes globe view states (`latitude`, `longitude`, and `zoom`), and performs projections between world and screen coordinates. It is a helper class for visualizing the earth as a 3D globe.
3+
The `GlobeViewport` class takes globe view states (`latitude`, `longitude`, `zoom`, `bearing`, and `pitch`), and performs projections between world and screen coordinates. It is a helper class for visualizing the earth as a 3D globe.
44

55
## Usage
66

@@ -25,7 +25,7 @@ viewport.project([-122.45, 37.78]);
2525
## Constructor
2626

2727
```js
28-
new GlobeViewport({width, height, longitude, latitude, zoom});
28+
new GlobeViewport({width, height, longitude, latitude, zoom, bearing, pitch});
2929
```
3030

3131
Parameters:
@@ -40,11 +40,13 @@ Parameters:
4040
+ `latitude` (number, optional) - Latitude of the viewport center on map. Default to `0`.
4141
+ `longitude` (number, optional) - Longitude of the viewport center on map. Default to `0`.
4242
+ `zoom` (number, optional) - Map zoom (scale is calculated as `2^zoom`). Default to `11`.
43+
+ `bearing` (number, optional) - Bearing angle in degrees. Default to `0`.
44+
+ `pitch` (number, optional) - Pitch angle in degrees. Default to `0`.
4345
+ `altitude` (number, optional) - Altitude of camera, 1 unit equals to the height of the viewport. Default to `1.5`.
4446

4547
projection matrix arguments:
4648

47-
+ `nearZMultiplier` (number, optional) - Scaler for the near plane, 1 unit equals to the height of the viewport. Default to `0.1`.
49+
+ `nearZMultiplier` (number, optional) - Scaler for the near plane, 1 unit equals to the height of the viewport. Default to `0.01`.
4850
+ `farZMultiplier` (number, optional) - Scaler for the far plane, 1 unit equals to the distance from the camera to the top edge of the screen. Default to `1`.
4951

5052
Remarks:

docs/api-reference/widgets/overview.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ This module contains the following widgets:
2121

2222
- [FullscreenWidget](./fullscreen-widget.md)
2323
- [SplitterWidget](./splitter-widget.md)
24+
- [View Layout](./view-layout.md)
2425

2526
### Information Widgets
2627

docs/api-reference/widgets/splitter-widget.md

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,10 @@ function App() {
140140
## Constructor
141141

142142
```ts
143-
import {_SplitterWidget as SplitterWidget, type SplitterWidgetProps} from '@deck.gl/widgets';
143+
import {
144+
_SplitterWidget as SplitterWidget,
145+
type SplitterWidgetProps
146+
} from '@deck.gl/widgets';
144147
new SplitterWidget<ViewType[]>({} satisfies SplitterWidgetProps);
145148
```
146149

@@ -150,7 +153,7 @@ new SplitterWidget<ViewType[]>({} satisfies SplitterWidgetProps);
150153

151154
The `SplitterWidget` accepts the generic [`WidgetProps`](../core/widget.md#widgetprops) and:
152155

153-
#### `viewLayout` (ViewLayout, required) {#viewlayout}
156+
#### `viewLayout` (SplitterWidgetViewLayout, required) {#viewlayout}
154157

155158
Layout descriptor of how views are arranged on the canvas. Contains the following fields:
156159

@@ -161,7 +164,7 @@ Layout descriptor of how views are arranged on the canvas. Contains the followin
161164
- `minSplit` (number, optional) - Min value of the split. The user cannot make the first view smaller than this ratio. Default `0.05`.
162165
- `maxSplit` (number, optional) - Max value of the split. The user cannot make the first view larger than this ratio. Default `0.95`.
163166

164-
You may also replace one or both item in `views` with a `ViewLayout` object, composing more than two views into a complex layout.
167+
You may also replace one or both items in `views` with a nested `SplitterWidgetViewLayout` object, composing more than two views into a complex layout.
165168

166169

167170
#### `onChange` (Function, optional) {#onchange}
Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
# View Layout
2+
3+
The view layout helpers build stable deck.gl view arrays from a declarative layout tree. They are generic utilities for applications that need multiple coordinated views without hand-computing every view rectangle in render code.
4+
5+
```js
6+
import {buildViewsFromViewLayout} from '@deck.gl/widgets';
7+
```
8+
9+
## Usage
10+
11+
Start by defining the deck.gl `View` instances that your application needs. Then place them in a plain layout object tree and compile that tree for the current deck canvas size.
12+
13+
```tsx
14+
import React from 'react';
15+
import {DeckGL} from '@deck.gl/react';
16+
import {OrthographicView} from '@deck.gl/core';
17+
import {buildViewsFromViewLayout} from '@deck.gl/widgets';
18+
import type {ViewLayout} from '@deck.gl/widgets';
19+
20+
const VIEW_LAYOUT = {
21+
type: 'column',
22+
children: [
23+
new OrthographicView({id: 'header', height: 48, controller: false}),
24+
{
25+
type: 'row',
26+
children: [
27+
new OrthographicView({id: 'sidebar', controller: false}),
28+
{
29+
type: 'overlay',
30+
children: [
31+
new OrthographicView({id: 'main', controller: true}),
32+
new OrthographicView({
33+
id: 'minimap',
34+
x: 'calc(100% - 180px)',
35+
y: 16,
36+
width: 164,
37+
height: 120,
38+
controller: false,
39+
clear: true
40+
})
41+
]
42+
}
43+
]
44+
}
45+
]
46+
} satisfies ViewLayout;
47+
48+
export function App({width, height, layers}) {
49+
const compiled = buildViewsFromViewLayout({layout: VIEW_LAYOUT, width, height});
50+
return <DeckGL views={compiled.views} layers={layers} />;
51+
}
52+
```
53+
54+
The returned `compiled.rectsById` map contains the same resolved rectangles keyed by view id. Use it when you need to position DOM overlays next to deck views, debug the generated layout, or scope non-layer UI to a view rectangle.
55+
56+
The returned `compiled.splittersById` map contains splitter metadata for rows and columns that declare a `splitId`. For two-child splits, the splitter id is exactly `splitId`. For three or more children, the compiler creates one splitter between each adjacent pair using generated ids such as `splitId-0`, `splitId-1`, and so on. Applications that store split values can pass them back into `buildViewsFromViewLayout` via `splitValues`.
57+
58+
Layout items may also define `minPixels` and `maxPixels` to constrain their size in the parent stack axis. The compiler combines those pixel constraints with percentage-based `width` or `height` values, and with `minSplit` and `maxSplit` when returning splitter metadata.
59+
60+
Use `viewPropsById` when an application needs to control layout-only bounds for a view without rebuilding the static layout tree. Override values use the same length syntax as authored view props.
61+
62+
The layout tree is a discriminated union of plain objects:
63+
64+
- `row`: lays out children left to right.
65+
- `column`: lays out children top to bottom.
66+
- `overlay`: gives each child the same parent rectangle.
67+
- `spacer`: reserves empty fixed or flexible space.
68+
69+
Raw deck.gl `View` instances are leaf nodes in `children`. Put layout-only `width`, `height`, `x`, and `y` props directly on the `View` when a leaf needs fixed sizing or overlay positioning.
70+
71+
For split layouts, `ViewLayout` also accepts the `SplitterWidgetViewLayout`-style aliases `orientation: 'horizontal' | 'vertical'` and `views`. A horizontal orientation is equivalent to `type: 'row'`; a vertical orientation is equivalent to `type: 'column'`.
72+
73+
`buildViewsFromViewLayout` compiles a layout tree into:
74+
75+
- `views`: concrete deck.gl views with numeric `x`, `y`, `width`, and `height`.
76+
- `rectsById`: resolved rectangles keyed by deck view id.
77+
- `splittersById`: resolved splitter metadata keyed by split id.
78+
79+
## Layout Sizing
80+
81+
`width`, `height`, `x`, and `y` accept numbers or CSS-like length strings such as percentages and simple `calc(...)` expressions. The compiler resolves those values against the current parent rectangle before passing numeric bounds to deck.gl.
82+
83+
```ts
84+
new OrthographicView({
85+
id: 'overlay',
86+
x: '50%',
87+
width: 'calc(50% - 12px)',
88+
height: 80
89+
});
90+
```
91+
92+
## View Reuse
93+
94+
Pass the previous `CompiledDeckViews` result back to `buildViewsFromViewLayout` when a caller needs structural view reuse across renders. A previous view is reused when its id, constructor, and resolved props match the next compilation.
95+
96+
```ts
97+
let compiled = buildViewsFromViewLayout({layout, width, height});
98+
99+
compiled = buildViewsFromViewLayout({
100+
layout,
101+
width,
102+
height,
103+
previous: compiled
104+
});
105+
```
106+
107+
## Types
108+
109+
### `ViewLayout`
110+
111+
Plain discriminated layout object. Children may be nested layout objects, raw deck.gl `View` instances, or falsey optional children.
112+
113+
### `buildViewsFromViewLayout`
114+
115+
Compiles a layout tree for the current deck canvas size.
116+
117+
Parameters:
118+
119+
- `layout` (`ViewLayout`) - Root layout tree to compile.
120+
- `width` (`number`) - Current deck width in pixels.
121+
- `height` (`number`) - Current deck height in pixels.
122+
- `previous` (`CompiledDeckViews`, optional) - Previous compilation for view reuse.
123+
- `splitValues` (`Record<string, number>`, optional) - Controlled split ratios keyed by layout `splitId`.
124+
- `viewPropsById` (`Record<string, {x?, y?, width?, height?}>`, optional) - Controlled layout-only view prop overrides keyed by deck view id.
125+
126+
Returns:
127+
128+
- `views` (`View[]`) - Concrete deck.gl views.
129+
- `rectsById` (`Record<string, {x, y, width, height}>`) - Resolved rectangles keyed by view id.
130+
131+
## Source
132+
133+
[modules/widgets/src/view-layout/build-views-from-view-layout.ts](https://github.com/visgl/deck.gl/tree/master/modules/widgets/src/view-layout/build-views-from-view-layout.ts)

docs/developer-guide/custom-layers/attribute-management.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ While most apps rely on their layers to automatically generate appropriate GPU b
4747

4848
While this allows for ultimate performance and control of updates, as well as potential sharing of buffers between layers, the application will need to generate attributes in exactly the format that the layer shaders expect, creating a strong coupling between the application and the layer.
4949

50-
**Note:** The application can provide some buffers and let others be managed by the layer. As an example management of the `instancePickingColors` buffer is normally left to the layer.
50+
**Note:** The application can provide some buffers and let others be managed by the layer. Explicit picking index buffers are only needed when the logical picking id differs from the rendered instance id.
5151

5252

5353
## More information

docs/developer-guide/custom-layers/layer-attributes.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ For _variable primitive layers_ there are two options:
5555

5656
2) Copy each descriptive attribute `N` times (`N` being the number of vertices generated for that row during tesselation). This is the method that is used in deck.gl today.
5757

58-
3) Add a single `rowIndex` attribute and copy the same index `N` times as above. In this approach, descriptive values could then be read from textures where they are stored a single time. This provides flexibility at the price of performance (texture access latency) and complexity (working with data in textures).
58+
3) Add a single `rowIndexes` attribute and copy the same index `N` times as above. In this approach, descriptive values could then be read from textures where they are stored a single time. This provides flexibility at the price of performance (texture access latency) and complexity (working with data in textures).
5959

6060

6161
Remarks:

0 commit comments

Comments
 (0)