@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,523 @@
1
+ import {
2
+ PolylineMesh as NavaraPolylineMesh,
3
+ PolylineMaterial,
4
+ } from "@navaramap/engine";
5
+ import {
6
+ BufferAttribute,
7
+ BufferGeometry,
8
+ Color,
9
+ Matrix4,
10
+ ShaderMaterial,
11
+ Vector2,
12
+ } from "three";
13
+
14
+ import type { EventContext } from "../event/context";
15
+ import { createPolylineMaterialEnhancer } from "../material/enhancer";
16
+
17
+ import {
18
+ BatchedFeatureMesh,
19
+ POLYLINE_BATCH_TEXTURE_ROWS,
20
+ type BatchedFeatureAttributes,
21
+ } from "./batchedFeature";
22
+ import type {
23
+ BatchedAttributeName,
24
+ BatchTextureRowKey,
25
+ DefaultBatchAttributeValues,
26
+ } from "./batchTexture";
27
+ import { releaseGeometryArraysAfterUpload } from "./releaseGeometryArrays";
28
+ import { setupRTECallback } from "./rtcRteHelper";
29
+
30
+ // Sentinel value for picking coordinate when not picking (reused to avoid allocations)
31
+ const PICKING_COORD_SENTINEL = new Vector2(-1, -1);
32
+
33
+ type Attributes = BatchedFeatureAttributes<{
34
+ position: BufferAttribute;
35
+ // RTE mode attributes (only present when useRTE=true)
36
+ position_3d_high?: BufferAttribute;
37
+ position_3d_low?: BufferAttribute;
38
+ start_3d_high?: BufferAttribute;
39
+ start_3d_low?: BufferAttribute;
40
+ end_3d_high?: BufferAttribute;
41
+ end_3d_low?: BufferAttribute;
42
+ // Non-RTE mode attributes (only present when useRTE=false)
43
+ start?: BufferAttribute;
44
+ forward_offset?: BufferAttribute;
45
+ // Common attributes (present for non-flat polylines)
46
+ start_normal?: BufferAttribute;
47
+ end_normal_and_texture_coordinate_normalization_x?: BufferAttribute;
48
+ // Always present
49
+ right_normal_and_texture_coordinate_normalization_y: BufferAttribute;
50
+ attrBatchId: BufferAttribute;
51
+ }>;
52
+
53
+ export class PolylineMesh extends BatchedFeatureMesh<
54
+ BufferGeometry<Attributes>,
55
+ ShaderMaterial
56
+ > {
57
+ readonly ctx: EventContext;
58
+ /** Material enhancer for managing shader state */
59
+ private _enhancedMaterial?: ReturnType<typeof createPolylineMaterialEnhancer>;
60
+ /** Flag indicating geometry initialization failed - mesh should never be visible */
61
+ private _geometryInitFailed = false;
62
+
63
+ constructor(ctx: EventContext) {
64
+ super(new BufferGeometry<Attributes>(), new ShaderMaterial());
65
+ this.ctx = ctx;
66
+ }
67
+
68
+ init(mesh: NavaraPolylineMesh) {
69
+ this.batchLength = mesh.batch_length;
70
+ const geometryResult = this.initGeometry(mesh);
71
+
72
+ // If geometry init failed (missing required buffers), mark as permanently invisible
73
+ if (!geometryResult.success) {
74
+ console.warn(
75
+ "PolylineMesh: Failed to initialize geometry due to missing required buffers. Mesh will be permanently invisible.",
76
+ );
77
+ this._geometryInitFailed = true;
78
+ this.visible = false;
79
+ }
80
+
81
+ this.initMaterial(mesh, geometryResult.useRTE);
82
+
83
+ this.addEventListener("removedFromWorld", () => {
84
+ this.dispose();
85
+ });
86
+
87
+ return this;
88
+ }
89
+
90
+ private initGeometry(
91
+ mesh: NavaraPolylineMesh,
92
+ ): { success: true; useRTE: boolean } | { success: false; useRTE: false } {
93
+ const { buf } = this.ctx;
94
+ const g = mesh.geometry;
95
+ const position = buf.removeF32(g.position.data);
96
+ const position_high = g.position_high
97
+ ? buf.removeF32(g.position_high.data)
98
+ : null;
99
+ const position_low = g.position_low
100
+ ? buf.removeF32(g.position_low.data)
101
+ : null;
102
+ const start_high = g.start_high ? buf.removeF32(g.start_high.data) : null;
103
+ const start_low = g.start_low ? buf.removeF32(g.start_low.data) : null;
104
+ const end_high = g.end_high ? buf.removeF32(g.end_high.data) : null;
105
+ const end_low = g.end_low ? buf.removeF32(g.end_low.data) : null;
106
+ const start_normals = g.start_normals
107
+ ? buf.removeF32(g.start_normals.data)
108
+ : null;
109
+ const end_normal_and_texture_coordinate_normalization_x =
110
+ g.end_normal_and_texture_coordinate_normalization_x
111
+ ? buf.removeF32(
112
+ g.end_normal_and_texture_coordinate_normalization_x.data,
113
+ )
114
+ : null;
115
+ const right_normal_and_texture_coordinate_normalization_y = buf.removeF32(
116
+ g.right_normal_and_texture_coordinate_normalization_y.data,
117
+ );
118
+ const indices = buf.removeU32(g.indices);
119
+ const batchIds = g.batch_ids ? buf.removeF32(g.batch_ids.data) : undefined;
120
+ const batchIdSize = g.batch_ids ? g.batch_ids.size : 0;
121
+ const batchIndex = g.batch_index
122
+ ? buf.removeU32(g.batch_index.data)
123
+ : undefined;
124
+ const batchIndexSize = g.batch_index ? g.batch_index.size : 0;
125
+
126
+ if (
127
+ !position ||
128
+ !right_normal_and_texture_coordinate_normalization_y ||
129
+ !indices
130
+ ) {
131
+ return { success: false, useRTE: false };
132
+ }
133
+
134
+ const geometry = this.geometry;
135
+ const useRTE = !!(
136
+ position_high &&
137
+ position_low &&
138
+ start_high &&
139
+ start_low &&
140
+ end_high &&
141
+ end_low
142
+ );
143
+
144
+ geometry.setAttribute(
145
+ "position",
146
+ new BufferAttribute(position, g.position.size),
147
+ );
148
+
149
+ if (useRTE) {
150
+ // RTE attributes
151
+ if (position_high && position_low) {
152
+ geometry.setAttribute(
153
+ "position_3d_high",
154
+ new BufferAttribute(position_high, 3),
155
+ );
156
+ geometry.setAttribute(
157
+ "position_3d_low",
158
+ new BufferAttribute(position_low, 3),
159
+ );
160
+ }
161
+ if (start_high && start_low) {
162
+ geometry.setAttribute(
163
+ "start_3d_high",
164
+ new BufferAttribute(start_high, 3),
165
+ );
166
+ geometry.setAttribute(
167
+ "start_3d_low",
168
+ new BufferAttribute(start_low, 3),
169
+ );
170
+ }
171
+ if (end_high && end_low) {
172
+ geometry.setAttribute("end_3d_high", new BufferAttribute(end_high, 3));
173
+ geometry.setAttribute("end_3d_low", new BufferAttribute(end_low, 3));
174
+ }
175
+ } else if (g.start && g.forward_offset) {
176
+ const start = buf.removeF32(g.start.data);
177
+ const forward_offset = buf.removeF32(g.forward_offset.data);
178
+
179
+ if (!start || !forward_offset) {
180
+ return { success: false, useRTE: false };
181
+ }
182
+
183
+ // Non-RTE mode: use regular start attribute
184
+ geometry.setAttribute("start", new BufferAttribute(start, g.start.size));
185
+
186
+ geometry.setAttribute(
187
+ "forward_offset",
188
+ new BufferAttribute(forward_offset, g.forward_offset.size),
189
+ );
190
+ }
191
+
192
+ if (start_normals && g.start_normals) {
193
+ geometry.setAttribute(
194
+ "start_normal",
195
+ new BufferAttribute(start_normals, g.start_normals.size),
196
+ );
197
+ }
198
+ if (
199
+ end_normal_and_texture_coordinate_normalization_x &&
200
+ g.end_normal_and_texture_coordinate_normalization_x
201
+ ) {
202
+ geometry.setAttribute(
203
+ "end_normal_and_texture_coordinate_normalization_x",
204
+ new BufferAttribute(
205
+ end_normal_and_texture_coordinate_normalization_x,
206
+ g.end_normal_and_texture_coordinate_normalization_x.size,
207
+ ),
208
+ );
209
+ }
210
+ geometry.setAttribute(
211
+ "right_normal_and_texture_coordinate_normalization_y",
212
+ new BufferAttribute(
213
+ right_normal_and_texture_coordinate_normalization_y,
214
+ g.right_normal_and_texture_coordinate_normalization_y.size,
215
+ ),
216
+ );
217
+
218
+ if (batchIds) {
219
+ geometry.setAttribute(
220
+ "attrBatchId",
221
+ new BufferAttribute(batchIds, batchIdSize),
222
+ );
223
+ }
224
+
225
+ if (batchIndex) {
226
+ this._setBatchIndex(Float32Array.from(batchIndex), batchIndexSize);
227
+ }
228
+
229
+ geometry.setIndex(new BufferAttribute(indices, 1));
230
+ // geometry.computeVertexNormals();
231
+
232
+ // The renderer lazily calls computeBoundingSphere(), which reads
233
+ // position.array, for every polyline: non-RTE ones through frustum culling
234
+ // (RTE disables it below), and ALL of them through depth sorting —
235
+ // renderer.sortObjects reads geometry.boundingSphere even when
236
+ // frustumCulled is false. Compute it eagerly so that read happens before
237
+ // we drop the CPU arrays. In RTE mode `position` still holds the f32
238
+ // world-space coordinates, so the resulting sphere is valid.
239
+ geometry.computeBoundingSphere();
240
+
241
+ // With the bounding sphere resolved and batch-id data consumed on the GPU,
242
+ // no CPU read survives the first upload. Drop the JS-heap copies to keep a
243
+ // single resident (GPU) copy — see releaseGeometryArraysAfterUpload for the
244
+ // context-loss trade-off.
245
+ releaseGeometryArraysAfterUpload(geometry);
246
+
247
+ return { success: true, useRTE };
248
+ }
249
+
250
+ private initMaterial(mesh: NavaraPolylineMesh, useRTE: boolean) {
251
+ const { uniforms } = this.ctx;
252
+ const meshMaterial = mesh.material;
253
+
254
+ const [minHeight, maxHeight] = meshMaterial.__internal__?.minMaxHeights ?? [
255
+ 0, 0,
256
+ ];
257
+
258
+ this.castShadow = !!meshMaterial.castShadow;
259
+ this.receiveShadow = !!meshMaterial.receiveShadow;
260
+
261
+ const isTexturized = mesh.should_be_texturized;
262
+
263
+ // Shader selection is handled by enhancer's transformShader
264
+ this.material.depthTest = false;
265
+
266
+ // Disable lighting for texturized rendering - the texture will be applied to the lit tile
267
+ this.material.lights = !isTexturized;
268
+ this.material.vertexColors = false;
269
+
270
+ // Ignored if it is cloned.
271
+ if (!this._enhancedMaterial) {
272
+ // Create enhanced material with encapsulated state
273
+ const enhancer = createPolylineMaterialEnhancer(this.material);
274
+ this._enhancedMaterial = enhancer;
275
+ }
276
+ const enhancer = this._enhancedMaterial;
277
+
278
+ enhancer.mount({
279
+ base: {
280
+ color: meshMaterial.color,
281
+ minMaxHeight: [minHeight, maxHeight],
282
+ addHeight: meshMaterial.height ?? 0,
283
+ width: meshMaterial.width,
284
+ maxWidth: meshMaterial.maxWidth,
285
+ isTexturized,
286
+ pickable: false,
287
+ useRTE,
288
+ transparent: meshMaterial.transparent,
289
+ opacity: meshMaterial.opacity,
290
+ depthWrite: meshMaterial.depthWrite,
291
+ // External shared uniforms from CommonUniforms
292
+ viewportAndPixelRatio: uniforms.viewportAndPixelRatio,
293
+ frustumNearFar: uniforms.frustumNearFar,
294
+ frustumRatio: uniforms.frustumRatio,
295
+ },
296
+ });
297
+
298
+ // Initialize enhancer uniforms early so they're available before onBeforeCompile
299
+ const mutates = enhancer.mutates();
300
+ mutates.updateUniforms(this.material.uniforms, enhancer.states());
301
+
302
+ // Set up RTE callback if needed
303
+ const state = enhancer.states();
304
+ if (state.useRTE) {
305
+ const mutates = enhancer.mutates();
306
+ const callback = setupRTECallback(
307
+ this,
308
+ (modelViewMatrixRTE, cameraPositionHigh, cameraPositionLow) =>
309
+ mutates.updateRteUniforms(
310
+ modelViewMatrixRTE,
311
+ cameraPositionHigh,
312
+ cameraPositionLow,
313
+ state,
314
+ ),
315
+ new Matrix4(),
316
+ new Matrix4(),
317
+ );
318
+ this.onBeforeRender = callback;
319
+ this.onBeforeShadow = callback;
320
+
321
+ // Disable frustum culling for RTE mode
322
+ this.frustumCulled = false;
323
+ }
324
+
325
+ // Set up custom program cache key based on config flags that affect shader defines
326
+ this.material.customProgramCacheKey = enhancer.programCacheKey;
327
+
328
+ // Set onBeforeCompile to use enhancer
329
+ this.material.onBeforeCompile = enhancer.transformShader;
330
+
331
+ this.ctx.viewContext.applyShadowMaterial(this.material);
332
+
333
+ this._initBatchedMaterial();
334
+
335
+ this._update(meshMaterial, mesh.active);
336
+ }
337
+
338
+ _getBatchTextureRows(): BatchTextureRowKey[] {
339
+ // No EXTRUDED_HEIGHT: the polyline shaders declare no receiver for it,
340
+ // so accepting the attribute would break shader compilation.
341
+ return POLYLINE_BATCH_TEXTURE_ROWS;
342
+ }
343
+
344
+ _initBatchDataTexture(): void {
345
+ // Call parent to create the texture
346
+ super._initBatchDataTexture();
347
+
348
+ // Update the enhancer with the new batchDataTexture
349
+ const texture = this._getBatchDataTexture();
350
+ if (texture) {
351
+ this.getEnhancer().update({
352
+ base: { useBatchTexture: true, batchDataTexture: { value: texture } },
353
+ });
354
+ }
355
+ }
356
+
357
+ /**
358
+ * Keep enhancer state in sync with batch-attribute usage so that
359
+ * customProgramCacheKey reflects the correct shader configuration.
360
+ *
361
+ * This mirrors PolygonMesh._updateBatchAttribute: when batch color
362
+ * is first enabled, also enable batchColorEnabled and set color to white.
363
+ */
364
+ _updateBatchAttribute(
365
+ batchId: number,
366
+ attribute: BatchedAttributeName,
367
+ value: number | number[] | boolean,
368
+ ): void {
369
+ switch (attribute) {
370
+ case "color": {
371
+ // When batch color is first used, enable batchColorEnabled and set material.color to white
372
+ if (!this.getEnhancer().states().batchColorEnabled) {
373
+ // Set material.color to white (multiplier identity) and enable batch color mode
374
+ this.getEnhancer().update({
375
+ base: { batchColorEnabled: true, color: 0xffffff },
376
+ });
377
+ }
378
+ this.getEnhancer().update({ base: { useBatchColorShow: true } });
379
+ break;
380
+ }
381
+ case "show": {
382
+ this.getEnhancer().update({ base: { useBatchColorShow: true } });
383
+ break;
384
+ }
385
+ case "height":
386
+ this.getEnhancer().update({ base: { useBatchHeight: true } });
387
+ break;
388
+ case "lineWidth":
389
+ this.getEnhancer().update({ base: { useBatchLineWidth: true } });
390
+ break;
391
+ }
392
+
393
+ // Call parent to update the batch texture
394
+ super._updateBatchAttribute(batchId, attribute, value);
395
+ }
396
+
397
+ _update(material: PolylineMaterial, active: boolean) {
398
+ // If geometry initialization failed, keep mesh permanently invisible
399
+ // to prevent WebGL errors from missing attributes/buffers
400
+ if (this._geometryInitFailed) {
401
+ this.visible = false;
402
+ return;
403
+ }
404
+
405
+ const enhancer = this.getEnhancer();
406
+
407
+ // Update mesh properties (not handled by enhancer)
408
+ this.visible = (material.show ?? true) && active;
409
+ this.castShadow = !!material.castShadow;
410
+ this.receiveShadow = !!material.receiveShadow;
411
+
412
+ const base = enhancer.states();
413
+
414
+ // Build update props from material
415
+ const minMaxHeights = material.__internal__?.minMaxHeights;
416
+ enhancer.update({
417
+ base: {
418
+ // `material.color` is used only when `batchColorEnabled` is `false`.
419
+ // Otherwise the color is updated via `_setFeatureColor` or the batch data texture.
420
+ color: base.batchColorEnabled ? undefined : material.color,
421
+ minMaxHeight:
422
+ minMaxHeights !== undefined
423
+ ? [minMaxHeights[0], minMaxHeights[1]]
424
+ : undefined,
425
+ addHeight: material.height,
426
+ width: material.width,
427
+ maxWidth: material.maxWidth,
428
+ transparent: material.transparent,
429
+ opacity: material.opacity,
430
+ depthWrite: material.depthWrite,
431
+ effectIdsMask:
432
+ this.ctx.viewContext.selectiveEffectRegistry?.computeMask(
433
+ material.effectIds ?? [],
434
+ ) ?? 0,
435
+ emissiveColor: material.emissiveColor ?? 0,
436
+ emissiveIntensity: material.emissiveIntensity ?? 0,
437
+ },
438
+ });
439
+
440
+ // Update material.lights flag based on isTexturized state
441
+ // (lighting should be disabled for texturized/draped polylines)
442
+ this.material.lights = !base.isTexturized;
443
+ }
444
+
445
+ /**
446
+ * Get the enhancer, throwing if not initialized.
447
+ * @throws Error if enhancer is not initialized
448
+ */
449
+ private getEnhancer(): NonNullable<typeof this._enhancedMaterial> {
450
+ if (!this._enhancedMaterial) {
451
+ throw new Error(
452
+ "PolylineMesh material enhancer is not initialized. This usually indicates a failure during construction or geometry/material setup.",
453
+ );
454
+ }
455
+ return this._enhancedMaterial;
456
+ }
457
+
458
+ get color() {
459
+ return this.material.uniforms.color.value;
460
+ }
461
+
462
+ get draped(): boolean {
463
+ return this.getEnhancer().states().isTexturized;
464
+ }
465
+
466
+ get emissiveColor(): number {
467
+ return this.getEnhancer().states().emissiveColor;
468
+ }
469
+ get emissiveIntensity(): number {
470
+ return this.getEnhancer().states().emissiveIntensity;
471
+ }
472
+ get effectIdsMask(): number {
473
+ return this.getEnhancer().states().effectIdsMask;
474
+ }
475
+
476
+ onBeforePicking(pickingCoord?: Vector2) {
477
+ this.getEnhancer().update({ base: { pickable: true } });
478
+ this.needsUpdate();
479
+
480
+ const mutates = this.getEnhancer().mutates();
481
+ if (pickingCoord) {
482
+ mutates.setPickingCoord(pickingCoord);
483
+ } else {
484
+ mutates.setPickingCoord(PICKING_COORD_SENTINEL);
485
+ }
486
+ }
487
+
488
+ onAfterPicking() {
489
+ this.getEnhancer().update({ base: { pickable: false } });
490
+ this.needsUpdate();
491
+ this.getEnhancer().mutates().setPickingCoord(PICKING_COORD_SENTINEL);
492
+ }
493
+
494
+ _getDefaultBatchAttributeValues(): DefaultBatchAttributeValues {
495
+ return {
496
+ color: this.color,
497
+ };
498
+ }
499
+
500
+ _setFeatureColor(color: Color): void {
501
+ // Called by evaluator to override feature color
502
+ // Set batchColorEnabled=true to prevent _update() from overwriting with material.color
503
+ this.getEnhancer().update({
504
+ base: { batchColorEnabled: true, color: color.getHex() },
505
+ });
506
+ }
507
+
508
+ _setFeatureShow(visible: boolean): void {
509
+ this.visible = visible;
510
+ }
511
+
512
+ clone() {
513
+ const cloned = new PolylineMesh(this.ctx) as this;
514
+ cloned.geometry = this.geometry;
515
+ cloned.material = this.material;
516
+ cloned._enhancedMaterial = this._enhancedMaterial;
517
+ return cloned;
518
+ }
519
+
520
+ dispose() {
521
+ this.ctx.viewContext.removeShadowMaterial(this.material);
522
+ }
523
+ }
@@ -0,0 +1,57 @@
1
+ import {
2
+ type BufferAttribute,
3
+ type BufferGeometry,
4
+ InterleavedBufferAttribute,
5
+ } from "three";
6
+
7
+ /**
8
+ * After the first GPU upload, drop the CPU-side typed array of a
9
+ * `BufferAttribute` so it is not kept resident on the JS heap alongside the GPU
10
+ * copy. This is the standard Three.js `onUpload` idiom (`this.array = null`).
11
+ *
12
+ * IMPORTANT: once released, the attribute can no longer be re-uploaded — a
13
+ * WebGL context loss will NOT be able to restore it. Our geometry is
14
+ * WASM-sourced and re-fetched on demand rather than re-uploaded, and the memory
15
+ * ledger (`GPU_GEOMETRY_RESIDENCY_FACTOR`) now assumes exactly one resident
16
+ * (GPU) copy, so this trade-off is intentional. Only apply it to attributes
17
+ * whose `.array` is not re-read on the CPU after upload (bounding volumes must
18
+ * already be computed/assigned; batch/feature-id arrays must be consumed at
19
+ * setup time, not lazily).
20
+ */
21
+ function disposeArray(this: BufferAttribute) {
22
+ // Three.js types `array` as a readonly typed array; null is the documented
23
+ // sentinel that frees it after upload.
24
+ (this as unknown as { array: unknown }).array = null;
25
+ }
26
+
27
+ /**
28
+ * Attach {@link disposeArray} to a single attribute (idempotent).
29
+ *
30
+ * Interleaved attributes are skipped: an `InterleavedBufferAttribute` (produced
31
+ * by `GLTFLoader` for interleaved bufferViews) has no `onUpload` method — only
32
+ * its shared underlying `InterleavedBuffer` does — and multiple attributes
33
+ * share one buffer, so releasing through it is unsafe without per-buffer
34
+ * dedupe. Skipping them keeps interleaved glTF/3D Tiles models rendering
35
+ * correctly at the cost of the array-release optimization for those attributes.
36
+ */
37
+ export function releaseAttributeAfterUpload(
38
+ attribute: BufferAttribute | InterleavedBufferAttribute | null | undefined,
39
+ ): void {
40
+ if (!attribute) return;
41
+ if (attribute instanceof InterleavedBufferAttribute) return;
42
+ attribute.onUpload(disposeArray);
43
+ }
44
+
45
+ /**
46
+ * Attach the post-upload CPU-array release to every attribute and the index of
47
+ * a geometry. Safe to call once per geometry after all CPU-side reads
48
+ * (bounding volumes, batch-id extraction) are done and before first render.
49
+ */
50
+ export function releaseGeometryArraysAfterUpload(
51
+ geometry: BufferGeometry,
52
+ ): void {
53
+ for (const attribute of Object.values(geometry.attributes)) {
54
+ releaseAttributeAfterUpload(attribute);
55
+ }
56
+ releaseAttributeAfterUpload(geometry.index);
57
+ }