@deck.gl/extensions 9.4.0-beta.1 → 9.4.0-beta.4

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 (37) hide show
  1. package/dist/dist.dev.js +1281 -120
  2. package/dist/fill-style/fill-style-extension.d.ts +38 -6
  3. package/dist/fill-style/fill-style-extension.d.ts.map +1 -1
  4. package/dist/fill-style/fill-style-extension.js +88 -10
  5. package/dist/fill-style/fill-style-extension.js.map +1 -1
  6. package/dist/fill-style/procedural-pattern.d.ts +65 -0
  7. package/dist/fill-style/procedural-pattern.d.ts.map +1 -0
  8. package/dist/fill-style/procedural-pattern.js +135 -0
  9. package/dist/fill-style/procedural-pattern.js.map +1 -0
  10. package/dist/fill-style/shader-module.d.ts +13 -4
  11. package/dist/fill-style/shader-module.d.ts.map +1 -1
  12. package/dist/fill-style/shader-module.js +212 -21
  13. package/dist/fill-style/shader-module.js.map +1 -1
  14. package/dist/index.cjs +886 -2702
  15. package/dist/index.cjs.map +3 -3
  16. package/dist/index.d.ts +2 -1
  17. package/dist/index.d.ts.map +1 -1
  18. package/dist/mask/shader-module.d.ts +1 -0
  19. package/dist/mask/shader-module.d.ts.map +1 -1
  20. package/dist/path-style/path-style-extension.d.ts +49 -6
  21. package/dist/path-style/path-style-extension.d.ts.map +1 -1
  22. package/dist/path-style/path-style-extension.js +237 -37
  23. package/dist/path-style/path-style-extension.js.map +1 -1
  24. package/dist/path-style/shaders.glsl.d.ts +30 -1
  25. package/dist/path-style/shaders.glsl.d.ts.map +1 -1
  26. package/dist/path-style/shaders.glsl.js +136 -21
  27. package/dist/path-style/shaders.glsl.js.map +1 -1
  28. package/dist/terrain/shader-module.d.ts +1 -0
  29. package/dist/terrain/shader-module.d.ts.map +1 -1
  30. package/dist.min.js +377 -98
  31. package/package.json +7 -7
  32. package/src/fill-style/fill-style-extension.ts +135 -13
  33. package/src/fill-style/procedural-pattern.ts +203 -0
  34. package/src/fill-style/shader-module.ts +233 -23
  35. package/src/index.ts +10 -1
  36. package/src/path-style/path-style-extension.ts +350 -44
  37. package/src/path-style/shaders.glsl.ts +268 -27
package/dist/index.cjs CHANGED
@@ -1,4 +1,3 @@
1
- "use strict";
2
1
  var __defProp = Object.defineProperty;
3
2
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
3
  var __getOwnPropNames = Object.getOwnPropertyNames;
@@ -33,2539 +32,11 @@ __export(index_exports, {
33
32
  });
34
33
  module.exports = __toCommonJS(index_exports);
35
34
 
