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
@@ -0,0 +1,40 @@
1
+ import { pump } from "./pump.js";
2
+ import { releaseArea } from "./releaseArea.js";
3
+
4
+ /** Cover the visible ground bounds and one bordering block, clipped to the archive. */
5
+
6
+ export function updateArea(backend) {
7
+ if (!backend._map || !backend._shared) return;
8
+ if (backend._geojson) {
9
+ if (!backend._areas.has('geojson')) {
10
+ backend._areas.set('geojson', { request: new AbortController() });
11
+ }
12
+ pump(backend);
13
+ return;
14
+ }
15
+ if (!backend.header) return;
16
+ const z = backend.header.minZoom;
17
+ const center = backend._map.project(backend._map.getCenter(), z).divideBy(256).floor();
18
+ const bounds = backend._map.getBounds();
19
+ const nw = backend._map.project(bounds.getNorthWest(), z).divideBy(256).floor();
20
+ const se = backend._map.project(bounds.getSouthEast(), z).divideBy(256).floor();
21
+ const archiveNW = backend._map.project([backend.header.maxLat, backend.header.minLon], z).divideBy(256).floor();
22
+ const archiveSE = backend._map.project([backend.header.minLat, backend.header.maxLon], z).divideBy(256).floor();
23
+ const wanted = new Map();
24
+ for (let x = Math.max(0, nw.x - 1, archiveNW.x); x <= Math.min(2 ** z - 1, se.x + 1, archiveSE.x); x++) {
25
+ for (let y = Math.max(0, nw.y - 1, archiveNW.y); y <= Math.min(2 ** z - 1, se.y + 1, archiveSE.y); y++) {
26
+ wanted.set(`${x}/${y}`, { z, x, y });
27
+ }
28
+ }
29
+ for (const [key, area] of backend._areas) {
30
+ if (!wanted.has(key)) {
31
+ releaseArea(backend, area);
32
+ backend._areas.delete(key);
33
+ }
34
+ }
35
+ // Load the nearest new blocks first without rebuilding retained geometry.
36
+ for (const [key, coords] of [...wanted].sort(([, a], [, b]) => Math.hypot(a.x - center.x, a.y - center.y) - Math.hypot(b.x - center.x, b.y - center.y))) {
37
+ if (!backend._areas.has(key)) backend._areas.set(key, { coords, request: new AbortController() });
38
+ }
39
+ pump(backend);
40
+ }
@@ -0,0 +1,32 @@
1
+ /** Orthonormal view basis plus perspective matrices, refreshed before projecting/drawing. */
2
+
3
+ const cross = (a, b) => [a[1] * b[2] - a[2] * b[1], a[2] * b[0] - a[0] * b[2], a[0] * b[1] - a[1] * b[0]];
4
+
5
+ export function updateCamera(camera) {
6
+ const z = camera.position.map((v, i) => v - camera.target[i]);
7
+ const zLength = Math.hypot(...z) || 1;
8
+ for (let i = 0; i < 3; i++) {
9
+ z[i] /= zLength;
10
+ }
11
+ const x = cross(camera.up, z), xLength = Math.hypot(...x) || 1;
12
+ for (let i = 0; i < 3; i++) {
13
+ x[i] /= xLength;
14
+ }
15
+ const y = cross(z, x);
16
+ const view = new DOMMatrix([x[0], x[1], x[2], 0, y[0], y[1], y[2], 0, z[0], z[1], z[2], 0, ...camera.position, 1]).inverse().toFloat64Array();
17
+ if (![...view].every(Number.isFinite)) {
18
+ throw new Error('Singular 3D transform');
19
+ }
20
+ for (let i = 0; i < 16; i++) {
21
+ camera.viewMatrix[i] = view[i];
22
+ }
23
+ const f = 1 / Math.tan(camera.fov * Math.PI / 360), n = camera.near, r = camera.far;
24
+ const projection = [f / camera.aspect, 0, 0, 0, 0, f, 0, 0, 0, 0, r / (n - r), -1, 0, 0, r * n / (n - r), 0];
25
+ for (let i = 0; i < 16; i++) {
26
+ camera.projectionMatrix[i] = projection[i];
27
+ }
28
+ const projectionView = new DOMMatrix(camera.projectionMatrix).multiply(new DOMMatrix(camera.viewMatrix)).toFloat64Array();
29
+ for (let i = 0; i < 16; i++) {
30
+ camera.projectionViewMatrix[i] = projectionView[i];
31
+ }
32
+ }
@@ -0,0 +1,38 @@
1
+ import { lightGrid } from './lightGrid.js';
2
+ import { traverse } from './traverse.js';
3
+ import { worldLights } from './worldLights.js';
4
+ import { destroyTexture } from './destroyTexture.js';
5
+ import { bindSunlight } from './bindSunlight.js';
6
+
7
+ /** A cached spatial grid limits fragment lighting to nearby lamps, without dropping dense cells. */
8
+
9
+ export function updatePointLights(backend) {
10
+ const { device, sunlight: sun } = backend.renderer;
11
+ const meshes = [];
12
+ for (const layer of backend._layers) {
13
+ if (!layer.options.nightLight || !layer.root.visible) continue;
14
+ traverse(layer.root, mesh => {
15
+ if (!mesh.visible) return true;
16
+ if (mesh.extras?.lights) meshes.push(mesh);
17
+ });
18
+ }
19
+ if (sun.lightMeshes?.length === meshes.length && meshes.every((mesh, i) => sun.lightMeshes[i].mesh === mesh &&
20
+ sun.lightMeshes[i].lights === mesh.extras.lights && mesh.worldMatrix.every((v, j) => v === sun.lightMeshes[i].matrix[j]))) return;
21
+ // Per mesh, world-space [x, y, z, radius, r, g, b, intensity] per light: re-packed only when its lights or matrix change.
22
+ const packed = meshes.map(mesh => {
23
+ const cache = mesh._worldLights, m = mesh.worldMatrix, lights = mesh.extras.lights;
24
+ if (cache?.lights === lights && m.every((v, j) => v === cache.matrix[j])) return cache.data;
25
+ const values = worldLights(lights, m);
26
+ mesh._worldLights = { lights, matrix: [...m], data: values };
27
+ return values;
28
+ });
29
+ const { data, count } = lightGrid(packed, device.limits.maxStorageBufferBindingSize);
30
+ if (sun.lights.size < data.byteLength) {
31
+ destroyTexture(backend, sun.lights);
32
+ sun.lights = device.createBuffer({ size: data.byteLength, usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_DST });
33
+ bindSunlight(backend);
34
+ }
35
+ device.queue.writeBuffer(sun.lights, 0, data);
36
+ sun.lightCount = count;
37
+ sun.lightMeshes = meshes.map(mesh => ({ mesh, lights: mesh.extras.lights, matrix: [...mesh.worldMatrix] }));
38
+ }
@@ -0,0 +1,47 @@
1
+ /** Compose parent*local matrices; a node.matrix overrides its position/rotation/scale. */
2
+
3
+ export function updateWorldMatrix(node) {
4
+ const parent = node.parent;
5
+ const parentVersion = parent?._worldMatrixVersion || 0;
6
+ const matrixMode = Boolean(node.matrix);
7
+ let changed = node._worldParent !== parent || node._parentWorldVersion !== parentVersion ||
8
+ node._worldMatrixMode !== matrixMode;
9
+ if (node.matrix) {
10
+ const state = node._matrixState ||= new Float64Array(16);
11
+ for (let i = 0; i < 16; i++) {
12
+ if (state[i] !== node.matrix[i]) changed = true;
13
+ state[i] = node.matrix[i];
14
+ }
15
+ } else {
16
+ const state = node._transformState ||= new Float64Array(9);
17
+ for (let i = 0; i < 9; i++) {
18
+ const value = i < 3 ? node.position[i] : i < 6 ? node.rotation[i - 3] : node.scale[i - 6];
19
+ if (state[i] !== value) changed = true;
20
+ state[i] = value;
21
+ }
22
+ }
23
+ if (!changed) {
24
+ for (const child of node.children) updateWorldMatrix(child);
25
+ return;
26
+ }
27
+ let local;
28
+ if (node.matrix) local = node.matrix;
29
+ else {
30
+ const degrees = 180 / Math.PI;
31
+ const matrix = new DOMMatrix().translate(...node.position);
32
+ // Node rotations use YXZ, as did the previous renderer.
33
+ matrix.rotateAxisAngleSelf(0, 1, 0, node.rotation[1] * degrees);
34
+ matrix.rotateAxisAngleSelf(1, 0, 0, node.rotation[0] * degrees);
35
+ matrix.rotateAxisAngleSelf(0, 0, 1, node.rotation[2] * degrees);
36
+ local = matrix.scale(...node.scale).toFloat64Array();
37
+ }
38
+ const world = parent
39
+ ? new DOMMatrix(parent.worldMatrix).multiply(new DOMMatrix(local)).toFloat64Array()
40
+ : local;
41
+ for (let i = 0; i < 16; i++) node.worldMatrix[i] = world[i];
42
+ node._worldParent = parent;
43
+ node._parentWorldVersion = parentVersion;
44
+ node._worldMatrixMode = matrixMode;
45
+ node._worldMatrixVersion = (node._worldMatrixVersion || 0) + 1;
46
+ for (const child of node.children) updateWorldMatrix(child);
47
+ }
@@ -0,0 +1,8 @@
1
+ import { speed } from "./speed.js";
2
+
3
+ /** Evenly spaced starting offsets (metres) for `flow` vehicles/h moving at `velocity` m/s on a `length` metres lane. */
4
+
5
+ export function vehicleOffsets(length, flow, velocity = speed) {
6
+ const count = Math.round(length * flow / 3600 / velocity);
7
+ return Array.from({ length: count }, (_, i) => (i + 0.5) * length / count);
8
+ }
@@ -1,69 +1,65 @@
1
- // Built-in vehicles for the 'traffic' type. Models are [ring of [x, z], bottom, top, rgb, topRing?] convex prisms in metres;
2
- // forward is -z, right is +x. `topRing` (same length as `ring`) tapers the prism; rgb components above 1 are self-lit lamps.
3
- const paints = [[0.86, 0.86, 0.88], [0.1, 0.1, 0.12], [0.5, 0.53, 0.57], [0.65, 0.1, 0.08], [0.12, 0.25, 0.55], [0.85, 0.7, 0.15]];
4
- export const box = (x0, x1, z0, z1) => [[x0, z0], [x1, z0], [x1, z1], [x0, z1]];
5
- const mirror = (x0, x1, z0, z1, ...rest) => [[box(x0, x1, z0, z1), ...rest], [box(-x1, -x0, z0, z1), ...rest]];
6
- const glass = [0.12, 0.15, 0.18], tyre = [0.05, 0.05, 0.05];
7
- const headlight = [1.9, 1.85, 1.7], taillight = [1.7, 0.06, 0.05];
8
- const car = i => {
9
- const paint = paints[i % paints.length];
10
- return [
11
- ...mirror(0.7, 0.92, -1.68, -1.02, 0, 0.64, tyre),
12
- ...mirror(0.7, 0.92, 1.02, 1.68, 0, 0.64, tyre),
13
- [[[-0.9, -1.95], [-0.72, -2.25], [0.72, -2.25], [0.9, -1.95], [0.9, 2.05], [0.76, 2.25], [-0.76, 2.25], [-0.9, 2.05]],
14
- 0.28, 0.82, paint],
15
- // Greenhouse: the windscreen leans back, the rear window less.
16
- [box(-0.84, 0.84, -0.75, 1.6), 0.82, 1.38, glass, box(-0.7, 0.7, -0.05, 1.3)],
17
- [box(-0.71, 0.71, -0.06, 1.31), 1.38, 1.46, paint],
18
- ...mirror(0.38, 0.8, -2.3, -2.16, 0.56, 0.76, headlight),
19
- [box(-0.78, 0.78, 2.16, 2.3), 0.6, 0.76, taillight],
20
- ];
21
- };
22
- // Panoramic river cruiser, about 60 × 11 m: glass saloon, open upper deck with benches, wheelhouse forward.
23
- const white = [0.92, 0.93, 0.92], hull = [[-5.5, 30], [5.5, 30], [5.5, -20], [4, -26], [1.5, -30], [-1.5, -30], [-4, -26], [-5.5, -20]];
24
- const boat = () => [
25
- [hull, 0, 0.8, [0.1, 0.16, 0.26]],
26
- [hull, 0.8, 1.4, white],
27
- [box(-5, 5, -18, 26), 1.4, 3.7, glass, box(-4.6, 4.6, -17.4, 25.6)],
28
- ...mirror(4.64, 4.74, -17, 25, 3.25, 3.45, [1.6, 1.25, 0.8]),
29
- [box(-4.8, 4.8, -17.8, 25.8), 3.7, 3.9, white],
30
- ...Array.from({ length: 12 }, (_, i) => mirror(0.5, 3.8, -12 + i * 3, -11.3 + i * 3, 3.9, 4.4, [0.62, 0.1, 0.1])).flat(),
31
- ...mirror(4.65, 4.8, -13.6, 25.8, 3.9, 4.8, white),
32
- [box(-4.8, 4.8, 25.65, 25.8), 3.9, 4.8, white],
33
- [box(-2.2, 2.2, -17.6, -14), 3.9, 4.7, white],
34
- [box(-2.2, 2.2, -17.6, -14), 4.7, 5.5, glass],
35
- [box(-2.5, 2.5, -18, -13.6), 5.5, 5.7, white],
36
- [box(-2.45, -2.2, -16.2, -15.8), 5, 5.3, [2, 0.15, 0.1]],
37
- [box(2.2, 2.45, -16.2, -15.8), 5, 5.3, [0.1, 2, 0.4]],
38
- [box(-0.1, 0.1, -15.9, -15.7), 5.7, 6.6, white],
39
- [box(-0.15, 0.15, -15.95, -15.65), 6.6, 6.8, [2, 2, 1.9]],
40
- ];
41
-
42
- export const build = parts => {
43
- const position = [], normal = [], color = [];
44
- const triangle = (a, b, c, tint) => {
45
- const u = b.map((v, i) => v - a[i]), v = c.map((w, i) => w - a[i]);
46
- const n = [u[1] * v[2] - u[2] * v[1], u[2] * v[0] - u[0] * v[2], u[0] * v[1] - u[1] * v[0]], length = Math.hypot(...n);
47
- for (const point of [a, b, c]) { position.push(...point); normal.push(...n.map(w => w / length)); color.push(...tint); }
48
- };
49
- for (const [ring, bottom, top, tint, topRing = ring] of parts) {
50
- const low = ring.map(([x, z]) => [x, bottom, z]), high = topRing.map(([x, z]) => [x, top, z]);
51
- for (let i = 0; i < ring.length; i++) {
52
- const j = (i + 1) % ring.length;
53
- triangle(low[i], low[j], high[j], tint); triangle(low[i], high[j], high[i], tint);
54
- }
55
- for (let i = 1; i < ring.length - 1; i++) {
56
- triangle(high[0], high[i], high[i + 1], tint); triangle(low[0], low[i + 1], low[i], tint);
57
- }
58
- }
59
- return { position, normal, color };
60
- };
61
-
62
- /**
63
- * `side`: default offset (metres) to the right of the lane centreline. `model(i)` gives the prisms of the i-th vehicle.
64
- * `lights`: night point lights in model space (see the night lighting grid), e.g. the pool cast by the headlights.
65
- */
66
- export const vehicles = {
67
- car: { side: 1.8, model: car, lights: [{ position: [0, 1.2, -6], radius: 10, color: [1, 0.94, 0.82], flux: 800 }] },
68
- boat: { side: 0, model: boat, lights: [{ position: [0, 8, 4], radius: 30, color: [1, 0.8, 0.55], flux: 20000 }] },
69
- };
1
+ import { hull } from "./hull.js";
2
+ import { box } from './box.js';
3
+ import { glass, tyre } from './glass.js';
4
+ import { mirror } from './mirror.js';
5
+ import { white } from "./white.js";
6
+ import { paints } from './paints.js';
7
+ import { headlight } from './headlight.js';
8
+ import { taillight } from './taillight.js';
9
+
10
+ /**
11
+ * `side`: default offset (metres) to the right of the lane centreline. `model(i)` gives the prisms of the i-th vehicle.
12
+ * `lights`: night point lights in model space (see the night lighting grid), e.g. the pool cast by the headlights.
13
+ */
14
+ export const vehicles = {
15
+ car: {
16
+ side: 1.8,
17
+ model: i => {
18
+ const paint = paints[i % paints.length];
19
+ return [
20
+ ...mirror(0.7, 0.92, -1.68, -1.02, 0, 0.64, tyre),
21
+ ...mirror(0.7, 0.92, 1.02, 1.68, 0, 0.64, tyre),
22
+ [[[-0.9, -1.95], [-0.72, -2.25], [0.72, -2.25], [0.9, -1.95], [0.9, 2.05], [0.76, 2.25], [-0.76, 2.25], [-0.9, 2.05]],
23
+ 0.28, 0.82, paint],
24
+ // Greenhouse: the windscreen leans back, the rear window less.
25
+ [box(-0.84, 0.84, -0.75, 1.6), 0.82, 1.38, glass, box(-0.7, 0.7, -0.05, 1.3)],
26
+ [box(-0.71, 0.71, -0.06, 1.31), 1.38, 1.46, paint],
27
+ ...mirror(0.38, 0.8, -2.3, -2.16, 0.56, 0.76, headlight),
28
+ [box(-0.78, 0.78, 2.16, 2.3), 0.6, 0.76, taillight],
29
+ ];
30
+ },
31
+ lights: [{
32
+ position: [0, 1.2, -6],
33
+ radius: 10,
34
+ color: [1, 0.94, 0.82],
35
+ flux: 800
36
+ }]
37
+ },
38
+ // Panoramic river cruiser, about 60 × 11 m: glass saloon, open upper deck with benches, wheelhouse forward.
39
+ boat: {
40
+ side: 0,
41
+ model: () => [
42
+ [hull, 0, 0.8, [0.1, 0.16, 0.26]],
43
+ [hull, 0.8, 1.4, white],
44
+ [box(-5, 5, -18, 26), 1.4, 3.7, glass, box(-4.6, 4.6, -17.4, 25.6)],
45
+ ...mirror(4.64, 4.74, -17, 25, 3.25, 3.45, [1.6, 1.25, 0.8]),
46
+ [box(-4.8, 4.8, -17.8, 25.8), 3.7, 3.9, white],
47
+ ...Array.from({ length: 12 }, (_, i) => mirror(0.5, 3.8, -12 + i * 3, -11.3 + i * 3, 3.9, 4.4, [0.62, 0.1, 0.1])).flat(),
48
+ ...mirror(4.65, 4.8, -13.6, 25.8, 3.9, 4.8, white),
49
+ [box(-4.8, 4.8, 25.65, 25.8), 3.9, 4.8, white],
50
+ [box(-2.2, 2.2, -17.6, -14), 3.9, 4.7, white],
51
+ [box(-2.2, 2.2, -17.6, -14), 4.7, 5.5, glass],
52
+ [box(-2.5, 2.5, -18, -13.6), 5.5, 5.7, white],
53
+ [box(-2.45, -2.2, -16.2, -15.8), 5, 5.3, [2, 0.15, 0.1]],
54
+ [box(2.2, 2.45, -16.2, -15.8), 5, 5.3, [0.1, 2, 0.4]],
55
+ [box(-0.1, 0.1, -15.9, -15.7), 5.7, 6.6, white],
56
+ [box(-0.15, 0.15, -15.95, -15.65), 6.6, 6.8, [2, 2, 1.9]],
57
+ ],
58
+ lights: [{
59
+ position: [0, 8, 4],
60
+ radius: 30,
61
+ color: [1, 0.8, 0.55],
62
+ flux: 20000
63
+ }]
64
+ },
65
+ };
@@ -0,0 +1,30 @@
1
+ /** Area-weighted vertex normals, for indexed or non-indexed triangles. */
2
+
3
+ export function vertexNormals(p, indices) {
4
+ // Accumulate area-weighted face normals for shared vertices, then normalize.
5
+ const normals = new Float32Array(p.length);
6
+ for (let i = 0; i < (indices?.length || p.length / 3); i += 3) {
7
+ const a = indices ? indices[i] : i,
8
+ b = indices ? indices[i + 1] : i + 1,
9
+ c = indices ? indices[i + 2] : i + 2;
10
+ const u = [0, 1, 2].map(j => p[b * 3 + j] - p[a * 3 + j]),
11
+ v = [0, 1, 2].map(j => p[c * 3 + j] - p[a * 3 + j]);
12
+ const n = [
13
+ u[1] * v[2] - u[2] * v[1],
14
+ u[2] * v[0] - u[0] * v[2],
15
+ u[0] * v[1] - u[1] * v[0]
16
+ ];
17
+ for (const index of [a, b, c]) {
18
+ for (let j = 0; j < 3; j++) {
19
+ normals[index * 3 + j] += n[j];
20
+ }
21
+ }
22
+ }
23
+ for (let i = 0; i < normals.length; i += 3) {
24
+ const length = Math.hypot(...normals.subarray(i, i + 3)) || 1;
25
+ for (let j = 0; j < 3; j++) {
26
+ normals[i + j] /= length;
27
+ }
28
+ }
29
+ return normals;
30
+ }
package/src/utils/walk.js CHANGED
@@ -1,72 +1,187 @@
1
- import { box } from './vehicles.js';
1
+ import * as createMesh from './createMesh.js';
2
+ import * as disposeMesh from './disposeMesh.js';
3
+ import * as update from './update.js';
4
+ import { build } from './build.js';
5
+ import { getElevation } from './getElevation.js';
6
+ import { hit } from './hit.js';
7
+ import { limbs } from './limbs.js';
8
+ import { moves } from './moves.js';
9
+ import { parts } from './parts.js';
10
+ import { wrap } from './wrap.js';
2
11
 
