@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,457 @@
1
+ import type { BaseEventMap, XYZ } from "@navaramap/core";
2
+ import { Euler, Matrix4, Object3D, Vector3 } from "three";
3
+ import invariant from "tiny-invariant";
4
+
5
+ import type ThreeView from "../index";
6
+ import type { Scenes } from "../scene";
7
+
8
+ import {
9
+ BaseDesc,
10
+ type BaseInstance,
11
+ type BaseDescConfig,
12
+ type BaseDescConfigUpdate,
13
+ } from "./BaseDesc";
14
+ import type { ViewContext } from "./ViewContext";
15
+
16
+ export type MeshConfig = {
17
+ type?: "mesh";
18
+ /**
19
+ * Local translation. When `matrix` or `matrixWorld` is also set, this is
20
+ * treated as an offset *inside* that frame (left-multiplied by the frame).
21
+ * Otherwise it's applied directly as `Object3D.position`.
22
+ */
23
+ position?: XYZ;
24
+ /**
25
+ * Local scale. See {@link position} for interaction with `matrix` / `matrixWorld`.
26
+ */
27
+ scale?: XYZ;
28
+ /**
29
+ * Local Euler rotation (XYZ order). See {@link position} for interaction
30
+ * with `matrix` / `matrixWorld`.
31
+ */
32
+ rotation?: XYZ;
33
+ /**
34
+ * Local frame. When combined with `position` / `rotation` / `scale`, the
35
+ * effective local matrix is `matrix · T(position) · R(rotation) · S(scale)`.
36
+ * Disables Three.js's auto matrix update.
37
+ */
38
+ matrix?: Matrix4;
39
+ /**
40
+ * World frame (e.g. an NUE-to-ECEF tangent frame on the globe). When
41
+ * combined with `position` / `rotation` / `scale`, the effective world
42
+ * matrix is `matrixWorld · T(position) · R(rotation) · S(scale)`, so the
43
+ * offset fields are interpreted in the frame's local coordinates.
44
+ * Disables Three.js's auto matrix-world update.
45
+ */
46
+ matrixWorld?: Matrix4;
47
+ } & BaseDescConfig;
48
+
49
+ export type MeshUpdate = Pick<
50
+ MeshConfig,
51
+ "position" | "scale" | "rotation" | "matrix" | "matrixWorld"
52
+ > &
53
+ BaseDescConfigUpdate;
54
+
55
+ export type PassKey = keyof Pick<
56
+ Scenes,
57
+ "opaque" | "transparent" | "mrt" | "skyEnvMap" | "draped"
58
+ >;
59
+
60
+ export type MeshBaseInstance<Instance extends object = object> =
61
+ Instance extends Object3D
62
+ ? Instance
63
+ : Instance extends {
64
+ raw: infer Raw extends Object3D;
65
+ }
66
+ ? Instance & { raw: Raw } & BaseInstance
67
+ : Instance & BaseInstance;
68
+
69
+ /**
70
+ * Abstract base class for creating custom mesh descriptors.
71
+ *
72
+ * Extend this class to add custom Three.js 3D objects (meshes, groups, particles, etc.)
73
+ * to the Navara scene. The base class handles position/scale/rotation synchronization
74
+ * and automatic scene management via {@link getPassKey}.
75
+ *
76
+ * ## Implementing a Custom Mesh Descriptor
77
+ *
78
+ * ### 1. Define configuration types
79
+ *
80
+ * Create a description type for your mesh-specific options, then merge it with the
81
+ * base config and update types:
82
+ *
83
+ * ```typescript
84
+ * type MyMeshDescription = {
85
+ * myMesh?: {
86
+ * radius?: number;
87
+ * color?: Color;
88
+ * castShadow?: boolean;
89
+ * };
90
+ * };
91
+ *
92
+ * type MyMeshConfig = MeshConfig & MyMeshDescription;
93
+ * type MyMeshUpdate = MeshUpdate & MyMeshDescription;
94
+ * ```
95
+ *
96
+ * ### 2. Extend `MeshDesc`
97
+ *
98
+ * Implement the {@link createMesh} factory method. Optionally override
99
+ * {@link getPassKey} to control which render scene the mesh belongs to,
100
+ * {@link onUpdateConfig} for dynamic updates, and {@link update} for animation.
101
+ *
102
+ * ```typescript
103
+ * class MyMeshDesc extends MeshDesc<
104
+ * MyMeshConfig,
105
+ * MyMeshUpdate,
106
+ * Mesh<SphereGeometry, MeshStandardMaterial>
107
+ * > {
108
+ * private config: MyMeshConfig;
109
+ *
110
+ * constructor(view: ThreeView, ctx: ViewContext, config: MyMeshConfig) {
111
+ * super(view, ctx, config);
112
+ * this.config = config;
113
+ * }
114
+ *
115
+ * createMesh() {
116
+ * const cfg = this.config.myMesh ?? {};
117
+ * const geometry = new SphereGeometry(cfg.radius ?? 1);
118
+ * const material = new MeshStandardMaterial({
119
+ * color: cfg.color?.raw ?? 0xffffff,
120
+ * });
121
+ * const mesh = new Mesh(geometry, material);
122
+ * mesh.castShadow = cfg.castShadow ?? false;
123
+ *
124
+ * // Enable CSM shadows if needed
125
+ * if (mesh.castShadow) {
126
+ * this.ctx.applyShadowMaterial(material);
127
+ * }
128
+ *
129
+ * return mesh;
130
+ * }
131
+ *
132
+ * onUpdateConfig(updates: MyMeshUpdate): void {
133
+ * if (updates.myMesh && this._instance) {
134
+ * if (updates.myMesh.color !== undefined) {
135
+ * this._instance.material.color.set(updates.myMesh.color.raw);
136
+ * }
137
+ * this.emit("needsUpdate");
138
+ * }
139
+ * super.onUpdateConfig(updates);
140
+ * }
141
+ * }
142
+ * ```
143
+ *
144
+ * ### 3. Register and use the descriptor
145
+ *
146
+ * ```typescript
147
+ * view.registerMesh("myMesh", MyMeshDesc);
148
+ *
149
+ * const handle = view.addMesh<MyMeshDesc>({
150
+ * position: { x: 0, y: 100, z: 0 },
151
+ * scale: { x: 10, y: 10, z: 10 },
152
+ * rotation: { x: 0, y: Math.PI / 4, z: 0 },
153
+ * myMesh: { radius: 5, color: new Color("#00ff00") },
154
+ * });
155
+ *
156
+ * // Update dynamically
157
+ * handle.update({ myMesh: { color: new Color("#ff0000") } });
158
+ *
159
+ * // Access the raw Three.js object for direct manipulation
160
+ * const mesh = handle.ref.raw;
161
+ *
162
+ * // Animate on every frame
163
+ * view.on("preUpdate", (time) => {
164
+ * mesh.rotation.y += 0.01;
165
+ * });
166
+ *
167
+ * // Remove the descriptor
168
+ * handle.delete();
169
+ * ```
170
+ *
171
+ * ## Render Scenes (Pass Keys)
172
+ *
173
+ * Override {@link getPassKey} to control which render scene the mesh is added to:
174
+ * - `"opaque"` (default) - Standard opaque rendering with depth testing.
175
+ * - `"transparent"` - Transparent rendering pass.
176
+ * - `"mrt"` - Multiple Render Target scene, used for selective effects (bloom, outline).
177
+ * - `"skyEnvMap"` - Sky environment map scene.
178
+ * - `"draped"` - This is only for `DrapedMesh`. The mesh is clamped to the terrain.
179
+ *
180
+ * ## Lifecycle
181
+ *
182
+ * 1. **Construction** - The descriptor is instantiated with the view context and config.
183
+ * 2. **{@link createMesh}** - Called during {@link onCreate} to create the Three.js object.
184
+ * The base class applies position/scale/rotation and adds it to the scene
185
+ * determined by {@link getPassKey}.
186
+ * 3. **{@link onUpdateConfig}** - Called when `handle.update()` is invoked. The base class
187
+ * handles `visible`, `matrix`, `matrixWorld`, `position`, `scale`, and `rotation`; override to handle your
188
+ * custom properties. Always call `super.onUpdateConfig(updates)`.
189
+ * 4. **{@link update}** - Optional per-frame callback for animation.
190
+ * 5. **{@link onResize}** - Optional callback when the viewport is resized.
191
+ * 6. **{@link onDestroy}** - Called on `handle.delete()`. The base class removes the mesh
192
+ * from its parent scene. Override to dispose geometry/material resources.
193
+ *
194
+ * @see The `custom-shader` example page for a complete custom mesh descriptor tutorial using
195
+ * MarchingCubes with a custom shader material.
196
+ *
197
+ * @typeParam Config - Configuration type (extends {@link MeshConfig})
198
+ * @typeParam UpdateConfig - Updatable properties (extends {@link MeshUpdate})
199
+ * @typeParam InstanceObj - The Three.js Object3D type or a wrapper with a `raw` property
200
+ * @typeParam CustomEvent - Additional custom events the descriptor can emit
201
+ * @typeParam Instance - Resolved instance type (inferred automatically)
202
+ */
203
+ export abstract class MeshDesc<
204
+ Config extends MeshConfig = MeshConfig,
205
+ UpdateConfig extends MeshUpdate = MeshUpdate,
206
+ InstanceObj extends Object3D | { raw: Object3D } =
207
+ | Object3D
208
+ | { raw: Object3D },
209
+ CustomEvent extends BaseEventMap = BaseEventMap,
210
+ Instance extends MeshBaseInstance<InstanceObj> =
211
+ MeshBaseInstance<InstanceObj>,
212
+ > extends BaseDesc<Config, UpdateConfig, Instance, CustomEvent> {
213
+ public position?: XYZ;
214
+ public scale?: XYZ;
215
+ public rotation?: XYZ;
216
+ public matrix?: Matrix4;
217
+ public matrixWorld?: Matrix4;
218
+ private prevPassKey?: PassKey;
219
+
220
+ constructor(view: ThreeView, ctx: ViewContext, config?: Config) {
221
+ const resolvedConfig = config ?? ({} as Config);
222
+ super(view, ctx, resolvedConfig);
223
+ this.position = resolvedConfig.position;
224
+ this.scale = resolvedConfig.scale;
225
+ this.rotation = resolvedConfig.rotation;
226
+ this.matrix = resolvedConfig.matrix;
227
+ this.matrixWorld = resolvedConfig.matrixWorld;
228
+ }
229
+
230
+ /**
231
+ * Determines which render scene the mesh is added to.
232
+ * Override this to change the rendering pass for your mesh.
233
+ *
234
+ * @returns The pass key: `"opaque"` (default), `"transparent"`, `"mrt"`, or `"skyEnvMap"`.
235
+ */
236
+ protected getPassKey(): PassKey {
237
+ return "opaque";
238
+ }
239
+
240
+ /**
241
+ * Factory method to create the Three.js 3D object.
242
+ *
243
+ * Override this to return your custom mesh. The returned object can be
244
+ * either a Three.js `Object3D` directly (e.g. `Mesh`, `Group`, `Points`) or
245
+ * a wrapper object with a `raw` property containing the `Object3D`.
246
+ *
247
+ * The base class calls this during {@link onCreate} and automatically
248
+ * applies position, scale, rotation, and adds the object to the appropriate
249
+ * scene. Picking is opt-in: if your layer supports it, construct a
250
+ * {@link PickableMesh} here and register it yourself via
251
+ * `this.ctx.registerPickableMesh(this.id, wrapper)` before returning.
252
+ */
253
+ abstract createMesh(): Instance;
254
+
255
+ get raw() {
256
+ if (!this._instance) return;
257
+
258
+ if (this._instance instanceof Object3D) {
259
+ return this._instance as Instance extends Object3D ? Instance : never;
260
+ }
261
+ if ("raw" in this._instance) {
262
+ return this._instance.raw as Instance extends {
263
+ raw: infer Raw extends Object3D;
264
+ }
265
+ ? Raw
266
+ : never;
267
+ }
268
+ return;
269
+ }
270
+
271
+ onCreate() {
272
+ this._instance = this.createMesh();
273
+ invariant(this.raw);
274
+
275
+ this.applyTransform();
276
+
277
+ this._instance.visible = this.visible;
278
+
279
+ this.onPassKeyChange();
280
+ }
281
+
282
+ /**
283
+ * Composes position, rotation, and scale into a local `T · R · S` matrix.
284
+ * Returns identity when none are set.
285
+ */
286
+ protected composeLocalTransform(): Matrix4 {
287
+ const local = new Matrix4();
288
+ if (this.position) {
289
+ local.multiply(
290
+ new Matrix4().makeTranslation(
291
+ this.position.x,
292
+ this.position.y,
293
+ this.position.z,
294
+ ),
295
+ );
296
+ }
297
+ if (this.rotation) {
298
+ local.multiply(
299
+ new Matrix4().makeRotationFromEuler(
300
+ new Euler(this.rotation.x, this.rotation.y, this.rotation.z),
301
+ ),
302
+ );
303
+ }
304
+ if (this.scale) {
305
+ local.scale(new Vector3(this.scale.x, this.scale.y, this.scale.z));
306
+ }
307
+ return local;
308
+ }
309
+
310
+ /**
311
+ * Applies the configured transform to the underlying `Object3D`.
312
+ *
313
+ * When `matrixWorld` (or `matrix`) is set together with any of
314
+ * `position` / `rotation` / `scale`, the base/frame is left-multiplied
315
+ * by the local `T · R · S`: e.g. `effective = matrixWorld · T · R · S`.
316
+ * This lets callers pass a frame (such as an NUE-to-ECEF matrix) as
317
+ * `matrixWorld` and express offsets inside that frame via
318
+ * `position` / `rotation` / `scale`.
319
+ */
320
+ private applyTransform(): void {
321
+ invariant(this.raw);
322
+ const hasLocal =
323
+ this.position != null || this.rotation != null || this.scale != null;
324
+
325
+ if (this.matrixWorld) {
326
+ this.raw.matrixAutoUpdate = false;
327
+ this.raw.matrixWorldAutoUpdate = false;
328
+ if (hasLocal) {
329
+ this.raw.matrixWorld.multiplyMatrices(
330
+ this.matrixWorld,
331
+ this.composeLocalTransform(),
332
+ );
333
+ } else {
334
+ this.raw.matrixWorld.copy(this.matrixWorld);
335
+ }
336
+ this.raw.updateMatrixWorld();
337
+ return;
338
+ }
339
+
340
+ if (this.matrix) {
341
+ this.raw.matrixAutoUpdate = false;
342
+ if (hasLocal) {
343
+ this.raw.matrix.multiplyMatrices(
344
+ this.matrix,
345
+ this.composeLocalTransform(),
346
+ );
347
+ } else {
348
+ this.raw.matrix.copy(this.matrix);
349
+ }
350
+ return;
351
+ }
352
+
353
+ if (this.position) this.raw.position.copy(this.position);
354
+ if (this.scale) this.raw.scale.copy(this.scale);
355
+ if (this.rotation)
356
+ this.raw.rotation.set(this.rotation.x, this.rotation.y, this.rotation.z);
357
+ }
358
+
359
+ removeFromScene(passKey: PassKey) {
360
+ const scenes = this.ctx.scenes;
361
+
362
+ if (scenes[passKey] && this.raw) {
363
+ scenes[passKey].remove(this.raw);
364
+ }
365
+ }
366
+
367
+ addToScene(passKey: PassKey) {
368
+ if (!this.raw) return;
369
+
370
+ const scenes = this.ctx.scenes;
371
+
372
+ if (scenes[passKey]) {
373
+ scenes[passKey].add(this.raw);
374
+ }
375
+ }
376
+
377
+ onUpdateConfig(updates: UpdateConfig): void {
378
+ super.onUpdateConfig(updates);
379
+ invariant(this.raw);
380
+
381
+ const spatialChanged =
382
+ updates.matrix !== undefined ||
383
+ updates.matrixWorld !== undefined ||
384
+ updates.position !== undefined ||
385
+ updates.scale !== undefined ||
386
+ updates.rotation !== undefined;
387
+
388
+ if (updates.matrix !== undefined) this.matrix = updates.matrix;
389
+ if (updates.matrixWorld !== undefined)
390
+ this.matrixWorld = updates.matrixWorld;
391
+ if (updates.position !== undefined) this.position = updates.position;
392
+ if (updates.scale !== undefined) this.scale = updates.scale;
393
+ if (updates.rotation !== undefined) this.rotation = updates.rotation;
394
+
395
+ if (spatialChanged) {
396
+ // With a frame present, the effective transform depends on the
397
+ // combination of all stored fields — recompose the whole thing.
398
+ // Without a frame, apply only the fields that were actually passed,
399
+ // so subclasses that strip a field from `updates` (e.g. GLTFModelLayer
400
+ // keeping `raw.position` at 0 for its RTE shader) can still opt out
401
+ // of having the base class copy it onto `raw`.
402
+ if (this.matrixWorld || this.matrix) {
403
+ this.applyTransform();
404
+ } else {
405
+ if (updates.position !== undefined) {
406
+ this.raw.position.copy(updates.position);
407
+ }
408
+ if (updates.scale !== undefined) {
409
+ this.raw.scale.copy(updates.scale);
410
+ }
411
+ if (updates.rotation !== undefined) {
412
+ this.raw.rotation.set(
413
+ updates.rotation.x,
414
+ updates.rotation.y,
415
+ updates.rotation.z,
416
+ );
417
+ }
418
+ }
419
+ }
420
+
421
+ this.onPassKeyChange();
422
+ }
423
+
424
+ onPassKeyChange() {
425
+ const nextPassKey = this.getPassKey();
426
+ if (this.prevPassKey === nextPassKey) return;
427
+ if (this.prevPassKey) {
428
+ this.removeFromScene(this.prevPassKey);
429
+ }
430
+ this.prevPassKey = nextPassKey;
431
+ this.addToScene(nextPassKey);
432
+ }
433
+
434
+ onDestroy(): void {
435
+ if (this.raw && this.raw.parent) {
436
+ this.raw.parent.remove(this.raw);
437
+ }
438
+
439
+ super.onDestroy();
440
+ }
441
+
442
+ /**
443
+ * Optional per-frame update callback.
444
+ * Override this to animate the mesh (e.g. rotation, morph targets, shader uniforms).
445
+ * @param time - High-resolution timestamp from the main render loop (same value passed
446
+ * to `requestAnimationFrame`), in milliseconds.
447
+ */
448
+ update?(time: number): void;
449
+
450
+ /**
451
+ * Optional callback when the viewport is resized.
452
+ * Override this to adjust the mesh based on viewport dimensions.
453
+ * @param width - New viewport width in pixels.
454
+ * @param height - New viewport height in pixels.
455
+ */
456
+ onResize?(width: number, height: number): void;
457
+ }
@@ -0,0 +1,32 @@
1
+ import type ThreeView from "../index";
2
+
3
+ import type { AnyMeshDesc } from "./BaseHandle";
4
+ import { DescRegistry } from "./DescRegistry";
5
+ import type { MeshConfig } from "./MeshDesc";
6
+ import type { ViewContext } from "./ViewContext";
7
+
8
+ export type AnyMeshConfig = MeshConfig;
9
+
10
+ export type MeshDescConstructor<TConfig extends AnyMeshConfig = AnyMeshConfig> =
11
+ new (view: ThreeView, ctx: ViewContext, config: TConfig) => AnyMeshDesc;
12
+
13
+ export class MeshDescRegistry extends DescRegistry<
14
+ MeshDescConstructor,
15
+ AnyMeshDesc,
16
+ AnyMeshConfig
17
+ > {
18
+ create(name: string, config: AnyMeshConfig): AnyMeshDesc {
19
+ const MeshClass = this.getConstructor(name);
20
+ if (!MeshClass) {
21
+ throw new Error(`Unknown mesh type: ${name}`);
22
+ }
23
+ return new MeshClass(this.view, this.ctx, config);
24
+ }
25
+
26
+ /**
27
+ * Find mesh type from config (alias for findTypeFromConfig for backward compatibility)
28
+ */
29
+ findMeshType(config: Record<string, unknown>): string | null {
30
+ return this.findTypeFromConfig(config);
31
+ }
32
+ }
@@ -0,0 +1,129 @@
1
+ import type { BaseEventMap } from "@navaramap/core";
2
+ import { Mesh, type Object3D } from "three";
3
+
4
+ import type ThreeView from "../index";
5
+ import { arraysEqual } from "../utils";
6
+
7
+ import {
8
+ MeshDesc,
9
+ type MeshConfig,
10
+ type MeshUpdate,
11
+ type MeshBaseInstance,
12
+ type PassKey,
13
+ } from "./MeshDesc";
14
+ import type { ViewContext } from "./ViewContext";
15
+
16
+ export type MeshConfigWithSelectiveEffect = MeshConfig & {
17
+ effectIds?: string[];
18
+ };
19
+
20
+ export type MeshUpdateWithSelectiveEffect = MeshUpdate & {
21
+ effectIds?: string[];
22
+ };
23
+
24
+ export abstract class MeshDescWithSelectiveEffect<
25
+ Config extends MeshConfigWithSelectiveEffect = MeshConfigWithSelectiveEffect,
26
+ UpdateConfig extends MeshUpdateWithSelectiveEffect =
27
+ MeshUpdateWithSelectiveEffect,
28
+ InstanceObj extends Object3D | { raw: Object3D } =
29
+ | Object3D
30
+ | { raw: Object3D },
31
+ CustomEvent extends BaseEventMap = BaseEventMap,
32
+ Instance extends MeshBaseInstance<InstanceObj> =
33
+ MeshBaseInstance<InstanceObj>,
34
+ > extends MeshDesc<Config, UpdateConfig, InstanceObj, CustomEvent, Instance> {
35
+ protected _effectIds: string[] = [];
36
+ private _onSlotsChanged = () => {
37
+ this.updateEffectIdsMask();
38
+ // Slot count changes can flip the pass returned by getPassKey()
39
+ // (mrt <-> opaque), so re-evaluate scene placement.
40
+ this.onPassKeyChange();
41
+ };
42
+
43
+ constructor(view: ThreeView, ctx: ViewContext, config?: Config) {
44
+ const resolvedConfig = config ?? ({} as Config);
45
+ super(view, ctx, resolvedConfig);
46
+ this._effectIds = resolvedConfig.effectIds ?? [];
47
+ }
48
+
49
+ protected override getPassKey(): PassKey {
50
+ // When at least one selective effect is registered on this view, all
51
+ // SE-capable meshes must share the MRT depth/color path so the depth
52
+ // ordering between SE participants stays consistent — an empty
53
+ // effectIds list still has to coexist with non-empty siblings, and is
54
+ // expressed by effectIdsMask=0 rather than by falling back to opaque.
55
+ // When no effect is registered, MRT participation is pure overhead, so
56
+ // defer to the parent's default (opaque) pass.
57
+ if (this.ctx.selectiveEffectRegistry.slotCount > 0) {
58
+ return "mrt";
59
+ }
60
+ return super.getPassKey();
61
+ }
62
+
63
+ override onCreate() {
64
+ super.onCreate();
65
+
66
+ // Compute and set effectIdsMask on material uniforms
67
+ this.updateEffectIdsMask();
68
+
69
+ // Recompute mask when slot assignments change (effect added/removed)
70
+ this.ctx.on("effectSlotsChanged", this._onSlotsChanged);
71
+ }
72
+
73
+ override onUpdateConfig(updates: UpdateConfig): void {
74
+ // ----------------------------------------------------------------------------
75
+ // SelectiveEffect: effectIds update
76
+ // Sync _effectIds before delegating to super so any downstream handler
77
+ // observing the descriptor sees the new value.
78
+ // ----------------------------------------------------------------------------
79
+ let effectIdsChanged = false;
80
+
81
+ if (updates.effectIds !== undefined) {
82
+ const nextEffectIds = updates.effectIds ?? [];
83
+
84
+ if (!arraysEqual(this._effectIds, nextEffectIds)) {
85
+ this._effectIds = [...nextEffectIds];
86
+ effectIdsChanged = true;
87
+ }
88
+ }
89
+
90
+ super.onUpdateConfig(updates);
91
+
92
+ if (effectIdsChanged) {
93
+ // Recompute effectIdsMask for material uniforms.
94
+ this.updateEffectIdsMask();
95
+ }
96
+ }
97
+
98
+ /**
99
+ * Compute effectIdsMask and set on the mesh's material.
100
+ * Override this for non-standard mesh structures (e.g., Object3D with child meshes).
101
+ */
102
+ protected updateEffectIdsMask(): void {
103
+ const registry = this.ctx.selectiveEffectRegistry;
104
+ if (!registry) return;
105
+
106
+ const mask =
107
+ this._effectIds.length > 0 ? registry.computeMask(this._effectIds) : 0;
108
+ const raw = this.raw;
109
+ if (
110
+ raw instanceof Mesh &&
111
+ !Array.isArray(raw.material) &&
112
+ raw.material?.userData?.uEffectIdsMask
113
+ ) {
114
+ raw.material.userData.uEffectIdsMask.value = mask;
115
+ }
116
+ }
117
+
118
+ override onDestroy(): void {
119
+ // ----------------------------------------------------------------------------
120
+ // SelectiveEffect: cleanup
121
+ // ----------------------------------------------------------------------------
122
+ this._effectIds = [];
123
+
124
+ // Unsubscribe from slot changes
125
+ this.ctx.off("effectSlotsChanged", this._onSlotsChanged);
126
+
127
+ super.onDestroy();
128
+ }
129
+ }
@@ -0,0 +1,59 @@
1
+ import type ThreeView from "../index";
2
+
3
+ import { EffectDescRegistry } from "./EffectDescRegistry";
4
+ import { LightDescRegistry } from "./LightDescRegistry";
5
+ import { MeshDescRegistry } from "./MeshDescRegistry";
6
+ import type { ViewContext } from "./ViewContext";
7
+ // import { ResourceRegistry } from "./ResourceRegistry"; // TODO: Implement when needed
8
+
9
+ /**
10
+ * Centralized registry manager that bundles all registry types.
11
+ * This provides direct property access to different types of registries
12
+ * in the Navara system.
13
+ */
14
+ export class Registries {
15
+ mesh: MeshDescRegistry;
16
+ light: LightDescRegistry;
17
+ effect: EffectDescRegistry;
18
+ // resource: ResourceRegistry; // TODO: Implement when needed
19
+ // pass: PassRegistry; // TODO: Implement when needed
20
+ // material: MaterialRegistry; // TODO: Implement when needed
21
+ // shader: ShaderRegistry; // TODO: Implement when needed
22
+
23
+ constructor(view: ThreeView, ctx: ViewContext) {
24
+ this.mesh = new MeshDescRegistry(view, ctx);
25
+ this.light = new LightDescRegistry(view, ctx);
26
+ this.effect = new EffectDescRegistry(view, ctx);
27
+ }
28
+
29
+ /**
30
+ * Get registry statistics for debugging and monitoring
31
+ */
32
+ getStats() {
33
+ return {
34
+ mesh: {
35
+ registeredCount: this.mesh.size(),
36
+ types: this.mesh.getRegisteredTypes(),
37
+ },
38
+ light: {
39
+ registeredCount: this.light.size(),
40
+ types: this.light.getRegisteredTypes(),
41
+ },
42
+ effect: {
43
+ registeredCount: this.effect.size(),
44
+ types: this.effect.getRegisteredTypes(),
45
+ },
46
+ // TODO: Add other registries when implemented
47
+ };
48
+ }
49
+
50
+ /**
51
+ * Clear all registries
52
+ */
53
+ clearAll(): void {
54
+ this.mesh.clear();
55
+ this.light.clear();
56
+ this.effect.clear();
57
+ // TODO: Clear other registries when implemented
58
+ }
59
+ }