maplibre-gl-layers 0.10.0 → 0.11.0
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/SpriteLayer.d.ts +5 -4
- package/dist/const.d.ts +2 -2
- package/dist/degreeInterpolation.d.ts +2 -2
- package/dist/distanceInterpolation.d.ts +2 -2
- package/dist/easing.d.ts +2 -2
- package/dist/index.cjs +1634 -165
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.mjs +1634 -165
- package/dist/index.mjs.map +1 -1
- package/dist/internalTypes.d.ts +78 -2
- package/dist/interpolation.d.ts +2 -2
- package/dist/interpolationChannels.d.ts +2 -2
- package/dist/location.d.ts +2 -2
- package/dist/looseQuadTree.d.ts +34 -0
- package/dist/math.d.ts +15 -2
- package/dist/rotationInterpolation.d.ts +2 -2
- package/dist/types.d.ts +13 -2
- package/dist/utils.d.ts +2 -2
- package/package.json +6 -6
package/dist/index.mjs
CHANGED
|
@@ -3,12 +3,12 @@ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { en
|
|
|
3
3
|
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
4
4
|
/*!
|
|
5
5
|
* name: maplibre-gl-layers
|
|
6
|
-
* version: 0.
|
|
6
|
+
* version: 0.11.0
|
|
7
7
|
* description: MapLibre's layer extension library enabling the display, movement, and modification of large numbers of dynamic sprite images
|
|
8
8
|
* author: Kouji Matsui (@kekyo@mi.kekyo.net)
|
|
9
9
|
* license: MIT
|
|
10
10
|
* repository.url: https://github.com/kekyo/maplibre-gl-layers.git
|
|
11
|
-
* git.commit.hash:
|
|
11
|
+
* git.commit.hash: 371efb126f281333d59ec75cfe788d45f3b1482e
|
|
12
12
|
*/
|
|
13
13
|
const UNLIMITED_SPRITE_SCALING_OPTIONS = {
|
|
14
14
|
metersPerPixel: 1,
|
|
@@ -21934,13 +21934,6 @@ const applySurfaceDisplacement = (baseLng, baseLat, east, north) => {
|
|
|
21934
21934
|
lat: baseLat + deltaLat
|
|
21935
21935
|
};
|
|
21936
21936
|
};
|
|
21937
|
-
const screenToClip = (x, y, drawingBufferWidth, drawingBufferHeight, pixelRatio) => {
|
|
21938
|
-
const deviceX = x * pixelRatio;
|
|
21939
|
-
const deviceY = y * pixelRatio;
|
|
21940
|
-
const clipX = deviceX / drawingBufferWidth * 2 - 1;
|
|
21941
|
-
const clipY = 1 - deviceY / drawingBufferHeight * 2;
|
|
21942
|
-
return [clipX, clipY];
|
|
21943
|
-
};
|
|
21944
21937
|
const clipToScreen = (clipPosition, drawingBufferWidth, drawingBufferHeight, pixelRatio) => {
|
|
21945
21938
|
const [clipX, clipY, , clipW] = clipPosition;
|
|
21946
21939
|
if (!Number.isFinite(clipW) || clipW === 0) {
|
|
@@ -22085,41 +22078,55 @@ const calculateBillboardCenterPosition = (params) => {
|
|
|
22085
22078
|
offsetShift
|
|
22086
22079
|
};
|
|
22087
22080
|
};
|
|
22088
|
-
const
|
|
22089
|
-
[-1, 1],
|
|
22090
|
-
[1, 1],
|
|
22091
|
-
[-1, -1],
|
|
22092
|
-
[1, -1]
|
|
22093
|
-
];
|
|
22094
|
-
const calculateBillboardCornerScreenPositions = (params) => {
|
|
22081
|
+
const computeSurfaceCornerShaderModel = (params) => {
|
|
22095
22082
|
var _a, _b;
|
|
22096
|
-
const {
|
|
22083
|
+
const {
|
|
22084
|
+
baseLngLat,
|
|
22085
|
+
worldWidthMeters,
|
|
22086
|
+
worldHeightMeters,
|
|
22087
|
+
anchor,
|
|
22088
|
+
totalRotateDeg,
|
|
22089
|
+
offsetMeters
|
|
22090
|
+
} = params;
|
|
22091
|
+
const halfWidth = worldWidthMeters / 2;
|
|
22092
|
+
const halfHeight = worldHeightMeters / 2;
|
|
22097
22093
|
if (halfWidth <= 0 || halfHeight <= 0) {
|
|
22098
|
-
|
|
22094
|
+
const cosLat2 = Math.cos(baseLngLat.lat * DEG2RAD);
|
|
22095
|
+
const cosLatClamped2 = Math.max(cosLat2, MIN_COS_LAT);
|
|
22096
|
+
const deltaLat = offsetMeters.north / EARTH_RADIUS_METERS * RAD2DEG;
|
|
22097
|
+
const deltaLng = offsetMeters.east / (EARTH_RADIUS_METERS * cosLatClamped2) * RAD2DEG;
|
|
22098
|
+
return SURFACE_BASE_CORNERS$1.map(() => ({
|
|
22099
|
+
east: offsetMeters.east,
|
|
22100
|
+
north: offsetMeters.north,
|
|
22101
|
+
lng: baseLngLat.lng + deltaLng,
|
|
22102
|
+
lat: baseLngLat.lat + deltaLat
|
|
22103
|
+
}));
|
|
22099
22104
|
}
|
|
22100
|
-
const
|
|
22101
|
-
const
|
|
22105
|
+
const anchorEast = ((_a = anchor == null ? void 0 : anchor.x) != null ? _a : 0) * halfWidth;
|
|
22106
|
+
const anchorNorth = ((_b = anchor == null ? void 0 : anchor.y) != null ? _b : 0) * halfHeight;
|
|
22102
22107
|
const rad = -totalRotateDeg * DEG2RAD;
|
|
22103
|
-
const cosR = Math.cos(rad);
|
|
22104
22108
|
const sinR = Math.sin(rad);
|
|
22105
|
-
const
|
|
22106
|
-
|
|
22107
|
-
|
|
22108
|
-
|
|
22109
|
-
const
|
|
22110
|
-
const
|
|
22111
|
-
const
|
|
22112
|
-
const
|
|
22113
|
-
const
|
|
22114
|
-
const
|
|
22115
|
-
|
|
22116
|
-
|
|
22117
|
-
|
|
22118
|
-
|
|
22119
|
-
|
|
22120
|
-
|
|
22121
|
-
|
|
22122
|
-
|
|
22109
|
+
const cosR = Math.cos(rad);
|
|
22110
|
+
const cosLat = Math.cos(baseLngLat.lat * DEG2RAD);
|
|
22111
|
+
const cosLatClamped = Math.max(cosLat, MIN_COS_LAT);
|
|
22112
|
+
return SURFACE_BASE_CORNERS$1.map(([eastNorm, northNorm]) => {
|
|
22113
|
+
const cornerEast = eastNorm * halfWidth;
|
|
22114
|
+
const cornerNorth = northNorm * halfHeight;
|
|
22115
|
+
const localEast = cornerEast - anchorEast;
|
|
22116
|
+
const localNorth = cornerNorth - anchorNorth;
|
|
22117
|
+
const rotatedEast = localEast * cosR - localNorth * sinR;
|
|
22118
|
+
const rotatedNorth = localEast * sinR + localNorth * cosR;
|
|
22119
|
+
const east = rotatedEast + offsetMeters.east;
|
|
22120
|
+
const north = rotatedNorth + offsetMeters.north;
|
|
22121
|
+
const deltaLat = north / EARTH_RADIUS_METERS * RAD2DEG;
|
|
22122
|
+
const deltaLng = east / (EARTH_RADIUS_METERS * cosLatClamped) * RAD2DEG;
|
|
22123
|
+
return {
|
|
22124
|
+
east,
|
|
22125
|
+
north,
|
|
22126
|
+
lng: baseLngLat.lng + deltaLng,
|
|
22127
|
+
lat: baseLngLat.lat + deltaLat
|
|
22128
|
+
};
|
|
22129
|
+
});
|
|
22123
22130
|
};
|
|
22124
22131
|
const calculateSurfaceCenterPosition = (params) => {
|
|
22125
22132
|
var _a, _b;
|
|
@@ -22229,7 +22236,7 @@ const calculateSurfaceCenterPosition = (params) => {
|
|
|
22229
22236
|
anchorlessLngLat
|
|
22230
22237
|
};
|
|
22231
22238
|
};
|
|
22232
|
-
const SURFACE_BASE_CORNERS = [
|
|
22239
|
+
const SURFACE_BASE_CORNERS$1 = [
|
|
22233
22240
|
[-1, 1],
|
|
22234
22241
|
[1, 1],
|
|
22235
22242
|
[-1, -1],
|
|
@@ -22245,7 +22252,7 @@ const calculateSurfaceCornerDisplacements = (params) => {
|
|
|
22245
22252
|
offsetMeters
|
|
22246
22253
|
} = params;
|
|
22247
22254
|
if (worldWidthMeters <= 0 || worldHeightMeters <= 0) {
|
|
22248
|
-
return SURFACE_BASE_CORNERS.map(() => ({
|
|
22255
|
+
return SURFACE_BASE_CORNERS$1.map(() => ({
|
|
22249
22256
|
east: offsetMeters.east,
|
|
22250
22257
|
north: offsetMeters.north
|
|
22251
22258
|
}));
|
|
@@ -22258,7 +22265,7 @@ const calculateSurfaceCornerDisplacements = (params) => {
|
|
|
22258
22265
|
const cosR = Math.cos(rad);
|
|
22259
22266
|
const sinR = Math.sin(rad);
|
|
22260
22267
|
const corners = [];
|
|
22261
|
-
for (const [eastNorm, northNorm] of SURFACE_BASE_CORNERS) {
|
|
22268
|
+
for (const [eastNorm, northNorm] of SURFACE_BASE_CORNERS$1) {
|
|
22262
22269
|
const cornerEast = eastNorm * halfWidth;
|
|
22263
22270
|
const cornerNorth = northNorm * halfHeight;
|
|
22264
22271
|
const localEast = cornerEast - anchorEast;
|
|
@@ -22509,12 +22516,262 @@ const applyOffsetUpdate = (image, nextOffset, options = {}) => {
|
|
|
22509
22516
|
applyOffsetDegUpdate(image, nextOffset, options.deg);
|
|
22510
22517
|
applyOffsetMetersUpdate(image, nextOffset, options.meters);
|
|
22511
22518
|
};
|
|
22519
|
+
const DEFAULT_MAX_ITEMS_PER_NODE = 16;
|
|
22520
|
+
const DEFAULT_MAX_DEPTH = 8;
|
|
22521
|
+
const DEFAULT_LOOSENESS = 1.5;
|
|
22522
|
+
const createNode = (bounds, looseness, depth) => ({
|
|
22523
|
+
bounds,
|
|
22524
|
+
looseBounds: expandRect(bounds, looseness),
|
|
22525
|
+
items: [],
|
|
22526
|
+
children: null,
|
|
22527
|
+
depth
|
|
22528
|
+
});
|
|
22529
|
+
const normalizeRect = (rect) => {
|
|
22530
|
+
const x0 = Math.min(rect.x0, rect.x1);
|
|
22531
|
+
const y0 = Math.min(rect.y0, rect.y1);
|
|
22532
|
+
const x1 = Math.max(rect.x0, rect.x1);
|
|
22533
|
+
const y1 = Math.max(rect.y0, rect.y1);
|
|
22534
|
+
return { x0, y0, x1, y1 };
|
|
22535
|
+
};
|
|
22536
|
+
const isFiniteRect = (rect) => Number.isFinite(rect.x0) && Number.isFinite(rect.y0) && Number.isFinite(rect.x1) && Number.isFinite(rect.y1);
|
|
22537
|
+
const expandRect = (rect, looseness) => {
|
|
22538
|
+
if (looseness === 1) {
|
|
22539
|
+
return rect;
|
|
22540
|
+
}
|
|
22541
|
+
const width = rect.x1 - rect.x0;
|
|
22542
|
+
const height = rect.y1 - rect.y0;
|
|
22543
|
+
const halfWidth = width * looseness / 2;
|
|
22544
|
+
const halfHeight = height * looseness / 2;
|
|
22545
|
+
const centerX = rect.x0 + width / 2;
|
|
22546
|
+
const centerY = rect.y0 + height / 2;
|
|
22547
|
+
return {
|
|
22548
|
+
x0: centerX - halfWidth,
|
|
22549
|
+
y0: centerY - halfHeight,
|
|
22550
|
+
x1: centerX + halfWidth,
|
|
22551
|
+
y1: centerY + halfHeight
|
|
22552
|
+
};
|
|
22553
|
+
};
|
|
22554
|
+
const rectContainsRectInclusive = (container, target) => container.x0 <= target.x0 && container.y0 <= target.y0 && container.x1 >= target.x1 && container.y1 >= target.y1;
|
|
22555
|
+
const rectsOverlapInclusive = (a, b) => !(a.x1 < b.x0 || a.x0 > b.x1 || a.y1 < b.y0 || a.y0 > b.y1);
|
|
22556
|
+
const rectEquals = (a, b) => a.x0 === b.x0 && a.y0 === b.y0 && a.x1 === b.x1 && a.y1 === b.y1;
|
|
22557
|
+
const createLooseQuadTree = (options) => {
|
|
22558
|
+
var _a, _b, _c;
|
|
22559
|
+
const maxItemsPerNode = (_a = options.maxItemsPerNode) != null ? _a : DEFAULT_MAX_ITEMS_PER_NODE;
|
|
22560
|
+
const maxDepth = (_b = options.maxDepth) != null ? _b : DEFAULT_MAX_DEPTH;
|
|
22561
|
+
const looseness = (_c = options.looseness) != null ? _c : DEFAULT_LOOSENESS;
|
|
22562
|
+
if (maxItemsPerNode <= 0) {
|
|
22563
|
+
throw new Error("maxItemsPerNode must be greater than 0.");
|
|
22564
|
+
}
|
|
22565
|
+
if (maxDepth < 0) {
|
|
22566
|
+
throw new Error("maxDepth must be 0 or greater.");
|
|
22567
|
+
}
|
|
22568
|
+
if (!(looseness >= 1)) {
|
|
22569
|
+
throw new Error("looseness must be greater than or equal to 1.");
|
|
22570
|
+
}
|
|
22571
|
+
const normalizedBounds = normalizeRect(options.bounds);
|
|
22572
|
+
if (!isFiniteRect(normalizedBounds)) {
|
|
22573
|
+
throw new Error("Bounds must have finite coordinates.");
|
|
22574
|
+
}
|
|
22575
|
+
let root = createNode(normalizedBounds, looseness, 0);
|
|
22576
|
+
let count = 0;
|
|
22577
|
+
let registry = /* @__PURE__ */ new WeakMap();
|
|
22578
|
+
const insertIntoNode = (node, quadItem) => {
|
|
22579
|
+
if (node.children) {
|
|
22580
|
+
const childIndex = findChildIndex(node.children, quadItem.rect);
|
|
22581
|
+
if (childIndex !== -1) {
|
|
22582
|
+
insertIntoNode(node.children[childIndex], quadItem);
|
|
22583
|
+
return;
|
|
22584
|
+
}
|
|
22585
|
+
}
|
|
22586
|
+
quadItem.node = node;
|
|
22587
|
+
quadItem.index = node.items.length;
|
|
22588
|
+
node.items.push(quadItem);
|
|
22589
|
+
if (node.items.length > maxItemsPerNode && node.depth < maxDepth) {
|
|
22590
|
+
if (!node.children) {
|
|
22591
|
+
subdivide(node);
|
|
22592
|
+
}
|
|
22593
|
+
const children = node.children;
|
|
22594
|
+
if (!children) {
|
|
22595
|
+
return;
|
|
22596
|
+
}
|
|
22597
|
+
let i = 0;
|
|
22598
|
+
while (i < node.items.length) {
|
|
22599
|
+
const candidate = node.items[i];
|
|
22600
|
+
const childIndex = findChildIndex(children, candidate.rect);
|
|
22601
|
+
if (childIndex !== -1) {
|
|
22602
|
+
detachFromNode(candidate);
|
|
22603
|
+
insertIntoNode(children[childIndex], candidate);
|
|
22604
|
+
} else {
|
|
22605
|
+
i += 1;
|
|
22606
|
+
}
|
|
22607
|
+
}
|
|
22608
|
+
}
|
|
22609
|
+
};
|
|
22610
|
+
const removeQuadItem = (quadItem) => {
|
|
22611
|
+
detachFromNode(quadItem);
|
|
22612
|
+
registry.delete(quadItem.item);
|
|
22613
|
+
};
|
|
22614
|
+
const detachFromNode = (quadItem) => {
|
|
22615
|
+
const node = quadItem.node;
|
|
22616
|
+
const index = quadItem.index;
|
|
22617
|
+
if (index < 0 || index >= node.items.length) {
|
|
22618
|
+
return;
|
|
22619
|
+
}
|
|
22620
|
+
const lastIndex = node.items.length - 1;
|
|
22621
|
+
if (index !== lastIndex) {
|
|
22622
|
+
const moved = node.items[lastIndex];
|
|
22623
|
+
node.items[index] = moved;
|
|
22624
|
+
moved.index = index;
|
|
22625
|
+
}
|
|
22626
|
+
node.items.pop();
|
|
22627
|
+
quadItem.index = -1;
|
|
22628
|
+
quadItem.node = node;
|
|
22629
|
+
};
|
|
22630
|
+
const reassignIfPossible = (quadItem) => {
|
|
22631
|
+
const node = quadItem.node;
|
|
22632
|
+
if (!node.children) {
|
|
22633
|
+
return;
|
|
22634
|
+
}
|
|
22635
|
+
const childIndex = findChildIndex(node.children, quadItem.rect);
|
|
22636
|
+
if (childIndex === -1) {
|
|
22637
|
+
return;
|
|
22638
|
+
}
|
|
22639
|
+
detachFromNode(quadItem);
|
|
22640
|
+
insertIntoNode(node.children[childIndex], quadItem);
|
|
22641
|
+
};
|
|
22642
|
+
const add = (item) => {
|
|
22643
|
+
const rect = normalizeRect(item);
|
|
22644
|
+
if (!rectContainsRectInclusive(root.bounds, rect)) {
|
|
22645
|
+
throw new Error("Item rectangle is outside of quadtree bounds.");
|
|
22646
|
+
}
|
|
22647
|
+
const quadItem = {
|
|
22648
|
+
item,
|
|
22649
|
+
rect,
|
|
22650
|
+
node: root,
|
|
22651
|
+
index: -1
|
|
22652
|
+
};
|
|
22653
|
+
insertIntoNode(root, quadItem);
|
|
22654
|
+
registry.set(item, quadItem);
|
|
22655
|
+
count += 1;
|
|
22656
|
+
};
|
|
22657
|
+
const remove = (x0, y0, x1, y1, item) => {
|
|
22658
|
+
const quadItem = registry.get(item);
|
|
22659
|
+
if (!quadItem) {
|
|
22660
|
+
return false;
|
|
22661
|
+
}
|
|
22662
|
+
const rect = normalizeRect({ x0, y0, x1, y1 });
|
|
22663
|
+
if (!rectEquals(rect, quadItem.rect)) {
|
|
22664
|
+
return false;
|
|
22665
|
+
}
|
|
22666
|
+
removeQuadItem(quadItem);
|
|
22667
|
+
count -= 1;
|
|
22668
|
+
return true;
|
|
22669
|
+
};
|
|
22670
|
+
const update = (oldX0, oldY0, oldX1, oldY1, newX0, newY0, newX1, newY1, item) => {
|
|
22671
|
+
const quadItem = registry.get(item);
|
|
22672
|
+
if (!quadItem) {
|
|
22673
|
+
return false;
|
|
22674
|
+
}
|
|
22675
|
+
const currentRect = quadItem.rect;
|
|
22676
|
+
const expectedOldRect = normalizeRect({
|
|
22677
|
+
x0: oldX0,
|
|
22678
|
+
y0: oldY0,
|
|
22679
|
+
x1: oldX1,
|
|
22680
|
+
y1: oldY1
|
|
22681
|
+
});
|
|
22682
|
+
if (!rectEquals(currentRect, expectedOldRect)) {
|
|
22683
|
+
return false;
|
|
22684
|
+
}
|
|
22685
|
+
const newRect = normalizeRect({
|
|
22686
|
+
x0: newX0,
|
|
22687
|
+
y0: newY0,
|
|
22688
|
+
x1: newX1,
|
|
22689
|
+
y1: newY1
|
|
22690
|
+
});
|
|
22691
|
+
if (!rectContainsRectInclusive(root.bounds, newRect)) {
|
|
22692
|
+
throw new Error("Updated rectangle is outside of quadtree bounds.");
|
|
22693
|
+
}
|
|
22694
|
+
if (rectContainsRectInclusive(quadItem.node.looseBounds, newRect)) {
|
|
22695
|
+
quadItem.rect = newRect;
|
|
22696
|
+
reassignIfPossible(quadItem);
|
|
22697
|
+
return true;
|
|
22698
|
+
}
|
|
22699
|
+
detachFromNode(quadItem);
|
|
22700
|
+
quadItem.rect = newRect;
|
|
22701
|
+
insertIntoNode(root, quadItem);
|
|
22702
|
+
return true;
|
|
22703
|
+
};
|
|
22704
|
+
const lookup = (x0, y0, x1, y1) => {
|
|
22705
|
+
const rect = normalizeRect({ x0, y0, x1, y1 });
|
|
22706
|
+
const results = [];
|
|
22707
|
+
collectFromNode(root, rect, results);
|
|
22708
|
+
return results;
|
|
22709
|
+
};
|
|
22710
|
+
const clear = () => {
|
|
22711
|
+
root = createNode(normalizedBounds, looseness, 0);
|
|
22712
|
+
registry = /* @__PURE__ */ new WeakMap();
|
|
22713
|
+
count = 0;
|
|
22714
|
+
};
|
|
22715
|
+
const collectFromNode = (node, rect, results) => {
|
|
22716
|
+
if (!rectsOverlapInclusive(node.looseBounds, rect)) {
|
|
22717
|
+
return;
|
|
22718
|
+
}
|
|
22719
|
+
for (const quadItem of node.items) {
|
|
22720
|
+
if (rectsOverlapInclusive(quadItem.rect, rect)) {
|
|
22721
|
+
results.push(quadItem.item);
|
|
22722
|
+
}
|
|
22723
|
+
}
|
|
22724
|
+
if (!node.children) {
|
|
22725
|
+
return;
|
|
22726
|
+
}
|
|
22727
|
+
for (const child of node.children) {
|
|
22728
|
+
collectFromNode(child, rect, results);
|
|
22729
|
+
}
|
|
22730
|
+
};
|
|
22731
|
+
const findChildIndex = (children, rect) => {
|
|
22732
|
+
for (let i = 0; i < children.length; i += 1) {
|
|
22733
|
+
const child = children[i];
|
|
22734
|
+
if (rectContainsRectInclusive(child.looseBounds, rect)) {
|
|
22735
|
+
return i;
|
|
22736
|
+
}
|
|
22737
|
+
}
|
|
22738
|
+
return -1;
|
|
22739
|
+
};
|
|
22740
|
+
const subdivide = (node) => {
|
|
22741
|
+
if (node.children) {
|
|
22742
|
+
return;
|
|
22743
|
+
}
|
|
22744
|
+
const { bounds } = node;
|
|
22745
|
+
const splitX = bounds.x0 + (bounds.x1 - bounds.x0) / 2;
|
|
22746
|
+
const splitY = bounds.y0 + (bounds.y1 - bounds.y0) / 2;
|
|
22747
|
+
const childrenBounds = [
|
|
22748
|
+
normalizeRect({ x0: bounds.x0, y0: bounds.y0, x1: splitX, y1: splitY }),
|
|
22749
|
+
normalizeRect({ x0: splitX, y0: bounds.y0, x1: bounds.x1, y1: splitY }),
|
|
22750
|
+
normalizeRect({ x0: bounds.x0, y0: splitY, x1: splitX, y1: bounds.y1 }),
|
|
22751
|
+
normalizeRect({ x0: splitX, y0: splitY, x1: bounds.x1, y1: bounds.y1 })
|
|
22752
|
+
];
|
|
22753
|
+
node.children = childrenBounds.map(
|
|
22754
|
+
(childBounds) => createNode(childBounds, looseness, node.depth + 1)
|
|
22755
|
+
);
|
|
22756
|
+
};
|
|
22757
|
+
return {
|
|
22758
|
+
get size() {
|
|
22759
|
+
return count;
|
|
22760
|
+
},
|
|
22761
|
+
add,
|
|
22762
|
+
remove,
|
|
22763
|
+
update,
|
|
22764
|
+
lookup,
|
|
22765
|
+
clear
|
|
22766
|
+
};
|
|
22767
|
+
};
|
|
22512
22768
|
const DEFAULT_ANCHOR = { x: 0, y: 0 };
|
|
22513
22769
|
const DEFAULT_AUTO_ROTATION_MIN_DISTANCE_METERS = 20;
|
|
22514
22770
|
const DEFAULT_IMAGE_OFFSET = {
|
|
22515
22771
|
offsetMeters: 0,
|
|
22516
22772
|
offsetDeg: 0
|
|
22517
22773
|
};
|
|
22774
|
+
const HIT_TEST_QUERY_RADIUS_PIXELS = 32;
|
|
22518
22775
|
const MIN_CLIP_W = 1e-6;
|
|
22519
22776
|
const MIN_CLIP_Z_EPSILON = 1e-7;
|
|
22520
22777
|
const EPS_NDC = 1e-6;
|
|
@@ -22605,7 +22862,7 @@ const resolveGlMagFilter = (glContext, filter) => {
|
|
|
22605
22862
|
return glContext.LINEAR;
|
|
22606
22863
|
}
|
|
22607
22864
|
};
|
|
22608
|
-
const calculatePerspectiveRatio = (mapInstance, location2) => {
|
|
22865
|
+
const calculatePerspectiveRatio = (mapInstance, location2, cachedMercator) => {
|
|
22609
22866
|
var _a, _b, _c;
|
|
22610
22867
|
const transform = mapInstance.transform;
|
|
22611
22868
|
if (!transform) {
|
|
@@ -22617,7 +22874,7 @@ const calculatePerspectiveRatio = (mapInstance, location2) => {
|
|
|
22617
22874
|
return 1;
|
|
22618
22875
|
}
|
|
22619
22876
|
try {
|
|
22620
|
-
const mercator = maplibreGlExports.MercatorCoordinate.fromLngLat(
|
|
22877
|
+
const mercator = cachedMercator != null ? cachedMercator : maplibreGlExports.MercatorCoordinate.fromLngLat(
|
|
22621
22878
|
{ lng: location2.lng, lat: location2.lat },
|
|
22622
22879
|
(_b = location2.z) != null ? _b : 0
|
|
22623
22880
|
);
|
|
@@ -22750,10 +23007,59 @@ const QUAD_VERTEX_COUNT = 6;
|
|
|
22750
23007
|
const VERTEX_SHADER_SOURCE = `
|
|
22751
23008
|
attribute vec4 a_position;
|
|
22752
23009
|
attribute vec2 a_uv;
|
|
23010
|
+
uniform vec2 u_screenToClipScale;
|
|
23011
|
+
uniform vec2 u_screenToClipOffset;
|
|
23012
|
+
uniform float u_billboardMode;
|
|
23013
|
+
uniform float u_surfaceMode;
|
|
23014
|
+
uniform vec2 u_billboardCenter;
|
|
23015
|
+
uniform vec2 u_billboardHalfSize;
|
|
23016
|
+
uniform vec2 u_billboardAnchor;
|
|
23017
|
+
uniform vec2 u_billboardSinCos;
|
|
23018
|
+
uniform float u_surfaceClipEnabled;
|
|
23019
|
+
uniform vec4 u_surfaceClipCenter;
|
|
23020
|
+
uniform vec4 u_surfaceClipBasisEast;
|
|
23021
|
+
uniform vec4 u_surfaceClipBasisNorth;
|
|
23022
|
+
uniform float u_surfaceDepthBias;
|
|
22753
23023
|
varying vec2 v_uv;
|
|
23024
|
+
vec2 computeBillboardCorner(vec2 uv) {
|
|
23025
|
+
vec2 base = vec2(uv.x * 2.0 - 1.0, 1.0 - uv.y * 2.0);
|
|
23026
|
+
vec2 anchorShift = vec2(u_billboardAnchor.x * u_billboardHalfSize.x, u_billboardAnchor.y * u_billboardHalfSize.y);
|
|
23027
|
+
vec2 shifted = vec2(base.x * u_billboardHalfSize.x, base.y * u_billboardHalfSize.y) - anchorShift;
|
|
23028
|
+
float sinR = u_billboardSinCos.x;
|
|
23029
|
+
float cosR = u_billboardSinCos.y;
|
|
23030
|
+
vec2 rotated = vec2(
|
|
23031
|
+
shifted.x * cosR - shifted.y * sinR,
|
|
23032
|
+
shifted.x * sinR + shifted.y * cosR
|
|
23033
|
+
);
|
|
23034
|
+
return vec2(
|
|
23035
|
+
u_billboardCenter.x + rotated.x,
|
|
23036
|
+
u_billboardCenter.y - rotated.y
|
|
23037
|
+
);
|
|
23038
|
+
}
|
|
23039
|
+
vec4 computeSurfaceCorner(vec2 corner) {
|
|
23040
|
+
if (u_surfaceClipEnabled < 0.5) {
|
|
23041
|
+
return vec4(0.0, 0.0, 0.0, 1.0);
|
|
23042
|
+
}
|
|
23043
|
+
vec4 clip = u_surfaceClipCenter
|
|
23044
|
+
+ (corner.x * u_surfaceClipBasisEast)
|
|
23045
|
+
+ (corner.y * u_surfaceClipBasisNorth);
|
|
23046
|
+
clip.z += u_surfaceDepthBias * clip.w;
|
|
23047
|
+
return clip;
|
|
23048
|
+
}
|
|
22754
23049
|
void main() {
|
|
22755
23050
|
v_uv = a_uv;
|
|
22756
|
-
|
|
23051
|
+
vec4 position;
|
|
23052
|
+
if (u_billboardMode > 0.5) {
|
|
23053
|
+
vec2 screenPosition = computeBillboardCorner(a_uv);
|
|
23054
|
+
position = vec4(screenPosition, 0.0, 1.0);
|
|
23055
|
+
} else if (u_surfaceMode > 0.5) {
|
|
23056
|
+
vec2 baseCorner = vec2(a_position.x, a_position.y);
|
|
23057
|
+
position = computeSurfaceCorner(baseCorner);
|
|
23058
|
+
} else {
|
|
23059
|
+
position = a_position;
|
|
23060
|
+
}
|
|
23061
|
+
position.xy = position.xy * u_screenToClipScale + u_screenToClipOffset;
|
|
23062
|
+
gl_Position = position;
|
|
22757
23063
|
}
|
|
22758
23064
|
`;
|
|
22759
23065
|
const FRAGMENT_SHADER_SOURCE = `
|
|
@@ -22772,6 +23078,175 @@ const INITIAL_QUAD_VERTICES = new Float32Array(
|
|
|
22772
23078
|
const QUAD_VERTEX_SCRATCH = new Float32Array(
|
|
22773
23079
|
QUAD_VERTEX_COUNT * VERTEX_COMPONENT_COUNT
|
|
22774
23080
|
);
|
|
23081
|
+
const DEBUG_OUTLINE_VERTEX_SHADER_SOURCE = `
|
|
23082
|
+
attribute vec4 a_position;
|
|
23083
|
+
uniform vec2 u_screenToClipScale;
|
|
23084
|
+
uniform vec2 u_screenToClipOffset;
|
|
23085
|
+
void main() {
|
|
23086
|
+
vec4 position = a_position;
|
|
23087
|
+
position.xy = position.xy * u_screenToClipScale + u_screenToClipOffset;
|
|
23088
|
+
gl_Position = position;
|
|
23089
|
+
}
|
|
23090
|
+
`;
|
|
23091
|
+
const DEBUG_OUTLINE_FRAGMENT_SHADER_SOURCE = `
|
|
23092
|
+
precision mediump float;
|
|
23093
|
+
uniform vec4 u_color;
|
|
23094
|
+
void main() {
|
|
23095
|
+
gl_FragColor = u_color;
|
|
23096
|
+
}
|
|
23097
|
+
`;
|
|
23098
|
+
const DEBUG_OUTLINE_VERTEX_COUNT = 4;
|
|
23099
|
+
const DEBUG_OUTLINE_POSITION_COMPONENT_COUNT = 4;
|
|
23100
|
+
const DEBUG_OUTLINE_VERTEX_STRIDE = DEBUG_OUTLINE_POSITION_COMPONENT_COUNT * FLOAT_SIZE;
|
|
23101
|
+
const DEBUG_OUTLINE_VERTEX_SCRATCH = new Float32Array(
|
|
23102
|
+
DEBUG_OUTLINE_VERTEX_COUNT * DEBUG_OUTLINE_POSITION_COMPONENT_COUNT
|
|
23103
|
+
);
|
|
23104
|
+
const DEBUG_OUTLINE_COLOR = [
|
|
23105
|
+
1,
|
|
23106
|
+
0,
|
|
23107
|
+
0,
|
|
23108
|
+
1
|
|
23109
|
+
];
|
|
23110
|
+
const DEBUG_OUTLINE_CORNER_ORDER = [0, 1, 3, 2];
|
|
23111
|
+
const BILLBOARD_BASE_CORNERS = [
|
|
23112
|
+
[-1, 1],
|
|
23113
|
+
[1, 1],
|
|
23114
|
+
[-1, -1],
|
|
23115
|
+
[1, -1]
|
|
23116
|
+
];
|
|
23117
|
+
const SURFACE_BASE_CORNERS = [
|
|
23118
|
+
[-1, 1],
|
|
23119
|
+
[1, 1],
|
|
23120
|
+
[-1, -1],
|
|
23121
|
+
[1, -1]
|
|
23122
|
+
];
|
|
23123
|
+
const computeBillboardCornersShaderModel = ({
|
|
23124
|
+
centerX,
|
|
23125
|
+
centerY,
|
|
23126
|
+
halfWidth,
|
|
23127
|
+
halfHeight,
|
|
23128
|
+
anchor,
|
|
23129
|
+
rotationDeg
|
|
23130
|
+
}) => {
|
|
23131
|
+
var _a, _b;
|
|
23132
|
+
const anchorX = (_a = anchor == null ? void 0 : anchor.x) != null ? _a : 0;
|
|
23133
|
+
const anchorY = (_b = anchor == null ? void 0 : anchor.y) != null ? _b : 0;
|
|
23134
|
+
const rad = -rotationDeg * DEG2RAD;
|
|
23135
|
+
const cosR = Math.cos(rad);
|
|
23136
|
+
const sinR = Math.sin(rad);
|
|
23137
|
+
return BILLBOARD_BASE_CORNERS.map(([cornerXNorm, cornerYNorm], index) => {
|
|
23138
|
+
const cornerX = cornerXNorm * halfWidth;
|
|
23139
|
+
const cornerY = cornerYNorm * halfHeight;
|
|
23140
|
+
const shiftedX = cornerX - anchorX * halfWidth;
|
|
23141
|
+
const shiftedY = cornerY - anchorY * halfHeight;
|
|
23142
|
+
const rotatedX = shiftedX * cosR - shiftedY * sinR;
|
|
23143
|
+
const rotatedY = shiftedX * sinR + shiftedY * cosR;
|
|
23144
|
+
const [u, v] = UV_CORNERS[index];
|
|
23145
|
+
return {
|
|
23146
|
+
x: centerX + rotatedX,
|
|
23147
|
+
y: centerY - rotatedY,
|
|
23148
|
+
u,
|
|
23149
|
+
v
|
|
23150
|
+
};
|
|
23151
|
+
});
|
|
23152
|
+
};
|
|
23153
|
+
const calculateWorldToMercatorScale = (base, altitudeMeters) => {
|
|
23154
|
+
const origin = maplibreGlExports.MercatorCoordinate.fromLngLat(
|
|
23155
|
+
{ lng: base.lng, lat: base.lat },
|
|
23156
|
+
altitudeMeters
|
|
23157
|
+
);
|
|
23158
|
+
const eastLngLat = applySurfaceDisplacement(base.lng, base.lat, 1, 0);
|
|
23159
|
+
const eastCoord = maplibreGlExports.MercatorCoordinate.fromLngLat(
|
|
23160
|
+
{ lng: eastLngLat.lng, lat: eastLngLat.lat },
|
|
23161
|
+
altitudeMeters
|
|
23162
|
+
);
|
|
23163
|
+
const northLngLat = applySurfaceDisplacement(base.lng, base.lat, 0, 1);
|
|
23164
|
+
const northCoord = maplibreGlExports.MercatorCoordinate.fromLngLat(
|
|
23165
|
+
{ lng: northLngLat.lng, lat: northLngLat.lat },
|
|
23166
|
+
altitudeMeters
|
|
23167
|
+
);
|
|
23168
|
+
return {
|
|
23169
|
+
east: eastCoord.x - origin.x,
|
|
23170
|
+
north: northCoord.y - origin.y
|
|
23171
|
+
};
|
|
23172
|
+
};
|
|
23173
|
+
const prepareSurfaceShaderInputs = (params) => {
|
|
23174
|
+
var _a, _b;
|
|
23175
|
+
const {
|
|
23176
|
+
baseLngLat,
|
|
23177
|
+
worldWidthMeters,
|
|
23178
|
+
worldHeightMeters,
|
|
23179
|
+
anchor,
|
|
23180
|
+
totalRotateDeg,
|
|
23181
|
+
offsetMeters,
|
|
23182
|
+
displacedCenter,
|
|
23183
|
+
altitudeMeters,
|
|
23184
|
+
depthBiasNdc,
|
|
23185
|
+
scaleAdjustment,
|
|
23186
|
+
centerDisplacement
|
|
23187
|
+
} = params;
|
|
23188
|
+
const halfSizeMeters = {
|
|
23189
|
+
east: worldWidthMeters / 2,
|
|
23190
|
+
north: worldHeightMeters / 2
|
|
23191
|
+
};
|
|
23192
|
+
const rotationRad = -totalRotateDeg * DEG2RAD;
|
|
23193
|
+
const sinR = Math.sin(rotationRad);
|
|
23194
|
+
const cosR = Math.cos(rotationRad);
|
|
23195
|
+
const mercatorCenter = maplibreGlExports.MercatorCoordinate.fromLngLat(
|
|
23196
|
+
{ lng: displacedCenter.lng, lat: displacedCenter.lat },
|
|
23197
|
+
altitudeMeters
|
|
23198
|
+
);
|
|
23199
|
+
const worldToMercatorScale = calculateWorldToMercatorScale(
|
|
23200
|
+
displacedCenter,
|
|
23201
|
+
altitudeMeters
|
|
23202
|
+
);
|
|
23203
|
+
const cornerModel = computeSurfaceCornerShaderModel({
|
|
23204
|
+
baseLngLat,
|
|
23205
|
+
worldWidthMeters,
|
|
23206
|
+
worldHeightMeters,
|
|
23207
|
+
anchor,
|
|
23208
|
+
totalRotateDeg,
|
|
23209
|
+
offsetMeters
|
|
23210
|
+
});
|
|
23211
|
+
return {
|
|
23212
|
+
mercatorCenter: {
|
|
23213
|
+
x: mercatorCenter.x,
|
|
23214
|
+
y: mercatorCenter.y,
|
|
23215
|
+
z: (_a = mercatorCenter.z) != null ? _a : 0
|
|
23216
|
+
},
|
|
23217
|
+
worldToMercatorScale,
|
|
23218
|
+
halfSizeMeters,
|
|
23219
|
+
anchor,
|
|
23220
|
+
offsetMeters: {
|
|
23221
|
+
east: offsetMeters.east,
|
|
23222
|
+
north: offsetMeters.north
|
|
23223
|
+
},
|
|
23224
|
+
sinCos: { sin: sinR, cos: cosR },
|
|
23225
|
+
totalRotateDeg,
|
|
23226
|
+
depthBiasNdc,
|
|
23227
|
+
centerDisplacement: {
|
|
23228
|
+
east: centerDisplacement.east,
|
|
23229
|
+
north: centerDisplacement.north
|
|
23230
|
+
},
|
|
23231
|
+
baseLngLat,
|
|
23232
|
+
displacedCenter: {
|
|
23233
|
+
lng: displacedCenter.lng,
|
|
23234
|
+
lat: displacedCenter.lat,
|
|
23235
|
+
z: (_b = displacedCenter.z) != null ? _b : altitudeMeters
|
|
23236
|
+
},
|
|
23237
|
+
scaleAdjustment,
|
|
23238
|
+
corners: cornerModel.map((corner) => ({
|
|
23239
|
+
east: corner.east,
|
|
23240
|
+
north: corner.north,
|
|
23241
|
+
lng: corner.lng,
|
|
23242
|
+
lat: corner.lat
|
|
23243
|
+
})),
|
|
23244
|
+
clipCenter: { x: 0, y: 0, z: 0, w: 1 },
|
|
23245
|
+
clipBasisEast: { x: 0, y: 0, z: 0, w: 0 },
|
|
23246
|
+
clipBasisNorth: { x: 0, y: 0, z: 0, w: 0 },
|
|
23247
|
+
clipCorners: []
|
|
23248
|
+
};
|
|
23249
|
+
};
|
|
22775
23250
|
const compileShader = (glContext, type, source) => {
|
|
22776
23251
|
var _a;
|
|
22777
23252
|
const shader = glContext.createShader(type);
|
|
@@ -23205,42 +23680,403 @@ const createImageStateFromInit = (imageInit, subLayer, order) => {
|
|
|
23205
23680
|
lastCommandOffsetDeg: initialOffset.offsetDeg,
|
|
23206
23681
|
lastCommandOffsetMeters: initialOffset.offsetMeters
|
|
23207
23682
|
};
|
|
23208
|
-
const rotateInitOption = (_i = (_h = imageInit.interpolation) == null ? void 0 : _h.rotateDeg) != null ? _i : null;
|
|
23209
|
-
if (rotateInitOption) {
|
|
23210
|
-
state.rotationInterpolationOptions = cloneInterpolationOptions(rotateInitOption);
|
|
23211
|
-
}
|
|
23212
|
-
syncImageRotationChannel(state);
|
|
23213
|
-
return state;
|
|
23214
|
-
};
|
|
23215
|
-
const createSpriteLayer = (options) => {
|
|
23216
|
-
var _a;
|
|
23217
|
-
const id = (_a = options == null ? void 0 : options.id) != null ? _a : "sprite-layer";
|
|
23218
|
-
const resolvedScaling = resolveScalingOptions(options == null ? void 0 : options.spriteScaling);
|
|
23219
|
-
const resolvedTextureFiltering = resolveTextureFilteringOptions(
|
|
23220
|
-
options == null ? void 0 : options.textureFiltering
|
|
23221
|
-
);
|
|
23222
|
-
|
|
23223
|
-
let
|
|
23224
|
-
let
|
|
23225
|
-
let
|
|
23226
|
-
let
|
|
23227
|
-
let
|
|
23228
|
-
let
|
|
23229
|
-
let
|
|
23230
|
-
let
|
|
23231
|
-
let
|
|
23232
|
-
|
|
23233
|
-
|
|
23234
|
-
|
|
23235
|
-
|
|
23683
|
+
const rotateInitOption = (_i = (_h = imageInit.interpolation) == null ? void 0 : _h.rotateDeg) != null ? _i : null;
|
|
23684
|
+
if (rotateInitOption) {
|
|
23685
|
+
state.rotationInterpolationOptions = cloneInterpolationOptions(rotateInitOption);
|
|
23686
|
+
}
|
|
23687
|
+
syncImageRotationChannel(state);
|
|
23688
|
+
return state;
|
|
23689
|
+
};
|
|
23690
|
+
const createSpriteLayer = (options) => {
|
|
23691
|
+
var _a;
|
|
23692
|
+
const id = (_a = options == null ? void 0 : options.id) != null ? _a : "sprite-layer";
|
|
23693
|
+
const resolvedScaling = resolveScalingOptions(options == null ? void 0 : options.spriteScaling);
|
|
23694
|
+
const resolvedTextureFiltering = resolveTextureFilteringOptions(
|
|
23695
|
+
options == null ? void 0 : options.textureFiltering
|
|
23696
|
+
);
|
|
23697
|
+
const showDebugBounds = (options == null ? void 0 : options.showDebugBounds) === true;
|
|
23698
|
+
let gl = null;
|
|
23699
|
+
let map = null;
|
|
23700
|
+
let program = null;
|
|
23701
|
+
let vertexBuffer = null;
|
|
23702
|
+
let attribPositionLocation = -1;
|
|
23703
|
+
let attribUvLocation = -1;
|
|
23704
|
+
let uniformTextureLocation = null;
|
|
23705
|
+
let uniformOpacityLocation = null;
|
|
23706
|
+
let uniformScreenToClipScaleLocation = null;
|
|
23707
|
+
let uniformScreenToClipOffsetLocation = null;
|
|
23708
|
+
let uniformBillboardModeLocation = null;
|
|
23709
|
+
let uniformBillboardCenterLocation = null;
|
|
23710
|
+
let uniformBillboardHalfSizeLocation = null;
|
|
23711
|
+
let uniformBillboardAnchorLocation = null;
|
|
23712
|
+
let uniformBillboardSinCosLocation = null;
|
|
23713
|
+
let uniformSurfaceModeLocation = null;
|
|
23714
|
+
let uniformSurfaceDepthBiasLocation = null;
|
|
23715
|
+
let uniformSurfaceClipEnabledLocation = null;
|
|
23716
|
+
let uniformSurfaceClipCenterLocation = null;
|
|
23717
|
+
let uniformSurfaceClipBasisEastLocation = null;
|
|
23718
|
+
let uniformSurfaceClipBasisNorthLocation = null;
|
|
23719
|
+
let anisotropyExtension = null;
|
|
23720
|
+
let maxSupportedAnisotropy = 1;
|
|
23721
|
+
let debugProgram = null;
|
|
23722
|
+
let debugVertexBuffer = null;
|
|
23723
|
+
let debugAttribPositionLocation = -1;
|
|
23724
|
+
let debugUniformColorLocation = null;
|
|
23725
|
+
let debugUniformScreenToClipScaleLocation = null;
|
|
23726
|
+
let debugUniformScreenToClipOffsetLocation = null;
|
|
23727
|
+
const images = /* @__PURE__ */ new Map();
|
|
23728
|
+
const queuedTextureIds = /* @__PURE__ */ new Set();
|
|
23729
|
+
const queueTextureUpload = (image) => {
|
|
23730
|
+
queuedTextureIds.add(image.id);
|
|
23731
|
+
};
|
|
23732
|
+
const cancelQueuedTextureUpload = (imageId) => {
|
|
23733
|
+
queuedTextureIds.delete(imageId);
|
|
23734
|
+
};
|
|
23735
|
+
const clearTextureQueue = () => {
|
|
23736
|
+
queuedTextureIds.clear();
|
|
23737
|
+
};
|
|
23738
|
+
const sprites = /* @__PURE__ */ new Map();
|
|
23739
|
+
const resolveSpriteMercator = (sprite) => {
|
|
23740
|
+
var _a2;
|
|
23741
|
+
const location2 = sprite.currentLocation;
|
|
23742
|
+
const altitude = (_a2 = location2.z) != null ? _a2 : 0;
|
|
23743
|
+
if (sprite.cachedMercator && sprite.cachedMercatorLng === location2.lng && sprite.cachedMercatorLat === location2.lat && sprite.cachedMercatorZ === altitude) {
|
|
23744
|
+
return sprite.cachedMercator;
|
|
23745
|
+
}
|
|
23746
|
+
const mercator = maplibreGlExports.MercatorCoordinate.fromLngLat(
|
|
23747
|
+
{ lng: location2.lng, lat: location2.lat },
|
|
23748
|
+
altitude
|
|
23749
|
+
);
|
|
23750
|
+
sprite.cachedMercator = mercator;
|
|
23751
|
+
sprite.cachedMercatorLng = location2.lng;
|
|
23752
|
+
sprite.cachedMercatorLat = location2.lat;
|
|
23753
|
+
sprite.cachedMercatorZ = altitude;
|
|
23754
|
+
return mercator;
|
|
23755
|
+
};
|
|
23756
|
+
const HIT_TEST_WORLD_BOUNDS = {
|
|
23757
|
+
x0: -180,
|
|
23758
|
+
y0: -90,
|
|
23759
|
+
x1: 180,
|
|
23760
|
+
y1: 90
|
|
23761
|
+
};
|
|
23762
|
+
const hitTestTree = createLooseQuadTree({
|
|
23763
|
+
bounds: HIT_TEST_WORLD_BOUNDS
|
|
23764
|
+
});
|
|
23765
|
+
let hitTestTreeItems = /* @__PURE__ */ new WeakMap();
|
|
23766
|
+
let isHitTestEnabled = true;
|
|
23767
|
+
const rectFromLngLatPoints = (points) => {
|
|
23768
|
+
let minLng = Number.POSITIVE_INFINITY;
|
|
23769
|
+
let maxLng = Number.NEGATIVE_INFINITY;
|
|
23770
|
+
let minLat = Number.POSITIVE_INFINITY;
|
|
23771
|
+
let maxLat = Number.NEGATIVE_INFINITY;
|
|
23772
|
+
for (const point of points) {
|
|
23773
|
+
if (!point || !Number.isFinite(point.lng) || !Number.isFinite(point.lat)) {
|
|
23774
|
+
continue;
|
|
23775
|
+
}
|
|
23776
|
+
if (point.lng < minLng) minLng = point.lng;
|
|
23777
|
+
if (point.lng > maxLng) maxLng = point.lng;
|
|
23778
|
+
if (point.lat < minLat) minLat = point.lat;
|
|
23779
|
+
if (point.lat > maxLat) maxLat = point.lat;
|
|
23780
|
+
}
|
|
23781
|
+
if (minLng === Number.POSITIVE_INFINITY || maxLng === Number.NEGATIVE_INFINITY || minLat === Number.POSITIVE_INFINITY || maxLat === Number.NEGATIVE_INFINITY) {
|
|
23782
|
+
return null;
|
|
23783
|
+
}
|
|
23784
|
+
return {
|
|
23785
|
+
x0: Math.max(
|
|
23786
|
+
HIT_TEST_WORLD_BOUNDS.x0,
|
|
23787
|
+
Math.min(minLng, HIT_TEST_WORLD_BOUNDS.x1)
|
|
23788
|
+
),
|
|
23789
|
+
y0: Math.max(
|
|
23790
|
+
HIT_TEST_WORLD_BOUNDS.y0,
|
|
23791
|
+
Math.min(minLat, HIT_TEST_WORLD_BOUNDS.y1)
|
|
23792
|
+
),
|
|
23793
|
+
x1: Math.max(
|
|
23794
|
+
HIT_TEST_WORLD_BOUNDS.x0,
|
|
23795
|
+
Math.min(maxLng, HIT_TEST_WORLD_BOUNDS.x1)
|
|
23796
|
+
),
|
|
23797
|
+
y1: Math.max(
|
|
23798
|
+
HIT_TEST_WORLD_BOUNDS.y0,
|
|
23799
|
+
Math.min(maxLat, HIT_TEST_WORLD_BOUNDS.y1)
|
|
23800
|
+
)
|
|
23801
|
+
};
|
|
23802
|
+
};
|
|
23803
|
+
const rectFromRadiusMeters = (base, radiusMeters) => {
|
|
23804
|
+
if (!Number.isFinite(base.lng) || !Number.isFinite(base.lat) || !Number.isFinite(radiusMeters) || radiusMeters <= 0) {
|
|
23805
|
+
return null;
|
|
23806
|
+
}
|
|
23807
|
+
const cornerNE = applySurfaceDisplacement(
|
|
23808
|
+
base.lng,
|
|
23809
|
+
base.lat,
|
|
23810
|
+
radiusMeters,
|
|
23811
|
+
radiusMeters
|
|
23812
|
+
);
|
|
23813
|
+
const cornerSW = applySurfaceDisplacement(
|
|
23814
|
+
base.lng,
|
|
23815
|
+
base.lat,
|
|
23816
|
+
-radiusMeters,
|
|
23817
|
+
-radiusMeters
|
|
23818
|
+
);
|
|
23819
|
+
return rectFromLngLatPoints([cornerNE, cornerSW]);
|
|
23820
|
+
};
|
|
23821
|
+
const estimateSurfaceImageBounds = (sprite, image) => {
|
|
23822
|
+
var _a2, _b, _c, _d, _e;
|
|
23823
|
+
const mapInstance = map;
|
|
23824
|
+
if (!mapInstance) {
|
|
23825
|
+
return null;
|
|
23826
|
+
}
|
|
23827
|
+
const imageResource = images.get(image.imageId);
|
|
23828
|
+
if (!imageResource) {
|
|
23829
|
+
return null;
|
|
23830
|
+
}
|
|
23831
|
+
const baseLocation = sprite.currentLocation;
|
|
23832
|
+
const zoom = mapInstance.getZoom();
|
|
23833
|
+
const zoomScaleFactor = calculateZoomScaleFactor(zoom, resolvedScaling);
|
|
23834
|
+
const metersPerPixelAtLat = calculateMetersPerPixelAtLatitude(
|
|
23835
|
+
zoom,
|
|
23836
|
+
baseLocation.lat
|
|
23837
|
+
);
|
|
23838
|
+
if (!Number.isFinite(metersPerPixelAtLat) || metersPerPixelAtLat <= 0) {
|
|
23839
|
+
return null;
|
|
23840
|
+
}
|
|
23841
|
+
const spriteMercator = resolveSpriteMercator(sprite);
|
|
23842
|
+
const perspectiveRatio = calculatePerspectiveRatio(
|
|
23843
|
+
mapInstance,
|
|
23844
|
+
baseLocation,
|
|
23845
|
+
spriteMercator
|
|
23846
|
+
);
|
|
23847
|
+
const effectivePixelsPerMeter = calculateEffectivePixelsPerMeter(
|
|
23848
|
+
metersPerPixelAtLat,
|
|
23849
|
+
perspectiveRatio
|
|
23850
|
+
);
|
|
23851
|
+
if (!Number.isFinite(effectivePixelsPerMeter) || effectivePixelsPerMeter <= 0) {
|
|
23852
|
+
return null;
|
|
23853
|
+
}
|
|
23854
|
+
const imageScale = (_a2 = image.scale) != null ? _a2 : 1;
|
|
23855
|
+
const baseMetersPerPixel = resolvedScaling.metersPerPixel;
|
|
23856
|
+
const spriteMinPixel = resolvedScaling.spriteMinPixel;
|
|
23857
|
+
const spriteMaxPixel = resolvedScaling.spriteMaxPixel;
|
|
23858
|
+
const worldDims = calculateSurfaceWorldDimensions(
|
|
23859
|
+
imageResource.width,
|
|
23860
|
+
imageResource.height,
|
|
23861
|
+
baseMetersPerPixel,
|
|
23862
|
+
imageScale,
|
|
23863
|
+
zoomScaleFactor,
|
|
23864
|
+
{
|
|
23865
|
+
effectivePixelsPerMeter,
|
|
23866
|
+
spriteMinPixel,
|
|
23867
|
+
spriteMaxPixel
|
|
23868
|
+
}
|
|
23869
|
+
);
|
|
23870
|
+
if (worldDims.width <= 0 || worldDims.height <= 0) {
|
|
23871
|
+
return null;
|
|
23872
|
+
}
|
|
23873
|
+
const anchor = (_b = image.anchor) != null ? _b : DEFAULT_ANCHOR;
|
|
23874
|
+
const offsetDef = (_c = image.offset) != null ? _c : DEFAULT_IMAGE_OFFSET;
|
|
23875
|
+
const offsetMetersVec = calculateSurfaceOffsetMeters(
|
|
23876
|
+
offsetDef,
|
|
23877
|
+
imageScale,
|
|
23878
|
+
zoomScaleFactor,
|
|
23879
|
+
worldDims.scaleAdjustment
|
|
23880
|
+
);
|
|
23881
|
+
const totalRotateDeg = Number.isFinite(image.displayedRotateDeg) ? image.displayedRotateDeg : normalizeAngleDeg(
|
|
23882
|
+
((_d = image.resolvedBaseRotateDeg) != null ? _d : 0) + ((_e = image.rotateDeg) != null ? _e : 0)
|
|
23883
|
+
);
|
|
23884
|
+
const cornerDisplacements = calculateSurfaceCornerDisplacements({
|
|
23885
|
+
worldWidthMeters: worldDims.width,
|
|
23886
|
+
worldHeightMeters: worldDims.height,
|
|
23887
|
+
anchor,
|
|
23888
|
+
totalRotateDeg,
|
|
23889
|
+
offsetMeters: offsetMetersVec
|
|
23890
|
+
});
|
|
23891
|
+
const corners = cornerDisplacements.map(
|
|
23892
|
+
(corner) => applySurfaceDisplacement(
|
|
23893
|
+
baseLocation.lng,
|
|
23894
|
+
baseLocation.lat,
|
|
23895
|
+
corner.east,
|
|
23896
|
+
corner.north
|
|
23897
|
+
)
|
|
23898
|
+
);
|
|
23899
|
+
return rectFromLngLatPoints(corners);
|
|
23900
|
+
};
|
|
23901
|
+
const estimateBillboardImageBounds = (sprite, image) => {
|
|
23902
|
+
var _a2, _b, _c, _d;
|
|
23903
|
+
const mapInstance = map;
|
|
23904
|
+
if (!mapInstance) {
|
|
23905
|
+
return null;
|
|
23906
|
+
}
|
|
23907
|
+
const imageResource = images.get(image.imageId);
|
|
23908
|
+
if (!imageResource) {
|
|
23909
|
+
return null;
|
|
23910
|
+
}
|
|
23911
|
+
const baseLocation = sprite.currentLocation;
|
|
23912
|
+
const zoom = mapInstance.getZoom();
|
|
23913
|
+
const zoomScaleFactor = calculateZoomScaleFactor(zoom, resolvedScaling);
|
|
23914
|
+
const metersPerPixelAtLat = calculateMetersPerPixelAtLatitude(
|
|
23915
|
+
zoom,
|
|
23916
|
+
baseLocation.lat
|
|
23917
|
+
);
|
|
23918
|
+
if (!Number.isFinite(metersPerPixelAtLat) || metersPerPixelAtLat <= 0) {
|
|
23919
|
+
return null;
|
|
23920
|
+
}
|
|
23921
|
+
const spriteMercator = resolveSpriteMercator(sprite);
|
|
23922
|
+
const perspectiveRatio = calculatePerspectiveRatio(
|
|
23923
|
+
mapInstance,
|
|
23924
|
+
baseLocation,
|
|
23925
|
+
spriteMercator
|
|
23926
|
+
);
|
|
23927
|
+
const effectivePixelsPerMeter = calculateEffectivePixelsPerMeter(
|
|
23928
|
+
metersPerPixelAtLat,
|
|
23929
|
+
perspectiveRatio
|
|
23930
|
+
);
|
|
23931
|
+
if (!Number.isFinite(effectivePixelsPerMeter) || effectivePixelsPerMeter <= 0) {
|
|
23932
|
+
return null;
|
|
23933
|
+
}
|
|
23934
|
+
const baseMetersPerPixel = resolvedScaling.metersPerPixel;
|
|
23935
|
+
const spriteMinPixel = resolvedScaling.spriteMinPixel;
|
|
23936
|
+
const spriteMaxPixel = resolvedScaling.spriteMaxPixel;
|
|
23937
|
+
const imageScale = (_a2 = image.scale) != null ? _a2 : 1;
|
|
23938
|
+
const totalRotateDeg = Number.isFinite(image.displayedRotateDeg) ? image.displayedRotateDeg : normalizeAngleDeg(
|
|
23939
|
+
((_b = image.resolvedBaseRotateDeg) != null ? _b : 0) + ((_c = image.rotateDeg) != null ? _c : 0)
|
|
23940
|
+
);
|
|
23941
|
+
const pixelDims = calculateBillboardPixelDimensions(
|
|
23942
|
+
imageResource.width,
|
|
23943
|
+
imageResource.height,
|
|
23944
|
+
baseMetersPerPixel,
|
|
23945
|
+
imageScale,
|
|
23946
|
+
zoomScaleFactor,
|
|
23947
|
+
effectivePixelsPerMeter,
|
|
23948
|
+
spriteMinPixel,
|
|
23949
|
+
spriteMaxPixel
|
|
23950
|
+
);
|
|
23951
|
+
const halfWidthMeters = pixelDims.width / 2 / effectivePixelsPerMeter;
|
|
23952
|
+
const halfHeightMeters = pixelDims.height / 2 / effectivePixelsPerMeter;
|
|
23953
|
+
const anchorShift = calculateBillboardAnchorShiftPixels(
|
|
23954
|
+
pixelDims.width / 2,
|
|
23955
|
+
pixelDims.height / 2,
|
|
23956
|
+
image.anchor,
|
|
23957
|
+
totalRotateDeg
|
|
23958
|
+
);
|
|
23959
|
+
const offsetShift = calculateBillboardOffsetPixels(
|
|
23960
|
+
(_d = image.offset) != null ? _d : DEFAULT_IMAGE_OFFSET,
|
|
23961
|
+
imageScale,
|
|
23962
|
+
zoomScaleFactor,
|
|
23963
|
+
effectivePixelsPerMeter
|
|
23964
|
+
);
|
|
23965
|
+
const anchorShiftMeters = Math.hypot(anchorShift.x, anchorShift.y) / effectivePixelsPerMeter;
|
|
23966
|
+
const offsetShiftMeters = Math.hypot(offsetShift.x, offsetShift.y) / effectivePixelsPerMeter;
|
|
23967
|
+
const safetyRadius = Math.hypot(halfWidthMeters, halfHeightMeters) + anchorShiftMeters + offsetShiftMeters;
|
|
23968
|
+
return rectFromRadiusMeters(baseLocation, safetyRadius);
|
|
23969
|
+
};
|
|
23970
|
+
const estimateImageBounds = (sprite, image) => {
|
|
23971
|
+
if (image.opacity <= 0 || !sprite.isEnabled) {
|
|
23972
|
+
return null;
|
|
23973
|
+
}
|
|
23974
|
+
if (image.mode === "surface") {
|
|
23975
|
+
return estimateSurfaceImageBounds(sprite, image);
|
|
23976
|
+
}
|
|
23977
|
+
return estimateBillboardImageBounds(sprite, image);
|
|
23978
|
+
};
|
|
23979
|
+
const removeImageBoundsFromHitTestTree = (image) => {
|
|
23980
|
+
const handle = hitTestTreeItems.get(image);
|
|
23981
|
+
if (!handle) {
|
|
23982
|
+
return;
|
|
23983
|
+
}
|
|
23984
|
+
hitTestTree.remove(
|
|
23985
|
+
handle.rect.x0,
|
|
23986
|
+
handle.rect.y0,
|
|
23987
|
+
handle.rect.x1,
|
|
23988
|
+
handle.rect.y1,
|
|
23989
|
+
handle.item
|
|
23990
|
+
);
|
|
23991
|
+
hitTestTreeItems.delete(image);
|
|
23992
|
+
};
|
|
23993
|
+
const setItemRect = (item, rect) => {
|
|
23994
|
+
const mutable = item;
|
|
23995
|
+
mutable.x0 = rect.x0;
|
|
23996
|
+
mutable.y0 = rect.y0;
|
|
23997
|
+
mutable.x1 = rect.x1;
|
|
23998
|
+
mutable.y1 = rect.y1;
|
|
23236
23999
|
};
|
|
23237
|
-
const
|
|
23238
|
-
|
|
24000
|
+
const registerImageBoundsInHitTestTree = (sprite, image) => {
|
|
24001
|
+
const existingHandle = hitTestTreeItems.get(image);
|
|
24002
|
+
if (!isHitTestEnabled) {
|
|
24003
|
+
if (existingHandle) {
|
|
24004
|
+
removeImageBoundsFromHitTestTree(image);
|
|
24005
|
+
}
|
|
24006
|
+
return;
|
|
24007
|
+
}
|
|
24008
|
+
const rect = estimateImageBounds(sprite, image);
|
|
24009
|
+
if (!rect) {
|
|
24010
|
+
if (existingHandle) {
|
|
24011
|
+
removeImageBoundsFromHitTestTree(image);
|
|
24012
|
+
}
|
|
24013
|
+
return;
|
|
24014
|
+
}
|
|
24015
|
+
if (!existingHandle) {
|
|
24016
|
+
const handle = {
|
|
24017
|
+
rect,
|
|
24018
|
+
item: {
|
|
24019
|
+
x0: rect.x0,
|
|
24020
|
+
y0: rect.y0,
|
|
24021
|
+
x1: rect.x1,
|
|
24022
|
+
y1: rect.y1,
|
|
24023
|
+
state: {
|
|
24024
|
+
sprite,
|
|
24025
|
+
image,
|
|
24026
|
+
drawIndex: 0
|
|
24027
|
+
}
|
|
24028
|
+
}
|
|
24029
|
+
};
|
|
24030
|
+
hitTestTree.add(handle.item);
|
|
24031
|
+
hitTestTreeItems.set(image, handle);
|
|
24032
|
+
return;
|
|
24033
|
+
}
|
|
24034
|
+
const currentRect = existingHandle.rect;
|
|
24035
|
+
const unchanged = currentRect.x0 === rect.x0 && currentRect.y0 === rect.y0 && currentRect.x1 === rect.x1 && currentRect.y1 === rect.y1;
|
|
24036
|
+
if (unchanged) {
|
|
24037
|
+
return;
|
|
24038
|
+
}
|
|
24039
|
+
const updated = hitTestTree.update(
|
|
24040
|
+
currentRect.x0,
|
|
24041
|
+
currentRect.y0,
|
|
24042
|
+
currentRect.x1,
|
|
24043
|
+
currentRect.y1,
|
|
24044
|
+
rect.x0,
|
|
24045
|
+
rect.y0,
|
|
24046
|
+
rect.x1,
|
|
24047
|
+
rect.y1,
|
|
24048
|
+
existingHandle.item
|
|
24049
|
+
);
|
|
24050
|
+
if (updated) {
|
|
24051
|
+
existingHandle.rect = rect;
|
|
24052
|
+
setItemRect(existingHandle.item, rect);
|
|
24053
|
+
return;
|
|
24054
|
+
}
|
|
24055
|
+
removeImageBoundsFromHitTestTree(image);
|
|
24056
|
+
const newHandle = {
|
|
24057
|
+
rect,
|
|
24058
|
+
item: {
|
|
24059
|
+
x0: rect.x0,
|
|
24060
|
+
y0: rect.y0,
|
|
24061
|
+
x1: rect.x1,
|
|
24062
|
+
y1: rect.y1,
|
|
24063
|
+
state: {
|
|
24064
|
+
sprite,
|
|
24065
|
+
image,
|
|
24066
|
+
drawIndex: 0
|
|
24067
|
+
}
|
|
24068
|
+
}
|
|
24069
|
+
};
|
|
24070
|
+
hitTestTree.add(newHandle.item);
|
|
24071
|
+
hitTestTreeItems.set(image, newHandle);
|
|
23239
24072
|
};
|
|
23240
|
-
const
|
|
23241
|
-
|
|
24073
|
+
const refreshSpriteHitTestBounds = (sprite) => {
|
|
24074
|
+
sprite.images.forEach((orderMap) => {
|
|
24075
|
+
orderMap.forEach((image) => {
|
|
24076
|
+
registerImageBoundsInHitTestTree(sprite, image);
|
|
24077
|
+
});
|
|
24078
|
+
});
|
|
23242
24079
|
};
|
|
23243
|
-
const sprites = /* @__PURE__ */ new Map();
|
|
23244
24080
|
const getImageState = (sprite, subLayer, order) => {
|
|
23245
24081
|
var _a2;
|
|
23246
24082
|
return (
|
|
@@ -23273,34 +24109,38 @@ const createSpriteLayer = (options) => {
|
|
|
23273
24109
|
return deleted;
|
|
23274
24110
|
};
|
|
23275
24111
|
const HIT_TEST_EPSILON = 1e-3;
|
|
23276
|
-
const
|
|
23277
|
-
|
|
23278
|
-
|
|
23279
|
-
|
|
23280
|
-
|
|
23281
|
-
|
|
23282
|
-
|
|
23283
|
-
|
|
23284
|
-
|
|
23285
|
-
|
|
23286
|
-
|
|
23287
|
-
|
|
23288
|
-
|
|
23289
|
-
|
|
23290
|
-
|
|
24112
|
+
const pointInRenderedQuad = (point, corners) => {
|
|
24113
|
+
let hasPositiveCross = false;
|
|
24114
|
+
let hasNegativeCross = false;
|
|
24115
|
+
for (let i = 0; i < DEBUG_OUTLINE_CORNER_ORDER.length; i++) {
|
|
24116
|
+
const currentIndex = DEBUG_OUTLINE_CORNER_ORDER[i];
|
|
24117
|
+
const nextIndex = DEBUG_OUTLINE_CORNER_ORDER[(i + 1) % DEBUG_OUTLINE_CORNER_ORDER.length];
|
|
24118
|
+
const a = corners[currentIndex];
|
|
24119
|
+
const b = corners[nextIndex];
|
|
24120
|
+
const edgeX = b.x - a.x;
|
|
24121
|
+
const edgeY = b.y - a.y;
|
|
24122
|
+
const pointX = point.x - a.x;
|
|
24123
|
+
const pointY = point.y - a.y;
|
|
24124
|
+
const cross = edgeX * pointY - edgeY * pointX;
|
|
24125
|
+
if (Math.abs(cross) <= HIT_TEST_EPSILON) {
|
|
24126
|
+
continue;
|
|
24127
|
+
}
|
|
24128
|
+
if (cross > 0) {
|
|
24129
|
+
hasPositiveCross = true;
|
|
24130
|
+
} else {
|
|
24131
|
+
hasNegativeCross = true;
|
|
24132
|
+
}
|
|
24133
|
+
if (hasPositiveCross && hasNegativeCross) {
|
|
24134
|
+
return false;
|
|
24135
|
+
}
|
|
23291
24136
|
}
|
|
23292
|
-
|
|
23293
|
-
const u = (dot11 * dot02 - dot01 * dot12) * invDenom;
|
|
23294
|
-
const v = (dot00 * dot12 - dot01 * dot02) * invDenom;
|
|
23295
|
-
const w = 1 - u - v;
|
|
23296
|
-
return u >= -HIT_TEST_EPSILON && v >= -HIT_TEST_EPSILON && w >= -HIT_TEST_EPSILON;
|
|
24137
|
+
return true;
|
|
23297
24138
|
};
|
|
23298
|
-
const pointInQuad = (point, corners) => pointInTriangle(point, corners[0], corners[1], corners[2]) || pointInTriangle(point, corners[0], corners[2], corners[3]);
|
|
23299
24139
|
const isPointInsideHitEntry = (entry, point) => {
|
|
23300
24140
|
if (point.x < entry.minX - HIT_TEST_EPSILON || point.x > entry.maxX + HIT_TEST_EPSILON || point.y < entry.minY - HIT_TEST_EPSILON || point.y > entry.maxY + HIT_TEST_EPSILON) {
|
|
23301
24141
|
return false;
|
|
23302
24142
|
}
|
|
23303
|
-
return
|
|
24143
|
+
return pointInRenderedQuad(point, entry.corners);
|
|
23304
24144
|
};
|
|
23305
24145
|
const buildSortedSubLayerBuckets = (entries) => {
|
|
23306
24146
|
const buckets = /* @__PURE__ */ new Map();
|
|
@@ -23442,6 +24282,7 @@ const createSpriteLayer = (options) => {
|
|
|
23442
24282
|
};
|
|
23443
24283
|
const renderTargetEntries = [];
|
|
23444
24284
|
const hitTestEntries = [];
|
|
24285
|
+
let hitTestEntryByImage = /* @__PURE__ */ new WeakMap();
|
|
23445
24286
|
const ensureHitTestCorners = (imageEntry) => {
|
|
23446
24287
|
if (!imageEntry.hitTestCorners) {
|
|
23447
24288
|
imageEntry.hitTestCorners = [
|
|
@@ -23453,7 +24294,10 @@ const createSpriteLayer = (options) => {
|
|
|
23453
24294
|
}
|
|
23454
24295
|
return imageEntry.hitTestCorners;
|
|
23455
24296
|
};
|
|
23456
|
-
const registerHitTestEntry = (spriteEntry, imageEntry, screenCorners) => {
|
|
24297
|
+
const registerHitTestEntry = (spriteEntry, imageEntry, screenCorners, drawIndex) => {
|
|
24298
|
+
if (!isHitTestEnabled) {
|
|
24299
|
+
return;
|
|
24300
|
+
}
|
|
23457
24301
|
const corners = screenCorners;
|
|
23458
24302
|
let minX = corners[0].x;
|
|
23459
24303
|
let maxX = corners[0].x;
|
|
@@ -23466,7 +24310,7 @@ const createSpriteLayer = (options) => {
|
|
|
23466
24310
|
if (corner.y < minY) minY = corner.y;
|
|
23467
24311
|
if (corner.y > maxY) maxY = corner.y;
|
|
23468
24312
|
}
|
|
23469
|
-
|
|
24313
|
+
const entry = {
|
|
23470
24314
|
sprite: spriteEntry,
|
|
23471
24315
|
image: imageEntry,
|
|
23472
24316
|
corners,
|
|
@@ -23474,9 +24318,15 @@ const createSpriteLayer = (options) => {
|
|
|
23474
24318
|
maxX,
|
|
23475
24319
|
minY,
|
|
23476
24320
|
maxY
|
|
23477
|
-
}
|
|
24321
|
+
};
|
|
24322
|
+
hitTestEntries.push(entry);
|
|
24323
|
+
hitTestEntryByImage.set(imageEntry, entry);
|
|
24324
|
+
const handle = hitTestTreeItems.get(imageEntry);
|
|
24325
|
+
if (handle) {
|
|
24326
|
+
handle.item.state.drawIndex = drawIndex;
|
|
24327
|
+
}
|
|
23478
24328
|
};
|
|
23479
|
-
const
|
|
24329
|
+
const findTopmostHitEntryLinear = (point) => {
|
|
23480
24330
|
for (let i = hitTestEntries.length - 1; i >= 0; i--) {
|
|
23481
24331
|
const entry = hitTestEntries[i];
|
|
23482
24332
|
if (isPointInsideHitEntry(entry, point)) {
|
|
@@ -23485,6 +24335,66 @@ const createSpriteLayer = (options) => {
|
|
|
23485
24335
|
}
|
|
23486
24336
|
return null;
|
|
23487
24337
|
};
|
|
24338
|
+
const findTopmostHitEntry = (point) => {
|
|
24339
|
+
if (!isHitTestEnabled) {
|
|
24340
|
+
return null;
|
|
24341
|
+
}
|
|
24342
|
+
const mapInstance = map;
|
|
24343
|
+
if (!mapInstance) {
|
|
24344
|
+
return findTopmostHitEntryLinear(point);
|
|
24345
|
+
}
|
|
24346
|
+
const centerLngLat = mapInstance.unproject([point.x, point.y]);
|
|
24347
|
+
if (!centerLngLat) {
|
|
24348
|
+
return findTopmostHitEntryLinear(point);
|
|
24349
|
+
}
|
|
24350
|
+
const searchPoints = [
|
|
24351
|
+
{ lng: centerLngLat.lng, lat: centerLngLat.lat }
|
|
24352
|
+
];
|
|
24353
|
+
const radius = HIT_TEST_QUERY_RADIUS_PIXELS;
|
|
24354
|
+
const offsets = [
|
|
24355
|
+
[point.x - radius, point.y - radius],
|
|
24356
|
+
[point.x + radius, point.y - radius],
|
|
24357
|
+
[point.x - radius, point.y + radius],
|
|
24358
|
+
[point.x + radius, point.y + radius]
|
|
24359
|
+
];
|
|
24360
|
+
for (const [x, y] of offsets) {
|
|
24361
|
+
const lngLat = mapInstance.unproject([x, y]);
|
|
24362
|
+
if (lngLat) {
|
|
24363
|
+
searchPoints.push({ lng: lngLat.lng, lat: lngLat.lat });
|
|
24364
|
+
}
|
|
24365
|
+
}
|
|
24366
|
+
const searchRect = rectFromLngLatPoints(searchPoints);
|
|
24367
|
+
if (!searchRect) {
|
|
24368
|
+
return findTopmostHitEntryLinear(point);
|
|
24369
|
+
}
|
|
24370
|
+
const candidates = hitTestTree.lookup(
|
|
24371
|
+
searchRect.x0,
|
|
24372
|
+
searchRect.y0,
|
|
24373
|
+
searchRect.x1,
|
|
24374
|
+
searchRect.y1
|
|
24375
|
+
);
|
|
24376
|
+
if (candidates.length === 0) {
|
|
24377
|
+
return findTopmostHitEntryLinear(point);
|
|
24378
|
+
}
|
|
24379
|
+
candidates.sort((a, b) => a.state.drawIndex - b.state.drawIndex);
|
|
24380
|
+
const seenImages = /* @__PURE__ */ new Set();
|
|
24381
|
+
for (let i = candidates.length - 1; i >= 0; i--) {
|
|
24382
|
+
const candidate = candidates[i];
|
|
24383
|
+
const image = candidate.state.image;
|
|
24384
|
+
if (seenImages.has(image)) {
|
|
24385
|
+
continue;
|
|
24386
|
+
}
|
|
24387
|
+
seenImages.add(image);
|
|
24388
|
+
const entry = hitTestEntryByImage.get(image);
|
|
24389
|
+
if (!entry) {
|
|
24390
|
+
continue;
|
|
24391
|
+
}
|
|
24392
|
+
if (isPointInsideHitEntry(entry, point)) {
|
|
24393
|
+
return entry;
|
|
24394
|
+
}
|
|
24395
|
+
}
|
|
24396
|
+
return findTopmostHitEntryLinear(point);
|
|
24397
|
+
};
|
|
23488
24398
|
const eventListeners = /* @__PURE__ */ new Map();
|
|
23489
24399
|
const getListenerSet = (type) => {
|
|
23490
24400
|
let set = eventListeners.get(type);
|
|
@@ -23867,7 +24777,59 @@ const createSpriteLayer = (options) => {
|
|
|
23867
24777
|
shaderProgram,
|
|
23868
24778
|
"u_opacity"
|
|
23869
24779
|
);
|
|
23870
|
-
|
|
24780
|
+
uniformScreenToClipScaleLocation = glContext.getUniformLocation(
|
|
24781
|
+
shaderProgram,
|
|
24782
|
+
"u_screenToClipScale"
|
|
24783
|
+
);
|
|
24784
|
+
uniformScreenToClipOffsetLocation = glContext.getUniformLocation(
|
|
24785
|
+
shaderProgram,
|
|
24786
|
+
"u_screenToClipOffset"
|
|
24787
|
+
);
|
|
24788
|
+
uniformBillboardModeLocation = glContext.getUniformLocation(
|
|
24789
|
+
shaderProgram,
|
|
24790
|
+
"u_billboardMode"
|
|
24791
|
+
);
|
|
24792
|
+
uniformBillboardCenterLocation = glContext.getUniformLocation(
|
|
24793
|
+
shaderProgram,
|
|
24794
|
+
"u_billboardCenter"
|
|
24795
|
+
);
|
|
24796
|
+
uniformBillboardHalfSizeLocation = glContext.getUniformLocation(
|
|
24797
|
+
shaderProgram,
|
|
24798
|
+
"u_billboardHalfSize"
|
|
24799
|
+
);
|
|
24800
|
+
uniformBillboardAnchorLocation = glContext.getUniformLocation(
|
|
24801
|
+
shaderProgram,
|
|
24802
|
+
"u_billboardAnchor"
|
|
24803
|
+
);
|
|
24804
|
+
uniformBillboardSinCosLocation = glContext.getUniformLocation(
|
|
24805
|
+
shaderProgram,
|
|
24806
|
+
"u_billboardSinCos"
|
|
24807
|
+
);
|
|
24808
|
+
uniformSurfaceModeLocation = glContext.getUniformLocation(
|
|
24809
|
+
shaderProgram,
|
|
24810
|
+
"u_surfaceMode"
|
|
24811
|
+
);
|
|
24812
|
+
uniformSurfaceDepthBiasLocation = glContext.getUniformLocation(
|
|
24813
|
+
shaderProgram,
|
|
24814
|
+
"u_surfaceDepthBias"
|
|
24815
|
+
);
|
|
24816
|
+
uniformSurfaceClipEnabledLocation = glContext.getUniformLocation(
|
|
24817
|
+
shaderProgram,
|
|
24818
|
+
"u_surfaceClipEnabled"
|
|
24819
|
+
);
|
|
24820
|
+
uniformSurfaceClipCenterLocation = glContext.getUniformLocation(
|
|
24821
|
+
shaderProgram,
|
|
24822
|
+
"u_surfaceClipCenter"
|
|
24823
|
+
);
|
|
24824
|
+
uniformSurfaceClipBasisEastLocation = glContext.getUniformLocation(
|
|
24825
|
+
shaderProgram,
|
|
24826
|
+
"u_surfaceClipBasisEast"
|
|
24827
|
+
);
|
|
24828
|
+
uniformSurfaceClipBasisNorthLocation = glContext.getUniformLocation(
|
|
24829
|
+
shaderProgram,
|
|
24830
|
+
"u_surfaceClipBasisNorth"
|
|
24831
|
+
);
|
|
24832
|
+
if (!uniformTextureLocation || !uniformOpacityLocation || !uniformScreenToClipScaleLocation || !uniformScreenToClipOffsetLocation || !uniformBillboardModeLocation || !uniformBillboardCenterLocation || !uniformBillboardHalfSizeLocation || !uniformBillboardAnchorLocation || !uniformBillboardSinCosLocation || !uniformSurfaceModeLocation || !uniformSurfaceDepthBiasLocation || !uniformSurfaceClipEnabledLocation || !uniformSurfaceClipCenterLocation || !uniformSurfaceClipBasisEastLocation || !uniformSurfaceClipBasisNorthLocation) {
|
|
23871
24833
|
throw new Error("Failed to acquire uniform locations.");
|
|
23872
24834
|
}
|
|
23873
24835
|
glContext.enableVertexAttribArray(attribPositionLocation);
|
|
@@ -23890,7 +24852,80 @@ const createSpriteLayer = (options) => {
|
|
|
23890
24852
|
);
|
|
23891
24853
|
glContext.uniform1i(uniformTextureLocation, 0);
|
|
23892
24854
|
glContext.uniform1f(uniformOpacityLocation, 1);
|
|
24855
|
+
glContext.uniform2f(uniformScreenToClipScaleLocation, 1, 1);
|
|
24856
|
+
glContext.uniform2f(uniformScreenToClipOffsetLocation, 0, 0);
|
|
24857
|
+
glContext.uniform1f(uniformSurfaceClipEnabledLocation, 0);
|
|
24858
|
+
glContext.uniform4f(uniformSurfaceClipCenterLocation, 0, 0, 0, 1);
|
|
24859
|
+
glContext.uniform4f(
|
|
24860
|
+
uniformSurfaceClipBasisEastLocation,
|
|
24861
|
+
0,
|
|
24862
|
+
0,
|
|
24863
|
+
0,
|
|
24864
|
+
0
|
|
24865
|
+
);
|
|
24866
|
+
glContext.uniform4f(
|
|
24867
|
+
uniformSurfaceClipBasisNorthLocation,
|
|
24868
|
+
0,
|
|
24869
|
+
0,
|
|
24870
|
+
0,
|
|
24871
|
+
0
|
|
24872
|
+
);
|
|
24873
|
+
glContext.uniform1f(uniformBillboardModeLocation, 0);
|
|
24874
|
+
glContext.uniform2f(uniformBillboardCenterLocation, 0, 0);
|
|
24875
|
+
glContext.uniform2f(uniformBillboardHalfSizeLocation, 0, 0);
|
|
24876
|
+
glContext.uniform2f(uniformBillboardAnchorLocation, 0, 0);
|
|
24877
|
+
glContext.uniform2f(uniformBillboardSinCosLocation, 0, 1);
|
|
24878
|
+
glContext.uniform1f(uniformSurfaceModeLocation, 0);
|
|
24879
|
+
glContext.uniform1f(uniformSurfaceDepthBiasLocation, 0);
|
|
23893
24880
|
glContext.bindBuffer(glContext.ARRAY_BUFFER, null);
|
|
24881
|
+
if (showDebugBounds) {
|
|
24882
|
+
const debugShaderProgram = createShaderProgram(
|
|
24883
|
+
glContext,
|
|
24884
|
+
DEBUG_OUTLINE_VERTEX_SHADER_SOURCE,
|
|
24885
|
+
DEBUG_OUTLINE_FRAGMENT_SHADER_SOURCE
|
|
24886
|
+
);
|
|
24887
|
+
debugProgram = debugShaderProgram;
|
|
24888
|
+
debugAttribPositionLocation = glContext.getAttribLocation(
|
|
24889
|
+
debugShaderProgram,
|
|
24890
|
+
"a_position"
|
|
24891
|
+
);
|
|
24892
|
+
if (debugAttribPositionLocation === -1) {
|
|
24893
|
+
throw new Error("Failed to acquire debug attribute location.");
|
|
24894
|
+
}
|
|
24895
|
+
const colorLocation = glContext.getUniformLocation(
|
|
24896
|
+
debugShaderProgram,
|
|
24897
|
+
"u_color"
|
|
24898
|
+
);
|
|
24899
|
+
if (!colorLocation) {
|
|
24900
|
+
throw new Error("Failed to acquire debug color uniform.");
|
|
24901
|
+
}
|
|
24902
|
+
debugUniformColorLocation = colorLocation;
|
|
24903
|
+
debugUniformScreenToClipScaleLocation = glContext.getUniformLocation(
|
|
24904
|
+
debugShaderProgram,
|
|
24905
|
+
"u_screenToClipScale"
|
|
24906
|
+
);
|
|
24907
|
+
debugUniformScreenToClipOffsetLocation = glContext.getUniformLocation(
|
|
24908
|
+
debugShaderProgram,
|
|
24909
|
+
"u_screenToClipOffset"
|
|
24910
|
+
);
|
|
24911
|
+
if (!debugUniformScreenToClipScaleLocation || !debugUniformScreenToClipOffsetLocation) {
|
|
24912
|
+
throw new Error("Failed to acquire debug screen-to-clip uniforms.");
|
|
24913
|
+
}
|
|
24914
|
+
glContext.uniform2f(debugUniformScreenToClipScaleLocation, 1, 1);
|
|
24915
|
+
glContext.uniform2f(debugUniformScreenToClipOffsetLocation, 0, 0);
|
|
24916
|
+
const outlineBuffer = glContext.createBuffer();
|
|
24917
|
+
if (!outlineBuffer) {
|
|
24918
|
+
throw new Error("Failed to create debug vertex buffer.");
|
|
24919
|
+
}
|
|
24920
|
+
debugVertexBuffer = outlineBuffer;
|
|
24921
|
+
glContext.bindBuffer(glContext.ARRAY_BUFFER, outlineBuffer);
|
|
24922
|
+
glContext.bufferData(
|
|
24923
|
+
glContext.ARRAY_BUFFER,
|
|
24924
|
+
DEBUG_OUTLINE_VERTEX_SCRATCH,
|
|
24925
|
+
glContext.DYNAMIC_DRAW
|
|
24926
|
+
);
|
|
24927
|
+
glContext.bindBuffer(glContext.ARRAY_BUFFER, null);
|
|
24928
|
+
}
|
|
23894
24929
|
scheduleRender();
|
|
23895
24930
|
};
|
|
23896
24931
|
const onRemove = () => {
|
|
@@ -23898,6 +24933,9 @@ const createSpriteLayer = (options) => {
|
|
|
23898
24933
|
inputListenerDisposers.length = 0;
|
|
23899
24934
|
canvasElement = null;
|
|
23900
24935
|
hitTestEntries.length = 0;
|
|
24936
|
+
hitTestEntryByImage = /* @__PURE__ */ new WeakMap();
|
|
24937
|
+
hitTestTree.clear();
|
|
24938
|
+
hitTestTreeItems = /* @__PURE__ */ new WeakMap();
|
|
23901
24939
|
const glContext = gl;
|
|
23902
24940
|
if (glContext) {
|
|
23903
24941
|
images.forEach((image) => {
|
|
@@ -23910,9 +24948,15 @@ const createSpriteLayer = (options) => {
|
|
|
23910
24948
|
if (vertexBuffer) {
|
|
23911
24949
|
glContext.deleteBuffer(vertexBuffer);
|
|
23912
24950
|
}
|
|
24951
|
+
if (debugVertexBuffer) {
|
|
24952
|
+
glContext.deleteBuffer(debugVertexBuffer);
|
|
24953
|
+
}
|
|
23913
24954
|
if (program) {
|
|
23914
24955
|
glContext.deleteProgram(program);
|
|
23915
24956
|
}
|
|
24957
|
+
if (debugProgram) {
|
|
24958
|
+
glContext.deleteProgram(debugProgram);
|
|
24959
|
+
}
|
|
23916
24960
|
}
|
|
23917
24961
|
eventListeners.forEach((set) => set.clear());
|
|
23918
24962
|
eventListeners.clear();
|
|
@@ -23920,20 +24964,36 @@ const createSpriteLayer = (options) => {
|
|
|
23920
24964
|
map = null;
|
|
23921
24965
|
program = null;
|
|
23922
24966
|
vertexBuffer = null;
|
|
24967
|
+
debugProgram = null;
|
|
24968
|
+
debugVertexBuffer = null;
|
|
23923
24969
|
attribPositionLocation = -1;
|
|
23924
24970
|
attribUvLocation = -1;
|
|
24971
|
+
debugAttribPositionLocation = -1;
|
|
23925
24972
|
uniformTextureLocation = null;
|
|
23926
24973
|
uniformOpacityLocation = null;
|
|
24974
|
+
uniformScreenToClipScaleLocation = null;
|
|
24975
|
+
uniformScreenToClipOffsetLocation = null;
|
|
24976
|
+
uniformBillboardModeLocation = null;
|
|
24977
|
+
uniformBillboardCenterLocation = null;
|
|
24978
|
+
uniformBillboardHalfSizeLocation = null;
|
|
24979
|
+
uniformBillboardAnchorLocation = null;
|
|
24980
|
+
uniformBillboardSinCosLocation = null;
|
|
24981
|
+
uniformSurfaceModeLocation = null;
|
|
24982
|
+
uniformSurfaceDepthBiasLocation = null;
|
|
24983
|
+
debugUniformColorLocation = null;
|
|
24984
|
+
debugUniformScreenToClipScaleLocation = null;
|
|
24985
|
+
debugUniformScreenToClipOffsetLocation = null;
|
|
23927
24986
|
anisotropyExtension = null;
|
|
23928
24987
|
maxSupportedAnisotropy = 1;
|
|
23929
24988
|
};
|
|
23930
24989
|
const render = (glContext, _options) => {
|
|
23931
24990
|
hitTestEntries.length = 0;
|
|
24991
|
+
hitTestEntryByImage = /* @__PURE__ */ new WeakMap();
|
|
23932
24992
|
const mapInstance = map;
|
|
23933
24993
|
if (!mapInstance || !program || !vertexBuffer) {
|
|
23934
24994
|
return;
|
|
23935
24995
|
}
|
|
23936
|
-
if (!uniformOpacityLocation || !uniformTextureLocation) {
|
|
24996
|
+
if (!uniformOpacityLocation || !uniformTextureLocation || !uniformScreenToClipScaleLocation || !uniformScreenToClipOffsetLocation) {
|
|
23937
24997
|
return;
|
|
23938
24998
|
}
|
|
23939
24999
|
const timestamp = typeof performance !== "undefined" && typeof performance.now === "function" ? (
|
|
@@ -23985,6 +25045,17 @@ const createSpriteLayer = (options) => {
|
|
|
23985
25045
|
const drawingBufferWidth = glContext.drawingBufferWidth;
|
|
23986
25046
|
const drawingBufferHeight = glContext.drawingBufferHeight;
|
|
23987
25047
|
const pixelRatio = drawingBufferWidth / cssWidth;
|
|
25048
|
+
if (drawingBufferWidth === 0 || drawingBufferHeight === 0) {
|
|
25049
|
+
return;
|
|
25050
|
+
}
|
|
25051
|
+
const screenToClipScaleX = 2 * pixelRatio / drawingBufferWidth;
|
|
25052
|
+
const screenToClipScaleY = -2 * pixelRatio / drawingBufferHeight;
|
|
25053
|
+
const screenToClipOffsetX = -1;
|
|
25054
|
+
const screenToClipOffsetY = 1;
|
|
25055
|
+
const identityScaleX = 1;
|
|
25056
|
+
const identityScaleY = 1;
|
|
25057
|
+
const identityOffsetX = 0;
|
|
25058
|
+
const identityOffsetY = 0;
|
|
23988
25059
|
const zoom = mapInstance.getZoom();
|
|
23989
25060
|
const zoomScaleFactor = calculateZoomScaleFactor(zoom, resolvedScaling);
|
|
23990
25061
|
const baseMetersPerPixel = resolvedScaling.metersPerPixel;
|
|
@@ -24019,11 +25090,76 @@ const createSpriteLayer = (options) => {
|
|
|
24019
25090
|
UV_OFFSET
|
|
24020
25091
|
);
|
|
24021
25092
|
glContext.uniform1i(uniformTextureLocation, 0);
|
|
25093
|
+
const screenToClipScaleLocation = uniformScreenToClipScaleLocation;
|
|
25094
|
+
const screenToClipOffsetLocation = uniformScreenToClipOffsetLocation;
|
|
25095
|
+
let currentScaleX = Number.NaN;
|
|
25096
|
+
let currentScaleY = Number.NaN;
|
|
25097
|
+
let currentOffsetX = Number.NaN;
|
|
25098
|
+
let currentOffsetY = Number.NaN;
|
|
25099
|
+
const applyScreenToClipUniforms = (scaleX, scaleY, offsetX, offsetY) => {
|
|
25100
|
+
if (scaleX !== currentScaleX || scaleY !== currentScaleY || offsetX !== currentOffsetX || offsetY !== currentOffsetY) {
|
|
25101
|
+
glContext.uniform2f(screenToClipScaleLocation, scaleX, scaleY);
|
|
25102
|
+
glContext.uniform2f(screenToClipOffsetLocation, offsetX, offsetY);
|
|
25103
|
+
currentScaleX = scaleX;
|
|
25104
|
+
currentScaleY = scaleY;
|
|
25105
|
+
currentOffsetX = offsetX;
|
|
25106
|
+
currentOffsetY = offsetY;
|
|
25107
|
+
}
|
|
25108
|
+
};
|
|
25109
|
+
let currentSurfaceMode = Number.NaN;
|
|
25110
|
+
const applySurfaceMode = (enabled) => {
|
|
25111
|
+
if (!uniformSurfaceModeLocation) {
|
|
25112
|
+
return;
|
|
25113
|
+
}
|
|
25114
|
+
const value = enabled ? 1 : 0;
|
|
25115
|
+
if (value !== currentSurfaceMode) {
|
|
25116
|
+
glContext.uniform1f(uniformSurfaceModeLocation, value);
|
|
25117
|
+
currentSurfaceMode = value;
|
|
25118
|
+
}
|
|
25119
|
+
};
|
|
25120
|
+
let currentSurfaceClipEnabled = Number.NaN;
|
|
25121
|
+
const applySurfaceClipUniforms = (enabled, inputs) => {
|
|
25122
|
+
if (!uniformSurfaceClipEnabledLocation || !uniformSurfaceClipCenterLocation || !uniformSurfaceClipBasisEastLocation || !uniformSurfaceClipBasisNorthLocation) {
|
|
25123
|
+
return;
|
|
25124
|
+
}
|
|
25125
|
+
const value = enabled ? 1 : 0;
|
|
25126
|
+
if (value !== currentSurfaceClipEnabled) {
|
|
25127
|
+
glContext.uniform1f(uniformSurfaceClipEnabledLocation, value);
|
|
25128
|
+
currentSurfaceClipEnabled = value;
|
|
25129
|
+
}
|
|
25130
|
+
const clipCenter = enabled && inputs ? inputs.clipCenter : { x: 0, y: 0, z: 0, w: 1 };
|
|
25131
|
+
glContext.uniform4f(
|
|
25132
|
+
uniformSurfaceClipCenterLocation,
|
|
25133
|
+
clipCenter.x,
|
|
25134
|
+
clipCenter.y,
|
|
25135
|
+
clipCenter.z,
|
|
25136
|
+
clipCenter.w
|
|
25137
|
+
);
|
|
25138
|
+
const clipBasisEast = enabled && inputs ? inputs.clipBasisEast : { x: 0, y: 0, z: 0, w: 0 };
|
|
25139
|
+
glContext.uniform4f(
|
|
25140
|
+
uniformSurfaceClipBasisEastLocation,
|
|
25141
|
+
clipBasisEast.x,
|
|
25142
|
+
clipBasisEast.y,
|
|
25143
|
+
clipBasisEast.z,
|
|
25144
|
+
clipBasisEast.w
|
|
25145
|
+
);
|
|
25146
|
+
const clipBasisNorth = enabled && inputs ? inputs.clipBasisNorth : { x: 0, y: 0, z: 0, w: 0 };
|
|
25147
|
+
glContext.uniform4f(
|
|
25148
|
+
uniformSurfaceClipBasisNorthLocation,
|
|
25149
|
+
clipBasisNorth.x,
|
|
25150
|
+
clipBasisNorth.y,
|
|
25151
|
+
clipBasisNorth.z,
|
|
25152
|
+
clipBasisNorth.w
|
|
25153
|
+
);
|
|
25154
|
+
};
|
|
25155
|
+
let drawOrderCounter = 0;
|
|
24022
25156
|
const drawSpriteImage = (spriteEntry, imageEntry, imageResource, originCenterCache2) => {
|
|
24023
|
-
var _a2, _b, _c, _d, _e, _f, _g, _h, _i, _j;
|
|
25157
|
+
var _a2, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n;
|
|
24024
25158
|
let screenCornerBuffer = null;
|
|
24025
25159
|
const anchor = (_a2 = imageEntry.anchor) != null ? _a2 : DEFAULT_ANCHOR;
|
|
24026
25160
|
const offsetDef = (_b = imageEntry.offset) != null ? _b : DEFAULT_IMAGE_OFFSET;
|
|
25161
|
+
applySurfaceMode(false);
|
|
25162
|
+
applySurfaceClipUniforms(false, null);
|
|
24027
25163
|
const totalRotateDeg = Number.isFinite(imageEntry.displayedRotateDeg) ? imageEntry.displayedRotateDeg : normalizeAngleDeg(
|
|
24028
25164
|
((_c = imageEntry.resolvedBaseRotateDeg) != null ? _c : 0) + ((_d = imageEntry.rotateDeg) != null ? _d : 0)
|
|
24029
25165
|
);
|
|
@@ -24031,6 +25167,7 @@ const createSpriteLayer = (options) => {
|
|
|
24031
25167
|
if (!projected) {
|
|
24032
25168
|
return;
|
|
24033
25169
|
}
|
|
25170
|
+
const spriteMercator = resolveSpriteMercator(spriteEntry);
|
|
24034
25171
|
const metersPerPixelAtLat = calculateMetersPerPixelAtLatitude(
|
|
24035
25172
|
zoom,
|
|
24036
25173
|
spriteEntry.currentLocation.lat
|
|
@@ -24040,7 +25177,8 @@ const createSpriteLayer = (options) => {
|
|
|
24040
25177
|
}
|
|
24041
25178
|
const perspectiveRatio = calculatePerspectiveRatio(
|
|
24042
25179
|
mapInstance,
|
|
24043
|
-
spriteEntry.currentLocation
|
|
25180
|
+
spriteEntry.currentLocation,
|
|
25181
|
+
spriteMercator
|
|
24044
25182
|
);
|
|
24045
25183
|
const effectivePixelsPerMeter = calculateEffectivePixelsPerMeter(
|
|
24046
25184
|
metersPerPixelAtLat,
|
|
@@ -24050,6 +25188,7 @@ const createSpriteLayer = (options) => {
|
|
|
24050
25188
|
return;
|
|
24051
25189
|
}
|
|
24052
25190
|
const imageScale = (_e = imageEntry.scale) != null ? _e : 1;
|
|
25191
|
+
const altitudeMeters = (_f = spriteEntry.currentLocation.z) != null ? _f : 0;
|
|
24053
25192
|
const centerParams = {
|
|
24054
25193
|
mapInstance,
|
|
24055
25194
|
images,
|
|
@@ -24064,7 +25203,7 @@ const createSpriteLayer = (options) => {
|
|
|
24064
25203
|
drawingBufferHeight,
|
|
24065
25204
|
pixelRatio,
|
|
24066
25205
|
clipContext,
|
|
24067
|
-
altitudeMeters
|
|
25206
|
+
altitudeMeters
|
|
24068
25207
|
};
|
|
24069
25208
|
let baseProjected = { x: projected.x, y: projected.y };
|
|
24070
25209
|
if (imageEntry.originLocation !== void 0) {
|
|
@@ -24081,6 +25220,13 @@ const createSpriteLayer = (options) => {
|
|
|
24081
25220
|
}
|
|
24082
25221
|
}
|
|
24083
25222
|
if (imageEntry.mode === "surface") {
|
|
25223
|
+
applyScreenToClipUniforms(
|
|
25224
|
+
identityScaleX,
|
|
25225
|
+
identityScaleY,
|
|
25226
|
+
identityOffsetX,
|
|
25227
|
+
identityOffsetY
|
|
25228
|
+
);
|
|
25229
|
+
imageEntry.surfaceShaderInputs = void 0;
|
|
24084
25230
|
const baseLngLat = imageEntry.originLocation !== void 0 ? (
|
|
24085
25231
|
// When an origin reference is set, reproject the cached screen point back to geographic space.
|
|
24086
25232
|
mapInstance.unproject([
|
|
@@ -24108,7 +25254,7 @@ const createSpriteLayer = (options) => {
|
|
|
24108
25254
|
drawingBufferWidth,
|
|
24109
25255
|
drawingBufferHeight,
|
|
24110
25256
|
pixelRatio,
|
|
24111
|
-
altitudeMeters
|
|
25257
|
+
altitudeMeters,
|
|
24112
25258
|
project: !clipContext ? (lngLat) => {
|
|
24113
25259
|
const result = mapInstance.project(lngLat);
|
|
24114
25260
|
return result ? { x: result.x, y: result.y } : null;
|
|
@@ -24117,6 +25263,9 @@ const createSpriteLayer = (options) => {
|
|
|
24117
25263
|
if (!surfaceCenter.center) {
|
|
24118
25264
|
return;
|
|
24119
25265
|
}
|
|
25266
|
+
if (uniformBillboardModeLocation) {
|
|
25267
|
+
glContext.uniform1f(uniformBillboardModeLocation, 0);
|
|
25268
|
+
}
|
|
24120
25269
|
const offsetMeters = calculateSurfaceOffsetMeters(
|
|
24121
25270
|
offsetDef,
|
|
24122
25271
|
imageScale,
|
|
@@ -24130,6 +25279,51 @@ const createSpriteLayer = (options) => {
|
|
|
24130
25279
|
totalRotateDeg,
|
|
24131
25280
|
offsetMeters
|
|
24132
25281
|
});
|
|
25282
|
+
const orderIndex = Math.min(imageEntry.order, ORDER_MAX - 1);
|
|
25283
|
+
const depthBiasNdc = -((imageEntry.subLayer * ORDER_BUCKET + orderIndex) * EPS_NDC);
|
|
25284
|
+
const displacedCenterLngLat = (_i = surfaceCenter.displacedLngLat) != null ? _i : baseLngLat;
|
|
25285
|
+
const displacedCenter = {
|
|
25286
|
+
lng: displacedCenterLngLat.lng,
|
|
25287
|
+
lat: displacedCenterLngLat.lat,
|
|
25288
|
+
z: altitudeMeters
|
|
25289
|
+
};
|
|
25290
|
+
const surfaceShaderInputs = prepareSurfaceShaderInputs({
|
|
25291
|
+
baseLngLat,
|
|
25292
|
+
worldWidthMeters: surfaceCenter.worldDimensions.width,
|
|
25293
|
+
worldHeightMeters: surfaceCenter.worldDimensions.height,
|
|
25294
|
+
anchor,
|
|
25295
|
+
totalRotateDeg,
|
|
25296
|
+
offsetMeters,
|
|
25297
|
+
displacedCenter,
|
|
25298
|
+
altitudeMeters,
|
|
25299
|
+
depthBiasNdc,
|
|
25300
|
+
scaleAdjustment: surfaceCenter.worldDimensions.scaleAdjustment,
|
|
25301
|
+
centerDisplacement: surfaceCenter.totalDisplacement
|
|
25302
|
+
});
|
|
25303
|
+
imageEntry.surfaceShaderInputs = surfaceShaderInputs;
|
|
25304
|
+
let useShaderSurface = !!clipContext;
|
|
25305
|
+
let clipCornerPositions = null;
|
|
25306
|
+
let clipCenterPosition = null;
|
|
25307
|
+
if (useShaderSurface) {
|
|
25308
|
+
clipCornerPositions = new Array(SURFACE_BASE_CORNERS.length);
|
|
25309
|
+
clipCenterPosition = projectLngLatToClipSpace(
|
|
25310
|
+
displacedCenter.lng,
|
|
25311
|
+
displacedCenter.lat,
|
|
25312
|
+
(_j = displacedCenter.z) != null ? _j : altitudeMeters,
|
|
25313
|
+
clipContext
|
|
25314
|
+
);
|
|
25315
|
+
if (!clipCenterPosition) {
|
|
25316
|
+
useShaderSurface = false;
|
|
25317
|
+
clipCornerPositions = null;
|
|
25318
|
+
}
|
|
25319
|
+
}
|
|
25320
|
+
applySurfaceMode(useShaderSurface);
|
|
25321
|
+
if (useShaderSurface && uniformSurfaceDepthBiasLocation) {
|
|
25322
|
+
glContext.uniform1f(
|
|
25323
|
+
uniformSurfaceDepthBiasLocation,
|
|
25324
|
+
surfaceShaderInputs.depthBiasNdc
|
|
25325
|
+
);
|
|
25326
|
+
}
|
|
24133
25327
|
const hitTestCorners = ensureHitTestCorners(imageEntry);
|
|
24134
25328
|
let bufferOffset = 0;
|
|
24135
25329
|
for (const index of TRIANGLE_INDICES) {
|
|
@@ -24143,46 +25337,145 @@ const createSpriteLayer = (options) => {
|
|
|
24143
25337
|
const clipPosition = projectLngLatToClipSpace(
|
|
24144
25338
|
displaced.lng,
|
|
24145
25339
|
displaced.lat,
|
|
24146
|
-
|
|
24147
|
-
(_j = spriteEntry.currentLocation.z) != null ? _j : 0,
|
|
25340
|
+
altitudeMeters,
|
|
24148
25341
|
clipContext
|
|
24149
25342
|
);
|
|
24150
25343
|
if (!clipPosition) {
|
|
24151
25344
|
return;
|
|
24152
25345
|
}
|
|
24153
|
-
const screenCorner = clipToScreen(
|
|
24154
|
-
clipPosition,
|
|
24155
|
-
drawingBufferWidth,
|
|
24156
|
-
drawingBufferHeight,
|
|
24157
|
-
pixelRatio
|
|
24158
|
-
);
|
|
24159
|
-
if (!screenCorner) {
|
|
24160
|
-
return;
|
|
24161
|
-
}
|
|
24162
|
-
const targetCorner = hitTestCorners[index];
|
|
24163
|
-
targetCorner.x = screenCorner.x;
|
|
24164
|
-
targetCorner.y = screenCorner.y;
|
|
24165
25346
|
let [clipX, clipY, clipZ, clipW] = clipPosition;
|
|
24166
|
-
{
|
|
24167
|
-
const
|
|
24168
|
-
|
|
24169
|
-
|
|
24170
|
-
|
|
25347
|
+
if (!useShaderSurface) {
|
|
25348
|
+
const screenCorner = clipToScreen(
|
|
25349
|
+
clipPosition,
|
|
25350
|
+
drawingBufferWidth,
|
|
25351
|
+
drawingBufferHeight,
|
|
25352
|
+
pixelRatio
|
|
25353
|
+
);
|
|
25354
|
+
if (!screenCorner) {
|
|
25355
|
+
return;
|
|
25356
|
+
}
|
|
25357
|
+
const targetCorner = hitTestCorners[index];
|
|
25358
|
+
targetCorner.x = screenCorner.x;
|
|
25359
|
+
targetCorner.y = screenCorner.y;
|
|
25360
|
+
}
|
|
25361
|
+
if (depthBiasNdc !== 0) {
|
|
25362
|
+
clipZ += depthBiasNdc * clipW;
|
|
24171
25363
|
const minClipZ = -clipW + MIN_CLIP_Z_EPSILON;
|
|
24172
25364
|
if (clipZ < minClipZ) {
|
|
24173
25365
|
clipZ = minClipZ;
|
|
24174
25366
|
}
|
|
24175
25367
|
}
|
|
25368
|
+
if (clipCornerPositions) {
|
|
25369
|
+
clipCornerPositions[index] = [clipX, clipY, clipZ, clipW];
|
|
25370
|
+
}
|
|
24176
25371
|
const [u, v] = UV_CORNERS[index];
|
|
24177
|
-
|
|
24178
|
-
|
|
24179
|
-
|
|
24180
|
-
|
|
25372
|
+
if (useShaderSurface) {
|
|
25373
|
+
const baseCorner = SURFACE_BASE_CORNERS[index];
|
|
25374
|
+
QUAD_VERTEX_SCRATCH[bufferOffset++] = baseCorner[0];
|
|
25375
|
+
QUAD_VERTEX_SCRATCH[bufferOffset++] = baseCorner[1];
|
|
25376
|
+
QUAD_VERTEX_SCRATCH[bufferOffset++] = 0;
|
|
25377
|
+
QUAD_VERTEX_SCRATCH[bufferOffset++] = 1;
|
|
25378
|
+
} else {
|
|
25379
|
+
QUAD_VERTEX_SCRATCH[bufferOffset++] = clipX;
|
|
25380
|
+
QUAD_VERTEX_SCRATCH[bufferOffset++] = clipY;
|
|
25381
|
+
QUAD_VERTEX_SCRATCH[bufferOffset++] = clipZ;
|
|
25382
|
+
QUAD_VERTEX_SCRATCH[bufferOffset++] = clipW;
|
|
25383
|
+
}
|
|
24181
25384
|
QUAD_VERTEX_SCRATCH[bufferOffset++] = u;
|
|
24182
25385
|
QUAD_VERTEX_SCRATCH[bufferOffset++] = v;
|
|
24183
25386
|
}
|
|
25387
|
+
let clipUniformEnabled = false;
|
|
25388
|
+
if (clipCornerPositions && clipCenterPosition && clipCornerPositions.every((corner) => Array.isArray(corner))) {
|
|
25389
|
+
const leftTop = clipCornerPositions[0];
|
|
25390
|
+
const rightTop = clipCornerPositions[1];
|
|
25391
|
+
const leftBottom = clipCornerPositions[2];
|
|
25392
|
+
const rightBottom = clipCornerPositions[3];
|
|
25393
|
+
if (leftTop && rightTop && leftBottom && rightBottom) {
|
|
25394
|
+
const clipBasisEast = [
|
|
25395
|
+
(rightTop[0] - leftTop[0]) * 0.5,
|
|
25396
|
+
(rightTop[1] - leftTop[1]) * 0.5,
|
|
25397
|
+
(rightTop[2] - leftTop[2]) * 0.5,
|
|
25398
|
+
(rightTop[3] - leftTop[3]) * 0.5
|
|
25399
|
+
];
|
|
25400
|
+
const clipBasisNorth = [
|
|
25401
|
+
(leftTop[0] - leftBottom[0]) * 0.5,
|
|
25402
|
+
(leftTop[1] - leftBottom[1]) * 0.5,
|
|
25403
|
+
(leftTop[2] - leftBottom[2]) * 0.5,
|
|
25404
|
+
(leftTop[3] - leftBottom[3]) * 0.5
|
|
25405
|
+
];
|
|
25406
|
+
surfaceShaderInputs.clipCenter = {
|
|
25407
|
+
x: clipCenterPosition[0],
|
|
25408
|
+
y: clipCenterPosition[1],
|
|
25409
|
+
z: clipCenterPosition[2],
|
|
25410
|
+
w: clipCenterPosition[3]
|
|
25411
|
+
};
|
|
25412
|
+
surfaceShaderInputs.clipBasisEast = {
|
|
25413
|
+
x: clipBasisEast[0],
|
|
25414
|
+
y: clipBasisEast[1],
|
|
25415
|
+
z: clipBasisEast[2],
|
|
25416
|
+
w: clipBasisEast[3]
|
|
25417
|
+
};
|
|
25418
|
+
surfaceShaderInputs.clipBasisNorth = {
|
|
25419
|
+
x: clipBasisNorth[0],
|
|
25420
|
+
y: clipBasisNorth[1],
|
|
25421
|
+
z: clipBasisNorth[2],
|
|
25422
|
+
w: clipBasisNorth[3]
|
|
25423
|
+
};
|
|
25424
|
+
const clipCornersForInputs = [];
|
|
25425
|
+
let allCornersResolved = true;
|
|
25426
|
+
for (let cornerIndex = 0; cornerIndex < SURFACE_BASE_CORNERS.length; cornerIndex++) {
|
|
25427
|
+
const clipCorner = clipCornerPositions[cornerIndex];
|
|
25428
|
+
if (!clipCorner) {
|
|
25429
|
+
allCornersResolved = false;
|
|
25430
|
+
break;
|
|
25431
|
+
}
|
|
25432
|
+
clipCornersForInputs.push({
|
|
25433
|
+
x: clipCorner[0],
|
|
25434
|
+
y: clipCorner[1],
|
|
25435
|
+
z: clipCorner[2],
|
|
25436
|
+
w: clipCorner[3]
|
|
25437
|
+
});
|
|
25438
|
+
const screenCorner = clipToScreen(
|
|
25439
|
+
clipCorner,
|
|
25440
|
+
drawingBufferWidth,
|
|
25441
|
+
drawingBufferHeight,
|
|
25442
|
+
pixelRatio
|
|
25443
|
+
);
|
|
25444
|
+
if (!screenCorner) {
|
|
25445
|
+
return;
|
|
25446
|
+
}
|
|
25447
|
+
const targetCorner = hitTestCorners[cornerIndex];
|
|
25448
|
+
targetCorner.x = screenCorner.x;
|
|
25449
|
+
targetCorner.y = screenCorner.y;
|
|
25450
|
+
}
|
|
25451
|
+
if (allCornersResolved) {
|
|
25452
|
+
surfaceShaderInputs.clipCorners = clipCornersForInputs;
|
|
25453
|
+
clipUniformEnabled = true;
|
|
25454
|
+
} else {
|
|
25455
|
+
surfaceShaderInputs.clipCorners = [];
|
|
25456
|
+
}
|
|
25457
|
+
}
|
|
25458
|
+
} else {
|
|
25459
|
+
surfaceShaderInputs.clipCorners = [];
|
|
25460
|
+
}
|
|
25461
|
+
if (useShaderSurface) {
|
|
25462
|
+
applySurfaceClipUniforms(
|
|
25463
|
+
clipUniformEnabled,
|
|
25464
|
+
clipUniformEnabled ? surfaceShaderInputs : null
|
|
25465
|
+
);
|
|
25466
|
+
} else {
|
|
25467
|
+
applySurfaceClipUniforms(false, null);
|
|
25468
|
+
}
|
|
24184
25469
|
screenCornerBuffer = hitTestCorners;
|
|
24185
25470
|
} else {
|
|
25471
|
+
applyScreenToClipUniforms(
|
|
25472
|
+
screenToClipScaleX,
|
|
25473
|
+
screenToClipScaleY,
|
|
25474
|
+
screenToClipOffsetX,
|
|
25475
|
+
screenToClipOffsetY
|
|
25476
|
+
);
|
|
25477
|
+
imageEntry.surfaceShaderInputs = void 0;
|
|
25478
|
+
applySurfaceMode(false);
|
|
24186
25479
|
const placement = calculateBillboardCenterPosition({
|
|
24187
25480
|
base: baseProjected,
|
|
24188
25481
|
imageWidth: imageResource.width,
|
|
@@ -24197,46 +25490,95 @@ const createSpriteLayer = (options) => {
|
|
|
24197
25490
|
anchor,
|
|
24198
25491
|
offset: offsetDef
|
|
24199
25492
|
});
|
|
24200
|
-
const
|
|
25493
|
+
const billboardShaderInputs = {
|
|
24201
25494
|
centerX: placement.centerX,
|
|
24202
25495
|
centerY: placement.centerY,
|
|
24203
25496
|
halfWidth: placement.halfWidth,
|
|
24204
25497
|
halfHeight: placement.halfHeight,
|
|
24205
25498
|
anchor,
|
|
24206
25499
|
totalRotateDeg
|
|
24207
|
-
}
|
|
24208
|
-
|
|
24209
|
-
|
|
24210
|
-
|
|
24211
|
-
|
|
24212
|
-
const [clipX, clipY] = screenToClip(
|
|
24213
|
-
corner.x,
|
|
24214
|
-
corner.y,
|
|
24215
|
-
drawingBufferWidth,
|
|
24216
|
-
drawingBufferHeight,
|
|
24217
|
-
pixelRatio
|
|
25500
|
+
};
|
|
25501
|
+
if (uniformBillboardModeLocation) {
|
|
25502
|
+
glContext.uniform1f(
|
|
25503
|
+
uniformBillboardModeLocation,
|
|
25504
|
+
1
|
|
24218
25505
|
);
|
|
24219
|
-
QUAD_VERTEX_SCRATCH[bufferOffset++] = clipX;
|
|
24220
|
-
QUAD_VERTEX_SCRATCH[bufferOffset++] = clipY;
|
|
24221
|
-
QUAD_VERTEX_SCRATCH[bufferOffset++] = 0;
|
|
24222
|
-
QUAD_VERTEX_SCRATCH[bufferOffset++] = 1;
|
|
24223
|
-
QUAD_VERTEX_SCRATCH[bufferOffset++] = corner.u;
|
|
24224
|
-
QUAD_VERTEX_SCRATCH[bufferOffset++] = corner.v;
|
|
24225
|
-
}
|
|
24226
|
-
for (let i = 0; i < corners.length; i++) {
|
|
24227
|
-
const source = corners[i];
|
|
24228
|
-
const target = hitTestCorners[i];
|
|
24229
|
-
target.x = source.x;
|
|
24230
|
-
target.y = source.y;
|
|
24231
25506
|
}
|
|
24232
|
-
|
|
25507
|
+
const writeBillboardCorners = (corners, useShaderGeometry) => {
|
|
25508
|
+
const hitTestCorners = ensureHitTestCorners(imageEntry);
|
|
25509
|
+
let bufferOffset = 0;
|
|
25510
|
+
for (const index of TRIANGLE_INDICES) {
|
|
25511
|
+
const corner = corners[index];
|
|
25512
|
+
{
|
|
25513
|
+
const baseCorner = BILLBOARD_BASE_CORNERS[index];
|
|
25514
|
+
QUAD_VERTEX_SCRATCH[bufferOffset++] = baseCorner[0];
|
|
25515
|
+
QUAD_VERTEX_SCRATCH[bufferOffset++] = baseCorner[1];
|
|
25516
|
+
}
|
|
25517
|
+
QUAD_VERTEX_SCRATCH[bufferOffset++] = 0;
|
|
25518
|
+
QUAD_VERTEX_SCRATCH[bufferOffset++] = 1;
|
|
25519
|
+
QUAD_VERTEX_SCRATCH[bufferOffset++] = corner.u;
|
|
25520
|
+
QUAD_VERTEX_SCRATCH[bufferOffset++] = corner.v;
|
|
25521
|
+
}
|
|
25522
|
+
for (let i = 0; i < corners.length; i++) {
|
|
25523
|
+
const source = corners[i];
|
|
25524
|
+
const target = hitTestCorners[i];
|
|
25525
|
+
target.x = source.x;
|
|
25526
|
+
target.y = source.y;
|
|
25527
|
+
}
|
|
25528
|
+
screenCornerBuffer = hitTestCorners;
|
|
25529
|
+
};
|
|
25530
|
+
let resolvedCorners;
|
|
25531
|
+
let shaderModelCorners;
|
|
25532
|
+
{
|
|
25533
|
+
if (uniformBillboardCenterLocation) {
|
|
25534
|
+
glContext.uniform2f(
|
|
25535
|
+
uniformBillboardCenterLocation,
|
|
25536
|
+
billboardShaderInputs.centerX,
|
|
25537
|
+
billboardShaderInputs.centerY
|
|
25538
|
+
);
|
|
25539
|
+
}
|
|
25540
|
+
if (uniformBillboardHalfSizeLocation) {
|
|
25541
|
+
glContext.uniform2f(
|
|
25542
|
+
uniformBillboardHalfSizeLocation,
|
|
25543
|
+
billboardShaderInputs.halfWidth,
|
|
25544
|
+
billboardShaderInputs.halfHeight
|
|
25545
|
+
);
|
|
25546
|
+
}
|
|
25547
|
+
if (uniformBillboardAnchorLocation) {
|
|
25548
|
+
glContext.uniform2f(
|
|
25549
|
+
uniformBillboardAnchorLocation,
|
|
25550
|
+
(_l = (_k = billboardShaderInputs.anchor) == null ? void 0 : _k.x) != null ? _l : 0,
|
|
25551
|
+
(_n = (_m = billboardShaderInputs.anchor) == null ? void 0 : _m.y) != null ? _n : 0
|
|
25552
|
+
);
|
|
25553
|
+
}
|
|
25554
|
+
if (uniformBillboardSinCosLocation) {
|
|
25555
|
+
const rad = -billboardShaderInputs.totalRotateDeg * DEG2RAD;
|
|
25556
|
+
glContext.uniform2f(
|
|
25557
|
+
uniformBillboardSinCosLocation,
|
|
25558
|
+
Math.sin(rad),
|
|
25559
|
+
Math.cos(rad)
|
|
25560
|
+
);
|
|
25561
|
+
}
|
|
25562
|
+
shaderModelCorners = computeBillboardCornersShaderModel({
|
|
25563
|
+
centerX: billboardShaderInputs.centerX,
|
|
25564
|
+
centerY: billboardShaderInputs.centerY,
|
|
25565
|
+
halfWidth: billboardShaderInputs.halfWidth,
|
|
25566
|
+
halfHeight: billboardShaderInputs.halfHeight,
|
|
25567
|
+
anchor: billboardShaderInputs.anchor,
|
|
25568
|
+
rotationDeg: billboardShaderInputs.totalRotateDeg
|
|
25569
|
+
});
|
|
25570
|
+
resolvedCorners = shaderModelCorners;
|
|
25571
|
+
}
|
|
25572
|
+
writeBillboardCorners(resolvedCorners);
|
|
24233
25573
|
}
|
|
24234
25574
|
if (screenCornerBuffer && screenCornerBuffer.length === 4) {
|
|
24235
25575
|
registerHitTestEntry(
|
|
24236
25576
|
spriteEntry,
|
|
24237
25577
|
imageEntry,
|
|
24238
|
-
screenCornerBuffer
|
|
25578
|
+
screenCornerBuffer,
|
|
25579
|
+
drawOrderCounter
|
|
24239
25580
|
);
|
|
25581
|
+
drawOrderCounter += 1;
|
|
24240
25582
|
}
|
|
24241
25583
|
glContext.bufferSubData(glContext.ARRAY_BUFFER, 0, QUAD_VERTEX_SCRATCH);
|
|
24242
25584
|
glContext.uniform1f(uniformOpacityLocation, imageEntry.opacity);
|
|
@@ -24266,6 +25608,7 @@ const createSpriteLayer = (options) => {
|
|
|
24266
25608
|
if (!projected) {
|
|
24267
25609
|
continue;
|
|
24268
25610
|
}
|
|
25611
|
+
const spriteMercator = resolveSpriteMercator(spriteEntry);
|
|
24269
25612
|
const metersPerPixelAtLat = calculateMetersPerPixelAtLatitude(
|
|
24270
25613
|
zoom,
|
|
24271
25614
|
spriteEntry.currentLocation.lat
|
|
@@ -24275,7 +25618,8 @@ const createSpriteLayer = (options) => {
|
|
|
24275
25618
|
}
|
|
24276
25619
|
const perspectiveRatio = calculatePerspectiveRatio(
|
|
24277
25620
|
mapInstance,
|
|
24278
|
-
spriteEntry.currentLocation
|
|
25621
|
+
spriteEntry.currentLocation,
|
|
25622
|
+
spriteMercator
|
|
24279
25623
|
);
|
|
24280
25624
|
const effectivePixelsPerMeter = calculateEffectivePixelsPerMeter(
|
|
24281
25625
|
metersPerPixelAtLat,
|
|
@@ -24438,6 +25782,64 @@ const createSpriteLayer = (options) => {
|
|
|
24438
25782
|
for (const [, bucket] of sortedSubLayerBuckets) {
|
|
24439
25783
|
renderSortedBucket(bucket);
|
|
24440
25784
|
}
|
|
25785
|
+
if (showDebugBounds && debugProgram && debugVertexBuffer && debugUniformColorLocation && debugAttribPositionLocation !== -1) {
|
|
25786
|
+
glContext.useProgram(debugProgram);
|
|
25787
|
+
glContext.bindBuffer(glContext.ARRAY_BUFFER, debugVertexBuffer);
|
|
25788
|
+
glContext.enableVertexAttribArray(debugAttribPositionLocation);
|
|
25789
|
+
glContext.vertexAttribPointer(
|
|
25790
|
+
debugAttribPositionLocation,
|
|
25791
|
+
DEBUG_OUTLINE_POSITION_COMPONENT_COUNT,
|
|
25792
|
+
glContext.FLOAT,
|
|
25793
|
+
false,
|
|
25794
|
+
DEBUG_OUTLINE_VERTEX_STRIDE,
|
|
25795
|
+
0
|
|
25796
|
+
);
|
|
25797
|
+
glContext.disable(glContext.DEPTH_TEST);
|
|
25798
|
+
glContext.depthMask(false);
|
|
25799
|
+
glContext.uniform4f(
|
|
25800
|
+
debugUniformColorLocation,
|
|
25801
|
+
DEBUG_OUTLINE_COLOR[0],
|
|
25802
|
+
DEBUG_OUTLINE_COLOR[1],
|
|
25803
|
+
DEBUG_OUTLINE_COLOR[2],
|
|
25804
|
+
DEBUG_OUTLINE_COLOR[3]
|
|
25805
|
+
);
|
|
25806
|
+
if (debugUniformScreenToClipScaleLocation && debugUniformScreenToClipOffsetLocation) {
|
|
25807
|
+
glContext.uniform2f(
|
|
25808
|
+
debugUniformScreenToClipScaleLocation,
|
|
25809
|
+
screenToClipScaleX,
|
|
25810
|
+
screenToClipScaleY
|
|
25811
|
+
);
|
|
25812
|
+
glContext.uniform2f(
|
|
25813
|
+
debugUniformScreenToClipOffsetLocation,
|
|
25814
|
+
screenToClipOffsetX,
|
|
25815
|
+
screenToClipOffsetY
|
|
25816
|
+
);
|
|
25817
|
+
}
|
|
25818
|
+
for (const entry of hitTestEntries) {
|
|
25819
|
+
let writeOffset = 0;
|
|
25820
|
+
for (const cornerIndex of DEBUG_OUTLINE_CORNER_ORDER) {
|
|
25821
|
+
const corner = entry.corners[cornerIndex];
|
|
25822
|
+
DEBUG_OUTLINE_VERTEX_SCRATCH[writeOffset++] = corner.x;
|
|
25823
|
+
DEBUG_OUTLINE_VERTEX_SCRATCH[writeOffset++] = corner.y;
|
|
25824
|
+
DEBUG_OUTLINE_VERTEX_SCRATCH[writeOffset++] = 0;
|
|
25825
|
+
DEBUG_OUTLINE_VERTEX_SCRATCH[writeOffset++] = 1;
|
|
25826
|
+
}
|
|
25827
|
+
glContext.bufferSubData(
|
|
25828
|
+
glContext.ARRAY_BUFFER,
|
|
25829
|
+
0,
|
|
25830
|
+
DEBUG_OUTLINE_VERTEX_SCRATCH
|
|
25831
|
+
);
|
|
25832
|
+
glContext.drawArrays(
|
|
25833
|
+
glContext.LINE_LOOP,
|
|
25834
|
+
0,
|
|
25835
|
+
DEBUG_OUTLINE_VERTEX_COUNT
|
|
25836
|
+
);
|
|
25837
|
+
}
|
|
25838
|
+
glContext.depthMask(true);
|
|
25839
|
+
glContext.enable(glContext.DEPTH_TEST);
|
|
25840
|
+
glContext.disableVertexAttribArray(debugAttribPositionLocation);
|
|
25841
|
+
glContext.bindBuffer(glContext.ARRAY_BUFFER, null);
|
|
25842
|
+
}
|
|
24441
25843
|
glContext.depthMask(true);
|
|
24442
25844
|
glContext.enable(glContext.DEPTH_TEST);
|
|
24443
25845
|
glContext.disable(glContext.BLEND);
|
|
@@ -24673,6 +26075,15 @@ const createSpriteLayer = (options) => {
|
|
|
24673
26075
|
if (!image) {
|
|
24674
26076
|
return false;
|
|
24675
26077
|
}
|
|
26078
|
+
sprites.forEach((sprite) => {
|
|
26079
|
+
sprite.images.forEach((orderMap) => {
|
|
26080
|
+
orderMap.forEach((imageState) => {
|
|
26081
|
+
if (imageState.imageId === imageId) {
|
|
26082
|
+
removeImageBoundsFromHitTestTree(imageState);
|
|
26083
|
+
}
|
|
26084
|
+
});
|
|
26085
|
+
});
|
|
26086
|
+
});
|
|
24676
26087
|
const glContext = gl;
|
|
24677
26088
|
if (glContext && image.texture) {
|
|
24678
26089
|
glContext.deleteTexture(image.texture);
|
|
@@ -24695,13 +26106,16 @@ const createSpriteLayer = (options) => {
|
|
|
24695
26106
|
}
|
|
24696
26107
|
});
|
|
24697
26108
|
images.clear();
|
|
26109
|
+
hitTestTree.clear();
|
|
26110
|
+
hitTestTreeItems = /* @__PURE__ */ new WeakMap();
|
|
26111
|
+
hitTestEntryByImage = /* @__PURE__ */ new WeakMap();
|
|
24698
26112
|
clearTextureQueue();
|
|
24699
26113
|
ensureRenderTargetEntries();
|
|
24700
26114
|
scheduleRender();
|
|
24701
26115
|
};
|
|
24702
26116
|
const getAllImageIds = () => Array.from(images.keys());
|
|
24703
26117
|
const addSpriteInternal = (spriteId, init) => {
|
|
24704
|
-
var _a2, _b, _c, _d;
|
|
26118
|
+
var _a2, _b, _c, _d, _e;
|
|
24705
26119
|
if (sprites.get(spriteId)) {
|
|
24706
26120
|
return false;
|
|
24707
26121
|
}
|
|
@@ -24762,23 +26176,33 @@ const createSpriteLayer = (options) => {
|
|
|
24762
26176
|
}
|
|
24763
26177
|
}
|
|
24764
26178
|
const currentLocation = cloneSpriteLocation(init.location);
|
|
26179
|
+
const initialAltitude = (_c = currentLocation.z) != null ? _c : 0;
|
|
26180
|
+
const initialMercator = maplibreGlExports.MercatorCoordinate.fromLngLat(
|
|
26181
|
+
{ lng: currentLocation.lng, lat: currentLocation.lat },
|
|
26182
|
+
initialAltitude
|
|
26183
|
+
);
|
|
24765
26184
|
const spriteState = {
|
|
24766
26185
|
spriteId,
|
|
24767
26186
|
// Sprites default to enabled unless explicitly disabled in the init payload.
|
|
24768
|
-
isEnabled: (
|
|
26187
|
+
isEnabled: (_d = init.isEnabled) != null ? _d : true,
|
|
24769
26188
|
currentLocation,
|
|
24770
26189
|
fromLocation: void 0,
|
|
24771
26190
|
toLocation: void 0,
|
|
24772
26191
|
images: images2,
|
|
24773
26192
|
// Tags default to null to simplify downstream comparisons.
|
|
24774
|
-
tag: (
|
|
26193
|
+
tag: (_e = init.tag) != null ? _e : null,
|
|
24775
26194
|
interpolationState: null,
|
|
24776
26195
|
pendingInterpolationOptions: null,
|
|
24777
26196
|
lastCommandLocation: cloneSpriteLocation(currentLocation),
|
|
24778
26197
|
lastAutoRotationLocation: cloneSpriteLocation(currentLocation),
|
|
24779
|
-
lastAutoRotationAngleDeg: 0
|
|
26198
|
+
lastAutoRotationAngleDeg: 0,
|
|
26199
|
+
cachedMercator: initialMercator,
|
|
26200
|
+
cachedMercatorLng: currentLocation.lng,
|
|
26201
|
+
cachedMercatorLat: currentLocation.lat,
|
|
26202
|
+
cachedMercatorZ: initialAltitude
|
|
24780
26203
|
};
|
|
24781
26204
|
sprites.set(spriteId, spriteState);
|
|
26205
|
+
refreshSpriteHitTestBounds(spriteState);
|
|
24782
26206
|
return true;
|
|
24783
26207
|
};
|
|
24784
26208
|
const resolveSpriteInitCollection = (collection) => {
|
|
@@ -24813,7 +26237,19 @@ const createSpriteLayer = (options) => {
|
|
|
24813
26237
|
}
|
|
24814
26238
|
return addedCount;
|
|
24815
26239
|
};
|
|
24816
|
-
const removeSpriteInternal = (spriteId) =>
|
|
26240
|
+
const removeSpriteInternal = (spriteId) => {
|
|
26241
|
+
const sprite = sprites.get(spriteId);
|
|
26242
|
+
if (!sprite) {
|
|
26243
|
+
return false;
|
|
26244
|
+
}
|
|
26245
|
+
sprite.images.forEach((orderMap) => {
|
|
26246
|
+
orderMap.forEach((image) => {
|
|
26247
|
+
removeImageBoundsFromHitTestTree(image);
|
|
26248
|
+
});
|
|
26249
|
+
});
|
|
26250
|
+
sprites.delete(spriteId);
|
|
26251
|
+
return true;
|
|
26252
|
+
};
|
|
24817
26253
|
const removeSprite = (spriteId) => {
|
|
24818
26254
|
const removed = removeSpriteInternal(spriteId);
|
|
24819
26255
|
if (!removed) {
|
|
@@ -24841,6 +26277,9 @@ const createSpriteLayer = (options) => {
|
|
|
24841
26277
|
if (removedCount === 0) {
|
|
24842
26278
|
return 0;
|
|
24843
26279
|
}
|
|
26280
|
+
hitTestTree.clear();
|
|
26281
|
+
hitTestTreeItems = /* @__PURE__ */ new WeakMap();
|
|
26282
|
+
hitTestEntryByImage = /* @__PURE__ */ new WeakMap();
|
|
24844
26283
|
sprites.clear();
|
|
24845
26284
|
ensureRenderTargetEntries();
|
|
24846
26285
|
scheduleRender();
|
|
@@ -24857,6 +26296,9 @@ const createSpriteLayer = (options) => {
|
|
|
24857
26296
|
let removedCount = 0;
|
|
24858
26297
|
sprite.images.forEach((orderMap) => {
|
|
24859
26298
|
removedCount += orderMap.size;
|
|
26299
|
+
orderMap.forEach((image) => {
|
|
26300
|
+
removeImageBoundsFromHitTestTree(image);
|
|
26301
|
+
});
|
|
24860
26302
|
});
|
|
24861
26303
|
sprite.images.clear();
|
|
24862
26304
|
ensureRenderTargetEntries();
|
|
@@ -24907,6 +26349,7 @@ const createSpriteLayer = (options) => {
|
|
|
24907
26349
|
}
|
|
24908
26350
|
syncImageRotationChannel(state);
|
|
24909
26351
|
setImageState(sprite, state);
|
|
26352
|
+
registerImageBoundsInHitTestTree(sprite, state);
|
|
24910
26353
|
resultOut.isUpdated = true;
|
|
24911
26354
|
return true;
|
|
24912
26355
|
};
|
|
@@ -25019,6 +26462,7 @@ const createSpriteLayer = (options) => {
|
|
|
25019
26462
|
hasRotationOverride ? rotationOverride != null ? rotationOverride : null : void 0
|
|
25020
26463
|
);
|
|
25021
26464
|
}
|
|
26465
|
+
registerImageBoundsInHitTestTree(sprite, state);
|
|
25022
26466
|
resultOut.isUpdated = true;
|
|
25023
26467
|
return true;
|
|
25024
26468
|
};
|
|
@@ -25037,6 +26481,10 @@ const createSpriteLayer = (options) => {
|
|
|
25037
26481
|
return true;
|
|
25038
26482
|
};
|
|
25039
26483
|
const removeSpriteImageInternal = (sprite, subLayer, order, resultOut) => {
|
|
26484
|
+
const state = getImageState(sprite, subLayer, order);
|
|
26485
|
+
if (state) {
|
|
26486
|
+
removeImageBoundsFromHitTestTree(state);
|
|
26487
|
+
}
|
|
25040
26488
|
const deleted = deleteImageState(sprite, subLayer, order);
|
|
25041
26489
|
if (deleted) {
|
|
25042
26490
|
resultOut.isUpdated = true;
|
|
@@ -25066,11 +26514,13 @@ const createSpriteLayer = (options) => {
|
|
|
25066
26514
|
}
|
|
25067
26515
|
let updated = false;
|
|
25068
26516
|
let isRequiredRender = false;
|
|
26517
|
+
let needsHitTestRefresh = false;
|
|
25069
26518
|
if (update.isEnabled !== void 0) {
|
|
25070
26519
|
if (sprite.isEnabled !== update.isEnabled) {
|
|
25071
26520
|
sprite.isEnabled = update.isEnabled;
|
|
25072
26521
|
updated = true;
|
|
25073
26522
|
isRequiredRender = true;
|
|
26523
|
+
needsHitTestRefresh = true;
|
|
25074
26524
|
}
|
|
25075
26525
|
}
|
|
25076
26526
|
let interpolationOptionsForLocation = void 0;
|
|
@@ -25147,6 +26597,7 @@ const createSpriteLayer = (options) => {
|
|
|
25147
26597
|
}
|
|
25148
26598
|
sprite.pendingInterpolationOptions = null;
|
|
25149
26599
|
applyAutoRotation(sprite, newCommandLocation);
|
|
26600
|
+
needsHitTestRefresh = true;
|
|
25150
26601
|
}
|
|
25151
26602
|
if (update.tag !== void 0) {
|
|
25152
26603
|
const nextTag = (_a2 = update.tag) != null ? _a2 : null;
|
|
@@ -25155,6 +26606,9 @@ const createSpriteLayer = (options) => {
|
|
|
25155
26606
|
updated = true;
|
|
25156
26607
|
}
|
|
25157
26608
|
}
|
|
26609
|
+
if (needsHitTestRefresh) {
|
|
26610
|
+
refreshSpriteHitTestBounds(sprite);
|
|
26611
|
+
}
|
|
25158
26612
|
if (isRequiredRender) {
|
|
25159
26613
|
return "isRequiredRender";
|
|
25160
26614
|
}
|
|
@@ -25389,6 +26843,21 @@ const createSpriteLayer = (options) => {
|
|
|
25389
26843
|
updateSprite,
|
|
25390
26844
|
mutateSprites,
|
|
25391
26845
|
updateForEach,
|
|
26846
|
+
setHitTestEnabled: (enabled) => {
|
|
26847
|
+
if (isHitTestEnabled === enabled) {
|
|
26848
|
+
return;
|
|
26849
|
+
}
|
|
26850
|
+
isHitTestEnabled = enabled;
|
|
26851
|
+
hitTestTree.clear();
|
|
26852
|
+
hitTestTreeItems = /* @__PURE__ */ new WeakMap();
|
|
26853
|
+
hitTestEntryByImage = /* @__PURE__ */ new WeakMap();
|
|
26854
|
+
if (!enabled) {
|
|
26855
|
+
return;
|
|
26856
|
+
}
|
|
26857
|
+
sprites.forEach((sprite) => {
|
|
26858
|
+
refreshSpriteHitTestBounds(sprite);
|
|
26859
|
+
});
|
|
26860
|
+
},
|
|
25392
26861
|
on: addEventListener2,
|
|
25393
26862
|
off: removeEventListener2
|
|
25394
26863
|
};
|