@navaramap/three 0.0.0

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 (350) hide show
  1. package/LICENSE +8 -0
  2. package/dist/assets/atmosphere/README.md +1 -0
  3. package/dist/assets/atmosphere/higher_order_scattering.bin +0 -0
  4. package/dist/assets/atmosphere/higher_order_scattering.exr +0 -0
  5. package/dist/assets/atmosphere/irradiance.bin +0 -0
  6. package/dist/assets/atmosphere/irradiance.exr +0 -0
  7. package/dist/assets/atmosphere/scattering.bin +0 -0
  8. package/dist/assets/atmosphere/scattering.exr +0 -0
  9. package/dist/assets/atmosphere/single_mie_scattering.bin +0 -0
  10. package/dist/assets/atmosphere/single_mie_scattering.exr +0 -0
  11. package/dist/assets/atmosphere/stars.bin +0 -0
  12. package/dist/assets/atmosphere/transmittance.bin +0 -0
  13. package/dist/assets/atmosphere/transmittance.exr +0 -0
  14. package/dist/assets/cloud/README.md +1 -0
  15. package/dist/assets/cloud/local_weather.png +0 -0
  16. package/dist/assets/cloud/shape.bin +1 -0
  17. package/dist/assets/cloud/shape_detail.bin +1 -0
  18. package/dist/assets/cloud/turbulence.png +0 -0
  19. package/dist/assets/fontWorker-CEJEfRpb.js +2 -0
  20. package/dist/assets/fontWorker-CEJEfRpb.js.map +1 -0
  21. package/dist/assets/index-BUB-ijMO.js +12 -0
  22. package/dist/assets/index-BUB-ijMO.js.map +1 -0
  23. package/dist/assets/navara_wasm_font_worker_bg-665OLxjy.wasm +0 -0
  24. package/dist/assets/navara_wasm_worker_bg-BXhKC5bE.wasm +0 -0
  25. package/dist/assets/noise/README.md +1 -0
  26. package/dist/assets/noise/stbn.bin +0 -0
  27. package/dist/assets/water/README.md +3 -0
  28. package/dist/assets/water/waternormals.jpg +0 -0
  29. package/dist/index.d.ts +10114 -0
  30. package/dist/index.js +34481 -0
  31. package/dist/index.js.map +1 -0
  32. package/dist/index.umd.cjs +6345 -0
  33. package/dist/index.umd.cjs.map +1 -0
  34. package/package.json +95 -0
  35. package/src/Color.ts +111 -0
  36. package/src/ShadowMapViewers.ts +49 -0
  37. package/src/atmosphere.test.ts +76 -0
  38. package/src/atmosphere.ts +364 -0
  39. package/src/bufferView.ts +90 -0
  40. package/src/camera.ts +182 -0
  41. package/src/concurrency.ts +15 -0
  42. package/src/constants/assets.ts +30 -0
  43. package/src/constants/decoder.ts +7 -0
  44. package/src/constants/index.ts +2 -0
  45. package/src/core/BaseDesc.ts +142 -0
  46. package/src/core/BaseHandle.ts +126 -0
  47. package/src/core/DescRegistry.ts +88 -0
  48. package/src/core/EffectDesc.ts +343 -0
  49. package/src/core/EffectDescRegistry.ts +31 -0
  50. package/src/core/InstancedMeshDesc.ts +413 -0
  51. package/src/core/LightDesc.ts +216 -0
  52. package/src/core/LightDescRegistry.ts +32 -0
  53. package/src/core/MeshDesc.ts +457 -0
  54. package/src/core/MeshDescRegistry.ts +32 -0
  55. package/src/core/MeshDescWithSelectiveEffect.ts +129 -0
  56. package/src/core/Registries.ts +59 -0
  57. package/src/core/SelectiveEffectRegistry.ts +90 -0
  58. package/src/core/ViewContext.ts +235 -0
  59. package/src/core/errors.ts +16 -0
  60. package/src/core/index.ts +50 -0
  61. package/src/device.ts +414 -0
  62. package/src/effects/CustomEffectPass.ts +28 -0
  63. package/src/effects/copy.ts +10 -0
  64. package/src/effects/effect.ts +87 -0
  65. package/src/effects/index.ts +4 -0
  66. package/src/effects/render.ts +10 -0
  67. package/src/evaluations/FeatureEvaluator.ts +529 -0
  68. package/src/evaluations/index.ts +1 -0
  69. package/src/event/HillshadeContext.test.ts +232 -0
  70. package/src/event/HillshadeContext.ts +299 -0
  71. package/src/event/context.ts +279 -0
  72. package/src/event/feature.ts +357 -0
  73. package/src/event/featureEvent.ts +81 -0
  74. package/src/event/features/billboard.ts +30 -0
  75. package/src/event/features/model.ts +192 -0
  76. package/src/event/features/modelGpuBytes.test.ts +69 -0
  77. package/src/event/features/modelGpuBytes.ts +87 -0
  78. package/src/event/features/point.ts +25 -0
  79. package/src/event/features/polygon.ts +23 -0
  80. package/src/event/features/polygonOutline.ts +19 -0
  81. package/src/event/features/polyline.ts +19 -0
  82. package/src/event/features/text.ts +71 -0
  83. package/src/event/hillshade.test.ts +842 -0
  84. package/src/event/hillshade.ts +588 -0
  85. package/src/event/index.ts +700 -0
  86. package/src/event/loaders.ts +53 -0
  87. package/src/event/tile.ts +19 -0
  88. package/src/event/worker.ts +999 -0
  89. package/src/event/workerTaskSettlement.test.ts +243 -0
  90. package/src/event/workerTaskSettlement.ts +128 -0
  91. package/src/inMemoryBufferStore.test.ts +60 -0
  92. package/src/inMemoryBufferStore.ts +67 -0
  93. package/src/index.iife.ts +11 -0
  94. package/src/index.ts +2556 -0
  95. package/src/input.ts +144 -0
  96. package/src/layer.ts +183 -0
  97. package/src/layers/effect/FinalCopyEffectDesc.ts +29 -0
  98. package/src/layers/effect/MRTPassEffectDesc.ts +105 -0
  99. package/src/layers/effect/README.md +9 -0
  100. package/src/layers/effect/SelectiveEffectDesc.ts +113 -0
  101. package/src/layers/effect/SkyEnvMapEffectDesc.ts +58 -0
  102. package/src/layers/effect/TransparentPassEffectDesc.ts +62 -0
  103. package/src/layers/effect/index.ts +5 -0
  104. package/src/layers/index.ts +1 -0
  105. package/src/layersManager.ts +63 -0
  106. package/src/light.ts +15 -0
  107. package/src/loaders/AbortableImageLoader.ts +203 -0
  108. package/src/loaders/AbortableTextureLoader.ts +74 -0
  109. package/src/loaders/index.ts +5 -0
  110. package/src/material/enhancer/DESIGN.md +300 -0
  111. package/src/material/enhancer/MaterialEnhancer.ts +112 -0
  112. package/src/material/enhancer/ShaderReplacer.test.ts +114 -0
  113. package/src/material/enhancer/ShaderReplacer.ts +97 -0
  114. package/src/material/enhancer/batchTexture.ts +8 -0
  115. package/src/material/enhancer/index.ts +46 -0
  116. package/src/material/enhancer/instancedSprite/index.ts +7 -0
  117. package/src/material/enhancer/instancedSprite/instancedSpriteBaseEnhancer/index.test.ts +214 -0
  118. package/src/material/enhancer/instancedSprite/instancedSpriteBaseEnhancer/index.ts +134 -0
  119. package/src/material/enhancer/instancedSprite/instancedSpriteBaseEnhancer/markers.ts +21 -0
  120. package/src/material/enhancer/instancedSprite/instancedSpriteBaseEnhancer/material.ts +32 -0
  121. package/src/material/enhancer/instancedSprite/instancedSpriteBaseEnhancer/mutates.test.ts +277 -0
  122. package/src/material/enhancer/instancedSprite/instancedSpriteBaseEnhancer/mutates.ts +151 -0
  123. package/src/material/enhancer/instancedSprite/instancedSpriteBaseEnhancer/shader.test.ts +114 -0
  124. package/src/material/enhancer/instancedSprite/instancedSpriteBaseEnhancer/shader.ts +49 -0
  125. package/src/material/enhancer/instancedSprite/instancedSpriteBaseEnhancer/state.test.ts +82 -0
  126. package/src/material/enhancer/instancedSprite/instancedSpriteBaseEnhancer/state.ts +80 -0
  127. package/src/material/enhancer/instancedSprite/instancedSpriteBaseEnhancer/types.ts +146 -0
  128. package/src/material/enhancer/instancedSprite/instancedSpriteMaterialEnhancer.ts +105 -0
  129. package/src/material/enhancer/model/index.ts +25 -0
  130. package/src/material/enhancer/model/modelBaseEnhancer/index.test.ts +74 -0
  131. package/src/material/enhancer/model/modelBaseEnhancer/index.ts +110 -0
  132. package/src/material/enhancer/model/modelBaseEnhancer/markers.ts +27 -0
  133. package/src/material/enhancer/model/modelBaseEnhancer/material.test.ts +66 -0
  134. package/src/material/enhancer/model/modelBaseEnhancer/material.ts +44 -0
  135. package/src/material/enhancer/model/modelBaseEnhancer/mutates.test.ts +84 -0
  136. package/src/material/enhancer/model/modelBaseEnhancer/mutates.ts +47 -0
  137. package/src/material/enhancer/model/modelBaseEnhancer/shader.test.ts +24 -0
  138. package/src/material/enhancer/model/modelBaseEnhancer/shader.ts +162 -0
  139. package/src/material/enhancer/model/modelBaseEnhancer/state.test.ts +103 -0
  140. package/src/material/enhancer/model/modelBaseEnhancer/state.ts +52 -0
  141. package/src/material/enhancer/model/modelBaseEnhancer/types.ts +89 -0
  142. package/src/material/enhancer/model/modelMaterialEnhancer.ts +91 -0
  143. package/src/material/enhancer/model/modelWaterEnhancer/index.test.ts +71 -0
  144. package/src/material/enhancer/model/modelWaterEnhancer/index.ts +175 -0
  145. package/src/material/enhancer/model/modelWaterEnhancer/material.test.ts +48 -0
  146. package/src/material/enhancer/model/modelWaterEnhancer/material.ts +25 -0
  147. package/src/material/enhancer/model/modelWaterEnhancer/mutates.test.ts +89 -0
  148. package/src/material/enhancer/model/modelWaterEnhancer/mutates.ts +89 -0
  149. package/src/material/enhancer/model/modelWaterEnhancer/shader.test.ts +34 -0
  150. package/src/material/enhancer/model/modelWaterEnhancer/shader.ts +111 -0
  151. package/src/material/enhancer/model/modelWaterEnhancer/state.test.ts +105 -0
  152. package/src/material/enhancer/model/modelWaterEnhancer/state.ts +59 -0
  153. package/src/material/enhancer/model/modelWaterEnhancer/types.ts +141 -0
  154. package/src/material/enhancer/model/pntsEnhancer/index.test.ts +96 -0
  155. package/src/material/enhancer/model/pntsEnhancer/index.ts +82 -0
  156. package/src/material/enhancer/model/pntsEnhancer/markers.ts +6 -0
  157. package/src/material/enhancer/model/pntsEnhancer/material.test.ts +37 -0
  158. package/src/material/enhancer/model/pntsEnhancer/material.ts +21 -0
  159. package/src/material/enhancer/model/pntsEnhancer/mutates.test.ts +80 -0
  160. package/src/material/enhancer/model/pntsEnhancer/mutates.ts +29 -0
  161. package/src/material/enhancer/model/pntsEnhancer/shader.test.ts +32 -0
  162. package/src/material/enhancer/model/pntsEnhancer/shader.ts +56 -0
  163. package/src/material/enhancer/model/pntsEnhancer/state.test.ts +87 -0
  164. package/src/material/enhancer/model/pntsEnhancer/state.ts +29 -0
  165. package/src/material/enhancer/model/pntsEnhancer/types.ts +38 -0
  166. package/src/material/enhancer/polygon/index.ts +22 -0
  167. package/src/material/enhancer/polygon/polygonBaseEnhancer/index.test.ts +101 -0
  168. package/src/material/enhancer/polygon/polygonBaseEnhancer/index.ts +130 -0
  169. package/src/material/enhancer/polygon/polygonBaseEnhancer/markers.ts +23 -0
  170. package/src/material/enhancer/polygon/polygonBaseEnhancer/material.test.ts +19 -0
  171. package/src/material/enhancer/polygon/polygonBaseEnhancer/material.ts +38 -0
  172. package/src/material/enhancer/polygon/polygonBaseEnhancer/mutates.test.ts +75 -0
  173. package/src/material/enhancer/polygon/polygonBaseEnhancer/mutates.ts +122 -0
  174. package/src/material/enhancer/polygon/polygonBaseEnhancer/shader.test.ts +25 -0
  175. package/src/material/enhancer/polygon/polygonBaseEnhancer/shader.ts +249 -0
  176. package/src/material/enhancer/polygon/polygonBaseEnhancer/state.test.ts +102 -0
  177. package/src/material/enhancer/polygon/polygonBaseEnhancer/state.ts +92 -0
  178. package/src/material/enhancer/polygon/polygonBaseEnhancer/types.ts +150 -0
  179. package/src/material/enhancer/polygon/polygonMaterialEnhancer.ts +97 -0
  180. package/src/material/enhancer/polygon/polygonWaterEnhancer/index.test.ts +72 -0
  181. package/src/material/enhancer/polygon/polygonWaterEnhancer/index.ts +164 -0
  182. package/src/material/enhancer/polygon/polygonWaterEnhancer/material.test.ts +48 -0
  183. package/src/material/enhancer/polygon/polygonWaterEnhancer/material.ts +35 -0
  184. package/src/material/enhancer/polygon/polygonWaterEnhancer/mutates.ts +61 -0
  185. package/src/material/enhancer/polygon/polygonWaterEnhancer/shader.test.ts +34 -0
  186. package/src/material/enhancer/polygon/polygonWaterEnhancer/shader.ts +96 -0
  187. package/src/material/enhancer/polygon/polygonWaterEnhancer/state.test.ts +98 -0
  188. package/src/material/enhancer/polygon/polygonWaterEnhancer/state.ts +57 -0
  189. package/src/material/enhancer/polygon/polygonWaterEnhancer/types.ts +115 -0
  190. package/src/material/enhancer/polyline/index.ts +7 -0
  191. package/src/material/enhancer/polyline/polylineBaseEnhancer/index.test.ts +157 -0
  192. package/src/material/enhancer/polyline/polylineBaseEnhancer/index.ts +154 -0
  193. package/src/material/enhancer/polyline/polylineBaseEnhancer/markers.ts +19 -0
  194. package/src/material/enhancer/polyline/polylineBaseEnhancer/material.test.ts +42 -0
  195. package/src/material/enhancer/polyline/polylineBaseEnhancer/material.ts +38 -0
  196. package/src/material/enhancer/polyline/polylineBaseEnhancer/mutates.test.ts +120 -0
  197. package/src/material/enhancer/polyline/polylineBaseEnhancer/mutates.ts +169 -0
  198. package/src/material/enhancer/polyline/polylineBaseEnhancer/shader.test.ts +67 -0
  199. package/src/material/enhancer/polyline/polylineBaseEnhancer/shader.ts +75 -0
  200. package/src/material/enhancer/polyline/polylineBaseEnhancer/state.test.ts +55 -0
  201. package/src/material/enhancer/polyline/polylineBaseEnhancer/state.ts +91 -0
  202. package/src/material/enhancer/polyline/polylineBaseEnhancer/types.ts +170 -0
  203. package/src/material/enhancer/polyline/polylineMaterialEnhancer.ts +102 -0
  204. package/src/material/enhancer/sdfText/index.ts +7 -0
  205. package/src/material/enhancer/sdfText/sdfTextBaseEnhancer/index.ts +125 -0
  206. package/src/material/enhancer/sdfText/sdfTextBaseEnhancer/markers.ts +19 -0
  207. package/src/material/enhancer/sdfText/sdfTextBaseEnhancer/material.test.ts +35 -0
  208. package/src/material/enhancer/sdfText/sdfTextBaseEnhancer/material.ts +32 -0
  209. package/src/material/enhancer/sdfText/sdfTextBaseEnhancer/mutates.test.ts +381 -0
  210. package/src/material/enhancer/sdfText/sdfTextBaseEnhancer/mutates.ts +232 -0
  211. package/src/material/enhancer/sdfText/sdfTextBaseEnhancer/shader.ts +36 -0
  212. package/src/material/enhancer/sdfText/sdfTextBaseEnhancer/state.test.ts +118 -0
  213. package/src/material/enhancer/sdfText/sdfTextBaseEnhancer/state.ts +107 -0
  214. package/src/material/enhancer/sdfText/sdfTextBaseEnhancer/types.ts +184 -0
  215. package/src/material/enhancer/sdfText/sdfTextMaterialEnhancer.ts +100 -0
  216. package/src/material/enhancer/shadowMap/index.ts +7 -0
  217. package/src/material/enhancer/shadowMap/shadowMapDepthEnhancer/index.ts +97 -0
  218. package/src/material/enhancer/shadowMap/shadowMapDepthEnhancer/markers.ts +10 -0
  219. package/src/material/enhancer/shadowMap/shadowMapDepthEnhancer/material.ts +31 -0
  220. package/src/material/enhancer/shadowMap/shadowMapDepthEnhancer/mutates.ts +8 -0
  221. package/src/material/enhancer/shadowMap/shadowMapDepthEnhancer/shader.test.ts +17 -0
  222. package/src/material/enhancer/shadowMap/shadowMapDepthEnhancer/shader.ts +53 -0
  223. package/src/material/enhancer/shadowMap/shadowMapDepthEnhancer/state.ts +17 -0
  224. package/src/material/enhancer/shadowMap/shadowMapDepthEnhancer/types.ts +26 -0
  225. package/src/material/enhancer/test-utils/shaderCompatibility.ts +124 -0
  226. package/src/material/enhancer/tileComposite/compose.test.ts +95 -0
  227. package/src/material/enhancer/tileComposite/compose.ts +112 -0
  228. package/src/material/enhancer/tileComposite/index.ts +23 -0
  229. package/src/material/enhancer/tileComposite/tileCompositeBaseEnhancer/index.ts +11 -0
  230. package/src/material/enhancer/tileComposite/tileCompositeBaseEnhancer/mutates.ts +132 -0
  231. package/src/material/enhancer/tileComposite/tileCompositeBaseEnhancer/shader.ts +245 -0
  232. package/src/material/enhancer/tileComposite/tileCompositeBaseEnhancer/types.ts +43 -0
  233. package/src/material/enhancer/tileComposite/tileElevationHeatmapEnhancer/index.ts +29 -0
  234. package/src/material/enhancer/tileComposite/tileElevationHeatmapEnhancer/mutates.ts +68 -0
  235. package/src/material/enhancer/tileComposite/tileElevationHeatmapEnhancer/shader.ts +24 -0
  236. package/src/material/enhancer/tileComposite/tileHillshadeEnhancer/index.ts +29 -0
  237. package/src/material/enhancer/tileComposite/tileHillshadeEnhancer/mutates.ts +34 -0
  238. package/src/material/enhancer/tileComposite/tileHillshadeEnhancer/shader.ts +36 -0
  239. package/src/material/enhancer/tileComposite/tileWaterEnhancer/index.ts +23 -0
  240. package/src/material/enhancer/tileComposite/tileWaterEnhancer/mutates.ts +23 -0
  241. package/src/material/enhancer/tileComposite/tileWaterEnhancer/shader.ts +8 -0
  242. package/src/material/enhancer/tileComposite/tileWatermaskEnhancer/index.ts +23 -0
  243. package/src/material/enhancer/tileComposite/tileWatermaskEnhancer/mutates.ts +34 -0
  244. package/src/material/enhancer/tileComposite/tileWatermaskEnhancer/shader.ts +13 -0
  245. package/src/material/enhancer/tileComposite/types.ts +58 -0
  246. package/src/material/index.ts +3 -0
  247. package/src/material/macro/index.ts +1 -0
  248. package/src/material/macro/tileShader.test.ts +136 -0
  249. package/src/material/macro/tileShader.ts +287 -0
  250. package/src/material/overrideMaterialsForMRT.ts +439 -0
  251. package/src/material/selectiveEffectMaterialSetup.test.ts +52 -0
  252. package/src/material/selectiveEffectMaterialSetup.ts +53 -0
  253. package/src/material/types/index.ts +1 -0
  254. package/src/material/types/uniform.ts +1 -0
  255. package/src/mesh/DrapedMesh.ts +101 -0
  256. package/src/mesh/batchTexture.test.ts +646 -0
  257. package/src/mesh/batchTexture.ts +437 -0
  258. package/src/mesh/batchedFeature.ts +186 -0
  259. package/src/mesh/batchedSdfText.ts +484 -0
  260. package/src/mesh/featureMesh.ts +43 -0
  261. package/src/mesh/index.ts +16 -0
  262. package/src/mesh/instanced.ts +117 -0
  263. package/src/mesh/model.ts +483 -0
  264. package/src/mesh/pickableMesh.ts +55 -0
  265. package/src/mesh/pickableMeshWrapper.ts +529 -0
  266. package/src/mesh/polygon.ts +699 -0
  267. package/src/mesh/polygonOutline.ts +393 -0
  268. package/src/mesh/polyline.ts +523 -0
  269. package/src/mesh/releaseGeometryArrays.ts +57 -0
  270. package/src/mesh/rtcRteHelper.ts +211 -0
  271. package/src/mesh/sdfText.test.ts +200 -0
  272. package/src/mesh/sdfText.ts +1019 -0
  273. package/src/mesh/sprite/billboardAtlas.test.ts +177 -0
  274. package/src/mesh/sprite/billboardAtlas.ts +210 -0
  275. package/src/mesh/sprite/billboardAtlasImageLoader.ts +29 -0
  276. package/src/mesh/sprite/index.ts +1 -0
  277. package/src/mesh/sprite/instancedSprite.ts +694 -0
  278. package/src/mesh/tile.test.ts +393 -0
  279. package/src/mesh/tile.ts +1790 -0
  280. package/src/object3DEvent.ts +6 -0
  281. package/src/orchestrators/RenderPassOrchestrator.ts +147 -0
  282. package/src/orchestrators/index.ts +1 -0
  283. package/src/passes/AllDepthCopyPass.ts +165 -0
  284. package/src/passes/CustomRenderPass.ts +279 -0
  285. package/src/passes/NormalCopyPass.ts +125 -0
  286. package/src/passes/RenderTargetCopyPass.ts +91 -0
  287. package/src/passes/SkyEnvMapPass.ts +58 -0
  288. package/src/passes/index.ts +5 -0
  289. package/src/pick/pickHelper.ts +273 -0
  290. package/src/pick/pickTerrain.ts +254 -0
  291. package/src/plugins/AttributionPlugin/AttributionPlugin.test.ts +210 -0
  292. package/src/plugins/AttributionPlugin/attribution.test.ts +225 -0
  293. package/src/plugins/AttributionPlugin/attribution.ts +355 -0
  294. package/src/plugins/AttributionPlugin/attributionStyles.ts +163 -0
  295. package/src/plugins/AttributionPlugin/index.ts +702 -0
  296. package/src/plugins/index.ts +1 -0
  297. package/src/quality.ts +1 -0
  298. package/src/renderOrder.ts +3 -0
  299. package/src/scene.test.ts +164 -0
  300. package/src/scene.ts +127 -0
  301. package/src/shaders/index.ts +1 -0
  302. package/src/solar.test.ts +81 -0
  303. package/src/solar.ts +101 -0
  304. package/src/source.ts +80 -0
  305. package/src/stats.ts +102 -0
  306. package/src/tasks/computeVertexNormalsAsync.ts +15 -0
  307. package/src/tasks/constructPolygonBatchedFeature.ts +34 -0
  308. package/src/tasks/constructPolylineBatchedFeature.ts +27 -0
  309. package/src/tasks/constructQuantizedMeshTerrainMesh.ts +24 -0
  310. package/src/tasks/constructTerrainMesh.ts +25 -0
  311. package/src/tasks/getImageDataFromBlob.ts +13 -0
  312. package/src/tasks/getImageDataFromImageBitmap.ts +12 -0
  313. package/src/tasks/parseMvtTile.ts +22 -0
  314. package/src/tasks/queueTask.ts +19 -0
  315. package/src/tasks/toCreasedNormalsAsync.ts +18 -0
  316. package/src/tasks/upsampleQuantizedMeshTerrainMesh.ts +44 -0
  317. package/src/tasks/upsampleTerrainMesh.ts +39 -0
  318. package/src/texture.ts +19 -0
  319. package/src/textures.ts +13 -0
  320. package/src/tileTexture/CompositeShader.snapshot.test.ts +59 -0
  321. package/src/tileTexture/CompositeShader.test.ts +168 -0
  322. package/src/tileTexture/CompositeShader.ts +53 -0
  323. package/src/tileTexture/SlotPlanner.test.ts +105 -0
  324. package/src/tileTexture/SlotPlanner.ts +102 -0
  325. package/src/tileTexture/TileTextureCache.test.ts +227 -0
  326. package/src/tileTexture/TileTextureCache.ts +192 -0
  327. package/src/tileTexture/TileTextureCompositor.test.ts +260 -0
  328. package/src/tileTexture/TileTextureCompositor.ts +421 -0
  329. package/src/tileTexture/__snapshots__/CompositeShader.snapshot.test.ts.snap +2649 -0
  330. package/src/tileTexture/index.ts +8 -0
  331. package/src/tileTexture/types.ts +150 -0
  332. package/src/type/index.ts +261 -0
  333. package/src/uniforms.ts +20 -0
  334. package/src/utils/arraysEqual.ts +9 -0
  335. package/src/utils/blendModes.ts +80 -0
  336. package/src/utils/geometry.ts +53 -0
  337. package/src/utils/hillshadeNormalMapGenerator.ts +193 -0
  338. package/src/utils/index.ts +8 -0
  339. package/src/utils/object.test.ts +14 -0
  340. package/src/utils/object.ts +7 -0
  341. package/src/utils/replacer.test.ts +42 -0
  342. package/src/utils/replacer.ts +89 -0
  343. package/src/utils/screen.ts +29 -0
  344. package/src/utils/textureFragmentIndex.test.ts +224 -0
  345. package/src/utils/textureFragmentIndex.ts +97 -0
  346. package/src/utils/worker.ts +3 -0
  347. package/src/vite-env.d.ts +2 -0
  348. package/src/worker/index.ts +13 -0
  349. package/src/worker/tasks/computeVertexNormals.ts +15 -0
  350. package/src/worker/tasks/toCreasedNormals.ts +22 -0
