leaflet-city-mapper 0.0.6 → 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 +7059 -6566
- 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.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/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/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 +4 -5
- package/src/sources/buildAreaFeature.js +3 -19
- package/src/sources/initVectorTiles.js +15 -0
- package/src/sources/isVectorTileSource.js +4 -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/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/buildAreaInWorker.js +3 -27
- package/src/workers/cogWorker.js +21 -0
- package/src/workers/createGeometryWorker.js +1 -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
package/libs/leaflet.js
CHANGED
|
@@ -11,7 +11,7 @@ const openlayers = new URLSearchParams(location.search).get('engine') === 'openl
|
|
|
11
11
|
document.write((openlayers
|
|
12
12
|
? '<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/ol@10.6.1/ol.css">' +
|
|
13
13
|
'<script src="https://cdn.jsdelivr.net/npm/ol@10.6.1/dist/ol.js"><\/script>' +
|
|
14
|
-
'<script src="https://unpkg.com/leaflet-city-mapper@0.0.
|
|
14
|
+
'<script src="https://unpkg.com/leaflet-city-mapper@0.0.7/libs/openlayers-bindings.min.js"><\/script>'
|
|
15
15
|
: '<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9/dist/leaflet.css"><script src="https://unpkg.com/leaflet@1.9/dist/leaflet-src.js"><\/script>'));
|
|
16
16
|
|
|
17
17
|
const engineStyle = document.createElement('style');
|
package/package.json
CHANGED
package/src/cog/initCog.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { initRaster } from '../raster/initRaster.js';
|
|
2
|
-
import {
|
|
2
|
+
import { openCogInWorker } from '../workers/openCogInWorker.js';
|
|
3
3
|
|
|
4
4
|
export function initCog(layer, options) {
|
|
5
5
|
initRaster(layer, /* alloc */ { ariaLabel: 'COG raster', ...options,
|
|
6
|
-
archive: options.archive ||
|
|
6
|
+
archive: options.archive || openCogInWorker(layer, options) });
|
|
7
7
|
}
|
|
@@ -3,10 +3,43 @@ import { tiledBounds } from '../globals/tiledBounds.js';
|
|
|
3
3
|
|
|
4
4
|
import { mapGetBearing } from '../camera/mapGetBearing.js';
|
|
5
5
|
import { mapGetPitch } from '../camera/mapGetPitch.js';
|
|
6
|
+
import { streamTerrainByMap } from '../weakmaps/streamTerrainByMap.js';
|
|
7
|
+
import { renderers } from '../weakmaps/renderers.js';
|
|
8
|
+
import { sceneOriginByLayer } from '../weakmaps/sceneOriginByLayer.js';
|
|
9
|
+
import { cameraViewByMap } from '../weakmaps/cameraViewByMap.js';
|
|
10
|
+
import { mapMethods } from '../globals/mapMethods.js';
|
|
11
|
+
import { radians } from '../globals/radians.js';
|
|
12
|
+
import { earthCirc } from '../globals/earthCirc.js';
|
|
13
|
+
import { mapElevationOf } from '../terrain/mapElevationOf.js';
|
|
14
|
+
import { groundBounds } from '../projections/groundBounds.js';
|
|
15
|
+
import { animationPoint } from '../projections/transformZoomAnimationPoint.js';
|
|
6
16
|
|
|
7
17
|
export function gridlayerGetTiledPixelBounds(center) {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
18
|
+
const map = this._map, stream = streamTerrainByMap.get(map);
|
|
19
|
+
if (!stream && !mapGetBearing(map) && !mapGetPitch(map)) return tiledBounds.value.call(this, center);
|
|
20
|
+
const bounds = map.getBounds();
|
|
21
|
+
const result = /* alloc */ new L.Bounds(map.project(bounds.getNorthWest(), this._tileZoom),
|
|
22
|
+
map.project(bounds.getSouthEast(), this._tileZoom));
|
|
23
|
+
const shared = renderers.get(map), origin = shared && sceneOriginByLayer.get(shared);
|
|
24
|
+
if (!stream || !origin) return result;
|
|
25
|
+
let minimum = Infinity, maximum = -Infinity, key, entry;
|
|
26
|
+
for ([key, entry] of stream.terrainCache) {
|
|
27
|
+
if (!key.startsWith(`${this._tileZoom}/`) || !entry.range) continue;
|
|
28
|
+
minimum = Math.min(minimum, entry.range[0]);
|
|
29
|
+
maximum = Math.max(maximum, entry.range[1]);
|
|
30
|
+
}
|
|
31
|
+
if (!Number.isFinite(minimum) || !Number.isFinite(maximum)) return result;
|
|
32
|
+
const zoom = cameraViewByMap.get(map)?.zoom ?? map.getZoom();
|
|
33
|
+
const scale = map.options.crs.scale(zoom) / (earthCirc * Math.cos(origin.lat * radians));
|
|
34
|
+
const target = mapElevationOf(map, map.getCenter()) ?? 0;
|
|
35
|
+
let i, j, footprint, point, raw;
|
|
36
|
+
for (i = 0; i < 2; i++) {
|
|
37
|
+
footprint = groundBounds(map, undefined, ((i ? maximum : minimum) - target) * scale);
|
|
38
|
+
for (j = 0; j < 2; j++) {
|
|
39
|
+
point = j ? footprint.max : footprint.min;
|
|
40
|
+
raw = mapMethods.value.containerPointToLayerPoint.call(map, animationPoint(map, point, true));
|
|
41
|
+
result.extend(map.project(map.layerPointToLatLng(raw), this._tileZoom));
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
return result;
|
|
12
45
|
}
|
package/src/core/markerSetPos.js
CHANGED
|
@@ -5,7 +5,7 @@ import { markerCameraIconPoint } from '../projections/markerCameraIconPoint.js';
|
|
|
5
5
|
import { displayPoint } from '../projections/displayContainerPoint.js';
|
|
6
6
|
|
|
7
7
|
export function markerSetPos(point) {
|
|
8
|
-
markerMethods.value._setPos.call(this, displayPoint(this._map, point));
|
|
8
|
+
markerMethods.value._setPos.call(this, displayPoint(this._map, point, this.getLatLng()));
|
|
9
9
|
let i, element, key, direction, options, anchor;
|
|
10
10
|
for (i = 0; i < 2; i++) {
|
|
11
11
|
element = i ? this._shadow : this._icon;
|
|
@@ -3,6 +3,6 @@ import { popupEvents } from '../globals/popupEvents.js';
|
|
|
3
3
|
|
|
4
4
|
export function popupGetEvents() {
|
|
5
5
|
const events = popupEvents.value.call(this);
|
|
6
|
-
events.rotate = events.pitch = events.move = this._updatePosition;
|
|
6
|
+
events.rotate = events.pitch = events.move = events.terrainchange = this._updatePosition;
|
|
7
7
|
return events;
|
|
8
8
|
}
|
|
@@ -5,13 +5,13 @@ import { popupPosition } from '../globals/popupPosition.js';
|
|
|
5
5
|
import { displayPoint } from '../projections/displayContainerPoint.js';
|
|
6
6
|
|
|
7
7
|
export function popupUpdatePosition() {
|
|
8
|
-
popupPosition.value.call(this);
|
|
9
|
-
if (!this._map) return;
|
|
10
|
-
const point = this._map.latLngToLayerPoint(this._latlng), delta = displayPoint(this._map, point).subtract(point);
|
|
11
|
-
if (this._zoomAnimated) {
|
|
12
|
-
L.DomUtil.setPosition(this._container, L.DomUtil.getPosition(this._container).add(delta));
|
|
13
|
-
} else {
|
|
14
|
-
this._container.style.left = `${this._containerLeft + delta.x}px`;
|
|
15
|
-
this._container.style.bottom = `${this._containerBottom - delta.y}px`;
|
|
8
|
+
popupPosition.value.call(this);
|
|
9
|
+
if (!this._map) return;
|
|
10
|
+
const point = this._map.latLngToLayerPoint(this._latlng), delta = displayPoint(this._map, point, this._latlng).subtract(point);
|
|
11
|
+
if (this._zoomAnimated) {
|
|
12
|
+
L.DomUtil.setPosition(this._container, L.DomUtil.getPosition(this._container).add(delta));
|
|
13
|
+
} else {
|
|
14
|
+
this._container.style.left = `${this._containerLeft + delta.x}px`;
|
|
15
|
+
this._container.style.bottom = `${this._containerBottom - delta.y}px`;
|
|
16
16
|
}
|
|
17
17
|
}
|
|
@@ -3,6 +3,6 @@ import { tooltipEvents } from '../globals/tooltipEvents.js';
|
|
|
3
3
|
|
|
4
4
|
export function tooltipGetEvents() {
|
|
5
5
|
const events = tooltipEvents.value.call(this);
|
|
6
|
-
events.rotate = events.pitch = events.move = this._updatePosition;
|
|
6
|
+
events.rotate = events.pitch = events.move = events.terrainchange = this._updatePosition;
|
|
7
7
|
return events;
|
|
8
8
|
}
|
|
@@ -5,7 +5,7 @@ import { tooltipPosition } from '../globals/tooltipPosition.js';
|
|
|
5
5
|
import { displayPoint } from '../projections/displayContainerPoint.js';
|
|
6
6
|
|
|
7
7
|
export function tooltipSetPosition(point) {
|
|
8
|
-
tooltipPosition.value.call(this, point);
|
|
9
|
-
const delta = displayPoint(this._map, point).subtract(point);
|
|
8
|
+
tooltipPosition.value.call(this, point);
|
|
9
|
+
const delta = displayPoint(this._map, point, this._latlng).subtract(point);
|
|
10
10
|
L.DomUtil.setPosition(this._container, L.DomUtil.getPosition(this._container).add(delta));
|
|
11
11
|
}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export function triangle(point, target, a, b, c) {
|
|
2
|
-
return target.push(...point(a), ...point(b), ...point(c));
|
|
1
|
+
export function triangle(point, target, a, b, c, anchorA, anchorB, anchorC) {
|
|
2
|
+
return target.push(...point(a, anchorA), ...point(b, anchorB), ...point(c, anchorC));
|
|
3
3
|
}
|
|
@@ -1,14 +1,8 @@
|
|
|
1
|
-
import { rendererByLayer } from '../weakmaps/rendererByLayer.js';
|
|
2
|
-
|
|
3
|
-
import { vertexNormals } from './vertexNormals.js';
|
|
1
|
+
import { rendererByLayer } from '../weakmaps/rendererByLayer.js';
|
|
2
|
+
|
|
4
3
|
import { createProgram } from '../materials/createProgram.js';
|
|
5
4
|
|
|
6
5
|
export function createModelGeometry(context, primitive, attributes) {
|
|
7
|
-
let normals;
|
|
8
|
-
if (!attributes.normal) {
|
|
9
|
-
normals = vertexNormals(attributes.position.data, attributes.index?.data);
|
|
10
|
-
attributes.normal = /* alloc */ { size: 3, data: normals };
|
|
11
|
-
}
|
|
12
6
|
const style = context.materials[primitive.material] || /* alloc */ {
|
|
13
7
|
color: /* alloc */ [1, 1, 1], metallic: 1,
|
|
14
8
|
};
|
|
@@ -18,7 +12,6 @@ export function createModelGeometry(context, primitive, attributes) {
|
|
|
18
12
|
const program = createProgram(context.backend, style);
|
|
19
13
|
context.resources.push(program);
|
|
20
14
|
const device = rendererByLayer.get(context.backend).device;
|
|
21
|
-
if (attributes.index?.data instanceof Uint8Array) attributes.index.data = Uint16Array.from(attributes.index.data);
|
|
22
15
|
let name, attribute;
|
|
23
16
|
for ([name, attribute] of Object.entries(attributes)) {
|
|
24
17
|
attribute.size ||= 1;
|
|
@@ -2,15 +2,20 @@ import { segment } from './segment.js';
|
|
|
2
2
|
|
|
3
3
|
export function dashedSegment(context, a, b, length, distance, period) {
|
|
4
4
|
const dash = context.dash;
|
|
5
|
-
let offset = 0, phase, index, end, delta;
|
|
5
|
+
let offset = 0, phase = ((distance % period) + period) % period, index = 0, end, delta, skipped = 0;
|
|
6
|
+
while (index < dash.length - 1 && phase >= dash[index]) phase -= dash[index++];
|
|
7
|
+
let remaining = Math.max(0, dash[index] - phase);
|
|
6
8
|
while (offset < length) {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
end = Math.min(length, offset + dash[index] - phase);
|
|
10
|
-
if (index % 2 === 0) {
|
|
9
|
+
end = Math.min(length, offset + remaining);
|
|
10
|
+
if (end > offset && index % 2 === 0) {
|
|
11
11
|
delta = b.subtract(a).divideBy(length);
|
|
12
12
|
segment(context, a.add(delta.multiplyBy(offset)), a.add(delta.multiplyBy(end)), true, true);
|
|
13
13
|
}
|
|
14
|
+
if (end <= offset) {
|
|
15
|
+
if (++skipped >= dash.length) throw /* alloc */ new Error('Leaflet dashArray is too small for these coordinates');
|
|
16
|
+
} else skipped = 0;
|
|
14
17
|
offset = end;
|
|
18
|
+
index = (index + 1) % dash.length;
|
|
19
|
+
remaining = dash[index];
|
|
15
20
|
}
|
|
16
21
|
}
|
package/src/geometry/disk.js
CHANGED
|
@@ -6,6 +6,6 @@ export function disk(point, center, radius, target, radiusY = radius) {
|
|
|
6
6
|
const count = Math.max(12, Math.min(128, Math.ceil(Math.PI * Math.sqrt(radius))));
|
|
7
7
|
let i;
|
|
8
8
|
for (i = 0; i < count; i++) {
|
|
9
|
-
triangle(point, target, center, diskAt(center, radius, radiusY, count, i), diskAt(center, radius, radiusY, count, i + 1));
|
|
9
|
+
triangle(point, target, center, diskAt(center, radius, radiusY, count, i), diskAt(center, radius, radiusY, count, i + 1), center, center, center);
|
|
10
10
|
}
|
|
11
11
|
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { triangle } from './appendNativeTriangle.js';
|
|
2
|
+
import { triangulate } from '../triangulation/triangulate.js';
|
|
3
|
+
|
|
4
|
+
export function fillNativePolygon(context, projected) {
|
|
5
|
+
const { options, fill, point } = context;
|
|
6
|
+
if (options.triangulated) {
|
|
7
|
+
if (projected.length !== 1 || projected[0].length !== 3) {
|
|
8
|
+
throw /* alloc */ new Error('triangulated polygons require three vertices per polygon and no holes');
|
|
9
|
+
}
|
|
10
|
+
triangle(point, fill, projected[0][0], projected[0][1], projected[0][2]);
|
|
11
|
+
return;
|
|
12
|
+
}
|
|
13
|
+
const valid = /* alloc */ [];
|
|
14
|
+
let ring, indices;
|
|
15
|
+
for (ring of projected) if (ring.length >= 3) valid.push(ring);
|
|
16
|
+
const vertices = valid.flat();
|
|
17
|
+
for (indices of triangulate(valid[0], valid.slice(1))) {
|
|
18
|
+
triangle(point, fill, vertices[indices[0]], vertices[indices[1]], vertices[indices[2]]);
|
|
19
|
+
}
|
|
20
|
+
}
|
package/src/geometry/lineJoin.js
CHANGED
|
@@ -19,8 +19,8 @@ export function lineJoin(context, points, i, b, length) {
|
|
|
19
19
|
const from = a.add(n1.multiplyBy(radius)), to = a.add(n2.multiplyBy(radius));
|
|
20
20
|
const denominator = 1 + n1.x * n2.x + n1.y * n2.y;
|
|
21
21
|
const miter = denominator > 0 ? n1.add(n2).multiplyBy(radius / denominator) : null;
|
|
22
|
-
triangle(point, stroke, from, a, to);
|
|
22
|
+
triangle(point, stroke, from, a, to, a, a, a);
|
|
23
23
|
if (options.lineJoin === 'miter' && miter && Math.hypot(miter.x, miter.y) <= radius * 4) {
|
|
24
|
-
triangle(point, stroke, from, a.add(miter), to);
|
|
24
|
+
triangle(point, stroke, from, a.add(miter), to, a, a, a);
|
|
25
25
|
}
|
|
26
26
|
}
|
|
@@ -8,11 +8,17 @@ import { localPosition } from '../projections/localPosition.js';
|
|
|
8
8
|
|
|
9
9
|
import { transformNativePoint } from '../transforms/transformNativePoint.js';
|
|
10
10
|
import { markerImageBounds } from './markerImageBounds.js';
|
|
11
|
+
import { streamTerrainByMap } from '../weakmaps/streamTerrainByMap.js';
|
|
12
|
+
import { mapElevationOf } from '../terrain/mapElevationOf.js';
|
|
11
13
|
|
|
12
14
|
export function markerQuadCorners(state, key, image) {
|
|
13
15
|
const { source, map, backend: layer } = state;
|
|
14
16
|
|
|
15
17
|
const position = localPosition(state, source.getLatLng());
|
|
18
|
+
if (streamTerrainByMap.get(map)) {
|
|
19
|
+
const root = rootByLayer.get(layer), elevation = mapElevationOf(map, source.getLatLng());
|
|
20
|
+
if (Number.isFinite(elevation)) position[1] = (elevation - root.position[1]) / root.scale[1];
|
|
21
|
+
}
|
|
16
22
|
const size = map.getSize();
|
|
17
23
|
const matrices = state.markerMatrices ||= /* alloc */ {
|
|
18
24
|
root: /* alloc */ new DOMMatrix(),
|
|
@@ -3,7 +3,7 @@ import { visit } from './visitNativeCoordinates.js';
|
|
|
3
3
|
import { dashValues } from './dashValues.js';
|
|
4
4
|
import { circleGeometry } from './circleGeometry.js';
|
|
5
5
|
|
|
6
|
-
/** Leaflet paths become flat triangles;
|
|
6
|
+
/** Leaflet paths become flat triangles; solid strokes retain stationary zoom anchors. */
|
|
7
7
|
export function nativeGeometry(source, map, point) {
|
|
8
8
|
const fill = /* alloc */ [];
|
|
9
9
|
const stroke = /* alloc */ [];
|
package/src/geometry/polygon.js
CHANGED
|
@@ -1,23 +1,17 @@
|
|
|
1
|
-
import { triangle } from './appendNativeTriangle.js';
|
|
2
1
|
import { line } from './line.js';
|
|
3
|
-
import {
|
|
2
|
+
import { fillNativePolygon } from './fillNativePolygon.js';
|
|
4
3
|
|
|
5
4
|
export function polygon(context, rings, closed) {
|
|
6
|
-
const { options,
|
|
5
|
+
const { options, map } = context;
|
|
7
6
|
const projected = /* alloc */ [];
|
|
8
|
-
let ring, path, latlng
|
|
7
|
+
let ring, path, latlng;
|
|
9
8
|
for (ring of rings) {
|
|
10
9
|
path = /* alloc */ [];
|
|
11
10
|
for (latlng of ring) path.push(map.project(latlng));
|
|
12
11
|
projected.push(path);
|
|
13
12
|
}
|
|
14
13
|
if (closed && options.fill && projected[0]?.length >= 3) {
|
|
15
|
-
|
|
16
|
-
for (ring of projected) if (ring.length >= 3) valid.push(ring);
|
|
17
|
-
const vertices = valid.flat();
|
|
18
|
-
for (indices of triangulate(valid[0], valid.slice(1))) {
|
|
19
|
-
triangle(point, fill, vertices[indices[0]], vertices[indices[1]], vertices[indices[2]]);
|
|
20
|
-
}
|
|
14
|
+
fillNativePolygon(context, projected);
|
|
21
15
|
}
|
|
22
16
|
for (ring of projected) line(context, ring, closed);
|
|
23
17
|
}
|
package/src/geometry/segment.js
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
import { L } from '../globals/L.js';
|
|
1
|
+
import { L } from '../globals/L.js';
|
|
2
2
|
import { triangle } from './appendNativeTriangle.js';
|
|
3
3
|
import { disk } from './disk.js';
|
|
4
4
|
|
|
5
5
|
export function segment(context, a, b, startCap, endCap) {
|
|
6
6
|
const { options, width, stroke, point } = context;
|
|
7
7
|
const radius = width / 2;
|
|
8
|
+
const anchorA = a, anchorB = b;
|
|
8
9
|
const length = a.distanceTo(b);
|
|
9
10
|
if (!length) return;
|
|
10
11
|
const direction = b.subtract(a).divideBy(length);
|
|
@@ -13,8 +14,8 @@ export function segment(context, a, b, startCap, endCap) {
|
|
|
13
14
|
if (startCap) a = a.subtract(direction.multiplyBy(radius));
|
|
14
15
|
if (endCap) b = b.add(direction.multiplyBy(radius));
|
|
15
16
|
}
|
|
16
|
-
triangle(point, stroke, a.add(normal), a.subtract(normal), b.add(normal));
|
|
17
|
-
triangle(point, stroke, b.add(normal), a.subtract(normal), b.subtract(normal));
|
|
17
|
+
triangle(point, stroke, a.add(normal), a.subtract(normal), b.add(normal), anchorA, anchorA, anchorB);
|
|
18
|
+
triangle(point, stroke, b.add(normal), a.subtract(normal), b.subtract(normal), anchorB, anchorA, anchorB);
|
|
18
19
|
if (options.lineCap === 'round') {
|
|
19
20
|
if (startCap) disk(point, a, radius, stroke);
|
|
20
21
|
if (endCap) disk(point, b, radius, stroke);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export const mvtTextDecoder = new TextDecoder('utf-8', { fatal: true });
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export const nativeScalableStyleKeys = new Set(['color', 'opacity', 'weight', 'fillColor', 'fillOpacity']);
|
package/src/globals/scenePass.js
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export const vectorTileEvents = 'move zoom rotate pitch resize viewreset';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export const workerCogSource = { key: null, archive: null };
|
package/src/gpu/mountRenderer.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { sizeByLayer } from '../weakmaps/sizeByLayer.js';
|
|
2
|
-
|
|
1
|
+
import { sizeByLayer } from '../weakmaps/sizeByLayer.js';
|
|
2
|
+
|
|
3
3
|
import { onMapChange } from '../scene/onMapChange.js';
|
|
4
4
|
import { startZoom } from '../animations/startZoom.js';
|
|
5
5
|
import { onZoomAnim } from '../animations/onZoomAnim.js';
|
|
@@ -8,17 +8,10 @@ import { endZoom } from '../animations/endZoom.js';
|
|
|
8
8
|
export function mountRenderer(layer, map, canvas) {
|
|
9
9
|
sizeByLayer.set(layer, null);
|
|
10
10
|
canvas.className = 'leaflet-3d';
|
|
11
|
-
canvas.style.cssText = 'position:absolute;top:0;left:0;pointer-events:none';
|
|
11
|
+
canvas.style.cssText = 'position:absolute;top:0;left:0;z-index:1;pointer-events:none';
|
|
12
12
|
canvas.setAttribute('role', 'img');
|
|
13
13
|
canvas.setAttribute('aria-label', layer.options.ariaLabel ?? '3D scene');
|
|
14
|
-
|
|
15
|
-
if (!pane) {
|
|
16
|
-
pane = map.createPane('webgpuPane', map.getContainer());
|
|
17
|
-
// The pitch sky uses 0 and may be inserted after this pane.
|
|
18
|
-
pane.style.zIndex = 1;
|
|
19
|
-
pane.style.pointerEvents = 'none';
|
|
20
|
-
}
|
|
21
|
-
pane.append(canvas);
|
|
14
|
+
map.getPane('mapPane').before(canvas);
|
|
22
15
|
map.on('move zoom rotate pitch resize viewreset layeradd layerremove', onMapChange, layer);
|
|
23
16
|
map.on('zoomstart', startZoom, layer);
|
|
24
17
|
map.on('zoomanim', onZoomAnim, layer);
|
|
@@ -2,6 +2,7 @@ export async function releaseRenderer(renderer, layer) {
|
|
|
2
2
|
try {
|
|
3
3
|
await renderer.device.queue.onSubmittedWorkDone();
|
|
4
4
|
renderer.depthTexture?.destroy();
|
|
5
|
+
renderer.colorTexture?.destroy();
|
|
5
6
|
renderer.roofFallbackTexture?.texture?.destroy();
|
|
6
7
|
renderer.uniformBuffer?.destroy();
|
|
7
8
|
renderer.sunlight?.texture?.destroy();
|
package/src/index.js
CHANGED
|
@@ -4,21 +4,16 @@ import { layerCallInitHooks as sharedLayerCallInitHooks } from './globals/layerC
|
|
|
4
4
|
import { removeLayer as sharedRemoveLayer } from './globals/removeLayer.js';
|
|
5
5
|
|
|
6
6
|
import './camera/mapCamera.js';
|
|
7
|
-
import { init3D } from './scene/init3D.js';
|
|
8
|
-
import { initNativeGPU } from './native/initNativeGPU.js';
|
|
9
|
-
import { initRaster } from './raster/initRaster.js';
|
|
10
|
-
import { setGeoJSONData } from './sources/setGeoJSONData.js';
|
|
11
|
-
import { initTerrain } from './terrain/initTerrain.js';
|
|
12
7
|
import './sunlight/initSunlight.js';
|
|
13
|
-
import { initTraffic } from './traffic/initTraffic.js';
|
|
14
8
|
import './walk/initWalk.js';
|
|
15
9
|
|
|
16
|
-
import { initializeNativeLayer } from './core/initializeNativeLayer.js';
|
|
17
10
|
import { layerLayerAdd } from './scene/addRegisteredLayer.js';
|
|
18
11
|
import { layerInitialize } from './scene/layerInitialize.js';
|
|
19
12
|
import { removeLayer } from './core/removeLayer.js';
|
|
20
13
|
import { getPitch } from './camera/getPitch.js';
|
|
21
14
|
import { getBearing } from './camera/getBearing.js';
|
|
15
|
+
import { setPitch } from './camera/setPitch.js';
|
|
16
|
+
import { setBearing } from './camera/setBearing.js';
|
|
22
17
|
import { setRotation } from './core/setRotation.js';
|
|
23
18
|
import { layerCallInitHooks } from './core/layerCallInitHooks.js';
|
|
24
19
|
|
|
@@ -39,19 +34,18 @@ import { layerCallInitHooks } from './core/layerCallInitHooks.js';
|
|
|
39
34
|
* Operations receive the layer explicitly, without subclasses or prototype replacement.
|
|
40
35
|
* Dataset-specific code and data (routes, timetables, API loaders) belong to the application, e.g. misc/.
|
|
41
36
|
*
|
|
42
|
-
* When `type` is omitted,
|
|
43
|
-
* 'pmtiles', *.tif/*.tiff URLs use 'cog', and other sources use '3d'.
|
|
37
|
+
* When `type` is omitted, *.pmtiles and *.tif/*.tiff URLs use 'raster'; other sources use 'vector'.
|
|
44
38
|
*/
|
|
45
39
|
|
|
46
40
|
layerProto.value = Object.defineProperties({}, Object.getOwnPropertyDescriptors(L.Layer.prototype));
|
|
47
41
|
sharedLayerCallInitHooks.value = L.Layer.prototype.callInitHooks;
|
|
48
42
|
|
|
49
43
|
/**
|
|
50
|
-
* The '
|
|
44
|
+
* The 'vector' layer type: native WebGPU scene synchronized with the map camera.
|
|
51
45
|
* Layers on one map share a canvas, scene and camera; each has its own root transform.
|
|
52
46
|
*
|
|
53
47
|
* @typedef {Object} Layer3DOptions Layer options; pane and attribution remain standard L.Layer options.
|
|
54
|
-
* @property {
|
|
48
|
+
* @property {'vector'|'raster'|'terrain'|'traffic'} [type]
|
|
55
49
|
* @property {number[]} [center] Local origin [lat,lng]; defaults to the first map center.
|
|
56
50
|
* @property {number} [terrainOffset=0] Vertical offset in metres when terrain is enabled.
|
|
57
51
|
* @property {boolean} [terrainConform=false] Fit lower model geometry to local terrain elevation.
|
|
@@ -108,5 +102,5 @@ L.Layer.include({
|
|
|
108
102
|
});
|
|
109
103
|
|
|
110
104
|
sharedRemoveLayer.value = L.Map.prototype.removeLayer;
|
|
111
|
-
L.Map.include({ removeLayer, getPitch, getBearing });
|
|
105
|
+
L.Map.include({ removeLayer, getPitch, getBearing, setPitch, setBearing });
|
|
112
106
|
L.Marker.include({ setRotation });
|
|
@@ -13,5 +13,6 @@ export function createProgramUniforms(material) {
|
|
|
13
13
|
if (material.emissiveTexture) uniforms.emissiveTexture = /* alloc */ { value: material.emissiveTexture };
|
|
14
14
|
if (material.occlusionTexture) uniforms.occlusionTexture = /* alloc */ { value: material.occlusionTexture };
|
|
15
15
|
if (material.roofTexture || material.wallTexture) uniforms.roofTexture = /* alloc */ { value: null };
|
|
16
|
+
if (material.nativeStroke) uniforms.strokeScale = /* alloc */ { value: 1 };
|
|
16
17
|
return uniforms;
|
|
17
18
|
}
|
package/src/models/loadModel.js
CHANGED
|
@@ -3,14 +3,14 @@ import { modelByLayer } from '../weakmaps/modelByLayer.js';
|
|
|
3
3
|
import { modelUrlByLayer } from '../weakmaps/modelUrlByLayer.js';
|
|
4
4
|
import { rootByLayer } from '../weakmaps/rootByLayer.js';
|
|
5
5
|
import { terrain3DByMap } from '../weakmaps/terrain3DByMap.js';
|
|
6
|
+
import { cameraViewByMap } from '../weakmaps/cameraViewByMap.js';
|
|
6
7
|
|
|
7
8
|
|
|
8
9
|
|
|
9
|
-
import {
|
|
10
|
+
import { runSourceWorker } from '../workers/runSourceWorker.js';
|
|
10
11
|
import { setParent } from '../scene/setParent.js';
|
|
11
12
|
import { emptyNode } from '../scene/createSceneNode.js';
|
|
12
13
|
import { conformModelToTerrain } from '../geometry/conformModelToTerrain.js';
|
|
13
|
-
import { loadModelResources } from './loadModelResources.js';
|
|
14
14
|
import { createModelContext } from './createModelContext.js';
|
|
15
15
|
import { buildModelNodes } from './buildModelNodes.js';
|
|
16
16
|
import { applyModelTransform } from './applyModelTransform.js';
|
|
@@ -22,14 +22,10 @@ import { applyModelTransform } from './applyModelTransform.js';
|
|
|
22
22
|
export async function loadModel(layer) {
|
|
23
23
|
await addedByLayer.get(layer).promise;
|
|
24
24
|
const url = /* alloc */ new URL(modelUrlByLayer.get(layer), document.baseURI).href;
|
|
25
|
-
const
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
const data = await response.arrayBuffer();
|
|
30
|
-
const description = decodeModel(data);
|
|
31
|
-
const directory = /* alloc */ new URL('.', url).href;
|
|
32
|
-
const images = await loadModelResources(layer, description, directory);
|
|
25
|
+
const { description, images } = await runSourceWorker(layer._map, layer.options.workerUrl,
|
|
26
|
+
/* alloc */ { type: 'model', url });
|
|
27
|
+
await addedByLayer.get(layer).promise;
|
|
28
|
+
await cameraViewByMap.get(layer._map);
|
|
33
29
|
const context = createModelContext(layer, description, images);
|
|
34
30
|
const scene = description.scenes?.[description.scene || 0];
|
|
35
31
|
if (!scene) throw /* alloc */ new Error('Missing glTF scene');
|
|
@@ -1,20 +1,14 @@
|
|
|
1
|
-
import { addedByLayer } from '../weakmaps/addedByLayer.js';
|
|
2
|
-
import { cameraViewByMap } from '../weakmaps/cameraViewByMap.js';
|
|
3
|
-
|
|
4
1
|
import { geometryEmpty } from '../globals/geometryEmpty.js';
|
|
5
2
|
import { loadBuffer } from './loadBuffer.js';
|
|
6
3
|
import { loadImage } from '../textures/loadModelImage.js';
|
|
7
4
|
|
|
8
|
-
export async function loadModelResources(
|
|
5
|
+
export async function loadModelResources(description, directory) {
|
|
9
6
|
const bufferRequests = /* alloc */ [];
|
|
10
7
|
let buffer;
|
|
11
8
|
for (buffer of description.buffers || geometryEmpty) bufferRequests.push(loadBuffer(buffer, directory));
|
|
12
9
|
await Promise.all(bufferRequests);
|
|
13
|
-
await addedByLayer.get(layer).promise;
|
|
14
10
|
const imageRequests = /* alloc */ [];
|
|
15
11
|
let image;
|
|
16
12
|
for (image of description.images || geometryEmpty) imageRequests.push(loadImage(description, directory, image));
|
|
17
|
-
|
|
18
|
-
await cameraViewByMap.get(layer._map);
|
|
19
|
-
return images;
|
|
13
|
+
return Promise.all(imageRequests);
|
|
20
14
|
}
|
package/src/models/modelNode.js
CHANGED
|
@@ -4,8 +4,6 @@ import { geometryEmpty } from '../globals/geometryEmpty.js';
|
|
|
4
4
|
import { emptyNode } from '../scene/createSceneNode.js';
|
|
5
5
|
import { nodeMatrix } from '../transforms/modelNodeMatrix.js';
|
|
6
6
|
import { setParent } from '../scene/setParent.js';
|
|
7
|
-
import { readModelAttributes } from './readModelAttributes.js';
|
|
8
|
-
import { readModelIndices } from './readModelIndices.js';
|
|
9
7
|
import { createModelGeometry } from '../geometry/createModelGeometry.js';
|
|
10
8
|
|
|
11
9
|
export function modelNode(context, index) {
|
|
@@ -20,13 +18,11 @@ export function modelNode(context, index) {
|
|
|
20
18
|
name: spec.name
|
|
21
19
|
};
|
|
22
20
|
group.matrix = nodeMatrix(spec);
|
|
23
|
-
let primitive,
|
|
21
|
+
let primitive, attributes, built, mesh, child;
|
|
24
22
|
if (spec.mesh !== undefined) {
|
|
25
23
|
for (primitive of description.meshes[spec.mesh].primitives) {
|
|
26
|
-
|
|
27
|
-
attributes =
|
|
28
|
-
vertexCount = attributeData.vertexCount;
|
|
29
|
-
readModelIndices(description, primitive, attributes, vertexCount);
|
|
24
|
+
// Node instances own their CPU data and GPU buffers, even when they share a glTF mesh.
|
|
25
|
+
attributes = structuredClone(primitive.preparedAttributes);
|
|
30
26
|
built = createModelGeometry(context, primitive, attributes);
|
|
31
27
|
mesh = /* alloc */ {
|
|
32
28
|
...emptyNode(),
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { decodeModel } from './decodeModel.js';
|
|
2
|
+
import { loadModelResources } from './loadModelResources.js';
|
|
3
|
+
import { prepareModelGeometry } from './prepareModelGeometry.js';
|
|
4
|
+
|
|
5
|
+
export async function prepareModel(url) {
|
|
6
|
+
const response = await fetch(url);
|
|
7
|
+
if (!response.ok) throw /* alloc */ new Error(`Unable to load model: HTTP ${response.status}`);
|
|
8
|
+
const description = decodeModel(await response.arrayBuffer());
|
|
9
|
+
const scene = description.scenes?.[description.scene || 0];
|
|
10
|
+
if (!scene) throw /* alloc */ new Error('Missing glTF scene');
|
|
11
|
+
const images = await loadModelResources(description, /* alloc */ new URL('.', url).href);
|
|
12
|
+
const transfers = prepareModelGeometry(description, scene);
|
|
13
|
+
let image;
|
|
14
|
+
for (image of images) transfers.push(image);
|
|
15
|
+
delete description.buffers;
|
|
16
|
+
delete description.bufferViews;
|
|
17
|
+
delete description.accessors;
|
|
18
|
+
return /* alloc */ { description, images, transfers };
|
|
19
|
+
}
|