@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,699 @@
1
+ import type { TileHandle } from "@navaramap/core";
2
+ import {
3
+ PolygonMesh as NavaraPolygonMesh,
4
+ PolygonMaterial,
5
+ } from "@navaramap/engine";
6
+ import type { Texture } from "three";
7
+ import {
8
+ BufferAttribute,
9
+ BufferGeometry,
10
+ Color,
11
+ MeshBasicMaterial,
12
+ MeshLambertMaterial,
13
+ RGBADepthPacking,
14
+ Sphere,
15
+ SphereGeometry,
16
+ Mesh as ThreeMesh,
17
+ Vector3,
18
+ } from "three";
19
+
20
+ import { PolygonOutlineMesh } from "..";
21
+ import type { EventContext } from "../event/context";
22
+ import type { PolygonMaterialProps } from "../material/enhancer/polygon";
23
+ import { createPolygonMaterialEnhancer } from "../material/enhancer/polygon/polygonMaterialEnhancer";
24
+
25
+ import {
26
+ BatchedFeatureMesh,
27
+ POLYGON_BATCH_TEXTURE_ROWS,
28
+ type BatchedFeatureAttributes,
29
+ } from "./batchedFeature";
30
+ import type {
31
+ BatchedAttributeName,
32
+ BatchTextureRowKey,
33
+ DefaultBatchAttributeValues,
34
+ } from "./batchTexture";
35
+ import { releaseGeometryArraysAfterUpload } from "./releaseGeometryArrays";
36
+ import { setupRTECallback } from "./rtcRteHelper";
37
+
38
+ /** Set to true to render bounding spheres as wireframe spheres for debugging. */
39
+ const DEBUG_BOUNDING_SPHERE = false;
40
+
41
+ type Attributes = BatchedFeatureAttributes<{
42
+ position?: BufferAttribute; // Present when use_rte = false
43
+ position_3d_high?: BufferAttribute; // Present when use_rte = true
44
+ position_3d_low?: BufferAttribute; // Present when use_rte = true
45
+ normal: BufferAttribute;
46
+ scaleNormalAndCap: BufferAttribute;
47
+ attrBatchId: BufferAttribute;
48
+ }>;
49
+
50
+ export class PolygonMesh extends BatchedFeatureMesh<
51
+ BufferGeometry<Attributes>,
52
+ MeshLambertMaterial
53
+ > {
54
+ outline?: PolygonOutlineMesh;
55
+
56
+ private _baseBoundingSphere?: {
57
+ surfaceCenter: Vector3; // Center point on ellipsoid surface (without height)
58
+ aabbRadius: number; // Horizontal extent radius from AABB
59
+ };
60
+
61
+ /** Debug wireframe mesh visualizing the bounding sphere */
62
+ private _debugBoundingSphereMesh?: ThreeMesh;
63
+
64
+ /** Running min/max of per-feature batch height values */
65
+ private _minBatchHeight = 0;
66
+ private _maxBatchHeight = 0;
67
+ /** Running max of per-feature batch extruded height values */
68
+ private _maxBatchExtrudedHeight = 0;
69
+
70
+ readonly ctx: EventContext;
71
+ /** Layer ID for SelectiveEffect handling */
72
+ private _layerId: string;
73
+
74
+ /** Enhanced material with encapsulated state */
75
+ private _enhancedMaterial?: ReturnType<typeof createPolygonMaterialEnhancer>;
76
+
77
+ constructor(ctx: EventContext, layerId: string) {
78
+ super(new BufferGeometry<Attributes>(), new MeshLambertMaterial());
79
+
80
+ this.ctx = ctx;
81
+ this._layerId = layerId;
82
+ }
83
+
84
+ ready() {
85
+ return !!this._enhancedMaterial;
86
+ }
87
+
88
+ init(mesh: NavaraPolygonMesh, tileHandle: TileHandle | undefined) {
89
+ this.batchLength = mesh.batch_length;
90
+ // Register cleanup listener first (before any potential early returns)
91
+ // This ensures dispose() is called even if geometry initialization fails
92
+ this.addEventListener("removedFromWorld", () => {
93
+ this.dispose();
94
+ });
95
+
96
+ const { success, useRTE } = this.initGeometry(mesh);
97
+ if (!success) {
98
+ console.warn("PolygonMesh.init: geometry initialization failed");
99
+ return this;
100
+ }
101
+ this.initMaterial(mesh, tileHandle, useRTE);
102
+ this.initDepthMaterial();
103
+
104
+ if (mesh.bounding_sphere) {
105
+ const bs = mesh.bounding_sphere;
106
+
107
+ this._baseBoundingSphere = {
108
+ // If this mesh is tile based, RTC is used. In this case, this mesh is transformed through matrixWorld.
109
+ surfaceCenter: useRTE
110
+ ? new Vector3(bs.center_x, bs.center_y, bs.center_z)
111
+ : new Vector3(),
112
+ aabbRadius: bs.radius,
113
+ };
114
+
115
+ this._recalculateBoundingSphere();
116
+ }
117
+
118
+ return this;
119
+ }
120
+
121
+ clone() {
122
+ const cloned = new PolygonMesh(this.ctx, this._layerId) as this;
123
+ cloned.geometry = this.geometry;
124
+ cloned.material = this.material;
125
+ cloned._enhancedMaterial = this._enhancedMaterial;
126
+ return cloned;
127
+ }
128
+
129
+ private initGeometry(mesh: NavaraPolygonMesh): {
130
+ success: boolean;
131
+ useRTE: boolean;
132
+ } {
133
+ const { buf } = this.ctx;
134
+ const g = mesh.geometry;
135
+
136
+ // Check if RTE attributes are present
137
+ const useRTE =
138
+ g.position_3d_high !== undefined && g.position_3d_high.size > 0;
139
+
140
+ const position =
141
+ !useRTE && g.position ? buf.removeF32(g.position.data) : undefined;
142
+ const position_3d_high =
143
+ useRTE && g.position_3d_high
144
+ ? buf.removeF32(g.position_3d_high.data)
145
+ : undefined;
146
+ const position_3d_low =
147
+ useRTE && g.position_3d_low
148
+ ? buf.removeF32(g.position_3d_low.data)
149
+ : undefined;
150
+ const normal = g.normal ? buf.removeF32(g.normal.data) : undefined;
151
+ const scale_normal_and_cap = g.scale_normal_and_cap
152
+ ? buf.removeF32(g.scale_normal_and_cap.data)
153
+ : undefined;
154
+ const indices = buf.removeU32(g.indices);
155
+ const batchIds = g.batch_ids ? buf.removeF32(g.batch_ids.data) : undefined;
156
+ const batchIdSize = g.batch_ids ? g.batch_ids.size : 0;
157
+ const batchIndex = g.batch_index
158
+ ? buf.removeU32(g.batch_index.data)
159
+ : undefined;
160
+ const batchIndexSize = g.batch_index ? g.batch_index.size : 0;
161
+
162
+ if (!indices) return { success: false, useRTE: false };
163
+ if (!useRTE && !position) return { success: false, useRTE: false };
164
+ if (useRTE && (!position_3d_high || !position_3d_low))
165
+ return { success: false, useRTE: false };
166
+
167
+ const geometry = this.geometry;
168
+
169
+ if (useRTE) {
170
+ // RTE mode: set position_3d_high and position_3d_low
171
+ if (
172
+ position_3d_high &&
173
+ position_3d_low &&
174
+ g.position_3d_high &&
175
+ g.position_3d_low
176
+ ) {
177
+ geometry.setAttribute(
178
+ "position_3d_high",
179
+ new BufferAttribute(position_3d_high, g.position_3d_high.size),
180
+ );
181
+ geometry.setAttribute(
182
+ "position_3d_low",
183
+ new BufferAttribute(position_3d_low, g.position_3d_low.size),
184
+ );
185
+ }
186
+ } else {
187
+ // Regular mode: set position
188
+ if (position && g.position) {
189
+ geometry.setAttribute(
190
+ "position",
191
+ new BufferAttribute(position, g.position.size),
192
+ );
193
+ }
194
+ }
195
+
196
+ if (g.normal && normal) {
197
+ geometry.setAttribute(
198
+ "normal",
199
+ new BufferAttribute(normal, g.normal.size),
200
+ );
201
+ }
202
+ if (g.scale_normal_and_cap && scale_normal_and_cap) {
203
+ geometry.setAttribute(
204
+ "scaleNormalAndCap",
205
+ new BufferAttribute(scale_normal_and_cap, g.scale_normal_and_cap.size),
206
+ );
207
+ }
208
+
209
+ if (batchIds) {
210
+ geometry.setAttribute(
211
+ "attrBatchId",
212
+ new BufferAttribute(batchIds, batchIdSize),
213
+ );
214
+ }
215
+
216
+ if (batchIndex) {
217
+ this._setBatchIndex(Float32Array.from(batchIndex), batchIndexSize);
218
+ }
219
+
220
+ geometry.setIndex(new BufferAttribute(indices, 1));
221
+
222
+ // Ensure a bounding sphere exists before we drop the CPU arrays. When
223
+ // `mesh.bounding_sphere` is provided, init() overwrites this from the
224
+ // WASM AABB (`_baseBoundingSphere`); otherwise this eager compute prevents
225
+ // Three.js from lazily calling computeBoundingSphere() on a nulled array
226
+ // during frustum culling. Batch-id attributes are consumed on the GPU
227
+ // (batch data texture), so no other CPU read survives the first upload.
228
+ // Drop the JS-heap copies to keep a single resident (GPU) copy — see
229
+ // releaseGeometryArraysAfterUpload for the context-loss trade-off.
230
+ geometry.computeBoundingSphere();
231
+ releaseGeometryArraysAfterUpload(geometry);
232
+
233
+ return { success: true, useRTE };
234
+ }
235
+
236
+ /**
237
+ * Get the enhancer, throwing if not initialized.
238
+ * @throws Error if enhancer is not initialized
239
+ */
240
+ private getEnhancer(): NonNullable<typeof this._enhancedMaterial> {
241
+ if (!this._enhancedMaterial) {
242
+ throw new Error("PolygonMesh must be initialized via init() before use");
243
+ }
244
+ return this._enhancedMaterial;
245
+ }
246
+
247
+ private enableWater() {
248
+ if (!this._enhancedMaterial) return;
249
+
250
+ const { base, water } = this._enhancedMaterial.states();
251
+
252
+ // Disable water normal map if water is off or texturized
253
+ if (!water.useWater || base.isTexturized) {
254
+ this._enhancedMaterial.update({ water: { waterNormalMap: null } });
255
+ return;
256
+ }
257
+
258
+ // Skip if not visible or already has water texture
259
+ if (!this.visible || water.waterNormalMap) {
260
+ return;
261
+ }
262
+
263
+ // Use shared water texture from CommonUniforms (must be enabled via Options.waterTexture.enabled)
264
+ if (this.ctx.uniforms?.waterTexture.value) {
265
+ this._enhancedMaterial.update({
266
+ water: { waterNormalMap: this.ctx.uniforms.waterTexture.value },
267
+ });
268
+ this.material.needsUpdate = true;
269
+ }
270
+ }
271
+
272
+ private initMaterial(
273
+ mesh: NavaraPolygonMesh,
274
+ tileHandle: TileHandle | undefined,
275
+ useRTE: boolean,
276
+ ) {
277
+ const uniforms = this.ctx.uniforms;
278
+ const meshMaterial = mesh.material;
279
+ const mcolor = meshMaterial.color;
280
+
281
+ this.castShadow = !!meshMaterial.castShadow;
282
+ this.receiveShadow = !!meshMaterial.receiveShadow;
283
+
284
+ // This mesh is texturized if it has a tile handle (terrain attachment).
285
+ const isTexturized = !!tileHandle;
286
+ const material = this.material;
287
+
288
+ material.vertexColors = false;
289
+ this.visible = !!meshMaterial.show;
290
+
291
+ const uMinMaxHeights = meshMaterial.__internal__?.minMaxHeights;
292
+ const minMaxHeight: [number, number] | undefined = uMinMaxHeights
293
+ ? [uMinMaxHeights[0], uMinMaxHeights[1]]
294
+ : undefined;
295
+
296
+ // Ignored if it is cloned.
297
+ if (!this._enhancedMaterial) {
298
+ // Create enhanced material with encapsulated state
299
+ const enhancer = createPolygonMaterialEnhancer(material);
300
+ this._enhancedMaterial = enhancer;
301
+ }
302
+ const enhancer = this._enhancedMaterial;
303
+
304
+ // Initialize material state with separated base and water props
305
+ const initialProps: PolygonMaterialProps = {
306
+ base: {
307
+ color: mcolor,
308
+ opacity: meshMaterial.opacity,
309
+ transparent: meshMaterial.transparent,
310
+ wireframe: meshMaterial.wireframe,
311
+ minMaxHeight,
312
+ clampToGround: meshMaterial.clampToGround,
313
+ isTexturized,
314
+ reflectivity: meshMaterial.reflectivity,
315
+ roughness: meshMaterial.roughness,
316
+ emissiveColor: meshMaterial.emissiveColor,
317
+ emissiveIntensity: meshMaterial.emissiveIntensity,
318
+ globeNormalTexture: uniforms.tGlobeNormal as { value: Texture | null },
319
+ useRTE,
320
+ },
321
+ water: {
322
+ water: meshMaterial.water,
323
+ waterScaleNormal: meshMaterial.waterScaleNormal,
324
+ waterSpeed: meshMaterial.waterSpeed,
325
+ shininess: meshMaterial.shininess,
326
+ specularStrength: meshMaterial.specularStrength,
327
+ applyWaterNormal: meshMaterial.applyWaterNormal,
328
+ specular: meshMaterial.specular,
329
+ ior: meshMaterial.ior,
330
+ timeUniform: uniforms.time as { value: number },
331
+ skyEnvMap: uniforms.tSkyEnvMap.value,
332
+ },
333
+ };
334
+
335
+ // Mount the enhancer
336
+ enhancer.mount(initialProps);
337
+
338
+ // Set up RTE if needed
339
+ const { base } = enhancer.states();
340
+ if (base.useRTE) {
341
+ const { base: baseMutates } = enhancer.mutates();
342
+ const callback = setupRTECallback(
343
+ this,
344
+ (modelViewMatrixRTE, cameraPositionHigh, cameraPositionLow) =>
345
+ baseMutates.updateRteUniforms(
346
+ modelViewMatrixRTE,
347
+ cameraPositionHigh,
348
+ cameraPositionLow,
349
+ base,
350
+ ),
351
+ );
352
+ this.onBeforeRender = callback;
353
+ this.onBeforeShadow = callback;
354
+ }
355
+
356
+ this.enableWater();
357
+
358
+ // Set up custom program cache key based on config flags that affect shader defines
359
+ material.customProgramCacheKey = enhancer.programCacheKey;
360
+
361
+ // Set up onBeforeCompile using the enhancer's transformShader
362
+ material.onBeforeCompile = enhancer.transformShader;
363
+
364
+ this.ctx.viewContext.applyShadowMaterial(material);
365
+
366
+ this._initBatchedMaterial();
367
+
368
+ this._update(meshMaterial, mesh.active, isTexturized);
369
+ }
370
+
371
+ /**
372
+ * Override a material that is used to generate a shadow map.
373
+ */
374
+ private initDepthMaterial() {
375
+ this.customDepthMaterial = this.material.clone();
376
+ this.customDepthMaterial.needsUpdate = true;
377
+
378
+ const origin = this.material;
379
+
380
+ this.customDepthMaterial.onBeforeCompile = (shader, renderer) => {
381
+ origin.onBeforeCompile(shader, renderer);
382
+
383
+ shader.defines ??= {};
384
+ Object.assign(shader.defines, origin.userData.defines || {});
385
+ shader.defines["USE_SHADOWMAP_DEPTH"] = 1;
386
+ shader.defines["DEPTH_PACKING"] = RGBADepthPacking;
387
+ };
388
+ }
389
+
390
+ _update(material: PolygonMaterial, active: boolean, isTexturized: boolean) {
391
+ const enhancer = this.getEnhancer();
392
+
393
+ // Update mesh properties (not handled by enhancer)
394
+ this.visible =
395
+ (material.show ?? true) && (material.surfaceShow ?? true) && active;
396
+ if (this._debugBoundingSphereMesh) {
397
+ this._debugBoundingSphereMesh.visible = this.visible;
398
+ }
399
+ this.castShadow = !!material.castShadow;
400
+ this.receiveShadow = !!material.receiveShadow;
401
+
402
+ const { base } = enhancer.states();
403
+
404
+ // Build props from material with separated base and water sections
405
+ const minMaxHeights = material.__internal__?.minMaxHeights;
406
+ const updateProps: PolygonMaterialProps = {
407
+ base: {
408
+ // `material.color` is used only when `batchColorEnabled` is `false`.
409
+ // Otherwise the color is update via `setFeatureColor` or the batch data texture.
410
+ color: base.batchColorEnabled ? undefined : material.color,
411
+ opacity: material.opacity,
412
+ transparent: !!material.transparent,
413
+ wireframe: !!material.wireframe,
414
+ minMaxHeight:
415
+ minMaxHeights !== undefined
416
+ ? [minMaxHeights[0], minMaxHeights[1]]
417
+ : undefined,
418
+ clampToGround: !!material.clampToGround,
419
+ isTexturized,
420
+ reflectivity: material.reflectivity,
421
+ roughness: material.roughness,
422
+ emissiveColor: material.emissiveColor,
423
+ emissiveIntensity: material.emissiveIntensity,
424
+ effectIdsMask:
425
+ this.ctx.viewContext.selectiveEffectRegistry?.computeMask(
426
+ material.effectIds ?? [],
427
+ ) ?? 0,
428
+ },
429
+ water: {
430
+ water: !!material.water,
431
+ waterScaleNormal: material.waterScaleNormal,
432
+ waterSpeed: material.waterSpeed,
433
+ shininess: material.shininess,
434
+ specularStrength: material.specularStrength,
435
+ applyWaterNormal: material.applyWaterNormal,
436
+ specular: material.specular,
437
+ ior: material.ior,
438
+ },
439
+ };
440
+
441
+ // Update via enhancer
442
+ enhancer.update(updateProps);
443
+
444
+ // Post-update actions
445
+ this.enableWater();
446
+ this._recalculateBoundingSphere();
447
+ }
448
+
449
+ private _recalculateBoundingSphere() {
450
+ const baseBounds = this._baseBoundingSphere;
451
+ if (!baseBounds || !this._enhancedMaterial) {
452
+ return;
453
+ }
454
+
455
+ if (!this.geometry.boundingSphere) {
456
+ this.geometry.boundingSphere = new Sphere();
457
+ }
458
+
459
+ // Cache values to avoid multiple calls
460
+ const { base } = this._enhancedMaterial.states();
461
+
462
+ if (base.clampToGround) {
463
+ this.geometry.boundingSphere?.set(
464
+ baseBounds.surfaceCenter,
465
+ baseBounds.aabbRadius,
466
+ );
467
+ return;
468
+ }
469
+
470
+ const { addHeight, addExtrudedHeight, minMaxHeight } = base;
471
+
472
+ if (!minMaxHeight) return;
473
+
474
+ // Compute effective min/max considering both uniform and per-feature batch values
475
+ const minHeight = Math.min(
476
+ minMaxHeight[0] + addHeight,
477
+ minMaxHeight[0] + this._minBatchHeight,
478
+ );
479
+ const maxHeight = Math.max(
480
+ minMaxHeight[1] + addHeight + addExtrudedHeight,
481
+ minMaxHeight[1] + this._maxBatchHeight + this._maxBatchExtrudedHeight,
482
+ );
483
+
484
+ const heightOffset = (maxHeight - minHeight) / 2.0;
485
+ const centerHeight = (maxHeight + minHeight) / 2.0;
486
+
487
+ // Get surface normal from surface center
488
+ const surfaceNormal = baseBounds.surfaceCenter.clone().normalize();
489
+
490
+ // Calculate new center by elevating along surface normal
491
+ const center = baseBounds.surfaceCenter
492
+ .clone()
493
+ .add(surfaceNormal.multiplyScalar(centerHeight));
494
+
495
+ // Calculate new radius using Pythagorean theorem
496
+ const radius = Math.sqrt(
497
+ baseBounds.aabbRadius * baseBounds.aabbRadius +
498
+ heightOffset * heightOffset,
499
+ );
500
+
501
+ // Update geometry bounding sphere
502
+ this.geometry.boundingSphere?.set(center, radius);
503
+
504
+ if (DEBUG_BOUNDING_SPHERE) {
505
+ this._updateDebugBoundingSphereMesh(center, radius);
506
+ }
507
+ }
508
+
509
+ private _updateDebugBoundingSphereMesh(center: Vector3, radius: number) {
510
+ if (!this._debugBoundingSphereMesh) {
511
+ const geo = new SphereGeometry(1, 16, 12);
512
+ const mat = new MeshBasicMaterial({
513
+ color: 0x00ff00,
514
+ wireframe: true,
515
+ depthTest: false,
516
+ transparent: true,
517
+ opacity: 0.3,
518
+ });
519
+ this._debugBoundingSphereMesh = new ThreeMesh(geo, mat);
520
+ // this._debugBoundingSphereMesh.frustumCulled = false;
521
+ this.add(this._debugBoundingSphereMesh);
522
+ }
523
+
524
+ this._debugBoundingSphereMesh.position.copy(center);
525
+ this._debugBoundingSphereMesh.scale.setScalar(radius);
526
+ }
527
+
528
+ _getDefaultBatchAttributeValues(): DefaultBatchAttributeValues {
529
+ return {
530
+ color: this.material.color,
531
+ };
532
+ }
533
+
534
+ _setFeatureColor(color: Color): void {
535
+ this.getEnhancer().update({
536
+ base: { batchColorEnabled: true, color: color.getHex() },
537
+ });
538
+ }
539
+
540
+ _setFeatureShow(visible: boolean): void {
541
+ this.visible = visible;
542
+ this.outline?._setFeatureShow(this.outline.visible && visible);
543
+ this.enableWater();
544
+ }
545
+
546
+ onBeforePicking(): void {
547
+ this.getEnhancer().update({ base: { pickable: true } });
548
+ this.needsUpdate();
549
+ }
550
+
551
+ onAfterPicking(): void {
552
+ this.getEnhancer().update({ base: { pickable: false } });
553
+ this.needsUpdate();
554
+ }
555
+
556
+ _updateBatchAttribute(
557
+ batchId: number,
558
+ attribute: BatchedAttributeName,
559
+ value: number | number[] | boolean,
560
+ ): void {
561
+ switch (attribute) {
562
+ case "color": {
563
+ // When batch color is first used, enable batchColorEnabled and set material.color to white
564
+ if (!this.getEnhancer().states().base.batchColorEnabled) {
565
+ // Set material.color to white (multiplier identity) and enable batch color mode
566
+ this.getEnhancer().update({
567
+ base: { batchColorEnabled: true, color: 0xffffff },
568
+ });
569
+ }
570
+ this.getEnhancer().update({ base: { useBatchColorShow: true } });
571
+ this.outline?.enableBatchColorShow();
572
+ break;
573
+ }
574
+ case "show": {
575
+ this.getEnhancer().update({ base: { useBatchColorShow: true } });
576
+ this.outline?.enableBatchColorShow();
577
+ break;
578
+ }
579
+ case "height": {
580
+ this.getEnhancer().update({ base: { useBatchHeight: true } });
581
+ this.outline?.enableBatchHeight();
582
+ const h = value as number;
583
+ if (h > this._maxBatchHeight) this._maxBatchHeight = h;
584
+ if (h < this._minBatchHeight) this._minBatchHeight = h;
585
+ break;
586
+ }
587
+ case "extrudedHeight": {
588
+ this.getEnhancer().update({ base: { useBatchExtrudedHeight: true } });
589
+ this.outline?.enableBatchExtrudedHeight();
590
+ const eh = value as number;
591
+ if (eh > this._maxBatchExtrudedHeight)
592
+ this._maxBatchExtrudedHeight = eh;
593
+ break;
594
+ }
595
+ case "opacity": {
596
+ // Opacity is bundled with show in COLOR_SHOW's alpha channel
597
+ this.getEnhancer().update({ base: { useBatchColorShow: true } });
598
+ break;
599
+ }
600
+ }
601
+
602
+ // Call parent to update the batch texture
603
+ super._updateBatchAttribute(batchId, attribute, value);
604
+
605
+ if (attribute === "height" || attribute === "extrudedHeight") {
606
+ this._recalculateBoundingSphere();
607
+ }
608
+ }
609
+
610
+ _getBatchTextureRows(): BatchTextureRowKey[] {
611
+ // No LINE_WIDTH: the polygon shaders declare no receiver for it,
612
+ // so accepting the attribute would break shader compilation.
613
+ return POLYGON_BATCH_TEXTURE_ROWS;
614
+ }
615
+
616
+ _initBatchDataTexture(): void {
617
+ // Call parent to create the texture
618
+ super._initBatchDataTexture();
619
+
620
+ // Update the enhancer with the new batchDataTexture
621
+ const texture = this._getBatchDataTexture();
622
+ if (texture) {
623
+ this.getEnhancer().update({
624
+ base: { useBatchTexture: true, batchDataTexture: { value: texture } },
625
+ });
626
+ // Share the same batch texture with outline (no duplicate data)
627
+ this.outline?.initBatchTexture(texture);
628
+ }
629
+ }
630
+
631
+ _setFeatureExtrudedHeight(height: number): void {
632
+ this.getEnhancer().update({ base: { addExtrudedHeight: height } });
633
+ this.outline?._setFeatureExtrudedHeight(height);
634
+ this._recalculateBoundingSphere();
635
+ }
636
+
637
+ _setFeatureHeight(height: number): void {
638
+ this.getEnhancer().update({ base: { addHeight: height } });
639
+ this.outline?._setFeatureHeight(height);
640
+ this._recalculateBoundingSphere();
641
+ }
642
+
643
+ get water(): boolean {
644
+ return this.getEnhancer().states().water.useWater;
645
+ }
646
+ set water(v: boolean) {
647
+ this.getEnhancer().update({ water: { water: v } });
648
+ }
649
+
650
+ /** Properties for material state used by TileMesh for texturized scene rendering */
651
+ get waterScaleNormal(): number {
652
+ return this.getEnhancer().states().water.waterScaleNormal;
653
+ }
654
+ get waterSpeed(): number {
655
+ return this.getEnhancer().states().water.waterSpeed;
656
+ }
657
+ get shininess(): number {
658
+ return this.getEnhancer().states().water.shininess;
659
+ }
660
+ get specularStrength(): number {
661
+ return this.getEnhancer().states().water.specularStrength;
662
+ }
663
+ get applyWaterNormal(): boolean {
664
+ return this.getEnhancer().states().water.applyWaterNormal;
665
+ }
666
+ get specular(): boolean {
667
+ return this.getEnhancer().states().water.specular;
668
+ }
669
+ get reflectivity(): number {
670
+ return this.getEnhancer().states().base.reflectivity;
671
+ }
672
+ get roughness(): number {
673
+ return this.getEnhancer().states().base.roughness;
674
+ }
675
+ get clampToGround(): boolean {
676
+ return this.getEnhancer().states().base.clampToGround;
677
+ }
678
+ get emissiveColor(): number {
679
+ return this.getEnhancer().states().base.emissiveColor;
680
+ }
681
+ get emissiveIntensity(): number {
682
+ return this.getEnhancer().states().base.emissiveIntensity;
683
+ }
684
+ get effectIdsMask(): number {
685
+ return this.getEnhancer().states().base.effectIdsMask;
686
+ }
687
+
688
+ dispose() {
689
+ if (this._debugBoundingSphereMesh) {
690
+ this._debugBoundingSphereMesh.geometry.dispose();
691
+ (this._debugBoundingSphereMesh.material as MeshBasicMaterial).dispose();
692
+ this.remove(this._debugBoundingSphereMesh);
693
+ this._debugBoundingSphereMesh = undefined;
694
+ }
695
+
696
+ this.ctx.viewContext.removeShadowMaterial(this.material);
697
+ this.customDepthMaterial?.dispose();
698
+ }
699
+ }