leaflet-city-mapper 0.0.1 → 0.0.3

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.
Files changed (629) hide show
  1. package/README.md +61 -13
  2. package/cucumber.mjs +4 -0
  3. package/dist/leaflet-city-mapper.js +3 -1
  4. package/dist/leaflet-city-mapper.js.map +4 -4
  5. package/package.json +3 -4
  6. package/src/archives/decodeDirectory.js +32 -0
  7. package/src/archives/decodeHeader.js +19 -0
  8. package/src/archives/decompress.js +5 -0
  9. package/src/archives/getHeader.js +9 -0
  10. package/src/archives/getZxy.js +75 -0
  11. package/src/archives/loadDirectory.js +7 -0
  12. package/src/archives/loadSource.js +17 -0
  13. package/src/archives/read.js +29 -0
  14. package/src/archives/tileId.js +19 -0
  15. package/src/archives/varint.js +15 -0
  16. package/src/camera/angles.js +6 -0
  17. package/src/camera/animationPoint.js +8 -0
  18. package/src/camera/cameraMapReady.js +8 -0
  19. package/src/camera/cancelCameraAnimation.js +11 -0
  20. package/src/camera/cleanupCameraMap.js +11 -0
  21. package/src/camera/constrainCameraToBounds.js +3 -0
  22. package/src/camera/displayPoint.js +3 -0
  23. package/src/camera/fitCameraBounds.js +48 -0
  24. package/src/camera/groundBounds.js +11 -0
  25. package/src/camera/initializeCameraMap.js +25 -0
  26. package/src/camera/mapAnimateCamera.js +17 -0
  27. package/src/camera/mapCamera.js +123 -0
  28. package/src/camera/mapContainerPointToLayerPoint.js +7 -0
  29. package/src/camera/mapGetBearing.js +1 -0
  30. package/src/camera/mapGetBounds.js +14 -0
  31. package/src/camera/mapGetBoundsCenterZoom.js +7 -0
  32. package/src/camera/mapGetBoundsZoom.js +14 -0
  33. package/src/camera/mapGetCenterLayerPoint.js +5 -0
  34. package/src/camera/mapGetPitch.js +1 -0
  35. package/src/camera/mapLayerPointToContainerPoint.js +7 -0
  36. package/src/camera/mapLimitCenter.js +12 -0
  37. package/src/camera/mapLimitOffset.js +10 -0
  38. package/src/camera/mapPanBy.js +9 -0
  39. package/src/camera/mapPanInside.js +14 -0
  40. package/src/camera/mapResetNorth.js +1 -0
  41. package/src/camera/mapResetNorthPitch.js +1 -0
  42. package/src/camera/mapSetBearing.js +1 -0
  43. package/src/camera/mapSetPitch.js +1 -0
  44. package/src/camera/mapSetPitchAndBearing.js +14 -0
  45. package/src/camera/mapSetZoomAround.js +11 -0
  46. package/src/camera/mapStopPitchBearingAnimation.js +6 -0
  47. package/src/camera/mapTryAnimatedPan.js +9 -0
  48. package/src/camera/mapUpdateCameraOverlays.js +7 -0
  49. package/src/camera/pointOf.js +3 -0
  50. package/src/camera/project.js +20 -0
  51. package/src/camera/runCameraAnimations.js +28 -0
  52. package/src/camera/scheduleCameraAnimation.js +8 -0
  53. package/src/camera/updateSky.js +16 -0
  54. package/src/camera/verticalGroundY.js +4 -0
  55. package/src/collision/collectMeshes.js +5 -0
  56. package/src/collision/collider.js +63 -0
  57. package/src/collision/horizontalRay.js +12 -0
  58. package/src/collision/intersectMeshes.js +133 -0
  59. package/src/collision/sortHits.js +23 -0
  60. package/src/constants/CELL.js +4 -0
  61. package/src/constants/Compass.js +7 -0
  62. package/src/constants/ContainerResize.js +7 -0
  63. package/src/constants/HEIGHT.js +1 -0
  64. package/src/constants/PitchDrag.js +7 -0
  65. package/src/constants/ShiftRotate.js +7 -0
  66. package/src/constants/TILE_RADIUS.js +1 -0
  67. package/src/constants/TILE_SIZE.js +1 -0
  68. package/src/constants/TouchMode.js +6 -0
  69. package/src/constants/accessorSizes.js +1 -0
  70. package/src/constants/accessorTypes.js +8 -0
  71. package/src/constants/attachState.js +1 -0
  72. package/src/constants/cameraControlsState.js +1 -0
  73. package/src/constants/cityMapper.js +6 -0
  74. package/src/constants/colliders.js +2 -0
  75. package/src/constants/dark.js +1 -0
  76. package/src/constants/elevationWGSL.js +27 -0
  77. package/src/constants/glass.js +1 -0
  78. package/src/constants/headlight.js +1 -0
  79. package/src/constants/hull.js +1 -0
  80. package/src/constants/indexState.js +1 -0
  81. package/src/constants/limbs.js +9 -0
  82. package/src/constants/mapCameraState.js +1 -0
  83. package/src/constants/moves.js +11 -0
  84. package/src/constants/nativeEventMaps.js +1 -0
  85. package/src/constants/nativeLayerState.js +1 -0
  86. package/src/constants/nativeMethodHandlers.js +31 -0
  87. package/src/constants/onMapChangeState.js +1 -0
  88. package/src/constants/onZoomAnimState.js +1 -0
  89. package/src/constants/paints.js +10 -0
  90. package/src/constants/parts.js +19 -0
  91. package/src/constants/pendingUpdates.js +1 -0
  92. package/src/constants/pumpState.js +1 -0
  93. package/src/constants/renderers.js +2 -0
  94. package/src/constants/ringDirections.js +10 -0
  95. package/src/constants/roundProfile.js +1 -0
  96. package/src/constants/shirt.js +1 -0
  97. package/src/constants/skin.js +2 -0
  98. package/src/constants/speed.js +3 -0
  99. package/src/constants/taillight.js +1 -0
  100. package/src/constants/trafficShader.js +49 -0
  101. package/src/constants/trousers.js +1 -0
  102. package/src/constants/tyre.js +1 -0
  103. package/src/constants/underEntryState.js +1 -0
  104. package/src/constants/vehicles.js +40 -0
  105. package/src/constants/white.js +1 -0
  106. package/src/controls/acceptPitchDrag.js +4 -0
  107. package/src/controls/acceptRotateDrag.js +3 -0
  108. package/src/controls/adjustCameraDrag.js +10 -0
  109. package/src/controls/cameraControls.js +60 -0
  110. package/src/controls/cameraDragClick.js +9 -0
  111. package/src/controls/cameraDragContextMenu.js +8 -0
  112. package/src/controls/cameraDragDown.js +20 -0
  113. package/src/controls/cameraDragEnd.js +6 -0
  114. package/src/controls/cameraDragMove.js +23 -0
  115. package/src/controls/changeCameraTouch.js +14 -0
  116. package/src/controls/cleanupCameraTouch.js +24 -0
  117. package/src/controls/compassAddHooks.js +15 -0
  118. package/src/controls/compassOrientation.js +6 -0
  119. package/src/controls/compassRemoveHooks.js +5 -0
  120. package/src/controls/containerResizeAddHooks.js +8 -0
  121. package/src/controls/containerResizeRemoveHooks.js +5 -0
  122. package/src/controls/dragCamera.js +22 -0
  123. package/src/controls/editable.js +3 -0
  124. package/src/controls/endAllCameraDrags.js +7 -0
  125. package/src/controls/endAllCameraTouches.js +7 -0
  126. package/src/controls/endCameraTouch.js +11 -0
  127. package/src/controls/endCameraTouchEvent.js +5 -0
  128. package/src/controls/finishCameraDrag.js +9 -0
  129. package/src/controls/finishCompassPermission.js +16 -0
  130. package/src/controls/loadCameraControls.js +9 -0
  131. package/src/controls/moveCameraTouch.js +22 -0
  132. package/src/controls/notifyCameraTouchChange.js +1 -0
  133. package/src/controls/pitchDragAddHooks.js +6 -0
  134. package/src/controls/pitchDragRemoveHooks.js +5 -0
  135. package/src/controls/refreshRotateControl.js +7 -0
  136. package/src/controls/refreshRotateFocus.js +5 -0
  137. package/src/controls/removeCameraDrag.js +23 -0
  138. package/src/controls/resizeMap.js +3 -0
  139. package/src/controls/rotateButtonClick.js +7 -0
  140. package/src/controls/rotateButtonKeydown.js +11 -0
  141. package/src/controls/rotateControl.js +3 -0
  142. package/src/controls/rotateOnAdd.js +38 -0
  143. package/src/controls/rotateOnRemove.js +6 -0
  144. package/src/controls/shiftRotateAddHooks.js +8 -0
  145. package/src/controls/shiftRotateRemoveHooks.js +5 -0
  146. package/src/controls/shiftRotateWheel.js +9 -0
  147. package/src/controls/startCameraTouch.js +23 -0
  148. package/src/core/addImageState.js +7 -0
  149. package/src/core/addRasterImage.js +10 -0
  150. package/src/core/adjustCameraMarkerPan.js +22 -0
  151. package/src/core/beforeNativeRender.js +10 -0
  152. package/src/core/boundsQuad.js +11 -0
  153. package/src/core/bringNativeLayerToBack.js +3 -0
  154. package/src/core/bringNativeLayerToFront.js +3 -0
  155. package/src/core/cameraCircleBounds.js +6 -0
  156. package/src/core/cameraMarkerDrag.js +18 -0
  157. package/src/core/cameraMarkerOnDrag.js +8 -0
  158. package/src/core/cancelGridFade.js +10 -0
  159. package/src/core/closestCameraLayerPoint.js +7 -0
  160. package/src/core/compareNativeHits.js +3 -0
  161. package/src/core/current.js +3 -0
  162. package/src/core/disposeNativeLayer.js +35 -0
  163. package/src/core/fireRasterLoad.js +5 -0
  164. package/src/core/forwardNativeError.js +3 -0
  165. package/src/core/gridlayerGetEvents.js +7 -0
  166. package/src/core/gridlayerGetTiledPixelBounds.js +8 -0
  167. package/src/core/handleNativeMapEvent.js +47 -0
  168. package/src/core/hideTargets.js +16 -0
  169. package/src/core/initNativeGPU.js +21 -0
  170. package/src/core/initializeGridContainer.js +6 -0
  171. package/src/core/initializeNativeLayer.js +42 -0
  172. package/src/core/localPixel.js +5 -0
  173. package/src/core/localPixelForGeometry.js +6 -0
  174. package/src/core/localPosition.js +6 -0
  175. package/src/core/markerCameraIconPoint.js +9 -0
  176. package/src/core/markerGetEvents.js +5 -0
  177. package/src/core/markerInitInteraction.js +8 -0
  178. package/src/core/markerQuadCorners.js +31 -0
  179. package/src/core/markerSetIcon.js +9 -0
  180. package/src/core/markerSetPos.js +14 -0
  181. package/src/core/markerSetRotation.js +7 -0
  182. package/src/core/markerUpdateZIndex.js +8 -0
  183. package/src/core/nativeAddLatLng.js +3 -0
  184. package/src/core/nativeBringToBack.js +3 -0
  185. package/src/core/nativeBringToFront.js +3 -0
  186. package/src/core/nativeEvents.js +26 -0
  187. package/src/core/nativeImageError.js +8 -0
  188. package/src/core/nativeImageRefresh.js +7 -0
  189. package/src/core/nativeLayer.js +97 -0
  190. package/src/core/nativeLayerMethod.js +21 -0
  191. package/src/core/nativeRedraw.js +3 -0
  192. package/src/core/nativeSetBounds.js +3 -0
  193. package/src/core/nativeSetIcon.js +3 -0
  194. package/src/core/nativeSetLatLng.js +3 -0
  195. package/src/core/nativeSetLatLngs.js +3 -0
  196. package/src/core/nativeSetOpacity.js +3 -0
  197. package/src/core/nativeSetRadius.js +3 -0
  198. package/src/core/nativeSetStyle.js +3 -0
  199. package/src/core/nativeSetUrl.js +3 -0
  200. package/src/core/nativeSetZIndex.js +3 -0
  201. package/src/core/nativeSetZIndexOffset.js +3 -0
  202. package/src/core/popupAdjustPan.js +23 -0
  203. package/src/core/popupGetEvents.js +5 -0
  204. package/src/core/popupUpdatePosition.js +14 -0
  205. package/src/core/putNativeMesh.js +33 -0
  206. package/src/core/quadNativeMesh.js +15 -0
  207. package/src/core/readyNativeGPU.js +6 -0
  208. package/src/core/refreshNativeEvent.js +5 -0
  209. package/src/core/refreshNativeLayer.js +29 -0
  210. package/src/core/refreshNativeLayerContract.js +3 -0
  211. package/src/core/rejectNativeReady.js +3 -0
  212. package/src/core/removeImageState.js +8 -0
  213. package/src/core/removeNativeEvents.js +16 -0
  214. package/src/core/removeTargets.js +8 -0
  215. package/src/core/reorderNativeLayer.js +6 -0
  216. package/src/core/resolveNativeReady.js +3 -0
  217. package/src/core/restoreNativeEvents.js +6 -0
  218. package/src/core/runGridFades.js +14 -0
  219. package/src/core/runMarkerPanFrame.js +12 -0
  220. package/src/core/scheduleGridFade.js +9 -0
  221. package/src/core/scheduleMarkerPan.js +8 -0
  222. package/src/core/styleNativeMesh.js +10 -0
  223. package/src/core/syncGridLayer.js +22 -0
  224. package/src/core/syncImageOverlay.js +9 -0
  225. package/src/core/syncMarker.js +12 -0
  226. package/src/core/syncVectorLayer.js +26 -0
  227. package/src/core/synchronizeNativeLayer.js +35 -0
  228. package/src/core/textureFor.js +48 -0
  229. package/src/core/tooltipGetEvents.js +5 -0
  230. package/src/core/tooltipSetPosition.js +8 -0
  231. package/src/core/updateGridOpacity.js +23 -0
  232. package/src/core/updateNativeLayerView.js +6 -0
  233. package/src/core/uploadCanvasTexture.js +19 -0
  234. package/src/geometry/addBridges.js +88 -0
  235. package/src/geometry/below.js +3 -0
  236. package/src/geometry/box.js +3 -0
  237. package/src/geometry/bridgeElevation.js +19 -0
  238. package/src/geometry/bridgeLocal.js +4 -0
  239. package/src/geometry/build.js +19 -0
  240. package/src/geometry/circleAt.js +5 -0
  241. package/src/geometry/clipLine.js +23 -0
  242. package/src/geometry/clipSegment.js +19 -0
  243. package/src/geometry/computeBounds.js +33 -0
  244. package/src/geometry/conformModelToTerrain.js +67 -0
  245. package/src/geometry/cross.js +3 -0
  246. package/src/geometry/disk.js +11 -0
  247. package/src/geometry/diskAt.js +4 -0
  248. package/src/geometry/dot.js +6 -0
  249. package/src/geometry/emitter.js +8 -0
  250. package/src/geometry/lampPostGeometry.js +24 -0
  251. package/src/geometry/lampRing.js +11 -0
  252. package/src/geometry/lightGeometry.js +15 -0
  253. package/src/geometry/line.js +54 -0
  254. package/src/geometry/nativeGeometry.js +55 -0
  255. package/src/geometry/nativeTriangle.js +3 -0
  256. package/src/geometry/polygon.js +22 -0
  257. package/src/geometry/push.js +3 -0
  258. package/src/geometry/quad.js +4 -0
  259. package/src/geometry/roofCoverage.js +52 -0
  260. package/src/geometry/samePoint.js +3 -0
  261. package/src/geometry/segment.js +21 -0
  262. package/src/geometry/setVertexColor.js +15 -0
  263. package/src/geometry/sub.js +6 -0
  264. package/src/geometry/surface.js +17 -0
  265. package/src/geometry/treeGeometry.js +31 -0
  266. package/src/geometry/treeRing.js +14 -0
  267. package/src/geometry/triangle.js +12 -0
  268. package/src/geometry/vertexNormals.js +32 -0
  269. package/src/geometry/visit.js +9 -0
  270. package/src/index.js +98 -65
  271. package/src/lighting/cacheLightGrid.js +23 -0
  272. package/src/lighting/collectLightMeshes.js +6 -0
  273. package/src/lighting/lightGrid.js +42 -0
  274. package/src/lighting/updatePointLights.js +34 -0
  275. package/src/lighting/visitCells.js +15 -0
  276. package/src/lighting/worldLights.js +27 -0
  277. package/src/models/decodeModel.js +45 -0
  278. package/src/models/hasUnsupportedPrimitives.js +10 -0
  279. package/src/models/loadBuffer.js +6 -0
  280. package/src/models/loadImage.js +15 -0
  281. package/src/models/loadModel.js +69 -0
  282. package/src/models/materialFor.js +21 -0
  283. package/src/models/modelNode.js +93 -0
  284. package/src/models/nodeMatrix.js +22 -0
  285. package/src/models/readAccessor.js +53 -0
  286. package/src/models/readAccessorValues.js +16 -0
  287. package/src/models/textureFor.js +35 -0
  288. package/src/models/textureSampler.js +10 -0
  289. package/src/picking/collectVisibleMesh.js +4 -0
  290. package/src/picking/findFeature.js +49 -0
  291. package/src/picking/hit.js +23 -0
  292. package/src/picking/hitMesh.js +30 -0
  293. package/src/picking/onClick.js +13 -0
  294. package/src/picking/onPointerLeave.js +11 -0
  295. package/src/picking/onPointerMove.js +15 -0
  296. package/src/picking/pointerClick.js +5 -0
  297. package/src/picking/pointerLeave.js +5 -0
  298. package/src/picking/pointerMove.js +5 -0
  299. package/src/picking/raycast.js +59 -0
  300. package/src/picking/setHighlight.js +13 -0
  301. package/src/picking/shouldSkipOther.js +3 -0
  302. package/src/picking/showFeature.js +34 -0
  303. package/src/raster/addRasterTile.js +114 -0
  304. package/src/raster/comparePendingTiles.js +5 -0
  305. package/src/raster/createGeometry.js +22 -0
  306. package/src/raster/createRasterMesh.js +47 -0
  307. package/src/raster/finishAttachment.js +11 -0
  308. package/src/raster/finishRasterTile.js +47 -0
  309. package/src/raster/getRasterEvents.js +6 -0
  310. package/src/raster/getRasterTileSize.js +5 -0
  311. package/src/raster/initRaster.js +38 -0
  312. package/src/raster/isLoading.js +5 -0
  313. package/src/raster/loadRasterTile.js +10 -0
  314. package/src/raster/onPMTileAdd.js +10 -0
  315. package/src/raster/onPMTileRemove.js +8 -0
  316. package/src/raster/pruneRasterTiles.js +37 -0
  317. package/src/raster/pumpRasterTiles.js +22 -0
  318. package/src/raster/readyRaster.js +13 -0
  319. package/src/raster/registerTerrainTile.js +12 -0
  320. package/src/raster/releaseRasterTile.js +18 -0
  321. package/src/raster/releaseRasterTiles.js +15 -0
  322. package/src/raster/removeRasterTile.js +13 -0
  323. package/src/raster/reportError.js +6 -0
  324. package/src/raster/setPMTileOpacity.js +7 -0
  325. package/src/raster/setPMTileZIndex.js +7 -0
  326. package/src/raster/setRasterOpacity.js +11 -0
  327. package/src/raster/setRasterTerrain.js +21 -0
  328. package/src/raster/setRasterZIndex.js +11 -0
  329. package/src/raster/updateAttachedTiles.js +10 -0
  330. package/src/raster/updateRasterTiles.js +59 -0
  331. package/src/rendering/collectFrameMeshes.js +31 -0
  332. package/src/rendering/collectMeshes.js +36 -0
  333. package/src/rendering/compareMeshes.js +10 -0
  334. package/src/rendering/compareRoofTiles.js +4 -0
  335. package/src/rendering/composeRoofAtlas.js +52 -0
  336. package/src/rendering/createMesh.js +33 -0
  337. package/src/rendering/createProgram.js +92 -0
  338. package/src/rendering/destroyAfterSubmission.js +8 -0
  339. package/src/rendering/destroyTexture.js +6 -0
  340. package/src/rendering/disposeMesh.js +14 -0
  341. package/src/rendering/drawGeometry.js +129 -0
  342. package/src/rendering/drawSceneMeshes.js +51 -0
  343. package/src/rendering/ensureRoofBlit.js +40 -0
  344. package/src/rendering/prepareFrameMeshes.js +42 -0
  345. package/src/rendering/prepareFrameUniforms.js +49 -0
  346. package/src/rendering/rebuildRoofAtlas.js +67 -0
  347. package/src/rendering/render.js +57 -0
  348. package/src/rendering/reportCompilation.js +17 -0
  349. package/src/rendering/resizeRenderer.js +19 -0
  350. package/src/rendering/sortMeshes.js +6 -0
  351. package/src/rendering/synchronizeZoomView.js +34 -0
  352. package/src/rendering/textureBinding.js +7 -0
  353. package/src/rendering/updateMapCamera.js +32 -0
  354. package/src/rendering/updateRoofRaster.js +32 -0
  355. package/src/scene/attach.js +161 -0
  356. package/src/scene/attachLayer.js +10 -0
  357. package/src/scene/cancelUpdate.js +10 -0
  358. package/src/scene/emptyEvents.js +3 -0
  359. package/src/scene/emptyNode.js +11 -0
  360. package/src/scene/endZoom.js +16 -0
  361. package/src/scene/failAttachment.js +9 -0
  362. package/src/scene/get3DEvents.js +13 -0
  363. package/src/scene/init3D.js +30 -0
  364. package/src/scene/initializeLayer.js +16 -0
  365. package/src/scene/initializerFor.js +14 -0
  366. package/src/scene/layerInitialize.js +38 -0
  367. package/src/scene/layerLayerAdd.js +21 -0
  368. package/src/scene/onAdd3DLayer.js +35 -0
  369. package/src/scene/onMapChange.js +16 -0
  370. package/src/scene/onRemove3DLayer.js +69 -0
  371. package/src/scene/onZoomAnim.js +16 -0
  372. package/src/scene/placeEntry.js +11 -0
  373. package/src/scene/placeUnderEntry.js +8 -0
  374. package/src/scene/ready3D.js +25 -0
  375. package/src/scene/releaseRenderer.js +14 -0
  376. package/src/scene/removeEntry.js +6 -0
  377. package/src/scene/renderPendingMapChange.js +11 -0
  378. package/src/scene/renderPendingUpdates.js +19 -0
  379. package/src/scene/renderPendingZoomAnimation.js +7 -0
  380. package/src/scene/rendererDeviceError.js +10 -0
  381. package/src/scene/rendererDeviceLost.js +11 -0
  382. package/src/scene/replaceEntry.js +7 -0
  383. package/src/scene/reportError.js +3 -0
  384. package/src/scene/requestAdapter.js +12 -0
  385. package/src/scene/requestDevice.js +9 -0
  386. package/src/scene/resolveNextInitialization.js +12 -0
  387. package/src/scene/restoreObject.js +71 -0
  388. package/src/scene/runPlacements.js +7 -0
  389. package/src/scene/setParent.js +7 -0
  390. package/src/scene/showWebGPUWarning.js +16 -0
  391. package/src/scene/startZoom.js +5 -0
  392. package/src/scene/traverse.js +7 -0
  393. package/src/scene/underEntry.js +17 -0
  394. package/src/scene/update.js +19 -0
  395. package/src/scene/updateCamera.js +34 -0
  396. package/src/scene/updateWorldMatrix.js +48 -0
  397. package/src/{utils/shaders.js → shaders/materialShaders.js} +246 -237
  398. package/src/shadows/bindSunlight.js +12 -0
  399. package/src/shadows/drawShadowMeshes.js +48 -0
  400. package/src/shadows/ensureShadowPipeline.js +53 -0
  401. package/src/shadows/renderSunlight.js +46 -0
  402. package/src/shadows/resizeSunlight.js +15 -0
  403. package/src/shadows/shadowBounds.js +32 -0
  404. package/src/shadows/shadowCacheMatches.js +23 -0
  405. package/src/shadows/shadowMatrix.js +39 -0
  406. package/src/sources/addGeneratedTriangle.js +6 -0
  407. package/src/sources/addTriangle.js +17 -0
  408. package/src/sources/attachAreaMesh.js +58 -0
  409. package/src/sources/buildArea.js +42 -0
  410. package/src/sources/buildAreaFeature.js +41 -0
  411. package/src/sources/buildAreaPoint.js +25 -0
  412. package/src/sources/buildAreaPolygon.js +29 -0
  413. package/src/sources/compareAreaDistance.js +4 -0
  414. package/src/sources/generateTreeGeometry.js +11 -0
  415. package/src/sources/groundOffset.js +3 -0
  416. package/src/sources/initializeGeoJSON.js +8 -0
  417. package/src/sources/instanceAreaGeometry.js +29 -0
  418. package/src/sources/projectRing.js +20 -0
  419. package/src/sources/projectedTree.js +13 -0
  420. package/src/sources/pump.js +54 -0
  421. package/src/sources/releaseArea.js +22 -0
  422. package/src/sources/setGeoJSONData.js +12 -0
  423. package/src/sources/setGeoJSONLayerData.js +5 -0
  424. package/src/sources/sourceAreaContext.js +9 -0
  425. package/src/sources/updateArea.js +45 -0
  426. package/src/sources/updateStatus.js +12 -0
  427. package/src/sunlight/addTimeLayer.js +3 -0
  428. package/src/sunlight/addTo.js +10 -0
  429. package/src/sunlight/atmosphere.js +28 -0
  430. package/src/sunlight/horizontalPosition.js +16 -0
  431. package/src/sunlight/initSunlight.js +14 -0
  432. package/src/sunlight/initialize.js +11 -0
  433. package/src/sunlight/mix.js +6 -0
  434. package/src/sunlight/moonPosition.js +17 -0
  435. package/src/sunlight/onAdd.js +5 -0
  436. package/src/sunlight/onAddSun.js +66 -0
  437. package/src/sunlight/projectCelestialBody.js +13 -0
  438. package/src/sunlight/remove.js +7 -0
  439. package/src/sunlight/removeSun.js +15 -0
  440. package/src/sunlight/removeTimeLayer.js +3 -0
  441. package/src/sunlight/render.js +7 -0
  442. package/src/sunlight/rgb.js +6 -0
  443. package/src/sunlight/solarPosition.js +17 -0
  444. package/src/sunlight/styleTimeControl.js +7 -0
  445. package/src/sunlight/tickSun.js +5 -0
  446. package/src/sunlight/updateSky.js +20 -0
  447. package/src/sunlight/updateSun.js +34 -0
  448. package/src/sunlight/useLiveTime.js +6 -0
  449. package/src/sunlight/useSelectedTime.js +20 -0
  450. package/src/terrain/clearLayerTerrain.js +5 -0
  451. package/src/terrain/getElevation.js +10 -0
  452. package/src/terrain/initTerrain.js +20 -0
  453. package/src/terrain/loadReadyTerrain.js +5 -0
  454. package/src/terrain/loadTerrain.js +63 -0
  455. package/src/terrain/loadTerrainTiles.js +13 -0
  456. package/src/terrain/onTerrainAdd.js +21 -0
  457. package/src/terrain/onTerrainChange.js +14 -0
  458. package/src/terrain/onTerrainRemove.js +41 -0
  459. package/src/terrain/readBridges.js +4 -0
  460. package/src/terrain/sample.js +7 -0
  461. package/src/terrain/setLayerTerrain.js +5 -0
  462. package/src/terrain/setTerrainHeight.js +10 -0
  463. package/src/terrain/terrainAtlas.js +23 -0
  464. package/src/terrain/terrainElevation.js +20 -0
  465. package/src/terrain/terrainGrid.js +24 -0
  466. package/src/traffic/addTraffic.js +7 -0
  467. package/src/traffic/along.js +14 -0
  468. package/src/traffic/clockMinutes.js +6 -0
  469. package/src/traffic/compareDepartures.js +5 -0
  470. package/src/traffic/createTrafficMesh.js +7 -0
  471. package/src/traffic/destroyTrafficGpu.js +5 -0
  472. package/src/traffic/disposeTrafficObject.js +13 -0
  473. package/src/traffic/drawTrafficRoute.js +6 -0
  474. package/src/traffic/failTraffic.js +6 -0
  475. package/src/traffic/failedTrafficLoad.js +5 -0
  476. package/src/traffic/fetchTrafficLanes.js +10 -0
  477. package/src/traffic/groundTraffic.js +15 -0
  478. package/src/traffic/initTraffic.js +54 -0
  479. package/src/traffic/loadTraffic.js +15 -0
  480. package/src/traffic/loadedTrafficLanes.js +16 -0
  481. package/src/traffic/locateTraffic.js +9 -0
  482. package/src/traffic/moveTraffic.js +15 -0
  483. package/src/traffic/placeTraffic.js +21 -0
  484. package/src/traffic/prepareTraffic.js +25 -0
  485. package/src/traffic/readyTraffic.js +6 -0
  486. package/src/traffic/rebaseTraffic.js +58 -0
  487. package/src/traffic/rebuildTrafficMesh.js +28 -0
  488. package/src/traffic/removeTraffic.js +17 -0
  489. package/src/traffic/routeColor.js +6 -0
  490. package/src/traffic/routeGeometry.js +31 -0
  491. package/src/traffic/scheduledTrips.js +40 -0
  492. package/src/traffic/startTraffic.js +8 -0
  493. package/src/traffic/tickTraffic.js +57 -0
  494. package/src/traffic/toLanes.js +16 -0
  495. package/src/traffic/tooltip.js +11 -0
  496. package/src/traffic/trafficBounds.js +17 -0
  497. package/src/traffic/trafficNow.js +4 -0
  498. package/src/traffic/trafficStorage.js +5 -0
  499. package/src/traffic/tripsAt.js +27 -0
  500. package/src/traffic/updateTraffic.js +8 -0
  501. package/src/traffic/updateTrafficTerrain.js +12 -0
  502. package/src/traffic/vehicleOffsets.js +11 -0
  503. package/src/triangulation/area.js +9 -0
  504. package/src/triangulation/clean.js +18 -0
  505. package/src/triangulation/containsVertex.js +11 -0
  506. package/src/triangulation/cross.js +3 -0
  507. package/src/triangulation/crossesBoundary.js +8 -0
  508. package/src/triangulation/crossesRing.js +9 -0
  509. package/src/triangulation/equal.js +3 -0
  510. package/src/triangulation/inside.js +10 -0
  511. package/src/triangulation/insideHole.js +7 -0
  512. package/src/triangulation/intersects.js +11 -0
  513. package/src/triangulation/isClockWise.js +13 -0
  514. package/src/triangulation/minimumX.js +6 -0
  515. package/src/triangulation/on.js +4 -0
  516. package/src/triangulation/sortHoles.js +26 -0
  517. package/src/triangulation/triangulate.js +86 -0
  518. package/src/utils/channel.js +4 -0
  519. package/src/utils/compareDistance.js +3 -0
  520. package/src/utils/noOperation.js +1 -0
  521. package/src/utils/parseColor.js +42 -0
  522. package/src/utils/toSRGB.js +3 -0
  523. package/src/utils/wrap.js +3 -0
  524. package/src/vehicles/bicycleModel.js +23 -0
  525. package/src/vehicles/boatBenches.js +8 -0
  526. package/src/vehicles/boatModel.js +27 -0
  527. package/src/vehicles/busModel.js +6 -0
  528. package/src/vehicles/carModel.js +22 -0
  529. package/src/vehicles/carriage.js +19 -0
  530. package/src/vehicles/metroModel.js +9 -0
  531. package/src/vehicles/mirror.js +8 -0
  532. package/src/vehicles/pedestrianModel.js +17 -0
  533. package/src/vehicles/tramModel.js +9 -0
  534. package/src/walk/blocked.js +6 -0
  535. package/src/walk/createWalk.js +60 -0
  536. package/src/walk/initWalk.js +18 -0
  537. package/src/walk/initialize.js +6 -0
  538. package/src/walk/local.js +10 -0
  539. package/src/walk/onAdd.js +4 -0
  540. package/src/walk/onBlur.js +3 -0
  541. package/src/walk/onKey.js +12 -0
  542. package/src/walk/onPointer.js +13 -0
  543. package/src/walk/onRemove.js +4 -0
  544. package/src/walk/onTerrain.js +5 -0
  545. package/src/walk/place.js +18 -0
  546. package/src/walk/start.js +37 -0
  547. package/src/walk/step.js +53 -0
  548. package/src/walk/stop.js +27 -0
  549. package/src/walk/toggle.js +6 -0
  550. package/dist/scene/gpu.js +0 -3
  551. package/dist/scene/gpu.js.map +0 -7
  552. package/dist/scene/lighting.js +0 -9
  553. package/dist/scene/lighting.js.map +0 -7
  554. package/dist/scene/model.js +0 -2
  555. package/dist/scene/model.js.map +0 -7
  556. package/dist/scene/picking.js +0 -2
  557. package/dist/scene/picking.js.map +0 -7
  558. package/dist/scene/pmtiles.js +0 -2
  559. package/dist/scene/pmtiles.js.map +0 -7
  560. package/dist/scene/render.js +0 -15
  561. package/dist/scene/render.js.map +0 -7
  562. package/dist/scene/sources.js +0 -2
  563. package/dist/scene/sources.js.map +0 -7
  564. package/dist/types/3d.js +0 -2
  565. package/dist/types/3d.js.map +0 -7
  566. package/dist/types/geojson.js +0 -2
  567. package/dist/types/geojson.js.map +0 -7
  568. package/dist/types/pmtiles.js +0 -2
  569. package/dist/types/pmtiles.js.map +0 -7
  570. package/dist/types/sunlight.js +0 -2
  571. package/dist/types/sunlight.js.map +0 -7
  572. package/dist/types/terrain.js +0 -24
  573. package/dist/types/terrain.js.map +0 -7
  574. package/dist/types/traffic.js +0 -41
  575. package/dist/types/traffic.js.map +0 -7
  576. package/dist/types/walk.js +0 -2
  577. package/dist/types/walk.js.map +0 -7
  578. package/dist/utils/control.js +0 -2
  579. package/dist/utils/control.js.map +0 -7
  580. package/dist/utils/geometry.js +0 -2
  581. package/dist/utils/geometry.js.map +0 -7
  582. package/dist/utils/lighting.js +0 -2
  583. package/dist/utils/lighting.js.map +0 -7
  584. package/dist/utils/model.js +0 -2
  585. package/dist/utils/model.js.map +0 -7
  586. package/dist/utils/picking.js +0 -2
  587. package/dist/utils/picking.js.map +0 -7
  588. package/dist/utils/pmtiles.js +0 -2
  589. package/dist/utils/pmtiles.js.map +0 -7
  590. package/dist/utils/scene.js +0 -2
  591. package/dist/utils/scene.js.map +0 -7
  592. package/dist/utils/shaders.js +0 -203
  593. package/dist/utils/shaders.js.map +0 -7
  594. package/dist/utils/sun.js +0 -2
  595. package/dist/utils/sun.js.map +0 -7
  596. package/dist/utils/terrain.js +0 -2
  597. package/dist/utils/terrain.js.map +0 -7
  598. package/dist/utils/traffic.js +0 -2
  599. package/dist/utils/traffic.js.map +0 -7
  600. package/dist/utils/vehicles.js +0 -2
  601. package/dist/utils/vehicles.js.map +0 -7
  602. package/dist/utils/walk.js +0 -2
  603. package/dist/utils/walk.js.map +0 -7
  604. package/src/scene/gpu.js +0 -438
  605. package/src/scene/lighting.js +0 -193
  606. package/src/scene/model.js +0 -204
  607. package/src/scene/picking.js +0 -150
  608. package/src/scene/pmtiles.js +0 -94
  609. package/src/scene/render.js +0 -467
  610. package/src/scene/sources.js +0 -265
  611. package/src/types/3d.js +0 -337
  612. package/src/types/geojson.js +0 -42
  613. package/src/types/pmtiles.js +0 -143
  614. package/src/types/sunlight.js +0 -142
  615. package/src/types/terrain.js +0 -331
  616. package/src/types/traffic.js +0 -356
  617. package/src/types/walk.js +0 -219
  618. package/src/utils/control.js +0 -18
  619. package/src/utils/geometry.js +0 -256
  620. package/src/utils/lighting.js +0 -51
  621. package/src/utils/model.js +0 -178
  622. package/src/utils/picking.js +0 -119
  623. package/src/utils/pmtiles.js +0 -79
  624. package/src/utils/scene.js +0 -102
  625. package/src/utils/sun.js +0 -71
  626. package/src/utils/terrain.js +0 -78
  627. package/src/utils/traffic.js +0 -90
  628. package/src/utils/vehicles.js +0 -69
  629. package/src/utils/walk.js +0 -72
