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

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 (88) 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 +3748 -1377
  6. package/dist/index.cjs +545 -219
  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/layers-pass.d.ts.map +1 -1
  27. package/dist/passes/layers-pass.js +13 -0
  28. package/dist/passes/layers-pass.js.map +1 -1
  29. package/dist/passes/pick-layers-pass.d.ts.map +1 -1
  30. package/dist/passes/pick-layers-pass.js +7 -2
  31. package/dist/passes/pick-layers-pass.js.map +1 -1
  32. package/dist/passes/screen-pass-uniforms.d.ts +1 -1
  33. package/dist/passes/screen-pass-uniforms.js +1 -1
  34. package/dist/shaderlib/color/color.d.ts +1 -4
  35. package/dist/shaderlib/color/color.d.ts.map +1 -1
  36. package/dist/shaderlib/color/color.js +0 -12
  37. package/dist/shaderlib/color/color.js.map +1 -1
  38. package/dist/shaderlib/index.d.ts +1 -2
  39. package/dist/shaderlib/index.d.ts.map +1 -1
  40. package/dist/shaderlib/index.js +1 -2
  41. package/dist/shaderlib/index.js.map +1 -1
  42. package/dist/shaderlib/misc/layer-uniforms.d.ts +3 -2
  43. package/dist/shaderlib/misc/layer-uniforms.d.ts.map +1 -1
  44. package/dist/shaderlib/misc/layer-uniforms.js +10 -1
  45. package/dist/shaderlib/misc/layer-uniforms.js.map +1 -1
  46. package/dist/shaderlib/picking/picking.d.ts +5 -3
  47. package/dist/shaderlib/picking/picking.d.ts.map +1 -1
  48. package/dist/shaderlib/picking/picking.js +29 -0
  49. package/dist/shaderlib/picking/picking.js.map +1 -1
  50. package/dist/shaderlib/project/project.glsl.js +1 -1
  51. package/dist/shaderlib/project/project.wgsl.d.ts.map +1 -1
  52. package/dist/shaderlib/project/project.wgsl.js +4 -6
  53. package/dist/shaderlib/project/project.wgsl.js.map +1 -1
  54. package/dist/shaderlib/shadow/shadow.d.ts +2 -2
  55. package/dist/shaderlib/shadow/shadow.js +1 -1
  56. package/dist/transitions/gpu-interpolation-transition.js +2 -2
  57. package/dist/transitions/gpu-interpolation-transition.js.map +1 -1
  58. package/dist/transitions/gpu-spring-transition.js +1 -1
  59. package/dist/transitions/gpu-transition-utils.d.ts.map +1 -1
  60. package/dist/transitions/gpu-transition-utils.js +3 -4
  61. package/dist/transitions/gpu-transition-utils.js.map +1 -1
  62. package/dist/utils/texture.d.ts.map +1 -1
  63. package/dist/utils/texture.js +3 -0
  64. package/dist/utils/texture.js.map +1 -1
  65. package/dist/utils/typed-array-manager.js.map +1 -1
  66. package/dist.min.js +582 -247
  67. package/package.json +8 -9
  68. package/src/controllers/terrain-controller.ts +60 -51
  69. package/src/lib/attribute/gl-utils.ts +2 -2
  70. package/src/lib/deck-picker.ts +98 -17
  71. package/src/lib/deck.ts +334 -86
  72. package/src/lib/layer.ts +98 -8
  73. package/src/lib/view-manager.ts +1 -1
  74. package/src/passes/layers-pass.ts +21 -1
  75. package/src/passes/pick-layers-pass.ts +6 -2
  76. package/src/passes/screen-pass-uniforms.ts +1 -1
  77. package/src/shaderlib/color/color.ts +0 -12
  78. package/src/shaderlib/index.ts +1 -3
  79. package/src/shaderlib/misc/layer-uniforms.ts +11 -1
  80. package/src/shaderlib/picking/picking.ts +30 -0
  81. package/src/shaderlib/project/project.glsl.ts +1 -1
  82. package/src/shaderlib/project/project.wgsl.ts +4 -6
  83. package/src/shaderlib/shadow/shadow.ts +1 -1
  84. package/src/transitions/gpu-interpolation-transition.ts +2 -2
  85. package/src/transitions/gpu-spring-transition.ts +1 -1
  86. package/src/transitions/gpu-transition-utils.ts +4 -5
  87. package/src/utils/texture.ts +2 -0
  88. package/src/utils/typed-array-manager.ts +3 -3
