leaflet-city-mapper 0.0.5 → 0.0.7
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/README.md +10 -5
- package/dist/leaflet-city-mapper-src.js +6874 -6304
- package/dist/leaflet-city-mapper-src.js.map +4 -4
- package/dist/leaflet-city-mapper-worker-src.js +2766 -0
- package/dist/leaflet-city-mapper-worker-src.js.map +4 -4
- package/dist/leaflet-city-mapper-worker.js +1 -1
- package/dist/leaflet-city-mapper-worker.js.map +4 -4
- package/dist/leaflet-city-mapper.js +5 -3
- package/dist/leaflet-city-mapper.js.map +4 -4
- package/libs/leaflet-lens.js +15 -3
- package/libs/leaflet.js +1 -1
- package/package.json +1 -1
- package/src/camera/setBearing.js +5 -0
- package/src/camera/setPitch.js +5 -0
- package/src/cog/initCog.js +2 -2
- package/src/collision/collectIntersections.js +16 -0
- package/src/collision/collider.js +3 -2
- package/src/collision/countCrossings.js +15 -0
- package/src/collision/insideMesh.js +4 -24
- package/src/collision/insideWalker.js +2 -2
- package/src/collision/readTriangle.js +7 -4
- package/src/collision/setTrafficNormal.js +9 -0
- package/src/collision/trafficCollision.js +4 -9
- package/src/collision/vertexCount.js +3 -0
- package/src/controls/cameraControls.js +6 -0
- package/src/core/gridlayerGetTiledPixelBounds.js +37 -4
- package/src/core/markerSetPos.js +1 -1
- package/src/core/popupGetEvents.js +1 -1
- package/src/core/popupUpdatePosition.js +8 -8
- package/src/core/tooltipGetEvents.js +1 -1
- package/src/core/tooltipSetPosition.js +2 -2
- package/src/geometry/appendNativeTriangle.js +2 -2
- package/src/geometry/createModelGeometry.js +2 -9
- package/src/geometry/dashedSegment.js +10 -5
- package/src/geometry/disk.js +1 -1
- package/src/geometry/fillNativePolygon.js +20 -0
- package/src/geometry/lineJoin.js +2 -2
- package/src/geometry/markerQuadCorners.js +6 -0
- package/src/geometry/nativeGeometry.js +1 -1
- package/src/geometry/polygon.js +4 -10
- package/src/geometry/segment.js +4 -3
- package/src/globals/colorTexture.js +6 -0
- package/src/globals/depthTexture.js +1 -0
- package/src/globals/drawMeshEntry.js +1 -1
- package/src/globals/meshPipeline.js +1 -0
- package/src/globals/mvtTextDecoder.js +1 -0
- package/src/globals/nativeScalableStyleKeys.js +1 -0
- package/src/globals/scenePass.js +1 -0
- package/src/globals/vectorStyleNamedColors.js +8 -0
- package/src/globals/vectorTileEvents.js +1 -0
- package/src/globals/workerCogSource.js +1 -0
- package/src/gpu/mountRenderer.js +4 -11
- package/src/gpu/releaseRenderer.js +1 -0
- package/src/index.js +6 -12
- package/src/materials/createProgramUniforms.js +1 -0
- package/src/models/loadModel.js +6 -10
- package/src/models/loadModelResources.js +2 -8
- package/src/models/modelNode.js +3 -7
- package/src/models/prepareModel.js +19 -0
- package/src/models/prepareModelGeometry.js +25 -0
- package/src/models/prepareModelPrimitive.js +17 -0
- package/src/mvt/addMvtCrossings.js +17 -0
- package/src/mvt/appendMvtBandTriangles.js +31 -0
- package/src/mvt/appendMvtCoordinates.js +11 -0
- package/src/mvt/appendMvtPolygonTriangles.js +19 -0
- package/src/mvt/beginMvtPath.js +9 -0
- package/src/mvt/closeMvtPath.js +7 -0
- package/src/mvt/collectMvtEdges.js +19 -0
- package/src/mvt/createMvtReader.js +7 -0
- package/src/mvt/decodeVectorTile.js +32 -0
- package/src/mvt/expectMvtWire.js +3 -0
- package/src/mvt/finishMvtPath.js +5 -0
- package/src/mvt/finiteMvtCoordinate.js +7 -0
- package/src/mvt/groupMvtPolygons.js +25 -0
- package/src/mvt/isMvtFallbackError.js +6 -0
- package/src/mvt/mergeMvtActiveEdges.js +9 -0
- package/src/mvt/mvtEdgeX.js +4 -0
- package/src/mvt/mvtPathsVertices.js +8 -0
- package/src/mvt/mvtPolygonPaths.js +12 -0
- package/src/mvt/numericMvtValue.js +4 -0
- package/src/mvt/readMvtFeature.js +34 -0
- package/src/mvt/readMvtField.js +8 -0
- package/src/mvt/readMvtGeometry.js +29 -0
- package/src/mvt/readMvtInteger.js +12 -0
- package/src/mvt/readMvtKnownValue.js +21 -0
- package/src/mvt/readMvtLayer.js +31 -0
- package/src/mvt/readMvtMessage.js +10 -0
- package/src/mvt/readMvtNumber.js +9 -0
- package/src/mvt/readMvtNumbers.js +11 -0
- package/src/mvt/readMvtString.js +6 -0
- package/src/mvt/readMvtValue.js +19 -0
- package/src/mvt/skipMvtField.js +14 -0
- package/src/mvt/sortMvtActiveEdges.js +15 -0
- package/src/mvt/sortedMvtLevels.js +22 -0
- package/src/mvt/takeMvtBytes.js +8 -0
- package/src/mvt/tessellateVectorRings.js +19 -0
- package/src/mvt/triangulateVectorRings.js +19 -0
- package/src/native/beforeNativeRender.js +6 -0
- package/src/native/canScaleNativeStyle.js +17 -0
- package/src/native/createNativeMesh.js +31 -0
- package/src/native/disposeNativeLayer.js +1 -1
- package/src/native/getGridTerrainTile.js +34 -0
- package/src/native/gridTerrainElevation.js +30 -0
- package/src/native/loadGridTerrain.js +26 -0
- package/src/native/nativeLayer.js +2 -2
- package/src/native/nativeLayerMethod.js +5 -14
- package/src/native/nativeProgram.js +20 -0
- package/src/native/nativeVectorGeometry.js +23 -0
- package/src/native/orderNativeGridLayer.js +14 -0
- package/src/native/putNativeMesh.js +15 -21
- package/src/native/refreshNativeEvent.js +13 -2
- package/src/native/refreshNativeLayer.js +1 -0
- package/src/native/syncGridLayer.js +48 -3
- package/src/native/syncNativeStrokeAnchors.js +12 -0
- package/src/native/syncNativeStrokeZoom.js +29 -0
- package/src/native/syncVectorLayer.js +15 -13
- package/src/native/terrainGridMesh.js +34 -0
- package/src/native/updateNativeStrokeRadius.js +9 -0
- package/src/projections/displayContainerPoint.js +23 -3
- package/src/projections/groundBounds.js +2 -2
- package/src/projections/localPixel.js +7 -2
- package/src/projections/localPixelForGeometry.js +4 -2
- package/src/projections/projectCameraPoint.js +6 -5
- package/src/raster/setRasterOpacity.js +1 -1
- package/src/raster/setRasterZIndex.js +1 -1
- package/src/rendering/collectVisibleMesh.js +5 -2
- package/src/rendering/drawSceneMeshes.js +3 -1
- package/src/rendering/nativeStrokeExpansion.js +4 -0
- package/src/rendering/prepareMeshUniforms.js +2 -0
- package/src/rendering/resizeRenderer.js +9 -0
- package/src/scene/initializerFor.js +3 -5
- package/src/scene/layerInitialize.js +14 -12
- package/src/scene/resolveNextInitialization.js +1 -1
- package/src/shaders/materialShaders.js +1 -0
- package/src/shaders/materialVertexShader.js +7 -2
- package/src/shaders/nativeStrokeShader.js +6 -0
- package/src/sources/attachAreaMesh.js +5 -6
- package/src/sources/buildArea.js +7 -17
- package/src/sources/buildAreaFeature.js +5 -24
- package/src/sources/buildAreaFeatures.js +14 -0
- package/src/sources/initVectorTiles.js +15 -0
- package/src/sources/isVectorTileSource.js +4 -0
- package/src/sources/matchesAreaTile.js +7 -0
- package/src/sources/prepareAreaGeometryJob.js +2 -11
- package/src/sources/projectAreaPolygons.js +15 -0
- package/src/sources/readyVectorTiles.js +10 -0
- package/src/sources/sourceAreaContext.js +1 -6
- package/src/sunlight/createSun.js +0 -1
- package/src/terrain/initTerrain.js +7 -1
- package/src/terrain/loadTerrain.js +4 -1
- package/src/terrain/mapElevationOf.js +5 -1
- package/src/terrain/onTerrainAdd.js +11 -1
- package/src/terrain/onTerrainRemove.js +10 -1
- package/src/utils/yieldTask.js +5 -0
- package/src/vector-style/appendQuotedStyleCharacter.js +22 -0
- package/src/vector-style/arrayContainsRange.js +8 -0
- package/src/vector-style/evaluateBoolean.js +18 -0
- package/src/vector-style/evaluateCoalesceOrCase.js +21 -0
- package/src/vector-style/evaluateComparison.js +16 -0
- package/src/vector-style/evaluateIExpression.js +8 -0
- package/src/vector-style/evaluateInput.js +6 -0
- package/src/vector-style/evaluateInterpolate.js +27 -0
- package/src/vector-style/evaluateMatch.js +12 -0
- package/src/vector-style/evaluateMath.js +14 -0
- package/src/vector-style/evaluateMembership.js +18 -0
- package/src/vector-style/evaluateNegation.js +13 -0
- package/src/vector-style/evaluatePrimitive.js +9 -0
- package/src/vector-style/evaluateStep.js +11 -0
- package/src/vector-style/evaluateStyle.js +33 -0
- package/src/vector-style/evaluateToExpression.js +14 -0
- package/src/vector-style/fillVectorPaint.js +17 -0
- package/src/vector-style/lineVectorPaint.js +21 -0
- package/src/vector-style/parseFunctionalColor.js +14 -0
- package/src/vector-style/parseHexColor.js +13 -0
- package/src/vector-style/parseVectorStyle.js +13 -0
- package/src/vector-style/readPaintValue.js +6 -0
- package/src/vector-style/removeTrailingCommas.js +12 -0
- package/src/vector-style/scaleDashArray.js +13 -0
- package/src/vector-style/skipStyleComment.js +9 -0
- package/src/vector-style/stripStyleComments.js +21 -0
- package/src/vector-style/styleColor.js +11 -0
- package/src/vector-style/validateVectorLayers.js +10 -0
- package/src/vector-style/vectorPaint.js +8 -0
- package/src/vector-style/visibleStyle.js +7 -0
- package/src/vector-tiles/appendVectorBatch.js +22 -0
- package/src/vector-tiles/attachVectorTileBatch.js +17 -0
- package/src/vector-tiles/attachVectorTileBatches.js +15 -0
- package/src/vector-tiles/compareVectorLabelPriority.js +3 -0
- package/src/vector-tiles/compareVectorTileDistance.js +3 -0
- package/src/vector-tiles/configureVectorTileLayer.js +28 -0
- package/src/vector-tiles/forwardVectorTileError.js +5 -0
- package/src/vector-tiles/loadVectorSprite.js +5 -0
- package/src/vector-tiles/loadVectorTile.js +36 -0
- package/src/vector-tiles/onVectorTileAdd.js +39 -0
- package/src/vector-tiles/onVectorTileMessage.js +10 -0
- package/src/vector-tiles/onVectorTileRemove.js +20 -0
- package/src/vector-tiles/onVectorTileWorkerError.js +11 -0
- package/src/vector-tiles/paintVectorTileBatch.js +12 -0
- package/src/vector-tiles/prepareVectorLabel.js +43 -0
- package/src/vector-tiles/prepareVectorStyleLayer.js +30 -0
- package/src/vector-tiles/prepareVectorTile.js +16 -0
- package/src/vector-tiles/projectVectorPaths.js +15 -0
- package/src/vector-tiles/projectVectorPoint.js +6 -0
- package/src/vector-tiles/projectVectorTriangles.js +18 -0
- package/src/vector-tiles/pruneVectorTiles.js +11 -0
- package/src/vector-tiles/pumpVectorTiles.js +18 -0
- package/src/vector-tiles/readTileJSON.js +17 -0
- package/src/vector-tiles/readVectorStyle.js +17 -0
- package/src/vector-tiles/refreshVectorTiles.js +5 -0
- package/src/vector-tiles/reserveVectorLabelCells.js +6 -0
- package/src/vector-tiles/retireVectorTileGroup.js +13 -0
- package/src/vector-tiles/revokeVectorWorkerUrl.js +9 -0
- package/src/vector-tiles/rotateVectorLabel.js +12 -0
- package/src/vector-tiles/rotateVectorLabels.js +6 -0
- package/src/vector-tiles/simplifyVectorPath.js +21 -0
- package/src/vector-tiles/updateVectorLabelMarker.js +27 -0
- package/src/vector-tiles/updateVectorTileLabels.js +28 -0
- package/src/vector-tiles/updateVectorTilePaint.js +20 -0
- package/src/vector-tiles/updateVectorTiles.js +29 -0
- package/src/vector-tiles/validateVectorTileZooms.js +6 -0
- package/src/vector-tiles/vectorFeaturePaint.js +15 -0
- package/src/vector-tiles/vectorFeaturePaths.js +16 -0
- package/src/vector-tiles/vectorFeatureZoom.js +8 -0
- package/src/vector-tiles/vectorLabelAnchors.js +24 -0
- package/src/vector-tiles/vectorLabelCandidates.js +11 -0
- package/src/vector-tiles/vectorLabelCells.js +26 -0
- package/src/vector-tiles/vectorLabelIcon.js +30 -0
- package/src/vector-tiles/vectorLabelProperty.js +3 -0
- package/src/vector-tiles/vectorSpriteIcon.js +11 -0
- package/src/vector-tiles/vectorStraightRun.js +14 -0
- package/src/vector-tiles/vectorStyleDependencies.js +15 -0
- package/src/vector-tiles/vectorStyleValue.js +5 -0
- package/src/vector-tiles/vectorStyleZoom.js +6 -0
- package/src/vector-tiles/vectorTileAwaited.js +9 -0
- package/src/vector-tiles/vectorTileOverlaps.js +4 -0
- package/src/vector-tiles/vectorTilePaint.js +10 -0
- package/src/vector-tiles/vectorTileSettings.js +17 -0
- package/src/vector-tiles/vectorTilesIdle.js +3 -0
- package/src/vector-tiles/vectorTolerance.js +4 -0
- package/src/vector-tiles/wrapVectorLabel.js +11 -0
- package/src/walk/animateWalker.js +2 -13
- package/src/walk/updateWalkerFrame.js +19 -0
- package/src/weakmaps/nativeProgramsByRenderer.js +1 -0
- package/src/weakmaps/streamTerrainByLayer.js +1 -0
- package/src/weakmaps/streamTerrainByMap.js +1 -0
- package/src/weakmaps/vectorTileOptionsByLayer.js +1 -0
- package/src/weakmaps/vectorWorkerByLayer.js +1 -0
- package/src/weakmaps/workerMapByLayer.js +1 -0
- package/src/workers/acquireGeometryWorker.js +2 -5
- package/src/workers/buildAreaInWorker.js +3 -23
- package/src/workers/cogWorker.js +21 -0
- package/src/workers/createGeometryWorker.js +20 -0
- package/src/workers/geometryWorker.js +15 -0
- package/src/workers/getCogInWorker.js +7 -0
- package/src/workers/modelWorker.js +10 -0
- package/src/workers/openCogInWorker.js +14 -0
- package/src/workers/runSourceWorker.js +32 -0
- package/src/workers/settleGeometryWorker.js +1 -1
- package/src/workers/vectorTileWorker.js +10 -0
- package/src/geometry/buildExtrudedPolygon.js +0 -10
- package/src/sources/buildAreaPoint.js +0 -7
|
@@ -1,22 +1,58 @@
|
|
|
1
1
|
import { L } from '../globals/L.js';
|
|
2
2
|
import { coreWhite } from '../globals/coreWhite.js';
|
|
3
|
+
import { streamTerrainByMap } from '../weakmaps/streamTerrainByMap.js';
|
|
3
4
|
|
|
4
5
|
import { styleNativeMesh } from './styleNativeMesh.js';
|
|
5
6
|
import { quadNativeMesh } from './quadNativeMesh.js';
|
|
6
7
|
import { boundsQuad } from '../geometry/boundsQuad.js';
|
|
8
|
+
import { loadGridTerrain } from './loadGridTerrain.js';
|
|
9
|
+
import { terrainGridMesh } from './terrainGridMesh.js';
|
|
7
10
|
|
|
8
11
|
|
|
9
12
|
export function syncGridLayer(state) {
|
|
10
13
|
const { source, textures, meshes } = state;
|
|
11
|
-
|
|
14
|
+
const stream = streamTerrainByMap.get(state.map);
|
|
15
|
+
if (state.terrainStream !== stream) {
|
|
16
|
+
state.terrainStream = stream;
|
|
17
|
+
state.terrainRequests = stream ? /* alloc */ new Map() : null;
|
|
18
|
+
}
|
|
19
|
+
let key, tile, opacity, retained, mesh, nw, se, request, pending = false;
|
|
20
|
+
if (state.terrainRequests) {
|
|
21
|
+
for (key of state.terrainRequests.keys()) {
|
|
22
|
+
if (!source._tiles[key]) state.terrainRequests.delete(key);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
12
25
|
for (key in source._tiles) {
|
|
13
26
|
if (!Object.hasOwn(source._tiles, key)) continue;
|
|
14
27
|
tile = source._tiles[key];
|
|
15
|
-
if (!tile.loaded || tile.el instanceof HTMLImageElement && !tile.el.naturalWidth)
|
|
28
|
+
if (!tile.loaded || tile.el instanceof HTMLImageElement && !tile.el.naturalWidth) {
|
|
29
|
+
if (stream) pending = true;
|
|
30
|
+
continue;
|
|
31
|
+
}
|
|
16
32
|
opacity = (source.options.opacity ?? 1) * (tile._gpuOpacity ?? 1);
|
|
17
33
|
retained = textures.get(key);
|
|
18
34
|
mesh = meshes.get(key);
|
|
19
|
-
if (
|
|
35
|
+
if (state.terrainRequests) {
|
|
36
|
+
request = state.terrainRequests.get(key);
|
|
37
|
+
if (!request || request.tile !== tile) {
|
|
38
|
+
request = /* alloc */ { tile, stream };
|
|
39
|
+
state.terrainRequests.set(key, request);
|
|
40
|
+
loadGridTerrain(state, key, tile, request);
|
|
41
|
+
}
|
|
42
|
+
if (!request.tiles) {
|
|
43
|
+
pending = true;
|
|
44
|
+
if (mesh && retained?.image === tile.el) {
|
|
45
|
+
retained.used = true;
|
|
46
|
+
styleNativeMesh(state, mesh, coreWhite, opacity);
|
|
47
|
+
}
|
|
48
|
+
continue;
|
|
49
|
+
}
|
|
50
|
+
if (mesh && mesh._terrainRequest === request && retained?.image === tile.el &&
|
|
51
|
+
retained.url === (tile.el.currentSrc || tile.el.src)) {
|
|
52
|
+
retained.used = true;
|
|
53
|
+
styleNativeMesh(state, mesh, coreWhite, opacity);
|
|
54
|
+
} else mesh = terrainGridMesh(state, key, tile, request, opacity);
|
|
55
|
+
} else if (mesh && !mesh._terrainRequest && retained?.image === tile.el && retained.url === (tile.el.currentSrc || tile.el.src)) {
|
|
20
56
|
retained.used = true;
|
|
21
57
|
styleNativeMesh(state, mesh, coreWhite, opacity);
|
|
22
58
|
} else {
|
|
@@ -26,4 +62,13 @@ export function syncGridLayer(state) {
|
|
|
26
62
|
}
|
|
27
63
|
if (mesh) mesh.renderOrder += tile.coords.z / 100;
|
|
28
64
|
}
|
|
65
|
+
if (stream && (pending || !Object.keys(source._tiles).length)) {
|
|
66
|
+
for ([key, mesh] of meshes) {
|
|
67
|
+
if (source._tiles[key] || !mesh._terrainRequest) continue;
|
|
68
|
+
retained = textures.get(key);
|
|
69
|
+
if (!retained) continue;
|
|
70
|
+
retained.used = true;
|
|
71
|
+
mesh._nativeUsed = true;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
29
74
|
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export function syncNativeStrokeAnchors(state, stroke) {
|
|
2
|
+
const { source } = state;
|
|
3
|
+
if (state.strokeAnchors?.length === stroke.length && stroke.length) {
|
|
4
|
+
if (source.options.interactive === false) state.strokeCoordinates = stroke;
|
|
5
|
+
else {
|
|
6
|
+
state.strokeCoordinates = /* alloc */ new Float64Array(stroke);
|
|
7
|
+
state.strokeAnchors = /* alloc */ new Float64Array(state.strokeAnchors);
|
|
8
|
+
}
|
|
9
|
+
state.strokeZoom = state.map.getZoom();
|
|
10
|
+
state.strokeWeight = Number(source.options.weight);
|
|
11
|
+
} else state.strokeAnchors = null;
|
|
12
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { styleNativeMesh } from './styleNativeMesh.js';
|
|
2
|
+
import { parseColor } from '../colors/parseColor.js';
|
|
3
|
+
|
|
4
|
+
export function syncNativeStrokeZoom(state) {
|
|
5
|
+
const { source, meshes, strokeCoordinates, strokeAnchors } = state;
|
|
6
|
+
const mesh = meshes.get('stroke');
|
|
7
|
+
let i, r, g, b, fill;
|
|
8
|
+
if (mesh) {
|
|
9
|
+
const factor = 2 ** (state.strokeZoom - state.map.getZoom()) *
|
|
10
|
+
Number(source.options.weight) / state.strokeWeight;
|
|
11
|
+
const attribute = mesh.geometry.attributes.position;
|
|
12
|
+
if (mesh.program.uniforms.strokeScale) {
|
|
13
|
+
mesh.program.uniforms.strokeScale.value = factor;
|
|
14
|
+
} else {
|
|
15
|
+
for (i = 0; i < strokeCoordinates.length; i++) {
|
|
16
|
+
attribute.data[i] = strokeAnchors[i] + (strokeCoordinates[i] - strokeAnchors[i]) * factor;
|
|
17
|
+
}
|
|
18
|
+
attribute.needsUpdate = true;
|
|
19
|
+
mesh.geometry.bounds = null;
|
|
20
|
+
}
|
|
21
|
+
({ r, g, b } = parseColor(source.options.color));
|
|
22
|
+
styleNativeMesh(state, mesh, /* alloc */ [r, g, b], source.options.opacity ?? 1);
|
|
23
|
+
}
|
|
24
|
+
fill = meshes.get('fill');
|
|
25
|
+
if (fill) {
|
|
26
|
+
({ r, g, b } = parseColor(source.options.fillColor || source.options.color));
|
|
27
|
+
styleNativeMesh(state, fill, /* alloc */ [r, g, b], source.options.fillOpacity ?? 1);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
@@ -1,22 +1,19 @@
|
|
|
1
|
-
import { geometryPixelStates } from '../globals/geometryPixelStates.js';
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
import { nativeGeometry } from '../geometry/nativeGeometry.js';
|
|
5
|
-
import { localPixelForGeometry } from '../projections/localPixelForGeometry.js';
|
|
6
1
|
import { parseColor } from '../colors/parseColor.js';
|
|
7
2
|
import { putNativeMesh } from './putNativeMesh.js';
|
|
3
|
+
import { syncNativeStrokeZoom } from './syncNativeStrokeZoom.js';
|
|
4
|
+
import { nativeVectorGeometry } from './nativeVectorGeometry.js';
|
|
5
|
+
import { syncNativeStrokeAnchors } from './syncNativeStrokeAnchors.js';
|
|
8
6
|
|
|
9
7
|
export function syncVectorLayer(state) {
|
|
10
8
|
const { source } = state;
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
} finally {
|
|
16
|
-
geometryPixelStates.pop();
|
|
9
|
+
if (state.zoomOnly) {
|
|
10
|
+
syncNativeStrokeZoom(state);
|
|
11
|
+
state.zoomOnly = false;
|
|
12
|
+
return;
|
|
17
13
|
}
|
|
18
|
-
const { fill, stroke } =
|
|
19
|
-
|
|
14
|
+
const { fill, stroke } = nativeVectorGeometry(state);
|
|
15
|
+
syncNativeStrokeAnchors(state, stroke);
|
|
16
|
+
let i, key, positions, color, opacity, r, g, b, attributes;
|
|
20
17
|
for (i = 0; i < 2; i++) {
|
|
21
18
|
key = i ? 'stroke' : 'fill';
|
|
22
19
|
positions = i ? stroke : fill;
|
|
@@ -25,5 +22,10 @@ export function syncVectorLayer(state) {
|
|
|
25
22
|
if (!positions.length) continue;
|
|
26
23
|
({ r, g, b } = parseColor(color));
|
|
27
24
|
putNativeMesh(state, key, positions, /* alloc */ [r, g, b], opacity ?? 1);
|
|
25
|
+
if (key === 'stroke' && source.options.interactive === false && state.strokeCoordinates) {
|
|
26
|
+
attributes = state.meshes.get(key).geometry.attributes;
|
|
27
|
+
state.strokeCoordinates = attributes.position.data;
|
|
28
|
+
state.strokeAnchors = attributes.normal.data;
|
|
29
|
+
}
|
|
28
30
|
}
|
|
29
31
|
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { rootByLayer } from '../weakmaps/rootByLayer.js';
|
|
2
|
+
import { coreWhite } from '../globals/coreWhite.js';
|
|
3
|
+
import { textureFor } from '../textures/nativeTextureFor.js';
|
|
4
|
+
import { terrainElevation } from '../terrain/terrainElevation.js';
|
|
5
|
+
import { localPosition } from '../projections/localPosition.js';
|
|
6
|
+
import { putNativeMesh } from './putNativeMesh.js';
|
|
7
|
+
|
|
8
|
+
export function terrainGridMesh(state, key, tile, request, opacity) {
|
|
9
|
+
const texture = textureFor(state, key, tile.el);
|
|
10
|
+
if (!texture) return;
|
|
11
|
+
const { x, y, z } = tile.coords, divisions = 32;
|
|
12
|
+
const northwest = localPosition(state, state.map.unproject(/* alloc */ [x * 256, y * 256], z));
|
|
13
|
+
const southeast = localPosition(state, state.map.unproject(/* alloc */ [(x + 1) * 256, (y + 1) * 256], z));
|
|
14
|
+
const vertices = /* alloc */ [], position = /* alloc */ [], uv = /* alloc */ [];
|
|
15
|
+
const base = rootByLayer.get(state.backend).position[1];
|
|
16
|
+
let row, col, u, v, elevation, a, b, c, d, index;
|
|
17
|
+
for (row = 0; row <= divisions; row++) for (col = 0; col <= divisions; col++) {
|
|
18
|
+
u = col / divisions; v = row / divisions;
|
|
19
|
+
elevation = terrainElevation(/* alloc */ { x: (x + u) * 256, y: (y + v) * 256 }, request.tiles);
|
|
20
|
+
if (!Number.isFinite(elevation)) throw /* alloc */ new Error(`Missing elevation sample in ${z}/${x}/${y}`);
|
|
21
|
+
vertices.push(/* alloc */ [northwest[0] + (southeast[0] - northwest[0]) * u, elevation - base,
|
|
22
|
+
northwest[2] + (southeast[2] - northwest[2]) * v, u, v]);
|
|
23
|
+
}
|
|
24
|
+
for (row = 0; row < divisions; row++) for (col = 0; col < divisions; col++) {
|
|
25
|
+
a = row * (divisions + 1) + col; b = a + 1; c = a + divisions + 1; d = c + 1;
|
|
26
|
+
for (index of /* alloc */ [a, c, b, b, c, d]) {
|
|
27
|
+
position.push(vertices[index][0], vertices[index][1], vertices[index][2]);
|
|
28
|
+
uv.push(vertices[index][3], vertices[index][4]);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
const mesh = putNativeMesh(state, key, position, coreWhite, opacity, texture, uv, true);
|
|
32
|
+
mesh._terrainRequest = request;
|
|
33
|
+
return mesh;
|
|
34
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export function updateNativeStrokeRadius(mesh) {
|
|
2
|
+
const attributes = mesh.geometry.attributes, positions = attributes.position.data, anchors = attributes.normal.data;
|
|
3
|
+
let i, radius = 0;
|
|
4
|
+
for (i = 0; i < positions.length; i += 3) {
|
|
5
|
+
radius = Math.max(radius, Math.hypot(positions[i] - anchors[i],
|
|
6
|
+
positions[i + 1] - anchors[i + 1], positions[i + 2] - anchors[i + 2]));
|
|
7
|
+
}
|
|
8
|
+
mesh.geometry.nativeStrokeRadius = radius;
|
|
9
|
+
}
|
|
@@ -1,3 +1,23 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
}
|
|
1
|
+
import { streamTerrainByMap } from '../weakmaps/streamTerrainByMap.js';
|
|
2
|
+
import { renderers } from '../weakmaps/renderers.js';
|
|
3
|
+
import { sceneOriginByLayer } from '../weakmaps/sceneOriginByLayer.js';
|
|
4
|
+
import { cameraViewByMap } from '../weakmaps/cameraViewByMap.js';
|
|
5
|
+
import { mapMethods } from '../globals/mapMethods.js';
|
|
6
|
+
import { radians } from '../globals/radians.js';
|
|
7
|
+
import { earthCirc } from '../globals/earthCirc.js';
|
|
8
|
+
import { mapElevationOf } from '../terrain/mapElevationOf.js';
|
|
9
|
+
import { animationPoint } from './transformZoomAnimationPoint.js';
|
|
10
|
+
import { project } from './projectCameraPoint.js';
|
|
11
|
+
|
|
12
|
+
export function displayPoint(map, point, location) {
|
|
13
|
+
const shared = renderers.get(map), origin = shared && sceneOriginByLayer.get(shared);
|
|
14
|
+
if (!streamTerrainByMap.get(map) || !origin) {
|
|
15
|
+
return map.layerPointToContainerPoint(point).subtract(map._getMapPanePos());
|
|
16
|
+
}
|
|
17
|
+
const elevation = mapElevationOf(map, location || map.layerPointToLatLng(point)) ?? 0;
|
|
18
|
+
const center = mapElevationOf(map, map.getCenter()) ?? 0;
|
|
19
|
+
const zoom = cameraViewByMap.get(map)?.zoom ?? map.getZoom();
|
|
20
|
+
const height = (elevation - center) * map.options.crs.scale(zoom) / (earthCirc * Math.cos(origin.lat * radians));
|
|
21
|
+
const raw = animationPoint(map, mapMethods.value.layerPointToContainerPoint.call(map, point));
|
|
22
|
+
return project(map, raw, false, false, height).subtract(map._getMapPanePos());
|
|
23
|
+
}
|
|
@@ -4,7 +4,7 @@ import { pointOf } from './toPoint.js';
|
|
|
4
4
|
import { project } from './projectCameraPoint.js';
|
|
5
5
|
|
|
6
6
|
|
|
7
|
-
export function groundBounds(map, padding = cameraZeroPadding) {
|
|
7
|
+
export function groundBounds(map, padding = cameraZeroPadding, height = 0) {
|
|
8
8
|
const min = pointOf(padding).divideBy(2), max = map.getSize().subtract(min);
|
|
9
9
|
const bounds = /* alloc */ new L.Bounds();
|
|
10
10
|
const minX = min.x, minY = min.y;
|
|
@@ -12,7 +12,7 @@ export function groundBounds(map, padding = cameraZeroPadding) {
|
|
|
12
12
|
for (i = 0; i < 4; i++) {
|
|
13
13
|
min.x = i % 2 ? max.x : minX;
|
|
14
14
|
min.y = i < 2 ? minY : max.y;
|
|
15
|
-
bounds.extend(project(map, min, true, true));
|
|
15
|
+
bounds.extend(project(map, min, true, true, height));
|
|
16
16
|
}
|
|
17
17
|
return bounds;
|
|
18
18
|
}
|
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
import { localPosition } from './localPosition.js';
|
|
2
2
|
|
|
3
|
-
export function localPixel(state, point) {
|
|
4
|
-
|
|
3
|
+
export function localPixel(state, point) {
|
|
4
|
+
if (state.pixelProjection) {
|
|
5
|
+
const { transformation, scale, origin, metres } = state.pixelProjection;
|
|
6
|
+
const projected = transformation.untransform(point, scale);
|
|
7
|
+
return /* alloc */ [(projected.x - origin.x) * metres, 0, -(projected.y - origin.y) * metres];
|
|
8
|
+
}
|
|
9
|
+
return localPosition(state, state.map.unproject(point));
|
|
5
10
|
}
|
|
@@ -2,6 +2,8 @@ import { geometryPixelStates } from '../globals/geometryPixelStates.js';
|
|
|
2
2
|
|
|
3
3
|
import { localPixel } from './localPixel.js';
|
|
4
4
|
|
|
5
|
-
export function localPixelForGeometry(point) {
|
|
6
|
-
|
|
5
|
+
export function localPixelForGeometry(point, anchor) {
|
|
6
|
+
const state = geometryPixelStates[geometryPixelStates.length - 1];
|
|
7
|
+
if (anchor && state.strokeAnchors) state.strokeAnchors.push(...localPixel(state, anchor));
|
|
8
|
+
return localPixel(state, point);
|
|
7
9
|
}
|
|
@@ -3,7 +3,7 @@ import { pointOf } from './toPoint.js';
|
|
|
3
3
|
import { angles } from './cameraAngles.js';
|
|
4
4
|
|
|
5
5
|
|
|
6
|
-
export function project(map, point, inverse = false, limit = false) {
|
|
6
|
+
export function project(map, point, inverse = false, limit = false, height = 0) {
|
|
7
7
|
const size = map.getSize(), halfX = size.x / 2, halfY = size.y / 2, distance = size.y * 1.5;
|
|
8
8
|
const result = pointOf(point);
|
|
9
9
|
if (!distance) return result;
|
|
@@ -12,16 +12,17 @@ export function project(map, point, inverse = false, limit = false) {
|
|
|
12
12
|
if (inverse) {
|
|
13
13
|
const far = size.y * map.options.pitchMaxDistance;
|
|
14
14
|
const denominator = tilt * distance + rise * y;
|
|
15
|
-
let v = denominator * tilt > 0
|
|
15
|
+
let v = denominator * tilt > 0
|
|
16
|
+
? (y * (distance - tilt * height) + distance * rise * height) / denominator : -far;
|
|
16
17
|
if (limit) v = Math.max(-far, Math.min(far, v));
|
|
17
|
-
const u = x * (distance - rise * v) / distance;
|
|
18
|
+
const u = x * (distance - rise * v - tilt * height) / distance;
|
|
18
19
|
result.x = cos * u + sin * v + halfX;
|
|
19
20
|
result.y = -sin * u + cos * v + halfY;
|
|
20
21
|
return result;
|
|
21
22
|
}
|
|
22
23
|
const u = cos * x - sin * y, v = sin * x + cos * y;
|
|
23
|
-
const scale = distance / (distance - rise * v);
|
|
24
|
+
const scale = distance / (distance - rise * v - tilt * height);
|
|
24
25
|
result.x = u * scale + halfX;
|
|
25
|
-
result.y = tilt * v * scale + halfY;
|
|
26
|
+
result.y = (tilt * v - rise * height) * scale + halfY;
|
|
26
27
|
return result;
|
|
27
28
|
}
|
|
@@ -9,7 +9,7 @@ export function setRasterOpacity(layer, opacity) {
|
|
|
9
9
|
let tile, terrainMesh;
|
|
10
10
|
for (tile of rasterTilesByLayer.get(layer).values()) {
|
|
11
11
|
if (tile.mesh) tile.mesh.opacity = opacity;
|
|
12
|
-
terrainMesh = rasterTilesByLayer.get(terrain3DByLayer.get(layer))
|
|
12
|
+
terrainMesh = rasterTilesByLayer.get(terrain3DByLayer.get(layer))?.get(tile);
|
|
13
13
|
if (terrainMesh) terrainMesh.opacity = opacity;
|
|
14
14
|
}
|
|
15
15
|
update(layer);
|
|
@@ -9,7 +9,7 @@ export function setRasterZIndex(layer, zIndex) {
|
|
|
9
9
|
let tile, terrainMesh;
|
|
10
10
|
for (tile of rasterTilesByLayer.get(layer).values()) {
|
|
11
11
|
if (tile.mesh) tile.mesh.renderOrder = zIndex;
|
|
12
|
-
terrainMesh = rasterTilesByLayer.get(terrain3DByLayer.get(layer))
|
|
12
|
+
terrainMesh = rasterTilesByLayer.get(terrain3DByLayer.get(layer))?.get(tile);
|
|
13
13
|
if (terrainMesh) terrainMesh.renderOrder = zIndex;
|
|
14
14
|
}
|
|
15
15
|
update(layer);
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { computeBounds } from '../geometry/computeBounds.js';
|
|
2
|
+
import { nativeStrokeExpansion } from './nativeStrokeExpansion.js';
|
|
2
3
|
|
|
3
4
|
export function collectVisibleMesh(mesh, projection, frustum, frustumLengths, candidates) {
|
|
4
5
|
if (!mesh.geometry.bounds) computeBounds(mesh.geometry);
|
|
@@ -12,16 +13,18 @@ export function collectVisibleMesh(mesh, projection, frustum, frustumLengths, ca
|
|
|
12
13
|
sphere.x = world[0] * center[0] + world[4] * center[1] + world[8] * center[2] + world[12];
|
|
13
14
|
sphere.y = world[1] * center[0] + world[5] * center[1] + world[9] * center[2] + world[13];
|
|
14
15
|
sphere.z = world[2] * center[0] + world[6] * center[1] + world[10] * center[2] + world[14];
|
|
15
|
-
sphere.
|
|
16
|
+
sphere.scale = Math.max(
|
|
16
17
|
Math.hypot(world[0], world[1], world[2]),
|
|
17
18
|
Math.hypot(world[4], world[5], world[6]),
|
|
18
19
|
Math.hypot(world[8], world[9], world[10])
|
|
19
20
|
);
|
|
21
|
+
sphere.radius = bounds.radius * sphere.scale;
|
|
20
22
|
sphere.bounds = bounds;
|
|
21
23
|
sphere.matrix = world;
|
|
22
24
|
sphere.version = mesh._worldMatrixVersion;
|
|
23
25
|
}
|
|
24
|
-
const { x, y, z
|
|
26
|
+
const { x, y, z } = sphere;
|
|
27
|
+
const radius = sphere.radius + nativeStrokeExpansion(mesh) * sphere.scale;
|
|
25
28
|
const clipZ = projection[2] * x + projection[6] * y + projection[10] * z + projection[14];
|
|
26
29
|
const clipW = projection[3] * x + projection[7] * y + projection[11] * z + projection[15];
|
|
27
30
|
mesh._sortDepth = clipZ / clipW;
|
|
@@ -9,11 +9,13 @@ import { drawGeometry } from './drawGeometry.js';
|
|
|
9
9
|
export function drawSceneMeshes(layer, encoder, meshes) {
|
|
10
10
|
const renderer = rendererByLayer.get(layer);
|
|
11
11
|
const pass = encoder.beginRenderPass((
|
|
12
|
-
scenePass.colorAttachments[0].view = renderer.
|
|
12
|
+
scenePass.colorAttachments[0].view = renderer.colorTexture.createView(),
|
|
13
|
+
scenePass.colorAttachments[0].resolveTarget = renderer.context.getCurrentTexture().createView(),
|
|
13
14
|
scenePass.depthStencilAttachment.view = renderer.depthTexture.createView(),
|
|
14
15
|
scenePass
|
|
15
16
|
));
|
|
16
17
|
scenePass.colorAttachments[0].view = null;
|
|
18
|
+
scenePass.colorAttachments[0].resolveTarget = null;
|
|
17
19
|
scenePass.depthStencilAttachment.view = null;
|
|
18
20
|
pass.setViewport(0, 0, renderer.canvas.width, renderer.canvas.height, 0, 1);
|
|
19
21
|
pass.setBindGroup(1, renderer.sunlight.bindGroup);
|
|
@@ -20,6 +20,8 @@ export function prepareMeshUniforms(renderer, mesh) {
|
|
|
20
20
|
data[base + 34] = mesh.program.nightSparkle ? data[55] : 0;
|
|
21
21
|
data[base + 35] = mesh.ground ? 1 : mesh._appearance ?? 1;
|
|
22
22
|
prepareMeshCutout(renderer, mesh, base);
|
|
23
|
+
data[base + 40] = uniforms.strokeScale?.value ?? 1;
|
|
24
|
+
data[base + 41] = data[base + 42] = data[base + 43] = 0;
|
|
23
25
|
return offset;
|
|
24
26
|
}
|
|
25
27
|
import { prepareMeshCutout } from '../materials/prepareMeshCutout.js';
|
|
@@ -2,6 +2,7 @@ import { rendererByLayer } from '../weakmaps/rendererByLayer.js';
|
|
|
2
2
|
import { sizeByLayer } from '../weakmaps/sizeByLayer.js';
|
|
3
3
|
|
|
4
4
|
import { depthTexture as sharedDepthTexture } from '../globals/depthTexture.js';
|
|
5
|
+
import { colorTexture as sharedColorTexture } from '../globals/colorTexture.js';
|
|
5
6
|
|
|
6
7
|
|
|
7
8
|
import { destroyTexture } from '../textures/destroyTexture.js';
|
|
@@ -15,6 +16,14 @@ export function resizeRenderer(layer, size) {
|
|
|
15
16
|
rendererByLayer.get(layer).canvas.style.width = `${size.x}px`;
|
|
16
17
|
rendererByLayer.get(layer).canvas.style.height = `${size.y}px`;
|
|
17
18
|
if (rendererByLayer.get(layer).depthTexture) destroyTexture(layer, rendererByLayer.get(layer).depthTexture);
|
|
19
|
+
rendererByLayer.get(layer).colorTexture?.destroy();
|
|
20
|
+
rendererByLayer.get(layer).colorTexture = rendererByLayer.get(layer).device.createTexture((
|
|
21
|
+
sharedColorTexture.size[0] = rendererByLayer.get(layer).canvas.width,
|
|
22
|
+
sharedColorTexture.size[1] = rendererByLayer.get(layer).canvas.height,
|
|
23
|
+
sharedColorTexture.format = rendererByLayer.get(layer).format,
|
|
24
|
+
sharedColorTexture.usage = GPUTextureUsage.RENDER_ATTACHMENT,
|
|
25
|
+
sharedColorTexture
|
|
26
|
+
));
|
|
18
27
|
rendererByLayer.get(layer).depthTexture = rendererByLayer.get(layer).device.createTexture((
|
|
19
28
|
sharedDepthTexture.size[0] = rendererByLayer.get(layer).canvas.width,
|
|
20
29
|
sharedDepthTexture.size[1] = rendererByLayer.get(layer).canvas.height,
|
|
@@ -1,14 +1,12 @@
|
|
|
1
|
-
import { initializeGeoJSON } from '../sources/initializeGeoJSON.js';
|
|
2
1
|
import { initRaster } from '../raster/initRaster.js';
|
|
3
2
|
import { initTerrain } from '../terrain/initTerrain.js';
|
|
4
3
|
import { initTraffic } from '../traffic/initTraffic.js';
|
|
5
4
|
import { initCog } from '../cog/initCog.js';
|
|
6
5
|
|
|
7
|
-
export function initializerFor(type) {
|
|
6
|
+
export function initializerFor(type, options = {}) {
|
|
8
7
|
switch (type) {
|
|
9
|
-
case '
|
|
10
|
-
|
|
11
|
-
case 'cog': return initCog;
|
|
8
|
+
case 'raster': return options.asset !== undefined || /\.tiff?(?:[?#]|$)/i.test(options.url)
|
|
9
|
+
? initCog : initRaster;
|
|
12
10
|
case 'terrain': return initTerrain;
|
|
13
11
|
case 'traffic': return initTraffic;
|
|
14
12
|
default: return null;
|
|
@@ -12,6 +12,9 @@ import { loading } from '../globals/loading.js';
|
|
|
12
12
|
|
|
13
13
|
|
|
14
14
|
import { init3D } from './init3D.js';
|
|
15
|
+
import { initializeGeoJSON } from '../sources/initializeGeoJSON.js';
|
|
16
|
+
import { isVectorTileSource } from '../sources/isVectorTileSource.js';
|
|
17
|
+
import { initVectorTiles } from '../sources/initVectorTiles.js';
|
|
15
18
|
import { noOperation } from '../utils/noOperation.js';
|
|
16
19
|
import { resolveNextInitialization } from './resolveNextInitialization.js';
|
|
17
20
|
import { initializeLayer } from './initializeLayer.js';
|
|
@@ -25,21 +28,20 @@ export function layerInitialize(options = sceneEmptyOptions) {
|
|
|
25
28
|
L.Util.setOptions(this, options);
|
|
26
29
|
return;
|
|
27
30
|
}
|
|
28
|
-
const {
|
|
29
|
-
|
|
30
|
-
type = options.source.data?.type === 'FeatureCollection'
|
|
31
|
-
? 'geojson'
|
|
32
|
-
: /\.pmtiles(?:[?#]|$)/i.test(options.source.url) ? 'pmtiles'
|
|
33
|
-
: /\.tiff?(?:[?#]|$)/i.test(options.source.url) ? 'cog' : '3d',
|
|
34
|
-
...source
|
|
35
|
-
},
|
|
36
|
-
...core
|
|
37
|
-
} = options;
|
|
31
|
+
const { source: { type = /\.pmtiles(?:[?#]|$)|\.tiff?(?:[?#]|$)/i.test(options.source.url)
|
|
32
|
+
? 'raster' : 'vector', ...source }, ...core } = options;
|
|
38
33
|
const settings = /* alloc */ { ...source, ...core };
|
|
39
34
|
L.Util.setOptions(this, core);
|
|
40
35
|
typeByLayer.set(this, type);
|
|
41
|
-
if (type === '
|
|
42
|
-
|
|
36
|
+
if (type === 'vector') {
|
|
37
|
+
if (isVectorTileSource(settings)) {
|
|
38
|
+
initVectorTiles(this, settings);
|
|
39
|
+
} else if (settings.data !== undefined ||
|
|
40
|
+
settings.url && !/\.(?:pmtiles|glb|gltf)(?:[?#]|$)/i.test(settings.url)) {
|
|
41
|
+
initializeGeoJSON(this, settings);
|
|
42
|
+
} else {
|
|
43
|
+
init3D(this, settings);
|
|
44
|
+
}
|
|
43
45
|
return;
|
|
44
46
|
}
|
|
45
47
|
kindByLayer.set(this, 'pending');
|
|
@@ -5,7 +5,7 @@ import { initializerFor } from './initializerFor.js';
|
|
|
5
5
|
|
|
6
6
|
export function resolveNextInitialization() {
|
|
7
7
|
const task = pendingInitializations.shift();
|
|
8
|
-
task.initialize = initializerFor(task.type);
|
|
8
|
+
task.initialize = initializerFor(task.type, task.settings);
|
|
9
9
|
if (!task.initialize) {
|
|
10
10
|
task.error = /* alloc */ new Error(`Unknown layer type: ${task.type}`);
|
|
11
11
|
}
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { roofVertexShader } from './roofVertexShader.js';
|
|
2
|
+
import { nativeStrokeShader } from './nativeStrokeShader.js';
|
|
2
3
|
|
|
3
4
|
export function materialVertexShader(material, sparkle, elevationWGSL, hasTerrain, textured, hasRoof) {
|
|
4
5
|
const instanceOffset = material.instanced ? ' + input.instanceOffset.xyz' : '';
|
|
6
|
+
const stroke = nativeStrokeShader(material);
|
|
5
7
|
return /* wgsl */ `
|
|
6
8
|
struct Mesh {
|
|
7
9
|
worldMatrix: mat4x4<f32>,
|
|
@@ -11,6 +13,7 @@ export function materialVertexShader(material, sparkle, elevationWGSL, hasTerrai
|
|
|
11
13
|
terrain: vec4<f32>,
|
|
12
14
|
highlight: vec4<f32>,
|
|
13
15
|
cutout: vec4<f32>,
|
|
16
|
+
nativeStroke: vec4<f32>,
|
|
14
17
|
};
|
|
15
18
|
struct Frame {
|
|
16
19
|
viewMatrix: mat4x4<f32>,
|
|
@@ -46,6 +49,7 @@ export function materialVertexShader(material, sparkle, elevationWGSL, hasTerrai
|
|
|
46
49
|
@vertex fn vertexMain(input: VertexInput, @builtin(vertex_index) vertexIndex: u32) -> VertexOutput {
|
|
47
50
|
var output: VertexOutput;
|
|
48
51
|
var position = input.position${instanceOffset};
|
|
52
|
+
${stroke.position}
|
|
49
53
|
${hasTerrain ? 'position.y = elevation(u.terrain.xy + input.uv * u.terrain.z, u.terrain.w) - u.terrain.w;' : ''}
|
|
50
54
|
let featureVertex = f32(vertexIndex)${material.instanced ? ' + input.instanceOffset.w' : ''};
|
|
51
55
|
let highlighted = featureVertex >= u.highlight.x && featureVertex < u.highlight.y;
|
|
@@ -54,8 +58,9 @@ export function materialVertexShader(material, sparkle, elevationWGSL, hasTerrai
|
|
|
54
58
|
: 'u.baseColor.rgb'};
|
|
55
59
|
// Inverse-transpose from cofactors; the camera view matrix is orthonormal.
|
|
56
60
|
let m = mat3x3<f32>(u.worldMatrix[0].xyz, u.worldMatrix[1].xyz, u.worldMatrix[2].xyz);
|
|
57
|
-
|
|
58
|
-
|
|
61
|
+
${stroke.normal}
|
|
62
|
+
let normal = (cross(m[1], m[2]) * sourceNormal.x + cross(m[2], m[0]) * sourceNormal.y +
|
|
63
|
+
cross(m[0], m[1]) * sourceNormal.z) / determinant(m);
|
|
59
64
|
output.normal = (frame.viewMatrix * vec4<f32>(normal, 0.0)).xyz;
|
|
60
65
|
let world = u.worldMatrix * vec4<f32>(position, 1.0);
|
|
61
66
|
output.shadowPosition = solar.matrix * world;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export function nativeStrokeShader(material) {
|
|
2
|
+
return /* alloc */ {
|
|
3
|
+
position: material.nativeStroke ? 'position = input.normal + (input.position - input.normal) * u.nativeStroke.x;' : '',
|
|
4
|
+
normal: material.nativeStroke ? 'let sourceNormal = vec3<f32>(0.0, 1.0, 0.0);' : 'let sourceNormal = input.normal;',
|
|
5
|
+
};
|
|
6
|
+
}
|
|
@@ -9,7 +9,6 @@ import { createProgram } from '../materials/createProgram.js';
|
|
|
9
9
|
|
|
10
10
|
import { setParent } from '../scene/setParent.js';
|
|
11
11
|
import { update } from '../scene/scheduleSceneUpdate.js';
|
|
12
|
-
import { instanceAreaGeometry } from '../geometry/instanceAreaGeometry.js';
|
|
13
12
|
|
|
14
13
|
export function attachAreaMesh(context) {
|
|
15
14
|
const { backend: layer, area } = context;
|
|
@@ -18,15 +17,15 @@ export function attachAreaMesh(context) {
|
|
|
18
17
|
return;
|
|
19
18
|
}
|
|
20
19
|
const device = rendererByLayer.get(layer).device;
|
|
21
|
-
const data = context.preparedGeometry
|
|
20
|
+
const data = context.preparedGeometry;
|
|
22
21
|
const attributes = /* alloc */ {
|
|
23
|
-
position: /* alloc */ { size: 3, data: data.positions
|
|
24
|
-
normal: /* alloc */ { size: 3, data: data.normals
|
|
25
|
-
color: /* alloc */ { size: 3, data: data.colors
|
|
22
|
+
position: /* alloc */ { size: 3, data: data.positions },
|
|
23
|
+
normal: /* alloc */ { size: 3, data: data.normals },
|
|
24
|
+
color: /* alloc */ { size: 3, data: data.colors },
|
|
26
25
|
};
|
|
27
26
|
if (data.instanceOffsets) attributes.instanceOffset = /* alloc */ { size: 4, data: data.instanceOffsets };
|
|
28
27
|
if (layer.options.nightLight) attributes.uv = /* alloc */ {
|
|
29
|
-
size: 2, data:
|
|
28
|
+
size: 2, data: data.uvs,
|
|
30
29
|
};
|
|
31
30
|
let name, attribute;
|
|
32
31
|
for (name in attributes) {
|
package/src/sources/buildArea.js
CHANGED
|
@@ -3,15 +3,14 @@ import { inflightByLayer } from '../weakmaps/inflightByLayer.js';
|
|
|
3
3
|
import { cameraViewByMap } from '../weakmaps/cameraViewByMap.js';
|
|
4
4
|
|
|
5
5
|
|
|
6
|
-
import { buildAreaFeature } from './buildAreaFeature.js';
|
|
7
6
|
import { attachAreaMesh } from './attachAreaMesh.js';
|
|
8
7
|
import { loadSource } from '../archives/loadSource.js';
|
|
9
8
|
import { sourceAreaContext } from './sourceAreaContext.js';
|
|
10
9
|
import { pump } from './pumpSourceAreas.js';
|
|
11
10
|
import { buildAreaInWorker } from '../workers/buildAreaInWorker.js';
|
|
11
|
+
import { buildAreaFeatures } from './buildAreaFeatures.js';
|
|
12
12
|
|
|
13
13
|
export async function buildArea(layer, area, map) {
|
|
14
|
-
let feature;
|
|
15
14
|
try {
|
|
16
15
|
await /* alloc */ new Promise(requestAnimationFrame);
|
|
17
16
|
await cameraViewByMap.get(map);
|
|
@@ -24,22 +23,13 @@ export async function buildArea(layer, area, map) {
|
|
|
24
23
|
if (geojsonByLayer.get(layer) && typeof layer.options.style !== 'function') {
|
|
25
24
|
throw /* alloc */ new Error('style must be a function');
|
|
26
25
|
}
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
if (layer.options.worker !== false && typeof Worker !== 'undefined' && data.features.length >= 64) {
|
|
30
|
-
context.jobs = /* alloc */ [];
|
|
31
|
-
}
|
|
32
|
-
let deadline = performance.now() + 4;
|
|
33
|
-
for (feature of data.features) {
|
|
34
|
-
if (area.request.signal.aborted) return;
|
|
35
|
-
if (performance.now() >= deadline) {
|
|
36
|
-
await /* alloc */ new Promise(requestAnimationFrame);
|
|
37
|
-
if (area.request.signal.aborted) return;
|
|
38
|
-
deadline = performance.now() + 4;
|
|
39
|
-
}
|
|
40
|
-
buildAreaFeature(context, feature);
|
|
26
|
+
if (layer.options.worker === false) {
|
|
27
|
+
throw /* alloc */ new Error('worker: false is no longer supported; GeoJSON geometry requires Web Workers');
|
|
41
28
|
}
|
|
42
|
-
|
|
29
|
+
const context = sourceAreaContext(layer, area, map);
|
|
30
|
+
await buildAreaFeatures(context, area, data.features);
|
|
31
|
+
if (area.request.signal.aborted) return;
|
|
32
|
+
await buildAreaInWorker(context, area.request.signal);
|
|
43
33
|
if (area.request.signal.aborted) return;
|
|
44
34
|
attachAreaMesh(context);
|
|
45
35
|
} catch (error) {
|