@@ -0,0 +1,999 @@
1
+ import {
2
+ generate_id_from_entity,
3
+ PolygonMaterialLike,
4
+ TransferablePolygonBatchedFeatureLike,
5
+ TransferableRasterDEMDataLike,
6
+ TransferableTileLike,
7
+ UpsamplableTerrainGeometryLike,
8
+ PolylineMaterialLike,
9
+ TransferablePolylineBatchedFeatureLike,
10
+ ExtentRadianF32Like,
11
+ type ReturnedConstructedTerrainMeshLike,
12
+ } from "@navaramap/core";
13
+ import {
14
+ ConstructPolygonBatchedFeatureParameters,
15
+ ConstructPolygonBatchedFeatureResult,
16
+ ConstructPolylineBatchedFeatureParameters,
17
+ ConstructPolylineBatchedFeatureResult,
18
+ ConstructTerrainMeshParameters,
19
+ ConstructTerrainMeshResult,
20
+ DelegatedWorkerTasksResult,
21
+ EntityEvent,
22
+ ExtentRadianF32,
23
+ ParseMvtTileParameters,
24
+ ParseMvtTileResult,
25
+ ReconstructableEntity,
26
+ TransferableFloatAttribute,
27
+ TransferableGeometry,
28
+ TransferablePolygonGeometry,
29
+ TransferablePolygonOutlineGeometry,
30
+ TransferablePolylineGeometry,
31
+ TransferableUintAttribute,
32
+ UpsampleTerrainMeshParameters,
33
+ UpsampleTerrainMeshResult,
34
+ Vec3,
35
+ type WorkerTaskDelegatedEvent,
36
+ } from "@navaramap/engine";
37
+
38
+ import { constructPolygonBatchedFeature } from "../tasks/constructPolygonBatchedFeature";
39
+ import { constructPolylineBatchedFeature } from "../tasks/constructPolylineBatchedFeature";
40
+ import { constructQuantizedMeshTerrainMesh } from "../tasks/constructQuantizedMeshTerrainMesh";
41
+ import { constructTerrainMesh } from "../tasks/constructTerrainMesh";
42
+ import { parseMvtTile } from "../tasks/parseMvtTile";
43
+ import { upsampleQuantizedMeshTerrainMesh } from "../tasks/upsampleQuantizedMeshTerrainMesh";
44
+ import { upsampleTerrainMesh } from "../tasks/upsampleTerrainMesh";
45
+
46
+ import { runDelegatedWorkerTask } from "./workerTaskSettlement";
47
+
48
+ import type { EventContext } from ".";
49
+
50
+ export async function processWorkerTaskDelegatedEvent(
51
+ ctx: EventContext,
52
+ event: WorkerTaskDelegatedEvent,
53
+ ) {
54
+ const id = generate_id_from_entity(event);
55
+ // Every wasm-bindgen getter access allocates a NEW owned wrapper (reading
56
+ // `event.task.<kind>` twice would leak one copy), so read `task` and each
57
+ // params object exactly once and free whatever this dispatch does not
58
+ // consume. `params` and `delegator_id` ownership moves to the process*
59
+ // handler (via `runDelegatedWorkerTask`).
60
+ const task = event.task;
61
+ try {
62
+ const constructTerrainMesh = task.construct_terrain_mesh;
63
+ if (constructTerrainMesh) {
64
+ return await processConstructTerrainMesh(
65
+ ctx,
66
+ id,
67
+ event.bits,
68
+ constructTerrainMesh,
69
+ task.delegator_id,
70
+ );
71
+ }
72
+ const upsampleTerrainMesh = task.upsample_terrain_mesh;
73
+ if (upsampleTerrainMesh) {
74
+ return await processUpsampleTerrainMesh(
75
+ ctx,
76
+ id,
77
+ event.bits,
78
+ upsampleTerrainMesh,
79
+ task.delegator_id,
80
+ );
81
+ }
82
+ const constructPolygon = task.construct_polygon_batched_feature;
83
+ if (constructPolygon) {
84
+ return await processConstructPolygonBatchedFeature(
85
+ ctx,
86
+ id,
87
+ event.bits,
88
+ constructPolygon,
89
+ task.delegator_id,
90
+ );
91
+ }
92
+ const constructPolyline = task.construct_polyline_batched_feature;
93
+ if (constructPolyline) {
94
+ return await processConstructPolylineBatchedFeature(
95
+ ctx,
96
+ id,
97
+ event.bits,
98
+ constructPolyline,
99
+ task.delegator_id,
100
+ );
101
+ }
102
+ const parseMvt = task.parse_mvt_tile;
103
+ if (parseMvt) {
104
+ return await processParseMvtTile(
105
+ ctx,
106
+ id,
107
+ event.bits,
108
+ parseMvt,
109
+ task.delegator_id,
110
+ );
111
+ }
112
+ } finally {
113
+ task.free();
114
+ }
115
+ }
116
+
117
+ export function processWorkerTaskRemovedEvent(
118
+ ctx: EventContext,
119
+ event: EntityEvent,
120
+ ) {
121
+ const id = generate_id_from_entity(event);
122
+ const promise = ctx.workerPoolPromises.get(id);
123
+ if (promise) {
124
+ ctx.workerPoolPromises.delete(id);
125
+ // `cancel()` rejects the promise (CancellationError) and returns it; the
126
+ // rejection is observed and classified by the dispatch-side
127
+ // `settleWorkerTask`, so it must NOT be awaited here — awaiting would
128
+ // rethrow the cancellation into the event pipeline.
129
+ promise.cancel();
130
+ }
131
+ }
132
+
133
+ /**
134
+ * Read the entity bits out of an owned `ReconstructableEntity` getter clone
135
+ * and free the wrapper. Getter accessors allocate a NEW owned wrapper per
136
+ * read, so callers must pass the single read they made.
137
+ */
138
+ function takeEntityBits(entity: ReconstructableEntity): bigint {
139
+ try {
140
+ return entity[0];
141
+ } finally {
142
+ entity.free();
143
+ }
144
+ }
145
+
146
+ /**
147
+ * Copy an owned `ExtentRadianF32` getter clone into a plain
148
+ * `ExtentRadianF32Like` and free the wasm object. Getter accessors allocate a
149
+ * NEW owned wrapper per read, so callers must pass the single read they made.
150
+ */
151
+ function intoExtentRadianLike(
152
+ extent: ExtentRadianF32 | undefined,
153
+ ): ExtentRadianF32Like | undefined {
154
+ if (!extent) return undefined;
155
+ try {
156
+ return new ExtentRadianF32Like(extent);
157
+ } finally {
158
+ extent.free();
159
+ }
160
+ }
161
+
162
+ /**
163
+ * Track BufferStore registrations made while assembling one task result so a
164
+ * bail-out can free everything registered so far: handles are never reused,
165
+ * so an entry orphaned by an early return stays in the BufferStore forever.
166
+ * On the success path the handles move into the delivered result and must
167
+ * NOT be freed.
168
+ */
169
+ function trackRegisteredHandles(bufHandler: EventContext["buf"]) {
170
+ const handles: number[] = [];
171
+ return {
172
+ register<T extends number | undefined>(handle: T): T {
173
+ if (handle != null) handles.push(handle);
174
+ return handle;
175
+ },
176
+ free() {
177
+ for (const handle of handles) {
178
+ bufHandler.remove(handle);
179
+ }
180
+ },
181
+ };
182
+ }
183
+
184
+ /**
185
+ * Register a worker terrain result's arrays in the BufferStore and assemble
186
+ * the `TransferableGeometry` (with optional normals and skirt data), returned
187
+ * together with the separately delivered heights handle. When a required
188
+ * registration fails, the entries registered before it are freed and
189
+ * `undefined` is returned.
190
+ */
191
+ function buildTerrainTransferableGeometry(
192
+ bufHandler: EventContext["buf"],
193
+ result: ReturnedConstructedTerrainMeshLike,
194
+ ): { geometry: TransferableGeometry; heights: number } | undefined {
195
+ // Rust reads none of these terrain arrays (only their handles + byte counts),
196
+ // so adopt them JS-side (zero-copy) instead of copying into WASM memory.
197
+ const registered = trackRegisteredHandles(bufHandler);
198
+ const vertices = registered.register(bufHandler.adoptF32(result.vertices));
199
+ const uvs = registered.register(bufHandler.adoptF32(result.uvs));
200
+ const indices = registered.register(bufHandler.adoptU32(result.indices));
201
+ const heights = registered.register(bufHandler.adoptF32(result.heights));
202
+ if (vertices == null || uvs == null || indices == null || heights == null) {
203
+ registered.free();
204
+ return undefined;
205
+ }
206
+
207
+ const geometry = new TransferableGeometry(vertices, uvs, indices);
208
+
209
+ if (result.normals) {
210
+ const normals = bufHandler.adoptF32(result.normals);
211
+ if (normals != null) geometry.normals = normals;
212
+ }
213
+
214
+ // Set skirt data if available
215
+ if (result.skirt_vertices && result.skirt_uvs && result.skirt_indices) {
216
+ const skirtVertices = bufHandler.adoptF32(result.skirt_vertices);
217
+ const skirtUvs = bufHandler.adoptF32(result.skirt_uvs);
218
+ const skirtIndices = bufHandler.adoptU32(result.skirt_indices);
219
+ const skirtNormals = result.skirt_normals
220
+ ? bufHandler.adoptF32(result.skirt_normals)
221
+ : undefined;
222
+
223
+ if (skirtVertices != null) {
224
+ geometry.skirt_vertices = skirtVertices;
225
+ }
226
+ if (skirtUvs != null) {
227
+ geometry.skirt_uvs = skirtUvs;
228
+ }
229
+ if (skirtIndices != null) {
230
+ geometry.skirt_indices = skirtIndices;
231
+ }
232
+ if (skirtNormals != null) {
233
+ geometry.skirt_normals = skirtNormals;
234
+ }
235
+ }
236
+
237
+ return { geometry, heights };
238
+ }
239
+
240
+ async function processConstructTerrainMesh(
241
+ ctx: EventContext,
242
+ id: string,
243
+ bits: bigint,
244
+ params: ConstructTerrainMeshParameters,
245
+ delegator_id: ReconstructableEntity,
246
+ ) {
247
+ const { buf: bufHandler, tileHandler, workerTaskHandler } = ctx;
248
+ await runDelegatedWorkerTask(
249
+ ctx,
250
+ id,
251
+ bits,
252
+ "construct terrain mesh",
253
+ params,
254
+ delegator_id,
255
+ async (task) => {
256
+ // buf.u8 returns a short-lived view into WASM memory; copy it since the
257
+ // bytes are transferred to the worker (a view's buffer is the whole WASM
258
+ // memory and is not detachable).
259
+ const bytes = bufHandler.u8(params.bytes_handle)?.slice();
260
+ if (!bytes) {
261
+ return;
262
+ }
263
+
264
+ const tile = tileHandler.getTile(params.tile_handle);
265
+ if (!tile) {
266
+ return;
267
+ }
268
+
269
+ let promise: ReturnType<
270
+ typeof constructQuantizedMeshTerrainMesh | typeof constructTerrainMesh
271
+ >;
272
+ if (params.isQuantizedMesh) {
273
+ promise = constructQuantizedMeshTerrainMesh(
274
+ bytes,
275
+ new TransferableTileLike(tile),
276
+ params.skirt,
277
+ params.skirtExaggeration,
278
+ params.geographic,
279
+ params.tms,
280
+ );
281
+ } else {
282
+ const elevationDecoder = tileHandler.getTileElevationDecoder(
283
+ params.tile_handle,
284
+ );
285
+ if (!elevationDecoder) {
286
+ return;
287
+ }
288
+ promise = constructTerrainMesh(
289
+ bytes,
290
+ new TransferableTileLike(tile),
291
+ new TransferableRasterDEMDataLike(elevationDecoder),
292
+ params.tile_size,
293
+ params.skirt,
294
+ params.skirtExaggeration,
295
+ );
296
+ }
297
+ const settled = await task.settle(promise);
298
+ if (!settled) return;
299
+ const { result } = settled;
300
+
301
+ if (!workerTaskHandler.hasWorkerTask(delegator_id[0])) return;
302
+
303
+ const built = buildTerrainTransferableGeometry(bufHandler, result);
304
+ if (!built) return;
305
+ const { geometry, heights } = built;
306
+
307
+ const rtcTranslation = result.rtc_translation;
308
+ const watermaskHandle = result.watermask
309
+ ? bufHandler.adoptU8(result.watermask)
310
+ : undefined;
311
+
312
+ const constructTerrainMeshResult = new ConstructTerrainMeshResult(
313
+ geometry,
314
+ heights,
315
+ result.min_height,
316
+ result.max_height,
317
+ rtcTranslation
318
+ ? new Vec3(rtcTranslation.x, rtcTranslation.y, rtcTranslation.z)
319
+ : undefined,
320
+ );
321
+ if (watermaskHandle != null) {
322
+ constructTerrainMeshResult.watermask = watermaskHandle;
323
+ }
324
+
325
+ task.complete((delegator_id) =>
326
+ DelegatedWorkerTasksResult.withConstructTerrainMesh(
327
+ delegator_id,
328
+ constructTerrainMeshResult,
329
+ ),
330
+ );
331
+ },
332
+ );
333
+ }
334
+
335
+ async function processUpsampleTerrainMesh(
336
+ ctx: EventContext,
337
+ id: string,
338
+ bits: bigint,
339
+ params: UpsampleTerrainMeshParameters,
340
+ delegator_id: ReconstructableEntity,
341
+ ) {
342
+ const { buf: bufHandler, tileHandler, workerTaskHandler } = ctx;
343
+ await runDelegatedWorkerTask(
344
+ ctx,
345
+ id,
346
+ bits,
347
+ "upsample terrain mesh",
348
+ params,
349
+ delegator_id,
350
+ async (task) => {
351
+ const tile = tileHandler.getTile(params.tile_handle);
352
+ if (!tile) {
353
+ return;
354
+ }
355
+ const parentTile = tileHandler.getParentTile(params.tile_handle);
356
+ if (!parentTile) {
357
+ return;
358
+ }
359
+
360
+ const cachedMeshHandle = parentTile.cached_mesh_handle;
361
+ if (!cachedMeshHandle || !cachedMeshHandle.heights) {
362
+ return;
363
+ }
364
+
365
+ // buf.* return short-lived views into WASM memory; copy them since the
366
+ // parent geometry is sent to the worker (a view's buffer is the whole
367
+ // WASM memory and is not transferable).
368
+ const parentUvs = bufHandler.f32(cachedMeshHandle.uvs)?.slice();
369
+ const parentIndices = bufHandler.u32(cachedMeshHandle.indices)?.slice();
370
+ const parentHeights = bufHandler.f32(cachedMeshHandle.heights)?.slice();
371
+ if (!parentUvs || !parentIndices || !parentHeights) {
372
+ return;
373
+ }
374
+
375
+ const parentNormalsHandle = cachedMeshHandle.normals;
376
+ const parentNormals =
377
+ parentNormalsHandle != null
378
+ ? bufHandler.f32(parentNormalsHandle)?.slice()
379
+ : undefined;
380
+
381
+ const parentWatermaskHandle = cachedMeshHandle.watermask;
382
+ const parentWatermask =
383
+ parentWatermaskHandle != null
384
+ ? bufHandler.u8(parentWatermaskHandle)?.slice()
385
+ : undefined;
386
+
387
+ const upsamplableTerrainGeometry = new UpsamplableTerrainGeometryLike(
388
+ parentUvs,
389
+ parentIndices,
390
+ parentHeights,
391
+ parentNormals,
392
+ parentWatermask,
393
+ );
394
+
395
+ let promise: ReturnType<
396
+ typeof upsampleQuantizedMeshTerrainMesh | typeof upsampleTerrainMesh
397
+ >;
398
+ if (params.isQuantizedMesh) {
399
+ promise = upsampleQuantizedMeshTerrainMesh(
400
+ new TransferableTileLike(tile),
401
+ new TransferableTileLike(parentTile),
402
+ upsamplableTerrainGeometry,
403
+ params.skirt,
404
+ params.skirtExaggeration,
405
+ params.geographic,
406
+ params.tms,
407
+ );
408
+ } else {
409
+ const elevationDecoder = tileHandler.getTileElevationDecoder(
410
+ params.tile_handle,
411
+ );
412
+ if (!elevationDecoder) {
413
+ return;
414
+ }
415
+ promise = upsampleTerrainMesh(
416
+ new TransferableTileLike(tile),
417
+ new TransferableTileLike(parentTile),
418
+ new TransferableRasterDEMDataLike(elevationDecoder),
419
+ upsamplableTerrainGeometry,
420
+ params.skirt,
421
+ params.skirtExaggeration,
422
+ params.tms,
423
+ );
424
+ }
425
+ const result = await task.settle(promise);
426
+ if (!result) return;
427
+
428
+ if (!workerTaskHandler.hasWorkerTask(delegator_id[0])) return;
429
+
430
+ const built = buildTerrainTransferableGeometry(bufHandler, result);
431
+ if (!built) return;
432
+ const { geometry, heights } = built;
433
+
434
+ const rtcTranslation = result.rtc_translation;
435
+ const watermaskHandle = result.watermask
436
+ ? bufHandler.adoptU8(result.watermask)
437
+ : undefined;
438
+
439
+ const upsampleTerrainMeshResult = new UpsampleTerrainMeshResult(
440
+ geometry,
441
+ heights,
442
+ result.min_height,
443
+ result.max_height,
444
+ rtcTranslation
445
+ ? new Vec3(rtcTranslation.x, rtcTranslation.y, rtcTranslation.z)
446
+ : undefined,
447
+ );
448
+ if (watermaskHandle != null) {
449
+ upsampleTerrainMeshResult.watermask = watermaskHandle;
450
+ }
451
+
452
+ task.complete((delegator_id) =>
453
+ DelegatedWorkerTasksResult.withUpsampleTerrainMesh(
454
+ delegator_id,
455
+ upsampleTerrainMeshResult,
456
+ ),
457
+ );
458
+ },
459
+ );
460
+ }
461
+
462
+ async function processConstructPolygonBatchedFeature(
463
+ ctx: EventContext,
464
+ id: string,
465
+ bits: bigint,
466
+ params: ConstructPolygonBatchedFeatureParameters,
467
+ delegator_id: ReconstructableEntity,
468
+ ) {
469
+ const { buf: bufHandler, featureHandler, workerTaskHandler } = ctx;
470
+ await runDelegatedWorkerTask(
471
+ ctx,
472
+ id,
473
+ bits,
474
+ "construct polygon batched feature",
475
+ params,
476
+ delegator_id,
477
+ async (task) => {
478
+ const transferable = featureHandler.getTransferablePolygonBatchedFeature(
479
+ takeEntityBits(params.batched_feature),
480
+ );
481
+
482
+ if (!transferable) return;
483
+
484
+ // The Like constructors copy every array and field out of WASM memory,
485
+ // and `material` is a getter_with_clone accessor whose every read
486
+ // allocates a new owned wrapper: read it once and free both wasm
487
+ // objects as soon as the copies exist.
488
+ let featureLike: TransferablePolygonBatchedFeatureLike;
489
+ let materialLike: PolygonMaterialLike;
490
+ try {
491
+ featureLike = new TransferablePolygonBatchedFeatureLike(transferable);
492
+ const material = transferable.material;
493
+ try {
494
+ materialLike = new PolygonMaterialLike(material);
495
+ } finally {
496
+ material.free();
497
+ }
498
+ } finally {
499
+ transferable.free();
500
+ }
501
+
502
+ const promise = constructPolygonBatchedFeature(
503
+ featureLike,
504
+ materialLike,
505
+ params.flat,
506
+ intoExtentRadianLike(params.tile_extent),
507
+ );
508
+ const result = await task.settle(promise);
509
+ if (!result) return;
510
+
511
+ if (!workerTaskHandler.hasWorkerTask(delegator_id[0])) return;
512
+
513
+ // Rust reads none of these polygon draw attributes (only handles + byte
514
+ // counts), so adopt them JS-side (zero-copy) rather than copy into WASM.
515
+ // Exception: batch_id must stay WASM-resident — when a feature is
516
+ // evicted before JS consumes the geometry, Rust's
517
+ // `TransferablePolygonGeometry::remove_buffers` reads its contents to
518
+ // purge the `BatchTable`, and an External entry would silently skip
519
+ // that purge and leak the table rows.
520
+ const registered = trackRegisteredHandles(bufHandler);
521
+ const batchId = result.batch_id
522
+ ? registered.register(bufHandler.newF32(result.batch_id))
523
+ : undefined;
524
+ const batchIndex = result.batch_index
525
+ ? registered.register(bufHandler.adoptU32(result.batch_index))
526
+ : undefined;
527
+ const normal = result.normal
528
+ ? registered.register(bufHandler.adoptF32(result.normal))
529
+ : undefined;
530
+ const position = result.position
531
+ ? registered.register(bufHandler.adoptF32(result.position))
532
+ : undefined;
533
+ const position3dHigh = result.position_3d_high
534
+ ? registered.register(bufHandler.adoptF32(result.position_3d_high))
535
+ : undefined;
536
+ const position3dLow = result.position_3d_low
537
+ ? registered.register(bufHandler.adoptF32(result.position_3d_low))
538
+ : undefined;
539
+ const scaleNormalAndCap = result.scale_normal_and_cap
540
+ ? registered.register(bufHandler.adoptF32(result.scale_normal_and_cap))
541
+ : undefined;
542
+ const indices = registered.register(bufHandler.adoptU32(result.indices));
543
+ if (!indices) {
544
+ registered.free();
545
+ return;
546
+ }
547
+ // Either position or (position_3d_high and position_3d_low) must be present
548
+ if (!position && (!position3dHigh || !position3dLow)) {
549
+ registered.free();
550
+ return;
551
+ }
552
+
553
+ const transferableBatchId = batchId
554
+ ? new TransferableFloatAttribute(batchId, result.batch_id_size ?? 0)
555
+ : undefined;
556
+ const transferableBatchIndex = batchIndex
557
+ ? new TransferableUintAttribute(
558
+ batchIndex,
559
+ result.batch_index_size ?? 0,
560
+ )
561
+ : undefined;
562
+ const transferableNormal = normal
563
+ ? new TransferableFloatAttribute(normal, result.normal_size ?? 0)
564
+ : undefined;
565
+ const transferablePosition = position
566
+ ? new TransferableFloatAttribute(position, result.position_size ?? 0)
567
+ : undefined;
568
+ const transferablePosition3dHigh = position3dHigh
569
+ ? new TransferableFloatAttribute(
570
+ position3dHigh,
571
+ result.position_3d_high_size ?? 0,
572
+ )
573
+ : undefined;
574
+ const transferablePosition3dLow = position3dLow
575
+ ? new TransferableFloatAttribute(
576
+ position3dLow,
577
+ result.position_3d_low_size ?? 0,
578
+ )
579
+ : undefined;
580
+ const transferableScaleNormalAndCap = scaleNormalAndCap
581
+ ? new TransferableFloatAttribute(
582
+ scaleNormalAndCap,
583
+ result.scale_normal_and_cap_size ?? 0,
584
+ )
585
+ : undefined;
586
+ const geometry = new TransferablePolygonGeometry(
587
+ transferablePosition,
588
+ transferablePosition3dHigh,
589
+ transferablePosition3dLow,
590
+ transferableNormal,
591
+ transferableScaleNormalAndCap,
592
+ transferableBatchId,
593
+ transferableBatchIndex,
594
+ indices,
595
+ );
596
+
597
+ // Construct outline geometry if present
598
+ let outlineGeometry: TransferablePolygonOutlineGeometry | undefined;
599
+ if (result.outline_position) {
600
+ const outlinePosition = bufHandler.adoptF32(result.outline_position);
601
+ const outlineScaleNormalAndCap = result.outline_scale_normal_and_cap
602
+ ? bufHandler.adoptF32(result.outline_scale_normal_and_cap)
603
+ : undefined;
604
+ const outlineSkipIndices = result.outline_skip_indices
605
+ ? bufHandler.adoptU32(result.outline_skip_indices)
606
+ : undefined;
607
+
608
+ const outlineBatchIndex = result.outline_batch_index
609
+ ? bufHandler.adoptF32(result.outline_batch_index)
610
+ : undefined;
611
+
612
+ outlineGeometry = new TransferablePolygonOutlineGeometry(
613
+ outlinePosition
614
+ ? new TransferableFloatAttribute(
615
+ outlinePosition,
616
+ result.outline_position_size ?? 3,
617
+ )
618
+ : undefined,
619
+ outlineScaleNormalAndCap
620
+ ? new TransferableFloatAttribute(
621
+ outlineScaleNormalAndCap,
622
+ result.outline_scale_normal_and_cap_size ?? 4,
623
+ )
624
+ : undefined,
625
+ outlineSkipIndices,
626
+ outlineBatchIndex
627
+ ? new TransferableFloatAttribute(
628
+ outlineBatchIndex,
629
+ result.outline_batch_index_size ?? 1,
630
+ )
631
+ : undefined,
632
+ );
633
+ }
634
+
635
+ const extent = result.extent;
636
+ const rtc_translation = result.rtc_translation;
637
+ const constructPolygonBatchedFeatureResult =
638
+ new ConstructPolygonBatchedFeatureResult(
639
+ geometry,
640
+ outlineGeometry,
641
+ extent
642
+ ? new ExtentRadianF32(
643
+ extent.west,
644
+ extent.south,
645
+ extent.east,
646
+ extent.north,
647
+ )
648
+ : undefined,
649
+
650
+ rtc_translation
651
+ ? new Vec3(rtc_translation.x, rtc_translation.y, rtc_translation.z)
652
+ : undefined, // RTC translation from worker
653
+ );
654
+
655
+ task.complete((delegator_id) =>
656
+ DelegatedWorkerTasksResult.withConstructPolygonBatchedFeature(
657
+ delegator_id,
658
+ constructPolygonBatchedFeatureResult,
659
+ ),
660
+ );
661
+ },
662
+ );
663
+ }
664
+
665
+ async function processConstructPolylineBatchedFeature(
666
+ ctx: EventContext,
667
+ id: string,
668
+ bits: bigint,
669
+ params: ConstructPolylineBatchedFeatureParameters,
670
+ delegator_id: ReconstructableEntity,
671
+ ) {
672
+ const { buf: bufHandler, featureHandler, workerTaskHandler } = ctx;
673
+ await runDelegatedWorkerTask(
674
+ ctx,
675
+ id,
676
+ bits,
677
+ "construct polyline batched feature",
678
+ params,
679
+ delegator_id,
680
+ async (task) => {
681
+ const transferable = featureHandler.getTransferablePolylineBatchedFeature(
682
+ takeEntityBits(params.batched_feature),
683
+ );
684
+
685
+ if (!transferable) return;
686
+
687
+ // The Like constructors copy every array and field out of WASM memory,
688
+ // and `material` is a getter_with_clone accessor whose every read
689
+ // allocates a new owned wrapper: read it once and free both wasm
690
+ // objects as soon as the copies exist.
691
+ let featureLike: TransferablePolylineBatchedFeatureLike;
692
+ let materialLike: PolylineMaterialLike;
693
+ try {
694
+ featureLike = new TransferablePolylineBatchedFeatureLike(transferable);
695
+ const material = transferable.material;
696
+ try {
697
+ materialLike = new PolylineMaterialLike(material);
698
+ } finally {
699
+ material.free();
700
+ }
701
+ } finally {
702
+ transferable.free();
703
+ }
704
+
705
+ const promise = constructPolylineBatchedFeature(
706
+ featureLike,
707
+ materialLike,
708
+ params.flat,
709
+ );
710
+ const result = await task.settle(promise);
711
+ if (!result || !result.batch_id || !result.batch_index) return;
712
+
713
+ if (!workerTaskHandler.hasWorkerTask(delegator_id[0])) return;
714
+
715
+ // Rust reads none of these polyline draw attributes (only handles + byte
716
+ // counts), so adopt them JS-side (zero-copy) rather than copy into WASM.
717
+ // Exception: batch_id must stay WASM-resident — when a feature is
718
+ // evicted before JS consumes the geometry, Rust's
719
+ // `TransferablePolylineGeometry::remove_buffers` reads its contents to
720
+ // purge the `BatchTable`, and an External entry would silently skip
721
+ // that purge and leak the table rows.
722
+ const registered = trackRegisteredHandles(bufHandler);
723
+ const position = registered.register(
724
+ bufHandler.adoptF32(result.position),
725
+ );
726
+ const positionHigh = result.position_high
727
+ ? registered.register(bufHandler.adoptF32(result.position_high))
728
+ : undefined;
729
+ const positionLow = result.position_low
730
+ ? registered.register(bufHandler.adoptF32(result.position_low))
731
+ : undefined;
732
+ const start = result.start
733
+ ? registered.register(bufHandler.adoptF32(result.start))
734
+ : undefined;
735
+ const startHigh = result.start_high
736
+ ? registered.register(bufHandler.adoptF32(result.start_high))
737
+ : undefined;
738
+ const startLow = result.start_low
739
+ ? registered.register(bufHandler.adoptF32(result.start_low))
740
+ : undefined;
741
+ const startNormals = result.start_normals
742
+ ? registered.register(bufHandler.adoptF32(result.start_normals))
743
+ : undefined;
744
+ const forwardOffset = result.forward_offset
745
+ ? registered.register(bufHandler.adoptF32(result.forward_offset))
746
+ : undefined;
747
+ const endHigh = result.end_high
748
+ ? registered.register(bufHandler.adoptF32(result.end_high))
749
+ : undefined;
750
+ const endLow = result.end_low
751
+ ? registered.register(bufHandler.adoptF32(result.end_low))
752
+ : undefined;
753
+ const endNormalAndTextureCoordinateNormalizationX =
754
+ result.end_normal_and_texture_coordinate_normalization_x
755
+ ? registered.register(
756
+ bufHandler.adoptF32(
757
+ result.end_normal_and_texture_coordinate_normalization_x,
758
+ ),
759
+ )
760
+ : undefined;
761
+ const rightNormalAndTextureCoordinateNormalizationY = registered.register(
762
+ bufHandler.adoptF32(
763
+ result.right_normal_and_texture_coordinate_normalization_y,
764
+ ),
765
+ );
766
+ const batchId = registered.register(bufHandler.newF32(result.batch_id));
767
+ const batchIndex = registered.register(
768
+ bufHandler.adoptU32(result.batch_index),
769
+ );
770
+ const indices = registered.register(bufHandler.adoptU32(result.indices));
771
+ if (
772
+ !batchId ||
773
+ !batchIndex ||
774
+ !position ||
775
+ !rightNormalAndTextureCoordinateNormalizationY ||
776
+ !indices
777
+ ) {
778
+ registered.free();
779
+ return;
780
+ }
781
+
782
+ const transferableBatchId = new TransferableFloatAttribute(
783
+ batchId,
784
+ result.batch_id_size ?? 0,
785
+ );
786
+ const transferableBatchIndex = new TransferableUintAttribute(
787
+ batchIndex,
788
+ result.batch_index_size ?? 0,
789
+ );
790
+ const transferablePosition = new TransferableFloatAttribute(
791
+ position,
792
+ result.position_size,
793
+ );
794
+ const transferablePositionHigh = positionHigh
795
+ ? new TransferableFloatAttribute(
796
+ positionHigh,
797
+ result.position_high_size ?? 0,
798
+ )
799
+ : undefined;
800
+ const transferablePositionLow = positionLow
801
+ ? new TransferableFloatAttribute(
802
+ positionLow,
803
+ result.position_low_size ?? 0,
804
+ )
805
+ : undefined;
806
+ const transferableStart = start
807
+ ? new TransferableFloatAttribute(start, result.start_size ?? 0)
808
+ : undefined;
809
+ const transferableStartHigh = startHigh
810
+ ? new TransferableFloatAttribute(startHigh, result.start_high_size ?? 0)
811
+ : undefined;
812
+ const transferableStartLow = startLow
813
+ ? new TransferableFloatAttribute(startLow, result.start_low_size ?? 0)
814
+ : undefined;
815
+ const transferableEndHigh = endHigh
816
+ ? new TransferableFloatAttribute(endHigh, result.end_high_size ?? 0)
817
+ : undefined;
818
+ const transferableEndLow = endLow
819
+ ? new TransferableFloatAttribute(endLow, result.end_low_size ?? 0)
820
+ : undefined;
821
+ const transferableStartNormals = startNormals
822
+ ? new TransferableFloatAttribute(
823
+ startNormals,
824
+ result.start_normals_size ?? 0,
825
+ )
826
+ : undefined;
827
+ const transferableForwardOffset = forwardOffset
828
+ ? new TransferableFloatAttribute(
829
+ forwardOffset,
830
+ result.forward_offset_size ?? 0,
831
+ )
832
+ : undefined;
833
+ const transferableEndNormalAndTextureCoordinateNormalizationX =
834
+ endNormalAndTextureCoordinateNormalizationX
835
+ ? new TransferableFloatAttribute(
836
+ endNormalAndTextureCoordinateNormalizationX,
837
+ result.end_normal_and_texture_coordinate_normalization_x_size ??
838
+ 0,
839
+ )
840
+ : undefined;
841
+ const transferableRightNormalAndTextureCoordinateNormalizationY =
842
+ new TransferableFloatAttribute(
843
+ rightNormalAndTextureCoordinateNormalizationY,
844
+ result.right_normal_and_texture_coordinate_normalization_y_size,
845
+ );
846
+
847
+ const geometry = new TransferablePolylineGeometry(
848
+ transferablePosition,
849
+ transferablePositionHigh,
850
+ transferablePositionLow,
851
+ transferableStart,
852
+ transferableStartHigh,
853
+ transferableStartLow,
854
+ transferableForwardOffset,
855
+ transferableEndHigh,
856
+ transferableEndLow,
857
+ transferableStartNormals,
858
+ transferableEndNormalAndTextureCoordinateNormalizationX,
859
+ transferableRightNormalAndTextureCoordinateNormalizationY,
860
+ transferableBatchId,
861
+ transferableBatchIndex,
862
+ indices,
863
+ );
864
+
865
+ const extent = result.extent;
866
+ const constructPolylineBatchedFeatureResult =
867
+ new ConstructPolylineBatchedFeatureResult(
868
+ geometry,
869
+ extent
870
+ ? new ExtentRadianF32(
871
+ extent.west,
872
+ extent.south,
873
+ extent.east,
874
+ extent.north,
875
+ )
876
+ : undefined,
877
+ );
878
+
879
+ task.complete((delegator_id) =>
880
+ DelegatedWorkerTasksResult.withConstructPolylineBatchedFeature(
881
+ delegator_id,
882
+ constructPolylineBatchedFeatureResult,
883
+ ),
884
+ );
885
+ },
886
+ );
887
+ }
888
+
889
+ async function processParseMvtTile(
890
+ ctx: EventContext,
891
+ id: string,
892
+ bits: bigint,
893
+ params: ParseMvtTileParameters,
894
+ delegator_id: ReconstructableEntity,
895
+ ) {
896
+ const { buf: bufHandler, workerTaskHandler } = ctx;
897
+ await runDelegatedWorkerTask(
898
+ ctx,
899
+ id,
900
+ bits,
901
+ "parse MVT tile",
902
+ params,
903
+ delegator_id,
904
+ async (task) => {
905
+ // Unlike the construct tasks, a parse that fails after dispatch
906
+ // completes with an empty result instead of releasing the delegator:
907
+ // this finalizes the tile with zero features, matching the synchronous
908
+ // path's behavior for an unparseable tile.
909
+ const completeWithEmptyResult = () => {
910
+ task.complete((delegator_id) =>
911
+ DelegatedWorkerTasksResult.withParseMvtTile(
912
+ delegator_id,
913
+ ParseMvtTileResult.empty(),
914
+ ),
915
+ );
916
+ };
917
+
918
+ // Move the pbf out of the BufferStore as we hand a copy to the worker:
919
+ // the main thread never reuses it (geometry comes back from the worker),
920
+ // so this avoids keeping the tile's bytes resident on the main thread
921
+ // for the whole parse. (finalize/cancel still call `buf.remove` as a
922
+ // no-op safety net for tasks that were cancelled before ever being
923
+ // dispatched here.)
924
+ const bytes = bufHandler.removeU8(params.pbf_handle);
925
+ if (!bytes) {
926
+ completeWithEmptyResult();
927
+ return;
928
+ }
929
+
930
+ const promise = parseMvtTile(
931
+ bytes,
932
+ params.x,
933
+ params.y,
934
+ params.z,
935
+ intoExtentRadianLike(params.tile_extent),
936
+ params.compression,
937
+ params.configs_json,
938
+ );
939
+ // Cancelled (tile evicted while parsing): there is nothing to deliver —
940
+ // the engine already marked the task Deleted.
941
+ const result = await task.settle(promise, completeWithEmptyResult);
942
+ if (!result) return;
943
+
944
+ // Nothing is registered in the BufferStore before this check, so a
945
+ // vanished task leaks nothing.
946
+ if (!workerTaskHandler.hasWorkerTask(delegator_id[0])) return;
947
+
948
+ // Store the four packed streams in the BufferStore (writing straight
949
+ // into WASM memory) and hand the engine only their handles; the
950
+ // delegated-task system frees them on every path, including a deleted
951
+ // delegator.
952
+ const registered = trackRegisteredHandles(bufHandler);
953
+ const f64Handle = registered.register(
954
+ bufHandler.newF64(result.f64_stream),
955
+ );
956
+ const f32Handle = registered.register(
957
+ bufHandler.newF32(result.f32_stream),
958
+ );
959
+ const u32Handle = registered.register(
960
+ bufHandler.newU32(result.u32_stream),
961
+ );
962
+ const u8Handle = registered.register(bufHandler.newU8(result.u8_stream));
963
+ if (
964
+ f64Handle == null ||
965
+ f32Handle == null ||
966
+ u32Handle == null ||
967
+ u8Handle == null
968
+ ) {
969
+ registered.free();
970
+ completeWithEmptyResult();
971
+ return;
972
+ }
973
+
974
+ // The wasm-bindgen constructor deserializes `meta` and can throw (it
975
+ // returns Result on the Rust side). The four handles registered above
976
+ // are owned by nobody until the result reaches the engine, so free them
977
+ // on failure or they stay in the BufferStore forever.
978
+ let parseResult: ParseMvtTileResult;
979
+ try {
980
+ parseResult = new ParseMvtTileResult(
981
+ f64Handle,
982
+ f32Handle,
983
+ u32Handle,
984
+ u8Handle,
985
+ result.meta,
986
+ );
987
+ } catch (err) {
988
+ registered.free();
989
+ console.error("Failed to deserialize MVT tile meta:", err);
990
+ completeWithEmptyResult();
991
+ return;
992
+ }
993
+
994
+ task.complete((delegator_id) =>
995
+ DelegatedWorkerTasksResult.withParseMvtTile(delegator_id, parseResult),
996
+ );
997
+ },
998
+ );
999
+ }