36
- // ../core/src/utils/log.ts
37
- var import_log = require("@probe.gl/log");
38
- var defaultLogger = new import_log.Log({ id: "deck" });
39
- var log_default = defaultLogger;
40
-
41
- // ../core/src/shaderlib/index.ts
42
- var import_shadertools2 = require("@luma.gl/shadertools");
43
-
44
- // ../core/src/shaderlib/misc/geometry.ts
45
- var source = (
46
- /* wgsl */
47
- `const SMOOTH_EDGE_RADIUS: f32 = 0.5;
48
-
49
- struct VertexGeometry {
50
- position: vec4<f32>,
51
- worldPosition: vec3<f32>,
52
- worldPositionAlt: vec3<f32>,
53
- normal: vec3<f32>,
54
- uv: vec2<f32>,
55
- pickingColor: vec3<f32>,
56
- };
57
-
58
- var<private> geometry_: VertexGeometry = VertexGeometry(
59
- vec4<f32>(0.0, 0.0, 1.0, 0.0),
60
- vec3<f32>(0.0, 0.0, 0.0),
61
- vec3<f32>(0.0, 0.0, 0.0),
62
- vec3<f32>(0.0, 0.0, 0.0),
63
- vec2<f32>(0.0, 0.0),
64
- vec3<f32>(0.0, 0.0, 0.0)
65
- );
66
-
67
- struct FragmentGeometry {
68
- uv: vec2<f32>,
69
- };
70
-
71
- var<private> fragmentGeometry: FragmentGeometry;
72
-
73
- fn smoothedge(edge: f32, x: f32) -> f32 {
74
- return smoothstep(edge - SMOOTH_EDGE_RADIUS, edge + SMOOTH_EDGE_RADIUS, x);
75
- }
76
- `
77
- );
78
- var defines = "#define SMOOTH_EDGE_RADIUS 0.5";
79
- var vs = (
80
- /* glsl */
81
- `${defines}
82
-
83
- struct VertexGeometry {
84
- vec4 position;
85
- vec3 worldPosition;
86
- vec3 worldPositionAlt;
87
- vec3 normal;
88
- vec2 uv;
89
- vec3 pickingColor;
90
- } geometry = VertexGeometry(
91
- vec4(0.0, 0.0, 1.0, 0.0),
92
- vec3(0.0),
93
- vec3(0.0),
94
- vec3(0.0),
95
- vec2(0.0),
96
- vec3(0.0)
97
- );
98
- `
99
- );
100
- var fs = (
101
- /* glsl */
102
- `${defines}
103
-
104
- struct FragmentGeometry {
105
- vec2 uv;
106
- };
107
- FragmentGeometry geometry;
108
-
109
- float smoothedge(float edge, float x) {
110
- return smoothstep(edge - SMOOTH_EDGE_RADIUS, edge + SMOOTH_EDGE_RADIUS, x);
111
- }
112
- `
113
- );
114
- var geometry_default = {
115
- name: "geometry",
116
- source,
117
- vs,
118
- fs
119
- };
120
-
121
- // ../core/src/shaderlib/project/project.ts
122
- var import_shadertools = require("@luma.gl/shadertools");
123
-
124
- // ../core/src/shaderlib/project/viewport-uniforms.ts
125
- var import_core = require("@math.gl/core");
126
-
127
- // ../core/src/lib/constants.ts
128
- var import_mjolnir = require("mjolnir.js");
129
- var COORDINATE_SYSTEM = {
130
- /**
131
- * `LNGLAT` if rendering into a geospatial viewport, `CARTESIAN` otherwise
132
- */
133
- DEFAULT: "default",
134
- /**
135
- * Positions are interpreted as [longitude, latitude, elevation]
136
- * longitude/latitude are in degrees, elevation is in meters.
137
- * Dimensions are in meters.
138
- */
139
- LNGLAT: "lnglat",
140
- /**
141
- * Positions are interpreted as [x, y, z] in meter offsets from the coordinate origin.
142
- * Dimensions are in meters.
143
- */
144
- METER_OFFSETS: "meter-offsets",
145
- /**
146
- * Positions are interpreted as [deltaLng, deltaLat, elevation] from the coordinate origin.
147
- * deltaLng/deltaLat are in degrees, elevation is in meters.
148
- * Dimensions are in meters.
149
- */
150
- LNGLAT_OFFSETS: "lnglat-offsets",
151
- /**
152
- * Positions and dimensions are in the common units of the viewport.
153
- */
154
- CARTESIAN: "cartesian"
155
- };
156
- Object.defineProperty(COORDINATE_SYSTEM, "IDENTITY", {
157
- get: () => {
158
- log_default.deprecated("COORDINATE_SYSTEM.IDENTITY", "COORDINATE_SYSTEM.CARTESIAN")();
159
- return COORDINATE_SYSTEM.CARTESIAN;
160
- }
161
- });
162
- var PROJECTION_MODE = {
163
- /**
164
- * Render geospatial data in Web Mercator projection
165
- */
166
- WEB_MERCATOR: 1,
167
- /**
168
- * Render geospatial data as a 3D globe
169
- */
170
- GLOBE: 2,
171
- /**
172
- * (Internal use only) Web Mercator projection at high zoom
173
- */
174
- WEB_MERCATOR_AUTO_OFFSET: 4,
175
- /**
176
- * No transformation
177
- */
178
- IDENTITY: 0
179
- };
180
- var UNIT = {
181
- common: 0,
182
- meters: 1,
183
- pixels: 2
184
- };
185
-
186
- // ../core/src/utils/memoize.ts
187
- function isEqual(a, b) {
188
- if (a === b) {
189
- return true;
190
- }
191
- if (Array.isArray(a)) {
192
- const len = a.length;
193
- if (!b || b.length !== len) {
194
- return false;
195
- }
196
- for (let i = 0; i < len; i++) {
197
- if (a[i] !== b[i]) {
198
- return false;
199
- }
200
- }
201
- return true;
202
- }
203
- return false;
204
- }
205
- function memoize(compute) {
206
- let cachedArgs = {};
207
- let cachedResult;
208
- return (args) => {
209
- for (const key in args) {
210
- if (!isEqual(args[key], cachedArgs[key])) {
211
- cachedResult = compute(args);
212
- cachedArgs = args;
213
- break;
214
- }
215
- }
216
- return cachedResult;
217
- };
218
- }
219
-
220
- // ../core/src/shaderlib/project/viewport-uniforms.ts
221
- var ZERO_VECTOR = [0, 0, 0, 0];
222
- var VECTOR_TO_POINT_MATRIX = [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0];
223
- var IDENTITY_MATRIX = [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1];
224
- var DEFAULT_PIXELS_PER_UNIT2 = [0, 0, 0];
225
- var DEFAULT_COORDINATE_ORIGIN = [0, 0, 0];
226
- var COORDINATE_SYSTEM_NUMBERS = {
227
- default: -1,
228
- cartesian: 0,
229
- lnglat: 1,
230
- "meter-offsets": 2,
231
- "lnglat-offsets": 3
232
- };
233
- function getShaderCoordinateSystem(coordinateSystem) {
234
- const shaderCoordinateSystem = COORDINATE_SYSTEM_NUMBERS[coordinateSystem];
235
- if (shaderCoordinateSystem === void 0) {
236
- throw new Error(`Invalid coordinateSystem: ${coordinateSystem}`);
237
- }
238
- return shaderCoordinateSystem;
239
- }
240
- var getMemoizedViewportUniforms = memoize(calculateViewportUniforms);
241
- function getOffsetOrigin(viewport, coordinateSystem, coordinateOrigin = DEFAULT_COORDINATE_ORIGIN) {
242
- if (coordinateOrigin.length < 3) {
243
- coordinateOrigin = [coordinateOrigin[0], coordinateOrigin[1], 0];
244
- }
245
- let shaderCoordinateOrigin = coordinateOrigin;
246
- let geospatialOrigin;
247
- let offsetMode = true;
248
- if (coordinateSystem === "lnglat-offsets" || coordinateSystem === "meter-offsets") {
249
- geospatialOrigin = coordinateOrigin;
250
- } else {
251
- geospatialOrigin = viewport.isGeospatial ? (
252
- // @ts-expect-error longitude and latitude are not defined on the base Viewport, but is expected on geospatial viewports
253
- [Math.fround(viewport.longitude), Math.fround(viewport.latitude), 0]
254
- ) : null;
255
- }
256
- switch (viewport.projectionMode) {
257
- case PROJECTION_MODE.WEB_MERCATOR:
258
- if (coordinateSystem === "lnglat" || coordinateSystem === "cartesian") {
259
- geospatialOrigin = [0, 0, 0];
260
- offsetMode = false;
261
- }
262
- break;
263
- case PROJECTION_MODE.WEB_MERCATOR_AUTO_OFFSET:
264
- if (coordinateSystem === "lnglat") {
265
- shaderCoordinateOrigin = geospatialOrigin;
266
- } else if (coordinateSystem === "cartesian") {
267
- shaderCoordinateOrigin = [
268
- Math.fround(viewport.center[0]),
269
- Math.fround(viewport.center[1]),
270
- 0
271
- ];
272
- geospatialOrigin = viewport.unprojectPosition(shaderCoordinateOrigin);
273
- shaderCoordinateOrigin[0] -= coordinateOrigin[0];
274
- shaderCoordinateOrigin[1] -= coordinateOrigin[1];
275
- shaderCoordinateOrigin[2] -= coordinateOrigin[2];
276
- }
277
- break;
278
- case PROJECTION_MODE.IDENTITY:
279
- shaderCoordinateOrigin = viewport.position.map(Math.fround);
280
- shaderCoordinateOrigin[2] = shaderCoordinateOrigin[2] || 0;
281
- break;
282
- case PROJECTION_MODE.GLOBE:
283
- offsetMode = false;
284
- geospatialOrigin = null;
285
- break;
286
- default:
287
- offsetMode = false;
288
- }
289
- return { geospatialOrigin, shaderCoordinateOrigin, offsetMode };
290
- }
291
- function calculateMatrixAndOffset(viewport, coordinateSystem, coordinateOrigin) {
292
- const { viewMatrixUncentered, projectionMatrix } = viewport;
293
- let { viewMatrix: viewMatrix2, viewProjectionMatrix } = viewport;
294
- let projectionCenter = ZERO_VECTOR;
295
- let originCommon = ZERO_VECTOR;
296
- let cameraPosCommon = viewport.cameraPosition;
297
- const { geospatialOrigin, shaderCoordinateOrigin, offsetMode } = getOffsetOrigin(
298
- viewport,
299
- coordinateSystem,
300
- coordinateOrigin
301
- );
302
- if (offsetMode) {
303
- originCommon = viewport.projectPosition(geospatialOrigin || shaderCoordinateOrigin);
304
- cameraPosCommon = [
305
- cameraPosCommon[0] - originCommon[0],
306
- cameraPosCommon[1] - originCommon[1],
307
- cameraPosCommon[2] - originCommon[2]
308
- ];
309
- originCommon[3] = 1;
310
- projectionCenter = import_core.vec4.transformMat4([], originCommon, viewProjectionMatrix);
311
- viewMatrix2 = viewMatrixUncentered || viewMatrix2;
312
- viewProjectionMatrix = import_core.mat4.multiply([], projectionMatrix, viewMatrix2);
313
- viewProjectionMatrix = import_core.mat4.multiply([], viewProjectionMatrix, VECTOR_TO_POINT_MATRIX);
314
- }
315
- return {
316
- viewMatrix: viewMatrix2,
317
- viewProjectionMatrix,
318
- projectionCenter,
319
- originCommon,
320
- cameraPosCommon,
321
- shaderCoordinateOrigin,
322
- geospatialOrigin
323
- };
324
- }
325
- function getUniformsFromViewport({
326
- viewport,
327
- devicePixelRatio = 1,
328
- modelMatrix = null,
329
- // Match Layer.defaultProps
330
- coordinateSystem = "default",
331
- coordinateOrigin = DEFAULT_COORDINATE_ORIGIN,
332
- autoWrapLongitude = false
333
- }) {
334
- if (coordinateSystem === "default") {
335
- coordinateSystem = viewport.isGeospatial ? "lnglat" : "cartesian";
336
- }
337
- const uniforms = getMemoizedViewportUniforms({
338
- viewport,
339
- devicePixelRatio,
340
- coordinateSystem,
341
- coordinateOrigin
342
- });
343
- uniforms.wrapLongitude = autoWrapLongitude;
344
- uniforms.modelMatrix = modelMatrix || IDENTITY_MATRIX;
345
- return uniforms;
346
- }
347
- function calculateViewportUniforms({
348
- viewport,
349
- devicePixelRatio,
350
- coordinateSystem,
351
- coordinateOrigin
352
- }) {
353
- const {
354
- projectionCenter,
355
- viewProjectionMatrix,
356
- originCommon,
357
- cameraPosCommon,
358
- shaderCoordinateOrigin,
359
- geospatialOrigin
360
- } = calculateMatrixAndOffset(viewport, coordinateSystem, coordinateOrigin);
361
- const distanceScales = viewport.getDistanceScales();
362
- const viewportSize = [
363
- viewport.width * devicePixelRatio,
364
- viewport.height * devicePixelRatio
365
- ];
366
- const focalDistance = import_core.vec4.transformMat4([], [0, 0, -viewport.focalDistance, 1], viewport.projectionMatrix)[3] || 1;
367
- const uniforms = {
368
- // Projection mode values
369
- coordinateSystem: getShaderCoordinateSystem(coordinateSystem),
370
- projectionMode: viewport.projectionMode,
371
- coordinateOrigin: shaderCoordinateOrigin,
372
- commonOrigin: originCommon.slice(0, 3),
373
- center: projectionCenter,
374
- // Backward compatibility
375
- // TODO: remove in v9
376
- // @ts-expect-error _pseudoMeters is only defined on WebMercator viewport
377
- pseudoMeters: Boolean(viewport._pseudoMeters),
378
- // Screen size
379
- viewportSize,
380
- devicePixelRatio,
381
- focalDistance,
382
- commonUnitsPerMeter: distanceScales.unitsPerMeter,
383
- commonUnitsPerWorldUnit: distanceScales.unitsPerMeter,
384
- commonUnitsPerWorldUnit2: DEFAULT_PIXELS_PER_UNIT2,
385
- scale: viewport.scale,
386
- // This is the mercator scale (2 ** zoom)
387
- wrapLongitude: false,
388
- viewProjectionMatrix,
389
- modelMatrix: IDENTITY_MATRIX,
390
- // This is for lighting calculations
391
- cameraPosition: cameraPosCommon
392
- };
393
- if (geospatialOrigin) {
394
- const distanceScalesAtOrigin = viewport.getDistanceScales(geospatialOrigin);
395
- switch (coordinateSystem) {
396
- case "meter-offsets":
397
- uniforms.commonUnitsPerWorldUnit = distanceScalesAtOrigin.unitsPerMeter;
398
- uniforms.commonUnitsPerWorldUnit2 = distanceScalesAtOrigin.unitsPerMeter2;
399
- break;
400
- case "lnglat":
401
- case "lnglat-offsets":
402
- if (!viewport._pseudoMeters) {
403
- uniforms.commonUnitsPerMeter = distanceScalesAtOrigin.unitsPerMeter;
404
- }
405
- uniforms.commonUnitsPerWorldUnit = distanceScalesAtOrigin.unitsPerDegree;
406
- uniforms.commonUnitsPerWorldUnit2 = distanceScalesAtOrigin.unitsPerDegree2;
407
- break;
408
- // a.k.a "preprojected" positions
409
- case "cartesian":
410
- uniforms.commonUnitsPerWorldUnit = [1, 1, distanceScalesAtOrigin.unitsPerMeter[2]];
411
- uniforms.commonUnitsPerWorldUnit2 = [0, 0, distanceScalesAtOrigin.unitsPerMeter2[2]];
412
- break;
413
- default:
414
- break;
415
- }
416
- }
417
- if (viewport.projectionMode === PROJECTION_MODE.GLOBE && coordinateSystem === "meter-offsets") {
418
- const EARTH_RADIUS2 = 6370972;
419
- const GLOBE_RADIUS2 = 256;
420
- const lambda = coordinateOrigin[0] * Math.PI / 180;
421
- const phi = coordinateOrigin[1] * Math.PI / 180;
422
- const cosPhi = Math.cos(phi);
423
- const D = ((coordinateOrigin[2] || 0) / EARTH_RADIUS2 + 1) * GLOBE_RADIUS2;
424
- uniforms.commonOrigin = [
425
- Math.sin(lambda) * cosPhi * D,
426
- -Math.cos(lambda) * cosPhi * D,
427
- Math.sin(phi) * D
428
- ];
429
- }
430
- return uniforms;
431
- }
432
-
433
- // ../core/src/shaderlib/project/project.wgsl.ts
434
- var SHADER_COORDINATE_SYSTEMS = [
435
- "default",
436
- "lnglat",
437
- "meter-offsets",
438
- "lnglat-offsets",
439
- "cartesian"
440
- ];
441
- var COORDINATE_SYSTEM_WGSL_CONSTANTS = SHADER_COORDINATE_SYSTEMS.map(
442
- (coordinateSystem) => `const COORDINATE_SYSTEM_${coordinateSystem.toUpperCase().replaceAll("-", "_")}: i32 = ${getShaderCoordinateSystem(coordinateSystem)};`
443
- ).join("");
444
- var PROJECTION_MODE_WGSL_CONSTANTS = Object.keys(PROJECTION_MODE).map((key) => `const PROJECTION_MODE_${key}: i32 = ${PROJECTION_MODE[key]};`).join("");
445
- var UNIT_WGSL_CONSTANTS = Object.keys(UNIT).map((key) => `const UNIT_${key.toUpperCase()}: i32 = ${UNIT[key]};`).join("");
446
- var projectWGSLHeader = (
447
- /* wgsl */
448
- `${COORDINATE_SYSTEM_WGSL_CONSTANTS}
449
- ${PROJECTION_MODE_WGSL_CONSTANTS}
450
- ${UNIT_WGSL_CONSTANTS}
451
-
452
- const TILE_SIZE: f32 = 512.0;
453
- const PI: f32 = 3.1415926536;
454
- const WORLD_SCALE: f32 = TILE_SIZE / (PI * 2.0);
455
- const ZERO_64_LOW: vec3<f32> = vec3<f32>(0.0, 0.0, 0.0);
456
- const EARTH_RADIUS: f32 = 6370972.0; // meters
457
- const GLOBE_RADIUS: f32 = 256.0;
458
-
459
- // -----------------------------------------------------------------------------
460
- // Uniform block (converted from GLSL uniform block)
461
- // -----------------------------------------------------------------------------
462
- struct ProjectUniforms {
463
- wrapLongitude: i32,
464
- coordinateSystem: i32,
465
- commonUnitsPerMeter: vec3<f32>,
466
- projectionMode: i32,
467
- scale: f32,
468
- commonUnitsPerWorldUnit: vec3<f32>,
469
- commonUnitsPerWorldUnit2: vec3<f32>,
470
- center: vec4<f32>,
471
- modelMatrix: mat4x4<f32>,
472
- viewProjectionMatrix: mat4x4<f32>,
473
- viewportSize: vec2<f32>,
474
- devicePixelRatio: f32,
475
- focalDistance: f32,
476
- cameraPosition: vec3<f32>,
477
- coordinateOrigin: vec3<f32>,
478
- commonOrigin: vec3<f32>,
479
- pseudoMeters: i32,
480
- };
481
-
482
- @group(0) @binding(auto)
483
- var<uniform> project: ProjectUniforms;
484
-
485
- // -----------------------------------------------------------------------------
486
- // Geometry data shared across the project helpers.
487
- // The active layer shader is responsible for populating this private module
488
- // state before calling the project functions below.
489
- // -----------------------------------------------------------------------------
490
-
491
- // Structure to carry additional geometry data used by deck.gl filters.
492
- struct Geometry {
493
- worldPosition: vec3<f32>,
494
- worldPositionAlt: vec3<f32>,
495
- position: vec4<f32>,
496
- normal: vec3<f32>,
497
- uv: vec2<f32>,
498
- pickingColor: vec3<f32>,
499
- };
500
-
501
- var<private> geometry: Geometry;
502
- `
503
- );
504
- var projectWGSL = (
505
- /* wgsl */
506
- `${projectWGSLHeader}
507
-
508
- // -----------------------------------------------------------------------------
509
- // Functions
510
- // -----------------------------------------------------------------------------
511
-
512
- // Returns an adjustment factor for commonUnitsPerMeter
513
- fn _project_size_at_latitude(lat: f32) -> f32 {
514
- let y = clamp(lat, -89.9, 89.9);
515
- return 1.0 / cos(radians(y));
516
- }
517
-
518
- // Overloaded version: scales a value in meters at a given latitude.
519
- fn _project_size_at_latitude_m(meters: f32, lat: f32) -> f32 {
520
- return meters * project.commonUnitsPerMeter.z * _project_size_at_latitude(lat);
521
- }
522
-
523
- // Computes a non-linear scale factor based on geometry.
524
- // (Note: This function relies on "geometry" being provided.)
525
- fn project_size() -> f32 {
526
- if (project.projectionMode == PROJECTION_MODE_WEB_MERCATOR &&
527
- project.coordinateSystem == COORDINATE_SYSTEM_LNGLAT &&
528
- project.pseudoMeters == 0) {
529
- if (geometry.position.w == 0.0) {
530
- return _project_size_at_latitude(geometry.worldPosition.y);
531
- }
532
- let y: f32 = geometry.position.y / TILE_SIZE * 2.0 - 1.0;
533
- let y2 = y * y;
534
- let y4 = y2 * y2;
535
- let y6 = y4 * y2;
536
- return 1.0 + 4.9348 * y2 + 4.0587 * y4 + 1.5642 * y6;
537
- }
538
- return 1.0;
539
- }
540
-
541
- // Overloads to scale offsets (meters to world units)
542
- fn project_size_float(meters: f32) -> f32 {
543
- return meters * project.commonUnitsPerMeter.z * project_size();
544
- }
545
-
546
- fn project_size_vec2(meters: vec2<f32>) -> vec2<f32> {
547
- return meters * project.commonUnitsPerMeter.xy * project_size();
548
- }
549
-
550
- fn project_size_vec3(meters: vec3<f32>) -> vec3<f32> {
551
- return meters * project.commonUnitsPerMeter * project_size();
552
- }
553
-
554
- fn project_size_vec4(meters: vec4<f32>) -> vec4<f32> {
555
- return vec4<f32>(meters.xyz * project.commonUnitsPerMeter, meters.w);
556
- }
557
-
558
- // Returns a rotation matrix aligning the z\u2011axis with the given up vector.
559
- fn project_get_orientation_matrix(up: vec3<f32>) -> mat3x3<f32> {
560
- let uz = normalize(up);
561
- let ux = select(
562
- vec3<f32>(1.0, 0.0, 0.0),
563
- normalize(vec3<f32>(uz.y, -uz.x, 0.0)),
564
- abs(uz.z) == 1.0
565
- );
566
- let uy = cross(uz, ux);
567
- return mat3x3<f32>(ux, uy, uz);
568
- }
569
-
570
- // Since WGSL does not support "out" parameters, we return a struct.
571
- struct RotationResult {
572
- needsRotation: bool,
573
- transform: mat3x3<f32>,
574
- };
575
-
576
- fn project_needs_rotation(commonPosition: vec3<f32>) -> RotationResult {
577
- if (project.projectionMode == PROJECTION_MODE_GLOBE) {
578
- return RotationResult(true, project_get_orientation_matrix(commonPosition));
579
- } else {
580
- return RotationResult(false, mat3x3<f32>()); // identity alternative if needed
581
- };
582
- }
583
-
584
- // Projects a normal vector from the current coordinate system to world space.
585
- fn project_normal(vector: vec3<f32>) -> vec3<f32> {
586
- let normal_modelspace = project.modelMatrix * vec4<f32>(vector, 0.0);
587
- var n = normalize(normal_modelspace.xyz * project.commonUnitsPerMeter);
588
- let rotResult = project_needs_rotation(geometry.position.xyz);
589
- if (rotResult.needsRotation) {
590
- n = rotResult.transform * n;
591
- }
592
- return n;
593
- }
594
-
595
- // Applies a scale offset based on y-offset (dy)
596
- fn project_offset_(offset: vec4<f32>) -> vec4<f32> {
597
- let dy: f32 = offset.y;
598
- let commonUnitsPerWorldUnit = project.commonUnitsPerWorldUnit + project.commonUnitsPerWorldUnit2 * dy;
599
- return vec4<f32>(offset.xyz * commonUnitsPerWorldUnit, offset.w);
600
- }
601
-
602
- // Projects lng/lat coordinates to a unit tile [0,1]
603
- fn project_mercator_(lnglat: vec2<f32>) -> vec2<f32> {
604
- var x = lnglat.x;
605
- if (project.wrapLongitude != 0) {
606
- x = ((x + 180.0) % 360.0) - 180.0;
607
- }
608
- let y = clamp(lnglat.y, -89.9, 89.9);
609
- return vec2<f32>(
610
- radians(x) + PI,
611
- PI + log(tan(PI * 0.25 + radians(y) * 0.5))
612
- ) * WORLD_SCALE;
613
- }
614
-
615
- // Projects lng/lat/z coordinates for a globe projection.
616
- fn project_globe_(lnglatz: vec3<f32>) -> vec3<f32> {
617
- let lambda = radians(lnglatz.x);
618
- let phi = radians(lnglatz.y);
619
- let cosPhi = cos(phi);
620
- let D = (lnglatz.z / EARTH_RADIUS + 1.0) * GLOBE_RADIUS;
621
- return vec3<f32>(
622
- sin(lambda) * cosPhi,
623
- -cos(lambda) * cosPhi,
624
- sin(phi)
625
- ) * D;
626
- }
627
-
628
- // Projects positions (with an optional 64-bit low part) from the input
629
- // coordinate system to the common space.
630
- fn project_position_vec4_f64(position: vec4<f32>, position64Low: vec3<f32>) -> vec4<f32> {
631
- var position_world = project.modelMatrix * position;
632
-
633
- // Work around for a Mac+NVIDIA bug:
634
- if (project.projectionMode == PROJECTION_MODE_WEB_MERCATOR) {
635
- if (project.coordinateSystem == COORDINATE_SYSTEM_LNGLAT) {
636
- return vec4<f32>(
637
- project_mercator_(position_world.xy),
638
- _project_size_at_latitude_m(position_world.z, position_world.y),
639
- position_world.w
640
- );
641
- }
642
- if (project.coordinateSystem == COORDINATE_SYSTEM_CARTESIAN) {
643
- position_world = vec4f(position_world.xyz + project.coordinateOrigin, position_world.w);
644
- }
645
- }
646
- if (project.projectionMode == PROJECTION_MODE_GLOBE) {
647
- if (project.coordinateSystem == COORDINATE_SYSTEM_LNGLAT) {
648
- return vec4<f32>(
649
- project_globe_(position_world.xyz),
650
- position_world.w
651
- );
652
- }
653
- if (project.coordinateSystem == COORDINATE_SYSTEM_METER_OFFSETS) {
654
- let enuMatrix = project_get_orientation_matrix(project.commonOrigin);
655
- let metersToCommon = GLOBE_RADIUS / EARTH_RADIUS;
656
- let offsetCommon = (enuMatrix * vec3<f32>(-position_world.x, -position_world.y, position_world.z)) * metersToCommon;
657
- return vec4<f32>(project.commonOrigin + offsetCommon, position_world.w);
658
- }
659
- }
660
- if (project.projectionMode == PROJECTION_MODE_WEB_MERCATOR_AUTO_OFFSET) {
661
- if (project.coordinateSystem == COORDINATE_SYSTEM_LNGLAT) {
662
- if (abs(position_world.y - project.coordinateOrigin.y) > 0.25) {
663
- return vec4<f32>(
664
- project_mercator_(position_world.xy) - project.commonOrigin.xy,
665
- project_size_float(position_world.z),
666
- position_world.w
667
- );
668
- }
669
- }
670
- }
671
- if (project.projectionMode == PROJECTION_MODE_IDENTITY ||
672
- (project.projectionMode == PROJECTION_MODE_WEB_MERCATOR_AUTO_OFFSET &&
673
- (project.coordinateSystem == COORDINATE_SYSTEM_LNGLAT ||
674
- project.coordinateSystem == COORDINATE_SYSTEM_CARTESIAN))) {
675
- position_world = vec4f(position_world.xyz - project.coordinateOrigin, position_world.w);
676
- }
677
-
678
- return project_offset_(position_world) +
679
- project_offset_(project.modelMatrix * vec4<f32>(position64Low, 0.0));
680
- }
681
-
682
- // Overloaded versions for different input types.
683
- fn project_position_vec4_f32(position: vec4<f32>) -> vec4<f32> {
684
- return project_position_vec4_f64(position, ZERO_64_LOW);
685
- }
686
-
687
- fn project_position_vec3_f64(position: vec3<f32>, position64Low: vec3<f32>) -> vec3<f32> {
688
- let projected_position = project_position_vec4_f64(vec4<f32>(position, 1.0), position64Low);
689
- return projected_position.xyz;
690
- }
691
-
692
- fn project_position_vec3_f32(position: vec3<f32>) -> vec3<f32> {
693
- let projected_position = project_position_vec4_f64(vec4<f32>(position, 1.0), ZERO_64_LOW);
694
- return projected_position.xyz;
695
- }
696
-
697
- fn project_position_vec2_f32(position: vec2<f32>) -> vec2<f32> {
698
- let projected_position = project_position_vec4_f64(vec4<f32>(position, 0.0, 1.0), ZERO_64_LOW);
699
- return projected_position.xy;
700
- }
701
-
702
- // Transforms a common space position to clip space.
703
- fn project_common_position_to_clipspace_with_projection(position: vec4<f32>, viewProjectionMatrix: mat4x4<f32>, center: vec4<f32>) -> vec4<f32> {
704
- var clipPosition = viewProjectionMatrix * position + center;
705
- // deck.gl projection matrices use WebGL's [-w, w] depth range; WebGPU clips z to [0, w].
706
- clipPosition.z = (clipPosition.z + clipPosition.w) * 0.5;
707
- return clipPosition;
708
- }
709
-
710
- // Uses the project viewProjectionMatrix and center.
711
- fn project_common_position_to_clipspace(position: vec4<f32>) -> vec4<f32> {
712
- return project_common_position_to_clipspace_with_projection(position, project.viewProjectionMatrix, project.center);
713
- }
714
-
715
- // Returns a clip space offset corresponding to a given number of screen pixels.
716
- fn project_pixel_size_to_clipspace(pixels: vec2<f32>) -> vec2<f32> {
717
- let offset = pixels / project.viewportSize * project.devicePixelRatio * 2.0;
718
- return offset * project.focalDistance;
719
- }
720
-
721
- fn project_meter_size_to_pixel(meters: f32) -> f32 {
722
- return project_size_float(meters) * project.scale;
723
- }
724
-
725
- fn project_unit_size_to_pixel(size: f32, unit: i32) -> f32 {
726
- if (unit == UNIT_METERS) {
727
- return project_meter_size_to_pixel(size);
728
- } else if (unit == UNIT_COMMON) {
729
- return size * project.scale;
730
- }
731
- // UNIT_PIXELS: no scaling applied.
732
- return size;
733
- }
734
-
735
- fn project_pixel_size_float(pixels: f32) -> f32 {
736
- return pixels / project.scale;
737
- }
738
-
739
- fn project_pixel_size_vec2(pixels: vec2<f32>) -> vec2<f32> {
740
- return pixels / project.scale;
741
- }
742
- `
743
- );
744
-
745
- // ../core/src/shaderlib/project/project.glsl.ts
746
- var SHADER_COORDINATE_SYSTEMS2 = [
747
- "default",
748
- "lnglat",
749
- "meter-offsets",
750
- "lnglat-offsets",
751
- "cartesian"
752
- ];
753
- var COORDINATE_SYSTEM_GLSL_CONSTANTS = SHADER_COORDINATE_SYSTEMS2.map(
754
- (coordinateSystem) => `const int COORDINATE_SYSTEM_${coordinateSystem.toUpperCase().replaceAll("-", "_")} = ${getShaderCoordinateSystem(coordinateSystem)};`
755
- ).join("");
756
- var PROJECTION_MODE_GLSL_CONSTANTS = Object.keys(PROJECTION_MODE).map((key) => `const int PROJECTION_MODE_${key} = ${PROJECTION_MODE[key]};`).join("");
757
- var UNIT_GLSL_CONSTANTS = Object.keys(UNIT).map((key) => `const int UNIT_${key.toUpperCase()} = ${UNIT[key]};`).join("");
758
- var projectGLSL = (
759
- /* glsl */
760
- `${COORDINATE_SYSTEM_GLSL_CONSTANTS}
761
- ${PROJECTION_MODE_GLSL_CONSTANTS}
762
- ${UNIT_GLSL_CONSTANTS}
763
-
764
- layout(std140) uniform projectUniforms {
765
- bool wrapLongitude;
766
- int coordinateSystem;
767
- vec3 commonUnitsPerMeter;
768
- int projectionMode;
769
- float scale;
770
- vec3 commonUnitsPerWorldUnit;
771
- vec3 commonUnitsPerWorldUnit2;
772
- vec4 center;
773
- mat4 modelMatrix;
774
- mat4 viewProjectionMatrix;
775
- vec2 viewportSize;
776
- float devicePixelRatio;
777
- float focalDistance;
778
- vec3 cameraPosition;
779
- vec3 coordinateOrigin;
780
- vec3 commonOrigin;
781
- bool pseudoMeters;
782
- } project;
783
-
784
-
785
- const float TILE_SIZE = 512.0;
786
- const float PI = 3.1415926536;
787
- const float WORLD_SCALE = TILE_SIZE / (PI * 2.0);
788
- const vec3 ZERO_64_LOW = vec3(0.0);
789
- const float EARTH_RADIUS = 6370972.0; // meters
790
- const float GLOBE_RADIUS = 256.0;
791
-
792
- // returns an adjustment factor for uCommonUnitsPerMeter
793
- float project_size_at_latitude(float lat) {
794
- float y = clamp(lat, -89.9, 89.9);
795
- return 1.0 / cos(radians(y));
796
- }
797
-
798
- float project_size() {
799
- if (project.projectionMode == PROJECTION_MODE_WEB_MERCATOR &&
800
- project.coordinateSystem == COORDINATE_SYSTEM_LNGLAT &&
801
- project.pseudoMeters == false) {
802
-
803
- // uCommonUnitsPerMeter in low-zoom Web Mercator is non-linear
804
- // Adjust by 1 / cos(latitude)
805
- // If geometry.position (vertex in common space) is populated, use it
806
- // Otherwise use geometry.worldPosition (anchor in world space)
807
-
808
- if (geometry.position.w == 0.0) {
809
- return project_size_at_latitude(geometry.worldPosition.y);
810
- }
811
-
812
- // latitude from common y: 2.0 * (atan(exp(y / TILE_SIZE * 2.0 * PI - PI)) - PI / 4.0)
813
- // Taylor series of 1 / cos(latitude)
814
- // Max error < 0.003
815
-
816
- float y = geometry.position.y / TILE_SIZE * 2.0 - 1.0;
817
- float y2 = y * y;
818
- float y4 = y2 * y2;
819
- float y6 = y4 * y2;
820
- return 1.0 + 4.9348 * y2 + 4.0587 * y4 + 1.5642 * y6;
821
- }
822
- return 1.0;
823
- }
824
-
825
- float project_size_at_latitude(float meters, float lat) {
826
- return meters * project.commonUnitsPerMeter.z * project_size_at_latitude(lat);
827
- }
828
-
829
- //
830
- // Scaling offsets - scales meters to "world distance"
831
- // Note the scalar version of project_size is for scaling the z component only
832
- //
833
- float project_size(float meters) {
834
- // For scatter relevant
835
- return meters * project.commonUnitsPerMeter.z * project_size();
836
- }
837
-
838
- vec2 project_size(vec2 meters) {
839
- return meters * project.commonUnitsPerMeter.xy * project_size();
840
- }
841
-
842
- vec3 project_size(vec3 meters) {
843
- return meters * project.commonUnitsPerMeter * project_size();
844
- }
845
-
846
- vec4 project_size(vec4 meters) {
847
- return vec4(meters.xyz * project.commonUnitsPerMeter, meters.w);
848
- }
849
-
850
- // Get rotation matrix that aligns the z axis with the given up vector
851
- // Find 3 unit vectors ux, uy, uz that are perpendicular to each other and uz == up
852
- mat3 project_get_orientation_matrix(vec3 up) {
853
- vec3 uz = normalize(up);
854
- // Tangent on XY plane
855
- vec3 ux = abs(uz.z) == 1.0 ? vec3(1.0, 0.0, 0.0) : normalize(vec3(uz.y, -uz.x, 0));
856
- vec3 uy = cross(uz, ux);
857
- return mat3(ux, uy, uz);
858
- }
859
-
860
- bool project_needs_rotation(vec3 commonPosition, out mat3 transform) {
861
- if (project.projectionMode == PROJECTION_MODE_GLOBE) {
862
- transform = project_get_orientation_matrix(commonPosition);
863
- return true;
864
- }
865
- return false;
866
- }
867
-
868
- //
869
- // Projecting normal - transform deltas from current coordinate system to
870
- // normals in the worldspace
871
- //
872
- vec3 project_normal(vec3 vector) {
873
- // Apply model matrix
874
- vec4 normal_modelspace = project.modelMatrix * vec4(vector, 0.0);
875
- vec3 n = normalize(normal_modelspace.xyz * project.commonUnitsPerMeter);
876
- mat3 rotation;
877
- if (project_needs_rotation(geometry.position.xyz, rotation)) {
878
- n = rotation * n;
879
- }
880
- return n;
881
- }
882
-
883
- vec4 project_offset_(vec4 offset) {
884
- float dy = offset.y;
885
- vec3 commonUnitsPerWorldUnit = project.commonUnitsPerWorldUnit + project.commonUnitsPerWorldUnit2 * dy;
886
- return vec4(offset.xyz * commonUnitsPerWorldUnit, offset.w);
887
- }
888
-
889
- //
890
- // Projecting positions - non-linear projection: lnglats => unit tile [0-1, 0-1]
891
- //
892
- vec2 project_mercator_(vec2 lnglat) {
893
- float x = lnglat.x;
894
- if (project.wrapLongitude) {
895
- x = mod(x + 180., 360.0) - 180.;
896
- }
897
- float y = clamp(lnglat.y, -89.9, 89.9);
898
- return vec2(
899
- radians(x) + PI,
900
- PI + log(tan_fp32(PI * 0.25 + radians(y) * 0.5))
901
- ) * WORLD_SCALE;
902
- }
903
-
904
- vec3 project_globe_(vec3 lnglatz) {
905
- float lambda = radians(lnglatz.x);
906
- float phi = radians(lnglatz.y);
907
- float cosPhi = cos(phi);
908
- float D = (lnglatz.z / EARTH_RADIUS + 1.0) * GLOBE_RADIUS;
909
-
910
- return vec3(
911
- sin(lambda) * cosPhi,
912
- -cos(lambda) * cosPhi,
913
- sin(phi)
914
- ) * D;
915
- }
916
-
917
- //
918
- // Projects positions (defined by project.coordinateSystem) to common space (defined by project.projectionMode)
919
- //
920
- vec4 project_position(vec4 position, vec3 position64Low) {
921
- vec4 position_world = project.modelMatrix * position;
922
-
923
- // Work around for a Mac+NVIDIA bug https://github.com/visgl/deck.gl/issues/4145
924
- if (project.projectionMode == PROJECTION_MODE_WEB_MERCATOR) {
925
- if (project.coordinateSystem == COORDINATE_SYSTEM_LNGLAT) {
926
- return vec4(
927
- project_mercator_(position_world.xy),
928
- project_size_at_latitude(position_world.z, position_world.y),
929
- position_world.w
930
- );
931
- }
932
- if (project.coordinateSystem == COORDINATE_SYSTEM_CARTESIAN) {
933
- position_world.xyz += project.coordinateOrigin;
934
- }
935
- }
936
- if (project.projectionMode == PROJECTION_MODE_GLOBE) {
937
- if (project.coordinateSystem == COORDINATE_SYSTEM_LNGLAT) {
938
- return vec4(
939
- project_globe_(position_world.xyz),
940
- position_world.w
941
- );
942
- }
943
- if (project.coordinateSystem == COORDINATE_SYSTEM_METER_OFFSETS) {
944
- mat3 enuMatrix = project_get_orientation_matrix(project.commonOrigin);
945
- float metersToCommon = GLOBE_RADIUS / EARTH_RADIUS;
946
- vec3 offsetCommon = (enuMatrix * vec3(-position_world.xy, position_world.z)) * metersToCommon;
947
- return vec4(project.commonOrigin + offsetCommon, position_world.w);
948
- }
949
- }
950
- if (project.projectionMode == PROJECTION_MODE_WEB_MERCATOR_AUTO_OFFSET) {
951
- if (project.coordinateSystem == COORDINATE_SYSTEM_LNGLAT) {
952
- if (abs(position_world.y - project.coordinateOrigin.y) > 0.25) {
953
- // Too far from the projection center for offset mode to be accurate
954
- // Only use high parts
955
- return vec4(
956
- project_mercator_(position_world.xy) - project.commonOrigin.xy,
957
- project_size(position_world.z),
958
- position_world.w
959
- );
960
- }
961
- }
962
- }
963
- if (project.projectionMode == PROJECTION_MODE_IDENTITY ||
964
- (project.projectionMode == PROJECTION_MODE_WEB_MERCATOR_AUTO_OFFSET &&
965
- (project.coordinateSystem == COORDINATE_SYSTEM_LNGLAT ||
966
- project.coordinateSystem == COORDINATE_SYSTEM_CARTESIAN))) {
967
- // Subtract high part of 64 bit value. Convert remainder to float32, preserving precision.
968
- position_world.xyz -= project.coordinateOrigin;
969
- }
970
-
971
- // Translation is already added to the high parts
972
- return project_offset_(position_world) + project_offset_(project.modelMatrix * vec4(position64Low, 0.0));
973
- }
974
-
975
- vec4 project_position(vec4 position) {
976
- return project_position(position, ZERO_64_LOW);
977
- }
978
-
979
- vec3 project_position(vec3 position, vec3 position64Low) {
980
- vec4 projected_position = project_position(vec4(position, 1.0), position64Low);
981
- return projected_position.xyz;
982
- }
983
-
984
- vec3 project_position(vec3 position) {
985
- vec4 projected_position = project_position(vec4(position, 1.0), ZERO_64_LOW);
986
- return projected_position.xyz;
987
- }
988
-
989
- vec2 project_position(vec2 position) {
990
- vec4 projected_position = project_position(vec4(position, 0.0, 1.0), ZERO_64_LOW);
991
- return projected_position.xy;
992
- }
993
-
994
- vec4 project_common_position_to_clipspace(vec4 position, mat4 viewProjectionMatrix, vec4 center) {
995
- return viewProjectionMatrix * position + center;
996
- }
997
-
998
- //
999
- // Projects from common space coordinates to clip space.
1000
- // Uses project.viewProjectionMatrix
1001
- //
1002
- vec4 project_common_position_to_clipspace(vec4 position) {
1003
- return project_common_position_to_clipspace(position, project.viewProjectionMatrix, project.center);
1004
- }
1005
-
1006
- // Returns a clip space offset that corresponds to a given number of screen pixels
1007
- vec2 project_pixel_size_to_clipspace(vec2 pixels) {
1008
- vec2 offset = pixels / project.viewportSize * project.devicePixelRatio * 2.0;
1009
- return offset * project.focalDistance;
1010
- }
1011
-
1012
- float project_size_to_pixel(float meters) {
1013
- return project_size(meters) * project.scale;
1014
- }
1015
- vec2 project_size_to_pixel(vec2 meters) {
1016
- return project_size(meters) * project.scale;
1017
- }
1018
- float project_size_to_pixel(float size, int unit) {
1019
- if (unit == UNIT_METERS) return project_size_to_pixel(size);
1020
- if (unit == UNIT_COMMON) return size * project.scale;
1021
- // UNIT_PIXELS
1022
- return size;
1023
- }
1024
- float project_pixel_size(float pixels) {
1025
- return pixels / project.scale;
1026
- }
1027
- vec2 project_pixel_size(vec2 pixels) {
1028
- return pixels / project.scale;
1029
- }
1030
- `
1031
- );
1032
-
1033
- // ../core/src/shaderlib/project/project.ts
1034
- var INITIAL_MODULE_OPTIONS = {};
1035
- function getUniforms(opts = INITIAL_MODULE_OPTIONS) {
1036
- if ("viewport" in opts) {
1037
- return getUniformsFromViewport(opts);
1038
- }
1039
- return {};
1040
- }
1041
- var project_default = {
1042
- name: "project",
1043
- dependencies: [import_shadertools.fp32, geometry_default],
1044
- source: projectWGSL,
1045
- vs: projectGLSL,
1046
- getUniforms,
1047
- uniformTypes: {
1048
- wrapLongitude: "f32",
1049
- coordinateSystem: "i32",
1050
- commonUnitsPerMeter: "vec3<f32>",
1051
- projectionMode: "i32",
1052
- scale: "f32",
1053
- commonUnitsPerWorldUnit: "vec3<f32>",
1054
- commonUnitsPerWorldUnit2: "vec3<f32>",
1055
- center: "vec4<f32>",
1056
- modelMatrix: "mat4x4<f32>",
1057
- viewProjectionMatrix: "mat4x4<f32>",
1058
- viewportSize: "vec2<f32>",
1059
- devicePixelRatio: "f32",
1060
- focalDistance: "f32",
1061
- cameraPosition: "vec3<f32>",
1062
- coordinateOrigin: "vec3<f32>",
1063
- commonOrigin: "vec3<f32>",
1064
- pseudoMeters: "f32"
1065
- }
1066
- // @ts-ignore TODO v9.1
1067
- };
1068
-
1069
- // ../core/src/passes/pass.ts
1070
- var Pass = class {
1071
- /** Create a new Pass instance */
1072
- constructor(device, props = { id: "pass" }) {
1073
- const { id } = props;
1074
- this.id = id;
1075
- this.device = device;
1076
- this.props = { ...props };
1077
- }
1078
- setProps(props) {
1079
- Object.assign(this.props, props);
1080
- }
1081
- render(params) {
1082
- }
1083
- // eslint-disable-line @typescript-eslint/no-empty-function
1084
- cleanup() {
1085
- }
1086
- // eslint-disable-line @typescript-eslint/no-empty-function
1087
- };
1088
-
1089
- // ../core/src/passes/layers-pass.ts
1090
- var WEBGPU_DEFAULT_DRAW_PARAMETERS = {
1091
- depthWriteEnabled: true,
1092
- depthCompare: "less-equal",
1093
- blendColorOperation: "add",
1094
- blendColorSrcFactor: "one",
1095
- blendColorDstFactor: "one-minus-src-alpha",
1096
- blendAlphaOperation: "add",
1097
- blendAlphaSrcFactor: "one",
1098
- blendAlphaDstFactor: "one-minus-src-alpha"
1099
- };
1100
- var LayersPass = class extends Pass {
1101
- constructor() {
1102
- super(...arguments);
1103
- this._lastRenderIndex = -1;
1104
- }
1105
- render(options) {
1106
- this._render(options);
1107
- }
1108
- _render(options) {
1109
- const { canvasContext = this.device.canvasContext } = options;
1110
- const framebuffer = options.target ?? canvasContext.getCurrentFramebuffer();
1111
- const [width, height] = canvasContext.getDrawingBufferSize();
1112
- const clearCanvas = options.clearCanvas ?? true;
1113
- let clearColor = options.clearColor ?? (clearCanvas ? [0, 0, 0, 0] : false);
1114
- let clearDepth = clearCanvas ? 1 : false;
1115
- let clearStencil = clearCanvas ? 0 : false;
1116
- const colorMask = options.colorMask ?? 15;
1117
- const parameters2 = { viewport: [0, 0, width, height] };
1118
- if (options.colorMask) {
1119
- parameters2.colorMask = colorMask;
1120
- }
1121
- if (options.scissorRect) {
1122
- parameters2.scissorRect = options.scissorRect;
1123
- }
1124
- const { shaderModuleProps, viewports, views, onViewportActive, clearStack = true } = options;
1125
- const pass = options.pass || "unknown";
1126
- const submitEachRenderPass = this.device.type === "webgpu";
1127
- if (clearStack) {
1128
- this._lastRenderIndex = -1;
1129
- }
1130
- const renderStats = [];
1131
- if (!viewports.length) {
1132
- const renderPass = this.device.beginRenderPass({
1133
- framebuffer,
1134
- parameters: parameters2,
1135
- clearColor,
1136
- clearDepth,
1137
- clearStencil
1138
- });
1139
- renderPass.end();
1140
- this.device.submit();
1141
- return renderStats;
1142
- }
1143
- try {
1144
- for (const viewport of viewports) {
1145
- onViewportActive == null ? void 0 : onViewportActive(viewport);
1146
- const drawLayerParams = this._getDrawLayerParams(viewport, options);
1147
- const view = views && views[viewport.id];
1148
- const subViewports = viewport.subViewports || [viewport];
1149
- const renderGroups = submitEachRenderPass ? subViewports.map((subViewport) => [subViewport]) : [subViewports];
1150
- for (const renderGroup of renderGroups) {
1151
- const renderPass = this.device.beginRenderPass({
1152
- framebuffer,
1153
- parameters: parameters2,
1154
- clearColor,
1155
- clearDepth,
1156
- clearStencil
1157
- });
1158
- try {
1159
- for (const subViewport of renderGroup) {
1160
- const stats = this._drawLayersInViewport(
1161
- renderPass,
1162
- {
1163
- target: framebuffer,
1164
- canvasContext,
1165
- shaderModuleProps,
1166
- viewport: subViewport,
1167
- view,
1168
- pass,
1169
- layers: options.layers,
1170
- isPicking: options.isPicking
1171
- },
1172
- drawLayerParams
1173
- );
1174
- renderStats.push(stats);
1175
- }
1176
- } finally {
1177
- renderPass.end();
1178
- if (submitEachRenderPass) {
1179
- this.device.submit();
1180
- }
1181
- }
1182
- clearColor = false;
1183
- clearDepth = false;
1184
- clearStencil = false;
1185
- }
1186
- }
1187
- return renderStats;
1188
- } finally {
1189
- if (!submitEachRenderPass) {
1190
- this.device.submit();
1191
- }
1192
- }
1193
- }
1194
- // When a viewport contains multiple subviewports (e.g. repeated web mercator map),
1195
- // this is only done once for the parent viewport
1196
- /* Resolve the parameters needed to draw each layer */
1197
- _getDrawLayerParams(viewport, {
1198
- layers,
1199
- pass,
1200
- isPicking = false,
1201
- layerFilter,
1202
- cullRect,
1203
- views,
1204
- effects,
1205
- canvasContext = this.device.canvasContext,
1206
- shaderModuleProps
1207
- }, evaluateShouldDrawOnly = false) {
1208
- var _a, _b;
1209
- const drawLayerParams = [];
1210
- const indexResolver = layerIndexResolver(this._lastRenderIndex + 1);
1211
- const drawContext = {
1212
- layer: layers[0],
1213
- viewport,
1214
- isPicking,
1215
- renderPass: pass,
1216
- cullRect
1217
- };
1218
- const layerFilterCache = {};
1219
- for (let layerIndex = 0; layerIndex < layers.length; layerIndex++) {
1220
- const layer = layers[layerIndex];
1221
- const shouldDrawLayer = this._shouldDrawLayer(
1222
- layer,
1223
- drawContext,
1224
- layerFilter,
1225
- layerFilterCache
1226
- );
1227
- const layerParam = { shouldDrawLayer };
1228
- if (shouldDrawLayer && !evaluateShouldDrawOnly) {
1229
- layerParam.shouldDrawLayer = true;
1230
- layerParam.layerRenderIndex = indexResolver(layer, shouldDrawLayer);
1231
- layerParam.shaderModuleProps = this._getShaderModuleProps(
1232
- layer,
1233
- effects,
1234
- pass,
1235
- canvasContext,
1236
- shaderModuleProps
1237
- );
1238
- const defaultParams = layer.context.device.type === "webgpu" ? WEBGPU_DEFAULT_DRAW_PARAMETERS : null;
1239
- layerParam.layerParameters = {
1240
- ...defaultParams,
1241
- ...(_a = layer.context.deck) == null ? void 0 : _a.props.parameters,
1242
- ...(_b = views == null ? void 0 : views[viewport.id]) == null ? void 0 : _b.props.parameters,
1243
- ...this.getLayerParameters(layer, layerIndex, viewport)
1244
- };
1245
- }
1246
- drawLayerParams[layerIndex] = layerParam;
1247
- }
1248
- return drawLayerParams;
1249
- }
1250
- // Draws a list of layers in one viewport
1251
- // TODO - when picking we could completely skip rendering viewports that dont
1252
- // intersect with the picking rect
1253
- /* eslint-disable max-depth, max-statements, complexity */
1254
- _drawLayersInViewport(renderPass, {
1255
- layers,
1256
- shaderModuleProps: globalModuleParameters,
1257
- pass,
1258
- target,
1259
- canvasContext,
1260
- viewport,
1261
- view,
1262
- isPicking
1263
- }, drawLayerParams) {
1264
- const glViewport = getGLViewport(this.device, {
1265
- canvasContext,
1266
- shaderModuleProps: globalModuleParameters,
1267
- target,
1268
- viewport
1269
- });
1270
- if (view) {
1271
- const { clear, clearColor, clearDepth, clearStencil } = view.props;
1272
- if (clear) {
1273
- let colorToUse = [0, 0, 0, 0];
1274
- let depthToUse = 1;
1275
- let stencilToUse = 0;
1276
- if (Array.isArray(clearColor) && !isPicking) {
1277
- colorToUse = [...clearColor.slice(0, 3), clearColor[3] || 255].map(
1278
- (c) => c / 255
1279
- );
1280
- } else if (clearColor === false) {
1281
- colorToUse = false;
1282
- }
1283
- if (clearDepth !== void 0) {
1284
- depthToUse = clearDepth;
1285
- }
1286
- if (clearStencil !== void 0) {
1287
- stencilToUse = clearStencil;
1288
- }
1289
- const clearRenderPass = this.device.beginRenderPass({
1290
- framebuffer: target,
1291
- parameters: {
1292
- viewport: glViewport,
1293
- scissorRect: glViewport
1294
- },
1295
- clearColor: colorToUse,
1296
- clearDepth: depthToUse,
1297
- clearStencil: stencilToUse
1298
- });
1299
- clearRenderPass.end();
1300
- }
1301
- }
1302
- const renderStatus = {
1303
- totalCount: layers.length,
1304
- visibleCount: 0,
1305
- compositeCount: 0,
1306
- pickableCount: 0
1307
- };
1308
- renderPass.setParameters({ viewport: glViewport });
1309
- for (let layerIndex = 0; layerIndex < layers.length; layerIndex++) {
1310
- const layer = layers[layerIndex];
1311
- const drawLayerParameters = drawLayerParams[layerIndex];
1312
- const { shouldDrawLayer } = drawLayerParameters;
1313
- if (shouldDrawLayer && layer.props.pickable) {
1314
- renderStatus.pickableCount++;
1315
- }
1316
- if (layer.isComposite) {
1317
- renderStatus.compositeCount++;
1318
- }
1319
- if (layer.isDrawable && drawLayerParameters.shouldDrawLayer) {
1320
- const { layerRenderIndex, shaderModuleProps, layerParameters } = drawLayerParameters;
1321
- renderStatus.visibleCount++;
1322
- this._lastRenderIndex = Math.max(this._lastRenderIndex, layerRenderIndex);
1323
- if (shaderModuleProps.project) {
1324
- shaderModuleProps.project.viewport = viewport;
1325
- }
1326
- layer.context.renderPass = renderPass;
1327
- try {
1328
- layer._drawLayer({
1329
- renderPass,
1330
- shaderModuleProps,
1331
- uniforms: { layerIndex: layerRenderIndex },
1332
- parameters: layerParameters
1333
- });
1334
- } catch (err) {
1335
- layer.raiseError(err, `drawing ${layer} to ${pass}`);
1336
- }
1337
- }
1338
- }
1339
- return renderStatus;
1340
- }
1341
- /* eslint-enable max-depth, max-statements */
1342
- /* Methods for subclass overrides */
1343
- shouldDrawLayer(layer) {
1344
- return true;
1345
- }
1346
- getShaderModuleProps(layer, effects, otherShaderModuleProps) {
1347
- return null;
1348
- }
1349
- getLayerParameters(layer, layerIndex, viewport) {
1350
- return layer.props.parameters;
1351
- }
1352
- /* Private */
1353
- _shouldDrawLayer(layer, drawContext, layerFilter, layerFilterCache) {
1354
- const shouldDrawLayer = layer.props.visible && this.shouldDrawLayer(layer);
1355
- if (!shouldDrawLayer) {
1356
- return false;
1357
- }
1358
- drawContext.layer = layer;
1359
- let parent = layer.parent;
1360
- while (parent) {
1361
- if (!parent.props.visible || !parent.filterSubLayer(drawContext)) {
1362
- return false;
1363
- }
1364
- drawContext.layer = parent;
1365
- parent = parent.parent;
1366
- }
1367
- if (layerFilter) {
1368
- const rootLayerId = drawContext.layer.id;
1369
- if (!(rootLayerId in layerFilterCache)) {
1370
- layerFilterCache[rootLayerId] = layerFilter(drawContext);
1371
- }
1372
- if (!layerFilterCache[rootLayerId]) {
1373
- return false;
1374
- }
1375
- }
1376
- layer.activateViewport(drawContext.viewport);
1377
- return true;
1378
- }
1379
- _getShaderModuleProps(layer, effects, pass, canvasContext, overrides) {
1380
- var _a, _b;
1381
- const devicePixelRatio = canvasContext.cssToDeviceRatio();
1382
- const layerProps = ((_a = layer.internalState) == null ? void 0 : _a.propsInTransition) || layer.props;
1383
- const shaderModuleProps = {
1384
- layer: layerProps,
1385
- picking: {
1386
- isActive: false
1387
- },
1388
- project: {
1389
- viewport: layer.context.viewport,
1390
- devicePixelRatio,
1391
- modelMatrix: layerProps.modelMatrix,
1392
- coordinateSystem: layerProps.coordinateSystem,
1393
- coordinateOrigin: layerProps.coordinateOrigin,
1394
- autoWrapLongitude: layer.wrapLongitude
1395
- }
1396
- };
1397
- if (effects) {
1398
- for (const effect of effects) {
1399
- mergeModuleParameters(
1400
- shaderModuleProps,
1401
- (_b = effect.getShaderModuleProps) == null ? void 0 : _b.call(effect, layer, shaderModuleProps)
1402
- );
1403
- }
1404
- }
1405
- for (const module2 of layer.context.defaultShaderModules) {
1406
- if (!(module2.name in shaderModuleProps)) {
1407
- shaderModuleProps[module2.name] = {};
1408
- }
1409
- }
1410
- return mergeModuleParameters(
1411
- shaderModuleProps,
1412
- this.getShaderModuleProps(layer, effects, shaderModuleProps),
1413
- overrides
1414
- );
1415
- }
1416
- };
1417
- function layerIndexResolver(startIndex = 0, layerIndices = {}) {
1418
- const resolvers = {};
1419
- const resolveLayerIndex = (layer, isDrawn) => {
1420
- const indexOverride = layer.props._offset;
1421
- const layerId = layer.id;
1422
- const parentId = layer.parent && layer.parent.id;
1423
- let index;
1424
- if (parentId && !(parentId in layerIndices)) {
1425
- resolveLayerIndex(layer.parent, false);
1426
- }
1427
- if (parentId in resolvers) {
1428
- const resolver = resolvers[parentId] = resolvers[parentId] || layerIndexResolver(layerIndices[parentId], layerIndices);
1429
- index = resolver(layer, isDrawn);
1430
- resolvers[layerId] = resolver;
1431
- } else if (Number.isFinite(indexOverride)) {
1432
- index = indexOverride + (layerIndices[parentId] || 0);
1433
- resolvers[layerId] = null;
1434
- } else {
1435
- index = startIndex;
1436
- }
1437
- if (isDrawn && index >= startIndex) {
1438
- startIndex = index + 1;
1439
- }
1440
- layerIndices[layerId] = index;
1441
- return index;
1442
- };
1443
- return resolveLayerIndex;
1444
- }
1445
- function getGLViewport(device, {
1446
- canvasContext = device.canvasContext,
1447
- shaderModuleProps,
1448
- target,
1449
- viewport
1450
- }) {
1451
- var _a;
1452
- const pixelRatio = ((_a = shaderModuleProps == null ? void 0 : shaderModuleProps.project) == null ? void 0 : _a.devicePixelRatio) ?? canvasContext.cssToDeviceRatio();
1453
- const [, drawingBufferHeight] = canvasContext.getDrawingBufferSize();
1454
- const height = target ? target.height : drawingBufferHeight;
1455
- const dimensions = viewport;
1456
- return [
1457
- dimensions.x * pixelRatio,
1458
- height - (dimensions.y + dimensions.height) * pixelRatio,
1459
- dimensions.width * pixelRatio,
1460
- dimensions.height * pixelRatio
1461
- ];
1462
- }
1463
- function mergeModuleParameters(target, ...sources) {
1464
- for (const source2 of sources) {
1465
- if (source2) {
1466
- for (const key in source2) {
1467
- if (target[key]) {
1468
- Object.assign(target[key], source2[key]);
1469
- } else {
1470
- target[key] = source2[key];
1471
- }
1472
- }
1473
- }
1474
- }
1475
- return target;
1476
- }
1477
-
1478
- // ../core/src/utils/math-utils.ts
1479
- var import_core2 = require("@math.gl/core");
1480
- function createMat4() {
1481
- return [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1];
1482
- }
1483
- function getCameraPosition(viewMatrixInverse) {
1484
- return [viewMatrixInverse[12], viewMatrixInverse[13], viewMatrixInverse[14]];
1485
- }
1486
- function getFrustumPlanes(viewProjectionMatrix) {
1487
- return {
1488
- left: getFrustumPlane(
1489
- viewProjectionMatrix[3] + viewProjectionMatrix[0],
1490
- viewProjectionMatrix[7] + viewProjectionMatrix[4],
1491
- viewProjectionMatrix[11] + viewProjectionMatrix[8],
1492
- viewProjectionMatrix[15] + viewProjectionMatrix[12]
1493
- ),
1494
- right: getFrustumPlane(
1495
- viewProjectionMatrix[3] - viewProjectionMatrix[0],
1496
- viewProjectionMatrix[7] - viewProjectionMatrix[4],
1497
- viewProjectionMatrix[11] - viewProjectionMatrix[8],
1498
- viewProjectionMatrix[15] - viewProjectionMatrix[12]
1499
- ),
1500
- bottom: getFrustumPlane(
1501
- viewProjectionMatrix[3] + viewProjectionMatrix[1],
1502
- viewProjectionMatrix[7] + viewProjectionMatrix[5],
1503
- viewProjectionMatrix[11] + viewProjectionMatrix[9],
1504
- viewProjectionMatrix[15] + viewProjectionMatrix[13]
1505
- ),
1506
- top: getFrustumPlane(
1507
- viewProjectionMatrix[3] - viewProjectionMatrix[1],
1508
- viewProjectionMatrix[7] - viewProjectionMatrix[5],
1509
- viewProjectionMatrix[11] - viewProjectionMatrix[9],
1510
- viewProjectionMatrix[15] - viewProjectionMatrix[13]
1511
- ),
1512
- near: getFrustumPlane(
1513
- viewProjectionMatrix[3] + viewProjectionMatrix[2],
1514
- viewProjectionMatrix[7] + viewProjectionMatrix[6],
1515
- viewProjectionMatrix[11] + viewProjectionMatrix[10],
1516
- viewProjectionMatrix[15] + viewProjectionMatrix[14]
1517
- ),
1518
- far: getFrustumPlane(
1519
- viewProjectionMatrix[3] - viewProjectionMatrix[2],
1520
- viewProjectionMatrix[7] - viewProjectionMatrix[6],
1521
- viewProjectionMatrix[11] - viewProjectionMatrix[10],
1522
- viewProjectionMatrix[15] - viewProjectionMatrix[14]
1523
- )
1524
- };
1525
- }
1526
- var scratchVector = new import_core2.Vector3();
1527
- function getFrustumPlane(a, b, c, d) {
1528
- scratchVector.set(a, b, c);
1529
- const L = scratchVector.len();
1530
- return { distance: d / L, normal: new import_core2.Vector3(-a / L, -b / L, -c / L) };
1531
- }
1532
- function fp64LowPart(x) {
1533
- return x - Math.fround(x);
1534
- }
1535
-
1536
- // ../core/src/viewports/viewport.ts
1537
- var import_core3 = require("@math.gl/core");
1538
- var import_web_mercator = require("@math.gl/web-mercator");
1539
- var DEGREES_TO_RADIANS = Math.PI / 180;
1540
- var IDENTITY = createMat4();
1541
- var ZERO_VECTOR2 = [0, 0, 0];
1542
- var DEFAULT_DISTANCE_SCALES = {
1543
- unitsPerMeter: [1, 1, 1],
1544
- metersPerUnit: [1, 1, 1]
1545
- };
1546
- function createProjectionMatrix({
1547
- width,
1548
- height,
1549
- orthographic,
1550
- fovyRadians,
1551
- focalDistance,
1552
- padding,
1553
- near,
1554
- far
1555
- }) {
1556
- const aspect = width / height;
1557
- const matrix = orthographic ? new import_core3.Matrix4().orthographic({ fovy: fovyRadians, aspect, focalDistance, near, far }) : new import_core3.Matrix4().perspective({ fovy: fovyRadians, aspect, near, far });
1558
- if (padding) {
1559
- const { left = 0, right = 0, top = 0, bottom = 0 } = padding;
1560
- const offsetX = (0, import_core3.clamp)((left + width - right) / 2, 0, width) - width / 2;
1561
- const offsetY = (0, import_core3.clamp)((top + height - bottom) / 2, 0, height) - height / 2;
1562
- matrix[8] -= offsetX * 2 / width;
1563
- matrix[9] += offsetY * 2 / height;
1564
- }
1565
- return matrix;
1566
- }
1567
- var _Viewport = class _Viewport {
1568
- // eslint-disable-next-line complexity
1569
- constructor(opts = {}) {
1570
- this._frustumPlanes = {};
1571
- this.id = opts.id || this.constructor.displayName || "viewport";
1572
- this.x = opts.x || 0;
1573
- this.y = opts.y || 0;
1574
- this.width = opts.width || 1;
1575
- this.height = opts.height || 1;
1576
- this.zoom = opts.zoom || 0;
1577
- this.padding = opts.padding;
1578
- this.distanceScales = opts.distanceScales || DEFAULT_DISTANCE_SCALES;
1579
- this.focalDistance = opts.focalDistance || 1;
1580
- this.position = opts.position || ZERO_VECTOR2;
1581
- this.modelMatrix = opts.modelMatrix || null;
1582
- const { longitude, latitude } = opts;
1583
- this.isGeospatial = Number.isFinite(latitude) && Number.isFinite(longitude);
1584
- this._initProps(opts);
1585
- this._initMatrices(opts);
1586
- this.equals = this.equals.bind(this);
1587
- this.project = this.project.bind(this);
1588
- this.unproject = this.unproject.bind(this);
1589
- this.projectPosition = this.projectPosition.bind(this);
1590
- this.unprojectPosition = this.unprojectPosition.bind(this);
1591
- this.projectFlat = this.projectFlat.bind(this);
1592
- this.unprojectFlat = this.unprojectFlat.bind(this);
1593
- }
1594
- get subViewports() {
1595
- return null;
1596
- }
1597
- get metersPerPixel() {
1598
- return this.distanceScales.metersPerUnit[2] / this.scale;
1599
- }
1600
- get projectionMode() {
1601
- if (this.isGeospatial) {
1602
- return this.zoom < 12 ? PROJECTION_MODE.WEB_MERCATOR : PROJECTION_MODE.WEB_MERCATOR_AUTO_OFFSET;
1603
- }
1604
- return PROJECTION_MODE.IDENTITY;
1605
- }
1606
- // Two viewports are equal if width and height are identical, and if
1607
- // their view and projection matrices are (approximately) equal.
1608
- equals(viewport) {
1609
- if (!(viewport instanceof _Viewport)) {
1610
- return false;
1611
- }
1612
- if (this === viewport) {
1613
- return true;
1614
- }
1615
- return viewport.width === this.width && viewport.height === this.height && viewport.scale === this.scale && (0, import_core3.equals)(viewport.projectionMatrix, this.projectionMatrix) && (0, import_core3.equals)(viewport.viewMatrix, this.viewMatrix);
1616
- }
1617
- /**
1618
- * Projects xyz (possibly latitude and longitude) to pixel coordinates in window
1619
- * using viewport projection parameters
1620
- * - [longitude, latitude] to [x, y]
1621
- * - [longitude, latitude, Z] => [x, y, z]
1622
- * Note: By default, returns top-left coordinates for canvas/SVG type render
1623
- *
1624
- * @param {Array} lngLatZ - [lng, lat] or [lng, lat, Z]
1625
- * @param {Object} opts - options
1626
- * @param {Object} opts.topLeft=true - Whether projected coords are top left
1627
- * @return {Array} - [x, y] or [x, y, z] in top left coords
1628
- */
1629
- project(xyz, { topLeft = true } = {}) {
1630
- const worldPosition = this.projectPosition(xyz);
1631
- const coord = (0, import_web_mercator.worldToPixels)(worldPosition, this.pixelProjectionMatrix);
1632
- const [x, y] = coord;
1633
- const y2 = topLeft ? y : this.height - y;
1634
- return xyz.length === 2 ? [x, y2] : [x, y2, coord[2]];
1635
- }
1636
- /**
1637
- * Unproject pixel coordinates on screen onto world coordinates,
1638
- * (possibly [lon, lat]) on map.
1639
- * - [x, y] => [lng, lat]
1640
- * - [x, y, z] => [lng, lat, Z]
1641
- * @param {Array} xyz -
1642
- * @param {Object} opts - options
1643
- * @param {Object} opts.topLeft=true - Whether origin is top left
1644
- * @return {Array|null} - [lng, lat, Z] or [X, Y, Z]
1645
- */
1646
- unproject(xyz, { topLeft = true, targetZ } = {}) {
1647
- const [x, y, z] = xyz;
1648
- const y2 = topLeft ? y : this.height - y;
1649
- const targetZWorld = targetZ && targetZ * this.distanceScales.unitsPerMeter[2];
1650
- const coord = (0, import_web_mercator.pixelsToWorld)([x, y2, z], this.pixelUnprojectionMatrix, targetZWorld);
1651
- const [X, Y, Z] = this.unprojectPosition(coord);
1652
- if (Number.isFinite(z)) {
1653
- return [X, Y, Z];
1654
- }
1655
- return Number.isFinite(targetZ) ? [X, Y, targetZ] : [X, Y];
1656
- }
1657
- // NON_LINEAR PROJECTION HOOKS
1658
- // Used for web meractor projection
1659
- projectPosition(xyz) {
1660
- const [X, Y] = this.projectFlat(xyz);
1661
- const Z = (xyz[2] || 0) * this.distanceScales.unitsPerMeter[2];
1662
- return [X, Y, Z];
1663
- }
1664
- unprojectPosition(xyz) {
1665
- const [X, Y] = this.unprojectFlat(xyz);
1666
- const Z = (xyz[2] || 0) * this.distanceScales.metersPerUnit[2];
1667
- return [X, Y, Z];
1668
- }
1669
- /**
1670
- * Project [lng,lat] on sphere onto [x,y] on 512*512 Mercator Zoom 0 tile.
1671
- * Performs the nonlinear part of the web mercator projection.
1672
- * Remaining projection is done with 4x4 matrices which also handles
1673
- * perspective.
1674
- * @param {Array} lngLat - [lng, lat] coordinates
1675
- * Specifies a point on the sphere to project onto the map.
1676
- * @return {Array} [x,y] coordinates.
1677
- */
1678
- projectFlat(xyz) {
1679
- if (this.isGeospatial) {
1680
- const result = (0, import_web_mercator.lngLatToWorld)(xyz);
1681
- result[1] = (0, import_core3.clamp)(result[1], -318, 830);
1682
- return result;
1683
- }
1684
- return xyz;
1685
- }
1686
- /**
1687
- * Unproject world point [x,y] on map onto {lat, lon} on sphere
1688
- * @param {object|Vector} xy - object with {x,y} members
1689
- * representing point on projected map plane
1690
- * @return {GeoCoordinates} - object with {lat,lon} of point on sphere.
1691
- * Has toArray method if you need a GeoJSON Array.
1692
- * Per cartographic tradition, lat and lon are specified as degrees.
1693
- */
1694
- unprojectFlat(xyz) {
1695
- if (this.isGeospatial) {
1696
- return (0, import_web_mercator.worldToLngLat)(xyz);
1697
- }
1698
- return xyz;
1699
- }
1700
- /**
1701
- * Get bounds of the current viewport
1702
- * @return {Array} - [minX, minY, maxX, maxY]
1703
- */
1704
- getBounds(options = {}) {
1705
- const unprojectOption = { targetZ: options.z || 0 };
1706
- const topLeft = this.unproject([0, 0], unprojectOption);
1707
- const topRight = this.unproject([this.width, 0], unprojectOption);
1708
- const bottomLeft = this.unproject([0, this.height], unprojectOption);
1709
- const bottomRight = this.unproject([this.width, this.height], unprojectOption);
1710
- return [
1711
- Math.min(topLeft[0], topRight[0], bottomLeft[0], bottomRight[0]),
1712
- Math.min(topLeft[1], topRight[1], bottomLeft[1], bottomRight[1]),
1713
- Math.max(topLeft[0], topRight[0], bottomLeft[0], bottomRight[0]),
1714
- Math.max(topLeft[1], topRight[1], bottomLeft[1], bottomRight[1])
1715
- ];
1716
- }
1717
- getDistanceScales(coordinateOrigin) {
1718
- if (coordinateOrigin && this.isGeospatial) {
1719
- return (0, import_web_mercator.getDistanceScales)({
1720
- longitude: coordinateOrigin[0],
1721
- latitude: coordinateOrigin[1],
1722
- highPrecision: true
1723
- });
1724
- }
1725
- return this.distanceScales;
1726
- }
1727
- containsPixel({
1728
- x,
1729
- y,
1730
- width = 1,
1731
- height = 1
1732
- }) {
1733
- return x < this.x + this.width && this.x < x + width && y < this.y + this.height && this.y < y + height;
1734
- }
1735
- // Extract frustum planes in common space
1736
- getFrustumPlanes() {
1737
- if (this._frustumPlanes.near) {
1738
- return this._frustumPlanes;
1739
- }
1740
- Object.assign(this._frustumPlanes, getFrustumPlanes(this.viewProjectionMatrix));
1741
- return this._frustumPlanes;
1742
- }
1743
- // EXPERIMENTAL METHODS
1744
- /**
1745
- * Needed by panning and linear transition
1746
- * Pan the viewport to place a given world coordinate at screen point [x, y]
1747
- *
1748
- * @param {Array} coords - world coordinates
1749
- * @param {Array} pixel - [x,y] coordinates on screen
1750
- * @param {Array} startPixel - [x,y] screen position where pan started (optional, for delta-based panning)
1751
- * @return {Object} props of the new viewport
1752
- */
1753
- panByPosition(coords, pixel, startPixel) {
1754
- return null;
1755
- }
1756
- // INTERNAL METHODS
1757
- /* eslint-disable complexity, max-statements */
1758
- _initProps(opts) {
1759
- const longitude = opts.longitude;
1760
- const latitude = opts.latitude;
1761
- if (this.isGeospatial) {
1762
- if (!Number.isFinite(opts.zoom)) {
1763
- this.zoom = (0, import_web_mercator.getMeterZoom)({ latitude }) + Math.log2(this.focalDistance);
1764
- }
1765
- this.distanceScales = opts.distanceScales || (0, import_web_mercator.getDistanceScales)({ latitude, longitude });
1766
- }
1767
- const scale = Math.pow(2, this.zoom);
1768
- this.scale = scale;
1769
- const { position, modelMatrix } = opts;
1770
- let meterOffset = ZERO_VECTOR2;
1771
- if (position) {
1772
- meterOffset = modelMatrix ? new import_core3.Matrix4(modelMatrix).transformAsVector(position, []) : position;
1773
- }
1774
- if (this.isGeospatial) {
1775
- const center = this.projectPosition([longitude, latitude, 0]);
1776
- this.center = new import_core3.Vector3(meterOffset).scale(this.distanceScales.unitsPerMeter).add(center);
1777
- } else {
1778
- this.center = this.projectPosition(meterOffset);
1779
- }
1780
- }
1781
- /* eslint-enable complexity, max-statements */
1782
- _initMatrices(opts) {
1783
- const {
1784
- // View matrix
1785
- viewMatrix: viewMatrix2 = IDENTITY,
1786
- // Projection matrix
1787
- projectionMatrix = null,
1788
- // Projection matrix parameters, used if projectionMatrix not supplied
1789
- orthographic = false,
1790
- fovyRadians,
1791
- fovy = 75,
1792
- near = 0.1,
1793
- // Distance of near clipping plane
1794
- far = 1e3,
1795
- // Distance of far clipping plane
1796
- padding = null,
1797
- // Center offset in pixels
1798
- focalDistance = 1
1799
- } = opts;
1800
- this.viewMatrixUncentered = viewMatrix2;
1801
- this.viewMatrix = new import_core3.Matrix4().multiplyRight(viewMatrix2).translate(new import_core3.Vector3(this.center).negate());
1802
- this.projectionMatrix = projectionMatrix || createProjectionMatrix({
1803
- width: this.width,
1804
- height: this.height,
1805
- orthographic,
1806
- fovyRadians: fovyRadians || fovy * DEGREES_TO_RADIANS,
1807
- focalDistance,
1808
- padding,
1809
- near,
1810
- far
1811
- });
1812
- const vpm = createMat4();
1813
- import_core3.mat4.multiply(vpm, vpm, this.projectionMatrix);
1814
- import_core3.mat4.multiply(vpm, vpm, this.viewMatrix);
1815
- this.viewProjectionMatrix = vpm;
1816
- this.viewMatrixInverse = import_core3.mat4.invert([], this.viewMatrix) || this.viewMatrix;
1817
- this.cameraPosition = getCameraPosition(this.viewMatrixInverse);
1818
- const viewportMatrix = createMat4();
1819
- const pixelProjectionMatrix = createMat4();
1820
- import_core3.mat4.scale(viewportMatrix, viewportMatrix, [this.width / 2, -this.height / 2, 1]);
1821
- import_core3.mat4.translate(viewportMatrix, viewportMatrix, [1, -1, 0]);
1822
- import_core3.mat4.multiply(pixelProjectionMatrix, viewportMatrix, this.viewProjectionMatrix);
1823
- this.pixelProjectionMatrix = pixelProjectionMatrix;
1824
- this.pixelUnprojectionMatrix = import_core3.mat4.invert(createMat4(), this.pixelProjectionMatrix);
1825
- if (!this.pixelUnprojectionMatrix) {
1826
- log_default.warn("Pixel project matrix not invertible")();
1827
- }
1828
- }
1829
- };
1830
- _Viewport.displayName = "Viewport";
1831
- var Viewport = _Viewport;
1832
-
1833
- // ../core/src/viewports/web-mercator-viewport.ts
1834
- var import_web_mercator2 = require("@math.gl/web-mercator");
1835
- var import_core4 = require("@math.gl/core");
1836
- var _WebMercatorViewport = class _WebMercatorViewport extends Viewport {
1837
- /* eslint-disable complexity, max-statements */
1838
- constructor(opts = {}) {
1839
- const {
1840
- latitude = 0,
1841
- longitude = 0,
1842
- zoom = 0,
1843
- pitch = 0,
1844
- bearing = 0,
1845
- nearZMultiplier = 0.1,
1846
- farZMultiplier = 1.01,
1847
- nearZ,
1848
- farZ,
1849
- orthographic = false,
1850
- projectionMatrix,
1851
- repeat = false,
1852
- worldOffset = 0,
1853
- position,
1854
- padding,
1855
- // backward compatibility
1856
- // TODO: remove in v9
1857
- legacyMeterSizes = false
1858
- } = opts;
1859
- let { width, height, altitude = 1.5 } = opts;
1860
- const scale = Math.pow(2, zoom);
1861
- width = width || 1;
1862
- height = height || 1;
1863
- let fovy;
1864
- let projectionParameters = null;
1865
- if (projectionMatrix) {
1866
- altitude = projectionMatrix[5] / 2;
1867
- fovy = (0, import_web_mercator2.altitudeToFovy)(altitude);
1868
- } else {
1869
- if (opts.fovy) {
1870
- fovy = opts.fovy;
1871
- altitude = (0, import_web_mercator2.fovyToAltitude)(fovy);
1872
- } else {
1873
- fovy = (0, import_web_mercator2.altitudeToFovy)(altitude);
1874
- }
1875
- let offset;
1876
- if (padding) {
1877
- const { top = 0, bottom = 0 } = padding;
1878
- offset = [0, (0, import_core4.clamp)((top + height - bottom) / 2, 0, height) - height / 2];
1879
- }
1880
- projectionParameters = (0, import_web_mercator2.getProjectionParameters)({
1881
- width,
1882
- height,
1883
- scale,
1884
- center: position && [0, 0, position[2] * (0, import_web_mercator2.unitsPerMeter)(latitude)],
1885
- offset,
1886
- pitch,
1887
- fovy,
1888
- nearZMultiplier,
1889
- farZMultiplier
1890
- });
1891
- if (Number.isFinite(nearZ)) {
1892
- projectionParameters.near = nearZ;
1893
- }
1894
- if (Number.isFinite(farZ)) {
1895
- projectionParameters.far = farZ;
1896
- }
1897
- }
1898
- let viewMatrixUncentered = (0, import_web_mercator2.getViewMatrix)({
1899
- height,
1900
- pitch,
1901
- bearing,
1902
- scale,
1903
- altitude
1904
- });
1905
- if (worldOffset) {
1906
- const viewOffset = new import_core4.Matrix4().translate([512 * worldOffset, 0, 0]);
1907
- viewMatrixUncentered = viewOffset.multiplyLeft(viewMatrixUncentered);
1908
- }
1909
- super({
1910
- ...opts,
1911
- // x, y,
1912
- width,
1913
- height,
1914
- // view matrix
1915
- viewMatrix: viewMatrixUncentered,
1916
- longitude,
1917
- latitude,
1918
- zoom,
1919
- // projection matrix parameters
1920
- ...projectionParameters,
1921
- fovy,
1922
- focalDistance: altitude
1923
- });
1924
- this.latitude = latitude;
1925
- this.longitude = longitude;
1926
- this.zoom = zoom;
1927
- this.pitch = pitch;
1928
- this.bearing = bearing;
1929
- this.altitude = altitude;
1930
- this.fovy = fovy;
1931
- this.orthographic = orthographic;
1932
- this._subViewports = repeat ? [] : null;
1933
- this._pseudoMeters = legacyMeterSizes;
1934
- Object.freeze(this);
1935
- }
1936
- /* eslint-enable complexity, max-statements */
1937
- get subViewports() {
1938
- if (this._subViewports && !this._subViewports.length) {
1939
- const bounds = this.getBounds();
1940
- const minOffset = Math.floor((bounds[0] + 180) / 360);
1941
- const maxOffset = Math.ceil((bounds[2] - 180) / 360);
1942
- for (let x = minOffset; x <= maxOffset; x++) {
1943
- const offsetViewport = x ? new _WebMercatorViewport({
1944
- ...this,
1945
- worldOffset: x
1946
- }) : this;
1947
- this._subViewports.push(offsetViewport);
1948
- }
1949
- }
1950
- return this._subViewports;
1951
- }
1952
- projectPosition(xyz) {
1953
- if (this._pseudoMeters) {
1954
- return super.projectPosition(xyz);
1955
- }
1956
- const [X, Y] = this.projectFlat(xyz);
1957
- const Z = (xyz[2] || 0) * (0, import_web_mercator2.unitsPerMeter)(xyz[1]);
1958
- return [X, Y, Z];
1959
- }
1960
- unprojectPosition(xyz) {
1961
- if (this._pseudoMeters) {
1962
- return super.unprojectPosition(xyz);
1963
- }
1964
- const [X, Y] = this.unprojectFlat(xyz);
1965
- const Z = (xyz[2] || 0) / (0, import_web_mercator2.unitsPerMeter)(Y);
1966
- return [X, Y, Z];
1967
- }
1968
- /**
1969
- * Add a meter delta to a base lnglat coordinate, returning a new lnglat array
1970
- *
1971
- * Note: Uses simple linear approximation around the viewport center
1972
- * Error increases with size of offset (roughly 1% per 100km)
1973
- *
1974
- * @param {[Number,Number]|[Number,Number,Number]) lngLatZ - base coordinate
1975
- * @param {[Number,Number]|[Number,Number,Number]) xyz - array of meter deltas
1976
- * @return {[Number,Number]|[Number,Number,Number]) array of [lng,lat,z] deltas
1977
- */
1978
- addMetersToLngLat(lngLatZ, xyz) {
1979
- return (0, import_web_mercator2.addMetersToLngLat)(lngLatZ, xyz);
1980
- }
1981
- panByPosition(coords, pixel, startPixel) {
1982
- const fromLocation = (0, import_web_mercator2.pixelsToWorld)(pixel, this.pixelUnprojectionMatrix);
1983
- const toLocation = this.projectFlat(coords);
1984
- const translate = import_core4.vec2.add([], toLocation, import_core4.vec2.negate([], fromLocation));
1985
- const newCenter = import_core4.vec2.add([], this.center, translate);
1986
- const [longitude, latitude] = this.unprojectFlat(newCenter);
1987
- return { longitude, latitude };
1988
- }
1989
- /**
1990
- * Returns a new longitude and latitude that keeps a 3D world coordinate at a given screen pixel
1991
- * This version handles the z-component (altitude) properly for cameras positioned above ground
1992
- */
1993
- panByPosition3D(coords, pixel) {
1994
- const targetZ = coords[2] || 0;
1995
- const deltaLngLat = import_core4.vec2.sub([], coords, this.unproject(pixel, { targetZ }));
1996
- return { longitude: this.longitude + deltaLngLat[0], latitude: this.latitude + deltaLngLat[1] };
1997
- }
1998
- getBounds(options = {}) {
1999
- const corners = (0, import_web_mercator2.getBounds)(this, options.z || 0);
2000
- return [
2001
- Math.min(corners[0][0], corners[1][0], corners[2][0], corners[3][0]),
2002
- Math.min(corners[0][1], corners[1][1], corners[2][1], corners[3][1]),
2003
- Math.max(corners[0][0], corners[1][0], corners[2][0], corners[3][0]),
2004
- Math.max(corners[0][1], corners[1][1], corners[2][1], corners[3][1])
2005
- ];
2006
- }
2007
- /**
2008
- * Returns a new viewport that fit around the given rectangle.
2009
- * Only supports non-perspective mode.
2010
- */
2011
- fitBounds(bounds, options = {}) {
2012
- const { width, height } = this;
2013
- const { longitude, latitude, zoom } = (0, import_web_mercator2.fitBounds)({ width, height, bounds, ...options });
2014
- return new _WebMercatorViewport({ width, height, longitude, latitude, zoom });
2015
- }
2016
- };
2017
- _WebMercatorViewport.displayName = "WebMercatorViewport";
2018
- var WebMercatorViewport = _WebMercatorViewport;
2019
-
2020
- // ../core/src/passes/pick-layers-pass.ts
2021
- var PICKING_BLENDING = {
2022
- blendColorOperation: "add",
2023
- blendColorSrcFactor: "one",
2024
- blendColorDstFactor: "zero",
2025
- blendAlphaOperation: "add",
2026
- blendAlphaSrcFactor: "constant",
2027
- blendAlphaDstFactor: "zero"
2028
- };
2029
- var PickLayersPass = class extends LayersPass {
2030
- constructor() {
2031
- super(...arguments);
2032
- this._colorEncoderState = null;
2033
- }
2034
- render(props) {
2035
- if ("pickingFBO" in props) {
2036
- return this._drawPickingBuffer(props);
2037
- }
2038
- const stats = super._render(props);
2039
- return { decodePickingColor: null, stats };
2040
- }
2041
- // Private
2042
- // Draws list of layers and viewports into the picking buffer
2043
- // Note: does not sample the buffer, that has to be done by the caller
2044
- _drawPickingBuffer({
2045
- layers,
2046
- layerFilter,
2047
- views,
2048
- viewports,
2049
- onViewportActive,
2050
- pickingFBO,
2051
- deviceRect: { x, y, width, height },
2052
- cullRect,
2053
- effects,
2054
- pass = "picking",
2055
- pickZ,
2056
- canvasContext,
2057
- shaderModuleProps,
2058
- clearColor
2059
- }) {
2060
- this.pickZ = pickZ;
2061
- const colorEncoderState = this._resetColorEncoder(pickZ);
2062
- const scissorRect = [x, y, width, height];
2063
- const renderStatus = super._render({
2064
- target: pickingFBO,
2065
- layers,
2066
- layerFilter,
2067
- views,
2068
- viewports,
2069
- onViewportActive,
2070
- cullRect,
2071
- effects: effects == null ? void 0 : effects.filter((e) => e.useInPicking),
2072
- pass,
2073
- canvasContext,
2074
- isPicking: true,
2075
- shaderModuleProps,
2076
- clearColor: clearColor ?? [0, 0, 0, 0],
2077
- colorMask: 15,
2078
- scissorRect
2079
- });
2080
- this._colorEncoderState = null;
2081
- const decodePickingColor = colorEncoderState && decodeColor.bind(null, colorEncoderState);
2082
- return { decodePickingColor, stats: renderStatus };
2083
- }
2084
- shouldDrawLayer(layer) {
2085
- const { pickable, operation } = layer.props;
2086
- return pickable && operation.includes("draw") || operation.includes("terrain") || operation.includes("mask");
2087
- }
2088
- getShaderModuleProps(layer, effects, otherShaderModuleProps) {
2089
- var _a;
2090
- return {
2091
- picking: {
2092
- isActive: 1,
2093
- isAttribute: this.pickZ,
2094
- disabledPickingIndices: (_a = layer.internalState) == null ? void 0 : _a.disabledPickingIndices
2095
- },
2096
- lighting: { enabled: false }
2097
- };
2098
- }
2099
- getLayerParameters(layer, layerIndex, viewport) {
2100
- var _a;
2101
- const pickParameters = {
2102
- ...layer.props.parameters
2103
- };
2104
- const { pickable, operation } = layer.props;
2105
- if (!this._colorEncoderState) {
2106
- pickParameters.blend = false;
2107
- } else if (pickable && operation.includes("draw")) {
2108
- Object.assign(pickParameters, PICKING_BLENDING);
2109
- pickParameters.blend = true;
2110
- if (this.device.type === "webgpu") {
2111
- pickParameters.blendConstant = encodeColor(this._colorEncoderState, layer, viewport);
2112
- } else {
2113
- pickParameters.blendColor = encodeColor(this._colorEncoderState, layer, viewport);
2114
- }
2115
- if (operation.includes("terrain") && ((_a = layer.state) == null ? void 0 : _a._hasPickingCover)) {
2116
- pickParameters.blendAlphaSrcFactor = "one";
2117
- }
2118
- } else if (operation.includes("terrain")) {
2119
- pickParameters.blend = false;
2120
- }
2121
- return pickParameters;
2122
- }
2123
- _resetColorEncoder(pickZ) {
2124
- this._colorEncoderState = pickZ ? null : {
2125
- byLayer: /* @__PURE__ */ new Map(),
2126
- byAlpha: []
2127
- };
2128
- return this._colorEncoderState;
2129
- }
2130
- };
2131
- function encodeColor(encoded, layer, viewport) {
2132
- const { byLayer, byAlpha } = encoded;
2133
- let a;
2134
- let entry = byLayer.get(layer);
2135
- if (entry) {
2136
- entry.viewports.push(viewport);
2137
- a = entry.a;
2138
- } else {
2139
- a = byLayer.size + 1;
2140
- if (a <= 255) {
2141
- entry = { a, layer, viewports: [viewport] };
2142
- byLayer.set(layer, entry);
2143
- byAlpha[a] = entry;
2144
- } else {
2145
- log_default.warn("Too many pickable layers, only picking the first 255")();
2146
- a = 0;
2147
- }
2148
- }
2149
- return [0, 0, 0, a / 255];
2150
- }
2151
- function decodeColor(encoded, pickedColor) {
2152
- const entry = encoded.byAlpha[pickedColor[3]];
2153
- return entry && {
2154
- pickedLayer: entry.layer,
2155
- pickedViewports: entry.viewports,
2156
- pickedObjectIndex: entry.layer.decodePickingColor(pickedColor)
2157
- };
2158
- }
2159
-
2160
- // ../core/src/utils/deep-equal.ts
2161
- function deepEqual(a, b, depth) {
2162
- if (a === b) {
2163
- return true;
2164
- }
2165
- if (!depth || !a || !b) {
2166
- return false;
2167
- }
2168
- if (Array.isArray(a)) {
2169
- if (!Array.isArray(b) || a.length !== b.length) {
2170
- return false;
2171
- }
2172
- for (let i = 0; i < a.length; i++) {
2173
- if (!deepEqual(a[i], b[i], depth - 1)) {
2174
- return false;
2175
- }
2176
- }
2177
- return true;
2178
- }
2179
- if (Array.isArray(b)) {
2180
- return false;
2181
- }
2182
- if (typeof a === "object" && typeof b === "object") {
2183
- const aKeys = Object.keys(a);
2184
- const bKeys = Object.keys(b);
2185
- if (aKeys.length !== bKeys.length) {
2186
- return false;
2187
- }
2188
- for (const key of aKeys) {
2189
- if (!b.hasOwnProperty(key)) {
2190
- return false;
2191
- }
2192
- if (!deepEqual(a[key], b[key], depth - 1)) {
2193
- return false;
2194
- }
2195
- }
2196
- return true;
2197
- }
2198
- return false;
2199
- }
2200
-
2201
- // ../core/src/viewports/globe-viewport.ts
2202
- var import_core5 = require("@math.gl/core");
2203
- var import_web_mercator3 = require("@math.gl/web-mercator");
2204
- var import_core6 = require("@math.gl/core");
2205
- var import_web_mercator4 = require("@math.gl/web-mercator");
2206
- var DEGREES_TO_RADIANS2 = Math.PI / 180;
2207
- var RADIANS_TO_DEGREES = 180 / Math.PI;
2208
- var EARTH_RADIUS = 6370972;
2209
- var GLOBE_RADIUS = 256;
2210
- function getDistanceScales2() {
2211
- const unitsPerMeter2 = GLOBE_RADIUS / EARTH_RADIUS;
2212
- const unitsPerDegree = Math.PI / 180 * GLOBE_RADIUS;
2213
- return {
2214
- unitsPerMeter: [unitsPerMeter2, unitsPerMeter2, unitsPerMeter2],
2215
- unitsPerMeter2: [0, 0, 0],
2216
- metersPerUnit: [1 / unitsPerMeter2, 1 / unitsPerMeter2, 1 / unitsPerMeter2],
2217
- unitsPerDegree: [unitsPerDegree, unitsPerDegree, unitsPerMeter2],
2218
- unitsPerDegree2: [0, 0, 0],
2219
- degreesPerUnit: [1 / unitsPerDegree, 1 / unitsPerDegree, 1 / unitsPerMeter2]
2220
- };
2221
- }
2222
- var GlobeViewport = class extends Viewport {
2223
- constructor(opts = {}) {
2224
- const {
2225
- longitude = 0,
2226
- bearing = 0,
2227
- pitch = 0,
2228
- zoom = 0,
2229
- // Matches Maplibre defaults
2230
- // https://github.com/maplibre/maplibre-gl-js/blob/f8ab4b48d59ab8fe7b068b102538793bbdd4c848/src/geo/projection/globe_transform.ts#L632-L633
2231
- nearZMultiplier = 0.5,
2232
- farZMultiplier = 1,
2233
- resolution = 10
2234
- } = opts;
2235
- let { latitude = 0, height, altitude = 1.5, fovy } = opts;
2236
- latitude = Math.max(Math.min(latitude, 90), -90);
2237
- height = height || 1;
2238
- if (fovy) {
2239
- altitude = (0, import_web_mercator3.fovyToAltitude)(fovy);
2240
- } else {
2241
- fovy = (0, import_web_mercator3.altitudeToFovy)(altitude);
2242
- }
2243
- const scaleLatitude = Math.max(Math.min(latitude, import_web_mercator4.MAX_LATITUDE), -import_web_mercator4.MAX_LATITUDE);
2244
- const scale = Math.pow(2, zoom - zoomAdjust(scaleLatitude));
2245
- const pitchRadians = pitch * DEGREES_TO_RADIANS2;
2246
- const nearZ = opts.nearZ ?? nearZMultiplier;
2247
- const farZ = opts.farZ ?? (altitude + GLOBE_RADIUS * 2 * scale / height / Math.max(Math.cos(pitchRadians), 0.1)) * farZMultiplier;
2248
- const viewMatrix2 = new import_core5.Matrix4().lookAt({ eye: [0, -altitude, 0], up: [0, 0, 1] }).rotateX(-pitchRadians).rotateY(-bearing * DEGREES_TO_RADIANS2).rotateX(latitude * DEGREES_TO_RADIANS2).rotateZ(-longitude * DEGREES_TO_RADIANS2).scale(scale / height);
2249
- super({
2250
- ...opts,
2251
- // x, y, width,
2252
- height,
2253
- // view matrix
2254
- viewMatrix: viewMatrix2,
2255
- longitude,
2256
- latitude,
2257
- zoom,
2258
- // projection matrix parameters
2259
- distanceScales: getDistanceScales2(),
2260
- fovy,
2261
- focalDistance: altitude,
2262
- near: nearZ,
2263
- far: farZ
2264
- });
2265
- this.scale = scale;
2266
- this.latitude = latitude;
2267
- this.longitude = longitude;
2268
- this.bearing = bearing;
2269
- this.pitch = pitch;
2270
- this.fovy = fovy;
2271
- this.resolution = resolution;
2272
- }
2273
- get projectionMode() {
2274
- return PROJECTION_MODE.GLOBE;
2275
- }
2276
- getDistanceScales() {
2277
- return this.distanceScales;
2278
- }
2279
- getBounds(options = {}) {
2280
- const unprojectOption = { targetZ: options.z || 0 };
2281
- const left = this.unproject([0, this.height / 2], unprojectOption);
2282
- const top = this.unproject([this.width / 2, 0], unprojectOption);
2283
- const right = this.unproject([this.width, this.height / 2], unprojectOption);
2284
- const bottom = this.unproject([this.width / 2, this.height], unprojectOption);
2285
- if (right[0] < this.longitude) right[0] += 360;
2286
- if (left[0] > this.longitude) left[0] -= 360;
2287
- return [
2288
- Math.min(left[0], right[0], top[0], bottom[0]),
2289
- Math.min(left[1], right[1], top[1], bottom[1]),
2290
- Math.max(left[0], right[0], top[0], bottom[0]),
2291
- Math.max(left[1], right[1], top[1], bottom[1])
2292
- ];
2293
- }
2294
- unproject(xyz, { topLeft = true, targetZ } = {}) {
2295
- const [x, y, z] = xyz;
2296
- const y2 = topLeft ? y : this.height - y;
2297
- const { pixelUnprojectionMatrix } = this;
2298
- let coord;
2299
- if (Number.isFinite(z)) {
2300
- coord = transformVector(pixelUnprojectionMatrix, [x, y2, z, 1]);
2301
- } else {
2302
- const coord0 = transformVector(pixelUnprojectionMatrix, [x, y2, -1, 1]);
2303
- const coord1 = transformVector(pixelUnprojectionMatrix, [x, y2, 1, 1]);
2304
- const lt = ((targetZ || 0) / EARTH_RADIUS + 1) * GLOBE_RADIUS;
2305
- const lSqr = import_core6.vec3.sqrLen(import_core6.vec3.sub([], coord0, coord1));
2306
- const l0Sqr = import_core6.vec3.sqrLen(coord0);
2307
- const l1Sqr = import_core6.vec3.sqrLen(coord1);
2308
- const sSqr = (4 * l0Sqr * l1Sqr - (lSqr - l0Sqr - l1Sqr) ** 2) / 16;
2309
- const dSqr = 4 * sSqr / lSqr;
2310
- const r0 = Math.sqrt(l0Sqr - dSqr);
2311
- const dr = Math.sqrt(Math.max(0, lt * lt - dSqr));
2312
- const t = (r0 - dr) / Math.sqrt(lSqr);
2313
- coord = import_core6.vec3.lerp([], coord0, coord1, t);
2314
- }
2315
- const [X, Y, Z] = this.unprojectPosition(coord);
2316
- if (Number.isFinite(z)) {
2317
- return [X, Y, Z];
2318
- }
2319
- return Number.isFinite(targetZ) ? [X, Y, targetZ] : [X, Y];
2320
- }
2321
- projectPosition(xyz) {
2322
- const [lng, lat, Z = 0] = xyz;
2323
- const lambda = lng * DEGREES_TO_RADIANS2;
2324
- const phi = lat * DEGREES_TO_RADIANS2;
2325
- const cosPhi = Math.cos(phi);
2326
- const D = (Z / EARTH_RADIUS + 1) * GLOBE_RADIUS;
2327
- return [Math.sin(lambda) * cosPhi * D, -Math.cos(lambda) * cosPhi * D, Math.sin(phi) * D];
2328
- }
2329
- unprojectPosition(xyz) {
2330
- const [x, y, z] = xyz;
2331
- const D = import_core6.vec3.len(xyz);
2332
- const phi = Math.asin(z / D);
2333
- const lambda = Math.atan2(x, -y);
2334
- const lng = lambda * RADIANS_TO_DEGREES;
2335
- const lat = phi * RADIANS_TO_DEGREES;
2336
- const Z = (D / GLOBE_RADIUS - 1) * EARTH_RADIUS;
2337
- return [lng, lat, Z];
2338
- }
2339
- projectFlat(xyz) {
2340
- return xyz;
2341
- }
2342
- unprojectFlat(xyz) {
2343
- return xyz;
2344
- }
2345
- /**
2346
- * Pan the globe using delta-based movement
2347
- * @param coords - the geographic coordinates where the pan started
2348
- * @param pixel - the current screen position
2349
- * @param startPixel - the screen position where the pan started
2350
- * @returns updated viewport options with new longitude/latitude
2351
- */
2352
- panByPosition([startLng, startLat, startZoom], pixel, startPixel) {
2353
- const scale = Math.pow(2, this.zoom - zoomAdjust(this.latitude));
2354
- const rotationSpeed = 0.25 / scale;
2355
- const longitude = startLng + rotationSpeed * (startPixel[0] - pixel[0]);
2356
- let latitude = startLat - rotationSpeed * (startPixel[1] - pixel[1]);
2357
- latitude = Math.max(Math.min(latitude, 90), -90);
2358
- const out = { longitude, latitude, zoom: startZoom - zoomAdjust(startLat) };
2359
- out.zoom += zoomAdjust(out.latitude);
2360
- return out;
2361
- }
2362
- };
2363
- GlobeViewport.displayName = "GlobeViewport";
2364
- function zoomAdjust(latitude, clampToPoles) {
2365
- if (clampToPoles) {
2366
- latitude = Math.max(Math.min(latitude, import_web_mercator4.MAX_LATITUDE), -import_web_mercator4.MAX_LATITUDE);
2367
- }
2368
- const scaleAdjust = Math.PI * Math.cos(latitude * Math.PI / 180);
2369
- return Math.log2(scaleAdjust);
2370
- }
2371
- function transformVector(matrix, vector) {
2372
- const result = import_core6.vec4.transformMat4([], vector, matrix);
2373
- import_core6.vec4.scale(result, result, 1 / result[3]);
2374
- return result;
2375
- }
2376
-
2377
- // ../core/src/utils/shader.ts
2378
- function mergeShaders(target, source2) {
2379
- if (!source2) {
2380
- return target;
2381
- }
2382
- const result = { ...target, ...source2 };
2383
- if ("defines" in source2) {
2384
- result.defines = { ...target.defines, ...source2.defines };
2385
- }
2386
- if ("modules" in source2) {
2387
- result.modules = (target.modules || []).concat(source2.modules);
2388
- if (source2.modules.some((module2) => module2.name === "project64")) {
2389
- const index = result.modules.findIndex((module2) => module2.name === "project32");
2390
- if (index >= 0) {
2391
- result.modules.splice(index, 1);
2392
- }
2393
- }
2394
- }
2395
- if ("inject" in source2) {
2396
- if (!target.inject) {
2397
- result.inject = source2.inject;
2398
- } else {
2399
- const mergedInjection = { ...target.inject };
2400
- for (const key in source2.inject) {
2401
- mergedInjection[key] = (mergedInjection[key] || "") + source2.inject[key];
2402
- }
2403
- result.inject = mergedInjection;
2404
- }
2405
- }
2406
- return result;
2407
- }
2408
-
2409
- // ../core/src/viewports/orthographic-viewport.ts
2410
- var import_core7 = require("@math.gl/core");
2411
- var import_web_mercator5 = require("@math.gl/web-mercator");
2412
- var viewMatrix = new import_core7.Matrix4().lookAt({ eye: [0, 0, 1] });
2413
- function getProjectionMatrix({
2414
- width,
2415
- height,
2416
- near,
2417
- far,
2418
- padding
2419
- }) {
2420
- let left = -width / 2;
2421
- let right = width / 2;
2422
- let bottom = -height / 2;
2423
- let top = height / 2;
2424
- if (padding) {
2425
- const { left: l = 0, right: r = 0, top: t = 0, bottom: b = 0 } = padding;
2426
- const offsetX = (0, import_core7.clamp)((l + width - r) / 2, 0, width) - width / 2;
2427
- const offsetY = (0, import_core7.clamp)((t + height - b) / 2, 0, height) - height / 2;
2428
- left -= offsetX;
2429
- right -= offsetX;
2430
- bottom += offsetY;
2431
- top += offsetY;
2432
- }
2433
- return new import_core7.Matrix4().ortho({
2434
- left,
2435
- right,
2436
- bottom,
2437
- top,
2438
- near,
2439
- far
2440
- });
2441
- }
2442
- var OrthographicViewport = class extends Viewport {
2443
- constructor(props) {
2444
- const {
2445
- width,
2446
- height,
2447
- near = 0.1,
2448
- far = 1e3,
2449
- zoom = 0,
2450
- target = [0, 0, 0],
2451
- padding = null,
2452
- flipY = true
2453
- } = props;
2454
- const zoomX = props.zoomX ?? (Array.isArray(zoom) ? zoom[0] : zoom);
2455
- const zoomY = props.zoomY ?? (Array.isArray(zoom) ? zoom[1] : zoom);
2456
- const zoom_ = Number.isFinite(props.zoom) ? props.zoom : Math.min(zoomX, zoomY);
2457
- const scale = Math.pow(2, zoom_);
2458
- let distanceScales;
2459
- if (zoomX !== zoom_ || zoomY !== zoom_) {
2460
- const scaleX = Math.pow(2, zoomX);
2461
- const scaleY = Math.pow(2, zoomY);
2462
- distanceScales = {
2463
- unitsPerMeter: [scaleX / scale, scaleY / scale, 1],
2464
- metersPerUnit: [scale / scaleX, scale / scaleY, 1]
2465
- };
2466
- }
2467
- super({
2468
- ...props,
2469
- // in case viewState contains longitude/latitude values,
2470
- // make sure that the base Viewport class does not treat this as a geospatial viewport
2471
- longitude: void 0,
2472
- position: target,
2473
- viewMatrix: viewMatrix.clone().scale([scale, scale * (flipY ? -1 : 1), scale]),
2474
- projectionMatrix: getProjectionMatrix({
2475
- width: width || 1,
2476
- height: height || 1,
2477
- padding,
2478
- near,
2479
- far
2480
- }),
2481
- zoom: zoom_,
2482
- distanceScales
2483
- });
2484
- this.target = target;
2485
- this.zoomX = zoomX;
2486
- this.zoomY = zoomY;
2487
- this.flipY = flipY;
2488
- }
2489
- projectFlat([X, Y]) {
2490
- const { unitsPerMeter: unitsPerMeter2 } = this.distanceScales;
2491
- return [X * unitsPerMeter2[0], Y * unitsPerMeter2[1]];
2492
- }
2493
- unprojectFlat([x, y]) {
2494
- const { metersPerUnit } = this.distanceScales;
2495
- return [x * metersPerUnit[0], y * metersPerUnit[1]];
2496
- }
2497
- /* Needed by LinearInterpolator */
2498
- panByPosition(coords, pixel, startPixel) {
2499
- const fromLocation = (0, import_web_mercator5.pixelsToWorld)(pixel, this.pixelUnprojectionMatrix);
2500
- const toLocation = this.projectFlat(coords);
2501
- const translate = import_core7.vec2.add([], toLocation, import_core7.vec2.negate([], fromLocation));
2502
- const newCenter = import_core7.vec2.add([], this.center, translate);
2503
- return { target: this.unprojectFlat(newCenter) };
2504
- }
2505
- };
2506
- OrthographicViewport.displayName = "OrthographicViewport";
2507
-
2508
- // ../core/src/lib/layer-extension.ts
2509
- var LayerExtension = class {
2510
- static get componentName() {
2511
- return Object.prototype.hasOwnProperty.call(this, "extensionName") ? this.extensionName : "";
2512
- }
2513
- constructor(opts) {
2514
- if (opts) {
2515
- this.opts = opts;
2516
- }
2517
- }
2518
- /** Returns true if two extensions are equivalent */
2519
- equals(extension) {
2520
- if (this === extension) {
2521
- return true;
2522
- }
2523
- return this.constructor === extension.constructor && deepEqual(this.opts, extension.opts, 1);
2524
- }
2525
- /** Only called if attached to a primitive layer */
2526
- getShaders(extension) {
2527
- return null;
2528
- }
2529
- /** Only called if attached to a CompositeLayer */
2530
- getSubLayerProps(extension) {
2531
- const { defaultProps: defaultProps9 } = extension.constructor;
2532
- const newProps = {
2533
- updateTriggers: {}
2534
- };
2535
- for (const key in defaultProps9) {
2536
- if (key in this.props) {
2537
- const propDef = defaultProps9[key];
2538
- const propValue = this.props[key];
2539
- newProps[key] = propValue;
2540
- if (propDef && propDef.type === "accessor") {
2541
- newProps.updateTriggers[key] = this.props.updateTriggers[key];
2542
- if (typeof propValue === "function") {
2543
- newProps[key] = this.getSubLayerAccessor(propValue);
2544
- }
2545
- }
2546
- }
2547
- }
2548
- return newProps;
2549
- }
2550
- /* eslint-disable @typescript-eslint/no-empty-function */
2551
- initializeState(context, extension) {
2552
- }
2553
- updateState(params, extension) {
2554
- }
2555
- onNeedsRedraw(extension) {
2556
- }
2557
- getNeedsPickingBuffer(extension) {
2558
- return false;
2559
- }
2560
- draw(params, extension) {
2561
- }
2562
- finalizeState(context, extension) {
2563
- }
2564
- };
2565
- LayerExtension.defaultProps = {};
2566
- LayerExtension.extensionName = "LayerExtension";
35
+ // dist/brushing/brushing-extension.js
36
+ var import_core2 = require("@deck.gl/core");
2567
37
 
