leaflet-city-mapper 0.0.0-stage → 0.0.2
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/LICENSE +674 -0
- package/README.md +78 -2
- package/cucumber.mjs +9 -0
- package/dist/leaflet-city-mapper.js +2 -0
- package/dist/leaflet-city-mapper.js.map +7 -0
- package/dist/utils/CELL.js +2 -0
- package/dist/utils/CELL.js.map +7 -0
- package/dist/utils/addBridges.js +2 -0
- package/dist/utils/addBridges.js.map +7 -0
- package/dist/utils/addRasterTile.js +2 -0
- package/dist/utils/addRasterTile.js.map +7 -0
- package/dist/utils/along.js +2 -0
- package/dist/utils/along.js.map +7 -0
- package/dist/utils/atmosphere.js +2 -0
- package/dist/utils/atmosphere.js.map +7 -0
- package/dist/utils/attach.js +2 -0
- package/dist/utils/attach.js.map +7 -0
- package/dist/utils/bindSunlight.js +2 -0
- package/dist/utils/bindSunlight.js.map +7 -0
- package/dist/utils/box.js +2 -0
- package/dist/utils/box.js.map +7 -0
- package/dist/utils/bridgeElevation.js +2 -0
- package/dist/utils/bridgeElevation.js.map +7 -0
- package/dist/utils/build.js +2 -0
- package/dist/utils/build.js.map +7 -0
- package/dist/utils/cameraControls.js +2 -0
- package/dist/utils/cameraControls.js.map +7 -0
- package/dist/utils/channel.js +2 -0
- package/dist/utils/channel.js.map +7 -0
- package/dist/utils/collider.js +2 -0
- package/dist/utils/collider.js.map +7 -0
- package/dist/utils/colliders.js +2 -0
- package/dist/utils/colliders.js.map +7 -0
- package/dist/utils/computeBounds.js +2 -0
- package/dist/utils/computeBounds.js.map +7 -0
- package/dist/utils/conformModelToTerrain.js +2 -0
- package/dist/utils/conformModelToTerrain.js.map +7 -0
- package/dist/utils/createMesh.js +2 -0
- package/dist/utils/createMesh.js.map +7 -0
- package/dist/utils/createProgram.js +3 -0
- package/dist/utils/createProgram.js.map +7 -0
- package/dist/utils/decodeDirectory.js +2 -0
- package/dist/utils/decodeDirectory.js.map +7 -0
- package/dist/utils/decodeHeader.js +2 -0
- package/dist/utils/decodeHeader.js.map +7 -0
- package/dist/utils/decodeModel.js +2 -0
- package/dist/utils/decodeModel.js.map +7 -0
- package/dist/utils/decompress.js +2 -0
- package/dist/utils/decompress.js.map +7 -0
- package/dist/utils/destroyTexture.js +2 -0
- package/dist/utils/destroyTexture.js.map +7 -0
- package/dist/utils/disposeMesh.js +2 -0
- package/dist/utils/disposeMesh.js.map +7 -0
- package/dist/utils/drawGeometry.js +2 -0
- package/dist/utils/drawGeometry.js.map +7 -0
- package/dist/utils/elevationWGSL.js +24 -0
- package/dist/utils/elevationWGSL.js.map +7 -0
- package/dist/utils/emptyNode.js +2 -0
- package/dist/utils/emptyNode.js.map +7 -0
- package/dist/utils/endZoom.js +2 -0
- package/dist/utils/endZoom.js.map +7 -0
- package/dist/utils/findFeature.js +2 -0
- package/dist/utils/findFeature.js.map +7 -0
- package/dist/utils/geometry.js +1 -0
- package/dist/utils/geometry.js.map +7 -0
- package/dist/utils/getElevation.js +2 -0
- package/dist/utils/getElevation.js.map +7 -0
- package/dist/utils/getHeader.js +2 -0
- package/dist/utils/getHeader.js.map +7 -0
- package/dist/utils/getZxy.js +2 -0
- package/dist/utils/getZxy.js.map +7 -0
- package/dist/utils/glass.js +2 -0
- package/dist/utils/glass.js.map +7 -0
- package/dist/utils/headlight.js +2 -0
- package/dist/utils/headlight.js.map +7 -0
- package/dist/utils/hit.js +2 -0
- package/dist/utils/hit.js.map +7 -0
- package/dist/utils/horizontalPosition.js +2 -0
- package/dist/utils/horizontalPosition.js.map +7 -0
- package/dist/utils/horizontalRay.js +2 -0
- package/dist/utils/horizontalRay.js.map +7 -0
- package/dist/utils/hull.js +2 -0
- package/dist/utils/hull.js.map +7 -0
- package/dist/utils/initSunlight.js +2 -0
- package/dist/utils/initSunlight.js.map +7 -0
- package/dist/utils/initTerrain.js +2 -0
- package/dist/utils/initTerrain.js.map +7 -0
- package/dist/utils/initTraffic.js +40 -0
- package/dist/utils/initTraffic.js.map +7 -0
- package/dist/utils/initWalk.js +2 -0
- package/dist/utils/initWalk.js.map +7 -0
- package/dist/utils/intersectMeshes.js +2 -0
- package/dist/utils/intersectMeshes.js.map +7 -0
- package/dist/utils/isClockWise.js +2 -0
- package/dist/utils/isClockWise.js.map +7 -0
- package/dist/utils/lampPostGeometry.js +2 -0
- package/dist/utils/lampPostGeometry.js.map +7 -0
- package/dist/utils/lightGeometry.js +2 -0
- package/dist/utils/lightGeometry.js.map +7 -0
- package/dist/utils/lightGrid.js +2 -0
- package/dist/utils/lightGrid.js.map +7 -0
- package/dist/utils/limbs.js +2 -0
- package/dist/utils/limbs.js.map +7 -0
- package/dist/utils/loadModel.js +2 -0
- package/dist/utils/loadModel.js.map +7 -0
- package/dist/utils/loadSource.js +2 -0
- package/dist/utils/loadSource.js.map +7 -0
- package/dist/utils/loadTerrain.js +2 -0
- package/dist/utils/loadTerrain.js.map +7 -0
- package/dist/utils/mapCamera.js +2 -0
- package/dist/utils/mapCamera.js.map +7 -0
- package/dist/utils/materialShaders.js +211 -0
- package/dist/utils/materialShaders.js.map +7 -0
- package/dist/utils/mirror.js +2 -0
- package/dist/utils/mirror.js.map +7 -0
- package/dist/utils/moonPosition.js +2 -0
- package/dist/utils/moonPosition.js.map +7 -0
- package/dist/utils/moves.js +2 -0
- package/dist/utils/moves.js.map +7 -0
- package/dist/utils/nativeEvents.js +2 -0
- package/dist/utils/nativeEvents.js.map +7 -0
- package/dist/utils/nativeGeometry.js +2 -0
- package/dist/utils/nativeGeometry.js.map +7 -0
- package/dist/utils/nativeLayer.js +2 -0
- package/dist/utils/nativeLayer.js.map +7 -0
- package/dist/utils/nodeMatrix.js +2 -0
- package/dist/utils/nodeMatrix.js.map +7 -0
- package/dist/utils/onAdd3DLayer.js +2 -0
- package/dist/utils/onAdd3DLayer.js.map +7 -0
- package/dist/utils/onAddSun.js +2 -0
- package/dist/utils/onAddSun.js.map +7 -0
- package/dist/utils/onClick.js +2 -0
- package/dist/utils/onClick.js.map +7 -0
- package/dist/utils/onMapChange.js +2 -0
- package/dist/utils/onMapChange.js.map +7 -0
- package/dist/utils/onPMTileAdd.js +2 -0
- package/dist/utils/onPMTileAdd.js.map +7 -0
- package/dist/utils/onPMTileRemove.js +2 -0
- package/dist/utils/onPMTileRemove.js.map +7 -0
- package/dist/utils/onPointerLeave.js +2 -0
- package/dist/utils/onPointerLeave.js.map +7 -0
- package/dist/utils/onPointerMove.js +2 -0
- package/dist/utils/onPointerMove.js.map +7 -0
- package/dist/utils/onRemove3DLayer.js +2 -0
- package/dist/utils/onRemove3DLayer.js.map +7 -0
- package/dist/utils/onRemoveSun.js +2 -0
- package/dist/utils/onRemoveSun.js.map +7 -0
- package/dist/utils/onTerrainAdd.js +2 -0
- package/dist/utils/onTerrainAdd.js.map +7 -0
- package/dist/utils/onTerrainChange.js +2 -0
- package/dist/utils/onTerrainChange.js.map +7 -0
- package/dist/utils/onTerrainRemove.js +2 -0
- package/dist/utils/onTerrainRemove.js.map +7 -0
- package/dist/utils/onZoomAnim.js +2 -0
- package/dist/utils/onZoomAnim.js.map +7 -0
- package/dist/utils/paints.js +2 -0
- package/dist/utils/paints.js.map +7 -0
- package/dist/utils/parseColor.js +2 -0
- package/dist/utils/parseColor.js.map +7 -0
- package/dist/utils/parts.js +2 -0
- package/dist/utils/parts.js.map +7 -0
- package/dist/utils/projectCelestialBody.js +2 -0
- package/dist/utils/projectCelestialBody.js.map +7 -0
- package/dist/utils/pump.js +2 -0
- package/dist/utils/pump.js.map +7 -0
- package/dist/utils/rasterTiles.js +2 -0
- package/dist/utils/rasterTiles.js.map +7 -0
- package/dist/utils/raycast.js +2 -0
- package/dist/utils/raycast.js.map +7 -0
- package/dist/utils/read.js +2 -0
- package/dist/utils/read.js.map +7 -0
- package/dist/utils/readAccessor.js +2 -0
- package/dist/utils/readAccessor.js.map +7 -0
- package/dist/utils/releaseArea.js +2 -0
- package/dist/utils/releaseArea.js.map +7 -0
- package/dist/utils/removeRasterTile.js +2 -0
- package/dist/utils/removeRasterTile.js.map +7 -0
- package/dist/utils/render.js +15 -0
- package/dist/utils/render.js.map +7 -0
- package/dist/utils/renderSunlight.js +13 -0
- package/dist/utils/renderSunlight.js.map +7 -0
- package/dist/utils/renderers.js +2 -0
- package/dist/utils/renderers.js.map +7 -0
- package/dist/utils/resizeSunlight.js +2 -0
- package/dist/utils/resizeSunlight.js.map +7 -0
- package/dist/utils/roofCoverage.js +2 -0
- package/dist/utils/roofCoverage.js.map +7 -0
- package/dist/utils/routeGeometry.js +2 -0
- package/dist/utils/routeGeometry.js.map +7 -0
- package/dist/utils/scheduledTrips.js +2 -0
- package/dist/utils/scheduledTrips.js.map +7 -0
- package/dist/utils/setGeoJSONData.js +2 -0
- package/dist/utils/setGeoJSONData.js.map +7 -0
- package/dist/utils/setHighlight.js +2 -0
- package/dist/utils/setHighlight.js.map +7 -0
- package/dist/utils/setPMTileOpacity.js +2 -0
- package/dist/utils/setPMTileOpacity.js.map +7 -0
- package/dist/utils/setPMTileZIndex.js +2 -0
- package/dist/utils/setPMTileZIndex.js.map +7 -0
- package/dist/utils/setParent.js +2 -0
- package/dist/utils/setParent.js.map +7 -0
- package/dist/utils/setTerrainHeight.js +2 -0
- package/dist/utils/setTerrainHeight.js.map +7 -0
- package/dist/utils/setVertexColor.js +2 -0
- package/dist/utils/setVertexColor.js.map +7 -0
- package/dist/utils/showFeature.js +2 -0
- package/dist/utils/showFeature.js.map +7 -0
- package/dist/utils/sizes.js +2 -0
- package/dist/utils/sizes.js.map +7 -0
- package/dist/utils/skin.js +2 -0
- package/dist/utils/skin.js.map +7 -0
- package/dist/utils/solarPosition.js +2 -0
- package/dist/utils/solarPosition.js.map +7 -0
- package/dist/utils/sortMeshes.js +2 -0
- package/dist/utils/sortMeshes.js.map +7 -0
- package/dist/utils/speed.js +2 -0
- package/dist/utils/speed.js.map +7 -0
- package/dist/utils/startZoom.js +2 -0
- package/dist/utils/startZoom.js.map +7 -0
- package/dist/utils/taillight.js +2 -0
- package/dist/utils/taillight.js.map +7 -0
- package/dist/utils/terrainAtlas.js +2 -0
- package/dist/utils/terrainAtlas.js.map +7 -0
- package/dist/utils/terrainElevation.js +2 -0
- package/dist/utils/terrainElevation.js.map +7 -0
- package/dist/utils/terrainGrid.js +2 -0
- package/dist/utils/terrainGrid.js.map +7 -0
- package/dist/utils/textureSampler.js +2 -0
- package/dist/utils/textureSampler.js.map +7 -0
- package/dist/utils/tileId.js +2 -0
- package/dist/utils/tileId.js.map +7 -0
- package/dist/utils/toLanes.js +2 -0
- package/dist/utils/toLanes.js.map +7 -0
- package/dist/utils/toSRGB.js +2 -0
- package/dist/utils/toSRGB.js.map +7 -0
- package/dist/utils/tooltip.js +3 -0
- package/dist/utils/tooltip.js.map +7 -0
- package/dist/utils/traffic.js +2 -0
- package/dist/utils/traffic.js.map +7 -0
- package/dist/utils/traverse.js +2 -0
- package/dist/utils/traverse.js.map +7 -0
- package/dist/utils/treeGeometry.js +2 -0
- package/dist/utils/treeGeometry.js.map +7 -0
- package/dist/utils/triangulate.js +2 -0
- package/dist/utils/triangulate.js.map +7 -0
- package/dist/utils/tripsAt.js +2 -0
- package/dist/utils/tripsAt.js.map +7 -0
- package/dist/utils/types.js +2 -0
- package/dist/utils/types.js.map +7 -0
- package/dist/utils/underEntry.js +2 -0
- package/dist/utils/underEntry.js.map +7 -0
- package/dist/utils/update.js +2 -0
- package/dist/utils/update.js.map +7 -0
- package/dist/utils/updateArea.js +2 -0
- package/dist/utils/updateArea.js.map +7 -0
- package/dist/utils/updateCamera.js +2 -0
- package/dist/utils/updateCamera.js.map +7 -0
- package/dist/utils/updatePointLights.js +2 -0
- package/dist/utils/updatePointLights.js.map +7 -0
- package/dist/utils/updateWorldMatrix.js +2 -0
- package/dist/utils/updateWorldMatrix.js.map +7 -0
- package/dist/utils/vehicleOffsets.js +2 -0
- package/dist/utils/vehicleOffsets.js.map +7 -0
- package/dist/utils/vehicles.js +2 -0
- package/dist/utils/vehicles.js.map +7 -0
- package/dist/utils/vertexNormals.js +2 -0
- package/dist/utils/vertexNormals.js.map +7 -0
- package/dist/utils/walk.js +2 -0
- package/dist/utils/walk.js.map +7 -0
- package/dist/utils/white.js +2 -0
- package/dist/utils/white.js.map +7 -0
- package/dist/utils/worldLights.js +2 -0
- package/dist/utils/worldLights.js.map +7 -0
- package/dist/utils/wrap.js +2 -0
- package/dist/utils/wrap.js.map +7 -0
- package/package.json +43 -4
- package/src/index.js +397 -0
- package/src/utils/CELL.js +4 -0
- package/src/utils/addBridges.js +66 -0
- package/src/utils/addRasterTile.js +112 -0
- package/src/utils/along.js +9 -0
- package/src/utils/atmosphere.js +20 -0
- package/src/utils/attach.js +255 -0
- package/src/utils/bindSunlight.js +12 -0
- package/src/utils/box.js +1 -0
- package/src/utils/bridgeElevation.js +18 -0
- package/src/utils/build.js +20 -0
- package/src/utils/cameraControls.js +287 -0
- package/src/utils/channel.js +4 -0
- package/src/utils/collider.js +62 -0
- package/src/utils/colliders.js +2 -0
- package/src/utils/computeBounds.js +17 -0
- package/src/utils/conformModelToTerrain.js +69 -0
- package/src/utils/createMesh.js +31 -0
- package/src/utils/createProgram.js +92 -0
- package/src/utils/decodeDirectory.js +40 -0
- package/src/utils/decodeHeader.js +15 -0
- package/src/utils/decodeModel.js +43 -0
- package/src/utils/decompress.js +5 -0
- package/src/utils/destroyTexture.js +7 -0
- package/src/utils/disposeMesh.js +13 -0
- package/src/utils/drawGeometry.js +122 -0
- package/src/utils/elevationWGSL.js +27 -0
- package/src/utils/emptyNode.js +9 -0
- package/src/utils/endZoom.js +15 -0
- package/src/utils/findFeature.js +49 -0
- package/src/utils/geometry.js +2 -0
- package/src/utils/getElevation.js +10 -0
- package/src/utils/getHeader.js +9 -0
- package/src/utils/getZxy.js +76 -0
- package/src/utils/glass.js +1 -0
- package/src/utils/headlight.js +1 -0
- package/src/utils/hit.js +41 -0
- package/src/utils/horizontalPosition.js +16 -0
- package/src/utils/horizontalRay.js +12 -0
- package/src/utils/hull.js +1 -0
- package/src/utils/initSunlight.js +9 -0
- package/src/utils/initTerrain.js +19 -0
- package/src/utils/initTraffic.js +93 -0
- package/src/utils/initWalk.js +72 -0
- package/src/utils/intersectMeshes.js +121 -0
- package/src/utils/isClockWise.js +12 -0
- package/src/utils/lampPostGeometry.js +26 -0
- package/src/utils/lightGeometry.js +22 -0
- package/src/utils/lightGrid.js +50 -0
- package/src/utils/limbs.js +9 -0
- package/src/utils/loadModel.js +217 -0
- package/src/utils/loadSource.js +17 -0
- package/src/utils/loadTerrain.js +65 -0
- package/src/utils/mapCamera.js +432 -0
- package/src/utils/materialShaders.js +243 -0
- package/src/utils/mirror.js +6 -0
- package/src/utils/moonPosition.js +17 -0
- package/src/utils/moves.js +11 -0
- package/src/utils/nativeEvents.js +77 -0
- package/src/utils/nativeGeometry.js +131 -0
- package/src/utils/nativeLayer.js +317 -0
- package/src/utils/nodeMatrix.js +22 -0
- package/src/utils/onAdd3DLayer.js +31 -0
- package/src/utils/onAddSun.js +147 -0
- package/src/utils/onClick.js +13 -0
- package/src/utils/onMapChange.js +16 -0
- package/src/utils/onPMTileAdd.js +15 -0
- package/src/utils/onPMTileRemove.js +8 -0
- package/src/utils/onPointerLeave.js +11 -0
- package/src/utils/onPointerMove.js +15 -0
- package/src/utils/onRemove3DLayer.js +78 -0
- package/src/utils/onRemoveSun.js +3 -0
- package/src/utils/onTerrainAdd.js +18 -0
- package/src/utils/onTerrainChange.js +13 -0
- package/src/utils/onTerrainRemove.js +40 -0
- package/src/utils/onZoomAnim.js +14 -0
- package/src/utils/paints.js +10 -0
- package/src/utils/parseColor.js +42 -0
- package/src/utils/parts.js +16 -0
- package/src/utils/projectCelestialBody.js +13 -0
- package/src/utils/pump.js +226 -0
- package/src/utils/rasterTiles.js +285 -0
- package/src/utils/raycast.js +60 -0
- package/src/utils/read.js +29 -0
- package/src/utils/readAccessor.js +68 -0
- package/src/utils/releaseArea.js +34 -0
- package/src/utils/removeRasterTile.js +13 -0
- package/src/utils/render.js +406 -0
- package/src/utils/renderSunlight.js +170 -0
- package/src/utils/renderers.js +2 -0
- package/src/utils/resizeSunlight.js +15 -0
- package/src/utils/roofCoverage.js +47 -0
- package/src/utils/routeGeometry.js +22 -0
- package/src/utils/scheduledTrips.js +29 -0
- package/src/utils/setGeoJSONData.js +11 -0
- package/src/utils/setHighlight.js +13 -0
- package/src/utils/setPMTileOpacity.js +7 -0
- package/src/utils/setPMTileZIndex.js +7 -0
- package/src/utils/setParent.js +7 -0
- package/src/utils/setTerrainHeight.js +10 -0
- package/src/utils/setVertexColor.js +14 -0
- package/src/utils/showFeature.js +27 -0
- package/src/utils/sizes.js +1 -0
- package/src/utils/skin.js +2 -0
- package/src/utils/solarPosition.js +17 -0
- package/src/utils/sortMeshes.js +12 -0
- package/src/utils/speed.js +3 -0
- package/src/utils/startZoom.js +5 -0
- package/src/utils/taillight.js +1 -0
- package/src/utils/terrainAtlas.js +21 -0
- package/src/utils/terrainElevation.js +20 -0
- package/src/utils/terrainGrid.js +23 -0
- package/src/utils/textureSampler.js +10 -0
- package/src/utils/tileId.js +18 -0
- package/src/utils/toLanes.js +7 -0
- package/src/utils/toSRGB.js +1 -0
- package/src/utils/tooltip.js +6 -0
- package/src/utils/traffic.js +315 -0
- package/src/utils/traverse.js +6 -0
- package/src/utils/treeGeometry.js +45 -0
- package/src/utils/triangulate.js +100 -0
- package/src/utils/tripsAt.js +16 -0
- package/src/utils/types.js +8 -0
- package/src/utils/underEntry.js +17 -0
- package/src/utils/update.js +18 -0
- package/src/utils/updateArea.js +40 -0
- package/src/utils/updateCamera.js +32 -0
- package/src/utils/updatePointLights.js +38 -0
- package/src/utils/updateWorldMatrix.js +47 -0
- package/src/utils/vehicleOffsets.js +8 -0
- package/src/utils/vehicles.js +65 -0
- package/src/utils/vertexNormals.js +30 -0
- package/src/utils/walk.js +187 -0
- package/src/utils/white.js +1 -0
- package/src/utils/worldLights.js +25 -0
- package/src/utils/wrap.js +1 -0
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
import { decodeModel } from './decodeModel.js';
|
|
2
|
+
import { emptyNode } from './emptyNode.js';
|
|
3
|
+
import { nodeMatrix } from './nodeMatrix.js';
|
|
4
|
+
import { readAccessor } from './readAccessor.js';
|
|
5
|
+
import { setParent } from './setParent.js';
|
|
6
|
+
import { textureSampler } from './textureSampler.js';
|
|
7
|
+
import { vertexNormals } from './vertexNormals.js';
|
|
8
|
+
import { createProgram } from './createProgram.js';
|
|
9
|
+
import { conformModelToTerrain } from './conformModelToTerrain.js';
|
|
10
|
+
|
|
11
|
+
/** glTF/GLB model loading. */
|
|
12
|
+
/** Load the configured GLB/glTF (static triangles) under `root`; GPU resources need attachment. */
|
|
13
|
+
|
|
14
|
+
export async function loadModel(backend) {
|
|
15
|
+
await backend._added.promise;
|
|
16
|
+
const url = new URL(backend.modelUrl, document.baseURI).href;
|
|
17
|
+
const response = await fetch(url);
|
|
18
|
+
if (!response.ok) {
|
|
19
|
+
throw new Error(`Unable to load model: HTTP ${response.status}`);
|
|
20
|
+
}
|
|
21
|
+
const data = await response.arrayBuffer();
|
|
22
|
+
const description = decodeModel(data);
|
|
23
|
+
const directory = new URL('.', url).href;
|
|
24
|
+
await Promise.all((description.buffers || []).map(async (buffer) => {
|
|
25
|
+
if (buffer.binary) {
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
const response = await fetch(new URL(buffer.uri, directory).href);
|
|
29
|
+
if (!response.ok) {
|
|
30
|
+
throw new Error(`Unable to load model buffer: HTTP ${response.status}`);
|
|
31
|
+
}
|
|
32
|
+
buffer.binary = await response.arrayBuffer();
|
|
33
|
+
}));
|
|
34
|
+
await backend._added.promise;
|
|
35
|
+
const images = await Promise.all((description.images || []).map(async (image) => {
|
|
36
|
+
let blob;
|
|
37
|
+
if (image.bufferView !== undefined) {
|
|
38
|
+
const view = description.bufferViews[image.bufferView];
|
|
39
|
+
const buffer = description.buffers[view.buffer].binary;
|
|
40
|
+
blob = new Blob([buffer.slice(view.byteOffset || 0, (view.byteOffset || 0) + view.byteLength)],
|
|
41
|
+
{ type: image.mimeType });
|
|
42
|
+
} else {
|
|
43
|
+
const response = await fetch(new URL(image.uri, directory).href);
|
|
44
|
+
if (!response.ok) throw new Error(`Unable to load model texture: HTTP ${response.status}`);
|
|
45
|
+
blob = await response.blob();
|
|
46
|
+
}
|
|
47
|
+
// Preserve straight alpha and raw samples; GPU sRGB formats do color decoding.
|
|
48
|
+
return createImageBitmap(blob, { premultiplyAlpha: 'none', colorSpaceConversion: 'none' });
|
|
49
|
+
}));
|
|
50
|
+
await backend._map?._terrain3D?._terrainPromise;
|
|
51
|
+
const textures = new Map();
|
|
52
|
+
const textureFor = (reference, color = false) => {
|
|
53
|
+
if (!reference) return null;
|
|
54
|
+
if ((reference.texCoord || 0) !== 0 || reference.extensions) {
|
|
55
|
+
throw new Error('Model textures currently require untransformed TEXCOORD_0 UVs');
|
|
56
|
+
}
|
|
57
|
+
const device = backend.renderer.device;
|
|
58
|
+
// A glTF image may serve both color and data maps: those cannot share a GPU format.
|
|
59
|
+
const key = `${reference.index}:${color}`;
|
|
60
|
+
if (!textures.has(key)) {
|
|
61
|
+
const texture = description.textures[reference.index];
|
|
62
|
+
const sampler = description.samplers?.[texture.sampler] || {};
|
|
63
|
+
const image = images[texture.source];
|
|
64
|
+
const format = color ? 'rgba8unorm-srgb' : 'rgba8unorm';
|
|
65
|
+
const samplerOptions = textureSampler(sampler);
|
|
66
|
+
textures.set(key, {
|
|
67
|
+
device,
|
|
68
|
+
texture: device.createTexture({
|
|
69
|
+
size: [image.width, image.height],
|
|
70
|
+
format,
|
|
71
|
+
usage: GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.COPY_DST | GPUTextureUsage.RENDER_ATTACHMENT,
|
|
72
|
+
}),
|
|
73
|
+
sampler: device.createSampler(samplerOptions),
|
|
74
|
+
samplerOptions,
|
|
75
|
+
format,
|
|
76
|
+
srgb: color,
|
|
77
|
+
image,
|
|
78
|
+
flipY: false,
|
|
79
|
+
uploaded: null,
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
return textures.get(key);
|
|
83
|
+
};
|
|
84
|
+
// Convert glTF materials directly to the shader's retained CPU styles.
|
|
85
|
+
const materials = (description.materials || []).map(material => {
|
|
86
|
+
const pbr = material.pbrMetallicRoughness || {};
|
|
87
|
+
return {
|
|
88
|
+
color: (pbr.baseColorFactor || [1, 1, 1, 1]).slice(0, 3),
|
|
89
|
+
opacity: pbr.baseColorFactor?.[3] ?? 1,
|
|
90
|
+
metallic: pbr.metallicFactor ?? 1,
|
|
91
|
+
roughness: pbr.roughnessFactor ?? 1,
|
|
92
|
+
baseTexture: textureFor(pbr.baseColorTexture, true),
|
|
93
|
+
metalTexture: textureFor(pbr.metallicRoughnessTexture),
|
|
94
|
+
emissiveTexture: textureFor(material.emissiveTexture, true),
|
|
95
|
+
occlusionTexture: textureFor(material.occlusionTexture),
|
|
96
|
+
emissive: material.emissiveFactor || [0, 0, 0],
|
|
97
|
+
occlusionStrength: material.occlusionTexture?.strength ?? 1,
|
|
98
|
+
alphaMode: backend.options.alphaMode || material.alphaMode || 'OPAQUE',
|
|
99
|
+
alphaCutoff: material.alphaCutoff ?? 0.5,
|
|
100
|
+
doubleSided: material.doubleSided,
|
|
101
|
+
};
|
|
102
|
+
});
|
|
103
|
+
let nodes;
|
|
104
|
+
{
|
|
105
|
+
// Track only the recursion path: shared mesh references are valid, cycles are not.
|
|
106
|
+
const active = new Set(), resources = [];
|
|
107
|
+
const node = index => {
|
|
108
|
+
if (active.has(index)) throw new Error('Cyclic glTF nodes');
|
|
109
|
+
const spec = description.nodes[index];
|
|
110
|
+
if (!spec) throw new Error('Invalid glTF node');
|
|
111
|
+
active.add(index);
|
|
112
|
+
const group = {
|
|
113
|
+
...emptyNode(),
|
|
114
|
+
name: spec.name
|
|
115
|
+
};
|
|
116
|
+
group.matrix = nodeMatrix(spec);
|
|
117
|
+
if (spec.mesh !== undefined) {
|
|
118
|
+
for (const primitive of description.meshes[spec.mesh].primitives) {
|
|
119
|
+
const attributes = {};
|
|
120
|
+
for (const [semantic, name] of [['POSITION', 'position'], ['NORMAL', 'normal'], ['TEXCOORD_0', 'uv']]) {
|
|
121
|
+
if (primitive.attributes[semantic] !== undefined) attributes[name] = readAccessor(description, primitive.attributes[semantic]);
|
|
122
|
+
}
|
|
123
|
+
if (!attributes.position) throw new Error('glTF mesh has no positions');
|
|
124
|
+
const vertexCount = attributes.position.data.length / 3;
|
|
125
|
+
if (attributes.position.size !== 3 || vertexCount < 3 ||
|
|
126
|
+
Object.values(attributes).some(attribute => attribute.data.length / attribute.size !== vertexCount)) throw new Error('Invalid glTF vertex attributes');
|
|
127
|
+
if (primitive.indices !== undefined) {
|
|
128
|
+
const index = readAccessor(description, primitive.indices);
|
|
129
|
+
attributes.index = { size: 1, data: index.indices };
|
|
130
|
+
if (![Uint8Array, Uint16Array, Uint32Array].some(Type => index.indices instanceof Type) ||
|
|
131
|
+
index.size !== 1 || index.indices.length % 3 || [...index.indices].some(i => i >= vertexCount)) throw new Error('Invalid glTF triangle indices');
|
|
132
|
+
}
|
|
133
|
+
if (!attributes.index && vertexCount % 3) throw new Error('Incomplete glTF triangle');
|
|
134
|
+
if (!attributes.normal) {
|
|
135
|
+
const normals = vertexNormals(attributes.position.data, attributes.index?.data);
|
|
136
|
+
attributes.normal = { size: 3, data: normals };
|
|
137
|
+
}
|
|
138
|
+
const style = materials[primitive.material] || { color: [1, 1, 1], metallic: 1 };
|
|
139
|
+
if ([style.baseTexture, style.metalTexture, style.emissiveTexture, style.occlusionTexture].some(Boolean) && !attributes.uv) {
|
|
140
|
+
throw new Error('Textured model mesh requires UV coordinates');
|
|
141
|
+
}
|
|
142
|
+
const program = createProgram(backend, style);
|
|
143
|
+
resources.push(program);
|
|
144
|
+
const device = backend.renderer.device;
|
|
145
|
+
if (attributes.index?.data instanceof Uint8Array) {
|
|
146
|
+
attributes.index.data = Uint16Array.from(attributes.index.data);
|
|
147
|
+
}
|
|
148
|
+
for (const [name, attribute] of Object.entries(attributes)) {
|
|
149
|
+
attribute.size ||= 1;
|
|
150
|
+
attribute.count = attribute.data.length / attribute.size;
|
|
151
|
+
attribute.indexFormat = attribute.data instanceof Uint32Array ? 'uint32' : 'uint16';
|
|
152
|
+
attribute.buffer = device.createBuffer({
|
|
153
|
+
size: Math.max(4, attribute.data.byteLength),
|
|
154
|
+
usage: name === 'index'
|
|
155
|
+
? GPUBufferUsage.INDEX | GPUBufferUsage.COPY_DST
|
|
156
|
+
: GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_DST,
|
|
157
|
+
});
|
|
158
|
+
device.queue.writeBuffer(attribute.buffer, 0, attribute.data);
|
|
159
|
+
}
|
|
160
|
+
const geometry = {
|
|
161
|
+
device,
|
|
162
|
+
attributes,
|
|
163
|
+
drawRange: { start: 0, count: attributes.index?.count || attributes.position.count },
|
|
164
|
+
};
|
|
165
|
+
resources.push(geometry);
|
|
166
|
+
const mesh = {
|
|
167
|
+
...emptyNode(),
|
|
168
|
+
device,
|
|
169
|
+
geometry,
|
|
170
|
+
program,
|
|
171
|
+
fadeDuration: 250,
|
|
172
|
+
id: L.Layer._nextId++,
|
|
173
|
+
renderOrder: 0
|
|
174
|
+
};
|
|
175
|
+
mesh.name = description.meshes[spec.mesh].name; mesh.extras = spec.extras || {};
|
|
176
|
+
setParent(mesh, group);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
for (const child of spec.children || []) setParent(node(child), group);
|
|
180
|
+
active.delete(index);
|
|
181
|
+
return group;
|
|
182
|
+
};
|
|
183
|
+
const scene = description.scenes?.[description.scene || 0];
|
|
184
|
+
if (!scene) throw new Error('Missing glTF scene');
|
|
185
|
+
try {
|
|
186
|
+
nodes = scene.nodes.map(node);
|
|
187
|
+
} catch (error) {
|
|
188
|
+
// Parsing can fail after earlier primitives allocated buffers/programs.
|
|
189
|
+
for (const resource of resources) {
|
|
190
|
+
if (resource.attributes) {
|
|
191
|
+
for (const attribute of Object.values(resource.attributes)) attribute.buffer.destroy();
|
|
192
|
+
} else {
|
|
193
|
+
resource.pipelineCache.clear();
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
throw error;
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
const model = {
|
|
200
|
+
...emptyNode(),
|
|
201
|
+
id: url,
|
|
202
|
+
extras: description.extras || {},
|
|
203
|
+
};
|
|
204
|
+
if (!nodes.length) throw new Error('Expected a glTF model with a non-empty scene');
|
|
205
|
+
for (const node of nodes) setParent(node, model);
|
|
206
|
+
backend.model = model;
|
|
207
|
+
if (backend.options.rotation) {
|
|
208
|
+
const [x, y = x, z = x] = backend.options.rotation;
|
|
209
|
+
backend.model.rotation[0] = x; backend.model.rotation[1] = y; backend.model.rotation[2] = z;
|
|
210
|
+
}
|
|
211
|
+
if (backend.options.scale) {
|
|
212
|
+
const [x, y = x, z = x] = backend.options.scale;
|
|
213
|
+
backend.model.scale[0] = x; backend.model.scale[1] = y; backend.model.scale[2] = z;
|
|
214
|
+
}
|
|
215
|
+
setParent(backend.model, backend.root);
|
|
216
|
+
conformModelToTerrain(backend, backend._map?._terrain3D);
|
|
217
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { getZxy } from './getZxy.js';
|
|
2
|
+
|
|
3
|
+
export async function loadSource(backend, area) {
|
|
4
|
+
if (backend._geojson) {
|
|
5
|
+
const { data, url } = backend.options;
|
|
6
|
+
if (data !== undefined && url) throw new Error('GeoJSON source requires either data or url');
|
|
7
|
+
if (data !== undefined) return data;
|
|
8
|
+
if (!url) throw new Error('GeoJSON source requires either data or url');
|
|
9
|
+
const response = await fetch(new URL(url, document.baseURI), { signal: area.request.signal });
|
|
10
|
+
if (!response.ok) throw new Error(`Unable to load GeoJSON: HTTP ${response.status}`);
|
|
11
|
+
return response.json();
|
|
12
|
+
}
|
|
13
|
+
const result = await getZxy(backend, area.coords.z, area.coords.x, area.coords.y, area.request.signal);
|
|
14
|
+
return result
|
|
15
|
+
? JSON.parse(new TextDecoder().decode(result.data))
|
|
16
|
+
: { type: 'FeatureCollection', features: [] };
|
|
17
|
+
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { addBridges } from './addBridges.js';
|
|
2
|
+
import { conformModelToTerrain } from './conformModelToTerrain.js';
|
|
3
|
+
import { getElevation } from './getElevation.js';
|
|
4
|
+
import { setTerrainHeight } from './setTerrainHeight.js';
|
|
5
|
+
import { update } from './update.js';
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
export async function loadTerrain(backend) {
|
|
9
|
+
if (backend._terrainLoading || !backend._map) return;
|
|
10
|
+
backend._terrainLoading = true;
|
|
11
|
+
backend._terrainReady = false;
|
|
12
|
+
const controller = backend._terrainController = new AbortController();
|
|
13
|
+
try {
|
|
14
|
+
if (!backend.terrainSource) throw new Error('Terrain layer requires a PMTiles elevation archive');
|
|
15
|
+
const archive = backend._terrainArchive = new L.Layer({ source: { type: 'pmtiles', url: backend.terrainSource } });
|
|
16
|
+
await archive.ready;
|
|
17
|
+
const header = archive.header;
|
|
18
|
+
if (header.tileType !== 0 || header.minZoom !== header.maxZoom) {
|
|
19
|
+
throw new Error('Expected a single-zoom Float32 PMTiles terrain archive');
|
|
20
|
+
}
|
|
21
|
+
backend._terrainZoom = header.maxZoom;
|
|
22
|
+
const map = backend._map;
|
|
23
|
+
const northwest = map.project([header.maxLat, header.minLon], backend._terrainZoom).divideBy(256).floor();
|
|
24
|
+
const southeast = map.project([header.minLat, header.maxLon], backend._terrainZoom).divideBy(256).floor();
|
|
25
|
+
backend._terrainBounds = new L.Bounds(northwest, southeast);
|
|
26
|
+
const tiles = [];
|
|
27
|
+
for (let x = northwest.x; x <= southeast.x; x++) {
|
|
28
|
+
for (let y = northwest.y; y <= southeast.y; y++) tiles.push({ z: backend._terrainZoom, x, y });
|
|
29
|
+
}
|
|
30
|
+
const center = map.project(map.getCenter(), backend._terrainZoom).divideBy(256);
|
|
31
|
+
tiles.sort((a, b) => Math.hypot(a.x + 0.5 - center.x, a.y + 0.5 - center.y) -
|
|
32
|
+
Math.hypot(b.x + 0.5 - center.x, b.y + 0.5 - center.y));
|
|
33
|
+
let next = 0;
|
|
34
|
+
await Promise.all(Array.from({ length: Math.min(4, tiles.length) }, async () => {
|
|
35
|
+
while (next < tiles.length) {
|
|
36
|
+
controller.signal.throwIfAborted();
|
|
37
|
+
const coords = tiles[next++];
|
|
38
|
+
const result = await archive.getZxy(coords.z, coords.x, coords.y, controller.signal);
|
|
39
|
+
if (!result || result.data.byteLength !== 256 * 256 * 4) {
|
|
40
|
+
throw new Error(`Missing or invalid Float32 terrain tile ${coords.z}/${coords.x}/${coords.y}`);
|
|
41
|
+
}
|
|
42
|
+
backend._terrainTiles.set(`${coords.x}/${coords.y}`, new Float32Array(result.data));
|
|
43
|
+
}
|
|
44
|
+
}));
|
|
45
|
+
const bridges = backend.options.bridges && await fetch(backend.options.bridges, { signal: controller.signal })
|
|
46
|
+
.then(response => { if (!response.ok) throw new Error(`Bridges: HTTP ${response.status}`); return response.json(); });
|
|
47
|
+
if (controller.signal.aborted || backend._map !== map) return;
|
|
48
|
+
backend._terrainReady = true;
|
|
49
|
+
backend._terrainOriginElevation = getElevation(backend, backend.location) ?? 0;
|
|
50
|
+
for (const layer of Object.values(map._layers)) {
|
|
51
|
+
setTerrainHeight(layer);
|
|
52
|
+
conformModelToTerrain(layer, backend);
|
|
53
|
+
}
|
|
54
|
+
if (bridges) addBridges(backend, bridges);
|
|
55
|
+
map.fire('terrainchange');
|
|
56
|
+
update(backend);
|
|
57
|
+
backend.fire('terrainready');
|
|
58
|
+
return true;
|
|
59
|
+
} catch (error) {
|
|
60
|
+
if (!controller.signal.aborted) backend.fire('error', { error });
|
|
61
|
+
return false;
|
|
62
|
+
} finally {
|
|
63
|
+
backend._terrainLoading = false;
|
|
64
|
+
}
|
|
65
|
+
}
|