@@ -0,0 +1,4 @@
1
+ export function quad(addTriangle, color, a, b, c, d, height, normal) {
2
+ addTriangle(a, height, b, height, c, height, ...normal, color);
3
+ addTriangle(a, height, c, height, d, height, ...normal, color);
4
+ }
@@ -0,0 +1,52 @@
1
+ /** Test the mesh's ground footprint against loaded imagery, including coarse parent tiles. */
2
+ export function roofCoverage(mesh, backend, rasters) {
3
+ const map = backend._map, bounds = mesh.geometry.bounds, world = mesh.worldMatrix;
4
+ let intersectsArchive = false;
5
+ let layer, zoom, origin, scale, min, max, i, x, y, z, px, py, nw, se, remaining, tile, size, left;
6
+ let top, pieces, x0, y0, x1, y1, l, t, r, b;
7
+ for (layer of rasters) {
8
+ zoom = layer._tileZoom, origin = map.project(backend._sceneOrigin, zoom);
9
+ scale = map.options.crs.scale(zoom) / (40075016.68557849 * Math.cos(backend._sceneOrigin.lat * Math.PI / 180));
10
+ min = [Infinity, Infinity], max = [-Infinity, -Infinity];
11
+ for (i = 0; i < 8; i++) {
12
+ x = i & 1 ? bounds.max[0] : bounds.min[0], y = i & 2 ? bounds.max[1] : bounds.min[1];
13
+ z = i & 4 ? bounds.max[2] : bounds.min[2];
14
+ px = origin.x + (world[0] * x + world[4] * y + world[8] * z + world[12]) * scale;
15
+ py = origin.y + (world[2] * x + world[6] * y + world[10] * z + world[14]) * scale;
16
+ min[0] = Math.min(min[0], px); min[1] = Math.min(min[1], py);
17
+ max[0] = Math.max(max[0], px); max[1] = Math.max(max[1], py);
18
+ }
19
+ if (layer.header.maxLat !== undefined && layer.header.minLon !== undefined &&
20
+ layer.header.minLat !== undefined && layer.header.maxLon !== undefined) {
21
+ nw = map.project([layer.header.maxLat, layer.header.minLon], zoom);
22
+ se = map.project([layer.header.minLat, layer.header.maxLon], zoom);
23
+ min[0] = Math.max(min[0], nw.x); min[1] = Math.max(min[1], nw.y);
24
+ max[0] = Math.min(max[0], se.x); max[1] = Math.min(max[1], se.y);
25
+ if (min[0] >= max[0] || min[1] >= max[1]) continue;
26
+ }
27
+ intersectsArchive = true;
28
+ remaining = [[min[0], min[1], max[0], max[1]]];
29
+ for (tile of layer._rasterTiles.values()) {
30
+ // Failed imagery already reports an error; do not hide the building indefinitely.
31
+ if (!tile.done && !tile.error) continue;
32
+ size = 256 * 2 ** (zoom - tile.coords.z);
33
+ left = tile.coords.x * size, top = tile.coords.y * size;
34
+ pieces = [];
35
+ for ([x0, y0, x1, y1] of remaining) {
36
+ l = Math.max(x0, left), t = Math.max(y0, top);
37
+ r = Math.min(x1, left + size), b = Math.min(y1, top + size);
38
+ if (l >= r || t >= b) {
39
+ pieces.push([x0, y0, x1, y1]);
40
+ continue;
41
+ }
42
+ if (y0 < t) pieces.push([x0, y0, x1, t]);
43
+ if (b < y1) pieces.push([x0, b, x1, y1]);
44
+ if (x0 < l) pieces.push([x0, t, l, b]);
45
+ if (r < x1) pieces.push([r, t, x1, b]);
46
+ }
47
+ remaining = pieces;
48
+ if (!remaining.length) return true;
49
+ }
50
+ }
51
+ return !intersectsArchive;
52
+ }
@@ -0,0 +1,3 @@
1
+ export function samePoint(a, b) {
2
+ return Math.abs(a[0] - b[0]) < 1e-10 && Math.abs(a[1] - b[1]) < 1e-10;
3
+ }
@@ -0,0 +1,21 @@
1
+ import { triangle } from './nativeTriangle.js';
2
+ import { disk } from './disk.js';
3
+
4
+ export function segment(context, a, b, startCap, endCap) {
5
+ const { options, width, stroke, point } = context;
6
+ const radius = width / 2;
7
+ const length = a.distanceTo(b);
8
+ if (!length) return;
9
+ const direction = b.subtract(a).divideBy(length);
10
+ const normal = new L.Point(-direction.y * radius, direction.x * radius);
11
+ if (options.lineCap === 'square') {
12
+ if (startCap) a = a.subtract(direction.multiplyBy(radius));
13
+ if (endCap) b = b.add(direction.multiplyBy(radius));
14
+ }
15
+ triangle(point, stroke, a.add(normal), a.subtract(normal), b.add(normal));
16
+ triangle(point, stroke, b.add(normal), a.subtract(normal), b.subtract(normal));
17
+ if (options.lineCap === 'round') {
18
+ if (startCap) disk(point, a, radius, stroke);
19
+ if (endCap) disk(point, b, radius, stroke);
20
+ }
21
+ }
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Paints the vertices `[start, end)` of a mesh and marks its color buffer dirty.
3
+ * @param {Object} mesh Layer-created mesh with a color attribute.
4
+ * @param {number} start Inclusive vertex index, not an offset into the RGB array.
5
+ * @param {number} end Exclusive vertex index.
6
+ * @param {Object} color sRGB {r,g,b}, typically from parseColor().
7
+ */
8
+
9
+ export function setVertexColor(mesh, start, end, color) {
10
+ let i;
11
+ for (i = start; i < end; i++) {
12
+ mesh.geometry.attributes.color.data.set([color.r, color.g, color.b], i * 3);
13
+ }
14
+ mesh.geometry.attributes.color.needsUpdate = true;
15
+ }
@@ -0,0 +1,6 @@
1
+ export function sub(a, b) {
2
+ const result = [];
3
+ let i;
4
+ for (i = 0; i < a.length; i++) result.push(a[i] - b[i]);
5
+ return result;
6
+ }
@@ -0,0 +1,17 @@
1
+ import { ring } from './treeRing.js';
2
+ import { ringDirections } from '../constants/ringDirections.js';
3
+
4
+ export function surface(point, addTriangle, lowRadius, low, highRadius, high, color) {
5
+ const lower = ring(point, lowRadius), upper = ring(point, highRadius);
6
+ let i, next, slope, length, nx, nz, ny, normalX, normalZ;
7
+ for (i = 0; i < 8; i++) {
8
+ next = (i + 1) % 8;
9
+ slope = (lowRadius - highRadius) / (high - low);
10
+ length = Math.hypot(1, slope);
11
+ ({ nx, nz } = ringDirections[i]);
12
+ ny = slope / length;
13
+ normalX = nx / length, normalZ = nz / length;
14
+ if (lowRadius) addTriangle(lower[i], low, lower[next], low, upper[next], high, normalX, ny, normalZ, color);
15
+ if (highRadius) addTriangle(lower[i], low, upper[next], high, upper[i], high, normalX, ny, normalZ, color);
16
+ }
17
+ }
@@ -0,0 +1,31 @@
1
+ import { roundProfile } from '../constants/roundProfile.js';
2
+ import { parseColor } from "../utils/parseColor.js";
3
+ import { ring } from './treeRing.js';
4
+ import { surface } from './surface.js';
5
+
6
+ /** Low-poly tree, sharing the source block's buffers, picking and terrain offset. */
7
+
8
+ export function treeGeometry(point, style, addTriangle) {
9
+ const { top, bottom = 0, trunkRadius, crownRadius, crownBottom, crownShape = 'round' } = style;
10
+ if (!Number.isFinite(trunkRadius) || !Number.isFinite(crownRadius) || !Number.isFinite(crownBottom) ||
11
+ trunkRadius <= 0 || crownRadius < trunkRadius || crownBottom <= bottom || crownBottom >= top ||
12
+ !['round', 'cone'].includes(crownShape)) {
13
+ throw new Error('Invalid tree dimensions or crown shape');
14
+ }
15
+ const trunk = parseColor(style.trunkColor ?? 0x72513a);
16
+ const crown = parseColor(style.color ?? 0x4f823b);
17
+ surface(point, addTriangle, trunkRadius, bottom, trunkRadius, crownBottom + (top - crownBottom) * 0.25, trunk);
18
+ let i, low, lr, high, hr;
19
+ if (crownShape === 'cone') {
20
+ const base = ring(point, crownRadius);
21
+ for (i = 0; i < 8; i++) addTriangle(point, crownBottom, base[i], crownBottom,
22
+ base[(i + 1) % 8], crownBottom, 0, -1, 0, crown);
23
+ surface(point, addTriangle, crownRadius, crownBottom, 0, top, crown);
24
+ } else {
25
+ for (i = 1; i < roundProfile.length; i++) {
26
+ [low, lr] = roundProfile[i - 1], [high, hr] = roundProfile[i];
27
+ surface(point, addTriangle, lr * crownRadius, crownBottom + low * (top - crownBottom),
28
+ hr * crownRadius, crownBottom + high * (top - crownBottom), crown);
29
+ }
30
+ }
31
+ }
@@ -0,0 +1,14 @@
1
+ import { ringDirections } from '../constants/ringDirections.js';
2
+
3
+ export function ring(point, radius) {
4
+ const result = [];
5
+ let direction;
6
+ for (direction of ringDirections) {
7
+ result.push({
8
+ x: point.x + direction.x * radius,
9
+ y: point.y + direction.y * radius,
10
+ ground: point.ground,
11
+ });
12
+ }
13
+ return result;
14
+ }
@@ -0,0 +1,12 @@
1
+ export function triangle(position, normal, color, a, b, c, tint) {
2
+ const u = [], v = [];
3
+ let i, point, value;
4
+ for (i = 0; i < b.length; i++) u.push(b[i] - a[i]);
5
+ for (i = 0; i < c.length; i++) v.push(c[i] - a[i]);
6
+ const n = [u[1] * v[2] - u[2] * v[1], u[2] * v[0] - u[0] * v[2], u[0] * v[1] - u[1] * v[0]], length = Math.hypot(...n);
7
+ for (point of [a, b, c]) {
8
+ position.push(...point);
9
+ for (value of n) normal.push(value / length);
10
+ color.push(...tint);
11
+ }
12
+ }
@@ -0,0 +1,32 @@
1
+ /** Area-weighted vertex normals, for indexed or non-indexed triangles. */
2
+
3
+ export function vertexNormals(p, indices) {
4
+ // Accumulate area-weighted face normals for shared vertices, then normalize.
5
+ const normals = new Float32Array(p.length);
6
+ let i, a, b, c, u, v, j, n, index, length;
7
+ for (i = 0; i < (indices?.length || p.length / 3); i += 3) {
8
+ a = indices ? indices[i] : i, b = indices ? indices[i + 1] : i + 1, c = indices ? indices[i + 2] : i + 2;
9
+ u = [], v = [];
10
+ for (j = 0; j < 3; j++) {
11
+ u.push(p[b * 3 + j] - p[a * 3 + j]);
12
+ v.push(p[c * 3 + j] - p[a * 3 + j]);
13
+ }
14
+ n = [
15
+ u[1] * v[2] - u[2] * v[1],
16
+ u[2] * v[0] - u[0] * v[2],
17
+ u[0] * v[1] - u[1] * v[0]
18
+ ];
19
+ for (index of [a, b, c]) {
20
+ for (j = 0; j < 3; j++) {
21
+ normals[index * 3 + j] += n[j];
22
+ }
23
+ }
24
+ }
25
+ for (i = 0; i < normals.length; i += 3) {
26
+ length = Math.hypot(...normals.subarray(i, i + 3)) || 1;
27
+ for (j = 0; j < 3; j++) {
28
+ normals[i + j] /= length;
29
+ }
30
+ }
31
+ return normals;
32
+ }
@@ -0,0 +1,9 @@
1
+ import { polygon } from './polygon.js';
2
+
3
+ export function visit(context, coordinates, closed) {
4
+ if (!coordinates.length) return;
5
+ let child;
6
+ if (coordinates[0] instanceof L.LatLng) polygon(context, [coordinates], closed);
7
+ else if (closed && coordinates[0][0] instanceof L.LatLng) polygon(context, coordinates, closed);
8
+ else for (child of coordinates) visit(context, child, closed);
9
+ }
package/src/index.js CHANGED
@@ -1,82 +1,115 @@
1
+ import './camera/mapCamera.js';
2
+ import { init3D } from './scene/init3D.js';
3
+ import { initNativeGPU } from './core/initNativeGPU.js';
4
+ import { initRaster } from './raster/initRaster.js';
5
+ import { setGeoJSONData } from './sources/setGeoJSONData.js';
6
+ import { initTerrain } from './terrain/initTerrain.js';
7
+ import './sunlight/initSunlight.js';
8
+ import { initTraffic } from './traffic/initTraffic.js';
9
+ import './walk/initWalk.js';
10
+ import { indexState } from './constants/indexState.js';
11
+ import { initializeNativeLayer } from './core/initializeNativeLayer.js';
12
+ import { layerLayerAdd } from './scene/layerLayerAdd.js';
13
+ import { layerInitialize } from './scene/layerInitialize.js';
14
+
1
15
  /**
2
16
  * `new L.Layer({ source: { type, url, ...settings }, pane, attribution })`: layers with a `source`
3
- * load their type module on first use. Subclasses are unchanged.
17
+ * initialize their specialized behavior on first use. Native map layers also join the WebGPU scene.
4
18
  */
