@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,700 @@
1
+ import {
2
+ generate_id_from_entity,
3
+ IMAGE_EXTENSIONS,
4
+ isEntityEvent,
5
+ } from "@navaramap/core";
6
+ import {
7
+ type Transform,
8
+ type EntityEvent,
9
+ type ObjectTransformEvent,
10
+ type DataRequestEvent,
11
+ type CameraFrustum,
12
+ TextureFragmentRequestedEvent,
13
+ TextureFragmentStatus,
14
+ DataRequesterRemovedEvent,
15
+ RenderableFeatureRemovedEvent,
16
+ Events,
17
+ } from "@navaramap/engine";
18
+ import { radianToDegree } from "@navaramap/three_api";
19
+ import { canWorkerProcessImmediately } from "@navaramap/worker";
20
+ import { Mesh, Object3D, Sprite } from "three";
21
+
22
+ import { BatchedSdfTextMesh, Layer } from "..";
23
+ import { disposeTexture } from "../loaders";
24
+ import { getImageDataFromBlob } from "../tasks/getImageDataFromBlob";
25
+
26
+ import { EventContext } from "./context";
27
+ import {
28
+ checkFeatureParallel,
29
+ processRenderableFeatureAdded,
30
+ processRenderableFeatureChanged,
31
+ } from "./feature";
32
+ import {
33
+ processHillshadeBackfilled,
34
+ processHillshadeCanceled,
35
+ } from "./hillshade";
36
+ import { ABORTABLE_TEXTURE_LOADER } from "./loaders";
37
+ import { processMeshAdded, processMeshChanged } from "./tile";
38
+ import {
39
+ processWorkerTaskDelegatedEvent,
40
+ processWorkerTaskRemovedEvent,
41
+ } from "./worker";
42
+
43
+ export type {
44
+ BufferLoader,
45
+ TextureFragmentHandler,
46
+ WorkerTaskHandler,
47
+ TileHandler,
48
+ GlobeHandler,
49
+ FeatureHandler,
50
+ MeshHandler,
51
+ LayerHandler,
52
+ } from "./context";
53
+ export { EventContext } from "./context";
54
+ export { HillshadeContext } from "./HillshadeContext";
55
+
56
+ export function processEvent(ctx: EventContext, event: Events | undefined) {
57
+ const {
58
+ eventManager,
59
+ meshes,
60
+ meshHandler,
61
+ viewEvents,
62
+ layersManager,
63
+ viewContext,
64
+ } = ctx;
65
+
66
+ eventManager.pushEvents(event);
67
+
68
+ eventManager.forEachStack("camera_transform_updated", (ev) =>
69
+ processCameraTransformUpdated(ctx, ev),
70
+ );
71
+
72
+ eventManager.forEachStack("camera_frustum_updated", (ev) =>
73
+ processCameraFrustumUpdated(ctx, ev),
74
+ );
75
+
76
+ eventManager.forEachStack("object_transform_updated", (ev) =>
77
+ processObjectTransformUpdated(ctx, ev),
78
+ );
79
+
80
+ eventManager.forEachStack("update_sample_terrain_height", (ev) =>
81
+ viewEvents.emit("_sample_terrain_height_received", ev),
82
+ );
83
+
84
+ // Process cancels before backfills, synchronously. Each cancel drops its
85
+ // own matching pending backfills from the stack (see processHillshadeCanceled),
86
+ // so the subsequent forEachStack only iterates surviving events.
87
+ //
88
+ // Using forEachStack here matches main's per-frame timing — switching this
89
+ // to processTransactionEvents earlier caused hillshade adds to be spread
90
+ // across frames via the TransactionManager chain, which produced visible
91
+ // texture offset during fast pan/zoom.
92
+ eventManager.forEachStack(
93
+ "hillshade_canceled",
94
+ (ev) => processHillshadeCanceled(ctx, ev),
95
+ Infinity,
96
+ );
97
+
98
+ eventManager.forEachStack("hillshade_backfilled", (ev) =>
99
+ processHillshadeBackfilled(ctx, ev),
100
+ );
101
+
102
+ eventManager.processTransactionEvents(
103
+ "meshEvent",
104
+ {
105
+ add: {
106
+ key: "mesh_added",
107
+ },
108
+ remove: {
109
+ key: "mesh_removed",
110
+ // This process is not heavy for now, so we can process it infinitely.
111
+ max: Infinity,
112
+ },
113
+ change: {
114
+ key: "mesh_updated",
115
+ // This process is not heavy for now, so we can process it infinitely.
116
+ max: Infinity,
117
+ },
118
+ },
119
+ async ({ type, event }) => {
120
+ switch (type) {
121
+ case "add":
122
+ await processMeshAdded(ctx, event);
123
+ meshHandler.setTileMeshPrepared(event.tile_handle);
124
+ break;
125
+ case "remove":
126
+ processObjectRemoved(ctx, event);
127
+ break;
128
+ case "change":
129
+ processMeshChanged(ctx, event);
130
+ break;
131
+ }
132
+ },
133
+ {
134
+ shouldProcess: ({ type }) => {
135
+ switch (type) {
136
+ case "add":
137
+ return canWorkerProcessImmediately();
138
+ case "remove":
139
+ return true;
140
+ case "change":
141
+ return true;
142
+ }
143
+ },
144
+ },
145
+ );
146
+
147
+ eventManager.processTransactionEvents(
148
+ "workerTaskEvent",
149
+ {
150
+ add: {
151
+ key: "worker_task_delegated",
152
+ },
153
+ remove: {
154
+ key: "worker_task_removed",
155
+ max: Infinity,
156
+ },
157
+ },
158
+ async ({ type, event }) => {
159
+ switch (type) {
160
+ case "add":
161
+ await processWorkerTaskDelegatedEvent(ctx, event);
162
+ break;
163
+ case "remove":
164
+ processWorkerTaskRemovedEvent(ctx, event);
165
+ break;
166
+ }
167
+ },
168
+ {
169
+ shouldProcess: ({ type }) => {
170
+ switch (type) {
171
+ case "add":
172
+ return canWorkerProcessImmediately();
173
+ case "remove":
174
+ return true;
175
+ case "change":
176
+ return true;
177
+ }
178
+ },
179
+ onAbort: (event) => {
180
+ processWorkerTaskRemovedEvent(ctx, event);
181
+ },
182
+ },
183
+ );
184
+
185
+ eventManager.processTransactionEvents(
186
+ "renderableFeatureEvent",
187
+ {
188
+ add: {
189
+ key: "renderable_feature_added",
190
+ },
191
+ remove: {
192
+ key: "renderable_feature_removed",
193
+ // This process is not heavy for now, so we can process it infinitely.
194
+ max: Infinity,
195
+ },
196
+ change: {
197
+ key: "renderable_feature_changed",
198
+ // This process is not heavy for now, so we can process it infinitely.
199
+ max: Infinity,
200
+ },
201
+ },
202
+ async ({ type, event }) => {
203
+ switch (type) {
204
+ case "add":
205
+ await processRenderableFeatureAdded(ctx, event);
206
+ break;
207
+ case "remove":
208
+ {
209
+ const removed = event as RenderableFeatureRemovedEvent;
210
+ const layer = layersManager.get(removed.layer_id);
211
+ if (layer && layer instanceof Layer) {
212
+ layer._unregisterFeatureEvaluator(removed.bits);
213
+ layer.emit("featureRemoved", { featureSetId: removed.bits });
214
+ }
215
+ processObjectRemoved(ctx, event);
216
+ }
217
+ break;
218
+ case "change":
219
+ await processRenderableFeatureChanged(ctx, event);
220
+ break;
221
+ }
222
+ },
223
+ {
224
+ shouldProcess: ({ type, event }) => {
225
+ switch (type) {
226
+ case "add":
227
+ return (
228
+ !checkFeatureParallel(event.feature) ||
229
+ viewContext.concurrencyManager.canIncrement()
230
+ );
231
+ case "remove":
232
+ return true;
233
+ case "change":
234
+ if (isEntityEvent(event)) {
235
+ const id = generate_id_from_entity(event);
236
+ return meshes.has(id);
237
+ }
238
+ return true;
239
+ }
240
+ },
241
+ },
242
+ );
243
+
244
+ eventManager.processTransactionEvents(
245
+ "textureFragmentEvent",
246
+ {
247
+ add: {
248
+ key: "texture_fragment_requested",
249
+ },
250
+ remove: {
251
+ key: "texture_fragment_removed",
252
+ // This process is not heavy for now, so we can process it infinitely.
253
+ max: Infinity,
254
+ },
255
+ },
256
+ async ({ type, event }) => {
257
+ switch (type) {
258
+ case "add":
259
+ await processTextureFragmentRequested(ctx, event);
260
+ break;
261
+ case "remove":
262
+ processTextureFragmentRemoved(ctx, event);
263
+ break;
264
+ }
265
+ },
266
+ {
267
+ onAbort: (event) => {
268
+ processTextureFragmentRemoved(ctx, event);
269
+ },
270
+ },
271
+ );
272
+
273
+ eventManager.processTransactionEvents(
274
+ "dataRequesterEvent",
275
+ {
276
+ add: {
277
+ key: "data_requested",
278
+ },
279
+ remove: {
280
+ key: "data_requester_removed",
281
+ // This process is not heavy for now, so we can process it infinitely.
282
+ max: Infinity,
283
+ },
284
+ },
285
+ async ({ type, event }) => {
286
+ switch (type) {
287
+ case "add":
288
+ await processRequestedData(ctx, event);
289
+ break;
290
+ case "remove":
291
+ processDataRequesterRemoved(ctx, event);
292
+ break;
293
+ }
294
+ },
295
+ {
296
+ onAbort: (event) => {
297
+ processDataRequesterRemoved(ctx, event);
298
+ },
299
+ },
300
+ );
301
+ }
302
+
303
+ function processCameraTransformUpdated(
304
+ ctx: EventContext,
305
+ transform: Transform | undefined,
306
+ ) {
307
+ if (!transform) return;
308
+ setTransform(ctx.camera.raw, transform);
309
+
310
+ ctx.camera.updateStatus();
311
+ }
312
+
313
+ function processCameraFrustumUpdated(
314
+ ctx: EventContext,
315
+ frustum: CameraFrustum | undefined,
316
+ ) {
317
+ if (!frustum) return;
318
+
319
+ ctx.camera.raw.near = frustum.near;
320
+ ctx.camera.raw.far = frustum.far;
321
+ ctx.camera.raw.fov = radianToDegree(frustum.fov);
322
+ ctx.camera.raw.updateProjectionMatrix();
323
+ ctx.camera.emit("frustumChanged");
324
+ }
325
+
326
+ function processObjectTransformUpdated(
327
+ ctx: EventContext,
328
+ e: ObjectTransformEvent,
329
+ ) {
330
+ const id = generate_id_from_entity(e);
331
+ const m = ctx.meshes.get(id);
332
+ if (m) {
333
+ setTransform(m, e.transform);
334
+ }
335
+ }
336
+
337
+ function processObjectRemoved(ctx: EventContext, obj: EntityEvent) {
338
+ const { meshes } = ctx;
339
+ const id = generate_id_from_entity(obj);
340
+ const m = meshes.get(id);
341
+ if (!m) return;
342
+
343
+ meshes.delete(id);
344
+
345
+ // Sprite, Mesh, and Group are all subclasses of Object3D
346
+ if (m instanceof Object3D) {
347
+ disposeObject3D(m);
348
+ }
349
+
350
+ if (m instanceof BatchedSdfTextMesh) {
351
+ m.dispose();
352
+ }
353
+
354
+ // Custom event not in Object3DEventMap
355
+ // @ts-expect-error - removedFromWorld is a custom event
356
+ m.dispatchEvent({ type: "removedFromWorld" });
357
+
358
+ // clear should after dispose, otherwise model's children will not be disposed
359
+ m.clear();
360
+
361
+ // Detach from whatever scene it was added to (mrt for opaque features,
362
+ // transparent for always-on-top overlay sprites, globe for globe meshes).
363
+ m.removeFromParent();
364
+ }
365
+
366
+ function disposeObject3D(model: Object3D): void {
367
+ model.traverse((object: Object3D) => {
368
+ if (object instanceof Mesh) {
369
+ const mesh = object as Mesh;
370
+
371
+ // Dispose geometry and aggressively drop all attributes
372
+ const g = mesh.geometry;
373
+ if (g) {
374
+ g.dispose?.();
375
+
376
+ // Remove every BufferAttribute (handles polyline/polygon custom attrs)
377
+ if (g.attributes) {
378
+ for (const key of Object.keys(g.attributes)) {
379
+ g.deleteAttribute(key);
380
+ }
381
+ }
382
+
383
+ g.index = null;
384
+ g.boundingBox = null;
385
+ g.boundingSphere = null;
386
+ }
387
+
388
+ // Dispose material(s)
389
+ if (mesh.material) {
390
+ if (Array.isArray(mesh.material)) {
391
+ mesh.material.forEach((material) => {
392
+ material.dispose();
393
+ });
394
+ } else {
395
+ const material = mesh.material;
396
+ material.dispose();
397
+ }
398
+ }
399
+ }
400
+ // point, billboard, text
401
+ else if (object instanceof Sprite) {
402
+ const sprite = object as Sprite;
403
+
404
+ // Dispose material
405
+ if (sprite.material) {
406
+ if (Array.isArray(sprite.material)) {
407
+ sprite.material.forEach((material) => {
408
+ material.dispose();
409
+ });
410
+ } else {
411
+ const material = sprite.material;
412
+ material.dispose();
413
+ }
414
+ }
415
+ }
416
+ });
417
+ }
418
+
419
+ // TODO: Need to check if the cached texture is removed completely
420
+ async function processRequestedData(ctx: EventContext, req: DataRequestEvent) {
421
+ const { buf, abortControllers } = ctx;
422
+ const id = generate_id_from_entity(req);
423
+
424
+ const abortController = (() => {
425
+ const a = abortControllers.get(id);
426
+ if (a) {
427
+ return a;
428
+ } else {
429
+ const a = new AbortController();
430
+ abortControllers.set(id, a);
431
+ return a;
432
+ }
433
+ })();
434
+
435
+ if (IMAGE_EXTENSIONS.includes(req.extension)) {
436
+ // Fetch the compressed bytes here and hand the Blob to a worker that runs
437
+ // createImageBitmap + getImageData. Decoding the image (e.g. terrain-RGB
438
+ // DEM tiles) entirely on the worker keeps the costly "Image Decode" off the
439
+ // main thread — previously we decoded an HTMLImageElement and then
440
+ // re-decoded it via createImageBitmap on the main thread.
441
+ await fetch(req.url, { signal: abortController.signal })
442
+ .then((res) => {
443
+ if (!res.ok) throw new Error();
444
+ return res.blob();
445
+ })
446
+ .then(async (blob) => {
447
+ if (abortController.signal.aborted) {
448
+ return;
449
+ }
450
+
451
+ const promise = getImageDataFromBlob(blob);
452
+
453
+ ctx.workerPoolPromises.set(id, promise);
454
+ const data = await (async () => {
455
+ try {
456
+ return await promise;
457
+ } finally {
458
+ ctx.workerPoolPromises.delete(id);
459
+ }
460
+ })();
461
+
462
+ if (abortController.signal.aborted) {
463
+ return;
464
+ }
465
+
466
+ let u8a: Uint8Array | null = new Uint8Array(data);
467
+ buf.setU8(req.handle, req.bits, u8a);
468
+
469
+ // Prevent memory leak
470
+ u8a.set([]);
471
+ u8a = null;
472
+
473
+ data.set([]);
474
+ })
475
+ .catch(() => {
476
+ buf.triggerDataRequesterFailed(req.bits);
477
+ })
478
+ .finally(() => {
479
+ abortControllers.delete(id);
480
+ });
481
+ return;
482
+ }
483
+
484
+ // Quantized-mesh extensions requested for this terrain tile (empty otherwise).
485
+ // The hyphen-joined token list is shared by the Accept header (server
486
+ // negotiation) and the URL query (cache key) below.
487
+ const terrainExts =
488
+ req.extension === "terrain"
489
+ ? [
490
+ ...(req.requestVertexNormals ? ["octvertexnormals"] : []),
491
+ ...(req.requestWaterMask ? ["watermask"] : []),
492
+ ]
493
+ : [];
494
+
495
+ // Cesium-style quantized-mesh servers gate the normals/watermask extensions
496
+ // behind an explicit Accept header. Only opt in when the layer requested it
497
+ // — otherwise some servers refuse to respond, and we don't want to pay for
498
+ // bytes we won't use anyway.
499
+ let headers = (() => {
500
+ if (req.extension !== "terrain") {
501
+ return req.token ? { Authorization: `Bearer ${req.token}` } : undefined;
502
+ }
503
+ const accept = terrainExts.length
504
+ ? `application/vnd.quantized-mesh;extensions=${terrainExts.join("-")},application/octet-stream;q=0.9,*/*;q=0.01`
505
+ : "application/vnd.quantized-mesh,application/octet-stream;q=0.9,*/*;q=0.01";
506
+ const h: Record<string, string> = { Accept: accept };
507
+ if (req.token) h.Authorization = `Bearer ${req.token}`;
508
+ return h;
509
+ })();
510
+
511
+ // Partial fetch: PMTiles (and any future range-based source) sets a byte
512
+ // range on the request. `!= null` is intentional so a 0n offset (the header
513
+ // bootstrap read) is still treated as present. A length of 0n (from a
514
+ // malformed header/directory or an upstream bug) would underflow `end` to
515
+ // `offset - 1n` and emit an invalid `Range` header — and falling back to a
516
+ // full fetch could silently download an entire multi-GB archive — so fail
517
+ // the request instead.
518
+ if (req.offset != null && req.length != null) {
519
+ if (req.length <= 0n) {
520
+ buf.triggerDataRequesterFailed(req.bits);
521
+ abortControllers.delete(id);
522
+ return;
523
+ }
524
+ const end = req.offset + req.length - 1n;
525
+ headers = { ...(headers ?? {}), Range: `bytes=${req.offset}-${end}` };
526
+ }
527
+
528
+ // Set extensions as query params to stale the cache.
529
+ const fetchUrl = (() => {
530
+ if (!terrainExts.length) return req.url;
531
+ const u = new URL(req.url, globalThis.location?.href);
532
+ u.searchParams.set("extensions", terrainExts.join("-"));
533
+ return u.toString();
534
+ })();
535
+
536
+ await fetch(fetchUrl, { signal: abortController.signal, headers })
537
+ .then((res) => {
538
+ // For range reads, require 206 so we don't silently accept a full-body 200
539
+ // response and download an entire PMTiles archive.
540
+ const isRangeRequest = req.offset != null && req.length != null;
541
+ if (isRangeRequest && res.status !== 206) {
542
+ throw new Error(
543
+ `Range request expected 206 Partial Content, got ${res.status} ${res.statusText}`,
544
+ );
545
+ }
546
+
547
+ // A successful range request returns 206 Partial Content, which is in
548
+ // the ok range (200-299), so this guard handles both 200 and 206.
549
+ if (!res.ok) {
550
+ throw new Error(`Request failed with ${res.status} ${res.statusText}`);
551
+ }
552
+ return res.arrayBuffer();
553
+ })
554
+ .then((val) => {
555
+ if (abortController.signal.aborted) {
556
+ return;
557
+ }
558
+
559
+ const bytes = new Uint8Array(val);
560
+ // MVT pbf: with the default delegated worker Rust never reads these
561
+ // bytes — they only travel back out to `processParseMvtTile`. Adopt
562
+ // them into the JS-side store (WASM tracks a byte-count-only `External`
563
+ // handle) so they never round-trip through WASM linear memory. Ownership
564
+ // moves into the store, so do NOT clear `bytes` afterward.
565
+ // Range reads (PMTiles) also arrive with the `mvt` extension but Rust
566
+ // parses those bytes (header/directory/payload), so they must stay
567
+ // WASM-resident.
568
+ const isRangeRequest = req.offset != null && req.length != null;
569
+ if (req.extension === "mvt" && !isRangeRequest) {
570
+ buf.setExternal(req.handle, req.bits, bytes);
571
+ } else {
572
+ buf.setU8(req.handle, req.bits, bytes);
573
+
574
+ // Prevent memory leak
575
+ bytes.set([]);
576
+ }
577
+ })
578
+ .catch(() => {
579
+ buf.triggerDataRequesterFailed(req.bits);
580
+ })
581
+ .finally(() => {
582
+ abortControllers.delete(id);
583
+ });
584
+ }
585
+
586
+ function processDataRequesterRemoved(
587
+ ctx: EventContext,
588
+ req: DataRequesterRemovedEvent,
589
+ ) {
590
+ const { abortControllers, workerPoolPromises, loadedTexs, hillshadeContext } =
591
+ ctx;
592
+ const id = generate_id_from_entity(req);
593
+ const abortController = abortControllers.get(id);
594
+ const workerPool = workerPoolPromises.get(id);
595
+
596
+ // Clean up hillshade resources first (if applicable)
597
+ // For hillshade entities, clearRenderTarget will dispose the RenderTarget and its texture
598
+ if (hillshadeContext) {
599
+ hillshadeContext.pendingEdges.delete(id);
600
+ hillshadeContext.clearTempDem(id);
601
+ hillshadeContext.clearRenderTarget(id);
602
+ }
603
+
604
+ // Dispose and remove texture from loadedTexs
605
+ // For hillshade entities, texture is already disposed by clearRenderTarget above
606
+ // Check isRenderTargetTexture to avoid double-dispose
607
+ if (loadedTexs) {
608
+ const texture = loadedTexs.get(id);
609
+ if (texture && !texture.isRenderTargetTexture) {
610
+ disposeTexture(texture);
611
+ }
612
+ loadedTexs.delete(id);
613
+ }
614
+
615
+ // Note: Do NOT call buf.remove(req.handle) here!
616
+ // The handle is shared among multiple consumers (via Rust DataManager)
617
+ // Rust side manages the lifecycle and will remove data when ref count reaches 0
618
+
619
+ abortController?.abort();
620
+ workerPool?.cancel();
621
+
622
+ abortControllers.delete(id);
623
+ workerPoolPromises.delete(id);
624
+ }
625
+
626
+ async function processTextureFragmentRequested(
627
+ ctx: EventContext,
628
+ req: TextureFragmentRequestedEvent,
629
+ ) {
630
+ const { texFragment, loadedTexs, abortControllers } = ctx;
631
+ const id = generate_id_from_entity(req);
632
+ if (loadedTexs.has(id)) return;
633
+
634
+ const abortController = (() => {
635
+ const a = abortControllers.get(id);
636
+ if (a) {
637
+ return a;
638
+ } else {
639
+ const a = new AbortController();
640
+ abortControllers.set(id, a);
641
+ return a;
642
+ }
643
+ })();
644
+
645
+ await ABORTABLE_TEXTURE_LOADER.loadAsyncWithAbort(req.url, abortController)
646
+ .then((t) => {
647
+ loadedTexs.set(id, t);
648
+ texFragment.triggerTextureFragmentLoaded(
649
+ req.bits,
650
+ TextureFragmentStatus.Success,
651
+ );
652
+ })
653
+ .catch(() => {
654
+ texFragment.triggerTextureFragmentLoaded(
655
+ req.bits,
656
+ TextureFragmentStatus.Fail,
657
+ );
658
+ })
659
+ .finally(() => {
660
+ abortControllers.delete(id);
661
+ });
662
+ }
663
+
664
+ function processTextureFragmentRemoved(ctx: EventContext, req: EntityEvent) {
665
+ const { loadedTexs, abortControllers, hillshadeContext } = ctx;
666
+ const id = generate_id_from_entity(req);
667
+ const abortController = abortControllers.get(id);
668
+
669
+ // Clean up hillshade resources first (if applicable)
670
+ // For hillshade entities, clearRenderTarget will dispose the RenderTarget and its texture
671
+ if (hillshadeContext) {
672
+ hillshadeContext.pendingEdges.delete(id);
673
+ hillshadeContext.clearTempDem(id);
674
+ hillshadeContext.clearRenderTarget(id);
675
+ }
676
+
677
+ // Dispose and remove texture from loadedTexs
678
+ // For hillshade entities, texture is already disposed by clearRenderTarget above
679
+ // Check isRenderTargetTexture to avoid double-dispose
680
+ const texture = loadedTexs.get(id);
681
+ if (texture && !texture.isRenderTargetTexture) {
682
+ disposeTexture(texture);
683
+ }
684
+ loadedTexs.delete(id);
685
+
686
+ abortController?.abort();
687
+ }
688
+
689
+ export function setTransform(
690
+ obj: Object3D,
691
+ transform: Transform,
692
+ keepPosition?: boolean,
693
+ ) {
694
+ const { tx, ty, tz, qx, qy, qz, qw, sx, sy, sz } = transform;
695
+ if (!keepPosition) {
696
+ obj.position.set(tx, ty, tz);
697
+ }
698
+ obj.quaternion.set(qx, qy, qz, qw);
699
+ obj.scale.set(sx, sy, sz);
700
+ }