@deck.gl/core 9.3.0-alpha.3 → 9.3.0-alpha.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (75) hide show
  1. package/dist/controllers/terrain-controller.d.ts +7 -6
  2. package/dist/controllers/terrain-controller.d.ts.map +1 -1
  3. package/dist/controllers/terrain-controller.js +58 -39
  4. package/dist/controllers/terrain-controller.js.map +1 -1
  5. package/dist/dist.dev.js +3076 -1197
  6. package/dist/index.cjs +525 -212
  7. package/dist/index.cjs.map +4 -4
  8. package/dist/lib/attribute/gl-utils.d.ts +1 -2
  9. package/dist/lib/attribute/gl-utils.d.ts.map +1 -1
  10. package/dist/lib/attribute/gl-utils.js +2 -2
  11. package/dist/lib/attribute/gl-utils.js.map +1 -1
  12. package/dist/lib/deck-picker.d.ts +3 -2
  13. package/dist/lib/deck-picker.d.ts.map +1 -1
  14. package/dist/lib/deck-picker.js +74 -17
  15. package/dist/lib/deck-picker.js.map +1 -1
  16. package/dist/lib/deck.d.ts +62 -0
  17. package/dist/lib/deck.d.ts.map +1 -1
  18. package/dist/lib/deck.js +219 -77
  19. package/dist/lib/deck.js.map +1 -1
  20. package/dist/lib/init.js +2 -2
  21. package/dist/lib/layer.d.ts.map +1 -1
  22. package/dist/lib/layer.js +60 -9
  23. package/dist/lib/layer.js.map +1 -1
  24. package/dist/lib/view-manager.js +1 -1
  25. package/dist/lib/view-manager.js.map +1 -1
  26. package/dist/passes/pick-layers-pass.d.ts.map +1 -1
  27. package/dist/passes/pick-layers-pass.js +7 -2
  28. package/dist/passes/pick-layers-pass.js.map +1 -1
  29. package/dist/passes/screen-pass-uniforms.d.ts +1 -1
  30. package/dist/passes/screen-pass-uniforms.js +1 -1
  31. package/dist/shaderlib/color/color.d.ts +1 -4
  32. package/dist/shaderlib/color/color.d.ts.map +1 -1
  33. package/dist/shaderlib/color/color.js +0 -12
  34. package/dist/shaderlib/color/color.js.map +1 -1
  35. package/dist/shaderlib/misc/layer-uniforms.d.ts +3 -2
  36. package/dist/shaderlib/misc/layer-uniforms.d.ts.map +1 -1
  37. package/dist/shaderlib/misc/layer-uniforms.js +10 -1
  38. package/dist/shaderlib/misc/layer-uniforms.js.map +1 -1
  39. package/dist/shaderlib/picking/picking.d.ts +3 -2
  40. package/dist/shaderlib/picking/picking.d.ts.map +1 -1
  41. package/dist/shaderlib/picking/picking.js +29 -0
  42. package/dist/shaderlib/picking/picking.js.map +1 -1
  43. package/dist/shaderlib/project/project.glsl.js +1 -1
  44. package/dist/shaderlib/project/project.wgsl.d.ts.map +1 -1
  45. package/dist/shaderlib/project/project.wgsl.js +4 -6
  46. package/dist/shaderlib/project/project.wgsl.js.map +1 -1
  47. package/dist/shaderlib/shadow/shadow.d.ts +2 -2
  48. package/dist/shaderlib/shadow/shadow.js +1 -1
  49. package/dist/transitions/gpu-interpolation-transition.js +2 -2
  50. package/dist/transitions/gpu-interpolation-transition.js.map +1 -1
  51. package/dist/transitions/gpu-spring-transition.js +1 -1
  52. package/dist/transitions/gpu-transition-utils.d.ts.map +1 -1
  53. package/dist/transitions/gpu-transition-utils.js +3 -4
  54. package/dist/transitions/gpu-transition-utils.js.map +1 -1
  55. package/dist/utils/typed-array-manager.js.map +1 -1
  56. package/dist.min.js +506 -234
  57. package/package.json +6 -7
  58. package/src/controllers/terrain-controller.ts +60 -51
  59. package/src/lib/attribute/gl-utils.ts +2 -2
  60. package/src/lib/deck-picker.ts +98 -17
  61. package/src/lib/deck.ts +334 -86
  62. package/src/lib/layer.ts +98 -8
  63. package/src/lib/view-manager.ts +1 -1
  64. package/src/passes/pick-layers-pass.ts +6 -2
  65. package/src/passes/screen-pass-uniforms.ts +1 -1
  66. package/src/shaderlib/color/color.ts +0 -12
  67. package/src/shaderlib/misc/layer-uniforms.ts +11 -1
  68. package/src/shaderlib/picking/picking.ts +30 -0
  69. package/src/shaderlib/project/project.glsl.ts +1 -1
  70. package/src/shaderlib/project/project.wgsl.ts +4 -6
  71. package/src/shaderlib/shadow/shadow.ts +1 -1
  72. package/src/transitions/gpu-interpolation-transition.ts +2 -2
  73. package/src/transitions/gpu-spring-transition.ts +1 -1
  74. package/src/transitions/gpu-transition-utils.ts +4 -5
  75. package/src/utils/typed-array-manager.ts +3 -3