5
19
 
6
20
  /**
7
21
  * Router for `new L.Layer({ source: { type, url, ...settings }, pane, attribution })`.
8
- * It imports the type module on demand and turns the
9
- * layer into it; types receive flat options (`{ ...source, pane, attribution }`), so `layer.options.url` etc.
22
+ * It initializes the existing instance from the bundled source modules;
23
+ * types receive flat options (`{ ...source, pane, attribution }`), so `layer.options.url` etc.
10
24
  *
11
25
  * Folder layout:
12
- * - types/: one module per `source.type`, the only files imported by this router:
13
- * - 'pmtiles': raster PMTiles basemap (an L.TileLayer), draped on the terrain when present;
14
- * - '3d': shared WebGPU scene with a GLB/glTF model, PMTiles GeoJSON features, or empty;
15
- * - 'geojson': inline or URL-backed GeoJSON features rendered by the shared 3D scene;
16
- * - 'terrain': Float32 PMTiles DEM that deforms raster tiles, buildings and the camera, plus optional bridge decks;
17
- * - 'sunlight': simulation clock control, sun/moon lighting and shadows;
18
- * - 'traffic': vehicles moving along GeoJSON lanes (measured flow or timetable);
19
- * - 'walk': third-person pedestrian moved with the keyboard, the camera following behind.
20
- * - scene/: named operations for GPU resources, model/archive loading, lighting, sources, picking
21
- * and rendering. They receive the layer explicitly; types/3d.js declares its delegates, without mixins.
22
- * - utils/: computations and scene-data helpers, independent of Leaflet layers and GPU devices.
23
- * Geometry, decoders, lighting grids, terrain sampling, traffic and collisions can be tested in Node;
24
- * scene transforms/picking use browser DOMMatrix/DOMPoint, and CSS colors use a canvas.
26
+ * - scene/: source routing, lifecycle and graph; initializers live in their domain folders.
27
+ * - core/: Leaflet layer integration; camera/ and controls/: camera and interaction.
28
+ * - sources/ and picking/: source geometry and feature interaction.
29
+ * - rendering/, shaders/, shadows/ and lighting/: WebGPU drawing and illumination.
30
+ * - geometry/, triangulation/ and collision/: mesh operations and spatial queries.
31
+ * - models/, archives/ and raster/: glTF loading, archive access and raster tiles.
32
+ * - constants/ and state/: exported module-level const and let bindings.
33
+ * - terrain/, sunlight/, traffic/ and walk/: feature-specific operations.
34
+ * Operations receive the layer explicitly, without subclasses or prototype replacement.
25
35
  * Dataset-specific code and data (routes, timetables, API loaders) belong to the application, e.g. misc/.
26
36
  *
27
- * When `type` is omitted it is inferred from `source.url`: *.pmtiles -> 'pmtiles', anything else -> '3d'.
37
+ * When `type` is omitted, inline FeatureCollections use 'geojson'; otherwise *.pmtiles URLs use
38
+ * 'pmtiles' and other sources use '3d'.
28
39
  */