2568
38
  // dist/brushing/shader-module.js
39
+ var import_core = require("@deck.gl/core");
2569
40
  var uniformBlock = (
2570
41
  /* glsl */
2571
42
  `layout(std140) uniform brushingUniforms {
@@ -2603,7 +74,7 @@ var vertex = (
2603
74
  }
2604
75
  `
2605
76
  );
2606
- var vs2 = `
77
+ var vs = `
2607
78
  ${uniformBlock}
2608
79
  ${vertex}
2609
80
  `;
@@ -2613,7 +84,7 @@ var fragment = (
2613
84
  in float brushing_isVisible;
2614
85
  `
2615
86
  );
2616
- var fs2 = `
87
+ var fs = `
2617
88
  ${uniformBlock}
2618
89
  ${fragment}
2619
90
  `;
@@ -2656,9 +127,9 @@ var inject = {
2656
127
  };
2657
128
  var shader_module_default = {
2658
129
  name: "brushing",
2659
- dependencies: [project_default],
2660
- vs: vs2,
2661
- fs: fs2,
130
+ dependencies: [import_core.project],
131
+ vs,
132
+ fs,
2662
133
  inject,
2663
134
  getUniforms: (opts) => {
2664
135
  if (!opts || !("viewport" in opts)) {
@@ -2687,7 +158,7 @@ var defaultProps = {
2687
158
  brushingEnabled: true,
2688
159
  brushingRadius: 1e4
2689
160
  };
2690
- var BrushingExtension = class extends LayerExtension {
161
+ var BrushingExtension = class extends import_core2.LayerExtension {
2691
162
  getShaders() {
2692
163
  return {
2693
164
  modules: [shader_module_default]
@@ -2742,6 +213,9 @@ BrushingExtension.defaultProps = defaultProps;
2742
213
  BrushingExtension.extensionName = "BrushingExtension";
2743
214
  var brushing_extension_default = BrushingExtension;
2744
215
 
216
+ // dist/data-filter/data-filter-extension.js
217
+ var import_core3 = require("@deck.gl/core");
218
+
2745
219
  // dist/data-filter/shader-module.js
2746
220
  var uniformBlock2 = (
2747
221
  /* glsl */
@@ -2925,7 +399,7 @@ float dataFilter_reduceValue(vec4 value) {
2925
399
  #endif
2926
400
  `