package/dist/index.cjs CHANGED
@@ -82,9 +82,9 @@ __export(dist_exports, {
82
82
  createIterable: () => createIterable,
83
83
  fp64LowPart: () => fp64LowPart,
84
84
  getShaderAssembler: () => getShaderAssembler,
85
- gouraudMaterial: () => import_shadertools4.gouraudMaterial,
85
+ gouraudMaterial: () => import_shadertools3.gouraudMaterial,
86
86
  log: () => log_default,
87
- phongMaterial: () => import_shadertools4.phongMaterial,
87
+ phongMaterial: () => import_shadertools3.phongMaterial,
88
88
  picking: () => picking_default,
89
89
  project: () => project_default,
90
90
  project32: () => project32_default,
@@ -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.6" : 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}`);
@@ -257,15 +257,25 @@ var VERSION = checkVersion();
257
257
 
258
258
  // dist/shaderlib/index.js
259
259
  var import_shadertools3 = require("@luma.gl/shadertools");
260
- var import_shadertools4 = require("@luma.gl/shadertools");
261
260
 
262
261
  // dist/shaderlib/misc/layer-uniforms.js
263
- var uniformBlock = `uniform layerUniforms {
262
+ var uniformBlockWGSL = (
263
+ /* wgsl */
264
+ `struct LayerUniforms {
265
+ opacity: f32,
266
+ };
267
+
268
+ @group(0) @binding(auto)
269
+ var<uniform> layer: LayerUniforms;
270
+ `
271
+ );
272
+ var uniformBlock = `layout(std140) uniform layerUniforms {
264
273
  uniform float opacity;
265
274
  } layer;
266
275
  `;
267
276
  var layerUniforms = {
268
277
  name: "layer",
278
+ source: uniformBlockWGSL,
269
279
  vs: uniformBlock,
270
280
  fs: uniformBlock,
271
281
  getUniforms: (props) => {
@@ -285,15 +295,6 @@ var colorWGSL = (
285
295
  /* WGSL */
286
296
  `
287
297
 
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
298
  @must_use
298
299
  fn deckgl_premultiplied_alpha(fragColor: vec4<f32>) -> vec4<f32> {
299
300
  return vec4(fragColor.rgb * fragColor.a, fragColor.a);
@@ -306,9 +307,6 @@ var color_default = {
306
307
  source: colorWGSL,
307
308
  getUniforms: (_props) => {
308
309
  return {};
309
- },
310
- uniformTypes: {
311
- opacity: "f32"
312
310
  }
313
311
  // @ts-ignore TODO v9.1
314
312
  };
@@ -716,14 +714,13 @@ struct ProjectUniforms {
716
714
  pseudoMeters: i32,
717
715
  };
718
716
 
719
- @group(0) @binding(0)
717
+ @group(0) @binding(auto)
720
718
  var<uniform> project: ProjectUniforms;
721
719
 
722
720
  // -----------------------------------------------------------------------------
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.)
721
+ // Geometry data shared across the project helpers.
722
+ // The active layer shader is responsible for populating this private module
723
+ // state before calling the project functions below.
727
724
  // -----------------------------------------------------------------------------
728
725
 
729
726
  // Structure to carry additional geometry data used by deck.gl filters.
@@ -736,7 +733,6 @@ struct Geometry {
736
733
  pickingColor: vec3<f32>,
737
734
  };
738
735
 
739
- // @group(0) @binding(1)
740
736
  var<private> geometry: Geometry;
741
737
  `
742
738
  );
@@ -981,7 +977,7 @@ var projectGLSL = (
981
977
  `${COORDINATE_SYSTEM_GLSL_CONSTANTS}
982
978
  ${PROJECTION_MODE_GLSL_CONSTANTS}
983
979
  ${UNIT_GLSL_CONSTANTS}
984
- uniform projectUniforms {
980
+ layout(std140) uniform projectUniforms {
985
981
  bool wrapLongitude;
986
982
  int coordinateSystem;
987
983
  vec3 commonUnitsPerMeter;
@@ -1296,7 +1292,7 @@ var import_web_mercator = require("@math.gl/web-mercator");
1296
1292
  var uniformBlock2 = (
1297
1293
  /* glsl */
1298
1294
  `
1299
- uniform shadowUniforms {
1295
+ layout(std140) uniform shadowUniforms {
1300
1296
  bool drawShadowMap;
1301
1297
  bool useShadowMap;
1302
1298
  vec4 color;
@@ -1524,8 +1520,39 @@ var shadow_default = {
1524
1520
 
1525
1521
  // dist/shaderlib/picking/picking.js
1526
1522
  var import_shadertools2 = require("@luma.gl/shadertools");
1523
+ var sourceWGSL = (
1524
+ /* wgsl */
1525
+ `struct pickingUniforms {
1526
+ isActive: f32,
1527
+ isAttribute: f32,
1528
+ isHighlightActive: f32,
1529
+ useFloatColors: f32,
1530
+ highlightedObjectColor: vec3<f32>,
1531
+ highlightColor: vec4<f32>,
1532
+ };
1533
+
1534
+ @group(0) @binding(auto) var<uniform> picking: pickingUniforms;
1535
+
1536
+ fn picking_normalizeColor(color: vec3<f32>) -> vec3<f32> {
1537
+ return select(color / 255.0, color, picking.useFloatColors > 0.5);
1538
+ }
1539
+
1540
+ fn picking_normalizeColor4(color: vec4<f32>) -> vec4<f32> {
1541
+ return select(color / 255.0, color, picking.useFloatColors > 0.5);
1542
+ }
1543
+
1544
+ fn picking_isColorZero(color: vec3<f32>) -> bool {
1545
+ return dot(color, vec3<f32>(1.0)) < 0.00001;
1546
+ }
1547
+
1548
+ fn picking_isColorValid(color: vec3<f32>) -> bool {
1549
+ return dot(color, vec3<f32>(1.0)) > 0.00001;
1550
+ }
1551
+ `
1552
+ );
1527
1553
  var picking_default = {
1528
1554
  ...import_shadertools2.picking,
1555
+ source: sourceWGSL,
1529
1556
  defaultUniforms: { ...import_shadertools2.picking.defaultUniforms, useFloatColors: false },
1530
1557
  inject: {
1531
1558
  "vs:DECKGL_FILTER_GL_POSITION": `
@@ -1636,6 +1663,16 @@ var Pass = class {
1636
1663
  };
1637
1664
 
1638
1665
  // dist/passes/layers-pass.js
1666
+ var WEBGPU_DEFAULT_DRAW_PARAMETERS = {
1667
+ depthWriteEnabled: true,
1668
+ depthCompare: "less-equal",
1669
+ blendColorOperation: "add",
1670
+ blendColorSrcFactor: "src-alpha",
1671
+ blendColorDstFactor: "one",
1672
+ blendAlphaOperation: "add",
1673
+ blendAlphaSrcFactor: "one-minus-dst-alpha",
1674
+ blendAlphaDstFactor: "one"
1675
+ };
1639
1676
  var LayersPass = class extends Pass {
1640
1677
  constructor() {
1641
1678
  super(...arguments);
@@ -1724,7 +1761,9 @@ var LayersPass = class extends Pass {
1724
1761
  layerParam.shouldDrawLayer = true;
1725
1762
  layerParam.layerRenderIndex = indexResolver(layer, shouldDrawLayer);
1726
1763
  layerParam.shaderModuleProps = this._getShaderModuleProps(layer, effects, pass, shaderModuleProps);
1764
+ const defaultParams = layer.context.device.type === "webgpu" ? WEBGPU_DEFAULT_DRAW_PARAMETERS : null;
1727
1765
  layerParam.layerParameters = {
1766
+ ...defaultParams,
1728
1767
  ...(_a = layer.context.deck) == null ? void 0 : _a.props.parameters,
1729
1768
  ...this.getLayerParameters(layer, layerIndex, viewport)
1730
1769
  };
@@ -2943,13 +2982,13 @@ var SunLight = class extends DirectionalLight {
2943
2982
  };
2944
2983
 
2945
2984
  // dist/effects/post-process-effect.js
2946
- var import_shadertools5 = require("@luma.gl/shadertools");
2985
+ var import_shadertools4 = require("@luma.gl/shadertools");
2947
2986
 
2948
2987
  // dist/passes/screen-pass.js
2949
2988
  var import_engine = require("@luma.gl/engine");
2950
2989
 
2951
2990
  // dist/passes/screen-pass-uniforms.js
2952
- var uniformBlock3 = `uniform screenUniforms {
2991
+ var uniformBlock3 = `layout(std140) uniform screenUniforms {
2953
2992
  vec2 texSize;
2954
2993
  } screen;
2955
2994
  `;
@@ -3022,7 +3061,7 @@ var PostProcessEffect = class {
3022
3061
  constructor(module2, props) {
3023
3062
  this.id = `${module2.name}-pass`;
3024
3063
  this.props = props;
3025
- (0, import_shadertools5.initializeShaderModule)(module2);
3064
+ (0, import_shadertools4.initializeShaderModule)(module2);
3026
3065
  this.module = module2;
3027
3066
  }
3028
3067
  setup({ device }) {
@@ -3176,7 +3215,11 @@ var PickLayersPass = class extends LayersPass {
3176
3215
  } else if (pickable && operation.includes("draw")) {
3177
3216
  Object.assign(pickParameters, PICKING_BLENDING);
3178
3217
  pickParameters.blend = true;
3179
- pickParameters.blendColor = encodeColor(this._colorEncoderState, layer, viewport);
3218
+ if (this.device.type === "webgpu") {
3219
+ pickParameters.blendConstant = encodeColor(this._colorEncoderState, layer, viewport);
3220
+ } else {
3221
+ pickParameters.blendColor = encodeColor(this._colorEncoderState, layer, viewport);
3222
+ }
3180
3223
  if (operation.includes("terrain") && ((_a = layer.state) == null ? void 0 : _a._hasPickingCover)) {
3181
3224
  pickParameters.blendAlphaSrcFactor = "one";
3182
3225
  }
@@ -6147,6 +6190,9 @@ var DeckRenderer = class {
6147
6190
  }
6148
6191
  };
6149
6192
 
6193
+ // dist/lib/deck-picker.js
6194
+ var import_core16 = require("@luma.gl/core");
6195
+
6150
6196
  // dist/lib/picking/query-object.js
6151
6197
  var NO_PICKED_OBJECT = {
6152
6198
  pickedColor: null,
@@ -6355,7 +6401,7 @@ var DeckPicker = class {
6355
6401
  /**
6356
6402
  * Pick the closest info at given coordinate
6357
6403
  * @returns picking info
6358
- * @deprecated WebGL only - use pickObjectAsync instead
6404
+ * @note WebGL only - use pickObjectAsync instead
6359
6405
  */
6360
6406
  pickObject(opts) {
6361
6407
  return this._pickClosestObject(opts);
@@ -6363,7 +6409,7 @@ var DeckPicker = class {
6363
6409
  /**
6364
6410
  * Get all unique infos within a bounding box
6365
6411
  * @returns all unique infos within a bounding box
6366
- * @deprecated WebGL only - use pickObjectAsync instead
6412
+ * @note WebGL only - use pickObjectAsync instead
6367
6413
  */
6368
6414
  pickObjects(opts) {
6369
6415
  return this._pickVisibleObjects(opts);
@@ -6389,13 +6435,25 @@ var DeckPicker = class {
6389
6435
  _resizeBuffer() {
6390
6436
  var _a, _b;
6391
6437
  if (!this.pickingFBO) {
6438
+ const pickingColorTexture = this.device.createTexture({
6439
+ format: "rgba8unorm",
6440
+ width: 1,
6441
+ height: 1,
6442
+ usage: import_core16.Texture.RENDER_ATTACHMENT | import_core16.Texture.COPY_SRC
6443
+ });
6392
6444
  this.pickingFBO = this.device.createFramebuffer({
6393
- colorAttachments: ["rgba8unorm"],
6445
+ colorAttachments: [pickingColorTexture],
6394
6446
  depthStencilAttachment: "depth16unorm"
6395
6447
  });
6396
6448
  if (this.device.isTextureFormatRenderable("rgba32float")) {
6449
+ const depthColorTexture = this.device.createTexture({
6450
+ format: "rgba32float",
6451
+ width: 1,
6452
+ height: 1,
6453
+ usage: import_core16.Texture.RENDER_ATTACHMENT | import_core16.Texture.COPY_SRC
6454
+ });
6397
6455
  const depthFBO = this.device.createFramebuffer({
6398
- colorAttachments: ["rgba32float"],
6456
+ colorAttachments: [depthColorTexture],
6399
6457
  depthStencilAttachment: "depth16unorm"
6400
6458
  });
6401
6459
  this.depthFBO = depthFBO;
@@ -6453,7 +6511,7 @@ var DeckPicker = class {
6453
6511
  for (let i = 0; i < depth; i++) {
6454
6512
  let pickInfo;
6455
6513
  if (deviceRect) {
6456
- const pickedResult = this._drawAndSample({
6514
+ const pickedResult = await this._drawAndSampleAsync({
6457
6515
  layers: pickableLayers,
6458
6516
  views,
6459
6517
  viewports,
@@ -6479,7 +6537,7 @@ var DeckPicker = class {
6479
6537
  let z;
6480
6538
  const depthLayers = this._getDepthLayers(pickInfo, pickableLayers, unproject3D);
6481
6539
  if (depthLayers.length > 0) {
6482
- const { pickedColors: pickedColors2 } = this._drawAndSample({
6540
+ const { pickedColors: pickedColors2 } = await this._drawAndSampleAsync({
6483
6541
  layers: depthLayers,
6484
6542
  views,
6485
6543
  viewports,
@@ -6666,7 +6724,7 @@ var DeckPicker = class {
6666
6724
  width: deviceRight - deviceLeft,
6667
6725
  height: deviceTop - deviceBottom
6668
6726
  };
6669
- const pickedResult = this._drawAndSample({
6727
+ const pickedResult = await this._drawAndSampleAsync({
6670
6728
  layers: pickableLayers,
6671
6729
  views,
6672
6730
  viewports,
@@ -6777,6 +6835,7 @@ var DeckPicker = class {
6777
6835
  }
6778
6836
  // Note: Implementation of the overloaded signatures above, TSDoc is on the signatures
6779
6837
  async _drawAndSampleAsync({ layers, views, viewports, onViewportActive, deviceRect, cullRect, effects, pass }, pickZ = false) {
6838
+ var _a;
6780
6839
  const pickingFBO = pickZ ? this.depthFBO : this.pickingFBO;
6781
6840
  const opts = {
6782
6841
  layers,
@@ -6801,16 +6860,58 @@ var DeckPicker = class {
6801
6860
  const { decodePickingColor, stats } = this.pickLayersPass.render(opts);
6802
6861
  this._updateStats(stats);
6803
6862
  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
- });
6863
+ const texture = (_a = pickingFBO.colorAttachments[0]) == null ? void 0 : _a.texture;
6864
+ if (!texture) {
6865
+ throw new Error("Picking framebuffer color attachment is missing");
6866
+ }
6867
+ const pickedColors = await this._readTextureDataAsync(texture, { x, y, width, height }, pickZ ? Float32Array : Uint8Array);
6868
+ if (!pickZ) {
6869
+ let hasNonZeroAlpha = false;
6870
+ for (let i = 3; i < pickedColors.length; i += 4) {
6871
+ if (pickedColors[i] !== 0) {
6872
+ hasNonZeroAlpha = true;
6873
+ break;
6874
+ }
6875
+ }
6876
+ if (!hasNonZeroAlpha && pickedColors.length > 0) {
6877
+ log_default.warn("Async pick readback returned only zero alpha values", {
6878
+ deviceRect,
6879
+ bytes: Array.from(pickedColors.subarray(0, Math.min(pickedColors.length, 16)))
6880
+ })();
6881
+ }
6882
+ }
6812
6883
  return { pickedColors, decodePickingColor };
6813
6884
  }
6885
+ async _readTextureDataAsync(texture, options, ArrayType) {
6886
+ const { width, height } = options;
6887
+ const layout = texture.computeMemoryLayout(options);
6888
+ const readBuffer = this.device.createBuffer({
6889
+ byteLength: layout.byteLength,
6890
+ usage: import_core16.Buffer.COPY_DST | import_core16.Buffer.MAP_READ
6891
+ });
6892
+ try {
6893
+ texture.readBuffer(options, readBuffer);
6894
+ const readData = await readBuffer.readAsync(0, layout.byteLength);
6895
+ const bytesPerElement = ArrayType.BYTES_PER_ELEMENT;
6896
+ if (layout.bytesPerRow % bytesPerElement !== 0) {
6897
+ throw new Error(`Texture readback row stride ${layout.bytesPerRow} is not aligned to ${bytesPerElement}-byte elements.`);
6898
+ }
6899
+ const source3 = new ArrayType(readData.buffer, readData.byteOffset, layout.byteLength / bytesPerElement);
6900
+ const packedRowLength = width * 4;
6901
+ const sourceRowLength = layout.bytesPerRow / bytesPerElement;
6902
+ if (sourceRowLength < packedRowLength) {
6903
+ throw new Error(`Texture readback row stride ${sourceRowLength} is smaller than packed row length ${packedRowLength}.`);
6904
+ }
6905
+ const packed = new ArrayType(width * height * 4);
6906
+ for (let row = 0; row < height; row++) {
6907
+ const sourceStart = row * sourceRowLength;
6908
+ packed.set(source3.subarray(sourceStart, sourceStart + packedRowLength), row * packedRowLength);
6909
+ }
6910
+ return packed;
6911
+ } finally {
6912
+ readBuffer.destroy();
6913
+ }
6914
+ }
6814
6915
  // Note: Implementation of the overloaded signatures above, TSDoc is on the signatures
6815
6916
  _drawAndSample({ layers, views, viewports, onViewportActive, deviceRect, cullRect, effects, pass }, pickZ = false) {
6816
6917
  const pickingFBO = pickZ ? this.depthFBO : this.pickingFBO;
@@ -7311,11 +7412,11 @@ TooltipWidget.defaultProps = {
7311
7412
  };
7312
7413
 
7313
7414
  // dist/lib/deck.js
7314
- var import_core16 = require("@luma.gl/core");
7415
+ var import_core17 = require("@luma.gl/core");
7315
7416
  var import_webgl = require("@luma.gl/webgl");
7417
+ var import_constants11 = require("@luma.gl/webgl/constants");
7316
7418
  var import_engine3 = require("@luma.gl/engine");
7317
7419
  var import_engine4 = require("@luma.gl/engine");
7318
- var import_constants11 = require("@luma.gl/constants");
7319
7420
  var import_stats2 = require("@probe.gl/stats");
7320
7421
  var import_mjolnir2 = require("mjolnir.js");
7321
7422
  function noop2() {
@@ -7329,6 +7430,7 @@ var defaultProps = {
7329
7430
  viewState: null,
7330
7431
  initialViewState: null,
7331
7432
  pickingRadius: 0,
7433
+ pickAsync: "auto",
7332
7434
  layerFilter: null,
7333
7435
  parameters: {},
7334
7436
  parent: null,
@@ -7414,6 +7516,8 @@ var Deck = class {
7414
7516
  gpuMemory: 0
7415
7517
  };
7416
7518
  this._metricsCounter = 0;
7519
+ this._hoverPickSequence = 0;
7520
+ this._pointerDownPickSequence = 0;
7417
7521
  this._needsRedraw = "Initial render";
7418
7522
  this._pickRequest = {
7419
7523
  mode: "hover",
@@ -7424,6 +7528,7 @@ var Deck = class {
7424
7528
  unproject3D: false
7425
7529
  };
7426
7530
  this._lastPointerDownInfo = null;
7531
+ this._lastPointerDownInfoPromise = null;
7427
7532
  this._onPointerMove = (event) => {
7428
7533
  const { _pickRequest } = this;
7429
7534
  if (event.type === "pointerleave") {
@@ -7452,49 +7557,63 @@ var Deck = class {
7452
7557
  if (!eventHandlerProp || !pos || !this.layerManager) {
7453
7558
  return;
7454
7559
  }
7455
- let info;
7456
7560
  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);
7561
+ const internalPickingMode = this._getInternalPickingMode();
7562
+ if (!internalPickingMode) {
7563
+ return;
7480
7564
  }
7481
- if (!handled) {
7482
- rootHandler == null ? void 0 : rootHandler(info, event);
7483
- this.widgetManager.onEvent(info, event);
7565
+ if (internalPickingMode === "sync") {
7566
+ 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);
7567
+ this._dispatchPickingEvent(info, event);
7568
+ return;
7484
7569
  }
7570
+ const pointerDownInfoPromise = this._lastPointerDownInfoPromise || Promise.resolve(this._getLastPointerDownPickingInfo(pos.x, pos.y, layers));
7571
+ pointerDownInfoPromise.then((info) => {
7572
+ this._dispatchPickingEvent(info, event);
7573
+ }).catch((error) => {
7574
+ var _a2, _b;
7575
+ return (_b = (_a2 = this.props).onError) == null ? void 0 : _b.call(_a2, error);
7576
+ });
7485
7577
  };
7486
7578
  this._onPointerDown = (event) => {
7487
7579
  var _a2;
7488
- if (((_a2 = this.device) == null ? void 0 : _a2.type) === "webgpu") {
7580
+ const pos = event.offsetCenter;
7581
+ if (!pos) {
7489
7582
  return;
7490
7583
  }
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
7584
+ const internalPickingMode = this._getInternalPickingMode();
7585
+ if (!internalPickingMode) {
7586
+ return;
7587
+ }
7588
+ const layers = ((_a2 = this.layerManager) == null ? void 0 : _a2.getLayers()) || [];
7589
+ const pointerDownPickSequence = ++this._pointerDownPickSequence;
7590
+ if (internalPickingMode === "sync") {
7591
+ const pickedInfo = this._pickPointSync({
7592
+ x: pos.x,
7593
+ y: pos.y,
7594
+ radius: this.props.pickingRadius
7595
+ });
7596
+ const info = this._getFirstPickedInfo(pickedInfo);
7597
+ this._lastPointerDownInfo = info;
7598
+ this._lastPointerDownInfoPromise = Promise.resolve(info);
7599
+ return;
7600
+ }
7601
+ const pickPromise = this._pickPointAsync(this._getPointPickOptions(pos.x, pos.y, {}, layers)).then((pickResult) => this._getFirstPickedInfo(pickResult)).then((info) => {
7602
+ if (pointerDownPickSequence === this._pointerDownPickSequence) {
7603
+ this._lastPointerDownInfo = info;
7604
+ }
7605
+ return info;
7606
+ }).catch((error) => {
7607
+ var _a3, _b;
7608
+ (_b = (_a3 = this.props).onError) == null ? void 0 : _b.call(_a3, error);
7609
+ const fallbackInfo = this.deckPicker && this.viewManager ? this._getLastPointerDownPickingInfo(pos.x, pos.y, layers) : {};
7610
+ if (pointerDownPickSequence === this._pointerDownPickSequence) {
7611
+ this._lastPointerDownInfo = fallbackInfo;
7612
+ }
7613
+ return fallbackInfo;
7496
7614
  });
7497
- this._lastPointerDownInfo = pickedInfo.result[0] || pickedInfo.emptyInfo;
7615
+ this._lastPointerDownInfo = null;
7616
+ this._lastPointerDownInfoPromise = pickPromise;
7498
7617
  };
7499
7618
  this.props = { ...defaultProps, ...props };
7500
7619
  props = this.props;
@@ -7541,7 +7660,10 @@ var Deck = class {
7541
7660
  (_a = this.animationLoop) == null ? void 0 : _a.stop();
7542
7661
  (_b = this.animationLoop) == null ? void 0 : _b.destroy();
7543
7662
  this.animationLoop = null;
7663
+ this._hoverPickSequence++;
7664
+ this._pointerDownPickSequence++;
7544
7665
  this._lastPointerDownInfo = null;
7666
+ this._lastPointerDownInfoPromise = null;
7545
7667
  (_c = this.layerManager) == null ? void 0 : _c.finalize();
7546
7668
  this.layerManager = null;
7547
7669
  (_d = this.viewManager) == null ? void 0 : _d.finalize();
@@ -7576,6 +7698,7 @@ var Deck = class {
7576
7698
  this.viewState = props.initialViewState;
7577
7699
  }
7578
7700
  Object.assign(this.props, props);
7701
+ this._validateInternalPickingMode();
7579
7702
  this._setCanvasSize(this.props);
7580
7703
  const resolvedProps = Object.create(this.props);
7581
7704
  Object.assign(resolvedProps, {
@@ -7680,16 +7803,37 @@ var Deck = class {
7680
7803
  return this.canvas;
7681
7804
  }
7682
7805
  /** Query the object rendered on top at a given point */
7806
+ async pickObjectAsync(opts) {
7807
+ const infos = (await this._pickAsync("pickObjectAsync", "pickObject Time", opts)).result;
7808
+ return infos.length ? infos[0] : null;
7809
+ }
7810
+ /**
7811
+ * Query all objects rendered on top within a bounding box
7812
+ * @note Caveat: this method performs multiple async GPU queries, so state could potentially change between calls.
7813
+ */
7814
+ async pickObjectsAsync(opts) {
7815
+ return await this._pickAsync("pickObjectsAsync", "pickObjects Time", opts);
7816
+ }
7817
+ /**
7818
+ * Query the object rendered on top at a given point
7819
+ * @deprecated WebGL only. Use `pickObjectsAsync` instead
7820
+ */
7683
7821
  pickObject(opts) {
7684
7822
  const infos = this._pick("pickObject", "pickObject Time", opts).result;
7685
7823
  return infos.length ? infos[0] : null;
7686
7824
  }
7687
- /* Query all rendered objects at a given point */
7825
+ /**
7826
+ * Query all rendered objects at a given point
7827
+ * @deprecated WebGL only. Use `pickObjectsAsync` instead
7828
+ */
7688
7829
  pickMultipleObjects(opts) {
7689
7830
  opts.depth = opts.depth || 10;
7690
7831
  return this._pick("pickObject", "pickMultipleObjects Time", opts).result;
7691
7832
  }
7692
- /* Query all objects rendered on top within a bounding box */
7833
+ /**
7834
+ * Query all objects rendered on top within a bounding box
7835
+ * @deprecated WebGL only. Use `pickObjectsAsync` instead
7836
+ */
7693
7837
  pickObjects(opts) {
7694
7838
  return this._pick("pickObjects", "pickObjects Time", opts);
7695
7839
  }
@@ -7698,8 +7842,11 @@ var Deck = class {
7698
7842
  * @private
7699
7843
  */
7700
7844
  _pickPositionForController(x, y) {
7701
- const pickResult = this.pickObject({ x, y, radius: 0, unproject3D: true });
7702
- return pickResult;
7845
+ const internalPickingMode = this._getInternalPickingMode();
7846
+ if (internalPickingMode !== "sync") {
7847
+ return null;
7848
+ }
7849
+ return this.pickObject({ x, y, radius: 0, unproject3D: true });
7703
7850
  }
7704
7851
  /** Experimental
7705
7852
  * Add a global resource for sharing among layers
@@ -7730,6 +7877,114 @@ var Deck = class {
7730
7877
  var _a;
7731
7878
  (_a = this.layerManager) == null ? void 0 : _a.removeDefaultShaderModule(module2);
7732
7879
  }
7880
+ // Private Methods
7881
+ _resolveInternalPickingMode() {
7882
+ var _a, _b;
7883
+ const { pickAsync } = this.props;
7884
+ const deviceType = ((_a = this.device) == null ? void 0 : _a.type) || ((_b = this.props.deviceProps) == null ? void 0 : _b.type);
7885
+ if (pickAsync === "auto") {
7886
+ return deviceType === "webgpu" ? "async" : "sync";
7887
+ }
7888
+ if (pickAsync === "sync" && deviceType === "webgpu") {
7889
+ throw new Error('`pickAsync: "sync"` is not supported when Deck is using a WebGPU device.');
7890
+ }
7891
+ return pickAsync;
7892
+ }
7893
+ _getInternalPickingMode() {
7894
+ var _a, _b;
7895
+ try {
7896
+ return this._resolveInternalPickingMode();
7897
+ } catch (error) {
7898
+ (_b = (_a = this.props).onError) == null ? void 0 : _b.call(_a, error);
7899
+ return null;
7900
+ }
7901
+ }
7902
+ _validateInternalPickingMode() {
7903
+ this._getInternalPickingMode();
7904
+ }
7905
+ _getFirstPickedInfo({ result, emptyInfo }) {
7906
+ return result[0] || emptyInfo;
7907
+ }
7908
+ _shouldUnproject3D(layers = ((_a) => (_a = this.layerManager) == null ? void 0 : _a.getLayers())() || []) {
7909
+ return layers.some((layer) => layer.props.pickable === "3d");
7910
+ }
7911
+ _getPointPickOptions(x, y, opts = {}, layers = ((_b) => (_b = this.layerManager) == null ? void 0 : _b.getLayers())() || []) {
7912
+ return {
7913
+ x,
7914
+ y,
7915
+ radius: this.props.pickingRadius,
7916
+ unproject3D: this._shouldUnproject3D(layers),
7917
+ ...opts
7918
+ };
7919
+ }
7920
+ _pickPointSync(opts) {
7921
+ return this._pick("pickObject", "pickObject Time", opts);
7922
+ }
7923
+ _pickPointAsync(opts) {
7924
+ return this._pickAsync("pickObjectAsync", "pickObject Time", opts);
7925
+ }
7926
+ _getLastPointerDownPickingInfo(x, y, layers = ((_c) => (_c = this.layerManager) == null ? void 0 : _c.getLayers())() || []) {
7927
+ return this.deckPicker.getLastPickedObject({
7928
+ x,
7929
+ y,
7930
+ layers,
7931
+ viewports: this.getViewports({ x, y })
7932
+ }, this._lastPointerDownInfo);
7933
+ }
7934
+ _applyHoverCallbacks({ result, emptyInfo }, event) {
7935
+ var _a, _b, _c;
7936
+ if (!this.widgetManager) {
7937
+ return;
7938
+ }
7939
+ this.cursorState.isHovering = result.length > 0;
7940
+ let pickedInfo = emptyInfo;
7941
+ let handled = false;
7942
+ for (const info of result) {
7943
+ pickedInfo = info;
7944
+ handled = ((_a = info.layer) == null ? void 0 : _a.onHover(info, event)) || handled;
7945
+ }
7946
+ if (!handled) {
7947
+ (_c = (_b = this.props).onHover) == null ? void 0 : _c.call(_b, pickedInfo, event);
7948
+ this.widgetManager.onHover(pickedInfo, event);
7949
+ }
7950
+ }
7951
+ _dispatchPickingEvent(info, event) {
7952
+ if (!this.layerManager || !this.widgetManager) {
7953
+ return;
7954
+ }
7955
+ const eventHandlerProp = EVENT_HANDLERS[event.type];
7956
+ if (!eventHandlerProp) {
7957
+ return;
7958
+ }
7959
+ const { layer } = info;
7960
+ const layerHandler = layer && (layer[eventHandlerProp] || layer.props[eventHandlerProp]);
7961
+ const rootHandler = this.props[eventHandlerProp];
7962
+ let handled = false;
7963
+ if (layerHandler) {
7964
+ handled = layerHandler.call(layer, info, event);
7965
+ }
7966
+ if (!handled) {
7967
+ rootHandler == null ? void 0 : rootHandler(info, event);
7968
+ this.widgetManager.onEvent(info, event);
7969
+ }
7970
+ }
7971
+ _pickAsync(method, statKey, opts) {
7972
+ assert(this.deckPicker);
7973
+ const { stats } = this;
7974
+ stats.get("Pick Count").incrementCount();
7975
+ stats.get(statKey).timeStart();
7976
+ const infos = this.deckPicker[method]({
7977
+ // layerManager, viewManager and effectManager are always defined if deckPicker is
7978
+ layers: this.layerManager.getLayers(opts),
7979
+ views: this.viewManager.getViews(),
7980
+ viewports: this.getViewports(opts),
7981
+ onViewportActive: this.layerManager.activateViewport,
7982
+ effects: this.effectManager.getEffects(),
7983
+ ...opts
7984
+ });
7985
+ stats.get(statKey).timeEnd();
7986
+ return infos;
7987
+ }
7733
7988
  _pick(method, statKey, opts) {
7734
7989
  assert(this.deckPicker);
7735
7990
  const { stats } = this;
@@ -7847,7 +8102,7 @@ var Deck = class {
7847
8102
  alphaMode: ((_b = this.props.deviceProps) == null ? void 0 : _b.type) === "webgpu" ? "premultiplied" : void 0
7848
8103
  };
7849
8104
  const userOnResize = (_c = this.props.deviceProps) == null ? void 0 : _c.onResize;
7850
- return import_core16.luma.createDevice({
8105
+ return import_core17.luma.createDevice({
7851
8106
  // luma by default throws if a device is already attached
7852
8107
  // asynchronous device creation could happen after finalize() is called
7853
8108
  // TODO - createDevice should support AbortController?
@@ -7894,28 +8149,33 @@ var Deck = class {
7894
8149
  }
7895
8150
  /** Actually run picking */
7896
8151
  _pickAndCallback() {
7897
- var _a, _b, _c, _d, _e;
7898
- if (((_a = this.device) == null ? void 0 : _a.type) === "webgpu") {
7899
- return;
7900
- }
8152
+ var _a;
7901
8153
  const { _pickRequest } = this;
7902
8154
  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
- }
8155
+ const event = _pickRequest.event;
8156
+ const layers = ((_a = this.layerManager) == null ? void 0 : _a.getLayers()) || [];
8157
+ const pickOptions = this._getPointPickOptions(_pickRequest.x, _pickRequest.y, {
8158
+ radius: _pickRequest.radius,
8159
+ mode: _pickRequest.mode
8160
+ }, layers);
8161
+ const internalPickingMode = this._getInternalPickingMode();
8162
+ const hoverPickSequence = ++this._hoverPickSequence;
7918
8163
  _pickRequest.event = null;
8164
+ if (!internalPickingMode) {
8165
+ return;
8166
+ }
8167
+ if (internalPickingMode === "sync") {
8168
+ this._applyHoverCallbacks(this._pickPointSync(pickOptions), event);
8169
+ return;
8170
+ }
8171
+ this._pickPointAsync(pickOptions).then(({ result, emptyInfo }) => {
8172
+ if (hoverPickSequence === this._hoverPickSequence) {
8173
+ this._applyHoverCallbacks({ result, emptyInfo }, event);
8174
+ }
8175
+ }).catch((error) => {
8176
+ var _a2, _b;
8177
+ return (_b = (_a2 = this.props).onError) == null ? void 0 : _b.call(_a2, error);
8178
+ });
7919
8179
  }
7920
8180
  }
7921
8181
  _updateCursor() {
@@ -7927,6 +8187,7 @@ var Deck = class {
7927
8187
  _setDevice(device) {
7928
8188
  var _a, _b, _c, _d;
7929
8189
  this.device = device;
8190
+ this._validateInternalPickingMode();
7930
8191
  if (!this.animationLoop) {
7931
8192
  return;
7932
8193
  }
@@ -8035,7 +8296,6 @@ var Deck = class {
8035
8296
  }
8036
8297
  // Callbacks
8037
8298
  _onRenderFrame() {
8038
- var _a;
8039
8299
  this._getFrameStats();
8040
8300
  if (this._metricsCounter++ % 60 === 0) {
8041
8301
  this._getMetrics();
@@ -8048,9 +8308,7 @@ var Deck = class {
8048
8308
  this._updateCanvasSize();
8049
8309
  this._updateCursor();
8050
8310
  this.layerManager.updateLayers();
8051
- if (((_a = this.device) == null ? void 0 : _a.type) !== "webgpu") {
8052
- this._pickAndCallback();
8053
- }
8311
+ this._pickAndCallback();
8054
8312
  this.redraw();
8055
8313
  if (this.viewManager) {
8056
8314
  this.viewManager.updateViewStates();
@@ -8098,7 +8356,7 @@ var Deck = class {
8098
8356
  metrics.cpuTime = stats.get("CPU Time").time;
8099
8357
  metrics.gpuTimePerFrame = stats.get("GPU Time").getAverageTime();
8100
8358
  metrics.cpuTimePerFrame = stats.get("CPU Time").getAverageTime();
8101
- const memoryStats = import_core16.luma.stats.get("GPU Time and Memory");
8359
+ const memoryStats = import_core17.luma.stats.get("GPU Time and Memory");
8102
8360
  metrics.bufferMemory = memoryStats.get("Buffer Memory").count;
8103
8361
  metrics.textureMemory = memoryStats.get("Texture Memory").count;
8104
8362
  metrics.renderbufferMemory = memoryStats.get("Renderbuffer Memory").count;
@@ -8110,10 +8368,10 @@ Deck.VERSION = VERSION;
8110
8368
  var deck_default = Deck;
8111
8369
 
8112
8370
  // dist/lib/attribute/data-column.js
8113
- var import_core18 = require("@luma.gl/core");
8371
+ var import_core19 = require("@luma.gl/core");
8114
8372
 
8115
8373
  // dist/lib/attribute/gl-utils.js
8116
- var import_core17 = require("@luma.gl/core");
8374
+ var import_core18 = require("@luma.gl/core");
8117
8375
  function typedArrayFromDataType(type) {
8118
8376
  switch (type) {
8119
8377
  case "float64":
@@ -8122,10 +8380,10 @@ function typedArrayFromDataType(type) {
8122
8380
  case "unorm8":
8123
8381
  return Uint8ClampedArray;
8124
8382
  default:
8125
- return (0, import_core17.getTypedArrayConstructor)(type);
8383
+ return (0, import_core18.getTypedArrayConstructor)(type);
8126
8384
  }
8127
8385
  }
8128
- var dataTypeFromTypedArray = import_core17.getDataType;
8386
+ var dataTypeFromTypedArray = import_core18.dataTypeDecoder.getDataType.bind(import_core18.dataTypeDecoder);
8129
8387
  function getBufferAttributeLayout(name, accessor, deviceType) {
8130
8388
  if (accessor.size > 4) {
8131
8389
  return null;
@@ -8343,7 +8601,7 @@ var DataColumn = class {
8343
8601
  let opts;
8344
8602
  if (ArrayBuffer.isView(data)) {
8345
8603
  opts = { value: data };
8346
- } else if (data instanceof import_core18.Buffer) {
8604
+ } else if (data instanceof import_core19.Buffer) {
8347
8605
  opts = { buffer: data };
8348
8606
  } else {
8349
8607
  opts = data;
@@ -8528,7 +8786,7 @@ var DataColumn = class {
8528
8786
  ...(_a = this._buffer) == null ? void 0 : _a.props,
8529
8787
  id: this.id,
8530
8788
  // 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,
8789
+ usage: (isIndexed ? import_core19.Buffer.INDEX : import_core19.Buffer.VERTEX) | import_core19.Buffer.COPY_DST,
8532
8790
  indexType: isIndexed ? type : void 0,
8533
8791
  byteLength
8534
8792
  });
@@ -8991,8 +9249,8 @@ var Attribute = class extends DataColumn {
8991
9249
 
8992
9250
  // dist/transitions/gpu-interpolation-transition.js
8993
9251
  var import_engine5 = require("@luma.gl/engine");
8994
- var import_shadertools6 = require("@luma.gl/shadertools");
8995
- var import_constants14 = require("@luma.gl/constants");
9252
+ var import_shadertools5 = require("@luma.gl/shadertools");
9253
+ var import_constants14 = require("@luma.gl/webgl/constants");
8996
9254
 
8997
9255
  // dist/utils/array-utils.js
8998
9256
  function padArrayChunk(options) {
@@ -9059,7 +9317,7 @@ function padArray({ source: source3, target, size, getData, sourceStartIndices,
9059
9317
  }
9060
9318
 
9061
9319
  // dist/transitions/gpu-transition-utils.js
9062
- var import_constants13 = require("@luma.gl/constants");
9320
+ var import_constants13 = require("@luma.gl/webgl/constants");
9063
9321
  function cloneAttribute(attribute) {
9064
9322
  const { device, settings, value } = attribute;
9065
9323
  const newAttribute = new Attribute(device, settings);
@@ -9278,7 +9536,7 @@ var GPUInterpolationTransition = class extends GPUTransitionBase {
9278
9536
  this.transform.destroy();
9279
9537
  }
9280
9538
  };
9281
- var uniformBlock4 = `uniform interpolationUniforms {
9539
+ var uniformBlock4 = `layout(std140) uniform interpolationUniforms {
9282
9540
  float time;
9283
9541
  } interpolation;
9284
9542
  `;
@@ -9355,7 +9613,7 @@ function getTransform(device, attribute) {
9355
9613
  }
9356
9614
  ],
9357
9615
  // @ts-expect-error fp64 module only sets ONE uniform via defaultUniforms
9358
- modules: [import_shadertools6.fp64arithmetic, interpolationUniforms],
9616
+ modules: [import_shadertools5.fp64arithmetic, interpolationUniforms],
9359
9617
  defines: {
9360
9618
  // @ts-expect-error TODO fix luma type
9361
9619
  ATTRIBUTE_TYPE: attributeType,
@@ -9459,7 +9717,7 @@ var GPUSpringTransition = class extends GPUTransitionBase {
9459
9717
  this.framebuffer.destroy();
9460
9718
  }
9461
9719
  };
9462
- var uniformBlock5 = `uniform springUniforms {
9720
+ var uniformBlock5 = `layout(std140) uniform springUniforms {
9463
9721
  float damping;
9464
9722
  float stiffness;
9465
9723
  } spring;
@@ -9897,11 +10155,11 @@ var AttributeManager = class {
9897
10155
  };
9898
10156
 
9899
10157
  // dist/lib/layer.js
9900
- var import_core21 = require("@luma.gl/core");
10158
+ var import_core22 = require("@luma.gl/core");
9901
10159
  var import_webgl2 = require("@luma.gl/webgl");
9902
10160
 
9903
10161
  // dist/transitions/cpu-interpolation-transition.js
9904
- var import_core19 = require("@math.gl/core");
10162
+ var import_core20 = require("@math.gl/core");
9905
10163
  var CPUInterpolationTransition = class extends Transition {
9906
10164
  get value() {
9907
10165
  return this._value;
@@ -9909,7 +10167,7 @@ var CPUInterpolationTransition = class extends Transition {
9909
10167
  _onUpdate() {
9910
10168
  const { time, settings: { fromValue, toValue, duration, easing } } = this;
9911
10169
  const t = easing(time / duration);
9912
- this._value = (0, import_core19.lerp)(fromValue, toValue, t);
10170
+ this._value = (0, import_core20.lerp)(fromValue, toValue, t);
9913
10171
  }
9914
10172
  };
9915
10173
 
@@ -10263,7 +10521,7 @@ function mergeShaders(target, source3) {
10263
10521
  }
10264
10522
 
10265
10523
  // dist/utils/texture.js
10266
- var import_core20 = require("@luma.gl/core");
10524
+ var import_core21 = require("@luma.gl/core");
10267
10525
  var DEFAULT_TEXTURE_PARAMETERS = {
10268
10526
  minFilter: "linear",
10269
10527
  mipmapFilter: "linear",
@@ -10273,7 +10531,7 @@ var DEFAULT_TEXTURE_PARAMETERS = {
10273
10531
  };
10274
10532
  var internalTextures = {};
10275
10533
  function createTexture(owner, device, image, sampler) {
10276
- if (image instanceof import_core20.Texture) {
10534
+ if (image instanceof import_core21.Texture) {
10277
10535
  return image;
10278
10536
  } else if (image.constructor && image.constructor.name !== "Object") {
10279
10537
  image = { data: image };
@@ -10297,12 +10555,14 @@ function createTexture(owner, device, image, sampler) {
10297
10555
  });
10298
10556
  if (device.type === "webgl") {
10299
10557
  texture.generateMipmapsWebGL();
10558
+ } else if (device.type === "webgpu") {
10559
+ device.generateMipmapsWebGPU(texture);
10300
10560
  }
10301
10561
  internalTextures[texture.id] = owner;
10302
10562
  return texture;
10303
10563
  }
10304
10564
  function destroyTexture(owner, texture) {
10305
- if (!texture || !(texture instanceof import_core20.Texture)) {
10565
+ if (!texture || !(texture instanceof import_core21.Texture)) {
10306
10566
  return;
10307
10567
  }
10308
10568
  if (internalTextures[texture.id] === owner) {
@@ -10908,7 +11168,7 @@ var LayerState = class extends ComponentState {
10908
11168
 
10909
11169
  // dist/lib/layer.js
10910
11170
  var import_web_mercator8 = require("@math.gl/web-mercator");
10911
- var import_core22 = require("@loaders.gl/core");
11171
+ var import_core23 = require("@loaders.gl/core");
10912
11172
  var TRACE_CHANGE_FLAG = "layer.changeFlag";
10913
11173
  var TRACE_INITIALIZE = "layer.initialize";
10914
11174
  var TRACE_UPDATE = "layer.update";
@@ -10954,7 +11214,7 @@ var defaultProps2 = {
10954
11214
  }
10955
11215
  let inResourceManager = resourceManager.contains(url);
10956
11216
  if (!inResourceManager && !loadOptions) {
10957
- resourceManager.add({ resourceId: url, data: (0, import_core22.load)(url, loaders), persistent: false });
11217
+ resourceManager.add({ resourceId: url, data: (0, import_core23.load)(url, loaders), persistent: false });
10958
11218
  inResourceManager = true;
10959
11219
  }
10960
11220
  if (inResourceManager) {
@@ -10968,7 +11228,7 @@ var defaultProps2 = {
10968
11228
  requestId: propName
10969
11229
  });
10970
11230
  }
10971
- return (0, import_core22.load)(url, loaders, loadOptions);
11231
+ return (0, import_core23.load)(url, loaders, loadOptions);
10972
11232
  }
10973
11233
  },
10974
11234
  updateTriggers: {},
@@ -11439,7 +11699,7 @@ var Layer = class extends component_default {
11439
11699
  const values = changedAttributes[name].getValue();
11440
11700
  for (const attributeName in values) {
11441
11701
  const value = values[attributeName];
11442
- if (value instanceof import_core21.Buffer) {
11702
+ if (value instanceof import_core22.Buffer) {
11443
11703
  if (changedAttributes[name].settings.isIndexed) {
11444
11704
  model.setIndexBuffer(value);
11445
11705
  } else {
@@ -11628,13 +11888,8 @@ var Layer = class extends component_default {
11628
11888
  if (context.device instanceof import_webgl2.WebGLDevice) {
11629
11889
  context.device.setParametersWebGL({ polygonOffset: offsets });
11630
11890
  }
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
- }
11891
+ const webGPUDrawParameters = context.device instanceof import_webgl2.WebGLDevice ? null : splitWebGPUDrawParameters(parameters);
11892
+ applyModelParameters(this.getModels(), renderPass, parameters, webGPUDrawParameters);
11638
11893
  if (context.device instanceof import_webgl2.WebGLDevice) {
11639
11894
  context.device.withParametersWebGL(parameters, () => {
11640
11895
  const opts = { renderPass, shaderModuleProps, uniforms, parameters, context };
@@ -11644,6 +11899,9 @@ var Layer = class extends component_default {
11644
11899
  this.draw(opts);
11645
11900
  });
11646
11901
  } else {
11902
+ if (webGPUDrawParameters == null ? void 0 : webGPUDrawParameters.renderPassParameters) {
11903
+ renderPass.setParameters(webGPUDrawParameters.renderPassParameters);
11904
+ }
11647
11905
  const opts = { renderPass, shaderModuleProps, uniforms, parameters, context };
11648
11906
  for (const extension of this.props.extensions) {
11649
11907
  extension.draw.call(this, opts, extension);
@@ -11819,6 +12077,58 @@ var Layer = class extends component_default {
11819
12077
  Layer.defaultProps = defaultProps2;
11820
12078
  Layer.layerName = "Layer";
11821
12079
  var layer_default = Layer;
12080
+ function splitWebGPUDrawParameters(parameters) {
12081
+ const { blendConstant, ...pipelineParameters } = parameters;
12082
+ return blendConstant ? {
12083
+ pipelineParameters,
12084
+ renderPassParameters: { blendConstant }
12085
+ } : { pipelineParameters };
12086
+ }
12087
+ function applyModelParameters(models, renderPass, parameters, webGPUDrawParameters) {
12088
+ for (const model of models) {
12089
+ if (model.device.type === "webgpu") {
12090
+ syncModelAttachmentFormats(model, renderPass);
12091
+ model.setParameters({
12092
+ ...model.parameters,
12093
+ ...webGPUDrawParameters == null ? void 0 : webGPUDrawParameters.pipelineParameters
12094
+ });
12095
+ } else {
12096
+ model.setParameters(parameters);
12097
+ }
12098
+ }
12099
+ }
12100
+ function syncModelAttachmentFormats(model, renderPass) {
12101
+ var _a, _b;
12102
+ const framebuffer = renderPass.props.framebuffer || (renderPass.framebuffer ?? null);
12103
+ if (!framebuffer) {
12104
+ return;
12105
+ }
12106
+ const colorAttachmentFormats = framebuffer.colorAttachments.map((attachment) => {
12107
+ var _a2;
12108
+ return ((_a2 = attachment == null ? void 0 : attachment.texture) == null ? void 0 : _a2.format) ?? null;
12109
+ });
12110
+ const depthStencilAttachmentFormat = (_b = (_a = framebuffer.depthStencilAttachment) == null ? void 0 : _a.texture) == null ? void 0 : _b.format;
12111
+ const modelWithProps = model;
12112
+ if (!equalAttachmentFormats(modelWithProps.props.colorAttachmentFormats, colorAttachmentFormats) || modelWithProps.props.depthStencilAttachmentFormat !== depthStencilAttachmentFormat) {
12113
+ modelWithProps.props.colorAttachmentFormats = colorAttachmentFormats;
12114
+ modelWithProps.props.depthStencilAttachmentFormat = depthStencilAttachmentFormat;
12115
+ modelWithProps._setPipelineNeedsUpdate("attachment formats");
12116
+ }
12117
+ }
12118
+ function equalAttachmentFormats(left, right) {
12119
+ if (left === right) {
12120
+ return true;
12121
+ }
12122
+ if (!left || !right || left.length !== right.length) {
12123
+ return false;
12124
+ }
12125
+ for (let i = 0; i < left.length; i++) {
12126
+ if (left[i] !== right[i]) {
12127
+ return false;
12128
+ }
12129
+ }
12130
+ return true;
12131
+ }
11822
12132
 
11823
12133
  // dist/lib/composite-layer.js
11824
12134
  var TRACE_RENDER_LAYERS2 = "compositeLayer.renderLayers";
@@ -11997,13 +12307,13 @@ CompositeLayer.layerName = "CompositeLayer";
11997
12307
  var composite_layer_default = CompositeLayer;
11998
12308
 
11999
12309
  // dist/viewports/orbit-viewport.js
12000
- var import_core23 = require("@math.gl/core");
12310
+ var import_core24 = require("@math.gl/core");
12001
12311
  var import_web_mercator9 = require("@math.gl/web-mercator");
12002
12312
  var DEGREES_TO_RADIANS3 = Math.PI / 180;
12003
12313
  function getViewMatrix2({ height, focalDistance, orbitAxis, rotationX, rotationOrbit, zoom }) {
12004
12314
  const up = orbitAxis === "Z" ? [0, 0, 1] : [0, 1, 0];
12005
12315
  const eye = orbitAxis === "Z" ? [0, -focalDistance, 0] : [0, 0, focalDistance];
12006
- const viewMatrix2 = new import_core23.Matrix4().lookAt({ eye, up });
12316
+ const viewMatrix2 = new import_core24.Matrix4().lookAt({ eye, up });
12007
12317
  viewMatrix2.rotateX(rotationX * DEGREES_TO_RADIANS3);
12008
12318
  if (orbitAxis === "Z") {
12009
12319
  viewMatrix2.rotateZ(rotationOrbit * DEGREES_TO_RADIANS3);
@@ -12083,9 +12393,9 @@ OrbitViewport.displayName = "OrbitViewport";
12083
12393
  var orbit_viewport_default = OrbitViewport;
12084
12394
 
12085
12395
  // dist/viewports/orthographic-viewport.js
12086
- var import_core24 = require("@math.gl/core");
12396
+ var import_core25 = require("@math.gl/core");
12087
12397
  var import_web_mercator10 = require("@math.gl/web-mercator");
12088
- var viewMatrix = new import_core24.Matrix4().lookAt({ eye: [0, 0, 1] });
12398
+ var viewMatrix = new import_core25.Matrix4().lookAt({ eye: [0, 0, 1] });
12089
12399
  function getProjectionMatrix({ width, height, near, far, padding }) {
12090
12400
  let left = -width / 2;
12091
12401
  let right = width / 2;
@@ -12093,14 +12403,14 @@ function getProjectionMatrix({ width, height, near, far, padding }) {
12093
12403
  let top = height / 2;
12094
12404
  if (padding) {
12095
12405
  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;
12406
+ const offsetX = (0, import_core25.clamp)((l + width - r) / 2, 0, width) - width / 2;
12407
+ const offsetY = (0, import_core25.clamp)((t + height - b) / 2, 0, height) - height / 2;
12098
12408
  left -= offsetX;
12099
12409
  right -= offsetX;
12100
12410
  bottom += offsetY;
12101
12411
  top += offsetY;
12102
12412
  }
12103
- return new import_core24.Matrix4().ortho({
12413
+ return new import_core25.Matrix4().ortho({
12104
12414
  left,
12105
12415
  right,
12106
12416
  bottom,
@@ -12159,8 +12469,8 @@ var OrthographicViewport = class extends viewport_default {
12159
12469
  panByPosition(coords, pixel, startPixel) {
12160
12470
  const fromLocation = (0, import_web_mercator10.pixelsToWorld)(pixel, this.pixelUnprojectionMatrix);
12161
12471
  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);
12472
+ const translate = import_core25.vec2.add([], toLocation, import_core25.vec2.negate([], fromLocation));
12473
+ const newCenter = import_core25.vec2.add([], this.center, translate);
12164
12474
  return { target: this.unprojectFlat(newCenter) };
12165
12475
  }
12166
12476
  };
@@ -12169,20 +12479,20 @@ var orthographic_viewport_default = OrthographicViewport;
12169
12479
 
12170
12480
  // dist/viewports/first-person-viewport.js
12171
12481
  var import_web_mercator11 = require("@math.gl/web-mercator");
12172
- var import_core25 = require("@math.gl/core");
12482
+ var import_core26 = require("@math.gl/core");
12173
12483
  var FirstPersonViewport = class extends viewport_default {
12174
12484
  constructor(props) {
12175
12485
  const { longitude, latitude, modelMatrix, bearing = 0, pitch = 0, up = [0, 0, 1] } = props;
12176
- const spherical = new import_core25._SphericalCoordinates({
12486
+ const spherical = new import_core26._SphericalCoordinates({
12177
12487
  bearing,
12178
12488
  // Avoid "pixel project matrix not invertible" error
12179
12489
  pitch: pitch === -90 ? 1e-4 : 90 + pitch
12180
12490
  });
12181
12491
  const dir = spherical.toVector3().normalize();
12182
- const center = modelMatrix ? new import_core25.Matrix4(modelMatrix).transformAsVector(dir) : dir;
12492
+ const center = modelMatrix ? new import_core26.Matrix4(modelMatrix).transformAsVector(dir) : dir;
12183
12493
  const zoom = Number.isFinite(latitude) ? (0, import_web_mercator11.getMeterZoom)({ latitude }) : 0;
12184
12494
  const scale = Math.pow(2, zoom);
12185
- const viewMatrix2 = new import_core25.Matrix4().lookAt({ eye: [0, 0, 0], center, up }).scale(scale);
12495
+ const viewMatrix2 = new import_core26.Matrix4().lookAt({ eye: [0, 0, 0], center, up }).scale(scale);
12186
12496
  super({
12187
12497
  ...props,
12188
12498
  zoom,
@@ -12199,7 +12509,7 @@ FirstPersonViewport.displayName = "FirstPersonViewport";
12199
12509
  var first_person_viewport_default = FirstPersonViewport;
12200
12510
 
12201
12511
  // dist/controllers/first-person-controller.js
12202
- var import_core26 = require("@math.gl/core");
12512
+ var import_core27 = require("@math.gl/core");
12203
12513
  var MOVEMENT_SPEED = 20;
12204
12514
  var PAN_SPEED = 500;
12205
12515
  var FirstPersonState = class extends ViewState {
@@ -12275,12 +12585,12 @@ var FirstPersonState = class extends ViewState {
12275
12585
  const { width, height, bearing, pitch } = this.getViewportProps();
12276
12586
  const deltaScaleX = PAN_SPEED * (pos[0] - startPanPos[0]) / width;
12277
12587
  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 });
12588
+ const up = new import_core27._SphericalCoordinates({ bearing, pitch });
12589
+ const forward = new import_core27._SphericalCoordinates({ bearing, pitch: -90 });
12280
12590
  const yDirection = up.toVector3().normalize();
12281
12591
  const xDirection = forward.toVector3().cross(yDirection).normalize();
12282
12592
  return this._getUpdatedState({
12283
- position: new import_core26.Vector3(startPanPosition).add(xDirection.scale(deltaScaleX)).add(yDirection.scale(deltaScaleY))
12593
+ position: new import_core27.Vector3(startPanPosition).add(xDirection.scale(deltaScaleX)).add(yDirection.scale(deltaScaleY))
12284
12594
  });
12285
12595
  }
12286
12596
  /**
@@ -12416,10 +12726,10 @@ var FirstPersonState = class extends ViewState {
12416
12726
  });
12417
12727
  }
12418
12728
  zoomIn(speed = MOVEMENT_SPEED) {
12419
- return this._move(new import_core26.Vector3(0, 0, 1), speed);
12729
+ return this._move(new import_core27.Vector3(0, 0, 1), speed);
12420
12730
  }
12421
12731
  zoomOut(speed = MOVEMENT_SPEED) {
12422
- return this._move(new import_core26.Vector3(0, 0, -1), speed);
12732
+ return this._move(new import_core27.Vector3(0, 0, -1), speed);
12423
12733
  }
12424
12734
  // shortest path between two view states
12425
12735
  shortestPathFrom(viewState) {
@@ -12438,11 +12748,11 @@ var FirstPersonState = class extends ViewState {
12438
12748
  _move(direction, speed, fromPosition = this.getViewportProps().position) {
12439
12749
  const delta = direction.scale(speed);
12440
12750
  return this._getUpdatedState({
12441
- position: new import_core26.Vector3(fromPosition).add(delta)
12751
+ position: new import_core27.Vector3(fromPosition).add(delta)
12442
12752
  });
12443
12753
  }
12444
12754
  getDirection(use2D = false) {
12445
- const spherical = new import_core26._SphericalCoordinates({
12755
+ const spherical = new import_core27._SphericalCoordinates({
12446
12756
  bearing: this.getViewportProps().bearing,
12447
12757
  pitch: use2D ? 90 : 90 + this.getViewportProps().pitch
12448
12758
  });
@@ -12460,7 +12770,7 @@ var FirstPersonState = class extends ViewState {
12460
12770
  // Apply any constraints (mathematical or defined by _viewportProps) to map state
12461
12771
  applyConstraints(props) {
12462
12772
  const { pitch, maxPitch, minPitch, longitude, position, bearing, maxBounds } = props;
12463
- props.pitch = (0, import_core26.clamp)(pitch, minPitch, maxPitch);
12773
+ props.pitch = (0, import_core27.clamp)(pitch, minPitch, maxPitch);
12464
12774
  if (longitude !== null && (longitude < -180 || longitude > 180)) {
12465
12775
  props.longitude = mod(longitude + 180, 360) - 180;
12466
12776
  }
@@ -12468,9 +12778,9 @@ var FirstPersonState = class extends ViewState {
12468
12778
  props.bearing = mod(bearing + 180, 360) - 180;
12469
12779
  }
12470
12780
  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);
12781
+ const x = (0, import_core27.clamp)(position[0], maxBounds[0][0], maxBounds[1][0]);
12782
+ const y = (0, import_core27.clamp)(position[1], maxBounds[0][1], maxBounds[1][1]);
12783
+ const z = (0, import_core27.clamp)(position[2] ?? 0, maxBounds[0][2] ?? 0, maxBounds[1][2] ?? 0);
12474
12784
  if (x !== position[0] || y !== position[1] || z !== position[2]) {
12475
12785
  props.position = [x, y, z];
12476
12786
  }
@@ -12505,7 +12815,7 @@ FirstPersonView.displayName = "FirstPersonView";
12505
12815
  var first_person_view_default = FirstPersonView;
12506
12816
 
12507
12817
  // dist/controllers/orbit-controller.js
12508
- var import_core27 = require("@math.gl/core");
12818
+ var import_core28 = require("@math.gl/core");
12509
12819
  var OrbitState = class extends ViewState {
12510
12820
  constructor(options) {
12511
12821
  const {
@@ -12777,7 +13087,7 @@ var OrbitState = class extends ViewState {
12777
13087
  applyConstraints(props) {
12778
13088
  const { maxRotationX, minRotationX, rotationOrbit } = props;
12779
13089
  props.zoom = this._constrainZoom(props.zoom, props);
12780
- props.rotationX = (0, import_core27.clamp)(props.rotationX, minRotationX, maxRotationX);
13090
+ props.rotationX = (0, import_core28.clamp)(props.rotationX, minRotationX, maxRotationX);
12781
13091
  if (rotationOrbit < -180 || rotationOrbit > 180) {
12782
13092
  props.rotationOrbit = mod(rotationOrbit + 180, 360) - 180;
12783
13093
  }
@@ -12799,7 +13109,7 @@ var OrbitState = class extends ViewState {
12799
13109
  minZoom = maxZoom;
12800
13110
  }
12801
13111
  }
12802
- return (0, import_core27.clamp)(zoom, minZoom, maxZoom);
13112
+ return (0, import_core28.clamp)(zoom, minZoom, maxZoom);
12803
13113
  }
12804
13114
  _constrainTarget(props) {
12805
13115
  var _a;
@@ -12820,9 +13130,9 @@ var OrbitState = class extends ViewState {
12820
13130
  const minDot = nx * (nx >= 0 ? minX : maxX) + ny * (ny >= 0 ? minY : maxY) + nz * (nz >= 0 ? minZ : maxZ);
12821
13131
  const maxDot = nx * (nx >= 0 ? maxX : minX) + ny * (ny >= 0 ? maxY : minY) + nz * (nz >= 0 ? maxZ : minZ);
12822
13132
  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);
13133
+ const clampX = (value) => (0, import_core28.clamp)(value, minX, maxX);
13134
+ const clampY = (value) => (0, import_core28.clamp)(value, minY, maxY);
13135
+ const clampZ = (value) => (0, import_core28.clamp)(value, minZ, maxZ);
12826
13136
  const f = (lambda2) => nx * clampX(target[0] - lambda2 * nx) + ny * clampY(target[1] - lambda2 * ny) + nz * clampZ(target[2] - lambda2 * nz) - c;
12827
13137
  let lo = -1;
12828
13138
  let hi = 1;
@@ -12858,9 +13168,9 @@ var OrbitState = class extends ViewState {
12858
13168
  }
12859
13169
  }
12860
13170
  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)
13171
+ (0, import_core28.clamp)(target[0], minX, maxX),
13172
+ (0, import_core28.clamp)(target[1], minY, maxY),
13173
+ (0, import_core28.clamp)(target[2], minZ, maxZ)
12864
13174
  ];
12865
13175
  }
12866
13176
  };
@@ -12911,7 +13221,7 @@ OrbitView.displayName = "OrbitView";
12911
13221
  var orbit_view_default = OrbitView;
12912
13222
 
12913
13223
  // dist/controllers/orthographic-controller.js
12914
- var import_core28 = require("@math.gl/core");
13224
+ var import_core29 = require("@math.gl/core");
12915
13225
  function normalizeZoom({ zoom = 0, zoomX, zoomY }) {
12916
13226
  zoomX = zoomX ?? (Array.isArray(zoom) ? zoom[0] : zoom);
12917
13227
  zoomY = zoomY ?? (Array.isArray(zoom) ? zoom[1] : zoom);
@@ -13157,8 +13467,8 @@ var OrthographicState = class extends ViewState {
13157
13467
  const maxX = maxBounds[1][0] - halfWidth;
13158
13468
  const minY = maxBounds[0][1] + halfHeight;
13159
13469
  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);
13470
+ const x = (0, import_core29.clamp)(target[0], minX, maxX);
13471
+ const y = (0, import_core29.clamp)(target[1], minY, maxY);
13162
13472
  if (x !== target[0] || y !== target[1]) {
13163
13473
  props.target = target.slice();
13164
13474
  props.target[0] = x;
@@ -13190,10 +13500,10 @@ var OrthographicState = class extends ViewState {
13190
13500
  }
13191
13501
  switch (zoomAxis) {
13192
13502
  case "X":
13193
- zoomX = (0, import_core28.clamp)(zoomX, minZoomX, maxZoomX);
13503
+ zoomX = (0, import_core29.clamp)(zoomX, minZoomX, maxZoomX);
13194
13504
  break;
13195
13505
  case "Y":
13196
- zoomY = (0, import_core28.clamp)(zoomY, minZoomY, maxZoomY);
13506
+ zoomY = (0, import_core29.clamp)(zoomY, minZoomY, maxZoomY);
13197
13507
  break;
13198
13508
  default:
13199
13509
  let delta = Math.min(maxZoomX - zoomX, maxZoomY - zoomY, 0);
@@ -13243,7 +13553,7 @@ OrthographicView.displayName = "OrthographicView";
13243
13553
  var orthographic_view_default = OrthographicView;
13244
13554
 
13245
13555
  // dist/controllers/globe-controller.js
13246
- var import_core29 = require("@math.gl/core");
13556
+ var import_core30 = require("@math.gl/core");
13247
13557
  var import_web_mercator12 = require("@math.gl/web-mercator");
13248
13558
  var DEGREES_TO_RADIANS4 = Math.PI / 180;
13249
13559
  var RADIANS_TO_DEGREES2 = 180 / Math.PI;
@@ -13304,10 +13614,10 @@ var GlobeState = class extends MapState {
13304
13614
  if (longitude < -180 || longitude > 180) {
13305
13615
  props.longitude = mod(longitude + 180, 360) - 180;
13306
13616
  }
13307
- props.latitude = (0, import_core29.clamp)(latitude, -import_web_mercator12.MAX_LATITUDE, import_web_mercator12.MAX_LATITUDE);
13617
+ props.latitude = (0, import_core30.clamp)(latitude, -import_web_mercator12.MAX_LATITUDE, import_web_mercator12.MAX_LATITUDE);
13308
13618
  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]);
13619
+ props.longitude = (0, import_core30.clamp)(props.longitude, maxBounds[0][0], maxBounds[1][0]);
13620
+ props.latitude = (0, import_core30.clamp)(props.latitude, maxBounds[0][1], maxBounds[1][1]);
13311
13621
  }
13312
13622
  if (maxBounds) {
13313
13623
  const effectiveZoom = props.zoom - zoomAdjust(latitude);
@@ -13315,11 +13625,11 @@ var GlobeState = class extends MapState {
13315
13625
  const latSpan = maxBounds[1][1] - maxBounds[0][1];
13316
13626
  if (latSpan > 0 && latSpan < import_web_mercator12.MAX_LATITUDE * 2) {
13317
13627
  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);
13628
+ props.latitude = (0, import_core30.clamp)(props.latitude, maxBounds[0][1] + halfHeightDegrees, maxBounds[1][1] - halfHeightDegrees);
13319
13629
  }
13320
13630
  if (lngSpan > 0 && lngSpan < 360) {
13321
13631
  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);
13632
+ props.longitude = (0, import_core30.clamp)(props.longitude, maxBounds[0][0] + halfWidthDegrees, maxBounds[1][0] - halfWidthDegrees);
13323
13633
  }
13324
13634
  }
13325
13635
  if (props.latitude !== latitude) {
@@ -13349,7 +13659,7 @@ var GlobeState = class extends MapState {
13349
13659
  if (minZoom > maxZoom)
13350
13660
  minZoom = maxZoom;
13351
13661
  }
13352
- return (0, import_core29.clamp)(zoom, minZoom + zoomAdjustment, maxZoom + zoomAdjustment);
13662
+ return (0, import_core30.clamp)(zoom, minZoom + zoomAdjustment, maxZoom + zoomAdjustment);
13353
13663
  }
13354
13664
  };
13355
13665
  var GlobeController = class extends Controller {
@@ -13390,27 +13700,55 @@ var TerrainController = class extends MapController {
13390
13700
  super(...arguments);
13391
13701
  this._terrainAltitude = void 0;
13392
13702
  this._terrainAltitudeTarget = void 0;
13703
+ this._pickFrameId = null;
13704
+ this._lastPickTime = 0;
13393
13705
  }
13394
13706
  setProps(props) {
13395
13707
  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
- }));
13708
+ if (this._pickFrameId === null) {
13709
+ const loop = () => {
13710
+ const now = Date.now();
13711
+ if (now - this._lastPickTime > 500 && !this.isDragging()) {
13712
+ this._lastPickTime = now;
13713
+ this._pickTerrainCenterAltitude();
13714
+ if (this._terrainAltitude === void 0 && this._terrainAltitudeTarget !== void 0) {
13715
+ this._terrainAltitude = this._terrainAltitudeTarget;
13716
+ const controllerState = new this.ControllerState({
13717
+ makeViewport: this.makeViewport,
13718
+ ...this.props,
13719
+ ...this.state
13720
+ });
13721
+ const rebaseProps = this._rebaseViewport(this._terrainAltitudeTarget, controllerState);
13722
+ if (rebaseProps) {
13723
+ const rebasedState = new this.ControllerState({
13724
+ makeViewport: this.makeViewport,
13725
+ ...this.props,
13726
+ ...this.state,
13727
+ ...rebaseProps
13728
+ });
13729
+ super.updateViewport(rebasedState);
13730
+ }
13731
+ }
13732
+ }
13733
+ this._pickFrameId = requestAnimationFrame(loop);
13734
+ };
13735
+ this._pickFrameId = requestAnimationFrame(loop);
13736
+ }
13737
+ }
13738
+ finalize() {
13739
+ if (this._pickFrameId !== null) {
13740
+ cancelAnimationFrame(this._pickFrameId);
13741
+ this._pickFrameId = null;
13402
13742
  }
13743
+ super.finalize();
13403
13744
  }
13404
13745
  updateViewport(newControllerState, extraProps = null, interactionState = {}) {
13405
- const SMOOTHING = 0.05;
13406
- if (this._terrainAltitudeTarget === void 0)
13407
- return;
13408
13746
  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;
13747
+ super.updateViewport(newControllerState, extraProps, interactionState);
13748
+ return;
13413
13749
  }
13750
+ const SMOOTHING = 0.05;
13751
+ this._terrainAltitude += (this._terrainAltitudeTarget - this._terrainAltitude) * SMOOTHING;
13414
13752
  const viewportProps = newControllerState.getViewportProps();
13415
13753
  const pos = viewportProps.position || [0, 0, 0];
13416
13754
  extraProps = {
@@ -13419,18 +13757,6 @@ var TerrainController = class extends MapController {
13419
13757
  };
13420
13758
  super.updateViewport(newControllerState, extraProps, interactionState);
13421
13759
  }
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
13760
  _pickTerrainCenterAltitude() {
13435
13761
  if (!this.pickPosition) {
13436
13762
  return;
@@ -13442,10 +13768,10 @@ var TerrainController = class extends MapController {
13442
13768
  }
13443
13769
  }
13444
13770
  /**
13445
- * Utility function to return viewport that looks the same, but with
13446
- * a position shifted to [0, 0, altitude]
13771
+ * Compute viewport adjustments to keep the view visually the same
13772
+ * when shifting position to [0, 0, altitude].
13447
13773
  */
13448
- _rebaseViewport(altitude, newControllerState, extraProps) {
13774
+ _rebaseViewport(altitude, newControllerState) {
13449
13775
  const viewportProps = newControllerState.getViewportProps();
13450
13776
  const oldViewport = this.makeViewport({ ...viewportProps, position: [0, 0, 0] });
13451
13777
  const oldCameraPos = oldViewport.cameraPosition;
@@ -13453,7 +13779,7 @@ var TerrainController = class extends MapController {
13453
13779
  const cameraHeightAboveOldCenter = oldCameraPos[2];
13454
13780
  const newCameraHeightAboveCenter = cameraHeightAboveOldCenter - centerZOffset;
13455
13781
  if (newCameraHeightAboveCenter <= 0) {
13456
- return extraProps;
13782
+ return null;
13457
13783
  }
13458
13784
  const zoomDelta = Math.log2(cameraHeightAboveOldCenter / newCameraHeightAboveCenter);
13459
13785
  const newZoom = viewportProps.zoom + zoomDelta;
@@ -13467,9 +13793,9 @@ var TerrainController = class extends MapController {
13467
13793
  const worldPoint = oldViewport.unproject(screenCenter, { targetZ: altitude });
13468
13794
  if (worldPoint && "panByPosition3D" in newViewport && typeof newViewport.panByPosition3D === "function") {
13469
13795
  const adjusted = newViewport.panByPosition3D(worldPoint, screenCenter);
13470
- return { ...extraProps, position: [0, 0, altitude], zoom: newZoom, ...adjusted };
13796
+ return { position: [0, 0, altitude], zoom: newZoom, ...adjusted };
13471
13797
  }
13472
- return extraProps;
13798
+ return null;
13473
13799
  }
13474
13800
  };
13475
13801
 
@@ -13535,7 +13861,7 @@ LayerExtension.extensionName = "LayerExtension";
13535
13861
  var layer_extension_default = LayerExtension;
13536
13862
 
13537
13863
  // dist/transitions/fly-to-interpolator.js
13538
- var import_core30 = require("@math.gl/core");
13864
+ var import_core31 = require("@math.gl/core");
13539
13865
  var import_web_mercator13 = require("@math.gl/web-mercator");
13540
13866
  var LINEARLY_INTERPOLATED_PROPS = {
13541
13867
  bearing: 0,
@@ -13558,7 +13884,7 @@ var FlyToInterpolator = class extends TransitionInterpolator {
13558
13884
  interpolateProps(startProps, endProps, t) {
13559
13885
  const viewport = (0, import_web_mercator13.flyToViewport)(startProps, endProps, t, this.opts);
13560
13886
  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);
13887
+ viewport[key] = (0, import_core31.lerp)(startProps[key] || LINEARLY_INTERPOLATED_PROPS[key], endProps[key] || LINEARLY_INTERPOLATED_PROPS[key], t);
13562
13888
  }
13563
13889
  return viewport;
13564
13890
  }
@@ -13573,7 +13899,7 @@ var FlyToInterpolator = class extends TransitionInterpolator {
13573
13899
  };
13574
13900
 
13575
13901
  // dist/utils/tesselator.js
13576
- var import_core31 = require("@luma.gl/core");
13902
+ var import_core32 = require("@luma.gl/core");
13577
13903
  var Tesselator = class {
13578
13904
  constructor(opts) {
13579
13905
  this.indexStarts = [0];
@@ -13680,7 +14006,7 @@ var Tesselator = class {
13680
14006
  instanceCount = vertexStarts[data.length] || 0;
13681
14007
  if (ArrayBuffer.isView(geometryBuffer)) {
13682
14008
  instanceCount = instanceCount || geometryBuffer.length / this.positionSize;
13683
- } else if (geometryBuffer instanceof import_core31.Buffer) {
14009
+ } else if (geometryBuffer instanceof import_core32.Buffer) {
13684
14010
  const byteStride = this.positionSize * 4;
13685
14011
  instanceCount = instanceCount || geometryBuffer.byteLength / byteStride;
13686
14012
  } else if (geometryBuffer.buffer) {