29
40
 
30
- const layerProto = Object.defineProperties({}, Object.getOwnPropertyDescriptors(L.Layer.prototype));
41
+ indexState.layerProto = Object.defineProperties({}, Object.getOwnPropertyDescriptors(L.Layer.prototype));
31
42
 
32
- // Stand-in while the type module loads: remembers the map, renders nothing.
33
- const Pending = L.Layer.extend({
34
- onAdd() {},
35
- onRemove() {},
36
- });
43
+ // One chain for every pending layer: they become real layers in creation order.
44
+ indexState.loading = Promise.resolve();
45
+
46
+ indexState.pendingInitializations = [];
47
+
48
+ indexState.closestMethods = new WeakMap();
49
+ indexState.boundsMethods = new WeakMap();
50
+ indexState.gridInitializers = new WeakMap();
37
51
 
38
- // One chain for every pending layer: they become real layers in creation order, whatever the import timing.
39
- let loading = Promise.resolve();
52
+ indexState.pendingGridFades = new Map();
53
+ indexState.gridFadeFrame = null;
40
54
 
41
- // Shared registry: type modules (src/types) register here.
42
- L.Layer.types = {};
55
+ indexState.pendingRasterLoads = [];
56
+
57
+ /**
58
+ * The '3d' layer type: native WebGPU scene synchronized with the map camera.
59
+ * Layers on one map share a canvas, scene and camera; each has its own root transform.
60
+ *
61
+ * @typedef {Object} Layer3DOptions Layer options; pane and attribution remain standard L.Layer options.
62
+ * @property {string} [type] '3d', 'geojson', 'pmtiles', 'terrain' or 'traffic'.
63
+ * @property {number[]} [center] Local origin [lat,lng]; defaults to the first map center.
64
+ * @property {number} [terrainOffset=0] Vertical offset in metres when terrain is enabled.
65
+ * @property {boolean} [terrainConform=false] Fit lower model geometry to local terrain elevation.
66
+ * @property {'OPAQUE'|'MASK'|'BLEND'} [alphaMode] Override every glTF material's alpha mode.
67
+ * @property {number[]} [rotation] Model Euler rotation [x,y,z] in radians, YXZ order.
68
+ * @property {number[]} [scale] Model scale [x,y,z].
69
+ * @property {string} [url] GLB/glTF model URL or PMTiles archive URL.
70
+ * @property {function(Object): (ExtrusionStyle|null)} [style] Source styling; null skips a feature.
71
+ * @property {function(PickedFeature): (Node|string)} [tooltip] Tooltip content; strings are text.
72
+ * @property {string} [ariaLabel='3D scene'] Shared canvas accessible name.
73
+ * @property {boolean} [nightLight=false] Point sources: emissive bulbs and local illumination.
74
+ * @property {boolean} [nightSparkle=false] Model: sparse luminous points at night.
75
+ *
76
+ * @typedef {Object} ExtrusionStyle
77
+ * @property {number} top Roof height in metres; must exceed bottom.
78
+ * @property {number} [bottom=0] Nonnegative base height.
79
+ * @property {number|string|Object} [color=0xd9b38c] RGB/CSS color or linear-space {h,s,l}.
80
+ * @property {number} [trunkRadius] Point tree trunk radius in metres.
81
+ * @property {number} [crownRadius] Point tree crown radius in metres.
82
+ * @property {number} [crownBottom] Point tree crown base in metres.
83
+ * @property {string} [crownShape='round'] Point tree crown shape.
84
+ * @property {number|string|Object} [trunkColor=0x72513a] Point tree bark color.
85
+ * @property {number} [lightRadius] Point light estimated ground reach in metres.
86
+ * @property {number} [lightFlux] Point light luminous flux in lumens.
87
+ *
88
+ * @typedef {Object} PickedFeature
89
+ * @property {string|number} id Source feature id or configured model URL.
90
+ * @property {Object} properties GeoJSON properties or model-level glTF extras.
91
+ * @property {Object} mesh Intersected mesh.
92
+ * @property {number[]} point Intersection [x,y,z] in shared scene metres.
93
+ * @property {Object} [model] Configured model root; absent for source polygons.
94
+ * @property {number} [vertexStart] First polygon vertex in the batched mesh.
95
+ * @property {number} [vertexEnd] Exclusive end of the polygon's vertex range.
96
+ *
97
+ * @typedef {Object} SourceArea
98
+ * @property {Object} coords Archive block {z,x,y}.
99
+ * @property {AbortController} request Cancellation prevents attaching obsolete results.
100
+ * @property {boolean} [done] Geometry built successfully, including empty blocks.
101
+ * @property {Object|null} [mesh] Batched GPU mesh.
102
+ * @property {number} [buildings] Emitted feature count.
103
+ * @property {number} [skipped] Features skipped by style.
104
+ * @property {string} [error] Failed load/build message.
105
+ *
106
+ * @param {L.Layer} backend
107
+ * @param {Layer3DOptions} [options] World origin comes from center or the first map centre.
108
+ */
43
109
 