2927
401
  );
2928
- var vs3 = `
402
+ var vs2 = `
2929
403
  ${uniformBlock2}
2930
404
  ${vertex2}
2931
405
  `;
@@ -2935,11 +409,11 @@ var fragment2 = (
2935
409
  in float dataFilter_value;
2936
410
  `
2937
411
  );
2938
- var fs3 = `
412
+ var fs2 = `
2939
413
  ${uniformBlock2}
2940
414
  ${fragment2}
2941
415
  `;
2942
- function getUniforms2(opts) {
416
+ function getUniforms(opts) {
2943
417
  if (!opts || !("extensions" in opts)) {
2944
418
  return {};
2945
419
  }
@@ -2974,7 +448,7 @@ function getUniforms64(opts) {
2974
448
  if (!opts || !("extensions" in opts)) {
2975
449
  return {};
2976
450
  }
2977
- const uniforms = getUniforms2(opts);
451
+ const uniforms = getUniforms(opts);
2978
452
  const min64High = uniforms.min.map(Math.fround);
2979
453
  uniforms.min = uniforms.min.map((x, i) => x - min64High[i]);
2980
454
  uniforms.softMin = uniforms.softMin.map((x, i) => x - min64High[i]);
@@ -3052,16 +526,16 @@ function uniformTypesFromOptions(opts) {
3052
526
  }
3053
527
  var dataFilter = {
3054
528
  name: "dataFilter",
3055
- vs: vs3,
3056
- fs: fs3,
529
+ vs: vs2,
530
+ fs: fs2,
3057
531
  inject: inject2,
3058
- getUniforms: getUniforms2,
532
+ getUniforms,
3059
533
  uniformTypesFromOptions
3060
534
  };
3061
535
  var dataFilter64 = {
3062
536
  name: "dataFilter",
3063
- vs: vs3,
3064
- fs: fs3,
537
+ vs: vs2,
538
+ fs: fs2,
3065
539
  inject: inject2,
3066
540
  getUniforms: getUniforms64,
3067
541
  uniformTypesFromOptions
@@ -3206,24 +680,24 @@ var DATA_TYPE_FROM_SIZE = {
3206
680
  3: "vec3",
3207
681
  4: "vec4"
3208
682
  };
3209
- var DataFilterExtension = class extends LayerExtension {
683
+ var DataFilterExtension = class extends import_core3.LayerExtension {
3210
684
  constructor(opts = {}) {
3211
685
  super({ ...defaultOptions, ...opts });
3212
686
  }
3213
687
  getShaders(extension) {
3214
688
  const { categorySize, filterSize, fp64: fp642 } = extension.opts;
3215
- const defines2 = {};
689
+ const defines = {};
3216
690
  if (categorySize) {
3217
- defines2.DATACATEGORY_TYPE = CATEGORY_TYPE_FROM_SIZE[categorySize];
3218
- defines2.DATACATEGORY_CHANNELS = categorySize;
691
+ defines.DATACATEGORY_TYPE = CATEGORY_TYPE_FROM_SIZE[categorySize];
692
+ defines.DATACATEGORY_CHANNELS = categorySize;
3219
693
  }
3220
694
  if (filterSize) {
3221
- defines2.DATAFILTER_TYPE = DATA_TYPE_FROM_SIZE[filterSize];
3222
- defines2.DATAFILTER_DOUBLE = Boolean(fp642);
695
+ defines.DATAFILTER_TYPE = DATA_TYPE_FROM_SIZE[filterSize];
696
+ defines.DATAFILTER_DOUBLE = Boolean(fp642);
3223
697
  }
3224
698
  const module2 = fp642 ? dataFilter64 : dataFilter;
3225
699
  module2.uniformTypes = module2.uniformTypesFromOptions(extension.opts);
3226
- return { modules: [module2], defines: defines2 };
700
+ return { modules: [module2], defines };
3227
701
  }
3228
702
  initializeState(context, extension) {
3229
703
  const attributeManager = this.getAttributeManager();
@@ -3293,7 +767,7 @@ var DataFilterExtension = class extends LayerExtension {
3293
767
  }
3294
768
  }
3295
769
  if (attributeManager == null ? void 0 : attributeManager.attributes.filterCategoryValues) {
3296
- const categoryBitMaskNeedsUpdate = attributeManager.attributes.filterCategoryValues.needsUpdate() || !deepEqual(props.filterCategories, oldProps.filterCategories, 2);
770
+ const categoryBitMaskNeedsUpdate = attributeManager.attributes.filterCategoryValues.needsUpdate() || !(0, import_core3._deepEqual)(props.filterCategories, oldProps.filterCategories, 2);
3297
771
  if (categoryBitMaskNeedsUpdate) {
3298
772
  this.setState({ categoryBitMask: null });
3299
773
  }
@@ -3387,7 +861,7 @@ var DataFilterExtension = class extends LayerExtension {
3387
861
  const channel = c * (maxCategories / 32) + Math.floor(key / 32);
3388
862
  categoryBitMask[channel] += Math.pow(2, key % 32);
3389
863
  } else {
3390
- log_default.warn(`Exceeded maximum number of categories (${maxCategories})`)();
864
+ import_core3.log.warn(`Exceeded maximum number of categories (${maxCategories})`)();
3391
865
  }
3392
866
  }
3393
867
  }
@@ -3409,8 +883,12 @@ DataFilterExtension.defaultProps = defaultProps2;
3409
883
  DataFilterExtension.extensionName = "DataFilterExtension";
3410
884
  var data_filter_extension_default = DataFilterExtension;
3411
885
 
886
+ // dist/fp64/fp64-extension.js
887
+ var import_core5 = require("@deck.gl/core");
888
+
3412
889
  // dist/fp64/project64.js
3413
- var import_shadertools3 = require("@luma.gl/shadertools");
890
+ var import_shadertools = require("@luma.gl/shadertools");
891
+ var import_core4 = require("@deck.gl/core");
3414
892
 
3415
893
  // dist/fp64/project64.glsl.js
3416
894
  var project64_glsl_default = `const vec2 WORLD_SCALE_FP64 = vec2(81.4873275756836, 0.0000032873668232014097);
