leaflet-city-mapper 0.0.1 → 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.
Files changed (472) hide show
  1. package/README.md +15 -13
  2. package/cucumber.mjs +4 -0
  3. package/dist/leaflet-city-mapper.js +1 -1
  4. package/dist/leaflet-city-mapper.js.map +4 -4
  5. package/dist/utils/CELL.js +2 -0
  6. package/dist/utils/CELL.js.map +7 -0
  7. package/dist/utils/addBridges.js +2 -0
  8. package/dist/utils/addBridges.js.map +7 -0
  9. package/dist/utils/addRasterTile.js +2 -0
  10. package/dist/utils/addRasterTile.js.map +7 -0
  11. package/dist/utils/along.js +2 -0
  12. package/dist/utils/along.js.map +7 -0
  13. package/dist/utils/atmosphere.js +2 -0
  14. package/dist/utils/atmosphere.js.map +7 -0
  15. package/dist/utils/attach.js +2 -0
  16. package/dist/utils/attach.js.map +7 -0
  17. package/dist/utils/bindSunlight.js +2 -0
  18. package/dist/utils/bindSunlight.js.map +7 -0
  19. package/dist/utils/box.js +2 -0
  20. package/dist/utils/box.js.map +7 -0
  21. package/dist/utils/bridgeElevation.js +2 -0
  22. package/dist/utils/bridgeElevation.js.map +7 -0
  23. package/dist/utils/build.js +2 -0
  24. package/dist/utils/build.js.map +7 -0
  25. package/dist/utils/cameraControls.js +2 -0
  26. package/dist/utils/cameraControls.js.map +7 -0
  27. package/dist/utils/channel.js +2 -0
  28. package/dist/utils/channel.js.map +7 -0
  29. package/dist/utils/collider.js +2 -0
  30. package/dist/utils/collider.js.map +7 -0
  31. package/dist/utils/colliders.js +2 -0
  32. package/dist/utils/colliders.js.map +7 -0
  33. package/dist/utils/computeBounds.js +2 -0
  34. package/dist/utils/computeBounds.js.map +7 -0
  35. package/dist/utils/conformModelToTerrain.js +2 -0
  36. package/dist/utils/conformModelToTerrain.js.map +7 -0
  37. package/dist/utils/createMesh.js +2 -0
  38. package/dist/utils/createMesh.js.map +7 -0
  39. package/dist/utils/createProgram.js +3 -0
  40. package/dist/utils/createProgram.js.map +7 -0
  41. package/dist/utils/decodeDirectory.js +2 -0
  42. package/dist/utils/decodeDirectory.js.map +7 -0
  43. package/dist/utils/decodeHeader.js +2 -0
  44. package/dist/utils/decodeHeader.js.map +7 -0
  45. package/dist/utils/decodeModel.js +2 -0
  46. package/dist/utils/decodeModel.js.map +7 -0
  47. package/dist/utils/decompress.js +2 -0
  48. package/dist/utils/decompress.js.map +7 -0
  49. package/dist/utils/destroyTexture.js +2 -0
  50. package/dist/utils/destroyTexture.js.map +7 -0
  51. package/dist/utils/disposeMesh.js +2 -0
  52. package/dist/utils/disposeMesh.js.map +7 -0
  53. package/dist/utils/drawGeometry.js +2 -0
  54. package/dist/utils/drawGeometry.js.map +7 -0
  55. package/dist/utils/elevationWGSL.js +24 -0
  56. package/dist/utils/elevationWGSL.js.map +7 -0
  57. package/dist/utils/emptyNode.js +2 -0
  58. package/dist/utils/emptyNode.js.map +7 -0
  59. package/dist/utils/endZoom.js +2 -0
  60. package/dist/utils/endZoom.js.map +7 -0
  61. package/dist/utils/findFeature.js +2 -0
  62. package/dist/utils/findFeature.js.map +7 -0
  63. package/dist/utils/geometry.js +0 -1
  64. package/dist/utils/geometry.js.map +4 -4
  65. package/dist/utils/getElevation.js +2 -0
  66. package/dist/utils/getElevation.js.map +7 -0
  67. package/dist/utils/getHeader.js +2 -0
  68. package/dist/utils/getHeader.js.map +7 -0
  69. package/dist/utils/getZxy.js +2 -0
  70. package/dist/utils/getZxy.js.map +7 -0
  71. package/dist/utils/glass.js +2 -0
  72. package/dist/utils/glass.js.map +7 -0
  73. package/dist/utils/headlight.js +2 -0
  74. package/dist/utils/headlight.js.map +7 -0
  75. package/dist/utils/hit.js +2 -0
  76. package/dist/utils/hit.js.map +7 -0
  77. package/dist/utils/horizontalPosition.js +2 -0
  78. package/dist/utils/horizontalPosition.js.map +7 -0
  79. package/dist/utils/horizontalRay.js +2 -0
  80. package/dist/utils/horizontalRay.js.map +7 -0
  81. package/dist/utils/hull.js +2 -0
  82. package/dist/utils/hull.js.map +7 -0
  83. package/dist/utils/initSunlight.js +2 -0
  84. package/dist/utils/initSunlight.js.map +7 -0
  85. package/dist/utils/initTerrain.js +2 -0
  86. package/dist/utils/initTerrain.js.map +7 -0
  87. package/dist/utils/initTraffic.js +40 -0
  88. package/dist/utils/initTraffic.js.map +7 -0
  89. package/dist/utils/initWalk.js +2 -0
  90. package/dist/utils/initWalk.js.map +7 -0
  91. package/dist/utils/intersectMeshes.js +2 -0
  92. package/dist/utils/intersectMeshes.js.map +7 -0
  93. package/dist/utils/isClockWise.js +2 -0
  94. package/dist/utils/isClockWise.js.map +7 -0
  95. package/dist/utils/lampPostGeometry.js +2 -0
  96. package/dist/utils/lampPostGeometry.js.map +7 -0
  97. package/dist/utils/lightGeometry.js +2 -0
  98. package/dist/utils/lightGeometry.js.map +7 -0
  99. package/dist/utils/lightGrid.js +2 -0
  100. package/dist/utils/lightGrid.js.map +7 -0
  101. package/dist/utils/limbs.js +2 -0
  102. package/dist/utils/limbs.js.map +7 -0
  103. package/dist/utils/loadModel.js +2 -0
  104. package/dist/utils/loadModel.js.map +7 -0
  105. package/dist/utils/loadSource.js +2 -0
  106. package/dist/utils/loadSource.js.map +7 -0
  107. package/dist/utils/loadTerrain.js +2 -0
  108. package/dist/utils/loadTerrain.js.map +7 -0
  109. package/dist/utils/mapCamera.js +2 -0
  110. package/dist/utils/mapCamera.js.map +7 -0
  111. package/dist/utils/{shaders.js → materialShaders.js} +16 -8
  112. package/dist/utils/materialShaders.js.map +7 -0
  113. package/dist/utils/mirror.js +2 -0
  114. package/dist/utils/mirror.js.map +7 -0
  115. package/dist/utils/moonPosition.js +2 -0
  116. package/dist/utils/moonPosition.js.map +7 -0
  117. package/dist/utils/moves.js +2 -0
  118. package/dist/utils/moves.js.map +7 -0
  119. package/dist/utils/nativeEvents.js +2 -0
  120. package/dist/utils/nativeEvents.js.map +7 -0
  121. package/dist/utils/nativeGeometry.js +2 -0
  122. package/dist/utils/nativeGeometry.js.map +7 -0
  123. package/dist/utils/nativeLayer.js +2 -0
  124. package/dist/utils/nativeLayer.js.map +7 -0
  125. package/dist/utils/nodeMatrix.js +2 -0
  126. package/dist/utils/nodeMatrix.js.map +7 -0
  127. package/dist/utils/onAdd3DLayer.js +2 -0
  128. package/dist/utils/onAdd3DLayer.js.map +7 -0
  129. package/dist/utils/onAddSun.js +2 -0
  130. package/dist/utils/onAddSun.js.map +7 -0
  131. package/dist/utils/onClick.js +2 -0
  132. package/dist/utils/onClick.js.map +7 -0
  133. package/dist/utils/onMapChange.js +2 -0
  134. package/dist/utils/onMapChange.js.map +7 -0
  135. package/dist/utils/onPMTileAdd.js +2 -0
  136. package/dist/utils/onPMTileAdd.js.map +7 -0
  137. package/dist/utils/onPMTileRemove.js +2 -0
  138. package/dist/utils/onPMTileRemove.js.map +7 -0
  139. package/dist/utils/onPointerLeave.js +2 -0
  140. package/dist/utils/onPointerLeave.js.map +7 -0
  141. package/dist/utils/onPointerMove.js +2 -0
  142. package/dist/utils/onPointerMove.js.map +7 -0
  143. package/dist/utils/onRemove3DLayer.js +2 -0
  144. package/dist/utils/onRemove3DLayer.js.map +7 -0
  145. package/dist/utils/onRemoveSun.js +2 -0
  146. package/dist/utils/onRemoveSun.js.map +7 -0
  147. package/dist/utils/onTerrainAdd.js +2 -0
  148. package/dist/utils/onTerrainAdd.js.map +7 -0
  149. package/dist/utils/onTerrainChange.js +2 -0
  150. package/dist/utils/onTerrainChange.js.map +7 -0
  151. package/dist/utils/onTerrainRemove.js +2 -0
  152. package/dist/utils/onTerrainRemove.js.map +7 -0
  153. package/dist/utils/onZoomAnim.js +2 -0
  154. package/dist/utils/onZoomAnim.js.map +7 -0
  155. package/dist/utils/paints.js +2 -0
  156. package/dist/utils/paints.js.map +7 -0
  157. package/dist/utils/parseColor.js +2 -0
  158. package/dist/utils/parseColor.js.map +7 -0
  159. package/dist/utils/parts.js +2 -0
  160. package/dist/utils/parts.js.map +7 -0
  161. package/dist/utils/projectCelestialBody.js +2 -0
  162. package/dist/utils/projectCelestialBody.js.map +7 -0
  163. package/dist/utils/pump.js +2 -0
  164. package/dist/utils/pump.js.map +7 -0
  165. package/dist/utils/rasterTiles.js +2 -0
  166. package/dist/utils/rasterTiles.js.map +7 -0
  167. package/dist/utils/raycast.js +2 -0
  168. package/dist/utils/raycast.js.map +7 -0
  169. package/dist/utils/read.js +2 -0
  170. package/dist/utils/read.js.map +7 -0
  171. package/dist/utils/readAccessor.js +2 -0
  172. package/dist/utils/readAccessor.js.map +7 -0
  173. package/dist/utils/releaseArea.js +2 -0
  174. package/dist/utils/releaseArea.js.map +7 -0
  175. package/dist/utils/removeRasterTile.js +2 -0
  176. package/dist/utils/removeRasterTile.js.map +7 -0
  177. package/dist/utils/render.js +15 -0
  178. package/dist/utils/render.js.map +7 -0
  179. package/dist/utils/renderSunlight.js +13 -0
  180. package/dist/utils/renderSunlight.js.map +7 -0
  181. package/dist/utils/renderers.js +2 -0
  182. package/dist/utils/renderers.js.map +7 -0
  183. package/dist/utils/resizeSunlight.js +2 -0
  184. package/dist/utils/resizeSunlight.js.map +7 -0
  185. package/dist/utils/roofCoverage.js +2 -0
  186. package/dist/utils/roofCoverage.js.map +7 -0
  187. package/dist/utils/routeGeometry.js +2 -0
  188. package/dist/utils/routeGeometry.js.map +7 -0
  189. package/dist/utils/scheduledTrips.js +2 -0
  190. package/dist/utils/scheduledTrips.js.map +7 -0
  191. package/dist/utils/setGeoJSONData.js +2 -0
  192. package/dist/utils/setGeoJSONData.js.map +7 -0
  193. package/dist/utils/setHighlight.js +2 -0
  194. package/dist/utils/setHighlight.js.map +7 -0
  195. package/dist/utils/setPMTileOpacity.js +2 -0
  196. package/dist/utils/setPMTileOpacity.js.map +7 -0
  197. package/dist/utils/setPMTileZIndex.js +2 -0
  198. package/dist/utils/setPMTileZIndex.js.map +7 -0
  199. package/dist/utils/setParent.js +2 -0
  200. package/dist/utils/setParent.js.map +7 -0
  201. package/dist/utils/setTerrainHeight.js +2 -0
  202. package/dist/utils/setTerrainHeight.js.map +7 -0
  203. package/dist/utils/setVertexColor.js +2 -0
  204. package/dist/utils/setVertexColor.js.map +7 -0
  205. package/dist/utils/showFeature.js +2 -0
  206. package/dist/utils/showFeature.js.map +7 -0
  207. package/dist/utils/sizes.js +2 -0
  208. package/dist/utils/sizes.js.map +7 -0
  209. package/dist/utils/skin.js +2 -0
  210. package/dist/utils/skin.js.map +7 -0
  211. package/dist/utils/solarPosition.js +2 -0
  212. package/dist/utils/solarPosition.js.map +7 -0
  213. package/dist/utils/sortMeshes.js +2 -0
  214. package/dist/utils/sortMeshes.js.map +7 -0
  215. package/dist/utils/speed.js +2 -0
  216. package/dist/utils/speed.js.map +7 -0
  217. package/dist/utils/startZoom.js +2 -0
  218. package/dist/utils/startZoom.js.map +7 -0
  219. package/dist/utils/taillight.js +2 -0
  220. package/dist/utils/taillight.js.map +7 -0
  221. package/dist/utils/terrainAtlas.js +2 -0
  222. package/dist/utils/terrainAtlas.js.map +7 -0
  223. package/dist/utils/terrainElevation.js +2 -0
  224. package/dist/utils/terrainElevation.js.map +7 -0
  225. package/dist/utils/terrainGrid.js +2 -0
  226. package/dist/utils/terrainGrid.js.map +7 -0
  227. package/dist/utils/textureSampler.js +2 -0
  228. package/dist/utils/textureSampler.js.map +7 -0
  229. package/dist/utils/tileId.js +2 -0
  230. package/dist/utils/tileId.js.map +7 -0
  231. package/dist/utils/toLanes.js +2 -0
  232. package/dist/utils/toLanes.js.map +7 -0
  233. package/dist/utils/toSRGB.js +2 -0
  234. package/dist/utils/toSRGB.js.map +7 -0
  235. package/dist/utils/tooltip.js +3 -0
  236. package/dist/utils/tooltip.js.map +7 -0
  237. package/dist/utils/traffic.js +1 -1
  238. package/dist/utils/traffic.js.map +3 -3
  239. package/dist/utils/traverse.js +2 -0
  240. package/dist/utils/traverse.js.map +7 -0
  241. package/dist/utils/treeGeometry.js +2 -0
  242. package/dist/utils/treeGeometry.js.map +7 -0
  243. package/dist/utils/triangulate.js +2 -0
  244. package/dist/utils/triangulate.js.map +7 -0
  245. package/dist/utils/tripsAt.js +2 -0
  246. package/dist/utils/tripsAt.js.map +7 -0
  247. package/dist/utils/types.js +2 -0
  248. package/dist/utils/types.js.map +7 -0
  249. package/dist/utils/underEntry.js +2 -0
  250. package/dist/utils/underEntry.js.map +7 -0
  251. package/dist/utils/update.js +2 -0
  252. package/dist/utils/update.js.map +7 -0
  253. package/dist/utils/updateArea.js +2 -0
  254. package/dist/utils/updateArea.js.map +7 -0
  255. package/dist/utils/updateCamera.js +2 -0
  256. package/dist/utils/updateCamera.js.map +7 -0
  257. package/dist/utils/updatePointLights.js +2 -0
  258. package/dist/utils/updatePointLights.js.map +7 -0
  259. package/dist/utils/updateWorldMatrix.js +2 -0
  260. package/dist/utils/updateWorldMatrix.js.map +7 -0
  261. package/dist/utils/vehicleOffsets.js +2 -0
  262. package/dist/utils/vehicleOffsets.js.map +7 -0
  263. package/dist/utils/vehicles.js +1 -1
  264. package/dist/utils/vehicles.js.map +3 -3
  265. package/dist/utils/vertexNormals.js +2 -0
  266. package/dist/utils/vertexNormals.js.map +7 -0
  267. package/dist/utils/walk.js +1 -1
  268. package/dist/utils/walk.js.map +3 -3
  269. package/dist/utils/white.js +2 -0
  270. package/dist/utils/white.js.map +7 -0
  271. package/dist/utils/worldLights.js +2 -0
  272. package/dist/utils/worldLights.js.map +7 -0
  273. package/dist/utils/wrap.js +2 -0
  274. package/dist/utils/wrap.js.map +7 -0
  275. package/package.json +2 -4
  276. package/src/index.js +365 -50
  277. package/src/utils/CELL.js +4 -0
  278. package/src/utils/addBridges.js +66 -0
  279. package/src/utils/addRasterTile.js +112 -0
  280. package/src/utils/along.js +9 -0
  281. package/src/utils/atmosphere.js +20 -0
  282. package/src/utils/attach.js +255 -0
  283. package/src/utils/bindSunlight.js +12 -0
  284. package/src/utils/box.js +1 -0
  285. package/src/utils/bridgeElevation.js +18 -0
  286. package/src/utils/build.js +20 -0
  287. package/src/utils/cameraControls.js +287 -0
  288. package/src/utils/channel.js +4 -0
  289. package/src/utils/collider.js +62 -0
  290. package/src/utils/colliders.js +2 -0
  291. package/src/utils/computeBounds.js +17 -0
  292. package/src/utils/conformModelToTerrain.js +69 -0
  293. package/src/utils/createMesh.js +31 -0
  294. package/src/utils/createProgram.js +92 -0
  295. package/src/utils/decodeDirectory.js +40 -0
  296. package/src/utils/decodeHeader.js +15 -0
  297. package/src/utils/decodeModel.js +43 -0
  298. package/src/utils/decompress.js +5 -0
  299. package/src/utils/destroyTexture.js +7 -0
  300. package/src/utils/disposeMesh.js +13 -0
  301. package/src/utils/drawGeometry.js +122 -0
  302. package/src/utils/elevationWGSL.js +27 -0
  303. package/src/utils/emptyNode.js +9 -0
  304. package/src/utils/endZoom.js +15 -0
  305. package/src/utils/findFeature.js +49 -0
  306. package/src/utils/geometry.js +0 -254
  307. package/src/utils/getElevation.js +10 -0
  308. package/src/utils/getHeader.js +9 -0
  309. package/src/utils/getZxy.js +76 -0
  310. package/src/utils/glass.js +1 -0
  311. package/src/utils/headlight.js +1 -0
  312. package/src/utils/hit.js +41 -0
  313. package/src/utils/horizontalPosition.js +16 -0
  314. package/src/utils/horizontalRay.js +12 -0
  315. package/src/utils/hull.js +1 -0
  316. package/src/utils/initSunlight.js +9 -0
  317. package/src/utils/initTerrain.js +19 -0
  318. package/src/utils/initTraffic.js +93 -0
  319. package/src/utils/initWalk.js +72 -0
  320. package/src/utils/{picking.js → intersectMeshes.js} +121 -119
  321. package/src/utils/isClockWise.js +12 -0
  322. package/src/utils/lampPostGeometry.js +26 -0
  323. package/src/utils/lightGeometry.js +22 -0
  324. package/src/utils/{lighting.js → lightGrid.js} +50 -51
  325. package/src/utils/limbs.js +9 -0
  326. package/src/{scene/model.js → utils/loadModel.js} +37 -24
  327. package/src/utils/loadSource.js +17 -0
  328. package/src/utils/loadTerrain.js +65 -0
  329. package/src/utils/mapCamera.js +432 -0
  330. package/src/utils/{shaders.js → materialShaders.js} +243 -237
  331. package/src/utils/mirror.js +6 -0
  332. package/src/utils/moonPosition.js +17 -0
  333. package/src/utils/moves.js +11 -0
  334. package/src/utils/nativeEvents.js +77 -0
  335. package/src/utils/nativeGeometry.js +131 -0
  336. package/src/utils/nativeLayer.js +317 -0
  337. package/src/utils/nodeMatrix.js +22 -0
  338. package/src/utils/onAdd3DLayer.js +31 -0
  339. package/src/utils/onAddSun.js +147 -0
  340. package/src/utils/onClick.js +13 -0
  341. package/src/utils/onMapChange.js +16 -0
  342. package/src/utils/onPMTileAdd.js +15 -0
  343. package/src/utils/onPMTileRemove.js +8 -0
  344. package/src/utils/onPointerLeave.js +11 -0
  345. package/src/utils/onPointerMove.js +15 -0
  346. package/src/utils/onRemove3DLayer.js +78 -0
  347. package/src/utils/onRemoveSun.js +3 -0
  348. package/src/utils/onTerrainAdd.js +18 -0
  349. package/src/utils/onTerrainChange.js +13 -0
  350. package/src/utils/onTerrainRemove.js +40 -0
  351. package/src/utils/onZoomAnim.js +14 -0
  352. package/src/utils/paints.js +10 -0
  353. package/src/utils/parseColor.js +42 -0
  354. package/src/utils/parts.js +16 -0
  355. package/src/utils/projectCelestialBody.js +13 -0
  356. package/src/{scene/sources.js → utils/pump.js} +59 -98
  357. package/src/utils/rasterTiles.js +285 -0
  358. package/src/utils/raycast.js +60 -0
  359. package/src/utils/read.js +29 -0
  360. package/src/utils/readAccessor.js +68 -0
  361. package/src/utils/releaseArea.js +34 -0
  362. package/src/utils/removeRasterTile.js +13 -0
  363. package/src/{scene → utils}/render.js +112 -173
  364. package/src/utils/renderSunlight.js +170 -0
  365. package/src/utils/renderers.js +2 -0
  366. package/src/utils/resizeSunlight.js +15 -0
  367. package/src/utils/roofCoverage.js +47 -0
  368. package/src/utils/routeGeometry.js +22 -0
  369. package/src/utils/scheduledTrips.js +29 -0
  370. package/src/utils/setGeoJSONData.js +11 -0
  371. package/src/utils/setHighlight.js +13 -0
  372. package/src/utils/setPMTileOpacity.js +7 -0
  373. package/src/utils/setPMTileZIndex.js +7 -0
  374. package/src/utils/setParent.js +7 -0
  375. package/src/utils/setTerrainHeight.js +10 -0
  376. package/src/utils/setVertexColor.js +14 -0
  377. package/src/utils/showFeature.js +27 -0
  378. package/src/utils/sizes.js +1 -0
  379. package/src/utils/skin.js +2 -0
  380. package/src/utils/solarPosition.js +17 -0
  381. package/src/utils/sortMeshes.js +12 -0
  382. package/src/utils/speed.js +3 -0
  383. package/src/utils/startZoom.js +5 -0
  384. package/src/utils/taillight.js +1 -0
  385. package/src/utils/terrainAtlas.js +21 -0
  386. package/src/utils/terrainElevation.js +20 -0
  387. package/src/utils/terrainGrid.js +23 -0
  388. package/src/utils/textureSampler.js +10 -0
  389. package/src/utils/tileId.js +18 -0
  390. package/src/utils/toLanes.js +7 -0
  391. package/src/utils/toSRGB.js +1 -0
  392. package/src/utils/tooltip.js +6 -0
  393. package/src/utils/traffic.js +310 -85
  394. package/src/utils/traverse.js +6 -0
  395. package/src/utils/treeGeometry.js +45 -0
  396. package/src/utils/triangulate.js +100 -0
  397. package/src/utils/tripsAt.js +16 -0
  398. package/src/utils/types.js +8 -0
  399. package/src/utils/{control.js → underEntry.js} +1 -2
  400. package/src/utils/update.js +18 -0
  401. package/src/utils/updateArea.js +40 -0
  402. package/src/utils/updateCamera.js +32 -0
  403. package/src/utils/updatePointLights.js +38 -0
  404. package/src/utils/updateWorldMatrix.js +47 -0
  405. package/src/utils/vehicleOffsets.js +8 -0
  406. package/src/utils/vehicles.js +65 -69
  407. package/src/utils/vertexNormals.js +30 -0
  408. package/src/utils/walk.js +181 -66
  409. package/src/utils/white.js +1 -0
  410. package/src/utils/worldLights.js +25 -0
  411. package/src/utils/wrap.js +1 -0
  412. package/dist/scene/gpu.js +0 -3
  413. package/dist/scene/gpu.js.map +0 -7
  414. package/dist/scene/lighting.js +0 -9
  415. package/dist/scene/lighting.js.map +0 -7
  416. package/dist/scene/model.js +0 -2
  417. package/dist/scene/model.js.map +0 -7
  418. package/dist/scene/picking.js +0 -2
  419. package/dist/scene/picking.js.map +0 -7
  420. package/dist/scene/pmtiles.js +0 -2
  421. package/dist/scene/pmtiles.js.map +0 -7
  422. package/dist/scene/render.js +0 -15
  423. package/dist/scene/render.js.map +0 -7
  424. package/dist/scene/sources.js +0 -2
  425. package/dist/scene/sources.js.map +0 -7
  426. package/dist/types/3d.js +0 -2
  427. package/dist/types/3d.js.map +0 -7
  428. package/dist/types/geojson.js +0 -2
  429. package/dist/types/geojson.js.map +0 -7
  430. package/dist/types/pmtiles.js +0 -2
  431. package/dist/types/pmtiles.js.map +0 -7
  432. package/dist/types/sunlight.js +0 -2
  433. package/dist/types/sunlight.js.map +0 -7
  434. package/dist/types/terrain.js +0 -24
  435. package/dist/types/terrain.js.map +0 -7
  436. package/dist/types/traffic.js +0 -41
  437. package/dist/types/traffic.js.map +0 -7
  438. package/dist/types/walk.js +0 -2
  439. package/dist/types/walk.js.map +0 -7
  440. package/dist/utils/control.js +0 -2
  441. package/dist/utils/control.js.map +0 -7
  442. package/dist/utils/lighting.js +0 -2
  443. package/dist/utils/lighting.js.map +0 -7
  444. package/dist/utils/model.js +0 -2
  445. package/dist/utils/model.js.map +0 -7
  446. package/dist/utils/picking.js +0 -2
  447. package/dist/utils/picking.js.map +0 -7
  448. package/dist/utils/pmtiles.js +0 -2
  449. package/dist/utils/pmtiles.js.map +0 -7
  450. package/dist/utils/scene.js +0 -2
  451. package/dist/utils/scene.js.map +0 -7
  452. package/dist/utils/shaders.js.map +0 -7
  453. package/dist/utils/sun.js +0 -2
  454. package/dist/utils/sun.js.map +0 -7
  455. package/dist/utils/terrain.js +0 -2
  456. package/dist/utils/terrain.js.map +0 -7
  457. package/src/scene/gpu.js +0 -438
  458. package/src/scene/lighting.js +0 -193
  459. package/src/scene/picking.js +0 -150
  460. package/src/scene/pmtiles.js +0 -94
  461. package/src/types/3d.js +0 -337
  462. package/src/types/geojson.js +0 -42
  463. package/src/types/pmtiles.js +0 -143
  464. package/src/types/sunlight.js +0 -142
  465. package/src/types/terrain.js +0 -331
  466. package/src/types/traffic.js +0 -356
  467. package/src/types/walk.js +0 -219
  468. package/src/utils/model.js +0 -178
  469. package/src/utils/pmtiles.js +0 -79
  470. package/src/utils/scene.js +0 -102
  471. package/src/utils/sun.js +0 -71
  472. package/src/utils/terrain.js +0 -78