3
- // Pedestrian, about 1.77 m tall, prisms as in utils/vehicles.js (forward -z). Limbs hang from their pivot at y = 0.
4
- const skin = [0.85, 0.64, 0.5], shirt = [0.75, 0.2, 0.15], trousers = [0.16, 0.2, 0.32], dark = [0.08, 0.07, 0.06];
5
- export const parts = {
6
- body: [
7
- [box(-0.17, 0.17, -0.1, 0.1), 0.82, 0.95, trousers],
8
- [box(-0.19, 0.19, -0.11, 0.11), 0.95, 1.44, shirt],
9
- [box(-0.05, 0.05, -0.05, 0.05), 1.44, 1.5, skin],
10
- [box(-0.1, 0.1, -0.11, 0.1), 1.5, 1.72, skin],
11
- [box(-0.105, 0.105, -0.06, 0.115), 1.58, 1.77, dark],
12
- [box(-0.105, 0.105, -0.115, -0.06), 1.7, 1.77, dark],
13
- ],
14
- leg: [[box(-0.07, 0.07, -0.07, 0.07), -0.82, 0, trousers], [box(-0.07, 0.07, -0.17, 0.07), -0.9, -0.82, dark]],
15
- arm: [[box(-0.05, 0.05, -0.05, 0.05), -0.55, 0, shirt], [box(-0.045, 0.045, -0.045, 0.045), -0.66, -0.55, skin]],
16
- };
17
- // [part, pivot x, pivot y, swing sign]
18
- export const limbs = [['body', 0, 0, 0], ['leg', -0.09, 0.9, 1], ['leg', 0.09, 0.9, -1], ['arm', -0.25, 1.42, -1], ['arm', 0.25, 1.42, 1]];
19
- // Walls (non-horizontal triangles) of a mesh in world space, bucketed by 8 m cells; `origin` is the world translation
20
- // at build time, since layer roots only move vertically with the terrain afterwards.
21
- export const CELL = 8;
22
- const colliders = new WeakMap();
23
- export function collider(mesh) {
24
- let c = colliders.get(mesh.geometry);
25
- if (c) return c;
26
- const m = mesh.worldMatrix, { position: { data: p }, index, normal, uv } = mesh.geometry.attributes;
27
- const count = index ? index.count : p.length / 3, tri = [], nrm = [], cells = new Map(), v = [];
28
- for (let i = 0; i < count; i += 3) {
29
- const first = index ? index.data[i] : i;
30
- // Streetlight halos (uv.x <= 2, see scene/picking.js) are light, not matter.
31
- if (mesh.program.nightLight && uv && uv.data[first * 2] <= 2) continue;
32
- for (let k = 0; k < 3; k++) {
33
- const j = (index ? index.data[i + k] : i + k) * 3, x = p[j], y = p[j + 1], z = p[j + 2];
34
- v[k * 3] = m[0] * x + m[4] * y + m[8] * z + m[12];
35
- v[k * 3 + 1] = m[1] * x + m[5] * y + m[9] * z + m[13];
36
- v[k * 3 + 2] = m[2] * x + m[6] * y + m[10] * z + m[14];
37
- }
38
- const ex = v[3] - v[0], ey = v[4] - v[1], ez = v[5] - v[2], fx = v[6] - v[0], fy = v[7] - v[1], fz = v[8] - v[2];
39
- let nx = ey * fz - ez * fy, nz = ex * fy - ey * fx;
40
- const ny = ez * fx - ex * fz, length = Math.hypot(nx, ny, nz);
41
- if (!length || Math.abs(ny) > 0.9 * length) continue;
42
- if (normal) {
43
- // The stored normal tells the outside, whatever the winding.
44
- const j = first * 3, a = normal.data;
45
- if ((m[0] * a[j] + m[4] * a[j + 1] + m[8] * a[j + 2]) * nx + (m[2] * a[j] + m[6] * a[j + 1] + m[10] * a[j + 2]) * nz < 0) { nx = -nx; nz = -nz; }
12
+ export function local() {
13
+ const { layer, state } = this;
14
+ const map = layer._map, crs = map.options.crs, origin = crs.project(layer.location);
15
+ const metres = Math.cos(layer.location.lat * Math.PI / 180);
16
+ const p = crs.project(state.latlng), terrain = map._terrain3D?._terrainReady && map._terrain3D;
17
+ const ground = (terrain && getElevation(terrain, state.latlng)) || 0;
18
+ return [(p.x - origin.x) * metres, ground - layer.root.position[1], -(p.y - origin.y) * metres];
19
+ }
20
+
21
+ export function place() {
22
+ const [x, y, z] = local.call(this);
23
+ // Model forward is -z; a yaw of -heading turns it to the compass heading (x east, -z north).
24
+ const yaw = -this.state.heading, cos = Math.cos(yaw), sin = Math.sin(yaw);
25
+ for (let i = 0; i < limbs.length; i++) {
26
+ const [, px, py, sign] = limbs[i];
27
+ const mesh = this.meshes[i];
28
+ mesh.position[0] = x + px * cos; mesh.position[1] = y + py; mesh.position[2] = z - px * sin;
29
+ mesh.rotation[0] = sign * this.swing * Math.sin(this.state.phase);
30
+ mesh.rotation[1] = yaw;
31
+ }
32
+ update.update(this.layer);
33
+ }
34
+
35
+ export function blocked(east, north, feet) {
36
+ const length = Math.hypot(east, north);
37
+ return length > 1e-6 && hit(this.layer, feet[0], feet[1], feet[2], east / length, -north / length, length + 0.3);
38
+ }
39
+
40
+ export function step(now) {
41
+ const layer = this.layer, map = layer._map;
42
+ this.frame = requestAnimationFrame(this.step);
43
+ const dt = Math.min(0.1, (now - (this.last ?? now)) / 1000);
44
+ this.last = now;
45
+ if (!layer.renderer) return;
46
+ let changed = false;
47
+ if (!this.meshes) {
48
+ this.meshes = [];
49
+ for (const [part] of limbs) this.meshes.push(createMesh.createMesh(layer, build(parts[part])));
50
+ changed = true;
51
+ }
52
+ let forward = 0, turn = 0;
53
+ for (const key of this.keys) { forward += moves[key]?.[0] || 0; turn += moves[key]?.[1] || 0; }
54
+ forward = Math.sign(forward); turn = Math.sign(turn);
55
+ if (turn) { this.state.heading = wrap(this.state.heading + turn * 2.5 * dt); changed = true; }
56
+ if (forward) {
57
+ const metres = forward * this.speed * dt, { lat, lng } = this.state.latlng, { position, scale } = layer.root;
58
+ let east = Math.sin(this.state.heading) * metres, north = Math.cos(this.state.heading) * metres;
59
+ const feet = local.call(this);
60
+ for (let i = 0; i < feet.length; i++) feet[i] = position[i] + scale[i] * feet[i];
61
+ // World x is east, z south; keep 0.3 m from walls and slide along the one in the way.
62
+ const wall = blocked.call(this, east, north, feet);
63
+ if (wall) {
64
+ const into = east * wall[0] - north * wall[1];
65
+ east -= into * wall[0]; north += into * wall[1];
66
+ if (blocked.call(this, east, north, feet)) east = north = 0;
46
67
  }
47
- const h = Math.hypot(nx, nz), t = nrm.length / 2;
48
- tri.push(...v); nrm.push(nx / h, nz / h);
49
- for (let ix = Math.floor(Math.min(v[0], v[3], v[6]) / CELL); ix <= Math.floor(Math.max(v[0], v[3], v[6]) / CELL); ix++)
50
- for (let iz = Math.floor(Math.min(v[2], v[5], v[8]) / CELL); iz <= Math.floor(Math.max(v[2], v[5], v[8]) / CELL); iz++) {
51
- const key = ix + ',' + iz;
52
- if (!cells.has(key)) cells.set(key, []);
53
- cells.get(key).push(t);
54
- }
68
+ this.state.latlng = new L.LatLng(lat + north / 111320, lng + east / (111320 * Math.cos(lat * Math.PI / 180)));
69
+ this.state.phase += Math.hypot(east, north) / 1.6 * Math.PI;
70
+ changed = true;
71
+ }
72
+ if (forward || turn) {
73
+ // The camera (looking along -bearing) swings back behind the walker.
74
+ const bearing = map.getBearing() * Math.PI / 180, behind = wrap(-this.state.heading - bearing);
75
+ if (Math.abs(behind) > 1e-3) map._setPitchAndBearing(map.getPitch(), (bearing + behind * Math.min(1, dt * 4)) * 180 / Math.PI);
76
+ map.setView(this.state.latlng, map.getZoom(), { animate: false });
55
77
  }
56
- c = { tri: Float32Array.from(tri), nrm: Float32Array.from(nrm), cells, origin: [m[12], m[13], m[14]] };
57
- colliders.set(mesh.geometry, c);
58
- return c;
78
+ const target = forward ? 0.9 : 0;
79
+ if (Math.abs(this.swing - target) > 1e-3) { this.swing += (target - this.swing) * Math.min(1, dt * 10); changed = true; }
80
+ if (changed) place.call(this);
81
+ }
82
+
83
+ export function onKey(event) {
84
+ // Text fields and sliders keep their keys; buttons and checkboxes don't.
85
+ if (event.target.closest?.('input:not([type=checkbox], [type=radio]), select, textarea, [contenteditable]') ||
86
+ event.ctrlKey || event.altKey || event.metaKey) return;
87
+ if (event.type === 'keydown' && event.code === 'Escape') { this.stop(); return; }
88
+ if (!moves[event.code]) return;
89
+ event.preventDefault();
90
+ if (event.type === 'keydown') this.keys.add(event.code); else this.keys.delete(event.code);
91
+ }
92
+
93
+ export function onBlur() {
94
+ this.keys.clear();
95
+ }
96
+
97
+ export function onPointer(event) {
98
+ // Dragging only turns the camera around the walker: horizontal = bearing, vertical = pitch.
99
+ const map = this.layer._map;
100
+ if (event.type === 'pointerdown') {
101
+ if (event.button !== 0 || event.target.closest('.leaflet-control')) return;
102
+ this.drag = { x: event.clientX, y: event.clientY };
103
+ map.getContainer().setPointerCapture(event.pointerId);
104
+ } else if (this.drag && event.type === 'pointermove') {
105
+ map._setPitchAndBearing(Math.max(20, Math.min(85, map.getPitch() - (event.clientY - this.drag.y) * 0.2)),
106
+ map.getBearing() - (event.clientX - this.drag.x) * 0.25);
107
+ this.drag = { x: event.clientX, y: event.clientY };
108
+ } else this.drag = null;
109
+ }
110
+
111
+ export function onTerrain() {
112
+ if (this.meshes) place.call(this);
113
+ }
114
+
115
+ export function start() {
116
+ const map = this.layer._map;
117
+ if (this.saved || !map) return;
118
+ this.state.latlng = map.getCenter();
119
+ // Zoom whose camera distance (1.5 viewport heights, as in scene/render.js) is about `distance` metres behind the walker.
120
+ const pixelsPerMetre = map.getSize().y * 1.5 / this.distance;
121
+ const zoom = Math.min(map.getMaxZoom(), Math.log2(pixelsPerMetre * 40075016.68557849 * Math.cos(this.state.latlng.lat * Math.PI / 180) / 256));
122
+ const handlers = [];
123
+ for (const name of ['dragging', 'keyboard', 'doubleClickZoom', 'boxZoom']) {
124
+ if (map[name]?.enabled()) handlers.push(name);
125
+ }
126
+ this.saved = {
127
+ zoom: map.getZoom(), pitch: map.getPitch(), scrollWheelZoom: map.options.scrollWheelZoom, handlers
128
+ };
129
+ for (const name of this.saved.handlers) map[name].disable();
130
+ // Wheel zoom moves the camera closer or farther, keeping the walker centred.
131
+ map.options.scrollWheelZoom = this.saved.scrollWheelZoom && 'center';
132
+ this.state.heading = -map.getBearing() * Math.PI / 180;
133
+ map.setView(this.state.latlng, zoom, { animate: false });
134
+ map.setPitch(75);
135
+ L.DomEvent.on(document, 'keydown keyup', this.onKey);
136
+ L.DomEvent.on(window, 'blur', this.onBlur);
137
+ L.DomEvent.on(map.getContainer(), 'pointerdown pointermove pointerup pointercancel', this.onPointer);
138
+ map.on('terrainchange', this.onTerrain);
139
+ this.button.setAttribute('aria-pressed', 'true');
140
+ this.button.style.background = '#e4e4e4';
141
+ this.hint.style.display = '';
142
+ this.last = undefined;
143
+ this.frame = requestAnimationFrame(this.step);
144
+ }
145
+
146
+ export function stop() {
147
+ const map = this.layer._map;
148
+ cancelAnimationFrame(this.frame);
149
+ this.keys.clear(); this.drag = null;
150
+ L.DomEvent.off(document, 'keydown keyup', this.onKey);
151
+ L.DomEvent.off(window, 'blur', this.onBlur);
152
+ for (const mesh of this.meshes || []) disposeMesh.disposeMesh(this.layer, mesh);
153
+ this.meshes = null;
154
+ this.button.setAttribute('aria-pressed', 'false');
155
+ this.button.style.background = '#fff';
156
+ this.hint.style.display = 'none';
157
+ if (!map || !this.saved) return;
158
+ L.DomEvent.off(map.getContainer(), 'pointerdown pointermove pointerup pointercancel', this.onPointer);
159
+ map.off('terrainchange', this.onTerrain);
160
+ map.options.scrollWheelZoom = this.saved.scrollWheelZoom;
161
+ for (const name of this.saved.handlers) map[name].enable();
162
+ map.setView(this.state.latlng, this.saved.zoom, { animate: false });
163
+ map.setPitch(this.saved.pitch);
164
+ this.saved = null;
165
+ }
166
+
167
+ export function toggle() {
168
+ if (this.saved) stop.call(this); else start.call(this);
169
+ }
170
+
171
+ export function controlOnAdd() {
172
+ return this.container;
173
+ }
174
+
175
+ export function onReady() {
176
+ this.ready = true;
177
+ if (this.layer._map) this.control.addTo(this.layer._map);
178
+ }
179
+
180
+ export function onLayerAdd() {
181
+ if (this.ready) this.control.addTo(this.layer._map);
59
182
  }
60
183
 
61
- // Möller-Trumbore for the horizontal ray (ox, oy, oz) + d·(dx, 0, dz) against triangle t; returns d or -1.
62
- export function horizontalRay(v, t, ox, oy, oz, dx, dz) {
63
- const i = t * 9, ex = v[i + 3] - v[i], ey = v[i + 4] - v[i + 1], ez = v[i + 5] - v[i + 2];
64
- const fx = v[i + 6] - v[i], fy = v[i + 7] - v[i + 1], fz = v[i + 8] - v[i + 2];
65
- const px = -dz * fy, py = dz * fx - dx * fz, pz = dx * fy, det = ex * px + ey * py + ez * pz;
66
- if (Math.abs(det) < 1e-9) return -1;
67
- const tx = ox - v[i], ty = oy - v[i + 1], tz = oz - v[i + 2], u = (tx * px + ty * py + tz * pz) / det;
68
- if (u < 0 || u > 1) return -1;
69
- const qx = ty * ez - tz * ey, qy = tz * ex - tx * ez, qz = tx * ey - ty * ex, w = (dx * qx + dz * qz) / det;
70
- if (w < 0 || u + w > 1) return -1;
71
- return (fx * qx + fy * qy + fz * qz) / det;
184
+ export function onLayerRemove() {
185
+ stop.call(this);
186
+ this.control.remove();
72
187
  }
@@ -0,0 +1 @@
1
+ export const white = [0.92, 0.93, 0.92];
@@ -0,0 +1,25 @@
1
+
2
+ /** World-space [x, y, z, radius, r, g, b, intensity] for one mesh's point lights. */
3
+ export function worldLights(lights, m) {
4
+ const values = new Float32Array(lights.length * 8);
5
+ lights.forEach(({
6
+ position: [x, y, z],
7
+ radius,
8
+ color,
9
+ flux
10
+ }, i) => {
11
+ const w = m[3] * x + m[7] * y + m[11] * z + m[15];
12
+ values.set(
13
+ [
14
+ (m[0] * x + m[4] * y + m[8] * z + m[12]) / w,
15
+ (m[1] * x + m[5] * y + m[9] * z + m[13]) / w,
16
+ (m[2] * x + m[6] * y + m[10] * z + m[14]) / w,
17
+ radius,
18
+ ...color,
19
+ flux / (4 * Math.PI) * 0.03
20
+ ],
21
+ i * 8
22
+ );
23
+ });
24
+ return values;
25
+ }
@@ -0,0 +1 @@
1
+ export const wrap = angle => Math.atan2(Math.sin(angle), Math.cos(angle));