@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.
- package/dist/dist.dev.js +1281 -120
- package/dist/fill-style/fill-style-extension.d.ts +38 -6
- package/dist/fill-style/fill-style-extension.d.ts.map +1 -1
- package/dist/fill-style/fill-style-extension.js +88 -10
- package/dist/fill-style/fill-style-extension.js.map +1 -1
- package/dist/fill-style/procedural-pattern.d.ts +65 -0
- package/dist/fill-style/procedural-pattern.d.ts.map +1 -0
- package/dist/fill-style/procedural-pattern.js +135 -0
- package/dist/fill-style/procedural-pattern.js.map +1 -0
- package/dist/fill-style/shader-module.d.ts +13 -4
- package/dist/fill-style/shader-module.d.ts.map +1 -1
- package/dist/fill-style/shader-module.js +212 -21
- package/dist/fill-style/shader-module.js.map +1 -1
- package/dist/index.cjs +886 -2702
- package/dist/index.cjs.map +3 -3
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/mask/shader-module.d.ts +1 -0
- package/dist/mask/shader-module.d.ts.map +1 -1
- package/dist/path-style/path-style-extension.d.ts +49 -6
- package/dist/path-style/path-style-extension.d.ts.map +1 -1
- package/dist/path-style/path-style-extension.js +237 -37
- package/dist/path-style/path-style-extension.js.map +1 -1
- package/dist/path-style/shaders.glsl.d.ts +30 -1
- package/dist/path-style/shaders.glsl.d.ts.map +1 -1
- package/dist/path-style/shaders.glsl.js +136 -21
- package/dist/path-style/shaders.glsl.js.map +1 -1
- package/dist/terrain/shader-module.d.ts +1 -0
- package/dist/terrain/shader-module.d.ts.map +1 -1
- package/dist.min.js +377 -98
- package/package.json +7 -7
- package/src/fill-style/fill-style-extension.ts +135 -13
- package/src/fill-style/procedural-pattern.ts +203 -0
- package/src/fill-style/shader-module.ts +233 -23
- package/src/index.ts +10 -1
- package/src/path-style/path-style-extension.ts +350 -44
- 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
|
-
//
|
|
37
|
-
var
|
|
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
|
|
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
|
|
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: [
|
|
2660
|
-
vs
|
|
2661
|
-
fs
|
|
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
|
|
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
|
|
412
|
+
var fs2 = `
|
|
2939
413
|
${uniformBlock2}
|
|
2940
414
|
${fragment2}
|
|
2941
415
|
`;
|
|
2942
|
-
function
|
|
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 =
|
|
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:
|
|
3056
|
-
fs:
|
|
529
|
+
vs: vs2,
|
|
530
|
+
fs: fs2,
|
|
3057
531
|
inject: inject2,
|
|
3058
|
-
getUniforms
|
|
532
|
+
getUniforms,
|
|
3059
533
|
uniformTypesFromOptions
|
|
3060
534
|
};
|
|
3061
535
|
var dataFilter64 = {
|
|
3062
536
|
name: "dataFilter",
|
|
3063
|
-
vs:
|
|
3064
|
-
fs:
|
|
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
|
|
689
|
+
const defines = {};
|
|
3216
690
|
if (categorySize) {
|
|
3217
|
-
|
|
3218
|
-
|
|
691
|
+
defines.DATACATEGORY_TYPE = CATEGORY_TYPE_FROM_SIZE[categorySize];
|
|
692
|
+
defines.DATACATEGORY_CHANNELS = categorySize;
|
|
3219
693
|
}
|
|
3220
694
|
if (filterSize) {
|
|
3221
|
-
|
|
3222
|
-
|
|
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
|
|
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() || !
|
|
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
|
-
|
|
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
|
|
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 } =
|
|
970
|
+
var { fp64ify, fp64ifyMatrix4 } = import_shadertools.fp64;
|
|
3493
971
|
var project64_default = {
|
|
3494
972
|
name: "project64",
|
|
3495
|
-
dependencies: [
|
|
973
|
+
dependencies: [import_core4.project, import_shadertools.fp64],
|
|
3496
974
|
vs: project64_glsl_default,
|
|
3497
|
-
getUniforms:
|
|
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 =
|
|
3506
|
-
function
|
|
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
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
3602
|
-
|
|
3603
|
-
|
|
3604
|
-
if (
|
|
3605
|
-
|
|
3606
|
-
|
|
3607
|
-
|
|
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
|
-
|
|
3613
|
-
if (!
|
|
3614
|
-
|
|
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-
|
|
3822
|
-
|
|
3823
|
-
|
|
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
|
|
3839
|
-
|
|
3840
|
-
|
|
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
|
|
1570
|
+
const defines = {};
|
|
3879
1571
|
if (extension.opts.dash) {
|
|
3880
|
-
result =
|
|
3881
|
-
|
|
3882
|
-
|
|
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 =
|
|
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
|
|
1596
|
+
defines
|
|
3900
1597
|
};
|
|
3901
1598
|
}
|
|
3902
1599
|
initializeState(context, extension) {
|
|
3903
|
-
|
|
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] +
|
|
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
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
4035
|
-
|
|
4036
|
-
|
|
4037
|
-
|
|
4038
|
-
|
|
4039
|
-
|
|
4040
|
-
|
|
4041
|
-
|
|
4042
|
-
|
|
4043
|
-
|
|
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 =
|
|
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
|
|
4064
|
-
|
|
4065
|
-
|
|
4066
|
-
|
|
4067
|
-
|
|
4068
|
-
|
|
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:
|
|
4077
|
-
fs:
|
|
2032
|
+
vs: vs3,
|
|
2033
|
+
fs: fs3,
|
|
4078
2034
|
inject: inject3,
|
|
4079
|
-
dependencies: [
|
|
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
|
-
|
|
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
|
|
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: [
|
|
4417
|
-
vs:
|
|
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
|
|
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
|
|
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
|
-
!
|
|
4522
|
-
renderInfo.layerBounds.some((b, i) => !(0,
|
|
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
|
|
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
|
|
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: [
|
|
4796
|
-
vs:
|
|
4797
|
-
fs:
|
|
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
|
|
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
|
|
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
|
|
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
|
-
|
|
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,
|
|
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
|
-
|
|
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
|
-
|
|
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: [
|
|
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 =
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
-
|
|
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]
|