package/dist/scene/gpu.js DELETED
@@ -1,3 +0,0 @@
1
- import{materialShaders as _}from"../utils/shaders.js";import{emptyNode as U,setParent as w,traverse as G}from"../utils/scene.js";async function B(r,e){let t=L.Layer.types["3d"]._renderers.get(e);if(t?._rendererReady&&await t._rendererReady.promise,!t){const o=Promise.withResolvers();t=r,r._rendererReady=o,o.promise.catch(()=>{}),L.Layer.types["3d"]._renderers.set(e,t);const x=l=>{throw o.reject(l),L.Layer.types["3d"]._renderers.delete(e),l},g=document.createElement("canvas");navigator.gpu||x(new Error("Layer3D requires WebGPU"));const f=await navigator.gpu.requestAdapter().catch(x);f||x(new Error("Unable to acquire a WebGPU adapter"));const i=await f.requestDevice().catch(x);i.addEventListener("uncapturederror",l=>{const p=L.Layer.types["3d"]._renderers.get(e);if(p?.renderer?.device===i)for(const v of p?._layers||[])v.fire("error",{error:l.error})}),i.lost.then(l=>{const p=L.Layer.types["3d"]._renderers.get(e);if(!p||p.renderer?.device!==i)return;const v=new Error(`WebGPU device lost: ${l.message||l.reason}`);for(const c of p._layers)c.fire("error",{error:v})});const u=g.getContext("webgpu");u||(i.destroy(),x(new Error("Unable to create a WebGPU canvas context")));const n=navigator.gpu.getPreferredCanvasFormat();u.configure({device:i,format:n,alphaMode:"premultiplied"}),r._shared=r,r._layers=new Set,r._sceneOrigin=r.location,r.scene=U(),r.camera={position:[0,0,0],up:[0,1,0],target:[0,0,0],viewMatrix:[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1],projectionMatrix:[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1],projectionViewMatrix:[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1],fov:45,aspect:1,near:.1,far:1e4},r.renderer={device:i,context:u,format:n,canvas:g,dpr:Math.min(window.devicePixelRatio,2)},r._initSunlight();const s=document.createElement("canvas");s.width=1,s.height=1,r.renderer.roofFallbackTexture={device:i,texture:i.createTexture({size:[1,1],format:"rgba8unorm",usage:GPUTextureUsage.TEXTURE_BINDING|GPUTextureUsage.COPY_DST|GPUTextureUsage.RENDER_ATTACHMENT}),sampler:i.createSampler({addressModeU:"clamp-to-edge",addressModeV:"clamp-to-edge"}),image:s,format:"rgba8unorm",srgb:!1,uploaded:null},t._size=null,g.className="leaflet-3d",g.style.cssText="position:absolute;top:0;left:0;pointer-events:none",g.setAttribute("role","img"),g.setAttribute("aria-label",r.options.ariaLabel);let a=e.getPane("webgpuPane");a||(a=e.createPane("webgpuPane",e.getContainer()),a.style.zIndex=450),a.append(g),e.on("move zoom rotate pitch resize viewreset layeradd layerremove",t._onMapChange,t),e.on("zoomstart",t._startZoom,t),e.on("zoomanim",t.update,t),e.on("zoomend",t._endZoom,t),o.resolve(),delete t._rendererReady,t._render(),L.Layer.types["3d"]._renderers.set(e,t)}const y=e.options.crs.project(t._sceneOrigin),h=e.options.crs.project(r.location),d=Math.cos(t._sceneOrigin.lat*Math.PI/180);r._terrainBaseY??=r.root.position[1],r.root.position[0]=(h.x-y.x)*d,r.root.position[1]=r._terrainBaseY,r.root.position[2]=-(h.y-y.y)*d,r._setTerrainHeight(),r.root.scale.fill(d/Math.cos(r.location.lat*Math.PI/180)),r._shared=t,r.renderer=t.renderer,r.scene=t.scene,r.camera=t.camera,t._layers.add(r),w(r.root,t.scene),G(r.root,o=>{if(o.geometry&&o.geometry.device!==t.renderer.device){const x=o.geometry,g=o.program._layerMaterial,f={};for(const u of["position","normal","color","uv","index"]){const n=x.attributes[u];if(!n)continue;const{data:s,size:a,count:l,normalized:p}=n;f[u]={data:s.slice(0,l*a),size:a,normalized:p}}const i=t.renderer.device;f.index?.data instanceof Uint8Array&&(f.index.data=Uint16Array.from(f.index.data));for(const[u,n]of Object.entries(f))n.size||=1,n.count=n.data.length/n.size,n.indexFormat=n.data instanceof Uint32Array?"uint32":"uint16",n.buffer=i.createBuffer({size:Math.max(4,n.data.byteLength),usage:u==="index"?GPUBufferUsage.INDEX|GPUBufferUsage.COPY_DST:GPUBufferUsage.VERTEX|GPUBufferUsage.COPY_DST}),i.queue.writeBuffer(n.buffer,0,n.data);o.geometry={device:i,attributes:f,drawRange:{start:0,count:f.index?.count||f.position.count}};for(const u of Object.values(x.attributes))u.buffer.destroy();o.bindGroup=null,o.boundTextures=[];for(const u of["baseTexture","metalTexture","emissiveTexture","occlusionTexture"]){const n=g[u];!n||n.device===i||(g[u]={...n,device:i,texture:i.createTexture({size:[n.image.width,n.image.height],format:n.format,usage:GPUTextureUsage.TEXTURE_BINDING|GPUTextureUsage.COPY_DST|GPUTextureUsage.RENDER_ATTACHMENT}),sampler:i.createSampler(n.samplerOptions),uploaded:null})}r._removeProgram(o.program),o.program=r._createProgram(g),o.device=i}o.texture&&o.texture.device!==t.renderer.device&&(o.texture={...o.texture,device:t.renderer.device,texture:t.renderer.device.createTexture({size:[o.texture.image.width,o.texture.image.height],format:o.texture.format,usage:GPUTextureUsage.TEXTURE_BINDING|GPUTextureUsage.COPY_DST|GPUTextureUsage.RENDER_ATTACHMENT}),sampler:t.renderer.device.createSampler(o.texture.samplerOptions),uploaded:null})}),t.update(),(r.header||r._geojson)&&r._updateArea()}function M(r,e){r.renderer.device.queue.onSubmittedWorkDone().then(()=>e.destroy(),t=>{r.fire("error",{error:t}),e.destroy()})}function R(r,e={}){const t=r.renderer.device,y=!!r.options.nightSparkle,h=_(e,y,e.terrain?L.Layer.types.terrain.elevationWGSL:""),{bindings:d,textured:o,hasTerrain:x}=h,g=t.createShaderModule({code:h.vertex}),f=t.createShaderModule({code:h.fragment});Promise.all([g.getCompilationInfo(),f.getCompilationInfo()]).then(a=>{const l=a.flatMap(p=>p.messages).filter(p=>p.type==="error");l.length&&r.fire("error",{error:new Error(`Unable to compile Layer3D WGSL: ${l.map(p=>p.message).join(`
2
- `)}`)})}).catch(a=>r.fire("error",{error:a}));const i=[{arrayStride:12,attributes:[{shaderLocation:0,offset:0,format:"float32x3"}]},{arrayStride:12,attributes:[{shaderLocation:1,offset:0,format:"float32x3"}]},e.vertexColors?{arrayStride:12,attributes:[{shaderLocation:2,offset:0,format:"float32x3"}]}:null,o?{arrayStride:8,attributes:[{shaderLocation:3,offset:0,format:"float32x2"}]}:null],u=[{binding:0,visibility:GPUShaderStage.VERTEX|GPUShaderStage.FRAGMENT,buffer:{type:"uniform",hasDynamicOffset:!0}},{binding:1,visibility:GPUShaderStage.VERTEX|GPUShaderStage.FRAGMENT,buffer:{type:"uniform"}}];x&&u.push({binding:2,visibility:GPUShaderStage.VERTEX,texture:{sampleType:"unfilterable-float",viewDimension:"2d"}});for(const a of d)u.push({binding:a.texture,visibility:GPUShaderStage.FRAGMENT,texture:{sampleType:"float",viewDimension:"2d"}}),u.push({binding:a.sampler,visibility:GPUShaderStage.FRAGMENT,sampler:{type:"filtering"}});const n=t.createBindGroupLayout({entries:u}),s=t.createPipelineLayout({bindGroupLayouts:[n,r.renderer.sunlight.layout]});return{device:t,vertex:g,fragment:f,bindings:d,vertexBuffers:i,bindGroupLayout:n,pipelineLayout:s,pipelineCache:new Map,cullMode:e.doubleSided?"none":"back",transparent:e.alphaMode==="BLEND",depthWrite:e.alphaMode!=="BLEND",depthTest:e.depthTest!==!1,terrain:e.terrain,nightLight:!!e.nightLight,nightSparkle:y,uniforms:{baseColor:{value:e.color||[1,1,1]},metallic:{value:e.metallic??0},roughness:{value:e.roughness??.85},opacity:{value:e.opacity??1},alphaCutoff:{value:e.alphaCutoff??.5},occlusionStrength:{value:e.occlusionStrength??1},emissive:{value:e.emissive||[0,0,0]},...e.baseTexture?{baseTexture:{value:e.baseTexture}}:{},...e.metalTexture?{metalTexture:{value:e.metalTexture}}:{},...e.emissiveTexture?{emissiveTexture:{value:e.emissiveTexture}}:{},...e.occlusionTexture?{occlusionTexture:{value:e.occlusionTexture}}:{},...e.roofTexture?{roofTexture:{value:null}}:{}},_layerMaterial:e}}function C(r){r.pipelineCache.clear()}function D(r,e,t={},y=0){const{device:h}=r.renderer,d={};for(const[x,g]of Object.entries(e)){const f=new Float32Array(g),i=h.createBuffer({size:Math.max(4,f.byteLength),usage:GPUBufferUsage.VERTEX|GPUBufferUsage.COPY_DST|y});h.queue.writeBuffer(i,0,f),d[x]={size:3,data:f,count:f.length/3,buffer:i}}const o={...U(),device:h,geometry:{device:h,attributes:d,drawRange:{start:0,count:d.position.count}},program:r._createProgram({vertexColors:!0,doubleSided:!0,...t}),id:L.Layer.types["3d"]._nextId++,renderOrder:0,extras:{}};return r.add(o),o}function N(r,e){if(e){r.remove(e);for(const t of Object.values(e.geometry.attributes))t.buffer.destroy();r._removeProgram(e.program)}}function z(r,e,t,y,h){const{geometry:d,program:o}=e,x=r.renderer.device,g=`${y}:${h}`;let f=o.pipelineCache.get(g);f||(f=x.createRenderPipeline({layout:o.pipelineLayout,vertex:{module:o.vertex,entryPoint:"vertexMain",buffers:o.vertexBuffers},fragment:{module:o.fragment,entryPoint:"fragmentMain",targets:[{format:r.renderer.format,blend:o.transparent?{color:{srcFactor:"src-alpha",dstFactor:"one-minus-src-alpha",operation:"add"},alpha:{srcFactor:"one",dstFactor:"one-minus-src-alpha",operation:"add"}}:void 0,writeMask:GPUColorWrite.ALL}]},primitive:{topology:"triangle-list",cullMode:y,frontFace:h},depthStencil:{format:"depth24plus",depthWriteEnabled:o.depthWrite,depthCompare:o.depthTest===!1?"always":"less-equal"}}),o.pipelineCache.set(g,f));const i=o.uniforms,u=r.renderer,n=u.uniformSlot++*256,s=u.uniformData,a=n/4;s.set(e.worldMatrix,a),s.set(i.baseColor.value,a+16),s[a+19]=1,s[a+20]=i.metallic.value,s[a+21]=i.roughness.value,s[a+22]=i.opacity.value,s[a+23]=i.alphaCutoff.value,s.set(i.emissive.value,a+24),s[a+27]=i.occlusionStrength.value,s[a+28]=e.terrain?.[0]??0,s[a+29]=e.terrain?.[1]??0,s[a+30]=e.terrain?.[2]??0,s[a+31]=e.terrain?.[3]??0,s[a+32]=e.highlight?.[0]??0,s[a+33]=e.highlight?.[1]??0,s[a+34]=o.nightSparkle?s[55]:0,s[a+35]=0;const l=e._textures||=[];l.length=0;for(const c of o.bindings){const m=i[c.name]?.value;if(!m)throw new Error(`Missing Layer3D texture: ${c.name}`);m.uploaded!==m.image&&(x.queue.copyExternalImageToTexture({source:m.image,flipY:!!m.flipY},{texture:m.texture},[m.image.width,m.image.height]),m.uploaded=m.image),l.push(m)}let p=!e.bindGroup||e.boundBuffer!==u.uniformBuffer||l.length!==e.boundTextures.length;for(let c=0;!p&&c<l.length;c++)(l[c].texture!==e.boundTextures[c][0]||l[c].sampler!==e.boundTextures[c][1])&&(p=!0);if(p){const c=[{binding:0,resource:{buffer:u.uniformBuffer,size:144}},{binding:1,resource:{buffer:u.uniformBuffer,size:240}}];o.terrain&&c.push({binding:2,resource:o.terrain.texture.createView()}),e.boundBuffer=u.uniformBuffer;const m=e.boundTextures||=[];m.length=l.length;for(let T=0;T<l.length;T++){const P=o.bindings[T],b=l[T];c.push({binding:P.texture,resource:b.texture.createView()}),c.push({binding:P.sampler,resource:b.sampler}),m[T]||=[],m[T][0]=b.texture,m[T][1]=b.sampler}e.bindGroup=x.createBindGroup({layout:o.bindGroupLayout,entries:c})}t.setPipeline(f),t.setBindGroup(0,e.bindGroup,[n]),t.setVertexBuffer(0,d.attributes.position.buffer),t.setVertexBuffer(1,d.attributes.normal.buffer),d.attributes.color&&t.setVertexBuffer(2,d.attributes.color.buffer),d.attributes.uv&&t.setVertexBuffer(3,d.attributes.uv.buffer);for(const c of Object.values(d.attributes))c.needsUpdate&&(x.queue.writeBuffer(c.buffer,0,c.data),c.needsUpdate=!1,d.bounds=null);const v=d.attributes.index;v?(t.setIndexBuffer(v.buffer,v.indexFormat),t.drawIndexed(d.drawRange.count,1,d.drawRange.start,0,0)):t.draw(d.drawRange.count,1,d.drawRange.start,0)}export{B as attach,D as createMesh,R as createProgram,M as destroyTexture,N as disposeMesh,z as drawGeometry,C as removeProgram};
3
- //# sourceMappingURL=gpu.js.map
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../src/scene/gpu.js"],
4
- "sourcesContent": ["import { materialShaders } from '../utils/shaders.js';\nimport { emptyNode, setParent, traverse } from '../utils/scene.js';\n\n/** WebGPU device attachment, materials/pipelines and draw calls. */\n/**\n * Join/create this map's shared scene and rebuild GPU objects if its context changed.\n * Buffer/program handles belong to one context; typed arrays and decoded images do not.\n * @private\n */\nexport async function attach(backend, map) {\n let shared = L.Layer.types['3d']._renderers.get(map);\n if (shared?._rendererReady) {\n await shared._rendererReady.promise;\n }\n if (!shared) {\n const rendererReady = Promise.withResolvers();\n shared = backend;\n backend._rendererReady = rendererReady;\n rendererReady.promise.catch(() => {});\n L.Layer.types['3d']._renderers.set(map, shared);\n const fail = error => {\n rendererReady.reject(error);\n L.Layer.types['3d']._renderers.delete(map);\n throw error;\n };\n const canvas = document.createElement('canvas');\n if (!navigator.gpu) fail(new Error('Layer3D requires WebGPU'));\n const adapter = await navigator.gpu.requestAdapter().catch(fail);\n if (!adapter) fail(new Error('Unable to acquire a WebGPU adapter'));\n const device = await adapter.requestDevice().catch(fail);\n device.addEventListener('uncapturederror', event => {\n const owner = L.Layer.types['3d']._renderers.get(map);\n if (owner?.renderer?.device !== device) return;\n for (const layer of owner?._layers || []) layer.fire('error', { error: event.error });\n });\n device.lost.then(info => {\n const owner = L.Layer.types['3d']._renderers.get(map);\n if (!owner || owner.renderer?.device !== device) return;\n const error = new Error(`WebGPU device lost: ${info.message || info.reason}`);\n for (const layer of owner._layers) layer.fire('error', { error });\n });\n const context = canvas.getContext('webgpu');\n if (!context) {\n device.destroy();\n fail(new Error('Unable to create a WebGPU canvas context'));\n }\n const format = navigator.gpu.getPreferredCanvasFormat();\n context.configure({ device, format, alphaMode: 'premultiplied' });\n backend._shared = backend;\n backend._layers = new Set();\n backend._sceneOrigin = backend.location;\n backend.scene = emptyNode();\n // Perspective camera state: fov in degrees, near/far in scene metres.\n backend.camera = {\n position: [0, 0, 0],\n up: [0, 1, 0],\n target: [0, 0, 0],\n viewMatrix: [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1],\n projectionMatrix: [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1],\n projectionViewMatrix: [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1],\n fov: 45,\n aspect: 1,\n near: 0.1,\n far: 10000,\n };\n backend.renderer = { device, context, format, canvas, dpr: Math.min(window.devicePixelRatio, 2) };\n backend._initSunlight();\n const emptyImage = document.createElement('canvas');\n emptyImage.width = 1;\n emptyImage.height = 1;\n backend.renderer.roofFallbackTexture = {\n device,\n texture: device.createTexture({\n size: [1, 1],\n format: 'rgba8unorm',\n usage: GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.COPY_DST | GPUTextureUsage.RENDER_ATTACHMENT,\n }),\n sampler: device.createSampler({\n addressModeU: 'clamp-to-edge', addressModeV: 'clamp-to-edge',\n }),\n image: emptyImage, format: 'rgba8unorm', srgb: false, uploaded: null,\n };\n shared._size = null;\n canvas.className = 'leaflet-3d';\n canvas.style.cssText = 'position:absolute;top:0;left:0;pointer-events:none';\n canvas.setAttribute('role', 'img');\n canvas.setAttribute('aria-label', backend.options.ariaLabel);\n let pane = map.getPane('webgpuPane');\n if (!pane) {\n pane = map.createPane('webgpuPane', map.getContainer());\n pane.style.zIndex = 450;\n }\n pane.append(canvas);\n map.on('move zoom rotate pitch resize viewreset layeradd layerremove', shared._onMapChange, shared);\n map.on('zoomstart', shared._startZoom, shared);\n map.on('zoomanim', shared.update, shared);\n map.on('zoomend', shared._endZoom, shared);\n rendererReady.resolve();\n delete shared._rendererReady;\n shared._render();\n L.Layer.types['3d']._renderers.set(map, shared);\n }\n const origin = map.options.crs.project(shared._sceneOrigin);\n const point = map.options.crs.project(backend.location);\n const metres = Math.cos(shared._sceneOrigin.lat * Math.PI / 180);\n backend._terrainBaseY ??= backend.root.position[1];\n backend.root.position[0] = (point.x - origin.x) * metres;\n backend.root.position[1] = backend._terrainBaseY;\n backend.root.position[2] = -(point.y - origin.y) * metres;\n backend._setTerrainHeight();\n // Each group's metres are measured at its own latitude, not the shared camera origin.\n backend.root.scale.fill(metres / Math.cos(backend.location.lat * Math.PI / 180));\n backend._shared = shared;\n backend.renderer = shared.renderer;\n backend.scene = shared.scene;\n backend.camera = shared.camera;\n shared._layers.add(backend);\n setParent(backend.root, shared.scene);\n traverse(backend.root, object => {\n if (object.geometry && object.geometry.device !== shared.renderer.device) {\n const geometry = object.geometry;\n const material = object.program._layerMaterial;\n // Retain packed CPU attributes, never old-context GPU buffer handles.\n const attributes = {};\n for (const name of ['position', 'normal', 'color', 'uv', 'index']) {\n const attribute = geometry.attributes[name];\n if (!attribute) continue;\n const { data, size, count, normalized } = attribute;\n attributes[name] = { data: data.slice(0, count * size), size, normalized };\n }\n const device = shared.renderer.device;\n if (attributes.index?.data instanceof Uint8Array) {\n attributes.index.data = Uint16Array.from(attributes.index.data);\n }\n for (const [name, attribute] of Object.entries(attributes)) {\n attribute.size ||= 1;\n attribute.count = attribute.data.length / attribute.size;\n attribute.indexFormat = attribute.data instanceof Uint32Array ? 'uint32' : 'uint16';\n attribute.buffer = device.createBuffer({\n size: Math.max(4, attribute.data.byteLength),\n usage: name === 'index'\n ? GPUBufferUsage.INDEX | GPUBufferUsage.COPY_DST\n : GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_DST,\n });\n device.queue.writeBuffer(attribute.buffer, 0, attribute.data);\n }\n object.geometry = {\n device,\n attributes,\n drawRange: { start: 0, count: attributes.index?.count || attributes.position.count },\n };\n for (const attribute of Object.values(geometry.attributes)) attribute.buffer.destroy();\n object.bindGroup = null;\n object.boundTextures = [];\n for (const key of ['baseTexture', 'metalTexture', 'emissiveTexture', 'occlusionTexture']) {\n const texture = material[key];\n if (!texture || texture.device === device) continue;\n material[key] = {\n ...texture,\n device,\n texture: device.createTexture({\n size: [texture.image.width, texture.image.height],\n format: texture.format,\n usage: GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.COPY_DST | GPUTextureUsage.RENDER_ATTACHMENT,\n }),\n sampler: device.createSampler(texture.samplerOptions),\n uploaded: null,\n };\n }\n backend._removeProgram(object.program);\n object.program = backend._createProgram(material);\n object.device = device;\n }\n if (object.texture && object.texture.device !== shared.renderer.device) {\n object.texture = {\n ...object.texture,\n device: shared.renderer.device,\n texture: shared.renderer.device.createTexture({\n size: [object.texture.image.width, object.texture.image.height],\n format: object.texture.format,\n usage: GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.COPY_DST | GPUTextureUsage.RENDER_ATTACHMENT,\n }),\n sampler: shared.renderer.device.createSampler(object.texture.samplerOptions),\n uploaded: null,\n };\n }\n });\n shared.update();\n if (backend.header || backend._geojson) backend._updateArea();\n}\n\nexport function destroyTexture(backend, texture) {\n backend.renderer.device.queue.onSubmittedWorkDone().then(() => texture.destroy(), error => {\n backend.fire('error', { error });\n texture.destroy();\n });\n}\n\nexport function createProgram(backend, material = {}) {\n const device = backend.renderer.device;\n const sparkle = Boolean(backend.options.nightSparkle);\n const shaders = materialShaders(material, sparkle, material.terrain ? L.Layer.types.terrain.elevationWGSL : '');\n const { bindings, textured, hasTerrain } = shaders;\n const vertex = device.createShaderModule({ code: shaders.vertex });\n const fragment = device.createShaderModule({ code: shaders.fragment });\n Promise.all([vertex.getCompilationInfo(), fragment.getCompilationInfo()]).then(infos => {\n const errors = infos.flatMap(info => info.messages).filter(message => message.type === 'error');\n if (errors.length) {\n backend.fire('error', {\n error: new Error(`Unable to compile Layer3D WGSL: ${errors.map(error => error.message).join('\\n')}`),\n });\n }\n }).catch(error => backend.fire('error', { error }));\n const vertexBuffers = [\n { arrayStride: 12, attributes: [{ shaderLocation: 0, offset: 0, format: 'float32x3' }] },\n { arrayStride: 12, attributes: [{ shaderLocation: 1, offset: 0, format: 'float32x3' }] },\n material.vertexColors ? { arrayStride: 12, attributes: [{ shaderLocation: 2, offset: 0, format: 'float32x3' }] } : null,\n textured ? { arrayStride: 8, attributes: [{ shaderLocation: 3, offset: 0, format: 'float32x2' }] } : null,\n ];\n const bindGroupEntries = [{\n binding: 0,\n visibility: GPUShaderStage.VERTEX | GPUShaderStage.FRAGMENT,\n buffer: { type: 'uniform', hasDynamicOffset: true },\n }, {\n binding: 1,\n visibility: GPUShaderStage.VERTEX | GPUShaderStage.FRAGMENT,\n buffer: { type: 'uniform' },\n }];\n if (hasTerrain) {\n bindGroupEntries.push({\n binding: 2,\n visibility: GPUShaderStage.VERTEX,\n texture: { sampleType: 'unfilterable-float', viewDimension: '2d' },\n });\n }\n for (const texture of bindings) {\n bindGroupEntries.push({\n binding: texture.texture,\n visibility: GPUShaderStage.FRAGMENT,\n texture: { sampleType: 'float', viewDimension: '2d' },\n });\n bindGroupEntries.push({\n binding: texture.sampler,\n visibility: GPUShaderStage.FRAGMENT,\n sampler: { type: 'filtering' },\n });\n }\n const bindGroupLayout = device.createBindGroupLayout({ entries: bindGroupEntries });\n const pipelineLayout = device.createPipelineLayout({ bindGroupLayouts: [bindGroupLayout, backend.renderer.sunlight.layout] });\n return {\n device,\n vertex,\n fragment,\n bindings,\n vertexBuffers,\n bindGroupLayout,\n pipelineLayout,\n pipelineCache: new Map(),\n cullMode: material.doubleSided ? 'none' : 'back',\n transparent: material.alphaMode === 'BLEND',\n depthWrite: material.alphaMode !== 'BLEND',\n depthTest: material.depthTest !== false,\n terrain: material.terrain,\n nightLight: Boolean(material.nightLight),\n nightSparkle: sparkle,\n uniforms: {\n baseColor: { value: material.color || [1, 1, 1] },\n metallic: { value: material.metallic ?? 0 },\n roughness: { value: material.roughness ?? 0.85 },\n opacity: { value: material.opacity ?? 1 },\n alphaCutoff: { value: material.alphaCutoff ?? 0.5 },\n occlusionStrength: { value: material.occlusionStrength ?? 1 },\n emissive: { value: material.emissive || [0, 0, 0] },\n ...(material.baseTexture ? { baseTexture: { value: material.baseTexture } } : {}),\n ...(material.metalTexture ? { metalTexture: { value: material.metalTexture } } : {}),\n ...(material.emissiveTexture ? { emissiveTexture: { value: material.emissiveTexture } } : {}),\n ...(material.occlusionTexture ? { occlusionTexture: { value: material.occlusionTexture } } : {}),\n ...(material.roofTexture ? { roofTexture: { value: null } } : {}),\n },\n _layerMaterial: material,\n };\n}\n\nexport function removeProgram(program) {\n program.pipelineCache.clear();\n}\n\n/**\n * Add a non-indexed, vertex-coloured mesh from flat vec3 arrays `{ position, normal, color }` in layer-local metres.\n * `usage` adds GPUBufferUsage flags to the vertex buffers (e.g. STORAGE for compute passes).\n */\nexport function createMesh(backend, data, material = {}, usage = 0) {\n const { device } = backend.renderer, attributes = {};\n for (const [name, values] of Object.entries(data)) {\n const array = new Float32Array(values);\n const buffer = device.createBuffer({ size: Math.max(4, array.byteLength), usage: GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_DST | usage });\n device.queue.writeBuffer(buffer, 0, array);\n attributes[name] = { size: 3, data: array, count: array.length / 3, buffer };\n }\n const mesh = {\n ...emptyNode(),\n device,\n geometry: { device, attributes, drawRange: { start: 0, count: attributes.position.count } },\n program: backend._createProgram({ vertexColors: true, doubleSided: true, ...material }),\n id: L.Layer.types['3d']._nextId++, renderOrder: 0, extras: {},\n };\n backend.add(mesh);\n return mesh;\n}\n\nexport function disposeMesh(backend, mesh) {\n if (!mesh) return;\n backend.remove(mesh);\n for (const attribute of Object.values(mesh.geometry.attributes)) attribute.buffer.destroy();\n backend._removeProgram(mesh.program);\n}\n\n/** Upload retained CPU data and draw one mesh in the active WebGPU render pass. */\nexport function drawGeometry(backend, mesh, pass, cullMode, frontFace) {\n const { geometry, program } = mesh;\n const device = backend.renderer.device;\n const pipelineKey = `${cullMode}:${frontFace}`;\n let pipeline = program.pipelineCache.get(pipelineKey);\n if (!pipeline) {\n pipeline = device.createRenderPipeline({\n layout: program.pipelineLayout,\n vertex: {\n module: program.vertex,\n entryPoint: 'vertexMain',\n buffers: program.vertexBuffers,\n },\n fragment: {\n module: program.fragment,\n entryPoint: 'fragmentMain',\n targets: [{\n format: backend.renderer.format,\n blend: program.transparent ? {\n color: { srcFactor: 'src-alpha', dstFactor: 'one-minus-src-alpha', operation: 'add' },\n alpha: { srcFactor: 'one', dstFactor: 'one-minus-src-alpha', operation: 'add' },\n } : undefined,\n writeMask: GPUColorWrite.ALL,\n }],\n },\n primitive: { topology: 'triangle-list', cullMode, frontFace },\n depthStencil: {\n format: 'depth24plus',\n depthWriteEnabled: program.depthWrite,\n depthCompare: program.depthTest === false ? 'always' : 'less-equal',\n },\n });\n program.pipelineCache.set(pipelineKey, pipeline);\n }\n\n const uniforms = program.uniforms;\n const renderer = backend.renderer;\n const offset = renderer.uniformSlot++ * 256;\n const data = renderer.uniformData, base = offset / 4;\n data.set(mesh.worldMatrix, base);\n data.set(uniforms.baseColor.value, base + 16);\n data[base + 19] = 1;\n data[base + 20] = uniforms.metallic.value;\n data[base + 21] = uniforms.roughness.value;\n data[base + 22] = uniforms.opacity.value;\n data[base + 23] = uniforms.alphaCutoff.value;\n data.set(uniforms.emissive.value, base + 24);\n data[base + 27] = uniforms.occlusionStrength.value;\n data[base + 28] = mesh.terrain?.[0] ?? 0;\n data[base + 29] = mesh.terrain?.[1] ?? 0;\n data[base + 30] = mesh.terrain?.[2] ?? 0;\n data[base + 31] = mesh.terrain?.[3] ?? 0;\n data[base + 32] = mesh.highlight?.[0] ?? 0;\n data[base + 33] = mesh.highlight?.[1] ?? 0;\n data[base + 34] = program.nightSparkle ? data[55] : 0;\n data[base + 35] = 0;\n\n const textures = mesh._textures ||= [];\n textures.length = 0;\n for (const binding of program.bindings) {\n const texture = uniforms[binding.name]?.value;\n if (!texture) throw new Error(`Missing Layer3D texture: ${binding.name}`);\n if (texture.uploaded !== texture.image) {\n device.queue.copyExternalImageToTexture(\n { source: texture.image, flipY: Boolean(texture.flipY) },\n { texture: texture.texture },\n [texture.image.width, texture.image.height],\n );\n texture.uploaded = texture.image;\n }\n textures.push(texture);\n }\n let bindingsChanged = !mesh.bindGroup || mesh.boundBuffer !== renderer.uniformBuffer ||\n textures.length !== mesh.boundTextures.length;\n for (let i = 0; !bindingsChanged && i < textures.length; i++) {\n if (textures[i].texture !== mesh.boundTextures[i][0] ||\n textures[i].sampler !== mesh.boundTextures[i][1]) bindingsChanged = true;\n }\n if (bindingsChanged) {\n const entries = [\n { binding: 0, resource: { buffer: renderer.uniformBuffer, size: 144 } },\n { binding: 1, resource: { buffer: renderer.uniformBuffer, size: 240 } },\n ];\n if (program.terrain) entries.push({ binding: 2, resource: program.terrain.texture.createView() });\n mesh.boundBuffer = renderer.uniformBuffer;\n const boundTextures = mesh.boundTextures ||= [];\n boundTextures.length = textures.length;\n for (let i = 0; i < textures.length; i++) {\n const binding = program.bindings[i], texture = textures[i];\n entries.push({ binding: binding.texture, resource: texture.texture.createView() });\n entries.push({ binding: binding.sampler, resource: texture.sampler });\n boundTextures[i] ||= [];\n boundTextures[i][0] = texture.texture;\n boundTextures[i][1] = texture.sampler;\n }\n mesh.bindGroup = device.createBindGroup({\n layout: program.bindGroupLayout,\n entries,\n });\n }\n pass.setPipeline(pipeline);\n pass.setBindGroup(0, mesh.bindGroup, [offset]);\n pass.setVertexBuffer(0, geometry.attributes.position.buffer);\n pass.setVertexBuffer(1, geometry.attributes.normal.buffer);\n if (geometry.attributes.color) pass.setVertexBuffer(2, geometry.attributes.color.buffer);\n if (geometry.attributes.uv) pass.setVertexBuffer(3, geometry.attributes.uv.buffer);\n for (const attribute of Object.values(geometry.attributes)) {\n if (!attribute.needsUpdate) continue;\n device.queue.writeBuffer(attribute.buffer, 0, attribute.data);\n attribute.needsUpdate = false;\n geometry.bounds = null;\n }\n const index = geometry.attributes.index;\n if (index) {\n pass.setIndexBuffer(index.buffer, index.indexFormat);\n pass.drawIndexed(geometry.drawRange.count, 1, geometry.drawRange.start, 0, 0);\n } else {\n pass.draw(geometry.drawRange.count, 1, geometry.drawRange.start, 0);\n }\n}\n"],
5
- "mappings": "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",
6
- "names": ["materialShaders", "emptyNode", "setParent", "traverse", "attach", "backend", "map", "shared", "rendererReady", "fail", "error", "canvas", "adapter", "device", "event", "owner", "layer", "info", "context", "format", "emptyImage", "pane", "origin", "point", "metres", "object", "geometry", "material", "attributes", "name", "attribute", "data", "size", "count", "normalized", "key", "texture", "destroyTexture", "createProgram", "sparkle", "shaders", "bindings", "textured", "hasTerrain", "vertex", "fragment", "infos", "errors", "message", "vertexBuffers", "bindGroupEntries", "bindGroupLayout", "pipelineLayout", "removeProgram", "program", "createMesh", "usage", "values", "array", "buffer", "mesh", "disposeMesh", "drawGeometry", "pass", "cullMode", "frontFace", "pipelineKey", "pipeline", "uniforms", "renderer", "offset", "base", "textures", "binding", "bindingsChanged", "i", "entries", "boundTextures", "index"]
7
- }
@@ -1,9 +0,0 @@
1
- import{lightGrid as U,worldLights as P}from"../utils/lighting.js";import{computeBounds as T}from"../utils/geometry.js";import{traverse as L,updateCamera as _}from"../utils/scene.js";function O(o){const t=o.renderer.device,a=t.createBindGroupLayout({entries:[{binding:0,visibility:GPUShaderStage.VERTEX|GPUShaderStage.FRAGMENT,buffer:{type:"uniform"}},{binding:1,visibility:GPUShaderStage.FRAGMENT,texture:{sampleType:"depth"}},{binding:2,visibility:GPUShaderStage.FRAGMENT,sampler:{type:"comparison"}},{binding:3,visibility:GPUShaderStage.FRAGMENT,buffer:{type:"read-only-storage"}}]}),s=t.createBuffer({size:80,usage:GPUBufferUsage.UNIFORM|GPUBufferUsage.COPY_DST}),d=t.createSampler({compare:"less-equal",minFilter:"linear",magFilter:"linear"}),u=t.createBuffer({size:32,usage:GPUBufferUsage.STORAGE|GPUBufferUsage.COPY_DST});o.renderer.sunlight={layout:a,buffer:s,sampler:d,lights:u,size:0};const r=new Float32Array(20);r.set([1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1]),t.queue.writeBuffer(s,0,r),o._resizeSunlight(1)}function A(o,t){const a=o.renderer.device,s=o.renderer.sunlight;s.size!==t&&(s.texture&&o._destroyTexture(s.texture),s.size=t,s.texture=a.createTexture({size:[t,t],format:"depth32float",usage:GPUTextureUsage.RENDER_ATTACHMENT|GPUTextureUsage.TEXTURE_BINDING|GPUTextureUsage.COPY_SRC}),o._bindSunlight())}function D(o){const t=o.renderer.sunlight;t.bindGroup=o.renderer.device.createBindGroup({layout:t.layout,entries:[{binding:0,resource:{buffer:t.buffer}},{binding:1,resource:t.texture.createView()},{binding:2,resource:t.sampler},{binding:3,resource:{buffer:t.lights}}]})}function z(o){const{device:t,sunlight:a}=o.renderer,s=[];for(const i of o._layers)!i.options.nightLight||!i.root.visible||L(i.root,n=>{if(!n.visible)return!0;n.extras?.lights&&s.push(n)});if(a.lightMeshes?.length===s.length&&s.every((i,n)=>a.lightMeshes[n].mesh===i&&a.lightMeshes[n].lights===i.extras.lights&&i.worldMatrix.every((p,c)=>p===a.lightMeshes[n].matrix[c])))return;const d=s.map(i=>{const n=i._worldLights,p=i.worldMatrix,c=i.extras.lights;if(n?.lights===c&&p.every((S,v)=>S===n.matrix[v]))return n.data;const w=P(c,p);return i._worldLights={lights:c,matrix:[...p],data:w},w}),{data:u,count:r}=U(d,t.limits.maxStorageBufferBindingSize);a.lights.size<u.byteLength&&(o._destroyTexture(a.lights),a.lights=t.createBuffer({size:u.byteLength,usage:GPUBufferUsage.STORAGE|GPUBufferUsage.COPY_DST}),o._bindSunlight()),t.queue.writeBuffer(a.lights,0,u),a.lightCount=r,a.lightMeshes=s.map(i=>({mesh:i,lights:i.extras.lights,matrix:[...i.worldMatrix]}))}function F(o,t,a,s){const d=o.renderer,u=d.device,r=d.sunlight;if(!a.length||!s||s.altitude<3){if(!r.enabled)return;const e=new Float32Array(20);e.set([1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1]),u.queue.writeBuffer(r.buffer,0,e),r.enabled=!1;return}const i=new Float32Array(20);r.enabled=!0,o._resizeSunlight(Math.min(2048,u.limits.maxTextureDimension2D));const n=[1/0,1/0,1/0],p=[-1/0,-1/0,-1/0];for(const e of a){e.geometry.bounds||T(e.geometry);const f=e.geometry.bounds,g=new DOMMatrix(e.worldMatrix);for(let l=0;l<8;l++){const h=new DOMPoint(...n.map((y,M)=>l&1<<M?f.max[M]:f.min[M]),1).matrixTransform(g);for(let y=0;y<3;y++){const M=[h.x,h.y,h.z][y]/h.w;n[y]=Math.min(n[y],M),p[y]=Math.max(p[y],M)}}}n[1]=Math.min(0,n[1]);const c=Math.max(100,Math.hypot(...n.map((e,f)=>p[f]-e))),w=n.map((e,f)=>(e+p[f])/2),S={position:w.map((e,f)=>e+s.direction[f]*c*2),target:w,up:[0,0,-1],fov:45,aspect:1,near:1,far:c*5,viewMatrix:[],projectionMatrix:[],projectionViewMatrix:[]};_(S);const v=new DOMMatrix(S.viewMatrix),B=[1/0,1/0,1/0],x=[-1/0,-1/0,-1/0];for(let e=0;e<8;e++){const f=new DOMPoint(...n.map((g,l)=>e&1<<l?p[l]:g),1).matrixTransform(v);[f.x,f.y,f.z].forEach((g,l)=>{B[l]=Math.min(B[l],g-20),x[l]=Math.max(x[l],g+20)})}const b=B.map((e,f)=>x[f]-e),G=new DOMMatrix([2/b[0],0,0,0,0,2/b[1],0,0,0,0,-1/b[2],0,-(x[0]+B[0])/b[0],-(x[1]+B[1])/b[1],x[2]/b[2],1]);if(i.set(G.multiply(v).toFloat32Array()),i[16]=1,u.queue.writeBuffer(r.buffer,0,i),!r.pipeline){r.meshLayout=u.createBindGroupLayout({entries:[{binding:0,visibility:GPUShaderStage.VERTEX,buffer:{type:"uniform",hasDynamicOffset:!0}}]}),r.depthLayout=u.createBindGroupLayout({entries:[{binding:0,visibility:GPUShaderStage.VERTEX,buffer:{type:"uniform"}}]}),r.depthBindGroup=u.createBindGroup({layout:r.depthLayout,entries:[{binding:0,resource:{buffer:r.buffer}}]});const e=u.createShaderModule({code:`
2
- struct Mesh { world: mat4x4<f32> };
3
- @group(0) @binding(0) var<uniform> mesh: Mesh;
4
- @group(1) @binding(0) var<uniform> matrix: mat4x4<f32>;
5
- @vertex fn main(@location(0) position: vec3<f32>) -> @builtin(position) vec4<f32> {
6
- return matrix * mesh.world * vec4<f32>(position, 1.0);
7
- }
8
- `});r.pipeline=u.createRenderPipeline({layout:u.createPipelineLayout({bindGroupLayouts:[r.meshLayout,r.depthLayout]}),vertex:{module:e,entryPoint:"main",buffers:[{arrayStride:12,attributes:[{shaderLocation:0,offset:0,format:"float32x3"}]}]},primitive:{topology:"triangle-list",cullMode:"none"},depthStencil:{format:"depth32float",depthWriteEnabled:!0,depthCompare:"less",depthBias:2,depthBiasSlopeScale:2}})}const m=t.beginRenderPass({colorAttachments:[],depthStencilAttachment:{view:r.texture.createView(),depthClearValue:1,depthLoadOp:"clear",depthStoreOp:"store"}});m.setPipeline(r.pipeline),m.setBindGroup(1,r.depthBindGroup);for(const e of a){const f=d.uniformSlot++*256;d.uniformData.set(e.worldMatrix,f/4),e._shadowBuffer!==d.uniformBuffer&&(e._shadowBuffer=d.uniformBuffer,e._shadowBindGroup=u.createBindGroup({layout:r.meshLayout,entries:[{binding:0,resource:{buffer:d.uniformBuffer,size:64}}]}));for(const h of Object.values(e.geometry.attributes))h.needsUpdate&&(u.queue.writeBuffer(h.buffer,0,h.data),h.needsUpdate=!1);m.setBindGroup(0,e._shadowBindGroup,[f]),m.setVertexBuffer(0,e.geometry.attributes.position.buffer);const g=e.geometry.attributes.index,l=e.geometry.drawRange;g?(m.setIndexBuffer(g.buffer,g.indexFormat),m.drawIndexed(l.count,1,l.start,0,0)):m.draw(l.count,1,l.start,0)}m.end()}export{D as bindSunlight,O as initSunlight,F as renderSunlight,A as resizeSunlight,z as updatePointLights};
9
- //# sourceMappingURL=lighting.js.map
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../src/scene/lighting.js"],
4
- "sourcesContent": ["import { lightGrid, worldLights } from '../utils/lighting.js';\r\nimport { computeBounds } from '../utils/geometry.js';\r\nimport { traverse, updateCamera } from '../utils/scene.js';\r\n\r\n/** Sunlight shadow maps and night point lights. */\r\nexport function initSunlight(backend) {\r\n const device = backend.renderer.device;\r\n const layout = device.createBindGroupLayout({ entries: [\r\n { binding: 0, visibility: GPUShaderStage.VERTEX | GPUShaderStage.FRAGMENT, buffer: { type: 'uniform' } },\r\n { binding: 1, visibility: GPUShaderStage.FRAGMENT, texture: { sampleType: 'depth' } },\r\n { binding: 2, visibility: GPUShaderStage.FRAGMENT, sampler: { type: 'comparison' } },\r\n { binding: 3, visibility: GPUShaderStage.FRAGMENT, buffer: { type: 'read-only-storage' } },\r\n ] });\r\n const buffer = device.createBuffer({ size: 80, usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST });\r\n const sampler = device.createSampler({ compare: 'less-equal', minFilter: 'linear', magFilter: 'linear' });\r\n const lights = device.createBuffer({ size: 32, usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_DST });\r\n backend.renderer.sunlight = { layout, buffer, sampler, lights, size: 0 };\r\n const values = new Float32Array(20);\r\n values.set([1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]);\r\n device.queue.writeBuffer(buffer, 0, values);\r\n backend._resizeSunlight(1);\r\n}\r\n\r\nexport function resizeSunlight(backend, size) {\r\n const device = backend.renderer.device, sun = backend.renderer.sunlight;\r\n if (sun.size === size) return;\r\n if (sun.texture) backend._destroyTexture(sun.texture);\r\n sun.size = size;\r\n sun.texture = device.createTexture({\r\n size: [size, size], format: 'depth32float',\r\n usage: GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.COPY_SRC,\r\n });\r\n backend._bindSunlight();\r\n}\r\n\r\nexport function bindSunlight(backend) {\r\n const sun = backend.renderer.sunlight;\r\n sun.bindGroup = backend.renderer.device.createBindGroup({ layout: sun.layout, entries: [\r\n { binding: 0, resource: { buffer: sun.buffer } },\r\n { binding: 1, resource: sun.texture.createView() },\r\n { binding: 2, resource: sun.sampler },\r\n { binding: 3, resource: { buffer: sun.lights } },\r\n ] });\r\n}\r\n\r\n/** A cached spatial grid limits fragment lighting to nearby lamps, without dropping dense cells. */\r\nexport function updatePointLights(backend) {\r\n const { device, sunlight: sun } = backend.renderer;\r\n const meshes = [];\r\n for (const layer of backend._layers) {\r\n if (!layer.options.nightLight || !layer.root.visible) continue;\r\n traverse(layer.root, mesh => {\r\n if (!mesh.visible) return true;\r\n if (mesh.extras?.lights) meshes.push(mesh);\r\n });\r\n }\r\n if (sun.lightMeshes?.length === meshes.length && meshes.every((mesh, i) => sun.lightMeshes[i].mesh === mesh &&\r\n sun.lightMeshes[i].lights === mesh.extras.lights && mesh.worldMatrix.every((v, j) => v === sun.lightMeshes[i].matrix[j]))) return;\r\n // Per mesh, world-space [x, y, z, radius, r, g, b, intensity] per light: re-packed only when its lights or matrix change.\r\n const packed = meshes.map(mesh => {\r\n const cache = mesh._worldLights, m = mesh.worldMatrix, lights = mesh.extras.lights;\r\n if (cache?.lights === lights && m.every((v, j) => v === cache.matrix[j])) return cache.data;\r\n const values = worldLights(lights, m);\r\n mesh._worldLights = { lights, matrix: [...m], data: values };\r\n return values;\r\n });\r\n const { data, count } = lightGrid(packed, device.limits.maxStorageBufferBindingSize);\r\n if (sun.lights.size < data.byteLength) {\r\n backend._destroyTexture(sun.lights);\r\n sun.lights = device.createBuffer({ size: data.byteLength, usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_DST });\r\n backend._bindSunlight();\r\n }\r\n device.queue.writeBuffer(sun.lights, 0, data);\r\n sun.lightCount = count;\r\n sun.lightMeshes = meshes.map(mesh => ({ mesh, lights: mesh.extras.lights, matrix: [...mesh.worldMatrix] }));\r\n}\r\n\r\n/** One shared directional depth map. Off-screen but loaded geometry can cast shadows. */\r\nexport function renderSunlight(backend, encoder, meshes, sunlight) {\r\n const renderer = backend.renderer, device = renderer.device, sun = renderer.sunlight;\r\n if (!meshes.length || !sunlight || sunlight.altitude < 3) {\r\n if (!sun.enabled) return;\r\n const values = new Float32Array(20);\r\n values.set([1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]);\r\n device.queue.writeBuffer(sun.buffer, 0, values);\r\n sun.enabled = false;\r\n return;\r\n }\r\n const values = new Float32Array(20);\r\n sun.enabled = true;\r\n backend._resizeSunlight(Math.min(2048, device.limits.maxTextureDimension2D));\r\n const min = [Infinity, Infinity, Infinity], max = [-Infinity, -Infinity, -Infinity];\r\n for (const mesh of meshes) {\r\n if (!mesh.geometry.bounds) computeBounds(mesh.geometry);\r\n const bounds = mesh.geometry.bounds, matrix = new DOMMatrix(mesh.worldMatrix);\r\n for (let i = 0; i < 8; i++) {\r\n const point = new DOMPoint(...min.map((_, axis) => (i & (1 << axis)) ? bounds.max[axis] : bounds.min[axis]), 1)\r\n .matrixTransform(matrix);\r\n for (let axis = 0; axis < 3; axis++) {\r\n const value = [point.x, point.y, point.z][axis] / point.w;\r\n min[axis] = Math.min(min[axis], value);\r\n max[axis] = Math.max(max[axis], value);\r\n }\r\n }\r\n }\r\n // Include ground receivers below/around the loaded buildings and trees.\r\n min[1] = Math.min(0, min[1]);\r\n const radius = Math.max(100, Math.hypot(...min.map((v, i) => max[i] - v)));\r\n const center = min.map((v, i) => (v + max[i]) / 2);\r\n const lightCamera = {\r\n position: center.map((v, i) => v + sunlight.direction[i] * radius * 2),\r\n target: center, up: [0, 0, -1], fov: 45, aspect: 1, near: 1, far: radius * 5,\r\n viewMatrix: [], projectionMatrix: [], projectionViewMatrix: [],\r\n };\r\n updateCamera(lightCamera);\r\n const view = new DOMMatrix(lightCamera.viewMatrix);\r\n const low = [Infinity, Infinity, Infinity], high = [-Infinity, -Infinity, -Infinity];\r\n for (let i = 0; i < 8; i++) {\r\n const point = new DOMPoint(...min.map((v, axis) => (i & (1 << axis)) ? max[axis] : v), 1).matrixTransform(view);\r\n [point.x, point.y, point.z].forEach((value, axis) => {\r\n low[axis] = Math.min(low[axis], value - 20);\r\n high[axis] = Math.max(high[axis], value + 20);\r\n });\r\n }\r\n const span = low.map((v, i) => high[i] - v);\r\n const projection = new DOMMatrix([\r\n 2 / span[0], 0, 0, 0, 0, 2 / span[1], 0, 0, 0, 0, -1 / span[2], 0,\r\n -(high[0] + low[0]) / span[0], -(high[1] + low[1]) / span[1], high[2] / span[2], 1,\r\n ]);\r\n values.set(projection.multiply(view).toFloat32Array());\r\n values[16] = 1;\r\n device.queue.writeBuffer(sun.buffer, 0, values);\r\n if (!sun.pipeline) {\r\n sun.meshLayout = device.createBindGroupLayout({ entries: [\r\n { binding: 0, visibility: GPUShaderStage.VERTEX, buffer: { type: 'uniform', hasDynamicOffset: true } },\r\n ] });\r\n // Do not bind the sampled depth texture while it is a render attachment.\r\n sun.depthLayout = device.createBindGroupLayout({ entries: [\r\n { binding: 0, visibility: GPUShaderStage.VERTEX, buffer: { type: 'uniform' } },\r\n ] });\r\n sun.depthBindGroup = device.createBindGroup({\r\n layout: sun.depthLayout, entries: [{ binding: 0, resource: { buffer: sun.buffer } }],\r\n });\r\n const shader = device.createShaderModule({ code: `\r\n struct Mesh { world: mat4x4<f32> };\r\n @group(0) @binding(0) var<uniform> mesh: Mesh;\r\n @group(1) @binding(0) var<uniform> matrix: mat4x4<f32>;\r\n @vertex fn main(@location(0) position: vec3<f32>) -> @builtin(position) vec4<f32> {\r\n return matrix * mesh.world * vec4<f32>(position, 1.0);\r\n }\r\n ` });\r\n sun.pipeline = device.createRenderPipeline({\r\n layout: device.createPipelineLayout({ bindGroupLayouts: [sun.meshLayout, sun.depthLayout] }),\r\n vertex: { module: shader, entryPoint: 'main', buffers: [\r\n { arrayStride: 12, attributes: [{ shaderLocation: 0, offset: 0, format: 'float32x3' }] },\r\n ] },\r\n primitive: { topology: 'triangle-list', cullMode: 'none' },\r\n depthStencil: { format: 'depth32float', depthWriteEnabled: true, depthCompare: 'less',\r\n depthBias: 2, depthBiasSlopeScale: 2 },\r\n });\r\n }\r\n const pass = encoder.beginRenderPass({\r\n colorAttachments: [],\r\n depthStencilAttachment: { view: sun.texture.createView(), depthClearValue: 1,\r\n depthLoadOp: 'clear', depthStoreOp: 'store' },\r\n });\r\n pass.setPipeline(sun.pipeline);\r\n pass.setBindGroup(1, sun.depthBindGroup);\r\n for (const mesh of meshes) {\r\n const offset = renderer.uniformSlot++ * 256;\r\n renderer.uniformData.set(mesh.worldMatrix, offset / 4);\r\n if (mesh._shadowBuffer !== renderer.uniformBuffer) {\r\n mesh._shadowBuffer = renderer.uniformBuffer;\r\n mesh._shadowBindGroup = device.createBindGroup({ layout: sun.meshLayout, entries: [\r\n { binding: 0, resource: { buffer: renderer.uniformBuffer, size: 64 } },\r\n ] });\r\n }\r\n for (const attribute of Object.values(mesh.geometry.attributes)) {\r\n if (attribute.needsUpdate) {\r\n device.queue.writeBuffer(attribute.buffer, 0, attribute.data);\r\n attribute.needsUpdate = false;\r\n }\r\n }\r\n pass.setBindGroup(0, mesh._shadowBindGroup, [offset]);\r\n pass.setVertexBuffer(0, mesh.geometry.attributes.position.buffer);\r\n const index = mesh.geometry.attributes.index, range = mesh.geometry.drawRange;\r\n if (index) {\r\n pass.setIndexBuffer(index.buffer, index.indexFormat);\r\n pass.drawIndexed(range.count, 1, range.start, 0, 0);\r\n } else pass.draw(range.count, 1, range.start, 0);\r\n }\r\n pass.end();\r\n}\r\n"],
5
- "mappings": "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",
6
- "names": ["lightGrid", "worldLights", "computeBounds", "traverse", "updateCamera", "initSunlight", "backend", "device", "layout", "buffer", "sampler", "lights", "values", "resizeSunlight", "size", "sun", "bindSunlight", "updatePointLights", "meshes", "layer", "mesh", "i", "v", "j", "packed", "cache", "m", "data", "count", "renderSunlight", "encoder", "sunlight", "renderer", "min", "max", "bounds", "matrix", "point", "_", "axis", "value", "radius", "center", "lightCamera", "view", "low", "high", "span", "projection", "shader", "pass", "offset", "attribute", "index", "range"]
7
- }
@@ -1,2 +0,0 @@
1
- import{decodeModel as I,readAccessor as F,nodeMatrix as M,vertexNormals as _,textureSampler as z}from"../utils/model.js";import{emptyNode as v,setParent as x}from"../utils/scene.js";async function D(o){await o._added.promise;const g=new URL(o.modelUrl,document.baseURI).href,T=await fetch(g);if(!T.ok)throw new Error(`Unable to load model: HTTP ${T.status}`);const R=await T.arrayBuffer(),i=I(R),E=new URL(".",g).href;await Promise.all((i.buffers||[]).map(async e=>{if(e.binary)return;const t=await fetch(new URL(e.uri,E).href);if(!t.ok)throw new Error(`Unable to load model buffer: HTTP ${t.status}`);e.binary=await t.arrayBuffer()})),await o._added.promise;const A=await Promise.all((i.images||[]).map(async e=>{let t;if(e.bufferView!==void 0){const s=i.bufferViews[e.bufferView],f=i.buffers[s.buffer].binary;t=new Blob([f.slice(s.byteOffset||0,(s.byteOffset||0)+s.byteLength)],{type:e.mimeType})}else{const s=await fetch(new URL(e.uri,E).href);if(!s.ok)throw new Error(`Unable to load model texture: HTTP ${s.status}`);t=await s.blob()}return createImageBitmap(t,{premultiplyAlpha:"none",colorSpaceConversion:"none"})})),y=new Map,p=(e,t=!1)=>{if(!e)return null;if((e.texCoord||0)!==0||e.extensions)throw new Error("Model textures currently require untransformed TEXCOORD_0 UVs");const s=o.renderer.device,f=`${e.index}:${t}`;if(!y.has(f)){const d=i.textures[e.index],l=i.samplers?.[d.sampler]||{},u=A[d.source],c=t?"rgba8unorm-srgb":"rgba8unorm",r=z(l);y.set(f,{device:s,texture:s.createTexture({size:[u.width,u.height],format:c,usage:GPUTextureUsage.TEXTURE_BINDING|GPUTextureUsage.COPY_DST|GPUTextureUsage.RENDER_ATTACHMENT}),sampler:s.createSampler(r),samplerOptions:r,format:c,srgb:t,image:u,flipY:!1,uploaded:null})}return y.get(f)},B=(i.materials||[]).map(e=>{const t=e.pbrMetallicRoughness||{};return{color:(t.baseColorFactor||[1,1,1,1]).slice(0,3),opacity:t.baseColorFactor?.[3]??1,metallic:t.metallicFactor??1,roughness:t.roughnessFactor??1,baseTexture:p(t.baseColorTexture,!0),metalTexture:p(t.metallicRoughnessTexture),emissiveTexture:p(e.emissiveTexture,!0),occlusionTexture:p(e.occlusionTexture),emissive:e.emissiveFactor||[0,0,0],occlusionStrength:e.occlusionTexture?.strength??1,alphaMode:e.alphaMode||"OPAQUE",alphaCutoff:e.alphaCutoff??.5,doubleSided:e.doubleSided}});let U;{const e=new Set,t=[],s=d=>{if(e.has(d))throw new Error("Cyclic glTF nodes");const l=i.nodes[d];if(!l)throw new Error("Invalid glTF node");e.add(d);const u={...v(),name:l.name};if(u.matrix=M(l),l.mesh!==void 0)for(const c of i.meshes[l.mesh].primitives){const r={};for(const[a,n]of[["POSITION","position"],["NORMAL","normal"],["TEXCOORD_0","uv"]])c.attributes[a]!==void 0&&(r[n]=F(i,c.attributes[a]));if(!r.position)throw new Error("glTF mesh has no positions");const h=r.position.data.length/3;if(r.position.size!==3||h<3||Object.values(r).some(a=>a.data.length/a.size!==h))throw new Error("Invalid glTF vertex attributes");if(c.indices!==void 0){const a=F(i,c.indices);if(r.index={size:1,data:a.indices},![Uint8Array,Uint16Array,Uint32Array].some(n=>a.indices instanceof n)||a.size!==1||a.indices.length%3||[...a.indices].some(n=>n>=h))throw new Error("Invalid glTF triangle indices")}if(!r.index&&h%3)throw new Error("Incomplete glTF triangle");if(!r.normal){const a=_(r.position.data,r.index?.data);r.normal={size:3,data:a}}const m=B[c.material]||{color:[1,1,1],metallic:1};if([m.baseTexture,m.metalTexture,m.emissiveTexture,m.occlusionTexture].some(Boolean)&&!r.uv)throw new Error("Textured model mesh requires UV coordinates");const O=o._createProgram(m);t.push(O);const w=o.renderer.device;r.index?.data instanceof Uint8Array&&(r.index.data=Uint16Array.from(r.index.data));for(const[a,n]of Object.entries(r))n.size||=1,n.count=n.data.length/n.size,n.indexFormat=n.data instanceof Uint32Array?"uint32":"uint16",n.buffer=w.createBuffer({size:Math.max(4,n.data.byteLength),usage:a==="index"?GPUBufferUsage.INDEX|GPUBufferUsage.COPY_DST:GPUBufferUsage.VERTEX|GPUBufferUsage.COPY_DST}),w.queue.writeBuffer(n.buffer,0,n.data);const C={device:w,attributes:r,drawRange:{start:0,count:r.index?.count||r.position.count}};t.push(C);const b={...v(),device:w,geometry:C,program:O,id:L.Layer.types["3d"]._nextId++,renderOrder:0};b.name=i.meshes[l.mesh].name,b.extras=l.extras||{},x(b,u)}for(const c of l.children||[])x(s(c),u);return e.delete(d),u},f=i.scenes?.[i.scene||0];if(!f)throw new Error("Missing glTF scene");try{U=f.nodes.map(s)}catch(d){for(const l of t)if(l.attributes)for(const u of Object.values(l.attributes))u.buffer.destroy();else o._removeProgram(l);throw d}}const P={...v(),id:g,extras:i.extras||{}};if(!U.length)throw new Error("Expected a glTF model with a non-empty scene");for(const e of U)x(e,P);if(o.model=P,o.options.rotation){const[e,t=e,s=e]=o.options.rotation;o.model.rotation[0]=e,o.model.rotation[1]=t,o.model.rotation[2]=s}if(o.options.scale){const[e,t=e,s=e]=o.options.scale;o.model.scale[0]=e,o.model.scale[1]=t,o.model.scale[2]=s}x(o.model,o.root)}export{D as loadModel};
2
- //# sourceMappingURL=model.js.map
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../src/scene/model.js"],
4
- "sourcesContent": ["import { decodeModel, readAccessor, nodeMatrix, vertexNormals, textureSampler } from '../utils/model.js';\nimport { emptyNode, setParent } from '../utils/scene.js';\n\n/** glTF/GLB model loading. */\n/** Load the configured GLB/glTF (static triangles) under `root`; GPU resources need attachment. */\nexport async function loadModel(backend) {\n await backend._added.promise;\n const url = new URL(backend.modelUrl, document.baseURI).href;\n const response = await fetch(url);\n if (!response.ok) {\n throw new Error(`Unable to load model: HTTP ${response.status}`);\n }\n const data = await response.arrayBuffer();\n const description = decodeModel(data);\n const directory = new URL('.', url).href;\n await Promise.all((description.buffers || []).map(async buffer => {\n if (buffer.binary) {\n return;\n }\n const response = await fetch(new URL(buffer.uri, directory).href);\n if (!response.ok) {\n throw new Error(`Unable to load model buffer: HTTP ${response.status}`);\n }\n buffer.binary = await response.arrayBuffer();\n }));\n await backend._added.promise;\n const images = await Promise.all((description.images || []).map(async image => {\n let blob;\n if (image.bufferView !== undefined) {\n const view = description.bufferViews[image.bufferView];\n const buffer = description.buffers[view.buffer].binary;\n blob = new Blob([buffer.slice(view.byteOffset || 0, (view.byteOffset || 0) + view.byteLength)],\n { type: image.mimeType });\n } else {\n const response = await fetch(new URL(image.uri, directory).href);\n if (!response.ok) throw new Error(`Unable to load model texture: HTTP ${response.status}`);\n blob = await response.blob();\n }\n // Preserve straight alpha and raw samples; GPU sRGB formats do color decoding.\n return createImageBitmap(blob, { premultiplyAlpha: 'none', colorSpaceConversion: 'none' });\n }));\n const textures = new Map();\n const textureFor = (reference, color = false) => {\n if (!reference) return null;\n if ((reference.texCoord || 0) !== 0 || reference.extensions) {\n throw new Error('Model textures currently require untransformed TEXCOORD_0 UVs');\n }\n const device = backend.renderer.device;\n // A glTF image may serve both color and data maps: those cannot share a GPU format.\n const key = `${reference.index}:${color}`;\n if (!textures.has(key)) {\n const texture = description.textures[reference.index];\n const sampler = description.samplers?.[texture.sampler] || {};\n const image = images[texture.source];\n const format = color ? 'rgba8unorm-srgb' : 'rgba8unorm';\n const samplerOptions = textureSampler(sampler);\n textures.set(key, {\n device,\n texture: device.createTexture({\n size: [image.width, image.height],\n format,\n usage: GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.COPY_DST | GPUTextureUsage.RENDER_ATTACHMENT,\n }),\n sampler: device.createSampler(samplerOptions),\n samplerOptions,\n format,\n srgb: color,\n image,\n flipY: false,\n uploaded: null,\n });\n }\n return textures.get(key);\n };\n // Convert glTF materials directly to the shader's retained CPU styles.\n const materials = (description.materials || []).map(material => {\n const pbr = material.pbrMetallicRoughness || {};\n return {\n color: (pbr.baseColorFactor || [1, 1, 1, 1]).slice(0, 3),\n opacity: pbr.baseColorFactor?.[3] ?? 1,\n metallic: pbr.metallicFactor ?? 1,\n roughness: pbr.roughnessFactor ?? 1,\n baseTexture: textureFor(pbr.baseColorTexture, true),\n metalTexture: textureFor(pbr.metallicRoughnessTexture),\n emissiveTexture: textureFor(material.emissiveTexture, true),\n occlusionTexture: textureFor(material.occlusionTexture),\n emissive: material.emissiveFactor || [0, 0, 0],\n occlusionStrength: material.occlusionTexture?.strength ?? 1,\n alphaMode: material.alphaMode || 'OPAQUE',\n alphaCutoff: material.alphaCutoff ?? 0.5,\n doubleSided: material.doubleSided,\n };\n });\n let nodes;\n {\n // Track only the recursion path: shared mesh references are valid, cycles are not.\n const active = new Set(), resources = [];\n const node = index => {\n if (active.has(index)) throw new Error('Cyclic glTF nodes');\n const spec = description.nodes[index];\n if (!spec) throw new Error('Invalid glTF node');\n active.add(index);\n const group = {\n ...emptyNode(),\n name: spec.name\n };\n group.matrix = nodeMatrix(spec);\n if (spec.mesh !== undefined) {\n for (const primitive of description.meshes[spec.mesh].primitives) {\n const attributes = {};\n for (const [semantic, name] of [['POSITION', 'position'], ['NORMAL', 'normal'], ['TEXCOORD_0', 'uv']]) {\n if (primitive.attributes[semantic] !== undefined) attributes[name] = readAccessor(description, primitive.attributes[semantic]);\n }\n if (!attributes.position) throw new Error('glTF mesh has no positions');\n const vertexCount = attributes.position.data.length / 3;\n if (attributes.position.size !== 3 || vertexCount < 3 ||\n Object.values(attributes).some(attribute => attribute.data.length / attribute.size !== vertexCount)) throw new Error('Invalid glTF vertex attributes');\n if (primitive.indices !== undefined) {\n const index = readAccessor(description, primitive.indices);\n attributes.index = { size: 1, data: index.indices };\n if (![Uint8Array, Uint16Array, Uint32Array].some(Type => index.indices instanceof Type) ||\n index.size !== 1 || index.indices.length % 3 || [...index.indices].some(i => i >= vertexCount)) throw new Error('Invalid glTF triangle indices');\n }\n if (!attributes.index && vertexCount % 3) throw new Error('Incomplete glTF triangle');\n if (!attributes.normal) {\n const normals = vertexNormals(attributes.position.data, attributes.index?.data);\n attributes.normal = { size: 3, data: normals };\n }\n const style = materials[primitive.material] || { color: [1, 1, 1], metallic: 1 };\n if ([style.baseTexture, style.metalTexture, style.emissiveTexture, style.occlusionTexture].some(Boolean) && !attributes.uv) {\n throw new Error('Textured model mesh requires UV coordinates');\n }\n const program = backend._createProgram(style);\n resources.push(program);\n const device = backend.renderer.device;\n if (attributes.index?.data instanceof Uint8Array) {\n attributes.index.data = Uint16Array.from(attributes.index.data);\n }\n for (const [name, attribute] of Object.entries(attributes)) {\n attribute.size ||= 1;\n attribute.count = attribute.data.length / attribute.size;\n attribute.indexFormat = attribute.data instanceof Uint32Array ? 'uint32' : 'uint16';\n attribute.buffer = device.createBuffer({\n size: Math.max(4, attribute.data.byteLength),\n usage: name === 'index'\n ? GPUBufferUsage.INDEX | GPUBufferUsage.COPY_DST\n : GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_DST,\n });\n device.queue.writeBuffer(attribute.buffer, 0, attribute.data);\n }\n const geometry = {\n device,\n attributes,\n drawRange: { start: 0, count: attributes.index?.count || attributes.position.count },\n };\n resources.push(geometry);\n const mesh = {\n ...emptyNode(),\n device,\n geometry,\n program,\n id: L.Layer.types['3d']._nextId++,\n renderOrder: 0\n };\n mesh.name = description.meshes[spec.mesh].name; mesh.extras = spec.extras || {};\n setParent(mesh, group);\n }\n }\n for (const child of spec.children || []) setParent(node(child), group);\n active.delete(index);\n return group;\n };\n const scene = description.scenes?.[description.scene || 0];\n if (!scene) throw new Error('Missing glTF scene');\n try {\n nodes = scene.nodes.map(node);\n } catch (error) {\n // Parsing can fail after earlier primitives allocated buffers/programs.\n for (const resource of resources) {\n if (resource.attributes) {\n for (const attribute of Object.values(resource.attributes)) attribute.buffer.destroy();\n } else backend._removeProgram(resource);\n }\n throw error;\n }\n }\n const model = {\n ...emptyNode(),\n id: url,\n extras: description.extras || {},\n };\n if (!nodes.length) throw new Error('Expected a glTF model with a non-empty scene');\n for (const node of nodes) setParent(node, model);\n backend.model = model;\n if (backend.options.rotation) {\n const [x, y = x, z = x] = backend.options.rotation;\n backend.model.rotation[0] = x; backend.model.rotation[1] = y; backend.model.rotation[2] = z;\n }\n if (backend.options.scale) {\n const [x, y = x, z = x] = backend.options.scale;\n backend.model.scale[0] = x; backend.model.scale[1] = y; backend.model.scale[2] = z;\n }\n setParent(backend.model, backend.root);\n}\n"],
5
- "mappings": "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",
6
- "names": ["decodeModel", "readAccessor", "nodeMatrix", "vertexNormals", "textureSampler", "emptyNode", "setParent", "loadModel", "backend", "url", "response", "data", "description", "directory", "buffer", "images", "image", "blob", "view", "textures", "textureFor", "reference", "color", "device", "key", "texture", "sampler", "format", "samplerOptions", "materials", "material", "pbr", "nodes", "active", "resources", "node", "index", "spec", "group", "primitive", "attributes", "semantic", "name", "vertexCount", "attribute", "Type", "i", "normals", "style", "program", "geometry", "mesh", "child", "scene", "error", "resource", "model", "x", "y", "z"]
7
- }
@@ -1,2 +0,0 @@
1
- import{intersectMeshes as p}from"../utils/picking.js";import{traverse as c,updateWorldMatrix as m,updateCamera as y}from"../utils/scene.js";function v(t,e,r=t.root.children,o=!0){if(!t.renderer)return[];const s=t._map.getContainer().getBoundingClientRect();m(t.scene),y(t.camera);const n=new DOMMatrix(t.camera.projectionViewMatrix).inverse();if(![...n.toFloat64Array()].every(Number.isFinite))throw new Error("Singular 3D transform");t.raycaster.origin[0]=t.camera.position[0],t.raycaster.origin[1]=t.camera.position[1],t.raycaster.origin[2]=t.camera.position[2];const l=new DOMPoint((e.clientX-s.left)/s.width*2-1,-((e.clientY-s.top)/s.height)*2+1,0,1).matrixTransform(n),u=[l.x/l.w,l.y/l.w,l.z/l.w];t.raycaster.direction[0]=u[0]-t.raycaster.origin[0],t.raycaster.direction[1]=u[1]-t.raycaster.origin[1],t.raycaster.direction[2]=u[2]-t.raycaster.origin[2];const f=Math.hypot(...t.raycaster.direction)||1;t.raycaster.direction[0]/=f,t.raycaster.direction[1]/=f,t.raycaster.direction[2]/=f;const a=[];for(const h of r)o?c(h,g=>{g.geometry&&g.visible&&a.push(g)}):h.geometry&&h.visible&&a.push(h);return p(t.raycaster,a,t.renderer.uniformData?.[55])}function _(t,e){if(!t.root||!t.camera)return null;for(const r of t.raycast(e,t.root.children,!!t.model)){if(t.model){let i=r.object;for(;i&&i!==t.model;)i=i.parent;if(i===t.model)return{id:t.model.id,properties:t.model.extras,model:t.model,mesh:r.object,point:r.point}}const o=r.object.extras?.featureFaces;if(!o)continue;let s=0,n=o.length-1;for(;s<=n;){const i=s+n>>1,l=o[i];if(r.faceIndex<l.faceStart)n=i-1;else if(r.faceIndex>=l.faceEnd)s=i+1;else return{...l,mesh:r.object,point:r.point}}}return null}function w(t,e){e?.model&&(e=null),!(t.highlightedFeature?.mesh===e?.mesh&&t.highlightedFeature?.vertexStart===e?.vertexStart)&&(t.highlightedFeature&&(t.highlightedFeature.mesh.highlight=null),t.highlightedFeature=e,e&&(e.mesh.highlight=[e.vertexStart,e.vertexEnd]),t.update())}function d(t,e,r){const o=t._tooltip;if(!o)return;if(e){o.replaceChildren(t.options.tooltipContent(e)),o.hidden=!1;const n=t.container.getBoundingClientRect(),i=r.clientX-n.left,l=r.clientY-n.top;o.style.left=`${i+o.offsetWidth+16>n.width?i-o.offsetWidth-12:i+12}px`,o.style.top=`${l+o.offsetHeight+16>n.height?l-o.offsetHeight-12:l+12}px`}else o.hidden=!0;const s=t._shared;s&&([...s._layers].some(i=>i._tooltip&&!i._tooltip.hidden)?(s._cursor===void 0&&(s._cursor=t.container.style.cursor),t.container.style.cursor="pointer"):s._cursor!==void 0&&(t.container.style.cursor=s._cursor,delete s._cursor))}function C(t,e){t.hoveredFeature=t._findFeature(e),t._setHighlight(t.hoveredFeature),t._showFeature(t.hoveredFeature,e),t.fire("featurehover",{feature:t.hoveredFeature,originalEvent:e})}function j(t,e){const r=t._findFeature(e);t.hoveredFeature=r,t._setHighlight(r),t._showFeature(r,e),t.fire("featureclick",{feature:r,originalEvent:e})}function M(t){t.hoveredFeature=null,t._setHighlight(null),t._showFeature(null),t.fire("featurehover",{feature:null})}export{_ as findFeature,j as onClick,M as onPointerLeave,C as onPointerMove,v as raycast,w as setHighlight,d as showFeature};
2
- //# sourceMappingURL=picking.js.map
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../src/scene/picking.js"],
4
- "sourcesContent": ["import { intersectMeshes } from '../utils/picking.js';\r\nimport { traverse, updateWorldMatrix, updateCamera } from '../utils/scene.js';\r\n\r\n/** Raycasting, hover/click highlight and tooltips. */\r\n/**\r\n * Finds the objects under a mouse or pointer event, nearest first.\r\n *\r\n * @param {MouseEvent} event\r\n * @param {Object[]} [objects] Defaults to this layer's root children, not all map layers.\r\n * @param {boolean} [recursive] Also test the descendants of `objects`.\r\n * @returns {Object[]} Nearest hit per mesh: object, shared-world point/distance and triangle faceIndex.\r\n */\r\nexport function raycast(backend, event, objects = backend.root.children, recursive = true) {\r\n if (!backend.renderer) {\r\n return [];\r\n }\r\n const rect = backend._map.getContainer().getBoundingClientRect();\r\n updateWorldMatrix(backend.scene);\r\n updateCamera(backend.camera);\r\n // Unproject the mouse (-1..1) into a world-space ray from the camera.\r\n const inverseCamera = new DOMMatrix(backend.camera.projectionViewMatrix).inverse();\r\n const inverseCameraValues = inverseCamera.toFloat64Array();\r\n if (![...inverseCameraValues].every(Number.isFinite)) {\r\n throw new Error('Singular 3D transform');\r\n }\r\n backend.raycaster.origin[0] = backend.camera.position[0];\r\n backend.raycaster.origin[1] = backend.camera.position[1];\r\n backend.raycaster.origin[2] = backend.camera.position[2];\r\n const unprojected = new DOMPoint(\r\n ((event.clientX - rect.left) / rect.width) * 2 - 1,\r\n -((event.clientY - rect.top) / rect.height) * 2 + 1,\r\n 0,\r\n 1\r\n ).matrixTransform(inverseCamera);\r\n const end = [\r\n unprojected.x / unprojected.w,\r\n unprojected.y / unprojected.w,\r\n unprojected.z / unprojected.w\r\n ];\r\n backend.raycaster.direction[0] = end[0] - backend.raycaster.origin[0];\r\n backend.raycaster.direction[1] = end[1] - backend.raycaster.origin[1];\r\n backend.raycaster.direction[2] = end[2] - backend.raycaster.origin[2];\r\n const rayLength = Math.hypot(...backend.raycaster.direction) || 1;\r\n backend.raycaster.direction[0] /= rayLength;\r\n backend.raycaster.direction[1] /= rayLength;\r\n backend.raycaster.direction[2] /= rayLength;\r\n const meshes = [];\r\n for (const object of objects) {\r\n if (recursive) traverse(object, mesh => { if\r\n (mesh.geometry && mesh.visible) meshes.push(mesh);\r\n });\r\n else if (object.geometry && object.visible) meshes.push(object);\r\n }\r\n return intersectMeshes(backend.raycaster, meshes, backend.renderer.uniformData?.[55]);\r\n}\r\n\r\n/**\r\n * Translate a geometry hit into a configured model or batched source feature.\r\n * Sorted half-open face ranges permit binary search without a feature per triangle.\r\n * @returns {PickedFeature|null}\r\n */\r\nexport function findFeature(backend, event) {\r\n if (!backend.root || !backend.camera) return null;\r\n for (const hit of backend.raycast(event, backend.root.children, Boolean(backend.model))) {\r\n if (backend.model) {\r\n let object = hit.object;\r\n while (object && object !== backend.model) object = object.parent;\r\n if (object === backend.model) {\r\n return {\r\n id: backend.model.id, properties: backend.model.extras,\r\n model: backend.model, mesh: hit.object, point: hit.point\r\n };\r\n }\r\n }\r\n const ranges = hit.object.extras?.featureFaces;\r\n if (!ranges) continue;\r\n let low = 0, high = ranges.length - 1;\r\n while (low <= high) {\r\n const middle = (low + high) >> 1;\r\n const range = ranges[middle];\r\n if (hit.faceIndex < range.faceStart) high = middle - 1;\r\n else if (hit.faceIndex >= range.faceEnd) low = middle + 1;\r\n else return { ...range, mesh: hit.object, point: hit.point };\r\n }\r\n }\r\n return null;\r\n}\r\n\r\n/** Highlight a source vertex range in the shader; vertex colors stay untouched. */\r\nexport function setHighlight(backend, feature) {\r\n if (feature?.model) feature = null;\r\n if (backend.highlightedFeature?.mesh === feature?.mesh &&\r\n backend.highlightedFeature?.vertexStart === feature?.vertexStart) return;\r\n if (backend.highlightedFeature) backend.highlightedFeature.mesh.highlight = null;\r\n backend.highlightedFeature = feature;\r\n if (feature) feature.mesh.highlight = [feature.vertexStart, feature.vertexEnd];\r\n backend.update();\r\n}\r\n\r\n/** Update tooltip content/position and arbitrate cursor ownership across shared layers. */\r\nexport function showFeature(backend, feature, event) {\r\n const tooltip = backend._tooltip;\r\n if (!tooltip) return;\r\n if (feature) {\r\n tooltip.replaceChildren(backend.options.tooltipContent(feature));\r\n tooltip.hidden = false;\r\n const rect = backend.container.getBoundingClientRect();\r\n const x = event.clientX - rect.left, y = event.clientY - rect.top;\r\n tooltip.style.left = `${x + tooltip.offsetWidth + 16 > rect.width ? x - tooltip.offsetWidth - 12 : x + 12}px`;\r\n tooltip.style.top = `${y + tooltip.offsetHeight + 16 > rect.height ? y - tooltip.offsetHeight - 12 : y + 12}px`;\r\n } else {\r\n tooltip.hidden = true;\r\n }\r\n const shared = backend._shared;\r\n if (shared) {\r\n const visible = [...shared._layers].some(layer => layer._tooltip && !layer._tooltip.hidden);\r\n if (visible) {\r\n if (shared._cursor === undefined) shared._cursor = backend.container.style.cursor;\r\n backend.container.style.cursor = 'pointer';\r\n } else if (shared._cursor !== undefined) {\r\n backend.container.style.cursor = shared._cursor;\r\n delete shared._cursor;\r\n }\r\n }\r\n}\r\n\r\n/** Hover is transient; featurehover also reports misses with feature:null. */\r\nexport function onPointerMove(backend, event) {\r\n backend.hoveredFeature = backend._findFeature(event);\r\n backend._setHighlight(backend.hoveredFeature);\r\n backend._showFeature(backend.hoveredFeature, event);\r\n backend.fire('featurehover', { feature: backend.hoveredFeature, originalEvent: event });\r\n}\r\n\r\n/** Emit click without moving the map or pinning the tooltip. */\r\nexport function onClick(backend, event) {\r\n const feature = backend._findFeature(event);\r\n backend.hoveredFeature = feature;\r\n backend._setHighlight(feature);\r\n backend._showFeature(feature, event);\r\n backend.fire('featureclick', { feature, originalEvent: event });\r\n}\r\n\r\n/** Clear hover, highlight and tooltip without retaining a selected feature. */\r\nexport function onPointerLeave(backend) {\r\n backend.hoveredFeature = null;\r\n backend._setHighlight(null);\r\n backend._showFeature(null);\r\n backend.fire('featurehover', { feature: null });\r\n}\r\n"],
5
- "mappings": "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",
6
- "names": ["intersectMeshes", "traverse", "updateWorldMatrix", "updateCamera", "raycast", "backend", "event", "objects", "recursive", "rect", "inverseCamera", "unprojected", "end", "rayLength", "meshes", "object", "mesh", "findFeature", "hit", "ranges", "low", "high", "middle", "range", "setHighlight", "feature", "showFeature", "tooltip", "x", "y", "shared", "layer", "onPointerMove", "onClick", "onPointerLeave"]
7
- }
@@ -1,2 +0,0 @@
1
- import{decodeHeader as I,decodeDirectory as T,decompress as m,tileId as p}from"../utils/pmtiles.js";async function P(e,r,s,f){if(f?.throwIfAborted(),!Number.isSafeInteger(r)||!Number.isSafeInteger(s)||r<0||s<=0||!Number.isSafeInteger(r+s))throw new Error("Invalid PMTiles byte range");const i=await fetch(e.url,{headers:{Range:`bytes=${r}-${r+s-1}`},signal:f});if(!i.ok)throw new Error(`Unable to read PMTiles: HTTP ${i.status}`);const a=i.headers.get("ETag");if(e._etag&&a!==e._etag)throw new Error("PMTiles archive changed; recreate the layer");a&&(e._etag=a);let t=await i.arrayBuffer();if(i.status===200)t=t.slice(r,r+s);else if(i.status!==206||!i.headers.get("Content-Range")?.startsWith(`bytes ${r}-${r+s-1}/`))throw new Error("Invalid PMTiles range response");if(t.byteLength!==s)throw new Error("Truncated PMTiles range");return t}function M(e){return e._header||=e._read(0,127).then(I)}async function x(e,r,s,f,i){const a=p(r,s,f);i?.throwIfAborted();const t=await e.getHeader();if(i?.throwIfAborted(),r<t.minZoom||r>t.maxZoom)return;let d=t.rootDirectoryOffset,c=t.rootDirectoryLength;const y=new Set;for(let _=0;_<4;_++){if(y.has(d))throw new Error("Cyclic PMTiles directory");y.add(d);const h=`${d}:${c}`;if(!e._directories.has(h)){e._directories.size>=32&&e._directories.delete(e._directories.keys().next().value);const n=e._read(d,c).then(u=>m(u,t.internalCompression)).then(T).catch(u=>{throw e._directories.get(h)===n&&e._directories.delete(h),u});e._directories.set(h,n)}const w=await e._directories.get(h);i?.throwIfAborted();let g=0,l=w.length-1;for(;g<=l;){const n=g+l>>1;w[n].tileId<=a?g=n+1:l=n-1}const o=w[l];if(!o)return;if(o.runLength){if(a-o.tileId>=o.runLength)return;if(o.offset+o.length>t.tileDataLength)throw new Error("PMTiles tile outside data section");const n=await m(await e._read(t.tileDataOffset+o.offset,o.length,i),t.tileCompression);return i?.throwIfAborted(),{data:n}}if(o.offset+o.length>t.leafDirectoryLength)throw new Error("PMTiles directory outside leaf section");d=t.leafDirectoryOffset+o.offset,c=o.length}throw new Error("PMTiles directory depth exceeds four levels")}export{M as getHeader,x as getZxy,P as read};
2
- //# sourceMappingURL=pmtiles.js.map
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../src/scene/pmtiles.js"],
4
- "sourcesContent": ["import { decodeHeader, decodeDirectory, decompress, tileId } from '../utils/pmtiles.js';\r\n\r\n/**\r\n * PMTiles v3 range reader.\r\n * Supports uncompressed/gzip sections. Other compression methods fail explicitly.\r\n * Specification: https://github.com/protomaps/PMTiles/blob/main/spec/v3/spec.md\r\n */\r\n/** Read exactly one archive range; reject changed archives rather than mix revisions. */\r\nexport async function read(backend, offset, length, signal) {\r\n signal?.throwIfAborted();\r\n if (!Number.isSafeInteger(offset) || !Number.isSafeInteger(length) ||\r\n offset < 0 || length <= 0 || !Number.isSafeInteger(offset + length)) {\r\n throw new Error('Invalid PMTiles byte range');\r\n }\r\n const response = await fetch(backend.url, {\r\n headers: { Range: `bytes=${offset}-${offset + length - 1}` }, signal,\r\n });\r\n if (!response.ok) throw new Error(`Unable to read PMTiles: HTTP ${response.status}`);\r\n const etag = response.headers.get('ETag');\r\n if (backend._etag && etag !== backend._etag) {\r\n throw new Error('PMTiles archive changed; recreate the layer');\r\n }\r\n if (etag) {\r\n backend._etag = etag;\r\n }\r\n let data = await response.arrayBuffer();\r\n if (response.status === 200) {\r\n data = data.slice(offset, offset + length);\r\n } else if (response.status !== 206 || !response.headers.get('Content-Range')?.startsWith(`bytes ${offset}-${offset + length - 1}/`)) {\r\n throw new Error('Invalid PMTiles range response');\r\n }\r\n if (data.byteLength !== length) {\r\n throw new Error('Truncated PMTiles range');\r\n }\r\n return data;\r\n}\r\n\r\n/** Cache header initialization; failures remain visible to all callers. */\r\nexport function getHeader(backend) {\r\n return backend._header ||= backend._read(0, 127).then(decodeHeader);\r\n}\r\n\r\n/** Nearest directory entry at/before the Hilbert ID, then follow leaf pointers. */\r\nexport async function getZxy(backend, z, x, y, signal) {\r\n const id = tileId(z, x, y);\r\n signal?.throwIfAborted();\r\n const header = await backend.getHeader();\r\n signal?.throwIfAborted();\r\n if (z < header.minZoom || z > header.maxZoom) return;\r\n let offset = header.rootDirectoryOffset, length = header.rootDirectoryLength;\r\n const visited = new Set();\r\n for (let depth = 0; depth < 4; depth++) {\r\n if (visited.has(offset)) {\r\n throw new Error('Cyclic PMTiles directory');\r\n }\r\n visited.add(offset);\r\n const key = `${offset}:${length}`;\r\n if (!backend._directories.has(key)) {\r\n if (backend._directories.size >= 32) {\r\n backend._directories.delete(backend._directories.keys().next().value);\r\n }\r\n const pending = backend._read(offset, length)\r\n .then(data => decompress(data, header.internalCompression))\r\n .then(decodeDirectory)\r\n .catch(error => {\r\n if (backend._directories.get(key) === pending) backend._directories.delete(key);\r\n throw error;\r\n });\r\n backend._directories.set(key, pending);\r\n }\r\n const entries = await backend._directories.get(key);\r\n signal?.throwIfAborted();\r\n let low = 0,\r\n high = entries.length - 1;\r\n while (low <= high) {\r\n const mid = (low + high) >> 1;\r\n if (entries[mid].tileId <= id) low = mid + 1;\r\n else high = mid - 1;\r\n }\r\n const entry = entries[high];\r\n if (!entry) return;\r\n if (entry.runLength) {\r\n if (id - entry.tileId >= entry.runLength) return;\r\n if (entry.offset + entry.length > header.tileDataLength) throw new Error('PMTiles tile outside data section');\r\n const data = await decompress(await backend._read(header.tileDataOffset + entry.offset, entry.length, signal), header.tileCompression);\r\n signal?.throwIfAborted();\r\n return { data };\r\n }\r\n if (entry.offset + entry.length > header.leafDirectoryLength) throw new Error('PMTiles directory outside leaf section');\r\n offset = header.leafDirectoryOffset + entry.offset;\r\n length = entry.length;\r\n }\r\n throw new Error('PMTiles directory depth exceeds four levels');\r\n}\r\n"],
5
- "mappings": "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",
6
- "names": ["decodeHeader", "decodeDirectory", "decompress", "tileId", "read", "backend", "offset", "length", "signal", "response", "etag", "data", "getHeader", "getZxy", "z", "x", "y", "id", "header", "visited", "depth", "key", "pending", "error", "entries", "low", "high", "mid", "entry"]
7
- }
@@ -1,15 +0,0 @@
1
- import{computeBounds as ae}from"../utils/geometry.js";import{traverse as K,updateWorldMatrix as fe,updateCamera as ce}from"../utils/scene.js";function ge(e){const s=e._shared;return s?s!==e?(s.update(),e):(e._frame||=requestAnimationFrame(()=>{e._frame=null,e._shared===e&&e.renderer&&e._render()}),e):e}function xe(e){e._queued||(e._queued=!0,queueMicrotask(()=>{e._queued=!1,!(e._shared!==e||!e.renderer)&&(e._map._animatingZoom?e.update():e._render())}))}function he(e){let s;return e._map.eachLayer(x=>{!s&&x instanceof L.TileLayer&&x._levels&&(s=x._levels[x._tileZoom])}),s}function de(e){e._zoomLevel=e._getTileLevel()}function ye(e){for(const s of e._zoomTransitions?.keys()||[])s.finish();e._zoomTransitions=null,e._zoomLevel=null,e.update()}function _e(e){if(cancelAnimationFrame(e._frame),e._frame=null,e._shared!==e||!e.renderer)return;const s=e._map,x=s.getSize();if(!x.x||!x.y)return;if(s._animatingZoom){e._zoomTransitions||=new Map;const t=performance.now();for(const r of s.getContainer().getAnimations({subtree:!0})){if(!(r instanceof CSSTransition)||r.transitionProperty!=="transform"||!r.effect.target.classList.contains("leaflet-zoom-animated")||e._zoomTransitions.has(r))continue;const i=r.currentTime||0;r.pause(),e._zoomTransitions.set(r,{start:t,time:i})}for(const[r,{start:i,time:c}]of e._zoomTransitions)r.currentTime=Math.min(r.effect.getComputedTiming().endTime,c+t-i)}(!e._size||!e._size.equals(x))&&(e.renderer.width=x.x,e.renderer.height=x.y,e.renderer.canvas.width=Math.round(x.x*e.renderer.dpr),e.renderer.canvas.height=Math.round(x.y*e.renderer.dpr),e.renderer.canvas.style.width=`${x.x}px`,e.renderer.canvas.style.height=`${x.y}px`,e.renderer.depthTexture&&e._destroyTexture(e.renderer.depthTexture),e.renderer.depthTexture=e.renderer.device.createTexture({size:[e.renderer.canvas.width,e.renderer.canvas.height],format:"depth24plus",usage:GPUTextureUsage.RENDER_ATTACHMENT}),e._size=x);let F=s.options.crs.scale(s.getZoom())/(4007501668557849e-8*Math.cos(e._sceneOrigin.lat*Math.PI/180)),j=s.project(e._sceneOrigin).subtract(s.getPixelOrigin());const T=e._zoomLevel?.el.isConnected?e._zoomLevel:e._getTileLevel();if(T&&s._animatingZoom&&(e._zoomLevel=T),T){const t=new DOMMatrix(s._animatingZoom?getComputedStyle(T.el).transform:T.el.style.transform),r=s.project(e._sceneOrigin,T.zoom).subtract(T.origin);j=new L.Point(r.x*t.a+t.e,r.y*t.d+t.f),F*=s.getZoomScale(T.zoom,s.getZoom())*t.a}const G=x.y*1.5/F,Q=s.containerPointToLayerPoint(x.divideBy(2)),B=[(Q.x-j.x)/F,s._terrain3D?._getElevation(s.getCenter())??0,(Q.y-j.y)/F],U=s.getPitch()*Math.PI/180,N=s.getBearing()*Math.PI/180,p=e.camera;p.fov=2*Math.atan(1/3)*180/Math.PI,p.aspect=x.x/x.y,p.near=Math.max(.1,G/1e4),p.far=Math.max(1e4,G*10),p.position[0]=B[0]+Math.sin(N)*Math.sin(U)*G,p.position[1]=B[1]+Math.cos(U)*G,p.position[2]=B[2]+Math.cos(N)*Math.sin(U)*G,p.up[0]=-Math.sin(N)*Math.cos(U),p.up[1]=Math.sin(U),p.up[2]=-Math.cos(N)*Math.cos(U),p.target[0]=B[0],p.target[1]=B[1],p.target[2]=B[2],ce(p);const v=s._sunlight,O=new DOMPoint(...v?.direction||[-300,500,300],0).matrixTransform(new DOMMatrix(p.viewMatrix)),q=Math.hypot(O.x,O.y,O.z)||1,ue=[O.x/q,O.y/q,O.z/q],D=new DOMPoint(0,1,0,0).matrixTransform(new DOMMatrix(p.viewMatrix)),$=Math.hypot(D.x,D.y,D.z)||1,le=[D.x/$,D.y/$,D.z/$],o=p.projectionViewMatrix,n=[[o[3]+o[0],o[7]+o[4],o[11]+o[8],o[15]+o[12]],[o[3]-o[0],o[7]-o[4],o[11]-o[8],o[15]-o[12]],[o[3]+o[1],o[7]+o[5],o[11]+o[9],o[15]+o[13]],[o[3]-o[1],o[7]-o[5],o[11]-o[9],o[15]-o[13]],[o[2],o[6],o[10],o[14]],[o[3]-o[2],o[7]-o[6],o[11]-o[10],o[15]-o[14]]],S=[Math.hypot(n[0][0],n[0][1],n[0][2]),Math.hypot(n[1][0],n[1][1],n[1][2]),Math.hypot(n[2][0],n[2][1],n[2][2]),Math.hypot(n[3][0],n[3][1],n[3][2]),Math.hypot(n[4][0],n[4][1],n[4][2]),Math.hypot(n[5][0],n[5][1],n[5][2])];fe(e.scene),K(e.scene,t=>{if(!t.visible)return!0;if(t.geometry){t.geometry.bounds||ae(t.geometry);const r=t.geometry.bounds,i=t.worldMatrix,c=r.center,a=i[0]*c[0]+i[4]*c[1]+i[8]*c[2]+i[12],l=i[1]*c[0]+i[5]*c[1]+i[9]*c[2]+i[13],f=i[2]*c[0]+i[6]*c[1]+i[10]*c[2]+i[14],m=r.radius*Math.max(Math.hypot(i[0],i[1],i[2]),Math.hypot(i[4],i[5],i[6]),Math.hypot(i[8],i[9],i[10]));if(t._visibleInFrame=n[0][0]*a+n[0][1]*l+n[0][2]*f+n[0][3]>=-m*S[0]&&n[1][0]*a+n[1][1]*l+n[1][2]*f+n[1][3]>=-m*S[1]&&n[2][0]*a+n[2][1]*l+n[2][2]*f+n[2][3]>=-m*S[2]&&n[3][0]*a+n[3][1]*l+n[3][2]*f+n[3][3]>=-m*S[3]&&n[4][0]*a+n[4][1]*l+n[4][2]*f+n[4][3]>=-m*S[4]&&n[5][0]*a+n[5][1]*l+n[5][2]*f+n[5][3]>=-m*S[5],!t._visibleInFrame)return}if(t.program?.transparent){t.geometry.bounds||ae(t.geometry);const r=t.geometry.bounds.center,i=t.worldMatrix,c=i[0]*r[0]+i[4]*r[1]+i[8]*r[2]+i[12],a=i[1]*r[0]+i[5]*r[1]+i[9]*r[2]+i[13],l=i[2]*r[0]+i[6]*r[1]+i[10]*r[2]+i[14],f=p.projectionViewMatrix,m=f[2]*c+f[6]*a+f[10]*l+f[14],b=f[3]*c+f[7]*a+f[11]*l+f[15];t._sortDepth=m/b}});const u=e.renderer;if([...e._layers].some(t=>t.options.roofTexture)){const t=Object.values(s._layers).filter(a=>a instanceof L.Layer.types.pmtiles&&a._tiles&&a.options.opacity>0),r=t.flatMap(a=>Object.values(a._tiles).filter(l=>l.el.done&&!l.el.request.signal.aborted&&l.el.isConnected).map(l=>({...l,layer:a}))),i=r.map(({el:a,coords:l,layer:f})=>`${L.Util.stamp(a)}:${l.z}:${l.x}:${l.y}:${f.options.opacity}:${f.options.zIndex}`).join("|"),c=t.map(a=>`${L.Util.stamp(a)}:${a.options.opacity}:${a.options.zIndex}`).join("|");if(!e._roofRaster||e._roofRaster.selection!==c||!t.some(a=>a.isLoading())&&e._roofRaster.signature!==i){const a=r.length?Math.max(...r.map(g=>g.coords.z)):s.getZoom(),l=new L.Bounds;for(const{coords:g,layer:_}of r){const h=_.getTileSize().multiplyBy(s.getZoomScale(a,g.z));l.extend(new L.Point(g.x,g.y).scaleBy(h)),l.extend(new L.Point(g.x+1,g.y+1).scaleBy(h))}const f=l.min||s.project(e._sceneOrigin,a),m=l.isValid()?l.getSize():new L.Point(1,1),k=Math.min(1,4096/Math.max(m.x,m.y)),w=Math.max(1,Math.ceil(m.x*k)),z=Math.max(1,Math.ceil(m.y*k)),ee=s.project(e._sceneOrigin,a),te=s.options.crs.scale(a)/(4007501668557849e-8*Math.cos(e._sceneOrigin.lat*Math.PI/180)),E=new DOMMatrix;E.m11=te/m.x,E.m33=te/m.y,E.m41=(ee.x-f.x)/m.x,E.m43=(ee.y-f.y)/m.y;const P=e._roofRaster?.texture;P&&(P.width!==w||P.height!==z)&&(e._destroyTexture(P.texture),P.texture=u.device.createTexture({size:[w,z],format:"rgba8unorm",usage:GPUTextureUsage.TEXTURE_BINDING|GPUTextureUsage.COPY_DST|GPUTextureUsage.RENDER_ATTACHMENT}),P.width=w,P.height=z),e._roofRaster={signature:i,selection:c,matrix:Array.from(E.toFloat64Array()),texture:P||{device:u.device,texture:u.device.createTexture({size:[w,z],format:"rgba8unorm",usage:GPUTextureUsage.TEXTURE_BINDING|GPUTextureUsage.COPY_DST|GPUTextureUsage.RENDER_ATTACHMENT}),sampler:u.device.createSampler({addressModeU:"clamp-to-edge",addressModeV:"clamp-to-edge"}),samplerOptions:{addressModeU:"clamp-to-edge",addressModeV:"clamp-to-edge"},image:null,width:w,height:z,format:"rgba8unorm",srgb:!1,flipY:!1,uploaded:null}};const y=u.device;if(!u.roofBlit){const g=y.createShaderModule({code:`
2
- @group(0) @binding(0) var source: texture_2d<f32>;
3
- @group(0) @binding(1) var sourceSampler: sampler;
4
- @group(0) @binding(2) var<uniform> opacity: f32;
5
- struct Varyings { @builtin(position) position: vec4f, @location(0) uv: vec2f };
6
- @vertex fn vertexMain(@builtin(vertex_index) index: u32) -> Varyings {
7
- let uv = vec2f(f32(index & 1u), f32(index >> 1u));
8
- return Varyings(vec4f(uv.x * 2.0 - 1.0, 1.0 - uv.y * 2.0, 0.0, 1.0), uv);
9
- }
10
- @fragment fn fragmentMain(input: Varyings) -> @location(0) vec4f {
11
- let color = textureSample(source, sourceSampler, input.uv);
12
- return vec4f(color.rgb, color.a * opacity);
13
- }
14
- `});u.roofBlit={pipeline:y.createRenderPipeline({layout:"auto",vertex:{module:g,entryPoint:"vertexMain"},fragment:{module:g,entryPoint:"fragmentMain",targets:[{format:"rgba8unorm",blend:{color:{srcFactor:"src-alpha",dstFactor:"one-minus-src-alpha",operation:"add"},alpha:{srcFactor:"one",dstFactor:"one-minus-src-alpha",operation:"add"}}}]},primitive:{topology:"triangle-strip"}}),sampler:y.createSampler({magFilter:"linear",minFilter:"linear"})}}const Z=e._roofTiles||=new Map;for(const[g,_]of Z)(!r.some(h=>h.el===g)||s._terrain3D?._rasterTiles.has(g))&&(_.texture.destroy(),Z.delete(g));const W=new Float32Array(Math.max(1,r.length)*64),X=y.createBuffer({size:W.byteLength,usage:GPUBufferUsage.UNIFORM|GPUBufferUsage.COPY_DST}),re=y.createCommandEncoder(),I=re.beginRenderPass({colorAttachments:[{view:e._roofRaster.texture.texture.createView(),clearValue:{r:0,g:0,b:0,a:0},loadOp:"clear",storeOp:"store"}]});I.setPipeline(u.roofBlit.pipeline),r.sort((g,_)=>(g.layer.options.zIndex||0)-(_.layer.options.zIndex||0)||g.coords.z-_.coords.z);for(const[g,{coords:_,el:h,layer:oe}]of r.entries()){let d=s._terrain3D?._rasterTiles.get(h)?.texture||Z.get(h);d||(d={texture:y.createTexture({size:[h.naturalWidth,h.naturalHeight],format:"rgba8unorm",usage:GPUTextureUsage.TEXTURE_BINDING|GPUTextureUsage.COPY_DST|GPUTextureUsage.RENDER_ATTACHMENT}),image:h,uploaded:null},Z.set(h,d)),d.uploaded!==d.image&&(y.queue.copyExternalImageToTexture({source:h},{texture:d.texture},[d.texture.width,d.texture.height]),d.uploaded=d.image),W[g*64]=oe.options.opacity;const J=oe.getTileSize().multiplyBy(s.getZoomScale(a,_.z)),ie=new L.Point(_.x,_.y).scaleBy(J).subtract(f),ne=ie.x*w/m.x,se=ie.y*z/m.y;I.setViewport(ne,se,Math.min(J.x*w/m.x,w-ne),Math.min(J.y*z/m.y,z-se),0,1),I.setBindGroup(0,y.createBindGroup({layout:u.roofBlit.pipeline.getBindGroupLayout(0),entries:[{binding:0,resource:d.texture.createView()},{binding:1,resource:u.roofBlit.sampler},{binding:2,resource:{buffer:X,offset:g*256,size:4}}]})),I.draw(4)}I.end(),y.queue.writeBuffer(X,0,W),y.queue.submit([re.finish()]),X.destroy()}}else if(e._roofRaster){e._destroyTexture(e._roofRaster.texture.texture),e._roofRaster=null;for(const t of e._roofTiles?.values()||[])t.texture.destroy();e._roofTiles=null}const C=[];K(e.scene,t=>{if(!t.visible)return!0;t.geometry&&t._visibleInFrame&&C.push(t)}),C.sort((t,r)=>Number(t.program.transparent)-Number(r.program.transparent)||t.program.transparent&&((t.renderOrder||0)-(r.renderOrder||0)||r._sortDepth-t._sortDepth)||t.id-r.id);const Y=u.device.createCommandEncoder(),H=[],V=[];if(v?.altitude>=3)for(const t of e._layers)t instanceof L.Layer.types.terrain||K(t.root,r=>{if(!r.visible)return!0;r.geometry&&!r.tile&&!r.program.nightLight&&r.program.depthTest!==!1&&V.push(r)});(!u.uniformBuffer||u.uniformBuffer.size<(C.length*2+V.length+1)*256)&&(u.uniformBuffer&&e._destroyTexture(u.uniformBuffer),u.uniformBuffer=u.device.createBuffer({size:Math.max(64,C.length*4+V.length*2)*256,usage:GPUBufferUsage.UNIFORM|GPUBufferUsage.COPY_DST}),u.uniformData=new Float32Array(u.uniformBuffer.size/4));const M=u.uniformData;M.set(p.viewMatrix,0),M.set(p.projectionMatrix,16),M.set(e._roofRaster?.matrix||[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1],32),M.set(ue,48),M[51]=v&&v.altitude<=0?0:1,M.set(le,52);const A=v?Math.max(0,Math.min(1,(3-v.altitude)/9)):0;M[55]=A*A*(3-2*A),M.set(v?.tint||[1,1,1],56),M[59]=0,A>0&&e._updatePointLights(),u.uniformSlot=1,e._renderSunlight(Y,V,v);const R=Y.beginRenderPass({colorAttachments:[{view:u.context.getCurrentTexture().createView(),clearValue:{r:0,g:0,b:0,a:0},loadOp:"clear",storeOp:"store"}],depthStencilAttachment:{view:u.depthTexture.createView(),depthClearValue:1,depthLoadOp:"clear",depthStoreOp:"store"}});R.setViewport(0,0,u.canvas.width,u.canvas.height,0,1),R.setBindGroup(1,u.sunlight.bindGroup);for(const t of C){t.tile&&t.tile.style.visibility!=="hidden"&&H.push(t.tile);const r=t.worldMatrix;t.texture&&(t.program.uniforms.baseTexture.value=t.texture,t.program.uniforms.opacity.value=t.opacity);const i=t.program.uniforms;i.roofTexture&&(i.roofTexture.value=e._roofRaster?.texture||u.roofFallbackTexture);const c=r[0]*(r[5]*r[10]-r[6]*r[9])-r[4]*(r[1]*r[10]-r[2]*r[9])+r[8]*(r[1]*r[6]-r[2]*r[5]);if(!Number.isFinite(c)||c===0)throw new Error("Singular 3D transform");const a=c<0?"cw":"ccw",l=t.program;l.transparent&&l._layerMaterial.doubleSided?(e._drawGeometry(t,R,"front",a),e._drawGeometry(t,R,"back",a)):e._drawGeometry(t,R,l.cullMode,a)}R.end(),u.device.queue.writeBuffer(u.uniformBuffer,0,u.uniformData,0,u.uniformSlot*64),u.device.queue.submit([Y.finish()]),H.length&&u.device.queue.onSubmittedWorkDone().then(()=>{for(const t of H)t.isConnected&&t._terrainVisibility!==void 0&&(t.style.visibility="hidden")},t=>{for(const r of e._layers||[])r.fire("error",{error:t})}),s._animatingZoom&&e.update()}export{ye as endZoom,he as getTileLevel,xe as onMapChange,_e as render,de as startZoom,ge as update};
15
- //# sourceMappingURL=render.js.map
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../src/scene/render.js"],
4
- "sourcesContent": ["import { computeBounds } from '../utils/geometry.js';\nimport { traverse, updateWorldMatrix, updateCamera } from '../utils/scene.js';\n\n/** Scene graph, shared camera and frame rendering. */\n/** Content changes: render once on the next animation frame. */\nexport function update(backend) {\n const shared = backend._shared;\n if (!shared) return backend;\n if (shared !== backend) {\n shared.update();\n return backend;\n }\n backend._frame ||= requestAnimationFrame(() => {\n backend._frame = null;\n if (backend._shared === backend && backend.renderer) backend._render();\n });\n return backend;\n}\n\n/** Map movement: render within the frame of Leaflet's CSS transforms, coalescing same-tick events. */\nexport function onMapChange(backend) {\n if (backend._queued) return;\n backend._queued = true;\n queueMicrotask(() => {\n backend._queued = false;\n if (backend._shared !== backend || !backend.renderer) return;\n if (backend._map._animatingZoom) backend.update();\n else backend._render();\n });\n}\n\n/** Find a raster tile's active CSS level to reproduce Leaflet's animated scale/rounding. */\nexport function getTileLevel(backend) {\n let level;\n backend._map.eachLayer(layer => {\n if (!level && layer instanceof L.TileLayer && layer._levels) {\n level = layer._levels[layer._tileZoom];\n }\n });\n return level;\n}\n\n/** Preserve the outgoing tile level before Leaflet changes its logical zoom. */\nexport function startZoom(backend) {\n backend._zoomLevel = backend._getTileLevel();\n}\n\n/** Stop using the outgoing level after zoomend; the next redraw uses current tiles. */\nexport function endZoom(backend) {\n for (const animation of backend._zoomTransitions?.keys() || []) animation.finish();\n backend._zoomTransitions = null;\n backend._zoomLevel = null;\n backend.update();\n}\n\n/**\n * Rendering owner: CSS pixels -> scene metres -> perspective camera.\n * Lights and transparent sort centers are converted into the current camera space.\n * Without raster tiles, logical map projection supplies the same static alignment.\n */\nexport function render(backend) {\n cancelAnimationFrame(backend._frame);\n backend._frame = null;\n if (backend._shared !== backend || !backend.renderer) return;\n const map = backend._map;\n const size = map.getSize();\n if (!size.x || !size.y) return;\n if (map._animatingZoom) {\n backend._zoomTransitions ||= new Map();\n const now = performance.now();\n for (const animation of map.getContainer().getAnimations({ subtree: true })) {\n if (!(animation instanceof CSSTransition) || animation.transitionProperty !== 'transform' ||\n !animation.effect.target.classList.contains('leaflet-zoom-animated') ||\n backend._zoomTransitions.has(animation)\n ) {\n continue;\n }\n const time = animation.currentTime || 0;\n animation.pause();\n backend._zoomTransitions.set(animation, { start: now, time });\n }\n // Freeze CSS between rendered frames: the compositor must not outrun the canvas.\n for (const [animation, { start, time }] of backend._zoomTransitions) {\n animation.currentTime = Math.min(animation.effect.getComputedTiming().endTime, time + now - start);\n }\n }\n if (!backend._size || !backend._size.equals(size)) {\n backend.renderer.width = size.x;\n backend.renderer.height = size.y;\n backend.renderer.canvas.width = Math.round(size.x * backend.renderer.dpr);\n backend.renderer.canvas.height = Math.round(size.y * backend.renderer.dpr);\n backend.renderer.canvas.style.width = `${size.x}px`;\n backend.renderer.canvas.style.height = `${size.y}px`;\n if (backend.renderer.depthTexture) backend._destroyTexture(backend.renderer.depthTexture);\n backend.renderer.depthTexture = backend.renderer.device.createTexture({\n size: [backend.renderer.canvas.width, backend.renderer.canvas.height],\n format: 'depth24plus',\n usage: GPUTextureUsage.RENDER_ATTACHMENT,\n });\n backend._size = size;\n }\n\n // Match the map's CSS camera: a perspective distance of 1.5 viewport heights.\n let pixelsPerMeter = map.options.crs.scale(map.getZoom()) / (40075016.68557849 * Math.cos(backend._sceneOrigin.lat * Math.PI / 180));\n let origin = map.project(backend._sceneOrigin).subtract(map.getPixelOrigin());\n const level = backend._zoomLevel?.el.isConnected ? backend._zoomLevel : backend._getTileLevel();\n if (level && map._animatingZoom) {\n backend._zoomLevel = level;\n }\n // Leaflet's logical zoom jumps before its tile CSS transition finishes.\n // Use the rendered tile transform, including its rounding, on every animation frame.\n if (level) {\n const transform = new DOMMatrix(map._animatingZoom ? getComputedStyle(level.el).transform : level.el.style.transform);\n const point = map.project(backend._sceneOrigin, level.zoom).subtract(level.origin);\n origin = new L.Point(point.x * transform.a + transform.e, point.y * transform.d + transform.f);\n pixelsPerMeter *= map.getZoomScale(level.zoom, map.getZoom()) * transform.a;\n }\n const distance = size.y * 1.5 / pixelsPerMeter;\n const center = map.containerPointToLayerPoint(size.divideBy(2));\n const target = [\n (center.x - origin.x) / pixelsPerMeter,\n map._terrain3D?._getElevation(map.getCenter()) ?? 0,\n (center.y - origin.y) / pixelsPerMeter\n ];\n const pitch = map.getPitch() * Math.PI / 180;\n const bearing = map.getBearing() * Math.PI / 180;\n const camera = backend.camera;\n camera.fov = 2 * Math.atan(1 / 3) * 180 / Math.PI;\n camera.aspect = size.x / size.y;\n camera.near = Math.max(0.1, distance / 10000);\n camera.far = Math.max(10000, distance * 10);\n camera.position[0] = target[0] + Math.sin(bearing) * Math.sin(pitch) * distance;\n camera.position[1] = target[1] + Math.cos(pitch) * distance;\n camera.position[2] = target[2] + Math.cos(bearing) * Math.sin(pitch) * distance;\n camera.up[0] = -Math.sin(bearing) * Math.cos(pitch);\n camera.up[1] = Math.sin(pitch);\n camera.up[2] = -Math.cos(bearing) * Math.cos(pitch);\n camera.target[0] = target[0]; camera.target[1] = target[1]; camera.target[2] = target[2];\n // Refresh the camera view, projection and combined projection-view matrices.\n updateCamera(camera);\n const sunlight = map._sunlight;\n const lightPoint = new DOMPoint(...(sunlight?.direction || [-300, 500, 300]), 0).matrixTransform(new DOMMatrix(camera.viewMatrix));\n const lightLength = Math.hypot(lightPoint.x, lightPoint.y, lightPoint.z) || 1;\n const light = [lightPoint.x / lightLength, lightPoint.y / lightLength, lightPoint.z / lightLength];\n const skyPoint = new DOMPoint(0, 1, 0, 0).matrixTransform(new DOMMatrix(camera.viewMatrix));\n const skyLength = Math.hypot(skyPoint.x, skyPoint.y, skyPoint.z) || 1;\n const sky = [skyPoint.x / skyLength, skyPoint.y / skyLength, skyPoint.z / skyLength];\n const projection = camera.projectionViewMatrix;\n const frustum = [\n [projection[3] + projection[0], projection[7] + projection[4], projection[11] + projection[8], projection[15] + projection[12]],\n [projection[3] - projection[0], projection[7] - projection[4], projection[11] - projection[8], projection[15] - projection[12]],\n [projection[3] + projection[1], projection[7] + projection[5], projection[11] + projection[9], projection[15] + projection[13]],\n [projection[3] - projection[1], projection[7] - projection[5], projection[11] - projection[9], projection[15] - projection[13]],\n [projection[2], projection[6], projection[10], projection[14]],\n [projection[3] - projection[2], projection[7] - projection[6], projection[11] - projection[10], projection[15] - projection[14]],\n ];\n const frustumLengths = [\n Math.hypot(frustum[0][0], frustum[0][1], frustum[0][2]),\n Math.hypot(frustum[1][0], frustum[1][1], frustum[1][2]),\n Math.hypot(frustum[2][0], frustum[2][1], frustum[2][2]),\n Math.hypot(frustum[3][0], frustum[3][1], frustum[3][2]),\n Math.hypot(frustum[4][0], frustum[4][1], frustum[4][2]),\n Math.hypot(frustum[5][0], frustum[5][1], frustum[5][2]),\n ];\n updateWorldMatrix(backend.scene);\n traverse(backend.scene, mesh => {\n if (!mesh.visible) return true;\n if (mesh.geometry) {\n if (!mesh.geometry.bounds) computeBounds(mesh.geometry);\n const bounds = mesh.geometry.bounds;\n const world = mesh.worldMatrix;\n const center = bounds.center;\n const x = world[0] * center[0] + world[4] * center[1] + world[8] * center[2] + world[12];\n const y = world[1] * center[0] + world[5] * center[1] + world[9] * center[2] + world[13];\n const z = world[2] * center[0] + world[6] * center[1] + world[10] * center[2] + world[14];\n const radius = bounds.radius * Math.max(\n Math.hypot(world[0], world[1], world[2]),\n Math.hypot(world[4], world[5], world[6]),\n Math.hypot(world[8], world[9], world[10])\n );\n mesh._visibleInFrame =\n frustum[0][0] * x + frustum[0][1] * y + frustum[0][2] * z + frustum[0][3] >= -radius * frustumLengths[0] &&\n frustum[1][0] * x + frustum[1][1] * y + frustum[1][2] * z + frustum[1][3] >= -radius * frustumLengths[1] &&\n frustum[2][0] * x + frustum[2][1] * y + frustum[2][2] * z + frustum[2][3] >= -radius * frustumLengths[2] &&\n frustum[3][0] * x + frustum[3][1] * y + frustum[3][2] * z + frustum[3][3] >= -radius * frustumLengths[3] &&\n frustum[4][0] * x + frustum[4][1] * y + frustum[4][2] * z + frustum[4][3] >= -radius * frustumLengths[4] &&\n frustum[5][0] * x + frustum[5][1] * y + frustum[5][2] * z + frustum[5][3] >= -radius * frustumLengths[5];\n if (!mesh._visibleInFrame) return;\n }\n if (mesh.program?.transparent) {\n if (!mesh.geometry.bounds) computeBounds(mesh.geometry);\n const center = mesh.geometry.bounds.center, world = mesh.worldMatrix;\n const x = world[0] * center[0] + world[4] * center[1] + world[8] * center[2] + world[12];\n const y = world[1] * center[0] + world[5] * center[1] + world[9] * center[2] + world[13];\n const z = world[2] * center[0] + world[6] * center[1] + world[10] * center[2] + world[14];\n const projection = camera.projectionViewMatrix;\n const clipZ = projection[2] * x + projection[6] * y + projection[10] * z + projection[14];\n const clipW = projection[3] * x + projection[7] * y + projection[11] * z + projection[15];\n mesh._sortDepth = clipZ / clipW;\n }\n });\n const renderer = backend.renderer;\n if ([...backend._layers].some(layer => layer.options.roofTexture)) {\n const rasters = Object.values(map._layers).filter(layer =>\n layer instanceof L.Layer.types.pmtiles && layer._tiles && layer.options.opacity > 0);\n const tiles = rasters.flatMap(layer => Object.values(layer._tiles)\n .filter(tile => tile.el.done && !tile.el.request.signal.aborted && tile.el.isConnected)\n .map(tile => ({ ...tile, layer })));\n const signature = tiles.map(({ el, coords, layer }) =>\n `${L.Util.stamp(el)}:${coords.z}:${coords.x}:${coords.y}:${layer.options.opacity}:${layer.options.zIndex}`).join('|');\n const selection = rasters.map(layer =>\n `${L.Util.stamp(layer)}:${layer.options.opacity}:${layer.options.zIndex}`).join('|');\n // Retain the geographically aligned atlas until a tile batch finishes loading.\n if (!backend._roofRaster || backend._roofRaster.selection !== selection ||\n (!rasters.some(layer => layer.isLoading()) && backend._roofRaster.signature !== signature)) {\n const zoom = tiles.length ? Math.max(...tiles.map(tile => tile.coords.z)) : map.getZoom();\n const bounds = new L.Bounds();\n for (const { coords, layer } of tiles) {\n const size = layer.getTileSize().multiplyBy(map.getZoomScale(zoom, coords.z));\n bounds.extend(new L.Point(coords.x, coords.y).scaleBy(size));\n bounds.extend(new L.Point(coords.x + 1, coords.y + 1).scaleBy(size));\n }\n const min = bounds.min || map.project(backend._sceneOrigin, zoom);\n const size = bounds.isValid() ? bounds.getSize() : new L.Point(1, 1);\n // ponytail: cap at 4096 px; virtual textures if wide views need native detail.\n const limit = 4096;\n const scale = Math.min(1, limit / Math.max(size.x, size.y));\n const width = Math.max(1, Math.ceil(size.x * scale));\n const height = Math.max(1, Math.ceil(size.y * scale));\n const origin = map.project(backend._sceneOrigin, zoom);\n const pixels = map.options.crs.scale(zoom) / (40075016.68557849 * Math.cos(backend._sceneOrigin.lat * Math.PI / 180));\n const matrix = new DOMMatrix();\n matrix.m11 = pixels / size.x; matrix.m33 = pixels / size.y;\n matrix.m41 = (origin.x - min.x) / size.x; matrix.m43 = (origin.y - min.y) / size.y;\n const texture = backend._roofRaster?.texture;\n if (texture && (texture.width !== width || texture.height !== height)) {\n backend._destroyTexture(texture.texture);\n texture.texture = renderer.device.createTexture({\n size: [width, height],\n format: 'rgba8unorm',\n usage: GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.COPY_DST | GPUTextureUsage.RENDER_ATTACHMENT,\n });\n texture.width = width;\n texture.height = height;\n }\n backend._roofRaster = {\n signature, selection, matrix: Array.from(matrix.toFloat64Array()),\n texture: texture || {\n device: renderer.device,\n texture: renderer.device.createTexture({\n size: [width, height],\n format: 'rgba8unorm',\n usage: GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.COPY_DST | GPUTextureUsage.RENDER_ATTACHMENT,\n }),\n sampler: renderer.device.createSampler({\n addressModeU: 'clamp-to-edge', addressModeV: 'clamp-to-edge',\n }),\n samplerOptions: { addressModeU: 'clamp-to-edge', addressModeV: 'clamp-to-edge' },\n image: null, width, height,\n format: 'rgba8unorm', srgb: false, flipY: false, uploaded: null,\n },\n };\n // Compose the atlas on the GPU: re-uploading a large canvas stalls Firefox for hundreds of ms.\n const device = renderer.device;\n if (!renderer.roofBlit) {\n const module = device.createShaderModule({ code: `\n @group(0) @binding(0) var source: texture_2d<f32>;\n @group(0) @binding(1) var sourceSampler: sampler;\n @group(0) @binding(2) var<uniform> opacity: f32;\n struct Varyings { @builtin(position) position: vec4f, @location(0) uv: vec2f };\n @vertex fn vertexMain(@builtin(vertex_index) index: u32) -> Varyings {\n let uv = vec2f(f32(index & 1u), f32(index >> 1u));\n return Varyings(vec4f(uv.x * 2.0 - 1.0, 1.0 - uv.y * 2.0, 0.0, 1.0), uv);\n }\n @fragment fn fragmentMain(input: Varyings) -> @location(0) vec4f {\n let color = textureSample(source, sourceSampler, input.uv);\n return vec4f(color.rgb, color.a * opacity);\n }\n ` });\n renderer.roofBlit = {\n pipeline: device.createRenderPipeline({\n layout: 'auto',\n vertex: { module, entryPoint: 'vertexMain' },\n fragment: {\n module,\n entryPoint: 'fragmentMain',\n targets: [{\n format: 'rgba8unorm',\n blend: {\n color: { srcFactor: 'src-alpha', dstFactor: 'one-minus-src-alpha', operation: 'add' },\n alpha: { srcFactor: 'one', dstFactor: 'one-minus-src-alpha', operation: 'add' },\n },\n }],\n },\n primitive: { topology: 'triangle-strip' },\n }),\n sampler: device.createSampler({ magFilter: 'linear', minFilter: 'linear' }),\n };\n }\n // Raster tiles keep their GPU copy; terrain meshes already own one for the same image.\n const roofTiles = backend._roofTiles ||= new Map();\n for (const [el, source] of roofTiles) {\n if (!tiles.some(tile => tile.el === el) || map._terrain3D?._rasterTiles.has(el)) {\n source.texture.destroy();\n roofTiles.delete(el);\n }\n }\n const opacities = new Float32Array(Math.max(1, tiles.length) * 64);\n const opacityBuffer = device.createBuffer({\n size: opacities.byteLength,\n usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST,\n });\n const encoder = device.createCommandEncoder();\n const atlasPass = encoder.beginRenderPass({\n colorAttachments: [{\n view: backend._roofRaster.texture.texture.createView(),\n clearValue: { r: 0, g: 0, b: 0, a: 0 },\n loadOp: 'clear',\n storeOp: 'store',\n }],\n });\n atlasPass.setPipeline(renderer.roofBlit.pipeline);\n tiles.sort((a, b) => (a.layer.options.zIndex || 0) - (b.layer.options.zIndex || 0) || a.coords.z - b.coords.z);\n for (const [i, { coords, el, layer }] of tiles.entries()) {\n let source = map._terrain3D?._rasterTiles.get(el)?.texture || roofTiles.get(el);\n if (!source) {\n source = {\n texture: device.createTexture({\n size: [el.naturalWidth, el.naturalHeight],\n format: 'rgba8unorm',\n usage: GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.COPY_DST | GPUTextureUsage.RENDER_ATTACHMENT,\n }),\n image: el, uploaded: null,\n };\n roofTiles.set(el, source);\n }\n if (source.uploaded !== source.image) {\n device.queue.copyExternalImageToTexture({ source: el }, { texture: source.texture },\n [source.texture.width, source.texture.height]);\n source.uploaded = source.image;\n }\n opacities[i * 64] = layer.options.opacity;\n const tileSize = layer.getTileSize().multiplyBy(map.getZoomScale(zoom, coords.z));\n const offset = new L.Point(coords.x, coords.y).scaleBy(tileSize).subtract(min);\n const x = offset.x * width / size.x, y = offset.y * height / size.y;\n atlasPass.setViewport(x, y, Math.min(tileSize.x * width / size.x, width - x),\n Math.min(tileSize.y * height / size.y, height - y), 0, 1);\n atlasPass.setBindGroup(0, device.createBindGroup({\n layout: renderer.roofBlit.pipeline.getBindGroupLayout(0),\n entries: [\n { binding: 0, resource: source.texture.createView() },\n { binding: 1, resource: renderer.roofBlit.sampler },\n { binding: 2, resource: { buffer: opacityBuffer, offset: i * 256, size: 4 } },\n ],\n }));\n atlasPass.draw(4);\n }\n atlasPass.end();\n device.queue.writeBuffer(opacityBuffer, 0, opacities);\n device.queue.submit([encoder.finish()]);\n opacityBuffer.destroy();\n }\n } else if (backend._roofRaster) {\n backend._destroyTexture(backend._roofRaster.texture.texture);\n backend._roofRaster = null;\n for (const source of backend._roofTiles?.values() || []) source.texture.destroy();\n backend._roofTiles = null;\n }\n // Visible meshes: opaque first, transparent surfaces back-to-front.\n const meshes = [];\n traverse(backend.scene, mesh => { if (!mesh.visible) return true; if (mesh.geometry && mesh._visibleInFrame) meshes.push(mesh); });\n meshes.sort((a, b) => Number(a.program.transparent) - Number(b.program.transparent) ||\n (a.program.transparent\n ? (a.renderOrder || 0) - (b.renderOrder || 0) ||\n b._sortDepth - a._sortDepth || a.id - b.id\n : a.id - b.id)\n );\n const encoder = renderer.device.createCommandEncoder();\n const pendingRasterTiles = [];\n // One uniform upload per frame: per-mesh writeBuffer calls dominate Firefox's GPU process.\n // Slot 0 holds the camera; 256-byte mesh slots follow (double-sided meshes use two).\n const shadowMeshes = [];\n if (sunlight?.altitude >= 3) {\n for (const layer of backend._layers) {\n if (layer instanceof L.Layer.types.terrain) continue;\n traverse(layer.root, mesh => {\n if (!mesh.visible) return true;\n if (mesh.geometry && !mesh.tile && !mesh.program.nightLight && mesh.program.depthTest !== false) shadowMeshes.push(mesh);\n });\n }\n }\n if (!renderer.uniformBuffer || renderer.uniformBuffer.size < (meshes.length * 2 + shadowMeshes.length + 1) * 256) {\n if (renderer.uniformBuffer) backend._destroyTexture(renderer.uniformBuffer);\n renderer.uniformBuffer = renderer.device.createBuffer({\n size: Math.max(64, meshes.length * 4 + shadowMeshes.length * 2) * 256,\n usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST,\n });\n renderer.uniformData = new Float32Array(renderer.uniformBuffer.size / 4);\n }\n const frameData = renderer.uniformData;\n frameData.set(camera.viewMatrix, 0);\n frameData.set(camera.projectionMatrix, 16);\n frameData.set(backend._roofRaster?.matrix || [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 32);\n frameData.set(light, 48);\n frameData[51] = sunlight && sunlight.altitude <= 0 ? 0 : 1;\n frameData.set(sky, 52);\n const night = sunlight ? Math.max(0, Math.min(1, (3 - sunlight.altitude) / 9)) : 0;\n frameData[55] = night * night * (3 - 2 * night);\n frameData.set(sunlight?.tint || [1, 1, 1], 56);\n frameData[59] = 0;\n if (night > 0) backend._updatePointLights();\n renderer.uniformSlot = 1;\n backend._renderSunlight(encoder, shadowMeshes, sunlight);\n const pass = encoder.beginRenderPass({\n colorAttachments: [{\n view: renderer.context.getCurrentTexture().createView(),\n clearValue: { r: 0, g: 0, b: 0, a: 0 },\n loadOp: 'clear',\n storeOp: 'store',\n }],\n depthStencilAttachment: {\n view: renderer.depthTexture.createView(),\n depthClearValue: 1,\n depthLoadOp: 'clear',\n depthStoreOp: 'store',\n },\n });\n pass.setViewport(0, 0, renderer.canvas.width, renderer.canvas.height, 0, 1);\n pass.setBindGroup(1, renderer.sunlight.bindGroup);\n for (const mesh of meshes) {\n if (mesh.tile && mesh.tile.style.visibility !== 'hidden') pendingRasterTiles.push(mesh.tile);\n const world = mesh.worldMatrix;\n if (mesh.texture) {\n mesh.program.uniforms.baseTexture.value = mesh.texture;\n mesh.program.uniforms.opacity.value = mesh.opacity;\n }\n const uniforms = mesh.program.uniforms;\n if (uniforms.roofTexture) uniforms.roofTexture.value = backend._roofRaster?.texture || renderer.roofFallbackTexture;\n const determinant = world[0] * (world[5] * world[10] - world[6] * world[9]) -\n world[4] * (world[1] * world[10] - world[2] * world[9]) +\n world[8] * (world[1] * world[6] - world[2] * world[5]);\n if (!Number.isFinite(determinant) || determinant === 0) {\n throw new Error('Singular 3D transform');\n }\n const frontFace = determinant < 0 ? 'cw' : 'ccw';\n const program = mesh.program;\n if (program.transparent && program._layerMaterial.doubleSided) {\n backend._drawGeometry(mesh, pass, 'front', frontFace);\n backend._drawGeometry(mesh, pass, 'back', frontFace);\n } else {\n backend._drawGeometry(mesh, pass, program.cullMode, frontFace);\n }\n }\n pass.end();\n renderer.device.queue.writeBuffer(renderer.uniformBuffer, 0, renderer.uniformData, 0, renderer.uniformSlot * 64);\n renderer.device.queue.submit([encoder.finish()]);\n if (pendingRasterTiles.length) {\n renderer.device.queue.onSubmittedWorkDone().then(() => {\n for (const tile of pendingRasterTiles) {\n if (tile.isConnected && tile._terrainVisibility !== undefined) tile.style.visibility = 'hidden';\n }\n }, error => {\n for (const layer of backend._layers || []) layer.fire('error', { error });\n });\n }\n if (map._animatingZoom) backend.update();\n}\n"],
5
- "mappings": "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",
6
- "names": ["computeBounds", "traverse", "updateWorldMatrix", "updateCamera", "update", "backend", "shared", "onMapChange", "getTileLevel", "level", "layer", "startZoom", "endZoom", "animation", "render", "map", "size", "now", "time", "start", "pixelsPerMeter", "origin", "transform", "point", "distance", "center", "target", "pitch", "bearing", "camera", "sunlight", "lightPoint", "lightLength", "light", "skyPoint", "skyLength", "sky", "projection", "frustum", "frustumLengths", "mesh", "bounds", "world", "x", "y", "z", "radius", "clipZ", "clipW", "renderer", "rasters", "tiles", "tile", "signature", "el", "coords", "selection", "zoom", "min", "scale", "width", "height", "pixels", "matrix", "texture", "device", "module", "roofTiles", "source", "opacities", "opacityBuffer", "encoder", "atlasPass", "a", "b", "i", "tileSize", "offset", "meshes", "pendingRasterTiles", "shadowMeshes", "frameData", "night", "pass", "uniforms", "determinant", "frontFace", "program", "error"]
7
- }
@@ -1,2 +0,0 @@
1
- import{parseColor as Y,triangulate as K,isClockWise as Q,treeGeometry as b,lightGeometry as k,lampPostGeometry as tt}from"../utils/geometry.js";import{emptyNode as et}from"../utils/scene.js";function it(t){if(t._map){for(const e of t._areas.values())t._releaseArea(e);t._areas.clear(),t._updateArea()}}function st(t){if(!t._map||!t.header)return;const e=t.header.minZoom,o=t._map.project(t._map.getCenter(),e).divideBy(256).floor(),n=t._map.getBounds(),O=t._map.project(n.getNorthWest(),e).divideBy(256).floor(),m=t._map.project(n.getSouthEast(),e).divideBy(256).floor(),G=t._map.project([t.header.maxLat,t.header.minLon],e).divideBy(256).floor(),P=t._map.project([t.header.minLat,t.header.maxLon],e).divideBy(256).floor(),A=new Map;for(let f=Math.max(0,O.x-1,G.x);f<=Math.min(2**e-1,m.x+1,P.x);f++)for(let y=Math.max(0,O.y-1,G.y);y<=Math.min(2**e-1,m.y+1,P.y);y++)A.set(`${f}/${y}`,{z:e,x:f,y});for(const[f,y]of t._areas)A.has(f)||(t._releaseArea(y),t._areas.delete(f));for(const[f,y]of[...A].sort(([,q],[,B])=>Math.hypot(q.x-o.x,q.y-o.y)-Math.hypot(B.x-o.x,B.y-o.y)))t._areas.has(f)||t._areas.set(f,{coords:y,request:new AbortController});t._pump()}async function nt(t,e){const{z:o,x:n,y:O}=e.coords,m=await t.getZxy(o,n,O,e.request.signal);return m?JSON.parse(new TextDecoder().decode(m.data)):{type:"FeatureCollection",features:[]}}function at(t){if(!(!t._map||!t._shared)){for(const e of t._areas.values()){if(t._inflight>=2)break;e.started||(e.started=!0,t._inflight++,(async()=>{try{const o=e.coords,n=await t._loadSource(e);if(e.request.signal.aborted)return;if(n?.type!=="FeatureCollection"||!Array.isArray(n.features))throw new Error("Invalid GeoJSON response");const O=n.features,m=[],G=[],P=[],A=[],f=[],y=[],q=new Set;let B=0;const U=t._map,R=U.options.crs,I=R.project(t.location),J=Math.cos(t.location.lat*Math.PI/180),$=i=>i.ground||0,S=(i,r,h,E,g,w,s,l,p,c)=>{const d=h.x-i.x,C=E-r,z=i.y-h.y,x=g.x-i.x,_=w-r,a=i.y-g.y;if((C*a-z*_)*s+(z*x-d*a)*l+(d*_-C*x)*p<0){const u=h,v=E;h=g,E=w,g=u,w=v}m.push(i.x,r+$(i),-i.y,h.x,E+$(h),-h.y,g.x,w+$(g),-g.y),G.push(s,l,p,s,l,p,s,l,p),P.push(c.r,c.g,c.b,c.r,c.g,c.b,c.r,c.g,c.b),t.options.nightLight&&A.push(...i.uv,...h.uv,...g.uv)};let Z=performance.now()+8;for(const i of O){if(e.request.signal.aborted)return;if(performance.now()>=Z){if(await new Promise(requestAnimationFrame),e.request.signal.aborted)return;Z=performance.now()+8}const r=i?.geometry,h=r?.type==="Point";if(t.options.nightLight&&!h)throw new Error("Night lights require Point geometry");const E=r?.type==="Polygon"?[r.coordinates]:r?.type==="MultiPolygon"?r.coordinates:null;if(!E&&!h)throw new Error("Unsupported GeoJSON geometry");const[g,w]=(h?r.coordinates:E[0]?.[0]?.[0])??[];if(!Number.isFinite(g)||!Number.isFinite(w))throw new Error("Invalid GeoJSON coordinates");if(o){const x=U.project(new L.LatLng(w,g),o.z);if(Math.floor(x.x/256)!==o.x||Math.floor(x.y/256)!==o.y)continue}const s=t.options.featureStyle(i);if(s===null){B++;continue}if(!s||typeof s!="object")throw new Error("featureStyle must return an extrusion style or null");const{top:l,bottom:p=0,color:c=14267276}=s;if(!Number.isFinite(l)||!Number.isFinite(p)||p<0||l<=p)throw new Error("Invalid extrusion heights: expected top > bottom >= 0");const d=Y(c),C=m.length/3;if(h){const x=R.project(new L.LatLng(w,g)),_=U._terrain3D?._getElevation([w,g]),a={x:(x.x-I.x)*J,y:(x.y-I.y)*J,ground:Number.isFinite(_)&&Number.isFinite(t.root.position[1])?_-t.root.position[1]:0};if(t.options.nightLight){if(!Number.isFinite(s.lightFlux)||s.lightFlux<=0)throw new Error("Invalid light flux");const u=i.properties?.cod_ouvrag||`${g},${w}`;s.poleRadius>0&&!q.has(u)&&(tt(a,s,S),q.add(u)),k(a,s,S),y.push({position:[a.x,a.ground+l,-a.y],radius:Math.hypot(l,s.lightRadius),color:[d.r,d.g,d.b],flux:s.lightFlux})}else b(a,s,S)}for(const x of E||[]){if(!x.length)throw new Error("Empty GeoJSON polygon");const _=x.map(u=>{if(u.length<4)throw new Error("Invalid GeoJSON polygon ring");return u.slice(0,-1).map(([v,N])=>{if(!Number.isFinite(v)||!Number.isFinite(N))throw new Error("Invalid GeoJSON coordinates");const j=R.project(new L.LatLng(N,v)),F=t._map._terrain3D?._getElevation([N,v]);return{x:(j.x-I.x)*J,y:(j.y-I.y)*J,ground:Number.isFinite(F)&&Number.isFinite(t.root.position[1])?F-t.root.position[1]:0}})}),a=_.flat();for(const[u,v,N]of K(_[0],_.slice(1)))S(a[u],l,a[v],l,a[N],l,0,1,0,d),p>0&&S(a[u],p,a[v],p,a[N],p,0,-1,0,d);_.forEach((u,v)=>{const N=Q(u)===(v===0)?-1:1;for(let j=0;j<u.length;j++){const F=u[j],M=u[(j+1)%u.length],W=Math.hypot(M.x-F.x,M.y-F.y);if(!W)continue;const H=N*(M.y-F.y)/W,V=N*(M.x-F.x)/W;S(F,p,M,p,M,l,H,0,V,d),S(F,p,M,l,F,l,H,0,V,d)}})}const z=m.length/3;f.push({id:i.id??i.properties?.objectid??JSON.stringify(r),properties:i.properties,baseColor:d,faceStart:C/3,faceEnd:z/3,vertexStart:C,vertexEnd:z})}if(!m.length){Object.assign(e,{mesh:null,buildings:0,skipped:B,done:!0});return}const T=t.renderer.device,D={position:{size:3,data:new Float32Array(m)},normal:{size:3,data:new Float32Array(G)},color:{size:3,data:new Float32Array(P)}};t.options.nightLight&&(D.uv={size:2,data:new Float32Array(A)});for(const[i,r]of Object.entries(D))r.count=r.data.length/r.size,r.buffer=T.createBuffer({size:Math.max(4,r.data.byteLength),usage:GPUBufferUsage.VERTEX|GPUBufferUsage.COPY_DST}),T.queue.writeBuffer(r.buffer,0,r.data);const X={device:T,attributes:D,drawRange:{start:0,count:D.position.count}};Object.assign(e,{mesh:{...et(),device:T,geometry:X,program:t._createProgram({vertexColors:!0,roofTexture:!!t.options.roofTexture,...t.options.nightLight?{nightLight:!0,alphaMode:"BLEND",doubleSided:!0}:{}}),id:L.Layer.types["3d"]._nextId++,renderOrder:0,extras:{featureFaces:f,lights:y}},buildings:f.length,skipped:B,done:!0}),t.add(e.mesh)}catch(o){if(e.request.signal.aborted)return;e.error=o.message,t.fire("error",{error:o})}})().finally(()=>{t._inflight--,t._pump()}))}t._updateStatus()}}function ut(t,e){if(e.request.abort(),e.mesh){t.highlightedFeature?.mesh===e.mesh&&(t._setHighlight(null),t.hoveredFeature=null,t._showFeature(null)),t.remove(e.mesh);const o=e.mesh.geometry;for(const n of Object.values(o.attributes))n.buffer.destroy();t._removeProgram(e.mesh.program)}}function lt(t,e=!0){const o={enabled:e,loaded:0,skipped:0,pending:0,errors:[]};for(const n of t._areas.values())n.error?o.errors.push(n.error):n.done||o.pending++,o.loaded+=n.buildings??0,o.skipped+=n.skipped??0;t.fire("progress",o)}export{nt as loadSource,it as onTerrainChange,at as pump,ut as releaseArea,st as updateArea,lt as updateStatus};
2
- //# sourceMappingURL=sources.js.map
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../src/scene/sources.js"],
4
- "sourcesContent": ["import { parseColor, triangulate, isClockWise, treeGeometry, lightGeometry, lampPostGeometry } from '../utils/geometry.js';\nimport { emptyNode } from '../utils/scene.js';\n\n/** GeoJSON source areas: loading, building and releasing. */\nexport function onTerrainChange(backend) {\n if (!backend._map) return;\n for (const area of backend._areas.values()) backend._releaseArea(area);\n backend._areas.clear();\n backend._updateArea();\n}\n\n/** Cover the visible ground bounds and one bordering block, clipped to the archive. */\nexport function updateArea(backend) {\n if (!backend._map || !backend.header) return;\n const z = backend.header.minZoom;\n const center = backend._map.project(backend._map.getCenter(), z).divideBy(256).floor();\n const bounds = backend._map.getBounds();\n const nw = backend._map.project(bounds.getNorthWest(), z).divideBy(256).floor();\n const se = backend._map.project(bounds.getSouthEast(), z).divideBy(256).floor();\n const archiveNW = backend._map.project([backend.header.maxLat, backend.header.minLon], z).divideBy(256).floor();\n const archiveSE = backend._map.project([backend.header.minLat, backend.header.maxLon], z).divideBy(256).floor();\n const wanted = new Map();\n for (let x = Math.max(0, nw.x - 1, archiveNW.x); x <= Math.min(2 ** z - 1, se.x + 1, archiveSE.x); x++) {\n for (let y = Math.max(0, nw.y - 1, archiveNW.y); y <= Math.min(2 ** z - 1, se.y + 1, archiveSE.y); y++) {\n wanted.set(`${x}/${y}`, { z, x, y });\n }\n }\n for (const [key, area] of backend._areas) {\n if (!wanted.has(key)) {\n backend._releaseArea(area);\n backend._areas.delete(key);\n }\n }\n // Load the nearest new blocks first without rebuilding retained geometry.\n for (const [key, coords] of [...wanted].sort(([, a], [, b]) =>\n Math.hypot(a.x - center.x, a.y - center.y) - Math.hypot(b.x - center.x, b.y - center.y))) {\n if (!backend._areas.has(key)) backend._areas.set(key, { coords, request: new AbortController() });\n }\n backend._pump();\n}\n\nexport async function loadSource(backend, area) {\n const { z, x, y } = area.coords;\n const result = await backend.getZxy(z, x, y, area.request.signal);\n return result ? JSON.parse(new TextDecoder().decode(result.data))\n : { type: 'FeatureCollection', features: [] };\n}\n\n/** Start at most two load/build tasks; cancelled tasks still free their slot in finally. */\nexport function pump(backend) {\n // Meshes need the shared renderer; _attach() re-runs _updateArea() once it exists.\n if (!backend._map || !backend._shared) return;\n for (const area of backend._areas.values()) {\n if (backend._inflight >= 2) break;\n if (area.started) continue;\n area.started = true;\n backend._inflight++;\n (async () => {\n try {\n const coords = area.coords;\n const data = await backend._loadSource(area);\n if (area.request.signal.aborted) return;\n if (data?.type !== 'FeatureCollection' || !Array.isArray(data.features)) {\n throw new Error('Invalid GeoJSON response');\n }\n const features = data.features;\n const positions = [], normals = [], colors = [], uvs = [], featureFaces = [], lights = [];\n const supports = new Set();\n let skipped = 0;\n const map = backend._map;\n const crs = map.options.crs;\n const origin = crs.project(backend.location);\n const metres = Math.cos(backend.location.lat * Math.PI / 180);\n const groundOffset = point => point.ground || 0;\n const addTriangle = (a, ah, b, bh, c, ch, nx, ny, nz, color) => {\n const ux = b.x - a.x, uy = bh - ah, uz = a.y - b.y;\n const vx = c.x - a.x, vy = ch - ah, vz = a.y - c.y;\n // Orient the triangle to its intended outward normal after flipping north to -z.\n if ((uy * vz - uz * vy) * nx + (uz * vx - ux * vz) * ny + (ux * vy - uy * vx) * nz < 0) {\n const point = b, height = bh;\n b = c; bh = ch; c = point; ch = height;\n }\n positions.push(a.x, ah + groundOffset(a), -a.y,\n b.x, bh + groundOffset(b), -b.y,\n c.x, ch + groundOffset(c), -c.y);\n normals.push(nx, ny, nz, nx, ny, nz, nx, ny, nz);\n colors.push(color.r, color.g, color.b, color.r, color.g, color.b, color.r, color.g, color.b);\n if (backend.options.nightLight) uvs.push(...a.uv, ...b.uv, ...c.uv);\n };\n let deadline = performance.now() + 8;\n for (const feature of features) {\n if (area.request.signal.aborted) return;\n if (performance.now() >= deadline) {\n await new Promise(requestAnimationFrame);\n if (area.request.signal.aborted) return;\n deadline = performance.now() + 8;\n }\n const geometry = feature?.geometry;\n const isTree = geometry?.type === 'Point';\n if (backend.options.nightLight && !isTree) throw new Error('Night lights require Point geometry');\n const polygons = geometry?.type === 'Polygon' ? [geometry.coordinates] : geometry?.type === 'MultiPolygon' ? geometry.coordinates : null;\n if (!polygons && !isTree) throw new Error('Unsupported GeoJSON geometry');\n const [lon, lat] = (isTree ? geometry.coordinates : polygons[0]?.[0]?.[0]) ?? [];\n if (!Number.isFinite(lon) || !Number.isFinite(lat)) throw new Error('Invalid GeoJSON coordinates');\n if (coords) {\n const anchor = map.project(new L.LatLng(lat, lon), coords.z);\n // Overlapping archive blocks may contain the same polygon; its first vertex owns it.\n if (Math.floor(anchor.x / 256) !== coords.x || Math.floor(anchor.y / 256) !== coords.y) continue;\n }\n const style = backend.options.featureStyle(feature);\n if (style === null) {\n skipped++;\n continue;\n }\n if (!style || typeof style !== 'object') throw new Error('featureStyle must return an extrusion style or null');\n const { top, bottom = 0, color = 0xd9b38c } = style;\n if (!Number.isFinite(top) || !Number.isFinite(bottom) || bottom < 0 || top <= bottom) {\n throw new Error('Invalid extrusion heights: expected top > bottom >= 0');\n }\n const baseColor = parseColor(color);\n const vertexStart = positions.length / 3;\n if (isTree) {\n const point = crs.project(new L.LatLng(lat, lon));\n const elevation = map._terrain3D?._getElevation([lat, lon]);\n const projected = {\n x: (point.x - origin.x) * metres, y: (point.y - origin.y) * metres,\n ground: Number.isFinite(elevation) && Number.isFinite(backend.root.position[1])\n ? elevation - backend.root.position[1] : 0,\n };\n if (backend.options.nightLight) {\n if (!Number.isFinite(style.lightFlux) || style.lightFlux <= 0) throw new Error('Invalid light flux');\n const support = feature.properties?.cod_ouvrag || `${lon},${lat}`;\n if (style.poleRadius > 0 && !supports.has(support)) {\n lampPostGeometry(projected, style, addTriangle);\n supports.add(support);\n }\n lightGeometry(projected, style, addTriangle);\n lights.push({\n position: [projected.x, projected.ground + top, -projected.y],\n radius: Math.hypot(top, style.lightRadius), color: [baseColor.r, baseColor.g, baseColor.b],\n flux: style.lightFlux,\n });\n } else treeGeometry(projected, style, addTriangle);\n }\n for (const rings of polygons || []) {\n if (!rings.length) throw new Error('Empty GeoJSON polygon');\n const paths = rings.map(ring => {\n if (ring.length < 4) throw new Error('Invalid GeoJSON polygon ring');\n return ring.slice(0, -1).map(([lng, lat]) => {\n if (!Number.isFinite(lng) || !Number.isFinite(lat)) throw new Error('Invalid GeoJSON coordinates');\n const point = crs.project(new L.LatLng(lat, lng));\n const elevation = backend._map._terrain3D?._getElevation([lat, lng]);\n return {\n x: (point.x - origin.x) * metres,\n y: (point.y - origin.y) * metres,\n ground: Number.isFinite(elevation) && Number.isFinite(backend.root.position[1])\n ? elevation - backend.root.position[1] : 0,\n };\n });\n });\n const points = paths.flat();\n for (const [a, b, c] of triangulate(paths[0], paths.slice(1))) {\n addTriangle(points[a], top, points[b], top, points[c], top, 0, 1, 0, baseColor);\n if (bottom > 0) addTriangle(points[a], bottom, points[b], bottom, points[c], bottom, 0, -1, 0, baseColor);\n }\n paths.forEach((path, index) => {\n // Interior walls face into the courtyard; exterior walls face away from the building.\n const sign = isClockWise(path) === (index === 0) ? -1 : 1;\n for (let i = 0; i < path.length; i++) {\n const a = path[i], b = path[(i + 1) % path.length];\n const length = Math.hypot(b.x - a.x, b.y - a.y);\n if (!length) continue;\n const nx = sign * (b.y - a.y) / length, nz = sign * (b.x - a.x) / length;\n addTriangle(a, bottom, b, bottom, b, top, nx, 0, nz, baseColor);\n addTriangle(a, bottom, b, top, a, top, nx, 0, nz, baseColor);\n }\n });\n }\n const vertexEnd = positions.length / 3;\n featureFaces.push({\n id: feature.id ?? feature.properties?.objectid ?? JSON.stringify(geometry),\n properties: feature.properties, baseColor,\n faceStart: vertexStart / 3, faceEnd: vertexEnd / 3, vertexStart, vertexEnd,\n });\n }\n if (!positions.length) {\n Object.assign(area, { mesh: null, buildings: 0, skipped, done: true });\n return;\n }\n const device = backend.renderer.device;\n const attributes = {\n position: { size: 3, data: new Float32Array(positions) },\n normal: { size: 3, data: new Float32Array(normals) },\n color: { size: 3, data: new Float32Array(colors) },\n };\n if (backend.options.nightLight) attributes.uv = { size: 2, data: new Float32Array(uvs) };\n for (const [name, attribute] of Object.entries(attributes)) {\n attribute.count = attribute.data.length / attribute.size;\n attribute.buffer = device.createBuffer({\n size: Math.max(4, attribute.data.byteLength),\n usage: GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_DST,\n });\n device.queue.writeBuffer(attribute.buffer, 0, attribute.data);\n }\n const meshGeometry = {\n device,\n attributes,\n drawRange: { start: 0, count: attributes.position.count },\n };\n Object.assign(area, {\n mesh: {\n ...emptyNode(),\n device,\n geometry: meshGeometry,\n program: backend._createProgram({ vertexColors: true, roofTexture: Boolean(backend.options.roofTexture),\n ...(backend.options.nightLight ? { nightLight: true, alphaMode: 'BLEND', doubleSided: true } : {}) }),\n id: L.Layer.types['3d']._nextId++,\n renderOrder: 0,\n extras: { featureFaces, lights },\n },\n buildings: featureFaces.length,\n skipped,\n done: true\n });\n backend.add(area.mesh);\n } catch (error) {\n if (area.request.signal.aborted) return;\n area.error = error.message;\n backend.fire('error', { error });\n }\n })().finally(() => {\n backend._inflight--;\n backend._pump();\n });\n }\n backend._updateStatus();\n}\n\n/** Cancel pending work and dispose this block's GPU data, including any hover highlight. */\nexport function releaseArea(backend, area) {\n area.request.abort();\n if (area.mesh) {\n if (backend.highlightedFeature?.mesh === area.mesh) {\n backend._setHighlight(null);\n backend.hoveredFeature = null;\n backend._showFeature(null);\n }\n backend.remove(area.mesh);\n const geometry = area.mesh.geometry;\n for (const attribute of Object.values(geometry.attributes)) attribute.buffer.destroy();\n backend._removeProgram(area.mesh.program);\n }\n}\n\n/** Emit a snapshot for consumers; ready does not wait for all neighborhood tasks. */\nexport function updateStatus(backend, enabled = true) {\n const progress = { enabled, loaded: 0, skipped: 0, pending: 0, errors: [] };\n for (const area of backend._areas.values()) {\n if (area.error) progress.errors.push(area.error);\n else if (!area.done) progress.pending++;\n progress.loaded += area.buildings ?? 0;\n progress.skipped += area.skipped ?? 0;\n }\n backend.fire('progress', progress);\n}\n"],
5
- "mappings": "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",
6
- "names": ["parseColor", "triangulate", "isClockWise", "treeGeometry", "lightGeometry", "lampPostGeometry", "emptyNode", "onTerrainChange", "backend", "area", "updateArea", "z", "center", "bounds", "nw", "se", "archiveNW", "archiveSE", "wanted", "x", "key", "coords", "a", "b", "loadSource", "y", "result", "pump", "data", "features", "positions", "normals", "colors", "uvs", "featureFaces", "lights", "supports", "skipped", "map", "crs", "origin", "metres", "groundOffset", "point", "addTriangle", "ah", "bh", "c", "ch", "nx", "ny", "nz", "color", "ux", "uy", "uz", "vx", "vy", "vz", "height", "deadline", "feature", "geometry", "isTree", "polygons", "lon", "lat", "anchor", "style", "top", "bottom", "baseColor", "vertexStart", "elevation", "projected", "support", "rings", "paths", "ring", "lng", "points", "path", "index", "sign", "i", "length", "vertexEnd", "device", "attributes", "name", "attribute", "meshGeometry", "error", "releaseArea", "updateStatus", "enabled", "progress"]
7
- }