@@ -3489,12 +967,12 @@ position, position64xyLow, offset, commonPosition
3489
967
  `;
3490
968
 
3491
969
  // dist/fp64/project64.js
3492
- var { fp64ify, fp64ifyMatrix4 } = import_shadertools3.fp64;
970
+ var { fp64ify, fp64ifyMatrix4 } = import_shadertools.fp64;
3493
971
  var project64_default = {
3494
972
  name: "project64",
3495
- dependencies: [project_default, import_shadertools3.fp64],
973
+ dependencies: [import_core4.project, import_shadertools.fp64],
3496
974
  vs: project64_glsl_default,
3497
- getUniforms: getUniforms3,
975
+ getUniforms: getUniforms2,
3498
976
  uniformTypes: {
3499
977
  scale: "vec2<f32>",
3500
978
  // Cannot pass as vec2[16], so instead split into 2 mat4x4
@@ -3502,8 +980,8 @@ var project64_default = {
3502
980
  viewProjectionMatrix64Low: "mat4x4<f32>"
3503
981
  }
3504
982
  };
3505
- var getMemoizedUniforms = memoize(calculateUniforms);
3506
- function getUniforms3(opts) {
983
+ var getMemoizedUniforms = (0, import_core4._memoize)(calculateUniforms);
984
+ function getUniforms2(opts) {
3507
985
  if (opts && "viewport" in opts) {
3508
986
  const { viewProjectionMatrix, scale } = opts.viewport;
3509
987
  return getMemoizedUniforms({ viewProjectionMatrix, scale });
@@ -3530,7 +1008,7 @@ function calculateUniforms({ viewProjectionMatrix, scale }) {
3530
1008
  }
3531
1009
 
3532
1010
  // dist/fp64/fp64-extension.js
3533
- var Fp64Extension = class extends LayerExtension {
1011
+ var Fp64Extension = class extends import_core5.LayerExtension {
3534
1012
  getShaders() {
3535
1013
  const { coordinateSystem } = this.props;
3536
1014
  if (coordinateSystem !== "lnglat" && coordinateSystem !== "default") {
@@ -3549,7 +1027,8 @@ Fp64Extension.extensionName = "Fp64Extension";
3549
1027
  var fp64_extension_default = Fp64Extension;
3550
1028
 
3551
1029
  // dist/path-style/path-style-extension.js
3552
- var import_core14 = require("@math.gl/core");
1030
+ var import_core6 = require("@deck.gl/core");
1031
+ var import_core7 = require("@math.gl/core");
3553
1032
 
3554
1033
  // dist/path-style/shaders.glsl.js
3555
1034
  var dashShaders = {
@@ -3557,26 +1036,68 @@ var dashShaders = {
3557
1036
  "vs:#decl": `
3558
1037
  in vec2 instanceDashArrays;
3559
1038
  #ifdef HIGH_PRECISION_DASH
3560
- in float instanceDashOffsets;
1039
+ in vec2 instanceDashOffsets;
3561
1040
  #endif
3562
1041
  out vec2 vDashArray;
3563
1042
  out float vDashOffset;
1043
+ out float vDashPathLength;
1044
+ layout(std140) uniform pathStyleUniforms {
1045
+ float dashAlignMode;
1046
+ bool dashGapPickable;
1047
+ highp int dashUnits;
1048
+ } pathStyle;
3564
1049
  `,
3565
1050
  "vs:#main-end": `
3566
- vDashArray = instanceDashArrays;
1051
+ float dashWidthPixels = path.billboard
1052
+ ? width.x * project.focalDistance
1053
+ : width.x * project.scale;
1054
+ float strokeHalfWidthPixels = path.billboard ? width.x : width.x * project.scale;
1055
+ float dashUnitPixels = strokeHalfWidthPixels;
1056
+ if (pathStyle.dashUnits == 1) {
1057
+ dashUnitPixels = 1.0;
1058
+ } else if (pathStyle.dashUnits == 2) {
1059
+ dashUnitPixels = project_size_to_pixel(1.0);
1060
+ } else if (pathStyle.dashUnits == 3) {
1061
+ dashUnitPixels = project.scale;
1062
+ }
1063
+ vDashArray = instanceDashArrays * (dashUnitPixels / dashWidthPixels);
3567
1064
  #ifdef HIGH_PRECISION_DASH
3568
- vDashOffset = instanceDashOffsets / width.x;
1065
+ vec2 dashOffsetAndLength = (instanceDashOffsets * project.scale) / dashWidthPixels;
1066
+ vDashPathLength = dashOffsetAndLength.y;
1067
+ float dashUnitLength = vDashArray.x + vDashArray.y;
1068
+ float dashPeriod = pathStyle.dashAlignMode == 0.0
1069
+ ? dashUnitLength
1070
+ : vDashPathLength / max(round(vDashPathLength / max(dashUnitLength, 0.0001)), 1.0);
1071
+ vDashOffset = dashPeriod > 0.0 ? mod(dashOffsetAndLength.x, dashPeriod) : 0.0;
3569
1072
  #else
3570
1073
  vDashOffset = 0.0;
1074
+ vDashPathLength = 0.0;
3571
1075
  #endif
3572
1076
  `,
3573
1077
  "fs:#decl": `
3574
1078
  layout(std140) uniform pathStyleUniforms {
3575
1079
  float dashAlignMode;
3576
1080
  bool dashGapPickable;
1081
+ highp int dashUnits;
3577
1082
  } pathStyle;
3578
1083
  in vec2 vDashArray;
3579
1084
  in float vDashOffset;
1085
+ in float vDashPathLength;
1086
+ float dashPatternIntegral(float position, float solidLength, float unitLength) {
1087
+ return floor(position / unitLength) * solidLength +
1088
+ min(mod(position, unitLength), solidLength);
1089
+ }
1090
+ float dashPatternCoverage(
1091
+ float position,
1092
+ float solidLength,
1093
+ float unitLength,
1094
+ float filterWidth
1095
+ ) {
1096
+ float halfFilter = 0.5 * filterWidth;
1097
+ float reducedPosition = mod(position, unitLength);
1098
+ return (dashPatternIntegral(reducedPosition + halfFilter, solidLength, unitLength) -
1099
+ dashPatternIntegral(reducedPosition - halfFilter, solidLength, unitLength)) / filterWidth;
1100
+ }
3580
1101
  `,
3581
1102
  // if given position is in the gap part of the dashed line
3582
1103
  // dashArray.x: solid stroke length, relative to width
@@ -3587,36 +1108,90 @@ in float vDashOffset;
3587
1108
  // 1 - stretch to fit, draw half dash at each end for nicer joints
3588
1109
  // o-- ---- ---- ---- --o-- --o-- ---- --o
3589
1110
  "fs:#main-start": `
1111
+ float dashCoverage = 1.0;
1112
+ bool shouldDiscardDash = false;
1113
+ bool inRoundedDashGap = false;
1114
+ float roundedDashResolvedCoverage = 1.0;
1115
+ float roundedDashSubPixelBlend = 0.0;
1116
+ float roundedDashDutyCycle = 1.0;
3590
1117
  float solidLength = vDashArray.x;
3591
1118
  float gapLength = vDashArray.y;
3592
1119
  float unitLength = solidLength + gapLength;