package/dist/index.cjs CHANGED
@@ -230,7 +230,7 @@ var json_loader_default = {
230
230
 
231
231
  // dist/lib/init.js
232
232
  function checkVersion() {
233
- const version = true ? "9.3.0-alpha.3" : globalThis.DECK_VERSION || "untranspiled source";
233
+ const version = true ? "9.3.0-alpha.5" : globalThis.DECK_VERSION || "untranspiled source";
234
234
  const existingVersion = globalThis.deck && globalThis.deck.VERSION;
235
235
  if (existingVersion && existingVersion !== version) {
236
236
  throw new Error(`deck.gl - multiple versions detected: ${existingVersion} vs ${version}`);
@@ -260,12 +260,23 @@ var import_shadertools3 = require("@luma.gl/shadertools");
260
260
  var import_shadertools4 = require("@luma.gl/shadertools");
261
261
 
262
262
  // dist/shaderlib/misc/layer-uniforms.js
263
- var uniformBlock = `uniform layerUniforms {
263
+ var uniformBlockWGSL = (
264
+ /* wgsl */
265
+ `struct LayerUniforms {
266
+ opacity: f32,
267
+ };
268
+
269
+ @group(0) @binding(auto)
270
+ var<uniform> layer: LayerUniforms;
271
+ `
272
+ );
273
+ var uniformBlock = `layout(std140) uniform layerUniforms {
264
274
  uniform float opacity;
265
275
  } layer;
266
276
  `;
267
277
  var layerUniforms = {
268
278
  name: "layer",
279
+ source: uniformBlockWGSL,
269
280
  vs: uniformBlock,
270
281
  fs: uniformBlock,
271
282
  getUniforms: (props) => {
@@ -285,15 +296,6 @@ var colorWGSL = (
285
296
  /* WGSL */
286
297
  `
287
298
 
288
- struct ColorUniforms {
289
- opacity: f32,
290
- };
291
-
292
- var<private> color: ColorUniforms = ColorUniforms(1.0);
293
- // TODO (kaapp) avoiding binding index collisions to handle layer opacity
294
- // requires some thought.
295
- // @group(0) @binding(0) var<uniform> color: ColorUniforms;
296
-
297
299
  @must_use
298
300
  fn deckgl_premultiplied_alpha(fragColor: vec4<f32>) -> vec4<f32> {
299
301
  return vec4(fragColor.rgb * fragColor.a, fragColor.a);
@@ -306,9 +308,6 @@ var color_default = {
306
308
  source: colorWGSL,
307
309
  getUniforms: (_props) => {
308
310
  return {};
309
- },
310
- uniformTypes: {
311
- opacity: "f32"
312
311
  }
313
312
  // @ts-ignore TODO v9.1
314
313
  };
@@ -716,14 +715,13 @@ struct ProjectUniforms {
716
715
  pseudoMeters: i32,
717
716
  };
718
717
 
719
- @group(0) @binding(0)
718
+ @group(0) @binding(auto)
720
719
  var<uniform> project: ProjectUniforms;
721
720
 
722
721
  // -----------------------------------------------------------------------------
723
- // Geometry data
724
- // (In your GLSL code, "geometry" was assumed to be available globally. In WGSL,
725
- // you might supply this via vertex attributes or a uniform. Here we define a
726
- // uniform struct for demonstration.)
722
+ // Geometry data shared across the project helpers.
723
+ // The active layer shader is responsible for populating this private module
724
+ // state before calling the project functions below.
727
725
  // -----------------------------------------------------------------------------
728
726
 
729
727
  // Structure to carry additional geometry data used by deck.gl filters.
@@ -736,7 +734,6 @@ struct Geometry {
736
734
  pickingColor: vec3<f32>,
737
735
  };
738
736
 
739
- // @group(0) @binding(1)
740
737
  var<private> geometry: Geometry;
741
738
  `
742
739
  );
@@ -981,7 +978,7 @@ var projectGLSL = (
981
978
  `${COORDINATE_SYSTEM_GLSL_CONSTANTS}
982
979
  ${PROJECTION_MODE_GLSL_CONSTANTS}
983
980
  ${UNIT_GLSL_CONSTANTS}
984
- uniform projectUniforms {
981
+ layout(std140) uniform projectUniforms {
985
982
  bool wrapLongitude;
986
983
  int coordinateSystem;
987
984
  vec3 commonUnitsPerMeter;
@@ -1296,7 +1293,7 @@ var import_web_mercator = require("@math.gl/web-mercator");
1296
1293
  var uniformBlock2 = (
1297
1294
  /* glsl */
1298
1295
  `
1299
- uniform shadowUniforms {
1296
+ layout(std140) uniform shadowUniforms {
1300
1297
  bool drawShadowMap;
1301
1298
  bool useShadowMap;
1302
1299
  vec4 color;
@@ -1524,8 +1521,39 @@ var shadow_default = {
1524
1521
 
1525
1522
  // dist/shaderlib/picking/picking.js
1526
1523
  var import_shadertools2 = require("@luma.gl/shadertools");
1524
+ var sourceWGSL = (
1525
+ /* wgsl */
1526
+ `struct pickingUniforms {
1527
+ isActive: f32,
1528
+ isAttribute: f32,
1529
+ isHighlightActive: f32,
1530
+ useFloatColors: f32,
1531
+ highlightedObjectColor: vec3<f32>,
1532
+ highlightColor: vec4<f32>,
1533
+ };
1534
+
1535
+ @group(0) @binding(auto) var<uniform> picking: pickingUniforms;
1536
+
1537
+ fn picking_normalizeColor(color: vec3<f32>) -> vec3<f32> {
1538
+ return select(color / 255.0, color, picking.useFloatColors > 0.5);
1539
+ }
1540
+
1541
+ fn picking_normalizeColor4(color: vec4<f32>) -> vec4<f32> {
1542
+ return select(color / 255.0, color, picking.useFloatColors > 0.5);
1543
+ }
1544
+
1545
+ fn picking_isColorZero(color: vec3<f32>) -> bool {
1546
+ return dot(color, vec3<f32>(1.0)) < 0.00001;
1547
+ }
1548
+
1549
+ fn picking_isColorValid(color: vec3<f32>) -> bool {
1550
+ return dot(color, vec3<f32>(1.0)) > 0.00001;
1551
+ }
1552
+ `
1553
+ );
1527
1554
  var picking_default = {
1528
1555
  ...import_shadertools2.picking,
1556
+ source: sourceWGSL,
1529
1557
  defaultUniforms: { ...import_shadertools2.picking.defaultUniforms, useFloatColors: false },
1530
1558
  inject: {
1531
1559
  "vs:DECKGL_FILTER_GL_POSITION": `
@@ -2949,7 +2977,7 @@ var import_shadertools5 = require("@luma.gl/shadertools");
2949
2977
  var import_engine = require("@luma.gl/engine");
2950
2978
 
2951
2979
  // dist/passes/screen-pass-uniforms.js
2952
- var uniformBlock3 = `uniform screenUniforms {
2980
+ var uniformBlock3 = `layout(std140) uniform screenUniforms {
2953
2981
  vec2 texSize;
2954
2982
  } screen;
2955
2983
  `;
@@ -3176,7 +3204,11 @@ var PickLayersPass = class extends LayersPass {
3176
3204
  } else if (pickable && operation.includes("draw")) {
3177
3205
  Object.assign(pickParameters, PICKING_BLENDING);
3178
3206
  pickParameters.blend = true;
3179
- pickParameters.blendColor = encodeColor(this._colorEncoderState, layer, viewport);
3207
+ if (this.device.type === "webgpu") {
3208
+ pickParameters.blendConstant = encodeColor(this._colorEncoderState, layer, viewport);
3209
+ } else {
3210
+ pickParameters.blendColor = encodeColor(this._colorEncoderState, layer, viewport);
3211
+ }
3180
3212
  if (operation.includes("terrain") && ((_a = layer.state) == null ? void 0 : _a._hasPickingCover)) {
3181
3213
  pickParameters.blendAlphaSrcFactor = "one";
3182
3214
  }
@@ -6147,6 +6179,9 @@ var DeckRenderer = class {
6147
6179
  }
6148
6180
  };
6149
6181
 
6182
+ // dist/lib/deck-picker.js
6183
+ var import_core16 = require("@luma.gl/core");
6184
+
6150
6185
  // dist/lib/picking/query-object.js
6151
6186
  var NO_PICKED_OBJECT = {
6152
6187
  pickedColor: null,
@@ -6355,7 +6390,7 @@ var DeckPicker = class {
6355
6390
  /**
6356
6391
  * Pick the closest info at given coordinate
6357
6392
  * @returns picking info
6358
- * @deprecated WebGL only - use pickObjectAsync instead
6393
+ * @note WebGL only - use pickObjectAsync instead
6359
6394
  */
6360
6395
  pickObject(opts) {
6361
6396
  return this._pickClosestObject(opts);
@@ -6363,7 +6398,7 @@ var DeckPicker = class {
6363
6398
  /**
6364
6399
  * Get all unique infos within a bounding box
6365
6400
  * @returns all unique infos within a bounding box
6366
- * @deprecated WebGL only - use pickObjectAsync instead
6401
+ * @note WebGL only - use pickObjectAsync instead
6367
6402
  */
6368
6403
  pickObjects(opts) {
6369
6404
  return this._pickVisibleObjects(opts);
@@ -6389,13 +6424,25 @@ var DeckPicker = class {
6389
6424
  _resizeBuffer() {
6390
6425
  var _a, _b;
6391
6426
  if (!this.pickingFBO) {
6427
+ const pickingColorTexture = this.device.createTexture({
6428
+ format: "rgba8unorm",
6429
+ width: 1,
6430
+ height: 1,
6431
+ usage: import_core16.Texture.RENDER_ATTACHMENT | import_core16.Texture.COPY_SRC
6432
+ });
6392
6433
  this.pickingFBO = this.device.createFramebuffer({
6393
- colorAttachments: ["rgba8unorm"],
6434
+ colorAttachments: [pickingColorTexture],
6394
6435
  depthStencilAttachment: "depth16unorm"
6395
6436
  });
6396
6437
  if (this.device.isTextureFormatRenderable("rgba32float")) {
6438
+ const depthColorTexture = this.device.createTexture({
6439
+ format: "rgba32float",
6440
+ width: 1,
6441
+ height: 1,
6442
+ usage: import_core16.Texture.RENDER_ATTACHMENT | import_core16.Texture.COPY_SRC
6443
+ });
6397
6444
  const depthFBO = this.device.createFramebuffer({
6398
- colorAttachments: ["rgba32float"],
6445
+ colorAttachments: [depthColorTexture],
6399
6446
  depthStencilAttachment: "depth16unorm"
6400
6447
  });
6401
6448
  this.depthFBO = depthFBO;
@@ -6453,7 +6500,7 @@ var DeckPicker = class {
6453
6500
  for (let i = 0; i < depth; i++) {
6454
6501
  let pickInfo;
6455
6502
  if (deviceRect) {
6456
- const pickedResult = this._drawAndSample({
6503
+ const pickedResult = await this._drawAndSampleAsync({
6457
6504
  layers: pickableLayers,
6458
6505
  views,
6459
6506
  viewports,
@@ -6479,7 +6526,7 @@ var DeckPicker = class {
6479
6526
  let z;
6480
6527
  const depthLayers = this._getDepthLayers(pickInfo, pickableLayers, unproject3D);
6481
6528
  if (depthLayers.length > 0) {
6482
- const { pickedColors: pickedColors2 } = this._drawAndSample({
6529
+ const { pickedColors: pickedColors2 } = await this._drawAndSampleAsync({
6483
6530
  layers: depthLayers,
6484
6531
  views,
6485
6532
  viewports,
@@ -6666,7 +6713,7 @@ var DeckPicker = class {
6666
6713
  width: deviceRight - deviceLeft,
6667
6714
  height: deviceTop - deviceBottom
6668
6715
  };
6669
- const pickedResult = this._drawAndSample({
6716
+ const pickedResult = await this._drawAndSampleAsync({
6670
6717
  layers: pickableLayers,
6671
6718
  views,
6672
6719
  viewports,
@@ -6777,6 +6824,7 @@ var DeckPicker = class {
6777
6824
  }
6778
6825
  // Note: Implementation of the overloaded signatures above, TSDoc is on the signatures
6779
6826
  async _drawAndSampleAsync({ layers, views, viewports, onViewportActive, deviceRect, cullRect, effects, pass }, pickZ = false) {
6827
+ var _a;
6780
6828
  const pickingFBO = pickZ ? this.depthFBO : this.pickingFBO;
6781
6829
  const opts = {
6782
6830
  layers,
@@ -6801,16 +6849,58 @@ var DeckPicker = class {
6801
6849
  const { decodePickingColor, stats } = this.pickLayersPass.render(opts);
6802
6850
  this._updateStats(stats);
6803
6851
  const { x, y, width, height } = deviceRect;
6804
- const pickedColors = new (pickZ ? Float32Array : Uint8Array)(width * height * 4);
6805
- this.device.readPixelsToArrayWebGL(pickingFBO, {
6806
- sourceX: x,
6807
- sourceY: y,
6808
- sourceWidth: width,
6809
- sourceHeight: height,
6810
- target: pickedColors
6811
- });
6852
+ const texture = (_a = pickingFBO.colorAttachments[0]) == null ? void 0 : _a.texture;
6853
+ if (!texture) {
6854
+ throw new Error("Picking framebuffer color attachment is missing");
6855
+ }
6856
+ const pickedColors = await this._readTextureDataAsync(texture, { x, y, width, height }, pickZ ? Float32Array : Uint8Array);
6857
+ if (!pickZ) {
6858
+ let hasNonZeroAlpha = false;
6859
+ for (let i = 3; i < pickedColors.length; i += 4) {
6860
+ if (pickedColors[i] !== 0) {
6861
+ hasNonZeroAlpha = true;
6862
+ break;
6863
+ }
6864
+ }
6865
+ if (!hasNonZeroAlpha && pickedColors.length > 0) {
6866
+ log_default.warn("Async pick readback returned only zero alpha values", {
6867
+ deviceRect,
6868
+ bytes: Array.from(pickedColors.subarray(0, Math.min(pickedColors.length, 16)))
6869
+ })();
6870
+ }
6871
+ }
6812
6872
  return { pickedColors, decodePickingColor };
6813
6873
  }
6874
+ async _readTextureDataAsync(texture, options, ArrayType) {
6875
+ const { width, height } = options;
6876
+ const layout = texture.computeMemoryLayout(options);
6877
+ const readBuffer = this.device.createBuffer({
6878
+ byteLength: layout.byteLength,
6879
+ usage: import_core16.Buffer.COPY_DST | import_core16.Buffer.MAP_READ
6880
+ });
6881
+ try {
6882
+ texture.readBuffer(options, readBuffer);
6883
+ const readData = await readBuffer.readAsync(0, layout.byteLength);
6884
+ const bytesPerElement = ArrayType.BYTES_PER_ELEMENT;
6885
+ if (layout.bytesPerRow % bytesPerElement !== 0) {
6886
+ throw new Error(`Texture readback row stride ${layout.bytesPerRow} is not aligned to ${bytesPerElement}-byte elements.`);
6887
+ }
6888
+ const source3 = new ArrayType(readData.buffer, readData.byteOffset, layout.byteLength / bytesPerElement);
6889
+ const packedRowLength = width * 4;
6890
+ const sourceRowLength = layout.bytesPerRow / bytesPerElement;
6891
+ if (sourceRowLength < packedRowLength) {
6892
+ throw new Error(`Texture readback row stride ${sourceRowLength} is smaller than packed row length ${packedRowLength}.`);
6893
+ }
6894
+ const packed = new ArrayType(width * height * 4);
6895
+ for (let row = 0; row < height; row++) {
6896
+ const sourceStart = row * sourceRowLength;
6897
+ packed.set(source3.subarray(sourceStart, sourceStart + packedRowLength), row * packedRowLength);
6898
+ }
6899
+ return packed;
6900
+ } finally {
6901
+ readBuffer.destroy();
6902
+ }
6903
+ }
6814
6904
  // Note: Implementation of the overloaded signatures above, TSDoc is on the signatures
6815
6905
  _drawAndSample({ layers, views, viewports, onViewportActive, deviceRect, cullRect, effects, pass }, pickZ = false) {
6816
6906
  const pickingFBO = pickZ ? this.depthFBO : this.pickingFBO;
@@ -7311,11 +7401,11 @@ TooltipWidget.defaultProps = {
7311
7401
  };
7312
7402
 
7313
7403
  // dist/lib/deck.js
7314
- var import_core16 = require("@luma.gl/core");
7404
+ var import_core17 = require("@luma.gl/core");
7315
7405
  var import_webgl = require("@luma.gl/webgl");
7316
7406
  var import_engine3 = require("@luma.gl/engine");
7317
7407
  var import_engine4 = require("@luma.gl/engine");
7318
- var import_constants11 = require("@luma.gl/constants");
7408
+ var import_constants11 = require("@luma.gl/webgl/constants");
7319
7409
  var import_stats2 = require("@probe.gl/stats");
7320
7410
  var import_mjolnir2 = require("mjolnir.js");
7321
7411
  function noop2() {
@@ -7329,6 +7419,7 @@ var defaultProps = {
7329
7419
  viewState: null,
7330
7420
  initialViewState: null,
7331
7421
  pickingRadius: 0,
7422
+ pickAsync: "auto",
7332
7423
  layerFilter: null,
7333
7424
  parameters: {},
7334
7425
  parent: null,
@@ -7414,6 +7505,8 @@ var Deck = class {
7414
7505
  gpuMemory: 0
7415
7506
  };
7416
7507
  this._metricsCounter = 0;
7508
+ this._hoverPickSequence = 0;
7509
+ this._pointerDownPickSequence = 0;
7417
7510
  this._needsRedraw = "Initial render";
7418
7511
  this._pickRequest = {
7419
7512
  mode: "hover",
@@ -7424,6 +7517,7 @@ var Deck = class {
7424
7517
  unproject3D: false
7425
7518
  };
7426
7519
  this._lastPointerDownInfo = null;
7520
+ this._lastPointerDownInfoPromise = null;
7427
7521
  this._onPointerMove = (event) => {
7428
7522
  const { _pickRequest } = this;
7429
7523
  if (event.type === "pointerleave") {
@@ -7452,49 +7546,63 @@ var Deck = class {
7452
7546
  if (!eventHandlerProp || !pos || !this.layerManager) {
7453
7547
  return;
7454
7548
  }
7455
- let info;
7456
7549
  const layers = this.layerManager.getLayers();
7457
- const has3DPickableLayers = layers.some((layer2) => layer2.props.pickable === "3d");
7458
- if (event.type === "click" && has3DPickableLayers) {
7459
- const pickResult = this._pick("pickObject", "pickObject Time", {
7460
- x: pos.x,
7461
- y: pos.y,
7462
- radius: this.props.pickingRadius,
7463
- unproject3D: true
7464
- });
7465
- info = pickResult.result[0] || pickResult.emptyInfo;
7466
- } else {
7467
- info = this.deckPicker.getLastPickedObject({
7468
- x: pos.x,
7469
- y: pos.y,
7470
- layers,
7471
- viewports: this.getViewports(pos)
7472
- }, this._lastPointerDownInfo);
7473
- }
7474
- const { layer } = info;
7475
- const layerHandler = layer && (layer[eventHandlerProp] || layer.props[eventHandlerProp]);
7476
- const rootHandler = this.props[eventHandlerProp];
7477
- let handled = false;
7478
- if (layerHandler) {
7479
- handled = layerHandler.call(layer, info, event);
7550
+ const internalPickingMode = this._getInternalPickingMode();
7551
+ if (!internalPickingMode) {
7552
+ return;
7480
7553
  }
7481
- if (!handled) {
7482
- rootHandler == null ? void 0 : rootHandler(info, event);
7483
- this.widgetManager.onEvent(info, event);
7554
+ if (internalPickingMode === "sync") {
7555
+ const info = event.type === "click" && this._shouldUnproject3D(layers) ? this._getFirstPickedInfo(this._pickPointSync(this._getPointPickOptions(pos.x, pos.y, { unproject3D: true }, layers))) : this._getLastPointerDownPickingInfo(pos.x, pos.y, layers);
7556
+ this._dispatchPickingEvent(info, event);
7557
+ return;
7484
7558
  }
7559
+ const pointerDownInfoPromise = this._lastPointerDownInfoPromise || Promise.resolve(this._getLastPointerDownPickingInfo(pos.x, pos.y, layers));
7560
+ pointerDownInfoPromise.then((info) => {
7561
+ this._dispatchPickingEvent(info, event);
7562
+ }).catch((error) => {
7563
+ var _a2, _b;
7564
+ return (_b = (_a2 = this.props).onError) == null ? void 0 : _b.call(_a2, error);
7565
+ });
7485
7566
  };
7486
7567
  this._onPointerDown = (event) => {
7487
7568
  var _a2;
7488
- if (((_a2 = this.device) == null ? void 0 : _a2.type) === "webgpu") {
7569
+ const pos = event.offsetCenter;
7570
+ if (!pos) {
7489
7571
  return;
7490
7572
  }
7491
- const pos = event.offsetCenter;
7492
- const pickedInfo = this._pick("pickObject", "pickObject Time", {
7493
- x: pos.x,
7494
- y: pos.y,
7495
- radius: this.props.pickingRadius
7573
+ const internalPickingMode = this._getInternalPickingMode();
7574
+ if (!internalPickingMode) {
7575
+ return;
7576
+ }
7577
+ const layers = ((_a2 = this.layerManager) == null ? void 0 : _a2.getLayers()) || [];
7578
+ const pointerDownPickSequence = ++this._pointerDownPickSequence;
7579
+ if (internalPickingMode === "sync") {
7580
+ const pickedInfo = this._pickPointSync({
7581
+ x: pos.x,
7582
+ y: pos.y,
7583
+ radius: this.props.pickingRadius
7584
+ });
7585
+ const info = this._getFirstPickedInfo(pickedInfo);
7586
+ this._lastPointerDownInfo = info;
7587
+ this._lastPointerDownInfoPromise = Promise.resolve(info);
7588
+ return;
7589
+ }
7590
+ const pickPromise = this._pickPointAsync(this._getPointPickOptions(pos.x, pos.y, {}, layers)).then((pickResult) => this._getFirstPickedInfo(pickResult)).then((info) => {
7591
+ if (pointerDownPickSequence === this._pointerDownPickSequence) {
7592
+ this._lastPointerDownInfo = info;
7593
+ }
7594
+ return info;
7595
+ }).catch((error) => {
7596
+ var _a3, _b;
7597
+ (_b = (_a3 = this.props).onError) == null ? void 0 : _b.call(_a3, error);
7598
+ const fallbackInfo = this.deckPicker && this.viewManager ? this._getLastPointerDownPickingInfo(pos.x, pos.y, layers) : {};
7599
+ if (pointerDownPickSequence === this._pointerDownPickSequence) {
7600
+ this._lastPointerDownInfo = fallbackInfo;
7601
+ }
7602
+ return fallbackInfo;
7496
7603
  });
7497
- this._lastPointerDownInfo = pickedInfo.result[0] || pickedInfo.emptyInfo;
7604
+ this._lastPointerDownInfo = null;
7605
+ this._lastPointerDownInfoPromise = pickPromise;
7498
7606
  };
7499
7607
  this.props = { ...defaultProps, ...props };
7500
7608
  props = this.props;
@@ -7541,7 +7649,10 @@ var Deck = class {
7541
7649
  (_a = this.animationLoop) == null ? void 0 : _a.stop();
7542
7650
  (_b = this.animationLoop) == null ? void 0 : _b.destroy();
7543
7651
  this.animationLoop = null;
7652
+ this._hoverPickSequence++;
7653
+ this._pointerDownPickSequence++;
7544
7654
  this._lastPointerDownInfo = null;
7655
+ this._lastPointerDownInfoPromise = null;
7545
7656
  (_c = this.layerManager) == null ? void 0 : _c.finalize();
7546
7657
  this.layerManager = null;
7547
7658
  (_d = this.viewManager) == null ? void 0 : _d.finalize();
@@ -7576,6 +7687,7 @@ var Deck = class {
7576
7687
  this.viewState = props.initialViewState;
7577
7688
  }
7578
7689
  Object.assign(this.props, props);
7690
+ this._validateInternalPickingMode();
7579
7691
  this._setCanvasSize(this.props);
7580
7692
  const resolvedProps = Object.create(this.props);
7581
7693
  Object.assign(resolvedProps, {
@@ -7680,16 +7792,37 @@ var Deck = class {
7680
7792
  return this.canvas;
7681
7793
  }
7682
7794
  /** Query the object rendered on top at a given point */
7795
+ async pickObjectAsync(opts) {
7796
+ const infos = (await this._pickAsync("pickObjectAsync", "pickObject Time", opts)).result;
7797
+ return infos.length ? infos[0] : null;
7798
+ }
7799
+ /**
7800
+ * Query all objects rendered on top within a bounding box
7801
+ * @note Caveat: this method performs multiple async GPU queries, so state could potentially change between calls.
7802
+ */
7803
+ async pickObjectsAsync(opts) {
7804
+ return await this._pickAsync("pickObjectsAsync", "pickObjects Time", opts);
7805
+ }
7806
+ /**
7807
+ * Query the object rendered on top at a given point
7808
+ * @deprecated WebGL only. Use `pickObjectsAsync` instead
7809
+ */
7683
7810
  pickObject(opts) {
7684
7811
  const infos = this._pick("pickObject", "pickObject Time", opts).result;
7685
7812
  return infos.length ? infos[0] : null;
7686
7813
  }
7687
- /* Query all rendered objects at a given point */
7814
+ /**
7815
+ * Query all rendered objects at a given point
7816
+ * @deprecated WebGL only. Use `pickObjectsAsync` instead
7817
+ */
7688
7818
  pickMultipleObjects(opts) {
7689
7819
  opts.depth = opts.depth || 10;
7690
7820
  return this._pick("pickObject", "pickMultipleObjects Time", opts).result;
7691
7821
  }
7692
- /* Query all objects rendered on top within a bounding box */
7822
+ /**
7823
+ * Query all objects rendered on top within a bounding box
7824
+ * @deprecated WebGL only. Use `pickObjectsAsync` instead
7825
+ */
7693
7826
  pickObjects(opts) {
7694
7827
  return this._pick("pickObjects", "pickObjects Time", opts);
7695
7828
  }
@@ -7698,8 +7831,11 @@ var Deck = class {
7698
7831
  * @private
7699
7832
  */
7700
7833
  _pickPositionForController(x, y) {
7701
- const pickResult = this.pickObject({ x, y, radius: 0, unproject3D: true });
7702
- return pickResult;
7834
+ const internalPickingMode = this._getInternalPickingMode();
7835
+ if (internalPickingMode !== "sync") {
7836
+ return null;
7837
+ }
7838
+ return this.pickObject({ x, y, radius: 0, unproject3D: true });
7703
7839
  }
7704
7840
  /** Experimental
7705
7841
  * Add a global resource for sharing among layers
@@ -7730,6 +7866,114 @@ var Deck = class {
7730
7866
  var _a;
7731
7867
  (_a = this.layerManager) == null ? void 0 : _a.removeDefaultShaderModule(module2);
7732
7868
  }
7869
+ // Private Methods
7870
+ _resolveInternalPickingMode() {
7871
+ var _a, _b;
7872
+ const { pickAsync } = this.props;
7873
+ const deviceType = ((_a = this.device) == null ? void 0 : _a.type) || ((_b = this.props.deviceProps) == null ? void 0 : _b.type);
7874
+ if (pickAsync === "auto") {
7875
+ return deviceType === "webgpu" ? "async" : "sync";
7876
+ }
7877
+ if (pickAsync === "sync" && deviceType === "webgpu") {
7878
+ throw new Error('`pickAsync: "sync"` is not supported when Deck is using a WebGPU device.');
7879
+ }
7880
+ return pickAsync;
7881
+ }
7882
+ _getInternalPickingMode() {
7883
+ var _a, _b;
7884
+ try {
7885
+ return this._resolveInternalPickingMode();
7886
+ } catch (error) {
7887
+ (_b = (_a = this.props).onError) == null ? void 0 : _b.call(_a, error);
7888
+ return null;
7889
+ }
7890
+ }
7891
+ _validateInternalPickingMode() {
7892
+ this._getInternalPickingMode();
7893
+ }
7894
+ _getFirstPickedInfo({ result, emptyInfo }) {
7895
+ return result[0] || emptyInfo;
7896
+ }
7897
+ _shouldUnproject3D(layers = ((_a) => (_a = this.layerManager) == null ? void 0 : _a.getLayers())() || []) {
7898
+ return layers.some((layer) => layer.props.pickable === "3d");
7899
+ }
7900
+ _getPointPickOptions(x, y, opts = {}, layers = ((_b) => (_b = this.layerManager) == null ? void 0 : _b.getLayers())() || []) {
7901
+ return {
7902
+ x,
7903
+ y,
7904
+ radius: this.props.pickingRadius,
7905
+ unproject3D: this._shouldUnproject3D(layers),
7906
+ ...opts
7907
+ };
7908
+ }
7909
+ _pickPointSync(opts) {
7910
+ return this._pick("pickObject", "pickObject Time", opts);
7911
+ }
7912
+ _pickPointAsync(opts) {
7913
+ return this._pickAsync("pickObjectAsync", "pickObject Time", opts);
7914
+ }
7915
+ _getLastPointerDownPickingInfo(x, y, layers = ((_c) => (_c = this.layerManager) == null ? void 0 : _c.getLayers())() || []) {
7916
+ return this.deckPicker.getLastPickedObject({
7917
+ x,
7918
+ y,
7919
+ layers,
7920
+ viewports: this.getViewports({ x, y })
7921
+ }, this._lastPointerDownInfo);
7922
+ }
7923
+ _applyHoverCallbacks({ result, emptyInfo }, event) {
7924
+ var _a, _b, _c;
7925
+ if (!this.widgetManager) {
7926
+ return;
7927
+ }
7928
+ this.cursorState.isHovering = result.length > 0;
7929
+ let pickedInfo = emptyInfo;
7930
+ let handled = false;
7931
+ for (const info of result) {
7932
+ pickedInfo = info;
7933
+ handled = ((_a = info.layer) == null ? void 0 : _a.onHover(info, event)) || handled;
7934
+ }
7935
+ if (!handled) {
7936
+ (_c = (_b = this.props).onHover) == null ? void 0 : _c.call(_b, pickedInfo, event);
7937
+ this.widgetManager.onHover(pickedInfo, event);
7938
+ }
7939
+ }
7940
+ _dispatchPickingEvent(info, event) {
7941
+ if (!this.layerManager || !this.widgetManager) {
7942
+ return;
7943
+ }
7944
+ const eventHandlerProp = EVENT_HANDLERS[event.type];
7945
+ if (!eventHandlerProp) {
7946
+ return;
7947
+ }
7948
+ const { layer } = info;
7949
+ const layerHandler = layer && (layer[eventHandlerProp] || layer.props[eventHandlerProp]);
7950
+ const rootHandler = this.props[eventHandlerProp];
7951
+ let handled = false;
7952
+ if (layerHandler) {
7953
+ handled = layerHandler.call(layer, info, event);
7954
+ }
7955
+ if (!handled) {
7956
+ rootHandler == null ? void 0 : rootHandler(info, event);
7957
+ this.widgetManager.onEvent(info, event);
7958
+ }
7959
+ }
7960
+ _pickAsync(method, statKey, opts) {
7961
+ assert(this.deckPicker);
7962
+ const { stats } = this;
7963
+ stats.get("Pick Count").incrementCount();
7964
+ stats.get(statKey).timeStart();
7965
+ const infos = this.deckPicker[method]({
7966
+ // layerManager, viewManager and effectManager are always defined if deckPicker is
7967
+ layers: this.layerManager.getLayers(opts),
7968
+ views: this.viewManager.getViews(),
7969
+ viewports: this.getViewports(opts),
7970
+ onViewportActive: this.layerManager.activateViewport,
7971
+ effects: this.effectManager.getEffects(),
7972
+ ...opts
7973
+ });
7974
+ stats.get(statKey).timeEnd();
7975
+ return infos;
7976
+ }
7733
7977
  _pick(method, statKey, opts) {
7734
7978
  assert(this.deckPicker);
7735
7979
  const { stats } = this;
@@ -7847,7 +8091,7 @@ var Deck = class {
7847
8091
  alphaMode: ((_b = this.props.deviceProps) == null ? void 0 : _b.type) === "webgpu" ? "premultiplied" : void 0
7848
8092
  };
7849
8093
  const userOnResize = (_c = this.props.deviceProps) == null ? void 0 : _c.onResize;
7850
- return import_core16.luma.createDevice({
8094
+ return import_core17.luma.createDevice({
7851
8095
  // luma by default throws if a device is already attached
7852
8096
  // asynchronous device creation could happen after finalize() is called
7853
8097
  // TODO - createDevice should support AbortController?
@@ -7894,28 +8138,33 @@ var Deck = class {
7894
8138
  }
7895
8139
  /** Actually run picking */
7896
8140
  _pickAndCallback() {
7897
- var _a, _b, _c, _d, _e;
7898
- if (((_a = this.device) == null ? void 0 : _a.type) === "webgpu") {
7899
- return;
7900
- }
8141
+ var _a;
7901
8142
  const { _pickRequest } = this;
7902
8143
  if (_pickRequest.event) {
7903
- const layers = ((_b = this.layerManager) == null ? void 0 : _b.getLayers()) || [];
7904
- const has3DPickableLayers = layers.some((layer) => layer.props.pickable === "3d");
7905
- _pickRequest.unproject3D = has3DPickableLayers;
7906
- const { result, emptyInfo } = this._pick("pickObject", "pickObject Time", _pickRequest);
7907
- this.cursorState.isHovering = result.length > 0;
7908
- let pickedInfo = emptyInfo;
7909
- let handled = false;
7910
- for (const info of result) {
7911
- pickedInfo = info;
7912
- handled = ((_c = info.layer) == null ? void 0 : _c.onHover(info, _pickRequest.event)) || handled;
7913
- }
7914
- if (!handled) {
7915
- (_e = (_d = this.props).onHover) == null ? void 0 : _e.call(_d, pickedInfo, _pickRequest.event);
7916
- this.widgetManager.onHover(pickedInfo, _pickRequest.event);
7917
- }
8144
+ const event = _pickRequest.event;
8145
+ const layers = ((_a = this.layerManager) == null ? void 0 : _a.getLayers()) || [];
8146
+ const pickOptions = this._getPointPickOptions(_pickRequest.x, _pickRequest.y, {
8147
+ radius: _pickRequest.radius,
8148
+ mode: _pickRequest.mode
8149
+ }, layers);
8150
+ const internalPickingMode = this._getInternalPickingMode();
8151
+ const hoverPickSequence = ++this._hoverPickSequence;
7918
8152
  _pickRequest.event = null;
8153
+ if (!internalPickingMode) {
8154
+ return;
8155
+ }
8156
+ if (internalPickingMode === "sync") {
8157
+ this._applyHoverCallbacks(this._pickPointSync(pickOptions), event);
8158
+ return;
8159
+ }
8160
+ this._pickPointAsync(pickOptions).then(({ result, emptyInfo }) => {
8161
+ if (hoverPickSequence === this._hoverPickSequence) {
8162
+ this._applyHoverCallbacks({ result, emptyInfo }, event);
8163
+ }
8164
+ }).catch((error) => {
8165
+ var _a2, _b;
8166
+ return (_b = (_a2 = this.props).onError) == null ? void 0 : _b.call(_a2, error);
8167
+ });
7919
8168
  }
7920
8169
  }
7921
8170
  _updateCursor() {
@@ -7927,6 +8176,7 @@ var Deck = class {
7927
8176
  _setDevice(device) {
7928
8177
  var _a, _b, _c, _d;
7929
8178
  this.device = device;
8179
+ this._validateInternalPickingMode();
7930
8180
  if (!this.animationLoop) {
7931
8181
  return;
7932
8182
  }
@@ -8035,7 +8285,6 @@ var Deck = class {
8035
8285
  }
8036
8286
  // Callbacks
8037
8287
  _onRenderFrame() {
8038
- var _a;
8039
8288
  this._getFrameStats();
8040
8289
  if (this._metricsCounter++ % 60 === 0) {
8041
8290
  this._getMetrics();
@@ -8048,9 +8297,7 @@ var Deck = class {
8048
8297
  this._updateCanvasSize();
8049
8298
  this._updateCursor();
8050
8299
  this.layerManager.updateLayers();
8051
- if (((_a = this.device) == null ? void 0 : _a.type) !== "webgpu") {
8052
- this._pickAndCallback();
8053
- }
8300
+ this._pickAndCallback();
8054
8301
  this.redraw();
8055
8302
  if (this.viewManager) {
8056
8303
  this.viewManager.updateViewStates();
@@ -8098,7 +8345,7 @@ var Deck = class {
8098
8345
  metrics.cpuTime = stats.get("CPU Time").time;
8099
8346
  metrics.gpuTimePerFrame = stats.get("GPU Time").getAverageTime();
8100
8347
  metrics.cpuTimePerFrame = stats.get("CPU Time").getAverageTime();
8101
- const memoryStats = import_core16.luma.stats.get("GPU Time and Memory");
8348
+ const memoryStats = import_core17.luma.stats.get("GPU Time and Memory");
8102
8349
  metrics.bufferMemory = memoryStats.get("Buffer Memory").count;
8103
8350
  metrics.textureMemory = memoryStats.get("Texture Memory").count;
8104
8351
  metrics.renderbufferMemory = memoryStats.get("Renderbuffer Memory").count;
@@ -8110,10 +8357,10 @@ Deck.VERSION = VERSION;
8110
8357
  var deck_default = Deck;
8111
8358
 
8112
8359
  // dist/lib/attribute/data-column.js
8113
- var import_core18 = require("@luma.gl/core");
8360
+ var import_core19 = require("@luma.gl/core");
8114
8361
 
8115
8362
  // dist/lib/attribute/gl-utils.js
8116
- var import_core17 = require("@luma.gl/core");
8363
+ var import_core18 = require("@luma.gl/core");
8117
8364
  function typedArrayFromDataType(type) {
8118
8365
  switch (type) {
8119
8366
  case "float64":
@@ -8122,10 +8369,10 @@ function typedArrayFromDataType(type) {
8122
8369
  case "unorm8":
8123
8370
  return Uint8ClampedArray;
8124
8371
  default:
8125
- return (0, import_core17.getTypedArrayConstructor)(type);
8372
+ return (0, import_core18.getTypedArrayConstructor)(type);
8126
8373
  }
8127
8374
  }
8128
- var dataTypeFromTypedArray = import_core17.getDataType;
8375
+ var dataTypeFromTypedArray = import_core18.dataTypeDecoder.getDataType.bind(import_core18.dataTypeDecoder);
8129
8376
  function getBufferAttributeLayout(name, accessor, deviceType) {
8130
8377
  if (accessor.size > 4) {
8131
8378
  return null;
@@ -8343,7 +8590,7 @@ var DataColumn = class {
8343
8590
  let opts;
8344
8591
  if (ArrayBuffer.isView(data)) {
8345
8592
  opts = { value: data };
8346
- } else if (data instanceof import_core18.Buffer) {
8593
+ } else if (data instanceof import_core19.Buffer) {
8347
8594
  opts = { buffer: data };
8348
8595
  } else {
8349
8596
  opts = data;
@@ -8528,7 +8775,7 @@ var DataColumn = class {
8528
8775
  ...(_a = this._buffer) == null ? void 0 : _a.props,
8529
8776
  id: this.id,
8530
8777
  // TODO(ibgreen) - WebGPU requires COPY_DST and COPY_SRC to allow write / read
8531
- usage: (isIndexed ? import_core18.Buffer.INDEX : import_core18.Buffer.VERTEX) | import_core18.Buffer.COPY_DST,
8778
+ usage: (isIndexed ? import_core19.Buffer.INDEX : import_core19.Buffer.VERTEX) | import_core19.Buffer.COPY_DST,
8532
8779
  indexType: isIndexed ? type : void 0,
8533
8780
  byteLength
8534
8781
  });
@@ -8992,7 +9239,7 @@ var Attribute = class extends DataColumn {
8992
9239
  // dist/transitions/gpu-interpolation-transition.js
8993
9240
  var import_engine5 = require("@luma.gl/engine");
8994
9241
  var import_shadertools6 = require("@luma.gl/shadertools");
8995
- var import_constants14 = require("@luma.gl/constants");
9242
+ var import_constants14 = require("@luma.gl/webgl/constants");
8996
9243
 
8997
9244
  // dist/utils/array-utils.js
8998
9245
  function padArrayChunk(options) {
@@ -9059,7 +9306,7 @@ function padArray({ source: source3, target, size, getData, sourceStartIndices,
9059
9306
  }
9060
9307
 
9061
9308
  // dist/transitions/gpu-transition-utils.js
9062
- var import_constants13 = require("@luma.gl/constants");
9309
+ var import_constants13 = require("@luma.gl/webgl/constants");
9063
9310
  function cloneAttribute(attribute) {
9064
9311
  const { device, settings, value } = attribute;
9065
9312
  const newAttribute = new Attribute(device, settings);
@@ -9278,7 +9525,7 @@ var GPUInterpolationTransition = class extends GPUTransitionBase {
9278
9525
  this.transform.destroy();
9279
9526
  }
9280
9527
  };
9281
- var uniformBlock4 = `uniform interpolationUniforms {
9528
+ var uniformBlock4 = `layout(std140) uniform interpolationUniforms {
9282
9529
  float time;
9283
9530
  } interpolation;
9284
9531
  `;
@@ -9459,7 +9706,7 @@ var GPUSpringTransition = class extends GPUTransitionBase {
9459
9706
  this.framebuffer.destroy();
9460
9707
  }
9461
9708
  };
9462
- var uniformBlock5 = `uniform springUniforms {
9709
+ var uniformBlock5 = `layout(std140) uniform springUniforms {
9463
9710
  float damping;
9464
9711
  float stiffness;
9465
9712
  } spring;
@@ -9897,11 +10144,11 @@ var AttributeManager = class {
9897
10144
  };
9898
10145
 
9899
10146
  // dist/lib/layer.js
9900
- var import_core21 = require("@luma.gl/core");
10147
+ var import_core22 = require("@luma.gl/core");
9901
10148
  var import_webgl2 = require("@luma.gl/webgl");
9902
10149
 
9903
10150
  // dist/transitions/cpu-interpolation-transition.js
9904
- var import_core19 = require("@math.gl/core");
10151
+ var import_core20 = require("@math.gl/core");
9905
10152
  var CPUInterpolationTransition = class extends Transition {
9906
10153
  get value() {
9907
10154
  return this._value;
@@ -9909,7 +10156,7 @@ var CPUInterpolationTransition = class extends Transition {
9909
10156
  _onUpdate() {
9910
10157
  const { time, settings: { fromValue, toValue, duration, easing } } = this;
9911
10158
  const t = easing(time / duration);
9912
- this._value = (0, import_core19.lerp)(fromValue, toValue, t);
10159
+ this._value = (0, import_core20.lerp)(fromValue, toValue, t);
9913
10160
  }
9914
10161
  };
9915
10162
 
@@ -10263,7 +10510,7 @@ function mergeShaders(target, source3) {
10263
10510
  }
10264
10511
 
10265
10512
  // dist/utils/texture.js
10266
- var import_core20 = require("@luma.gl/core");
10513
+ var import_core21 = require("@luma.gl/core");
10267
10514
  var DEFAULT_TEXTURE_PARAMETERS = {
10268
10515
  minFilter: "linear",
10269
10516
  mipmapFilter: "linear",
@@ -10273,7 +10520,7 @@ var DEFAULT_TEXTURE_PARAMETERS = {
10273
10520
  };
10274
10521
  var internalTextures = {};
10275
10522
  function createTexture(owner, device, image, sampler) {
10276
- if (image instanceof import_core20.Texture) {
10523
+ if (image instanceof import_core21.Texture) {
10277
10524
  return image;
10278
10525
  } else if (image.constructor && image.constructor.name !== "Object") {
10279
10526
  image = { data: image };
@@ -10302,7 +10549,7 @@ function createTexture(owner, device, image, sampler) {
10302
10549
  return texture;
10303
10550
  }
10304
10551
  function destroyTexture(owner, texture) {
10305
- if (!texture || !(texture instanceof import_core20.Texture)) {
10552
+ if (!texture || !(texture instanceof import_core21.Texture)) {
10306
10553
  return;
10307
10554
  }
10308
10555
  if (internalTextures[texture.id] === owner) {
@@ -10908,7 +11155,7 @@ var LayerState = class extends ComponentState {
10908
11155
 
10909
11156
  // dist/lib/layer.js
10910
11157
  var import_web_mercator8 = require("@math.gl/web-mercator");
10911
- var import_core22 = require("@loaders.gl/core");
11158
+ var import_core23 = require("@loaders.gl/core");
10912
11159
  var TRACE_CHANGE_FLAG = "layer.changeFlag";
10913
11160
  var TRACE_INITIALIZE = "layer.initialize";
10914
11161
  var TRACE_UPDATE = "layer.update";
@@ -10954,7 +11201,7 @@ var defaultProps2 = {
10954
11201
  }
10955
11202
  let inResourceManager = resourceManager.contains(url);
10956
11203
  if (!inResourceManager && !loadOptions) {
10957
- resourceManager.add({ resourceId: url, data: (0, import_core22.load)(url, loaders), persistent: false });
11204
+ resourceManager.add({ resourceId: url, data: (0, import_core23.load)(url, loaders), persistent: false });
10958
11205
  inResourceManager = true;
10959
11206
  }
10960
11207
  if (inResourceManager) {
@@ -10968,7 +11215,7 @@ var defaultProps2 = {
10968
11215
  requestId: propName
10969
11216
  });
10970
11217
  }
10971
- return (0, import_core22.load)(url, loaders, loadOptions);
11218
+ return (0, import_core23.load)(url, loaders, loadOptions);
10972
11219
  }
10973
11220
  },
10974
11221
  updateTriggers: {},
@@ -11439,7 +11686,7 @@ var Layer = class extends component_default {
11439
11686
  const values = changedAttributes[name].getValue();
11440
11687
  for (const attributeName in values) {
11441
11688
  const value = values[attributeName];
11442
- if (value instanceof import_core21.Buffer) {
11689
+ if (value instanceof import_core22.Buffer) {
11443
11690
  if (changedAttributes[name].settings.isIndexed) {
11444
11691
  model.setIndexBuffer(value);
11445
11692
  } else {
@@ -11628,13 +11875,8 @@ var Layer = class extends component_default {
11628
11875
  if (context.device instanceof import_webgl2.WebGLDevice) {
11629
11876
  context.device.setParametersWebGL({ polygonOffset: offsets });
11630
11877
  }
11631
- for (const model of this.getModels()) {
11632
- if (model.device.type === "webgpu") {
11633
- model.setParameters({ ...model.parameters, ...parameters });
11634
- } else {
11635
- model.setParameters(parameters);
11636
- }
11637
- }
11878
+ const webGPUDrawParameters = context.device instanceof import_webgl2.WebGLDevice ? null : splitWebGPUDrawParameters(parameters);
11879
+ applyModelParameters(this.getModels(), renderPass, parameters, webGPUDrawParameters);
11638
11880
  if (context.device instanceof import_webgl2.WebGLDevice) {
11639
11881
  context.device.withParametersWebGL(parameters, () => {
11640
11882
  const opts = { renderPass, shaderModuleProps, uniforms, parameters, context };
@@ -11644,6 +11886,9 @@ var Layer = class extends component_default {
11644
11886
  this.draw(opts);
11645
11887
  });
11646
11888
  } else {
11889
+ if (webGPUDrawParameters == null ? void 0 : webGPUDrawParameters.renderPassParameters) {
11890
+ renderPass.setParameters(webGPUDrawParameters.renderPassParameters);
11891
+ }
11647
11892
  const opts = { renderPass, shaderModuleProps, uniforms, parameters, context };
11648
11893
  for (const extension of this.props.extensions) {
11649
11894
  extension.draw.call(this, opts, extension);
@@ -11819,6 +12064,58 @@ var Layer = class extends component_default {
11819
12064
  Layer.defaultProps = defaultProps2;
11820
12065
  Layer.layerName = "Layer";
11821
12066
  var layer_default = Layer;
12067
+ function splitWebGPUDrawParameters(parameters) {
12068
+ const { blendConstant, ...pipelineParameters } = parameters;
12069
+ return blendConstant ? {
12070
+ pipelineParameters,
12071
+ renderPassParameters: { blendConstant }
12072
+ } : { pipelineParameters };
12073
+ }
12074
+ function applyModelParameters(models, renderPass, parameters, webGPUDrawParameters) {
12075
+ for (const model of models) {
12076
+ if (model.device.type === "webgpu") {
12077
+ syncModelAttachmentFormats(model, renderPass);
12078
+ model.setParameters({
12079
+ ...model.parameters,
12080
+ ...webGPUDrawParameters == null ? void 0 : webGPUDrawParameters.pipelineParameters
12081
+ });
12082
+ } else {
12083
+ model.setParameters(parameters);
12084
+ }
12085
+ }
12086
+ }
12087
+ function syncModelAttachmentFormats(model, renderPass) {
12088
+ var _a, _b;
12089
+ const framebuffer = renderPass.props.framebuffer || (renderPass.framebuffer ?? null);
12090
+ if (!framebuffer) {
12091
+ return;
12092
+ }
12093
+ const colorAttachmentFormats = framebuffer.colorAttachments.map((attachment) => {
12094
+ var _a2;
12095
+ return ((_a2 = attachment == null ? void 0 : attachment.texture) == null ? void 0 : _a2.format) ?? null;
12096
+ });
12097
+ const depthStencilAttachmentFormat = (_b = (_a = framebuffer.depthStencilAttachment) == null ? void 0 : _a.texture) == null ? void 0 : _b.format;
12098
+ const modelWithProps = model;
12099
+ if (!equalAttachmentFormats(modelWithProps.props.colorAttachmentFormats, colorAttachmentFormats) || modelWithProps.props.depthStencilAttachmentFormat !== depthStencilAttachmentFormat) {
12100
+ modelWithProps.props.colorAttachmentFormats = colorAttachmentFormats;
12101
+ modelWithProps.props.depthStencilAttachmentFormat = depthStencilAttachmentFormat;
12102
+ modelWithProps._setPipelineNeedsUpdate("attachment formats");
12103
+ }
12104
+ }
12105
+ function equalAttachmentFormats(left, right) {
12106
+ if (left === right) {
12107
+ return true;
12108
+ }
12109
+ if (!left || !right || left.length !== right.length) {
12110
+ return false;
12111
+ }
12112
+ for (let i = 0; i < left.length; i++) {
12113
+ if (left[i] !== right[i]) {
12114
+ return false;
12115
+ }
12116
+ }
12117
+ return true;
12118
+ }
11822
12119
 
11823
12120
  // dist/lib/composite-layer.js
11824
12121
  var TRACE_RENDER_LAYERS2 = "compositeLayer.renderLayers";
@@ -11997,13 +12294,13 @@ CompositeLayer.layerName = "CompositeLayer";
11997
12294
  var composite_layer_default = CompositeLayer;
11998
12295
 
11999
12296
  // dist/viewports/orbit-viewport.js
12000
- var import_core23 = require("@math.gl/core");
12297
+ var import_core24 = require("@math.gl/core");
12001
12298
  var import_web_mercator9 = require("@math.gl/web-mercator");
12002
12299
  var DEGREES_TO_RADIANS3 = Math.PI / 180;
12003
12300
  function getViewMatrix2({ height, focalDistance, orbitAxis, rotationX, rotationOrbit, zoom }) {
12004
12301
  const up = orbitAxis === "Z" ? [0, 0, 1] : [0, 1, 0];
12005
12302
  const eye = orbitAxis === "Z" ? [0, -focalDistance, 0] : [0, 0, focalDistance];
12006
- const viewMatrix2 = new import_core23.Matrix4().lookAt({ eye, up });
12303
+ const viewMatrix2 = new import_core24.Matrix4().lookAt({ eye, up });
12007
12304
  viewMatrix2.rotateX(rotationX * DEGREES_TO_RADIANS3);
12008
12305
  if (orbitAxis === "Z") {
12009
12306
  viewMatrix2.rotateZ(rotationOrbit * DEGREES_TO_RADIANS3);
@@ -12083,9 +12380,9 @@ OrbitViewport.displayName = "OrbitViewport";
12083
12380
  var orbit_viewport_default = OrbitViewport;
12084
12381
 
12085
12382
  // dist/viewports/orthographic-viewport.js
12086
- var import_core24 = require("@math.gl/core");
12383
+ var import_core25 = require("@math.gl/core");
12087
12384
  var import_web_mercator10 = require("@math.gl/web-mercator");
12088
- var viewMatrix = new import_core24.Matrix4().lookAt({ eye: [0, 0, 1] });
12385
+ var viewMatrix = new import_core25.Matrix4().lookAt({ eye: [0, 0, 1] });
12089
12386
  function getProjectionMatrix({ width, height, near, far, padding }) {
12090
12387
  let left = -width / 2;
12091
12388
  let right = width / 2;
@@ -12093,14 +12390,14 @@ function getProjectionMatrix({ width, height, near, far, padding }) {
12093
12390
  let top = height / 2;
12094
12391
  if (padding) {
12095
12392
  const { left: l = 0, right: r = 0, top: t = 0, bottom: b = 0 } = padding;
12096
- const offsetX = (0, import_core24.clamp)((l + width - r) / 2, 0, width) - width / 2;
12097
- const offsetY = (0, import_core24.clamp)((t + height - b) / 2, 0, height) - height / 2;
12393
+ const offsetX = (0, import_core25.clamp)((l + width - r) / 2, 0, width) - width / 2;
12394
+ const offsetY = (0, import_core25.clamp)((t + height - b) / 2, 0, height) - height / 2;
12098
12395
  left -= offsetX;
12099
12396
  right -= offsetX;
12100
12397
  bottom += offsetY;
12101
12398
  top += offsetY;
12102
12399
  }
12103
- return new import_core24.Matrix4().ortho({
12400
+ return new import_core25.Matrix4().ortho({
12104
12401
  left,
12105
12402
  right,
12106
12403
  bottom,
@@ -12159,8 +12456,8 @@ var OrthographicViewport = class extends viewport_default {
12159
12456
  panByPosition(coords, pixel, startPixel) {
12160
12457
  const fromLocation = (0, import_web_mercator10.pixelsToWorld)(pixel, this.pixelUnprojectionMatrix);
12161
12458
  const toLocation = this.projectFlat(coords);
12162
- const translate = import_core24.vec2.add([], toLocation, import_core24.vec2.negate([], fromLocation));
12163
- const newCenter = import_core24.vec2.add([], this.center, translate);
12459
+ const translate = import_core25.vec2.add([], toLocation, import_core25.vec2.negate([], fromLocation));
12460
+ const newCenter = import_core25.vec2.add([], this.center, translate);
12164
12461
  return { target: this.unprojectFlat(newCenter) };
12165
12462
  }
12166
12463
  };
@@ -12169,20 +12466,20 @@ var orthographic_viewport_default = OrthographicViewport;
12169
12466
 
12170
12467
  // dist/viewports/first-person-viewport.js
12171
12468
  var import_web_mercator11 = require("@math.gl/web-mercator");
12172
- var import_core25 = require("@math.gl/core");
12469
+ var import_core26 = require("@math.gl/core");
12173
12470
  var FirstPersonViewport = class extends viewport_default {
12174
12471
  constructor(props) {
12175
12472
  const { longitude, latitude, modelMatrix, bearing = 0, pitch = 0, up = [0, 0, 1] } = props;
12176
- const spherical = new import_core25._SphericalCoordinates({
12473
+ const spherical = new import_core26._SphericalCoordinates({
12177
12474
  bearing,
12178
12475
  // Avoid "pixel project matrix not invertible" error
12179
12476
  pitch: pitch === -90 ? 1e-4 : 90 + pitch
12180
12477
  });
12181
12478
  const dir = spherical.toVector3().normalize();
12182
- const center = modelMatrix ? new import_core25.Matrix4(modelMatrix).transformAsVector(dir) : dir;
12479
+ const center = modelMatrix ? new import_core26.Matrix4(modelMatrix).transformAsVector(dir) : dir;
12183
12480
  const zoom = Number.isFinite(latitude) ? (0, import_web_mercator11.getMeterZoom)({ latitude }) : 0;
12184
12481
  const scale = Math.pow(2, zoom);
12185
- const viewMatrix2 = new import_core25.Matrix4().lookAt({ eye: [0, 0, 0], center, up }).scale(scale);
12482
+ const viewMatrix2 = new import_core26.Matrix4().lookAt({ eye: [0, 0, 0], center, up }).scale(scale);
12186
12483
  super({
12187
12484
  ...props,
12188
12485
  zoom,
@@ -12199,7 +12496,7 @@ FirstPersonViewport.displayName = "FirstPersonViewport";
12199
12496
  var first_person_viewport_default = FirstPersonViewport;
12200
12497
 
12201
12498
  // dist/controllers/first-person-controller.js
12202
- var import_core26 = require("@math.gl/core");
12499
+ var import_core27 = require("@math.gl/core");
12203
12500
  var MOVEMENT_SPEED = 20;
12204
12501
  var PAN_SPEED = 500;
12205
12502
  var FirstPersonState = class extends ViewState {
@@ -12275,12 +12572,12 @@ var FirstPersonState = class extends ViewState {
12275
12572
  const { width, height, bearing, pitch } = this.getViewportProps();
12276
12573
  const deltaScaleX = PAN_SPEED * (pos[0] - startPanPos[0]) / width;
12277
12574
  const deltaScaleY = PAN_SPEED * (pos[1] - startPanPos[1]) / height;
12278
- const up = new import_core26._SphericalCoordinates({ bearing, pitch });
12279
- const forward = new import_core26._SphericalCoordinates({ bearing, pitch: -90 });
12575
+ const up = new import_core27._SphericalCoordinates({ bearing, pitch });
12576
+ const forward = new import_core27._SphericalCoordinates({ bearing, pitch: -90 });
12280
12577
  const yDirection = up.toVector3().normalize();
12281
12578
  const xDirection = forward.toVector3().cross(yDirection).normalize();
12282
12579
  return this._getUpdatedState({
12283
- position: new import_core26.Vector3(startPanPosition).add(xDirection.scale(deltaScaleX)).add(yDirection.scale(deltaScaleY))
12580
+ position: new import_core27.Vector3(startPanPosition).add(xDirection.scale(deltaScaleX)).add(yDirection.scale(deltaScaleY))
12284
12581
  });
12285
12582
  }
12286
12583
  /**
@@ -12416,10 +12713,10 @@ var FirstPersonState = class extends ViewState {
12416
12713
  });
12417
12714
  }
12418
12715
  zoomIn(speed = MOVEMENT_SPEED) {
12419
- return this._move(new import_core26.Vector3(0, 0, 1), speed);
12716
+ return this._move(new import_core27.Vector3(0, 0, 1), speed);
12420
12717
  }
12421
12718
  zoomOut(speed = MOVEMENT_SPEED) {
12422
- return this._move(new import_core26.Vector3(0, 0, -1), speed);
12719
+ return this._move(new import_core27.Vector3(0, 0, -1), speed);
12423
12720
  }
12424
12721
  // shortest path between two view states
12425
12722
  shortestPathFrom(viewState) {
@@ -12438,11 +12735,11 @@ var FirstPersonState = class extends ViewState {
12438
12735
  _move(direction, speed, fromPosition = this.getViewportProps().position) {
12439
12736
  const delta = direction.scale(speed);
12440
12737
  return this._getUpdatedState({
12441
- position: new import_core26.Vector3(fromPosition).add(delta)
12738
+ position: new import_core27.Vector3(fromPosition).add(delta)
12442
12739
  });
12443
12740
  }
12444
12741
  getDirection(use2D = false) {
12445
- const spherical = new import_core26._SphericalCoordinates({
12742
+ const spherical = new import_core27._SphericalCoordinates({
12446
12743
  bearing: this.getViewportProps().bearing,
12447
12744
  pitch: use2D ? 90 : 90 + this.getViewportProps().pitch
12448
12745
  });
@@ -12460,7 +12757,7 @@ var FirstPersonState = class extends ViewState {
12460
12757
  // Apply any constraints (mathematical or defined by _viewportProps) to map state
12461
12758
  applyConstraints(props) {
12462
12759
  const { pitch, maxPitch, minPitch, longitude, position, bearing, maxBounds } = props;
12463
- props.pitch = (0, import_core26.clamp)(pitch, minPitch, maxPitch);
12760
+ props.pitch = (0, import_core27.clamp)(pitch, minPitch, maxPitch);
12464
12761
  if (longitude !== null && (longitude < -180 || longitude > 180)) {
12465
12762
  props.longitude = mod(longitude + 180, 360) - 180;
12466
12763
  }
@@ -12468,9 +12765,9 @@ var FirstPersonState = class extends ViewState {
12468
12765
  props.bearing = mod(bearing + 180, 360) - 180;
12469
12766
  }
12470
12767
  if (maxBounds) {
12471
- const x = (0, import_core26.clamp)(position[0], maxBounds[0][0], maxBounds[1][0]);
12472
- const y = (0, import_core26.clamp)(position[1], maxBounds[0][1], maxBounds[1][1]);
12473
- const z = (0, import_core26.clamp)(position[2] ?? 0, maxBounds[0][2] ?? 0, maxBounds[1][2] ?? 0);
12768
+ const x = (0, import_core27.clamp)(position[0], maxBounds[0][0], maxBounds[1][0]);
12769
+ const y = (0, import_core27.clamp)(position[1], maxBounds[0][1], maxBounds[1][1]);
12770
+ const z = (0, import_core27.clamp)(position[2] ?? 0, maxBounds[0][2] ?? 0, maxBounds[1][2] ?? 0);
12474
12771
  if (x !== position[0] || y !== position[1] || z !== position[2]) {
12475
12772
  props.position = [x, y, z];
12476
12773
  }
@@ -12505,7 +12802,7 @@ FirstPersonView.displayName = "FirstPersonView";
12505
12802
  var first_person_view_default = FirstPersonView;
12506
12803
 
12507
12804
  // dist/controllers/orbit-controller.js
12508
- var import_core27 = require("@math.gl/core");
12805
+ var import_core28 = require("@math.gl/core");
12509
12806
  var OrbitState = class extends ViewState {
12510
12807
  constructor(options) {
12511
12808
  const {
@@ -12777,7 +13074,7 @@ var OrbitState = class extends ViewState {
12777
13074
  applyConstraints(props) {
12778
13075
  const { maxRotationX, minRotationX, rotationOrbit } = props;
12779
13076
  props.zoom = this._constrainZoom(props.zoom, props);
12780
- props.rotationX = (0, import_core27.clamp)(props.rotationX, minRotationX, maxRotationX);
13077
+ props.rotationX = (0, import_core28.clamp)(props.rotationX, minRotationX, maxRotationX);
12781
13078
  if (rotationOrbit < -180 || rotationOrbit > 180) {
12782
13079
  props.rotationOrbit = mod(rotationOrbit + 180, 360) - 180;
12783
13080
  }
@@ -12799,7 +13096,7 @@ var OrbitState = class extends ViewState {
12799
13096
  minZoom = maxZoom;
12800
13097
  }
12801
13098
  }
12802
- return (0, import_core27.clamp)(zoom, minZoom, maxZoom);
13099
+ return (0, import_core28.clamp)(zoom, minZoom, maxZoom);
12803
13100
  }
12804
13101
  _constrainTarget(props) {
12805
13102
  var _a;
@@ -12820,9 +13117,9 @@ var OrbitState = class extends ViewState {
12820
13117
  const minDot = nx * (nx >= 0 ? minX : maxX) + ny * (ny >= 0 ? minY : maxY) + nz * (nz >= 0 ? minZ : maxZ);
12821
13118
  const maxDot = nx * (nx >= 0 ? maxX : minX) + ny * (ny >= 0 ? maxY : minY) + nz * (nz >= 0 ? maxZ : minZ);
12822
13119
  if ((nx || ny || nz) && c >= minDot && c <= maxDot) {
12823
- const clampX = (value) => (0, import_core27.clamp)(value, minX, maxX);
12824
- const clampY = (value) => (0, import_core27.clamp)(value, minY, maxY);
12825
- const clampZ = (value) => (0, import_core27.clamp)(value, minZ, maxZ);
13120
+ const clampX = (value) => (0, import_core28.clamp)(value, minX, maxX);
13121
+ const clampY = (value) => (0, import_core28.clamp)(value, minY, maxY);
13122
+ const clampZ = (value) => (0, import_core28.clamp)(value, minZ, maxZ);
12826
13123
  const f = (lambda2) => nx * clampX(target[0] - lambda2 * nx) + ny * clampY(target[1] - lambda2 * ny) + nz * clampZ(target[2] - lambda2 * nz) - c;
12827
13124
  let lo = -1;
12828
13125
  let hi = 1;
@@ -12858,9 +13155,9 @@ var OrbitState = class extends ViewState {
12858
13155
  }
12859
13156
  }
12860
13157
  return [
12861
- (0, import_core27.clamp)(target[0], minX, maxX),
12862
- (0, import_core27.clamp)(target[1], minY, maxY),
12863
- (0, import_core27.clamp)(target[2], minZ, maxZ)
13158
+ (0, import_core28.clamp)(target[0], minX, maxX),
13159
+ (0, import_core28.clamp)(target[1], minY, maxY),
13160
+ (0, import_core28.clamp)(target[2], minZ, maxZ)
12864
13161
  ];
12865
13162
  }
12866
13163
  };
@@ -12911,7 +13208,7 @@ OrbitView.displayName = "OrbitView";
12911
13208
  var orbit_view_default = OrbitView;
12912
13209
 
12913
13210
  // dist/controllers/orthographic-controller.js
12914
- var import_core28 = require("@math.gl/core");
13211
+ var import_core29 = require("@math.gl/core");
12915
13212
  function normalizeZoom({ zoom = 0, zoomX, zoomY }) {
12916
13213
  zoomX = zoomX ?? (Array.isArray(zoom) ? zoom[0] : zoom);
12917
13214
  zoomY = zoomY ?? (Array.isArray(zoom) ? zoom[1] : zoom);
@@ -13157,8 +13454,8 @@ var OrthographicState = class extends ViewState {
13157
13454
  const maxX = maxBounds[1][0] - halfWidth;
13158
13455
  const minY = maxBounds[0][1] + halfHeight;
13159
13456
  const maxY = maxBounds[1][1] - halfHeight;
13160
- const x = (0, import_core28.clamp)(target[0], minX, maxX);
13161
- const y = (0, import_core28.clamp)(target[1], minY, maxY);
13457
+ const x = (0, import_core29.clamp)(target[0], minX, maxX);
13458
+ const y = (0, import_core29.clamp)(target[1], minY, maxY);
13162
13459
  if (x !== target[0] || y !== target[1]) {
13163
13460
  props.target = target.slice();
13164
13461
  props.target[0] = x;
@@ -13190,10 +13487,10 @@ var OrthographicState = class extends ViewState {
13190
13487
  }
13191
13488
  switch (zoomAxis) {
13192
13489
  case "X":
13193
- zoomX = (0, import_core28.clamp)(zoomX, minZoomX, maxZoomX);
13490
+ zoomX = (0, import_core29.clamp)(zoomX, minZoomX, maxZoomX);
13194
13491
  break;
13195
13492
  case "Y":
13196
- zoomY = (0, import_core28.clamp)(zoomY, minZoomY, maxZoomY);
13493
+ zoomY = (0, import_core29.clamp)(zoomY, minZoomY, maxZoomY);
13197
13494
  break;
13198
13495
  default:
13199
13496
  let delta = Math.min(maxZoomX - zoomX, maxZoomY - zoomY, 0);
@@ -13243,7 +13540,7 @@ OrthographicView.displayName = "OrthographicView";
13243
13540
  var orthographic_view_default = OrthographicView;
13244
13541
 
13245
13542
  // dist/controllers/globe-controller.js
13246
- var import_core29 = require("@math.gl/core");
13543
+ var import_core30 = require("@math.gl/core");
13247
13544
  var import_web_mercator12 = require("@math.gl/web-mercator");
13248
13545
  var DEGREES_TO_RADIANS4 = Math.PI / 180;
13249
13546
  var RADIANS_TO_DEGREES2 = 180 / Math.PI;
@@ -13304,10 +13601,10 @@ var GlobeState = class extends MapState {
13304
13601
  if (longitude < -180 || longitude > 180) {
13305
13602
  props.longitude = mod(longitude + 180, 360) - 180;
13306
13603
  }
13307
- props.latitude = (0, import_core29.clamp)(latitude, -import_web_mercator12.MAX_LATITUDE, import_web_mercator12.MAX_LATITUDE);
13604
+ props.latitude = (0, import_core30.clamp)(latitude, -import_web_mercator12.MAX_LATITUDE, import_web_mercator12.MAX_LATITUDE);
13308
13605
  if (maxBounds) {
13309
- props.longitude = (0, import_core29.clamp)(props.longitude, maxBounds[0][0], maxBounds[1][0]);
13310
- props.latitude = (0, import_core29.clamp)(props.latitude, maxBounds[0][1], maxBounds[1][1]);
13606
+ props.longitude = (0, import_core30.clamp)(props.longitude, maxBounds[0][0], maxBounds[1][0]);
13607
+ props.latitude = (0, import_core30.clamp)(props.latitude, maxBounds[0][1], maxBounds[1][1]);
13311
13608
  }
13312
13609
  if (maxBounds) {
13313
13610
  const effectiveZoom = props.zoom - zoomAdjust(latitude);
@@ -13315,11 +13612,11 @@ var GlobeState = class extends MapState {
13315
13612
  const latSpan = maxBounds[1][1] - maxBounds[0][1];
13316
13613
  if (latSpan > 0 && latSpan < import_web_mercator12.MAX_LATITUDE * 2) {
13317
13614
  const halfHeightDegrees = Math.min(pixelsToDegrees(props.height, effectiveZoom), latSpan) / 2;
13318
- props.latitude = (0, import_core29.clamp)(props.latitude, maxBounds[0][1] + halfHeightDegrees, maxBounds[1][1] - halfHeightDegrees);
13615
+ props.latitude = (0, import_core30.clamp)(props.latitude, maxBounds[0][1] + halfHeightDegrees, maxBounds[1][1] - halfHeightDegrees);
13319
13616
  }
13320
13617
  if (lngSpan > 0 && lngSpan < 360) {
13321
13618
  const halfWidthDegrees = Math.min(pixelsToDegrees(props.width / Math.cos(props.latitude * DEGREES_TO_RADIANS4), effectiveZoom), lngSpan) / 2;
13322
- props.longitude = (0, import_core29.clamp)(props.longitude, maxBounds[0][0] + halfWidthDegrees, maxBounds[1][0] - halfWidthDegrees);
13619
+ props.longitude = (0, import_core30.clamp)(props.longitude, maxBounds[0][0] + halfWidthDegrees, maxBounds[1][0] - halfWidthDegrees);
13323
13620
  }
13324
13621
  }
13325
13622
  if (props.latitude !== latitude) {
@@ -13349,7 +13646,7 @@ var GlobeState = class extends MapState {
13349
13646
  if (minZoom > maxZoom)
13350
13647
  minZoom = maxZoom;
13351
13648
  }
13352
- return (0, import_core29.clamp)(zoom, minZoom + zoomAdjustment, maxZoom + zoomAdjustment);
13649
+ return (0, import_core30.clamp)(zoom, minZoom + zoomAdjustment, maxZoom + zoomAdjustment);
13353
13650
  }
13354
13651
  };
13355
13652
  var GlobeController = class extends Controller {
@@ -13390,27 +13687,55 @@ var TerrainController = class extends MapController {
13390
13687
  super(...arguments);
13391
13688
  this._terrainAltitude = void 0;
13392
13689
  this._terrainAltitudeTarget = void 0;
13690
+ this._pickFrameId = null;
13691
+ this._lastPickTime = 0;
13393
13692
  }
13394
13693
  setProps(props) {
13395
13694
  super.setProps({ rotationPivot: "3d", ...props });
13396
- if (this._terrainAltitude !== void 0 && this._terrainAltitudeTarget !== void 0 && Math.abs(this._terrainAltitudeTarget - this._terrainAltitude) > 0.01) {
13397
- this.updateViewport(new this.ControllerState({
13398
- makeViewport: this.makeViewport,
13399
- ...this.props,
13400
- ...this.state
13401
- }));
13695
+ if (this._pickFrameId === null) {
13696
+ const loop = () => {
13697
+ const now = Date.now();
13698
+ if (now - this._lastPickTime > 500 && !this.isDragging()) {
13699
+ this._lastPickTime = now;
13700
+ this._pickTerrainCenterAltitude();
13701
+ if (this._terrainAltitude === void 0 && this._terrainAltitudeTarget !== void 0) {
13702
+ this._terrainAltitude = this._terrainAltitudeTarget;
13703
+ const controllerState = new this.ControllerState({
13704
+ makeViewport: this.makeViewport,
13705
+ ...this.props,
13706
+ ...this.state
13707
+ });
13708
+ const rebaseProps = this._rebaseViewport(this._terrainAltitudeTarget, controllerState);
13709
+ if (rebaseProps) {
13710
+ const rebasedState = new this.ControllerState({
13711
+ makeViewport: this.makeViewport,
13712
+ ...this.props,
13713
+ ...this.state,
13714
+ ...rebaseProps
13715
+ });
13716
+ super.updateViewport(rebasedState);
13717
+ }
13718
+ }
13719
+ }
13720
+ this._pickFrameId = requestAnimationFrame(loop);
13721
+ };
13722
+ this._pickFrameId = requestAnimationFrame(loop);
13723
+ }
13724
+ }
13725
+ finalize() {
13726
+ if (this._pickFrameId !== null) {
13727
+ cancelAnimationFrame(this._pickFrameId);
13728
+ this._pickFrameId = null;
13402
13729
  }
13730
+ super.finalize();
13403
13731
  }
13404
13732
  updateViewport(newControllerState, extraProps = null, interactionState = {}) {
13405
- const SMOOTHING = 0.05;
13406
- if (this._terrainAltitudeTarget === void 0)
13407
- return;
13408
13733
  if (this._terrainAltitude === void 0) {
13409
- this._terrainAltitude = this._terrainAltitudeTarget;
13410
- extraProps = this._rebaseViewport(this._terrainAltitudeTarget, newControllerState, extraProps);
13411
- } else {
13412
- this._terrainAltitude += (this._terrainAltitudeTarget - this._terrainAltitude) * SMOOTHING;
13734
+ super.updateViewport(newControllerState, extraProps, interactionState);
13735
+ return;
13413
13736
  }
13737
+ const SMOOTHING = 0.05;
13738
+ this._terrainAltitude += (this._terrainAltitudeTarget - this._terrainAltitude) * SMOOTHING;
13414
13739
  const viewportProps = newControllerState.getViewportProps();
13415
13740
  const pos = viewportProps.position || [0, 0, 0];
13416
13741
  extraProps = {
@@ -13419,18 +13744,6 @@ var TerrainController = class extends MapController {
13419
13744
  };
13420
13745
  super.updateViewport(newControllerState, extraProps, interactionState);
13421
13746
  }
13422
- _onPanStart(event) {
13423
- this._pickTerrainCenterAltitude();
13424
- return super._onPanStart(event);
13425
- }
13426
- _onWheel(event) {
13427
- this._pickTerrainCenterAltitude();
13428
- return super._onWheel(event);
13429
- }
13430
- _onDoubleClick(event) {
13431
- this._pickTerrainCenterAltitude();
13432
- return super._onDoubleClick(event);
13433
- }
13434
13747
  _pickTerrainCenterAltitude() {
13435
13748
  if (!this.pickPosition) {
13436
13749
  return;
@@ -13442,10 +13755,10 @@ var TerrainController = class extends MapController {
13442
13755
  }
13443
13756
  }
13444
13757
  /**
13445
- * Utility function to return viewport that looks the same, but with
13446
- * a position shifted to [0, 0, altitude]
13758
+ * Compute viewport adjustments to keep the view visually the same
13759
+ * when shifting position to [0, 0, altitude].
13447
13760
  */
13448
- _rebaseViewport(altitude, newControllerState, extraProps) {
13761
+ _rebaseViewport(altitude, newControllerState) {
13449
13762
  const viewportProps = newControllerState.getViewportProps();
13450
13763
  const oldViewport = this.makeViewport({ ...viewportProps, position: [0, 0, 0] });
13451
13764
  const oldCameraPos = oldViewport.cameraPosition;
@@ -13453,7 +13766,7 @@ var TerrainController = class extends MapController {
13453
13766
  const cameraHeightAboveOldCenter = oldCameraPos[2];
13454
13767
  const newCameraHeightAboveCenter = cameraHeightAboveOldCenter - centerZOffset;
13455
13768
  if (newCameraHeightAboveCenter <= 0) {
13456
- return extraProps;
13769
+ return null;
13457
13770
  }
13458
13771
  const zoomDelta = Math.log2(cameraHeightAboveOldCenter / newCameraHeightAboveCenter);
13459
13772
  const newZoom = viewportProps.zoom + zoomDelta;
@@ -13467,9 +13780,9 @@ var TerrainController = class extends MapController {
13467
13780
  const worldPoint = oldViewport.unproject(screenCenter, { targetZ: altitude });
13468
13781
  if (worldPoint && "panByPosition3D" in newViewport && typeof newViewport.panByPosition3D === "function") {
13469
13782
  const adjusted = newViewport.panByPosition3D(worldPoint, screenCenter);
13470
- return { ...extraProps, position: [0, 0, altitude], zoom: newZoom, ...adjusted };
13783
+ return { position: [0, 0, altitude], zoom: newZoom, ...adjusted };
13471
13784
  }
13472
- return extraProps;
13785
+ return null;
13473
13786
  }
13474
13787
  };
13475
13788
 
@@ -13535,7 +13848,7 @@ LayerExtension.extensionName = "LayerExtension";
13535
13848
  var layer_extension_default = LayerExtension;
13536
13849
 
13537
13850
  // dist/transitions/fly-to-interpolator.js
13538
- var import_core30 = require("@math.gl/core");
13851
+ var import_core31 = require("@math.gl/core");
13539
13852
  var import_web_mercator13 = require("@math.gl/web-mercator");
13540
13853
  var LINEARLY_INTERPOLATED_PROPS = {
13541
13854
  bearing: 0,
@@ -13558,7 +13871,7 @@ var FlyToInterpolator = class extends TransitionInterpolator {
13558
13871
  interpolateProps(startProps, endProps, t) {
13559
13872
  const viewport = (0, import_web_mercator13.flyToViewport)(startProps, endProps, t, this.opts);
13560
13873
  for (const key in LINEARLY_INTERPOLATED_PROPS) {
13561
- viewport[key] = (0, import_core30.lerp)(startProps[key] || LINEARLY_INTERPOLATED_PROPS[key], endProps[key] || LINEARLY_INTERPOLATED_PROPS[key], t);
13874
+ viewport[key] = (0, import_core31.lerp)(startProps[key] || LINEARLY_INTERPOLATED_PROPS[key], endProps[key] || LINEARLY_INTERPOLATED_PROPS[key], t);
13562
13875
  }
13563
13876
  return viewport;
13564
13877
  }
@@ -13573,7 +13886,7 @@ var FlyToInterpolator = class extends TransitionInterpolator {
13573
13886
  };
13574
13887
 
13575
13888
  // dist/utils/tesselator.js
13576
- var import_core31 = require("@luma.gl/core");
13889
+ var import_core32 = require("@luma.gl/core");
13577
13890
  var Tesselator = class {
13578
13891
  constructor(opts) {
13579
13892
  this.indexStarts = [0];
@@ -13680,7 +13993,7 @@ var Tesselator = class {
13680
13993
  instanceCount = vertexStarts[data.length] || 0;
13681
13994
  if (ArrayBuffer.isView(geometryBuffer)) {
13682
13995
  instanceCount = instanceCount || geometryBuffer.length / this.positionSize;
13683
- } else if (geometryBuffer instanceof import_core31.Buffer) {
13996
+ } else if (geometryBuffer instanceof import_core32.Buffer) {
13684
13997
  const byteStride = this.positionSize * 4;
13685
13998
  instanceCount = instanceCount || geometryBuffer.byteLength / byteStride;
13686
13999
  } else if (geometryBuffer.buffer) {