44
- // Core L.Layer has no initialize and init hooks get no arguments: keep the options for the hook.
45
110
  L.Layer.include({
46
- initialize(options = {}) {
47
- if (Object.getPrototypeOf(this) !== L.Layer.prototype || !options.source) {
48
- if (layerProto.initialize) return layerProto.initialize.apply(this, arguments);
49
- L.Util.setOptions(this, options);
50
- return;
51
- }
52
- const layer = this;
53
- const { source: { type = /\.pmtiles(?:[?#]|$)/i.test(options.source.url) ? 'pmtiles' : '3d', ...source }, ...core } = options;
54
- const settings = { ...source, ...core };
55
- // A stand-in created by the entry point before this module loaded may already be on a map.
56
- const map = layer._map;
57
- map?.removeLayer(layer);
58
- delete layer.onAdd;
59
- delete layer.onRemove;
60
- if (L.Layer.types[type]) {
61
- Object.setPrototypeOf(layer, L.Layer.types[type].prototype);
62
- layer.options = Object.create(L.Layer.types[type].prototype.options);
63
- L.Layer.types[type].prototype.initialize.call(layer, settings);
64
- map?.addLayer(layer);
65
- return;
66
- }
67
- Object.setPrototypeOf(layer, Pending.prototype);
68
- L.Util.setOptions(layer, core);
69
- map?.addLayer(layer);
70
- // ponytail: type methods (setOpacity, add, ...) exist only once `ready` resolves.
71
- loading = loading.catch(() => {}).then(() => import(`./types/${type}.js`));
72
- const pending = layer.ready = loading.then(() => {
73
- const map = layer._map;
74
- map?.removeLayer(layer);
75
- Object.setPrototypeOf(layer, L.Layer.types[type].prototype);
76
- layer.options = Object.create(L.Layer.types[type].prototype.options);
77
- L.Layer.types[type].prototype.initialize.call(layer, settings);
78
- map?.addLayer(layer);
79
- return layer.ready === pending ? layer : layer.ready;
80
- });
81
- },
82
- });
111
+ _layerAdd: layerLayerAdd,
112
+ initialize: layerInitialize,
113
+ });
114
+
115
+ L.Layer.addInitHook(initializeNativeLayer);
@@ -0,0 +1,23 @@
1
+ import { lightGrid } from './lightGrid.js';
2
+ import { worldLights } from './worldLights.js';
3
+
4
+ /** Keep fixed lamps cached when moving headlights change. */
5
+ export function cacheLightGrid(meshes, previous, maxBytes) {
6
+ let unchanged = previous?.meshes.length === meshes.length;
7
+ const packed = [], snapshots = [];
8
+ let i, mesh, matrix, lights, cache, sameMatrix, j;
9
+ for (i = 0; i < meshes.length; i++) {
10
+ mesh = meshes[i], matrix = mesh.worldMatrix, lights = mesh.extras.lights;
11
+ cache = mesh._worldLights;
12
+ sameMatrix = Boolean(cache);
13
+ for (j = 0; j < matrix.length && sameMatrix; j++) sameMatrix = matrix[j] === cache.matrix[j];
14
+ if (!sameMatrix || cache.lights !== lights) {
15
+ cache = mesh._worldLights = { lights, matrix: [...matrix], data: worldLights(lights, matrix) };
16
+ }
17
+ unchanged &&= previous.meshes[i].mesh === mesh && previous.meshes[i].cache === cache;
18
+ packed.push(cache.data);
19
+ snapshots.push({ mesh, cache });
20
+ }
21
+ if (unchanged) return previous;
22
+ return { ...lightGrid(packed, maxBytes), meshes: snapshots };
23
+ }
@@ -0,0 +1,6 @@
1
+ export function collectLightMeshes(node, fixed, moving) {
2
+ if (!node.visible) return;
3
+ if (node.extras?.lights) (node.extras.dynamicLights ? moving : fixed).push(node);
4
+ let child;
5
+ for (child of node.children || []) collectLightMeshes(child, fixed, moving);
6
+ }
@@ -0,0 +1,42 @@
1
+ import { visitCells } from './visitCells.js';
2
+
3
+ /** Pack world-space point lights into the shader's spatial grid. */
4
+ export function lightGrid(packed, maxBytes) {
5
+ let count = 0;
6
+ let values, i, value, key;
7
+ for (values of packed) count += values.length / 8;
8
+ const cellSize = 32;
9
+ let data = new Float32Array(8);
10
+ if (count) {
11
+ let minX = Infinity, minZ = Infinity, maxX = -Infinity, maxZ = -Infinity;
12
+ for (values of packed) for (i = 0; i < values.length; i += 8) {
13
+ minX = Math.min(minX, values[i] - values[i + 3]);
14
+ maxX = Math.max(maxX, values[i] + values[i + 3]);
15
+ minZ = Math.min(minZ, values[i + 2] - values[i + 3]);
16
+ maxZ = Math.max(maxZ, values[i + 2] + values[i + 3]);
17
+ }
18
+ const columns = Math.ceil((maxX - minX) / cellSize) + 1,
19
+ rows = Math.ceil((maxZ - minZ) / cellSize) + 1;
20
+ // Counting sort: count the lights of each cell, then fill each cell's slice.
21
+ const counts = new Uint32Array(columns * rows),
22
+ next = new Uint32Array(columns * rows);
23
+ visitCells(packed, minX, minZ, cellSize, columns, counts);
24
+ let entries = 0;
25
+ for (value of counts) entries += value;
26
+ const length = (2 + columns * rows + entries * 2) * 4;
27
+ if (length * 4 > maxBytes) {
28
+ throw new Error('Streetlight grid exceeds GPU storage limit');
29
+ }
30
+ data = new Float32Array(length);
31
+ data.set([minX, minZ, cellSize, columns, rows, count, 0, 0]);
32
+ let offset = 2 + columns * rows;
33
+ for (key = 0; key < counts.length; key++) if (counts[key]) {
34
+ data[(2 + key) * 4] = next[key] = offset;
35
+ data[(2 + key) * 4 + 1] = counts[key];
36
+ offset += counts[key] * 2;
37
+ }
38
+ visitCells(packed, minX, minZ, cellSize, columns, next, data);
39
+ }
40
+
41
+ return { data, count };
42
+ }
@@ -0,0 +1,34 @@
1
+ import { destroyTexture } from '../rendering/destroyTexture.js';
2
+ import { bindSunlight } from '../shadows/bindSunlight.js';
3
+ import { cacheLightGrid } from './cacheLightGrid.js';
4
+ import { collectLightMeshes } from './collectLightMeshes.js';
5
+
6
+ export function updatePointLights(backend) {
7
+ const { device, sunlight: sun } = backend.renderer;
8
+ const fixed = [], moving = [];
9
+ let layer;
10
+ for (layer of backend._layers) {
11
+ if (!layer.options.nightLight || !layer.root.visible) continue;
12
+ collectLightMeshes(layer.root, fixed, moving);
13
+ }
14
+ const maxBytes = device.limits.maxStorageBufferBindingSize;
15
+ const staticGrid = cacheLightGrid(fixed, sun.staticLightGrid, maxBytes);
16
+ const dynamicGrid = cacheLightGrid(moving, sun.dynamicLightGrid, maxBytes);
17
+ if (staticGrid === sun.staticLightGrid && dynamicGrid === sun.dynamicLightGrid) return;
18
+ const size = staticGrid.data.byteLength + dynamicGrid.data.byteLength;
19
+ if (size > maxBytes) throw new Error('Streetlight grid exceeds GPU storage limit');
20
+ let uploadStatic = staticGrid !== sun.staticLightGrid;
21
+ if (sun.lights.size < size) {
22
+ destroyTexture(backend, sun.lights);
23
+ sun.lights = device.createBuffer({ size, usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_DST });
24
+ bindSunlight(backend);
25
+ uploadStatic = true;
26
+ }
27
+ // The spare header component points to a second grid in the same storage binding.
28
+ staticGrid.data[6] = staticGrid.data.length / 4;
29
+ if (uploadStatic) device.queue.writeBuffer(sun.lights, 0, staticGrid.data);
30
+ device.queue.writeBuffer(sun.lights, staticGrid.data.byteLength, dynamicGrid.data);
31
+ sun.lightCount = staticGrid.count + dynamicGrid.count;
32
+ sun.staticLightGrid = staticGrid;
33
+ sun.dynamicLightGrid = dynamicGrid;
34
+ }
@@ -0,0 +1,15 @@
1
+ export function visitCells(packed, minX, minZ, cellSize, columns, offsets, data) {
2
+ let values, i, radius, x, z, y, c, key, j, o;
3
+ for (values of packed) for (i = 0; i < values.length; i += 8) {
4
+ radius = values[i + 3], x = values[i] - minX, z = values[i + 2] - minZ;
5
+ for (y = Math.floor((z - radius) / cellSize); y <= Math.floor((z + radius) / cellSize); y++) {
6
+ for (c = Math.floor((x - radius) / cellSize); c <= Math.floor((x + radius) / cellSize); c++) {
7
+ key = y * columns + c;
8
+ if (data) {
9
+ for (j = 0, o = offsets[key] * 4; j < 8; j++) data[o + j] = values[i + j];
10
+ offsets[key] += 2;
11
+ } else offsets[key]++;
12
+ }
13
+ }
14
+ }
15
+ }
@@ -0,0 +1,27 @@
1
+
2
+ /** World-space [x, y, z, radius, r, g, b, intensity] for one mesh's point lights. */
3
+ export function worldLights(lights, m) {
4
+ const values = new Float32Array(lights.length * 8);
5
+ let i, x, y, z, radius, color, flux, w;
6
+ for (i = 0; i < lights.length; i++) {
7
+ ({
8
+ position: [x, y, z],
9
+ radius,
10
+ color,
11
+ flux
12
+ } = lights[i]);
13
+ w = m[3] * x + m[7] * y + m[11] * z + m[15];
14
+ values.set(
15
+ [
16
+ (m[0] * x + m[4] * y + m[8] * z + m[12]) / w,
17
+ (m[1] * x + m[5] * y + m[9] * z + m[13]) / w,
18
+ (m[2] * x + m[6] * y + m[10] * z + m[14]) / w,
19
+ radius,
20
+ ...color,
21
+ flux / (4 * Math.PI) * 0.03
22
+ ],
23
+ i * 8
24
+ );
25
+ }
26
+ return values;
27
+ }
@@ -0,0 +1,45 @@
1
+ /** Decode a static glTF JSON document or GLB v2 container. */
2
+ import { hasUnsupportedPrimitives } from './hasUnsupportedPrimitives.js';
3
+
4
+ export function decodeModel(data) {
5
+ const view = new DataView(data), decoder = new TextDecoder();
6
+ let description;
7
+ let offset, length, type, chunk;
8
+ if (view.getUint32(0, true) === 0x46546c67) {
9
+ // Decode GLB v2 chunks; unknown types are skipped.
10
+ if (view.getUint32(4, true) !== 2 || view.getUint32(8, true) !== data.byteLength) {
11
+ throw new Error('Invalid GLB header');
12
+ }
13
+ let binary;
14
+ for (offset = 12; offset < data.byteLength;) {
15
+ if (offset + 8 > data.byteLength) {
16
+ throw new Error('Truncated GLB chunk');
17
+ }
18
+ length = view.getUint32(offset, true), type = view.getUint32(offset + 4, true);
19
+ offset += 8;
20
+ if (offset + length > data.byteLength) {
21
+ throw new Error('Truncated GLB data');
22
+ }
23
+ chunk = data.slice(offset, offset + length);
24
+ if (type === 0x4e4f534a) {
25
+ description = JSON.parse(decoder.decode(chunk));
26
+ }
27
+ if (type === 0x004e4942) {
28
+ binary = chunk;
29
+ }
30
+ offset += length;
31
+ }
32
+ if (!description) {
33
+ throw new Error('Missing GLB JSON');
34
+ }
35
+ if (binary) {
36
+ description.buffers[0].binary = binary;
37
+ }
38
+ } else {
39
+ description = JSON.parse(decoder.decode(data));
40
+ }
41
+ if (description.skins?.length || description.animations?.length || description.extensionsRequired?.length || hasUnsupportedPrimitives(description.meshes)) {
42
+ throw new Error('Layer3D supports static triangle glTF models without required extensions');
43
+ }
44
+ return description;
45
+ }
@@ -0,0 +1,10 @@
1
+ export function hasUnsupportedPrimitives(meshes) {
2
+ if (!meshes) return false;
3
+ let mesh, primitive;
4
+ for (mesh of meshes) {
5
+ for (primitive of mesh.primitives) {
6
+ if (primitive.targets || (primitive.mode !== undefined && primitive.mode !== 4)) return true;
7
+ }
8
+ }
9
+ return false;
10
+ }
@@ -0,0 +1,6 @@
1
+ export async function loadBuffer(buffer, directory) {
2
+ if (buffer.binary) return;
3
+ const response = await fetch(new URL(buffer.uri, directory).href);
4
+ if (!response.ok) throw new Error(`Unable to load model buffer: HTTP ${response.status}`);
5
+ buffer.binary = await response.arrayBuffer();
6
+ }