1120
+ if (unitLength > 0.0 && gapLength > 0.0) {
3593
1121
  float offset;
3594
- if (unitLength > 0.0) {
3595
1122
  if (pathStyle.dashAlignMode == 0.0) {
3596
1123
  offset = vDashOffset;
3597
1124
  } else {
3598
- unitLength = vPathLength / round(vPathLength / unitLength);
1125
+ #ifdef HIGH_PRECISION_DASH
1126
+ unitLength = vDashPathLength / max(round(vDashPathLength / unitLength), 1.0);
1127
+ #else
1128
+ unitLength = vPathLength / max(round(vPathLength / unitLength), 1.0);
1129
+ #endif
1130
+ solidLength = min(solidLength, unitLength);
3599
1131
  offset = solidLength / 2.0;
1132
+ #ifdef HIGH_PRECISION_DASH
1133
+ offset += vDashOffset;
1134
+ #endif
3600
1135
  }
3601
- float unitOffset = mod(vPathPosition.y + offset, unitLength);
3602
- if (gapLength > 0.0 && unitOffset > solidLength) {
3603
- if (path.capType <= 0.5) {
3604
- if (!(pathStyle.dashGapPickable && bool(picking.isActive))) {
3605
- discard;
3606
- }
3607
- } else {
3608
- float distToEnd = length(vec2(
1136
+ float alongPath = vPathPosition.y + offset;
1137
+ float unitOffset = mod(alongPath, unitLength);
1138
+ float filterWidth = max(fwidth(alongPath), 0.0001);
1139
+ if (bool(picking.isActive)) {
1140
+ bool inGap = unitOffset > solidLength;
1141
+ if (inGap && path.capType > 0.5) {
1142
+ inGap = length(vec2(
3609
1143
  min(unitOffset - solidLength, unitLength - unitOffset),
3610
1144
  vPathPosition.x
3611
- ));
3612
- if (distToEnd > 1.0) {
3613
- if (!(pathStyle.dashGapPickable && bool(picking.isActive))) {
3614
- discard;
1145
+ )) > 1.0;
1146
+ }
1147
+ if (inGap && !pathStyle.dashGapPickable) {
1148
+ shouldDiscardDash = true;
3615
1149
  }
1150
+ } else if (path.capType <= 0.5) {
1151
+ dashCoverage = dashPatternCoverage(alongPath, solidLength, unitLength, filterWidth);
1152
+ } else {
1153
+ float distanceAlongGap = min(unitOffset - solidLength, unitLength - unitOffset);
1154
+ float distanceToEnd = length(vec2(max(distanceAlongGap, 0.0), vPathPosition.x));
1155
+ float capEdgePixels = (1.0 - distanceToEnd) / max(fwidth(distanceToEnd), 1e-6);
1156
+ if (distanceAlongGap > 0.0) {
1157
+ inRoundedDashGap = true;
1158
+ roundedDashResolvedCoverage = smoothedge(0.0, capEdgePixels);
1159
+ dashCoverage = roundedDashResolvedCoverage;
1160
+ }
1161
+ float subPixelBlend = smoothstep(unitLength, 2.0 * unitLength, filterWidth);
1162
+ roundedDashSubPixelBlend = subPixelBlend;
1163
+ float boundedSolidLength = min(solidLength, unitLength);
1164
+ float effectiveGap = max(unitLength - boundedSolidLength, 0.0);
1165
+ float capSpan = 2.0 * sqrt(max(1.0 - vPathPosition.x * vPathPosition.x, 0.0));
1166
+ float roundedDutyCycle = clamp(
1167
+ (boundedSolidLength + min(effectiveGap, capSpan)) / unitLength,
1168
+ 0.0,
1169
+ 1.0
1170
+ );
1171
+ roundedDashDutyCycle = roundedDutyCycle;
1172
+ dashCoverage = mix(dashCoverage, roundedDutyCycle, subPixelBlend);
3616
1173
  }
1174
+ dashCoverage = clamp(dashCoverage, 0.0, 1.0);
1175
+ shouldDiscardDash = shouldDiscardDash || dashCoverage <= 0.0;
3617
1176
  }
1177
+ `,
1178
+ "fs:#main-end": `
1179
+ #ifdef ANTIALIASING
1180
+ if (inRoundedDashGap) {
1181
+ float pathCoverage = smoothedge(0.0, edgePixels);
1182
+ float resolvedCapMultiplier =
1183
+ min(pathCoverage, roundedDashResolvedCoverage) / max(pathCoverage, 1e-6);
1184
+ dashCoverage = mix(
1185
+ resolvedCapMultiplier,
1186
+ roundedDashDutyCycle,
1187
+ roundedDashSubPixelBlend
1188
+ );
3618
1189
  }
1190
+ #endif
1191
+ if (shouldDiscardDash) {
1192
+ discard;
3619
1193
  }
1194
+ fragColor.a *= dashCoverage;
3620
1195
  `
3621
1196
  }
3622
1197
  };
@@ -3817,13 +1392,32 @@ float offsetDir = sign(instanceOffsets);
3817
1392
  vPathPosition.x = (vPathPosition.x + offsetDir) * offsetWidth - offsetDir;
3818
1393
  vPathPosition.y *= offsetWidth;
3819
1394
  vPathLength *= offsetWidth;
1395
+ #ifdef DASH_ENABLED
1396
+ if (pathStyle.dashUnits != 0) {
1397
+ vDashArray *= offsetWidth;
1398
+ }
1399
+ vPathBounds *= offsetWidth;
1400
+ #ifdef HIGH_PRECISION_DASH
1401
+ vDashPathLength *= offsetWidth;
1402
+ float restoredDashUnitLength = vDashArray.x + vDashArray.y;
1403
+ float restoredDashPeriod = pathStyle.dashAlignMode == 0.0
1404
+ ? restoredDashUnitLength
1405
+ : vDashPathLength /
1406
+ max(round(vDashPathLength / max(restoredDashUnitLength, 0.0001)), 1.0);
1407
+ vDashOffset = restoredDashPeriod > 0.0
1408
+ ? mod(dashOffsetAndLength.x * offsetWidth, restoredDashPeriod)
1409
+ : 0.0;
1410
+ #else
1411
+ vDashOffset *= offsetWidth;
1412
+ #endif
1413
+ #endif
3820
1414
  `,
3821
- "fs:#main-start": `
3822
- float isInside;
3823
- isInside = step(-1.0, vPathPosition.x) * step(vPathPosition.x, 1.0);
3824
- if (isInside == 0.0) {
1415
+ "fs:#main-end": `
1416
+ #ifndef ANTIALIASING
1417
+ if (abs(vPathPosition.x) > 1.0) {
3825
1418
  discard;
3826
1419
  }
1420
+ #endif
3827
1421
  `
3828
1422
  }
3829
1423
  };
@@ -3833,11 +1427,56 @@ var defaultProps3 = {
3833
1427
  getDashArray: { type: "accessor", value: [0, 0] },
3834
1428
  getOffset: { type: "accessor", value: 0 },
3835
1429
  dashJustified: false,
3836
- dashGapPickable: false
1430
+ dashGapPickable: false,
1431
+ dashUnits: "widths"
1432
+ };
1433
+ var DASH_UNITS = {
1434
+ widths: 0,
1435
+ pixels: 1,
1436
+ meters: 2,
1437
+ common: 3
3837
1438
  };
3838
- var PathStyleExtension = class extends LayerExtension {
3839
- constructor({ dash = false, offset = false, highPrecisionDash = false } = {}) {
3840
- super({ dash: dash || highPrecisionDash, offset, highPrecisionDash });
1439
+ var PATH_STYLE_ATTRIBUTES = ["instanceDashArrays", "instanceDashOffsets", "instanceOffsets"];
1440
+ function dashMetricsProjectionPropsChanged({ props, oldProps }) {
1441
+ return !(0, import_core6._deepEqual)(props.modelMatrix, oldProps.modelMatrix, 2) || props.coordinateSystem !== oldProps.coordinateSystem || !(0, import_core6._deepEqual)(props.coordinateOrigin, oldProps.coordinateOrigin, 1);
1442
+ }
1443
+ function projectRenderedPathPosition(layer, position, projectUniforms) {
1444
+ const viewport = layer.context.viewport;
1445
+ if (!(viewport instanceof import_core6.WebMercatorViewport) || viewport.zoom < 12) {
1446
+ return layer.projectPosition(position, { autoOffset: false });
1447
+ }
1448
+ const positionWorld = import_core7.vec4.transformMat4([], [position[0], position[1], position[2] || 0, 1], projectUniforms.modelMatrix);
1449
+ const coordinateSystem = layer.props.coordinateSystem === "default" ? "lnglat" : layer.props.coordinateSystem;
1450
+ if (coordinateSystem === "lnglat") {
1451
+ if (Math.abs(positionWorld[1] - projectUniforms.coordinateOrigin[1]) > 0.25) {
1452
+ let longitude = positionWorld[0];
1453
+ if (projectUniforms.wrapLongitude) {
1454
+ longitude = ((longitude + 180) % 360 + 360) % 360 - 180;
1455
+ }
1456
+ const commonPosition = viewport.projectPosition([longitude, positionWorld[1], 0]);
1457
+ return [
1458
+ commonPosition[0] - projectUniforms.commonOrigin[0],
1459
+ commonPosition[1] - projectUniforms.commonOrigin[1],
1460
+ positionWorld[2] * projectUniforms.commonUnitsPerMeter[2]
1461
+ ];
1462
+ }
1463
+ import_core7.vec3.sub(positionWorld, positionWorld, projectUniforms.coordinateOrigin);
1464
+ } else if (coordinateSystem === "cartesian") {
1465
+ import_core7.vec3.sub(positionWorld, positionWorld, projectUniforms.coordinateOrigin);
1466
+ }
1467
+ const deltaLatitude = positionWorld[1];
1468
+ const scale = import_core7.vec3.scaleAndAdd([], projectUniforms.commonUnitsPerWorldUnit, projectUniforms.commonUnitsPerWorldUnit2, deltaLatitude);
1469
+ return import_core7.vec3.multiply([], positionWorld, scale);
1470
+ }
1471
+ var PathStyleExtension = class extends import_core6.LayerExtension {
1472
+ constructor({ dash = false, offset = false, dashMode, highPrecisionDash = false } = {}) {
1473
+ const resolvedDashMode = dashMode ?? (highPrecisionDash ? "path" : "segment");
1474
+ super({
1475
+ dash: dash || highPrecisionDash || dashMode !== void 0,
1476
+ offset,
1477
+ dashMode: resolvedDashMode,
1478
+ highPrecisionDash: resolvedDashMode === "path"
1479
+ });
3841
1480
  }
3842
1481
  getLayerType(layer) {
3843
1482
  if ("pathTesselator" in layer.state) {
@@ -3852,6 +1491,59 @@ var PathStyleExtension = class extends LayerExtension {
3852
1491
  }
3853
1492
  return null;
3854
1493
  }
1494
+ synchronizeAttributes(layer) {
1495
+ const attributeManager = layer.getAttributeManager();
1496
+ const layerType = this.getLayerType(layer);
1497
+ if (!attributeManager || !layerType) {
1498
+ return false;
1499
+ }
1500
+ const attributes = attributeManager.getAttributes();
1501
+ const desiredAttributes = /* @__PURE__ */ new Set();
1502
+ if (this.opts.dash) {
1503
+ desiredAttributes.add("instanceDashArrays");
1504
+ }
1505
+ if (layerType === "path" && this.opts.dash && this.opts.dashMode === "path") {
1506
+ desiredAttributes.add("instanceDashOffsets");
1507
+ }
1508
+ if (layerType === "path" && this.opts.offset) {
1509
+ desiredAttributes.add("instanceOffsets");
1510
+ }
1511
+ let topologyChanged = false;
1512
+ for (const attributeName of PATH_STYLE_ATTRIBUTES) {
1513
+ if (attributes[attributeName] && !desiredAttributes.has(attributeName)) {
1514
+ attributeManager.remove([attributeName]);
1515
+ topologyChanged = true;
1516
+ }
1517
+ }
1518
+ if (desiredAttributes.has("instanceDashArrays") && !attributes.instanceDashArrays) {
1519
+ attributeManager.addInstanced({
1520
+ instanceDashArrays: { size: 2, accessor: "getDashArray" }
1521
+ });
1522
+ topologyChanged = true;
1523
+ }
1524
+ if (desiredAttributes.has("instanceDashOffsets") && !attributes.instanceDashOffsets) {
1525
+ attributeManager.addInstanced({
1526
+ instanceDashOffsets: {
1527
+ // [distance from the start of the path, total length of the path]
1528
+ size: 2,
1529
+ // Recalculate from rendered geometry when getPath changes. A binary getPath buffer
1530
+ // contains positions, not dash metrics, so keep it as an update trigger rather than
1531
+ // binding it directly to this attribute.
1532
+ accessor: ["getPath"],
1533
+ // eslint-disable-next-line @typescript-eslint/unbound-method
1534
+ update: this.calculateDashMetrics
1535
+ }
1536
+ });
1537
+ topologyChanged = true;
1538
+ }
1539
+ if (desiredAttributes.has("instanceOffsets") && !attributes.instanceOffsets) {
1540
+ attributeManager.addInstanced({
1541
+ instanceOffsets: { size: 1, accessor: "getOffset" }
1542
+ });
1543
+ topologyChanged = true;
1544
+ }
1545
+ return topologyChanged;
1546
+ }
3855
1547
  isEnabled(layer) {
3856
1548
  return this.getLayerType(layer) !== null;
3857
1549
  }
@@ -3875,60 +1567,58 @@ var PathStyleExtension = class extends LayerExtension {
3875
1567
  return { modules: [pathStyle2] };
3876
1568
  }
3877
1569
  let result = {};
3878
- const defines2 = {};
1570
+ const defines = {};
3879
1571
  if (extension.opts.dash) {
3880
- result = mergeShaders(result, dashShaders);
3881
- if (extension.opts.highPrecisionDash) {
3882
- defines2.HIGH_PRECISION_DASH = true;
1572
+ result = (0, import_core6._mergeShaders)(result, dashShaders);
1573
+ defines.DASH_ENABLED = true;
1574
+ if (extension.opts.dashMode === "path") {
1575
+ defines.HIGH_PRECISION_DASH = true;
3883
1576
  }
3884
1577
  }
3885
1578
  if (extension.opts.offset) {
3886
- result = mergeShaders(result, offsetShaders);
1579
+ result = (0, import_core6._mergeShaders)(result, offsetShaders);
1580
+ defines.PATH_STYLE_OFFSET = true;
3887
1581
  }
3888
1582
  const { inject: inject6 } = result;
3889
1583
  const pathStyle = {
3890
1584
  name: "pathStyle",
3891
- inject: inject6,
3892
- uniformTypes: {
3893
- dashAlignMode: "f32",
3894
- dashGapPickable: "i32"
3895
- }
1585
+ inject: inject6
3896
1586
  };
1587
+ if (extension.opts.dash) {
1588
+ pathStyle.uniformTypes = {
1589
+ dashAlignMode: "f32",
1590
+ dashGapPickable: "i32",
1591
+ dashUnits: "i32"
1592
+ };
1593
+ }
3897
1594
  return {
3898
1595
  modules: [pathStyle],
3899
- defines: defines2
1596
+ defines
3900
1597
  };
3901
1598
  }
3902
1599
  initializeState(context, extension) {
3903
- const attributeManager = this.getAttributeManager();
3904
- const layerType = extension.getLayerType(this);
3905
- if (!attributeManager || !layerType) {
3906
- return;
3907
- }
3908
- if (extension.opts.dash) {
3909
- attributeManager.addInstanced({
3910
- instanceDashArrays: { size: 2, accessor: "getDashArray" },
3911
- ...layerType === "path" && extension.opts.highPrecisionDash ? {
3912
- instanceDashOffsets: {
3913
- size: 1,
3914
- accessor: "getPath",
3915
- transform: extension.getDashOffsets.bind(this)
3916
- }
3917
- } : {}
3918
- });
3919
- }
3920
- if (layerType === "path" && extension.opts.offset) {
3921
- attributeManager.addInstanced({
3922
- instanceOffsets: { size: 1, accessor: "getOffset" }
3923
- });
3924
- }
1600
+ extension.synchronizeAttributes(this);
3925
1601
  }
3926
1602
  updateState(params, extension) {
1603
+ var _a;
3927
1604
  if (!extension.isEnabled(this)) {
3928
1605
  return;
3929
1606
  }
1607
+ if (params.changeFlags.extensionsChanged) {
1608
+ const topologyChanged = extension.synchronizeAttributes(this);
1609
+ const attributeManager = this.getAttributeManager();
1610
+ if (attributeManager && topologyChanged) {
1611
+ attributeManager.invalidateAll();
1612
+ for (const model of this.getModels()) {
1613
+ model.setBufferLayout(attributeManager.getBufferLayouts(model));
1614
+ }
1615
+ }
1616
+ }
3930
1617
  if (extension.opts.dash) {
3931
1618
  const layerType = extension.getLayerType(this);
1619
+ if (layerType === "path" && extension.opts.dashMode === "path" && dashMetricsProjectionPropsChanged(params)) {
1620
+ (_a = this.getAttributeManager()) == null ? void 0 : _a.invalidate("instanceDashOffsets");
1621
+ }
3932
1622
  if (layerType === "scatterplot" || layerType === "textBackground") {
3933
1623
  const pathStyleProps = {
3934
1624
  dashGapPickable: Boolean(this.props.dashGapPickable)
@@ -3937,12 +1627,96 @@ var PathStyleExtension = class extends LayerExtension {
3937
1627
  } else {
3938
1628
  const pathStyleProps = {
3939
1629
  dashAlignMode: this.props.dashJustified ? 1 : 0,
3940
- dashGapPickable: Boolean(this.props.dashGapPickable)
1630
+ dashGapPickable: Boolean(this.props.dashGapPickable),
1631
+ dashUnits: DASH_UNITS[this.props.dashUnits ?? "widths"]
3941
1632
  };
3942
1633
  this.setShaderModuleProps({ pathStyle: pathStyleProps });
3943
1634
  }
3944
1635
  }
3945
1636
  }
1637
+ calculateDashMetrics(attribute, { startRow, endRow }) {
1638
+ var _a, _b, _c;
1639
+ const pathTesselator = this.state.pathTesselator;
1640
+ const vertexStarts = pathTesselator == null ? void 0 : pathTesselator.vertexStarts;
1641
+ const instanceCount = pathTesselator == null ? void 0 : pathTesselator.instanceCount;
1642
+ const packedPositions = pathTesselator == null ? void 0 : pathTesselator.get("positions");
1643
+ if (!vertexStarts || instanceCount === void 0 || typeof (pathTesselator == null ? void 0 : pathTesselator.getPathSegmentIndices) !== "function") {
1644
+ throw new Error("PathStyleExtension requires PathLayer tessellation data for path dashes.");
1645
+ }
1646
+ const binaryPath = (_b = (_a = this.props.data) == null ? void 0 : _a.attributes) == null ? void 0 : _b.getPath;
1647
+ const binaryValue = ArrayBuffer.isView(binaryPath) ? binaryPath : binaryPath == null ? void 0 : binaryPath.value;
1648
+ const hasReadableBinaryPath = ArrayBuffer.isView(binaryValue);
1649
+ const usePackedPositions = packedPositions && (!binaryPath || pathTesselator.normalize || ((_c = pathTesselator.opts) == null ? void 0 : _c.isWebGPU));
1650
+ if (binaryPath && !hasReadableBinaryPath || !usePackedPositions && !hasReadableBinaryPath) {
1651
+ throw new Error("PathStyleExtension cannot calculate whole-path dash metrics from GPU-only getPath data; supply data.attributes.instanceDashOffsets.");
1652
+ }
1653
+ const output = attribute.value;
1654
+ const metricSize = attribute.size;
1655
+ const firstRow = Math.max(0, startRow);
1656
+ const lastRow = Math.min(endRow, vertexStarts.length - 1);
1657
+ let binarySize = 3;
1658
+ let binaryStride = 3;
1659
+ let binaryOffset = 0;
1660
+ if (!usePackedPositions) {
1661
+ const bytesPerElement = binaryValue.BYTES_PER_ELEMENT;
1662
+ binarySize = (binaryPath == null ? void 0 : binaryPath.size) || (this.props.positionFormat === "XY" ? 2 : 3);
1663
+ binaryStride = (binaryPath == null ? void 0 : binaryPath.stride) ? binaryPath.stride / bytesPerElement : binarySize;
1664
+ binaryOffset = (binaryPath == null ? void 0 : binaryPath.offset) ? binaryPath.offset / bytesPerElement : 0;
1665
+ }
1666
+ const sourcePosition = new Array(3);
1667
+ const projectUniforms = import_core6.project.getUniforms({
1668
+ viewport: this.context.viewport,
1669
+ modelMatrix: this.props.modelMatrix,
1670
+ coordinateSystem: this.props.coordinateSystem,
1671
+ coordinateOrigin: this.props.coordinateOrigin,
1672
+ // PathLayer normalizes/cuts wrapped paths on the CPU; its shader never wraps again.
1673
+ autoWrapLongitude: this.wrapLongitude
1674
+ });
1675
+ const readPosition = (vertexIndex) => {
1676
+ if (usePackedPositions) {
1677
+ sourcePosition[0] = packedPositions[vertexIndex * 3];
1678
+ sourcePosition[1] = packedPositions[vertexIndex * 3 + 1];
1679
+ sourcePosition[2] = packedPositions[vertexIndex * 3 + 2];
1680
+ } else {
1681
+ const sourceIndex = binaryOffset + vertexIndex * binaryStride;
1682
+ sourcePosition[0] = binaryValue[sourceIndex];
1683
+ sourcePosition[1] = binaryValue[sourceIndex + 1];
1684
+ sourcePosition[2] = binarySize === 3 ? binaryValue[sourceIndex + 2] : 0;
1685
+ }
1686
+ return sourcePosition;
1687
+ };
1688
+ attribute.startIndices = vertexStarts;
1689
+ for (let row = firstRow; row < lastRow; row++) {
1690
+ const rowStart = vertexStarts[row];
1691
+ const rowEnd = Math.min(vertexStarts[row + 1] ?? instanceCount, instanceCount);
1692
+ output.fill(0, rowStart * metricSize, rowEnd * metricSize);
1693
+ const validSegments = pathTesselator.getPathSegmentIndices(row);
1694
+ let phase = 0;
1695
+ let previousSegment = -2;
1696
+ let previousEnd = null;
1697
+ for (const segmentIndex of validSegments) {
1698
+ const outputIndex = segmentIndex * metricSize;
1699
+ output[outputIndex] = phase;
1700
+ const start = segmentIndex === previousSegment + 1 && previousEnd ? previousEnd : projectRenderedPathPosition(this, readPosition(segmentIndex), projectUniforms);
1701
+ const end = projectRenderedPathPosition(this, readPosition(segmentIndex + 1), projectUniforms);
1702
+ phase += import_core7.vec3.dist(start, end);
1703
+ previousSegment = segmentIndex;
1704
+ previousEnd = end;
1705
+ }
1706
+ if (metricSize > 1) {
1707
+ for (let vertexIndex = rowStart; vertexIndex < rowEnd; vertexIndex++) {
1708
+ output[vertexIndex * metricSize + 1] = phase;
1709
+ }
1710
+ }
1711
+ }
1712
+ }
1713
+ /**
1714
+ * Calculates the distance from the start of a path to each rendered segment.
1715
+ *
1716
+ * The final entry is zero because PathLayer reserves the final vertex as invalid padding.
1717
+ * This scalar return shape is retained for compatibility; path-mode rendering uses an
1718
+ * internal attribute containing both each segment offset and the total path length.
1719
+ */
3946
1720
  getDashOffsets(path) {
3947
1721
  const result = [0];
3948
1722
  const positionSize = this.props.positionFormat === "XY" ? 2 : 3;
@@ -3952,9 +1726,9 @@ var PathStyleExtension = class extends LayerExtension {
3952
1726
  let prevP;
3953
1727
  for (let i = 0; i < geometrySize - 1; i++) {
3954
1728
  p = isNested ? path[i] : path.slice(i * positionSize, i * positionSize + positionSize);
3955
- p = this.projectPosition(p);
1729
+ p = this.projectPosition(p, { autoOffset: false });
3956
1730
  if (i > 0) {
3957
- result[i] = result[i - 1] + import_core14.vec3.dist(prevP, p);
1731
+ result[i] = result[i - 1] + import_core7.vec3.dist(prevP, p);
3958
1732
  }
3959
1733
  prevP = p;
3960
1734
  }
@@ -3966,13 +1740,31 @@ PathStyleExtension.defaultProps = defaultProps3;
3966
1740
  PathStyleExtension.extensionName = "PathStyleExtension";
3967
1741
  var path_style_extension_default = PathStyleExtension;
3968
1742
 
1743
+ // dist/fill-style/fill-style-extension.js
1744
+ var import_core9 = require("@deck.gl/core");
1745
+
3969
1746
  // dist/fill-style/shader-module.js
1747
+ var import_core8 = require("@deck.gl/core");
1748
+ var FILL_UV_SCALE = 512 / 4e7;
1749
+ function getPatternUnitScale(sizeUnits, viewport) {
1750
+ switch (sizeUnits) {
1751
+ case "pixels":
1752
+ return 2 ** -Math.round(viewport.zoom);
1753
+ case "common":
1754
+ return 1;
1755
+ default:
1756
+ return FILL_UV_SCALE;
1757
+ }
1758
+ }
3970
1759
  var uniformBlock3 = (
3971
1760
  /* glsl */
3972
1761
  `layout(std140) uniform fillUniforms {
3973
1762
  vec2 patternTextureSize;
1763
+ float patternUnitScale;
3974
1764
  bool patternEnabled;
3975
1765
  bool patternMask;
1766
+ bool procedural;
1767
+ bool flipY;
3976
1768
  vec2 uvCoordinateOrigin;
3977
1769
  vec2 uvCoordinateOrigin64Low;
3978
1770
  } fill;
@@ -3981,16 +1773,23 @@ var uniformBlock3 = (
3981
1773
  var patternVs = (
3982
1774
  /* glsl */
3983
1775
  `
1776
+ uniform sampler2D fill_patternTexture;
1777
+
3984
1778
  in vec4 fillPatternFrames;
3985
1779
  in float fillPatternScales;
3986
1780
  in vec2 fillPatternOffsets;
1781
+ in vec4 fillPatternBackgroundColors;
3987
1782
 
3988
1783
  out vec2 fill_uv;
3989
1784
  out vec4 fill_patternBounds;
3990
1785
  out vec4 fill_patternPlacement;
1786
+ out vec4 fill_backgroundColor;
1787
+ out float fill_patternCoordinateScale;
1788
+ flat out vec4 fill_patternParams0;
1789
+ flat out vec4 fill_patternParams1;
3991
1790
  `
3992
1791
  );
3993
- var vs4 = `
1792
+ var vs3 = `
3994
1793
  ${uniformBlock3}
3995
1794
  ${patternVs}
3996
1795
  `;
@@ -4001,29 +1800,172 @@ uniform sampler2D fill_patternTexture;
4001
1800
 
4002
1801
  in vec4 fill_patternBounds;
4003
1802
  in vec4 fill_patternPlacement;
1803
+ in vec4 fill_backgroundColor;
4004
1804
  in vec2 fill_uv;
1805
+ in float fill_patternCoordinateScale;
1806
+ flat in vec4 fill_patternParams0;
1807
+ flat in vec4 fill_patternParams1;
1808
+
1809
+ const float FILL_PATTERN_HATCH = 1.0;
1810
+ const float FILL_PATTERN_CROSS_HATCH = 2.0;
1811
+ const float FILL_PATTERN_DOTS = 3.0;
1812
+
1813
+ float fill_getPatternCoordinate(vec2 axis, float period, float offset) {
1814
+ float coordinateScale = max(abs(fill_patternCoordinateScale), 1.0e-20);
1815
+ vec2 coordinateOrigin = fill.uvCoordinateOrigin;
1816
+ vec2 coordinateOffset = fill.uvCoordinateOrigin64Low + fill_uv;
1817
+ float yDirection = fill.flipY ? 1.0 : -1.0;
1818
+ coordinateOrigin.y *= yDirection;
1819
+ coordinateOffset.y *= yDirection;
1820
+
1821
+ // Reduce the high part before adding the local offset to retain precision in large coordinates.
1822
+ float highPart = mod(dot(coordinateOrigin, axis) / coordinateScale, period);
1823
+ float lowPart = dot(coordinateOffset, axis) / coordinateScale;
1824
+ return mod(highPart + lowPart + offset * period, period);
1825
+ }
1826
+
1827
+ vec2 fill_getPatternCoords(
1828
+ vec2 axis0,
1829
+ vec2 axis1,
1830
+ vec2 period,
1831
+ vec2 offset
1832
+ ) {
1833
+ return vec2(
1834
+ fill_getPatternCoordinate(axis0, period.x, offset.x),
1835
+ fill_getPatternCoordinate(axis1, period.y, offset.y)
1836
+ );
1837
+ }
1838
+
1839
+ float fill_getScreenSpaceAlpha(float signedDistance) {
1840
+ float distanceDerivative = fwidth(signedDistance);
1841
+ if (distanceDerivative == 0.0) {
1842
+ return signedDistance <= 0.0 ? 1.0 : 0.0;
1843
+ }
1844
+ // Normalize the SDF to screen pixels so the coverage ramp is independent of pattern units.
1845
+ float distanceInPixels = signedDistance / distanceDerivative;
1846
+ return 1.0 - smoothstep(-0.5, 0.5, distanceInPixels);
1847
+ }
1848
+
1849
+ float fill_getLineAlpha(float position, float center, float period, float strokeWidth) {
1850
+ float distanceToLine = abs(mod(position - center + period * 0.5, period) - period * 0.5);
1851
+ return fill_getScreenSpaceAlpha(distanceToLine - strokeWidth * 0.5);
1852
+ }
1853
+
1854
+ float fill_getHatchAlpha(float angle, float strokeWidth, vec2 gaps, bool alternating) {
1855
+ vec2 lineDirection = vec2(cos(angle), sin(angle));
1856
+ vec2 lineNormal = vec2(-lineDirection.y, lineDirection.x);
1857
+ float period = alternating
1858
+ ? strokeWidth * 2.0 + gaps.x + gaps.y
1859
+ : strokeWidth + gaps.x;
1860
+ float offset = dot(fill_patternPlacement.xy, lineNormal);
1861
+ float position = fill_getPatternCoordinate(lineNormal, period, offset);
1862
+ float alpha = fill_getLineAlpha(position, 0.0, period, strokeWidth);
1863
+ if (alternating) {
1864
+ alpha = max(
1865
+ alpha,
1866
+ fill_getLineAlpha(position, strokeWidth + gaps.x, period, strokeWidth)
1867
+ );
1868
+ }
1869
+ return alpha;
1870
+ }
1871
+
1872
+ float fill_getDotAlpha(float angle, float skew, float radius, float gap) {
1873
+ vec2 axis0 = vec2(cos(angle), sin(angle));
1874
+ float axis1Angle = angle + 1.5707963267948966 - skew;
1875
+ vec2 axis1 = vec2(cos(axis1Angle), sin(axis1Angle));
1876
+ float determinant = axis0.x * axis1.y - axis0.y * axis1.x;
1877
+
1878
+ // The reciprocal basis maps common coordinates into the skewed dot lattice.
1879
+ vec2 reciprocal0 = vec2(axis1.y, -axis1.x) / determinant;
1880
+ vec2 reciprocal1 = vec2(-axis0.y, axis0.x) / determinant;
1881
+ float period = radius * 2.0 + gap;
1882
+ vec2 latticeCoords = fill_getPatternCoords(
1883
+ reciprocal0,
1884
+ reciprocal1,
1885
+ vec2(period),
1886
+ fill_patternPlacement.xy
1887
+ );
1888
+ vec2 cellOffset = mod(latticeCoords + period * 0.5, period) - period * 0.5;
1889
+ float distanceToDotSquared = 1.0e20;
1890
+ // In a skewed lattice the closest dot is not necessarily in the independently wrapped cell.
1891
+ // Include adjacent cells to keep the repeated distance field continuous at cell boundaries.
1892
+ for (int x = -1; x <= 1; x++) {
1893
+ for (int y = -1; y <= 1; y++) {
1894
+ vec2 neighborOffset = cellOffset + vec2(float(x), float(y)) * period;
1895
+ vec2 dotOffset = axis0 * neighborOffset.x + axis1 * neighborOffset.y;
1896
+ distanceToDotSquared = min(distanceToDotSquared, dot(dotOffset, dotOffset));
1897
+ }
1898
+ }
1899
+ float distanceToDot = sqrt(distanceToDotSquared);
1900
+ return fill_getScreenSpaceAlpha(distanceToDot - radius);
1901
+ }
1902
+
1903
+ float fill_getProceduralPatternAlpha() {
1904
+ float patternType = fill_patternParams0.x;
1905
+ float size = fill_patternParams0.y;
1906
+ vec2 gaps = fill_patternParams0.zw;
1907
+ vec2 angles = fill_patternParams1.xy;
1908
+ float elementCount = fill_patternParams1.z;
1909
+
1910
+ if (patternType == FILL_PATTERN_HATCH) {
1911
+ return fill_getHatchAlpha(angles.x, size, gaps, elementCount == 2.0);
1912
+ }
1913
+ if (patternType == FILL_PATTERN_CROSS_HATCH) {
1914
+ return max(
1915
+ fill_getHatchAlpha(angles.x, size, gaps, false),
1916
+ fill_getHatchAlpha(angles.y, size, gaps, false)
1917
+ );
1918
+ }
1919
+ if (patternType == FILL_PATTERN_DOTS) {
1920
+ return fill_getDotAlpha(angles.x, angles.y, size, gaps.x);
1921
+ }
1922
+ return 1.0;
1923
+ }
4005
1924
 
4006
- const float FILL_UV_SCALE = 512.0 / 40000000.0;
1925
+ // Draw the pattern over the background fill (Porter-Duff source-over)
1926
+ vec4 fill_blendOverBackground(vec4 pattern, vec4 background) {
1927
+ if (background.a == 0.0 || layer.opacity == 0.0) return pattern;
1928
+ float patternAlpha = pattern.a / layer.opacity;
1929
+ float blendedAlpha = patternAlpha + background.a * (1.0 - patternAlpha);
1930
+ vec3 blendedRGB = mix(background.rgb, pattern.rgb, patternAlpha / blendedAlpha);
1931
+ return vec4(blendedRGB, blendedAlpha * layer.opacity);
1932
+ }
4007
1933
  `
4008
1934
  );
4009
- var fs4 = `
1935
+ var fs3 = `
4010
1936
  ${uniformBlock3}
4011
1937
  ${patternFs}
4012
1938
  `;
4013
1939
  var inject3 = {
4014
1940
  "vs:DECKGL_FILTER_GL_POSITION": (
4015
- /* glsl */
4016
- `
4017
- fill_uv = geometry.position.xy;
4018
- `
4019
- ),
4020
- "vs:DECKGL_FILTER_COLOR": (
4021
1941
  /* glsl */
4022
1942
  `
4023
1943
  if (fill.patternEnabled) {
4024
- fill_patternBounds = fillPatternFrames / vec4(fill.patternTextureSize, fill.patternTextureSize);
4025
1944
  fill_patternPlacement.xy = fillPatternOffsets;
4026
- fill_patternPlacement.zw = fillPatternScales * fillPatternFrames.zw;
1945
+ fill_backgroundColor = fillPatternBackgroundColors;
1946
+ if (fill.procedural) {
1947
+ fill_uv = geometry.position.xy;
1948
+ fill_patternCoordinateScale = fill.patternUnitScale * fillPatternScales;
1949
+ int texelIndex = int(fillPatternFrames.x) * 4;
1950
+ fill_patternParams0 = vec4(
1951
+ texelFetch(fill_patternTexture, ivec2(texelIndex, 0), 0).rg,
1952
+ texelFetch(fill_patternTexture, ivec2(texelIndex + 1, 0), 0).rg
1953
+ );
1954
+ fill_patternParams1 = vec4(
1955
+ texelFetch(fill_patternTexture, ivec2(texelIndex + 2, 0), 0).rg,
1956
+ texelFetch(fill_patternTexture, ivec2(texelIndex + 3, 0), 0).rg
1957
+ );
1958
+ } else {
1959
+ fill_patternBounds = fillPatternFrames / vec4(fill.patternTextureSize, fill.patternTextureSize);
1960
+ vec2 patternFrameCommon = fill.patternUnitScale * fillPatternScales * fillPatternFrames.zw;
1961
+ // Reduce the coordinate origin to within one tile before adding the vertex position. The
1962
+ // origin is large in common space, and fp32 cannot carry the sum at full precision.
1963
+ vec2 origin = mod(fill.uvCoordinateOrigin, patternFrameCommon) + fill.uvCoordinateOrigin64Low;
1964
+ fill_uv = (origin + geometry.position.xy) / patternFrameCommon;
1965
+ // Pattern atlases use top-left coordinates, so reverse common-space Y in bottom-left views.
1966
+ fill_uv.y *= fill.flipY ? 1.0 : -1.0;
1967
+ fill_uv += fillPatternOffsets;
1968
+ }
4027
1969
  }
4028
1970
  `
4029
1971
  ),
@@ -4031,22 +1973,31 @@ var inject3 = {
4031
1973
  /* glsl */
4032
1974
  `
4033
1975
  if (fill.patternEnabled) {
4034
- vec2 scale = FILL_UV_SCALE * fill_patternPlacement.zw;
4035
- vec2 patternUV = mod(mod(fill.uvCoordinateOrigin, scale) + fill.uvCoordinateOrigin64Low + fill_uv, scale) / scale;
4036
- patternUV = mod(fill_patternPlacement.xy + patternUV, 1.0);
4037
-
4038
- vec2 texCoords = fill_patternBounds.xy + fill_patternBounds.zw * patternUV;
4039
-
4040
- vec4 patternColor = texture(fill_patternTexture, texCoords);
4041
- color.a *= patternColor.a;
4042
- if (!fill.patternMask) {
4043
- color.rgb = patternColor.rgb;
1976
+ if (fill.procedural) {
1977
+ color.a *= fill_getProceduralPatternAlpha();
1978
+ } else {
1979
+ vec2 patternUV = fract(fill_uv);
1980
+ vec2 texCoords = fill_patternBounds.xy + fill_patternBounds.zw * patternUV;
1981
+
1982
+ // Tiling is emulated by wrapping the coordinate, so texCoords jumps from the end of the
1983
+ // frame back to its start once per tile, leading to the wrong mip level being selected,
1984
+ // which leads to artifacts at pattern edges. fill_uv is continuous across the primitive,
1985
+ // meaning that the correct mip level is always selected
1986
+ vec4 grad = fill_patternBounds.zwzw * vec4(dFdx(fill_uv), dFdy(fill_uv));
1987
+ vec4 patternColor = textureGrad(fill_patternTexture, texCoords, grad.xy, grad.zw);
1988
+
1989
+ color.a *= patternColor.a;
1990
+ if (!fill.patternMask) {
1991
+ color.rgb = patternColor.rgb;
1992
+ }
4044
1993
  }
1994
+ color = fill_blendOverBackground(color, fill_backgroundColor);
4045
1995
  }
4046
1996
  `
4047
1997
  )
4048
1998
  };
4049
1999
  function getPatternUniforms(opts) {
2000
+ var _a;
4050
2001
  if (!opts) {
4051
2002
  return {};
4052
2003
  }
@@ -4057,54 +2008,200 @@ function getPatternUniforms(opts) {
4057
2008
  uniforms.patternTextureSize = [fillPatternTexture.width, fillPatternTexture.height];
4058
2009
  }
4059
2010
  if ("project" in opts) {
4060
- const { fillPatternMask = true, fillPatternEnabled = true } = opts;
4061
- const projectUniforms = project_default.getUniforms(opts.project);
2011
+ const { fillPatternMask = true, fillPatternEnabled = true, fillPatternSizeUnits = "meters", fillPatternCommonFrame = null, procedural = false } = opts;
2012
+ const projectUniforms = import_core8.project.getUniforms(opts.project);
4062
2013
  const { commonOrigin: coordinateOriginCommon } = projectUniforms;
4063
- const coordinateOriginCommon64Low = [
4064
- fp64LowPart(coordinateOriginCommon[0]),
4065
- fp64LowPart(coordinateOriginCommon[1])
4066
- ];
4067
- uniforms.uvCoordinateOrigin = coordinateOriginCommon.slice(0, 2);
4068
- uniforms.uvCoordinateOrigin64Low = coordinateOriginCommon64Low;
2014
+ const unitScale = getPatternUnitScale(fillPatternSizeUnits, opts.project.viewport);
2015
+ const origin = [coordinateOriginCommon[0], coordinateOriginCommon[1]];
2016
+ if (fillPatternCommonFrame) {
2017
+ origin[0] %= unitScale * fillPatternCommonFrame[0];
2018
+ origin[1] %= unitScale * fillPatternCommonFrame[1];
2019
+ }
2020
+ uniforms.uvCoordinateOrigin = origin;
2021
+ uniforms.uvCoordinateOrigin64Low = [(0, import_core8.fp64LowPart)(origin[0]), (0, import_core8.fp64LowPart)(origin[1])];
2022
+ uniforms.patternUnitScale = unitScale;
4069
2023
  uniforms.patternMask = fillPatternMask;
4070
2024
  uniforms.patternEnabled = fillPatternEnabled;
2025
+ uniforms.procedural = procedural;
2026
+ uniforms.flipY = ((_a = opts.project.viewport) == null ? void 0 : _a.flipY) ?? false;
4071
2027
  }
4072
2028
  return uniforms;
4073
2029
  }
4074
2030
  var patternShaders = {
4075
2031
  name: "fill",
4076
- vs: vs4,
4077
- fs: fs4,
2032
+ vs: vs3,
2033
+ fs: fs3,
4078
2034
  inject: inject3,
4079
- dependencies: [project_default],
2035
+ dependencies: [import_core8.project],
4080
2036
  getUniforms: getPatternUniforms,
4081
2037
  uniformTypes: {
4082
2038
  patternTextureSize: "vec2<f32>",
2039
+ patternUnitScale: "f32",
4083
2040
  patternEnabled: "i32",
4084
2041
  patternMask: "i32",
2042
+ procedural: "i32",
2043
+ flipY: "i32",
4085
2044
  uvCoordinateOrigin: "vec2<f32>",
4086
2045
  uvCoordinateOrigin64Low: "vec2<f32>"
4087
2046
  }
4088
2047
  };
4089
2048
 
2049
+ // dist/fill-style/procedural-pattern.js
2050
+ var PROCEDURAL_PATTERN_TEXTURE_FORMAT = "rg32float";
2051
+ var PROCEDURAL_PATTERN_COMPONENTS_PER_TEXEL = 2;
2052
+ var PROCEDURAL_PATTERN_TEXELS_PER_PATTERN = 4;
2053
+ var PROCEDURAL_PATTERN_TYPES = {
2054
+ none: 0,
2055
+ hatch: 1,
2056
+ crossHatch: 2,
2057
+ dots: 3
2058
+ };
2059
+ var PROCEDURAL_PATTERN_OFFSETS = {
2060
+ type: 0,
2061
+ size: 1,
2062
+ gap0: 2,
2063
+ gap1: 3,
2064
+ angle0: 4,
2065
+ angle1: 5,
2066
+ /** Number of alternating gaps, hatch directions, or dot-grid axes, depending on type. */
2067
+ elementCount: 6
2068
+ };
2069
+ var COMPONENTS_PER_PATTERN = PROCEDURAL_PATTERN_COMPONENTS_PER_TEXEL * PROCEDURAL_PATTERN_TEXELS_PER_PATTERN;
2070
+ var DEGREES_TO_RADIANS = Math.PI / 180;
2071
+ var DEFAULT_SIZE = 1;
2072
+ var DEFAULT_GAP = 1;
2073
+ var DEFAULT_HATCH_ANGLE = 0;
2074
+ var DEFAULT_CROSS_HATCH_ANGLES = [45, 135];
2075
+ var DEFAULT_DOT_ANGLE = 0;
2076
+ var DEFAULT_DOT_SKEW = 0;
2077
+ function packProceduralPatterns(mapping) {
2078
+ const entries = Object.entries(mapping);
2079
+ const data = new Float32Array((entries.length + 1) * COMPONENTS_PER_PATTERN);
2080
+ const patternIndices = /* @__PURE__ */ new Map();
2081
+ entries.forEach(([id, config], entryIndex) => {
2082
+ const patternIndex = entryIndex + 1;
2083
+ const offset = patternIndex * COMPONENTS_PER_PATTERN;
2084
+ patternIndices.set(id, patternIndex);
2085
+ switch (config.type) {
2086
+ case "hatch": {
2087
+ const gap = config.gap === void 0 ? DEFAULT_GAP : config.gap;
2088
+ const strokeWidth = config.strokeWidth === void 0 ? DEFAULT_SIZE : config.strokeWidth;
2089
+ const angle = config.angle === void 0 ? DEFAULT_HATCH_ANGLE : config.angle;
2090
+ if (Array.isArray(gap) && gap.length !== 2) {
2091
+ throw new Error(`${id}.gap must be a number or a two-element array`);
2092
+ }
2093
+ const gaps = Array.isArray(gap) ? gap : [gap, gap];
2094
+ validatePositive(strokeWidth, `${id}.strokeWidth`);
2095
+ validateNonNegative(gaps[0], `${id}.gap[0]`);
2096
+ validateNonNegative(gaps[1], `${id}.gap[1]`);
2097
+ validateAngle(angle, `${id}.angle`);
2098
+ data[offset + PROCEDURAL_PATTERN_OFFSETS.type] = PROCEDURAL_PATTERN_TYPES.hatch;
2099
+ data[offset + PROCEDURAL_PATTERN_OFFSETS.size] = strokeWidth;
2100
+ data[offset + PROCEDURAL_PATTERN_OFFSETS.gap0] = gaps[0];
2101
+ data[offset + PROCEDURAL_PATTERN_OFFSETS.gap1] = gaps[1];
2102
+ data[offset + PROCEDURAL_PATTERN_OFFSETS.angle0] = angle * DEGREES_TO_RADIANS;
2103
+ data[offset + PROCEDURAL_PATTERN_OFFSETS.elementCount] = Array.isArray(gap) ? 2 : 1;
2104
+ break;
2105
+ }
2106
+ case "cross-hatch": {
2107
+ const angles = config.angles === void 0 ? DEFAULT_CROSS_HATCH_ANGLES : config.angles;
2108
+ const strokeWidth = config.strokeWidth === void 0 ? DEFAULT_SIZE : config.strokeWidth;
2109
+ const gap = config.gap === void 0 ? DEFAULT_GAP : config.gap;
2110
+ if (!Array.isArray(angles) || angles.length !== 2) {
2111
+ throw new Error(`${id}.angles must be a two-element array`);
2112
+ }
2113
+ validatePositive(strokeWidth, `${id}.strokeWidth`);
2114
+ validateNonNegative(gap, `${id}.gap`);
2115
+ validateAngle(angles[0], `${id}.angles[0]`);
2116
+ validateAngle(angles[1], `${id}.angles[1]`);
2117
+ data[offset + PROCEDURAL_PATTERN_OFFSETS.type] = PROCEDURAL_PATTERN_TYPES.crossHatch;
2118
+ data[offset + PROCEDURAL_PATTERN_OFFSETS.size] = strokeWidth;
2119
+ data[offset + PROCEDURAL_PATTERN_OFFSETS.gap0] = gap;
2120
+ data[offset + PROCEDURAL_PATTERN_OFFSETS.gap1] = gap;
2121
+ data[offset + PROCEDURAL_PATTERN_OFFSETS.angle0] = angles[0] * DEGREES_TO_RADIANS;
2122
+ data[offset + PROCEDURAL_PATTERN_OFFSETS.angle1] = angles[1] * DEGREES_TO_RADIANS;
2123
+ data[offset + PROCEDURAL_PATTERN_OFFSETS.elementCount] = 2;
2124
+ break;
2125
+ }
2126
+ case "dots": {
2127
+ const radius = config.radius === void 0 ? DEFAULT_SIZE : config.radius;
2128
+ const gap = config.gap === void 0 ? DEFAULT_GAP : config.gap;
2129
+ const angle = config.angle === void 0 ? DEFAULT_DOT_ANGLE : config.angle;
2130
+ const skew = config.skew === void 0 ? DEFAULT_DOT_SKEW : config.skew;
2131
+ validatePositive(radius, `${id}.radius`);
2132
+ validateNonNegative(gap, `${id}.gap`);
2133
+ validateAngle(angle, `${id}.angle`);
2134
+ validateSkew(skew, `${id}.skew`);
2135
+ data[offset + PROCEDURAL_PATTERN_OFFSETS.type] = PROCEDURAL_PATTERN_TYPES.dots;
2136
+ data[offset + PROCEDURAL_PATTERN_OFFSETS.size] = radius;
2137
+ data[offset + PROCEDURAL_PATTERN_OFFSETS.gap0] = gap;
2138
+ data[offset + PROCEDURAL_PATTERN_OFFSETS.gap1] = gap;
2139
+ data[offset + PROCEDURAL_PATTERN_OFFSETS.angle0] = angle * DEGREES_TO_RADIANS;
2140
+ data[offset + PROCEDURAL_PATTERN_OFFSETS.angle1] = skew * DEGREES_TO_RADIANS;
2141
+ data[offset + PROCEDURAL_PATTERN_OFFSETS.elementCount] = 2;
2142
+ break;
2143
+ }
2144
+ default:
2145
+ throw new Error(`${id}.type is not a supported procedural pattern type`);
2146
+ }
2147
+ });
2148
+ return {
2149
+ data,
2150
+ width: data.length / PROCEDURAL_PATTERN_COMPONENTS_PER_TEXEL,
2151
+ height: 1,
2152
+ patternIndices
2153
+ };
2154
+ }
2155
+ function validatePositive(value, name) {
2156
+ if (!Number.isFinite(value) || value <= 0) {
2157
+ throw new Error(`${name} must be a finite number greater than 0`);
2158
+ }
2159
+ }
2160
+ function validateNonNegative(value, name) {
2161
+ if (!Number.isFinite(value) || value < 0) {
2162
+ throw new Error(`${name} must be a finite number greater than or equal to 0`);
2163
+ }
2164
+ }
2165
+ function validateAngle(value, name) {
2166
+ if (!Number.isFinite(value)) {
2167
+ throw new Error(`${name} must be a finite number`);
2168
+ }
2169
+ }
2170
+ function validateSkew(value, name) {
2171
+ if (!Number.isFinite(value) || value <= -90 || value >= 90) {
2172
+ throw new Error(`${name} must be a finite number greater than -90 and less than 90`);
2173
+ }
2174
+ }
2175
+
4090
2176
  // dist/fill-style/fill-style-extension.js
2177
+ function leastCommonMultiple(a, b) {
2178
+ if (!Number.isInteger(b) || b <= 0)
2179
+ return 0;
2180
+ if (a === 0)
2181
+ return b;
2182
+ let [x, y] = [a, b];
2183
+ while (y > 0)
2184
+ [x, y] = [y, x % y];
2185
+ return a / x * b;
2186
+ }
4091
2187
  var defaultProps4 = {
4092
2188
  fillPatternEnabled: true,
4093
2189
  fillPatternAtlas: {
4094
2190
  type: "image",
4095
2191
  value: null,
4096
- async: true,
4097
- parameters: { lodMaxClamp: 0 }
2192
+ async: true
4098
2193
  },
4099
2194
  fillPatternMapping: { type: "object", value: {}, async: true },
4100
2195
  fillPatternMask: true,
2196
+ fillPatternSizeUnits: "meters",
4101
2197
  getFillPattern: { type: "accessor", value: (d) => d.pattern },
4102
2198
  getFillPatternScale: { type: "accessor", value: 1 },
4103
- getFillPatternOffset: { type: "accessor", value: [0, 0] }
2199
+ getFillPatternOffset: { type: "accessor", value: [0, 0] },
2200
+ getFillPatternBackgroundColor: { type: "accessor", value: [0, 0, 0, 0] }
4104
2201
  };
4105
- var FillStyleExtension = class extends LayerExtension {
4106
- constructor({ pattern = false } = {}) {
4107
- super({ pattern });
2202
+ var FillStyleExtension = class extends import_core9.LayerExtension {
2203
+ constructor({ pattern = false, proceduralPattern = false } = {}) {
2204
+ super({ pattern: pattern || proceduralPattern, proceduralPattern });
4108
2205
  }
4109
2206
  isEnabled(layer) {
4110
2207
  return layer.getAttributeManager() !== null && !("pathTesselator" in layer.state);
@@ -4128,7 +2225,7 @@ var FillStyleExtension = class extends LayerExtension {
4128
2225
  size: 4,
4129
2226
  stepMode: "dynamic",
4130
2227
  accessor: "getFillPattern",
4131
- transform: extension.getPatternFrame.bind(this)
2228
+ transform: extension.opts.proceduralPattern ? extension.getProceduralPatternIndex.bind(this) : extension.getPatternFrame.bind(this)
4132
2229
  },
4133
2230
  fillPatternScales: {
4134
2231
  size: 1,
@@ -4140,6 +2237,13 @@ var FillStyleExtension = class extends LayerExtension {
4140
2237
  size: 2,
4141
2238
  stepMode: "dynamic",
4142
2239
  accessor: "getFillPatternOffset"
2240
+ },
2241
+ fillPatternBackgroundColors: {
2242
+ size: 4,
2243
+ type: "unorm8",
2244
+ stepMode: "dynamic",
2245
+ accessor: "getFillPatternBackgroundColor",
2246
+ defaultValue: [0, 0, 0, 255]
4143
2247
  }
4144
2248
  });
4145
2249
  }
@@ -4148,7 +2252,8 @@ var FillStyleExtension = class extends LayerExtension {
4148
2252
  data: new Uint8Array(4),
4149
2253
  width: 1,
4150
2254
  height: 1
4151
- })
2255
+ }),
2256
+ ...extension.opts.proceduralPattern && extension.createProceduralPatternTexture.call(this, {})
4152
2257
  });
4153
2258
  }
4154
2259
  updateState({ props, oldProps }, extension) {
@@ -4156,30 +2261,81 @@ var FillStyleExtension = class extends LayerExtension {
4156
2261
  return;
4157
2262
  }
4158
2263
  if (props.fillPatternMapping && props.fillPatternMapping !== oldProps.fillPatternMapping) {
2264
+ if (extension.opts.proceduralPattern && typeof props.fillPatternMapping !== "string") {
2265
+ const oldTexture = this.state.proceduralPatternTexture;
2266
+ this.setState(extension.createProceduralPatternTexture.call(this, props.fillPatternMapping));
2267
+ oldTexture == null ? void 0 : oldTexture.delete();
2268
+ }
4159
2269
  this.getAttributeManager().invalidate("getFillPattern");
4160
2270
  }
2271
+ if (props.fillPatternMapping !== oldProps.fillPatternMapping || props.getFillPatternScale !== oldProps.getFillPatternScale) {
2272
+ this.setState({ commonFrame: extension.getCommonFrame(props) });
2273
+ }
4161
2274
  }
4162
2275
  draw(params, extension) {
4163
2276
  if (!extension.isEnabled(this)) {
4164
2277
  return;
4165
2278
  }
4166
- const { fillPatternAtlas, fillPatternEnabled, fillPatternMask } = this.props;
2279
+ const { fillPatternAtlas, fillPatternEnabled, fillPatternMask, fillPatternSizeUnits } = this.props;
4167
2280
  const fillProps = {
4168
2281
  project: params.shaderModuleProps.project,
4169
2282
  fillPatternEnabled,
4170
2283
  fillPatternMask,
4171
- fillPatternTexture: fillPatternAtlas || this.state.emptyTexture
2284
+ fillPatternSizeUnits,
2285
+ procedural: extension.opts.proceduralPattern,
2286
+ fillPatternTexture: extension.opts.proceduralPattern ? this.state.proceduralPatternTexture || this.state.emptyTexture : fillPatternAtlas || this.state.emptyTexture,
2287
+ fillPatternCommonFrame: this.state.commonFrame
4172
2288
  };
4173
2289
  this.setShaderModuleProps({ fill: fillProps });
4174
2290
  }
4175
2291
  finalizeState() {
4176
2292
  const emptyTexture = this.state.emptyTexture;
4177
2293
  emptyTexture == null ? void 0 : emptyTexture.delete();
2294
+ const proceduralPatternTexture = this.state.proceduralPatternTexture;
2295
+ proceduralPatternTexture == null ? void 0 : proceduralPatternTexture.delete();
4178
2296
  }
4179
2297
  getPatternFrame(name) {
4180
2298
  const { fillPatternMapping } = this.getCurrentLayer().props;
4181
2299
  const def = fillPatternMapping && fillPatternMapping[name];
4182
- return def ? [def.x, def.y, def.width, def.height] : [0, 0, 0, 0];
2300
+ return def && "x" in def ? [def.x, def.y, def.width, def.height] : [0, 0, 0, 0];
2301
+ }
2302
+ /**
2303
+ * Returns common frame into which all patterns fit as integer multiples
2304
+ */
2305
+ getCommonFrame(props) {
2306
+ const { fillPatternMapping, getFillPatternScale: scale } = props;
2307
+ if (typeof scale !== "number" || !(scale > 0) || typeof fillPatternMapping !== "object") {
2308
+ return null;
2309
+ }
2310
+ let width = 0;
2311
+ let height = 0;
2312
+ for (const name in fillPatternMapping) {
2313
+ const frame = fillPatternMapping[name];
2314
+ if (!("width" in frame))
2315
+ return null;
2316
+ width = leastCommonMultiple(width, frame.width);
2317
+ height = leastCommonMultiple(height, frame.height);
2318
+ if (!width || !height)
2319
+ return null;
2320
+ }
2321
+ return width ? [scale * width, scale * height] : null;
2322
+ }
2323
+ getProceduralPatternIndex(name) {
2324
+ const patternIndices = this.state.proceduralPatternIndices;
2325
+ return [(patternIndices == null ? void 0 : patternIndices.get(name)) ?? 0, 0, 0, 0];
2326
+ }
2327
+ createProceduralPatternTexture(mapping) {
2328
+ const packedPatterns = packProceduralPatterns(mapping);
2329
+ return {
2330
+ proceduralPatternIndices: packedPatterns.patternIndices,
2331
+ proceduralPatternTexture: this.context.device.createTexture({
2332
+ data: packedPatterns.data,
2333
+ width: packedPatterns.width,
2334
+ height: packedPatterns.height,
2335
+ format: PROCEDURAL_PATTERN_TEXTURE_FORMAT,
2336
+ sampler: { minFilter: "nearest", magFilter: "nearest" }
2337
+ })
2338
+ };
4183
2339
  }
4184
2340
  };
4185
2341
  FillStyleExtension.defaultProps = defaultProps4;
@@ -4187,6 +2343,7 @@ FillStyleExtension.extensionName = "FillStyleExtension";
4187
2343
  var fill_style_extension_default = FillStyleExtension;
4188
2344
 
4189
2345
  // dist/clip/clip-extension.js
2346
+ var import_core10 = require("@deck.gl/core");
4190
2347
  var defaultProps5 = {
4191
2348
  clipBounds: [0, 0, 1, 1],
4192
2349
  clipByInstance: void 0
@@ -4269,7 +2426,7 @@ in vec2 clip_commonPosition;
4269
2426
  `
4270
2427
  )
4271
2428
  };
4272
- var ClipExtension = class extends LayerExtension {
2429
+ var ClipExtension = class extends import_core10.LayerExtension {
4273
2430
  getShaders() {
4274
2431
  let clipByInstance = "instancePositions" in this.getAttributeManager().attributes;
4275
2432
  if (this.props.clipByInstance !== void 0) {
@@ -4314,8 +2471,12 @@ ClipExtension.defaultProps = defaultProps5;
4314
2471
  ClipExtension.extensionName = "ClipExtension";
4315
2472
  var clip_extension_default = ClipExtension;
4316
2473
 
2474
+ // dist/collision-filter/collision-filter-extension.js
2475
+ var import_core15 = require("@deck.gl/core");
2476
+
4317
2477
  // dist/collision-filter/shader-module.js
4318
- var vs5 = (
2478
+ var import_core11 = require("@deck.gl/core");
2479
+ var vs4 = (
4319
2480
  /* glsl */
4320
2481
  `
4321
2482
  in float collisionPriorities;
@@ -4413,8 +2574,8 @@ var getCollisionUniforms = (opts) => {
4413
2574
  };
4414
2575
  var shader_module_default2 = {
4415
2576
  name: "collision",
4416
- dependencies: [project_default],
4417
- vs: vs5,
2577
+ dependencies: [import_core11.project],
2578
+ vs: vs4,
4418
2579
  inject: inject4,
4419
2580
  getUniforms: getCollisionUniforms,
4420
2581
  uniformTypes: {
@@ -4424,10 +2585,12 @@ var shader_module_default2 = {
4424
2585
  };
4425
2586
 
4426
2587
  // dist/collision-filter/collision-filter-effect.js
4427
- var import_core20 = require("@math.gl/core");
2588
+ var import_core13 = require("@math.gl/core");
2589
+ var import_core14 = require("@deck.gl/core");
4428
2590
 
4429
2591
  // dist/collision-filter/collision-filter-pass.js
4430
- var CollisionFilterPass = class extends LayersPass {
2592
+ var import_core12 = require("@deck.gl/core");
2593
+ var CollisionFilterPass = class extends import_core12._LayersPass {
4431
2594
  renderCollisionMap(target, options) {
4432
2595
  const padding = 1;
4433
2596
  const clearColor = [0, 0, 0, 0];
@@ -4518,8 +2681,8 @@ var CollisionFilterEffect = class {
4518
2681
  }
4519
2682
  const needsRender = viewportChanged || // If render info is new
4520
2683
  renderInfo === oldRenderInfo || // If sublayers have changed
4521
- !deepEqual(oldRenderInfo.layers, renderInfo.layers, 1) || // If a sublayer's bounds have been updated
4522
- renderInfo.layerBounds.some((b, i) => !(0, import_core20.equals)(b, oldRenderInfo.layerBounds[i])) || // If a sublayer's isLoaded state has been updated
2684
+ !(0, import_core14._deepEqual)(oldRenderInfo.layers, renderInfo.layers, 1) || // If a sublayer's bounds have been updated
2685
+ renderInfo.layerBounds.some((b, i) => !(0, import_core13.equals)(b, oldRenderInfo.layerBounds[i])) || // If a sublayer's isLoaded state has been updated
4523
2686
  renderInfo.allLayersLoaded !== oldRenderInfo.allLayersLoaded || // Some prop is in transition
4524
2687
  renderInfo.layers.some((layer) => layer.props.transitions);
4525
2688
  this.channels[collisionGroup] = renderInfo;
@@ -4651,7 +2814,7 @@ var defaultProps6 = {
4651
2814
  collisionGroup: { type: "string", value: "default" },
4652
2815
  collisionTestProps: {}
4653
2816
  };
4654
- var CollisionFilterExtension = class extends LayerExtension {
2817
+ var CollisionFilterExtension = class extends import_core15.LayerExtension {
4655
2818
  getShaders() {
4656
2819
  return { modules: [shader_module_default2] };
4657
2820
  }
@@ -4685,7 +2848,11 @@ CollisionFilterExtension.defaultProps = defaultProps6;
4685
2848
  CollisionFilterExtension.extensionName = "CollisionFilterExtension";
4686
2849
  var collision_filter_extension_default = CollisionFilterExtension;
4687
2850
 
2851
+ // dist/mask/mask-extension.js
2852
+ var import_core21 = require("@deck.gl/core");
2853
+
4688
2854
  // dist/mask/shader-module.js
2855
+ var import_core16 = require("@deck.gl/core");
4689
2856
  var uniformBlock4 = (
4690
2857
  /* glsl */
4691
2858
  `layout(std140) uniform maskUniforms {
@@ -4705,7 +2872,7 @@ vec2 mask_getCoords(vec4 position) {
4705
2872
  }
4706
2873
  `
4707
2874
  );
4708
- var vs6 = `
2875
+ var vs5 = `
4709
2876
  ${uniformBlock4}
4710
2877
  ${vertex3}
4711
2878
  `;
@@ -4738,7 +2905,7 @@ bool mask_isInBounds(vec2 texCoords) {
4738
2905
  }
4739
2906
  `
4740
2907
  );
4741
- var fs5 = `
2908
+ var fs4 = `
4742
2909
  ${uniformBlock4}
4743
2910
  ${fragment3}
4744
2911
  `;
@@ -4792,9 +2959,9 @@ var getMaskUniforms = (opts) => {
4792
2959
  };
4793
2960
  var shader_module_default3 = {
4794
2961
  name: "mask",
4795
- dependencies: [project_default],
4796
- vs: vs6,
4797
- fs: fs5,
2962
+ dependencies: [import_core16.project],
2963
+ vs: vs5,
2964
+ fs: fs4,
4798
2965
  inject: inject5,
4799
2966
  getUniforms: getMaskUniforms,
4800
2967
  uniformTypes: {
@@ -4807,9 +2974,11 @@ var shader_module_default3 = {
4807
2974
  };
4808
2975
 
4809
2976
  // dist/mask/mask-effect.js
4810
- var import_core27 = require("@math.gl/core");
2977
+ var import_core19 = require("@deck.gl/core");
2978
+ var import_core20 = require("@math.gl/core");
4811
2979
 
4812
2980
  // dist/mask/mask-pass.js
2981
+ var import_core17 = require("@deck.gl/core");
4813
2982
  var MASK_BLENDING = {
4814
2983
  blendColorOperation: "subtract",
4815
2984
  blendColorSrcFactor: "zero",
@@ -4818,7 +2987,7 @@ var MASK_BLENDING = {
4818
2987
  blendAlphaSrcFactor: "zero",
4819
2988
  blendAlphaDstFactor: "one"
4820
2989
  };
4821
- var MaskPass = class extends LayersPass {
2990
+ var MaskPass = class extends import_core17._LayersPass {
4822
2991
  constructor(device, props) {
4823
2992
  super(device, props);
4824
2993
  const { mapSize = 2048 } = props;
@@ -4863,7 +3032,8 @@ var MaskPass = class extends LayersPass {
4863
3032
  };
4864
3033
 
4865
3034
  // dist/utils/projection-utils.js
4866
- var MERCATOR_REFERENCE_VIEWPORT = new WebMercatorViewport({
3035
+ var import_core18 = require("@deck.gl/core");
3036
+ var MERCATOR_REFERENCE_VIEWPORT = new import_core18.WebMercatorViewport({
4867
3037
  width: 1,
4868
3038
  height: 1,
4869
3039
  longitude: 0,
@@ -4925,7 +3095,7 @@ function makeViewport(opts) {
4925
3095
  zoom += Math.log2(r);
4926
3096
  }
4927
3097
  }
4928
- return isGeospatial ? new WebMercatorViewport({
3098
+ return isGeospatial ? new import_core18.WebMercatorViewport({
4929
3099
  id: viewport.id,
4930
3100
  x: border,
4931
3101
  y: border,
@@ -4935,7 +3105,7 @@ function makeViewport(opts) {
4935
3105
  latitude: centerWorld[1],
4936
3106
  zoom,
4937
3107
  orthographic: true
4938
- }) : new OrthographicViewport({
3108
+ }) : new import_core18.OrthographicViewport({
4939
3109
  id: viewport.id,
4940
3110
  x: border,
4941
3111
  y: border,
@@ -5028,7 +3198,7 @@ var MaskEffect = class {
5028
3198
  const viewport = viewports[0];
5029
3199
  const viewportChanged = !this.lastViewport || !this.lastViewport.equals(viewport);
5030
3200
  if (viewport.resolution !== void 0) {
5031
- log_default.warn("MaskExtension is not supported in GlobeView")();
3201
+ import_core19.log.warn("MaskExtension is not supported in GlobeView")();
5032
3202
  return { didRender };
5033
3203
  }
5034
3204
  for (const maskId in channelMap) {
@@ -5071,7 +3241,7 @@ var MaskEffect = class {
5071
3241
  this.lastViewport = viewport;
5072
3242
  const layerBounds = joinLayerBounds(channelInfo.layers, viewport);
5073
3243
  channelInfo.bounds = layerBounds && getRenderBounds(layerBounds, viewport);
5074
- if (maskChanged || !(0, import_core27.equals)(channelInfo.bounds, oldChannelInfo.bounds)) {
3244
+ if (maskChanged || !(0, import_core20.equals)(channelInfo.bounds, oldChannelInfo.bounds)) {
5075
3245
  const { maskPass, maskMap } = this;
5076
3246
  const maskViewport = layerBounds && makeViewport({
5077
3247
  bounds: channelInfo.bounds,
@@ -5122,7 +3292,7 @@ var MaskEffect = class {
5122
3292
  let channelInfo = channelMap[id];
5123
3293
  if (!channelInfo) {
5124
3294
  if (++channelCount > 4) {
5125
- log_default.warn("Too many mask layers. The max supported is 4")();
3295
+ import_core19.log.warn("Too many mask layers. The max supported is 4")();
5126
3296
  continue;
5127
3297
  }
5128
3298
  channelInfo = {
@@ -5183,7 +3353,7 @@ var defaultProps7 = {
5183
3353
  maskByInstance: void 0,
5184
3354
  maskInverted: false
5185
3355
  };
5186
- var MaskExtension = class extends LayerExtension {
3356
+ var MaskExtension = class extends import_core21.LayerExtension {
5187
3357
  initializeState() {
5188
3358
  var _a;
5189
3359
  (_a = this.context.deck) == null ? void 0 : _a._addDefaultEffect(new MaskEffect());
@@ -5211,8 +3381,8 @@ var MaskExtension = class extends LayerExtension {
5211
3381
  maskProps.enabled = true;
5212
3382
  maskProps.channel = index;
5213
3383
  maskProps.inverted = maskInverted;
5214
- if (fromCoordinateSystem === COORDINATE_SYSTEM.DEFAULT) {
5215
- fromCoordinateSystem = viewport.isGeospatial ? COORDINATE_SYSTEM.LNGLAT : COORDINATE_SYSTEM.CARTESIAN;
3384
+ if (fromCoordinateSystem === import_core21.COORDINATE_SYSTEM.DEFAULT) {
3385
+ fromCoordinateSystem = viewport.isGeospatial ? import_core21.COORDINATE_SYSTEM.LNGLAT : import_core21.COORDINATE_SYSTEM.CARTESIAN;
5216
3386
  }
5217
3387
  const opts = { modelMatrix: null, fromCoordinateOrigin, fromCoordinateSystem };
5218
3388
  const bl = this.projectPosition([bounds[0], bounds[1], 0], opts);
@@ -5220,7 +3390,7 @@ var MaskExtension = class extends LayerExtension {
5220
3390
  maskProps.bounds = [bl[0], bl[1], tr[0], tr[1]];
5221
3391
  } else {
5222
3392
  if (maskId) {
5223
- log_default.warn(`Could not find a mask layer with id: ${maskId}`)();
3393
+ import_core21.log.warn(`Could not find a mask layer with id: ${maskId}`)();
5224
3394
  }
5225
3395
  maskProps.enabled = false;
5226
3396
  }
@@ -5231,7 +3401,14 @@ MaskExtension.defaultProps = defaultProps7;
5231
3401
  MaskExtension.extensionName = "MaskExtension";
5232
3402
  var mask_extension_default = MaskExtension;
5233
3403
 
3404
+ // dist/terrain/terrain-extension.js
3405
+ var import_core28 = require("@deck.gl/core");
3406
+
3407
+ // dist/terrain/terrain-effect.js
3408
+ var import_core27 = require("@deck.gl/core");
3409
+
5234
3410
  // dist/terrain/shader-module.js
3411
+ var import_core22 = require("@deck.gl/core");
5235
3412
  var TERRAIN_MODE = {
5236
3413
  NONE: 0,
5237
3414
  /** A terrain layer rendering encoded ground elevation into the height map */
@@ -5260,7 +3437,7 @@ uniform sampler2D terrain_map;
5260
3437
  );
5261
3438
  var terrainModule = {
5262
3439
  name: "terrain",
5263
- dependencies: [project_default],
3440
+ dependencies: [import_core22.project],
5264
3441
  vs: `${uniformBlock5}
5265
3442
  out vec3 commonPos;
5266
3443
  // In globe mode, absolute Mercator position for terrain FBO UV lookups
@@ -5358,7 +3535,7 @@ if ((terrain.mode == TERRAIN_MODE_USE_COVER) || (terrain.mode == TERRAIN_MODE_US
5358
3535
  }
5359
3536
  if ("terrainSkipRender" in opts || "drawToTerrainHeightMap" in opts) {
5360
3537
  const { drawToTerrainHeightMap, heightMap, heightMapBounds, dummyHeightMap, terrainCover, useTerrainHeightMap, terrainSkipRender } = opts;
5361
- const projectUniforms = project_default.getUniforms(opts.project);
3538
+ const projectUniforms = import_core22.project.getUniforms(opts.project);
5362
3539
  const { commonOrigin } = projectUniforms;
5363
3540
  let mode = terrainSkipRender ? TERRAIN_MODE.SKIP : TERRAIN_MODE.NONE;
5364
3541
  let sampler = dummyHeightMap;
@@ -5408,7 +3585,11 @@ if ((terrain.mode == TERRAIN_MODE_USE_COVER) || (terrain.mode == TERRAIN_MODE_US
5408
3585
  }
5409
3586
  };
5410
3587
 
3588
+ // dist/terrain/terrain-cover.js
3589
+ var import_core23 = require("@deck.gl/core");
3590
+
5411
3591
  // dist/terrain/utils.js
3592
+ var import_constants = require("@luma.gl/webgl/constants");
5412
3593
  function createRenderTarget(device, opts) {
5413
3594
  return device.createFramebuffer({
5414
3595
  id: opts.id,
@@ -5522,7 +3703,7 @@ var TerrainCover = class {
5522
3703
  } else {
5523
3704
  const oldZoom = (_a = this.renderViewport) == null ? void 0 : _a.zoom;
5524
3705
  shouldRedraw = shouldRedraw || newZoom !== oldZoom;
5525
- const newBounds = viewport instanceof GlobeViewport ? this.targetBoundsCommon : getRenderBounds(this.targetBoundsCommon, viewport);
3706
+ const newBounds = viewport instanceof import_core23._GlobeViewport ? this.targetBoundsCommon : getRenderBounds(this.targetBoundsCommon, viewport);
5526
3707
  const oldBounds = this.bounds;
5527
3708
  shouldRedraw = shouldRedraw || !oldBounds || newBounds.some((x, i) => x !== oldBounds[i]);
5528
3709
  this.bounds = newBounds;
@@ -5599,6 +3780,7 @@ function intersect(b1, b2) {
5599
3780
  }
5600
3781
 
5601
3782
  // dist/terrain/terrain-pass.js
3783
+ var import_core24 = require("@deck.gl/core");
5602
3784
  var TERRAIN_BLENDING = {
5603
3785
  blendColorOperation: "max",
5604
3786
  blendColorSrcFactor: "one",
@@ -5607,7 +3789,7 @@ var TERRAIN_BLENDING = {
5607
3789
  blendAlphaSrcFactor: "one",
5608
3790
  blendAlphaDstFactor: "one"
5609
3791
  };
5610
- var TerrainPass = class extends LayersPass {
3792
+ var TerrainPass = class extends import_core24._LayersPass {
5611
3793
  getRenderableLayers(viewport, opts) {
5612
3794
  const { layers } = opts;
5613
3795
  const result = [];
@@ -5672,7 +3854,8 @@ var TerrainPass = class extends LayersPass {
5672
3854
  };
5673
3855
 
5674
3856
  // dist/terrain/terrain-picking-pass.js
5675
- var TerrainPickingPass = class extends PickLayersPass {
3857
+ var import_core25 = require("@deck.gl/core");
3858
+ var TerrainPickingPass = class extends import_core25._PickLayersPass {
5676
3859
  constructor() {
5677
3860
  super(...arguments);
5678
3861
  this.drawParameters = {};
@@ -5743,6 +3926,7 @@ var TerrainPickingPass = class extends PickLayersPass {
5743
3926
  };
5744
3927
 
5745
3928
  // dist/terrain/height-map-builder.js
3929
+ var import_core26 = require("@deck.gl/core");
5746
3930
  var MAP_MAX_SIZE = 2048;
5747
3931
  var HeightMapBuilder = class {
5748
3932
  static isSupported(device) {
@@ -5789,7 +3973,7 @@ var HeightMapBuilder = class {
5789
3973
  if (!this.layersBoundsCommon) {
5790
3974
  this.renderViewport = null;
5791
3975
  } else if (layersChanged || viewportChanged) {
5792
- const bounds = viewport instanceof GlobeViewport ? this.layersBoundsCommon : getRenderBounds(this.layersBoundsCommon, viewport);
3976
+ const bounds = viewport instanceof import_core26._GlobeViewport ? this.layersBoundsCommon : getRenderBounds(this.layersBoundsCommon, viewport);
5793
3977
  if (bounds[2] <= bounds[0] || bounds[3] <= bounds[1]) {
5794
3978
  this.renderViewport = null;
5795
3979
  return false;
@@ -5847,7 +4031,7 @@ var TerrainEffect = class {
5847
4031
  if (HeightMapBuilder.isSupported(device)) {
5848
4032
  this.heightMap = new HeightMapBuilder(device);
5849
4033
  } else {
5850
- log_default.warn("Terrain offset mode is not supported by this browser")();
4034
+ import_core27.log.warn("Terrain offset mode is not supported by this browser")();
5851
4035
  }
5852
4036
  deck._addDefaultShaderModule(terrainModule);
5853
4037
  }
@@ -6015,7 +4199,7 @@ var TerrainEffect = class {
6015
4199
  var defaultProps8 = {
6016
4200
  terrainDrawMode: void 0
6017
4201
  };
6018
- var TerrainExtension = class extends LayerExtension {
4202
+ var TerrainExtension = class extends import_core28.LayerExtension {
6019
4203
  getShaders() {
6020
4204
  return {
6021
4205
  modules: [terrainModule]