@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
package/package.json ADDED
@@ -0,0 +1,95 @@
1
+ {
2
+ "name": "@navaramap/three",
3
+ "type": "module",
4
+ "version": "0.0.0",
5
+ "main": "dist/index.umd.cjs",
6
+ "module": "dist/index.js",
7
+ "types": "dist/index.d.ts",
8
+ "files": [
9
+ "src",
10
+ "dist"
11
+ ],
12
+ "license": "MIT OR Apache-2.0",
13
+ "repository": {
14
+ "type": "git",
15
+ "url": "git+https://github.com/eukarya-inc/navara.git",
16
+ "directory": "web/navara_three"
17
+ },
18
+ "publishConfig": {
19
+ "access": "public"
20
+ },
21
+ "peerDependencies": {
22
+ "postprocessing": ">=6.38.0",
23
+ "three": ">=0.183.0"
24
+ },
25
+ "dependencies": {
26
+ "@takram/three-atmosphere": "0.19.1",
27
+ "@takram/three-clouds": "0.7.6",
28
+ "@takram/three-geospatial": "0.9.1",
29
+ "@takram/three-geospatial-effects": "0.6.4",
30
+ "astronomy-engine": "2.1.19",
31
+ "stats.js": "0.17.0",
32
+ "three-stdlib": "2.36.1",
33
+ "@navaramap/core": "0.0.0",
34
+ "@navaramap/worker": "0.0.0",
35
+ "@navaramap/engine": "0.0.0",
36
+ "@navaramap/font": "0.0.0",
37
+ "@navaramap/engine-api": "0.0.0",
38
+ "@navaramap/three_csm": "0.0.0",
39
+ "@navaramap/three_api": "0.0.0"
40
+ },
41
+ "devDependencies": {
42
+ "@playwright/test": "1.59.1",
43
+ "@radix-ui/react-collapsible": "1.1.12",
44
+ "@radix-ui/react-label": "2.1.8",
45
+ "@radix-ui/react-select": "2.2.6",
46
+ "@radix-ui/react-separator": "1.1.8",
47
+ "@radix-ui/react-slider": "1.3.6",
48
+ "@radix-ui/react-slot": "1.2.4",
49
+ "@radix-ui/react-switch": "1.2.6",
50
+ "@tailwindcss/postcss": "4.2.2",
51
+ "@tweakpane/core": "2.0.5",
52
+ "@types/geojson": "7946.0.16",
53
+ "@types/stats.js": "0.17.4",
54
+ "@types/three": "0.184.0",
55
+ "ajv": "8.20.0",
56
+ "class-variance-authority": "0.7.1",
57
+ "clsx": "2.1.1",
58
+ "dayjs": "1.11.20",
59
+ "lucide-react": "1.14.0",
60
+ "playwright": "1.59.1",
61
+ "postcss": "8.5.9",
62
+ "postprocessing": "6.38.3",
63
+ "sharp": "0.34.5",
64
+ "shiki": "4.3.1",
65
+ "tailwind-merge": "3.5.0",
66
+ "tailwindcss": "4.2.2",
67
+ "tailwindcss-animate": "1.0.7",
68
+ "three": "0.184.0",
69
+ "tsx": "4.21.0",
70
+ "tweakpane": "4.0.5",
71
+ "vite-plugin-glsl": "1.6.0",
72
+ "vite-plugin-static-copy": "4.1.0",
73
+ "@navaramap/three_default_descs": "0.0.0",
74
+ "@navaramap/three_default_plugin": "0.0.0",
75
+ "@navaramap/three_plugins": "0.0.0",
76
+ "@navaramap/three_react": "0.0.0"
77
+ },
78
+ "scripts": {
79
+ "start": "vite",
80
+ "dev": "vite -c vite.config.example.ts --host",
81
+ "type-check": "tsc && tsc -p tsconfig.node.json",
82
+ "build": "pnpm type-check && vite build -c vite.config.ts",
83
+ "build:dev": "vite build --mode development",
84
+ "build:dev:watch": "pnpm build:dev --watch",
85
+ "build:iife": "vite build -c vite.config.iife.ts",
86
+ "build:example": "tsc && vite build -c vite.config.example.ts",
87
+ "preview": "vite preview",
88
+ "test": "vitest --passWithNoTests --watch=false",
89
+ "lint": "eslint . --fix",
90
+ "lint:check": "eslint .",
91
+ "format": "prettier --write --ignore-path ../../.gitignore --ignore-path ../../.prettierignore .",
92
+ "format:check": "prettier --check --ignore-path ../../.gitignore --ignore-path ../../.prettierignore .",
93
+ "screenshots": "tsx scripts/generate-screenshots.ts"
94
+ }
95
+ }
package/src/Color.ts ADDED
@@ -0,0 +1,111 @@
1
+ import { Color as CoreColor } from "@navaramap/core";
2
+ import { NoColorSpace, SRGBColorSpace, Color as ThreeColor } from "three";
3
+
4
+ /**
5
+ * Class representing a color.
6
+ * This class assumes that the specified color represents the sRGB color space.
7
+ *
8
+ * ```
9
+ * const red = new Color().setRGB(1.0, 0.0, 0.0);
10
+ * const green = new Color().setHex(0x00ff00);
11
+ * const blue = new Color().setStyle("#0000ff");
12
+ * ```
13
+ */
14
+ export class Color implements CoreColor {
15
+ #color = new ThreeColor();
16
+
17
+ /**
18
+ * Sets the color using RGB values in sRGB color space.
19
+ * @param r - Red component (0.0 to 1.0)
20
+ * @param g - Green component (0.0 to 1.0)
21
+ * @param b - Blue component (0.0 to 1.0)
22
+ * @returns This color instance for chaining
23
+ */
24
+ setRGB(r: number, g: number, b: number) {
25
+ this.#color.setRGB(r, g, b, SRGBColorSpace);
26
+ return this;
27
+ }
28
+
29
+ /**
30
+ * Sets the color using RGB values in linear color space (no gamma correction).
31
+ * @param r - Red component (0.0 to 1.0)
32
+ * @param g - Green component (0.0 to 1.0)
33
+ * @param b - Blue component (0.0 to 1.0)
34
+ * @returns This color instance for chaining
35
+ */
36
+ setRGBLinear(r: number, g: number, b: number) {
37
+ this.#color.setRGB(r, g, b, NoColorSpace);
38
+ return this;
39
+ }
40
+
41
+ /**
42
+ * Sets the color from a hexadecimal value in sRGB color space.
43
+ * @param hex - Hexadecimal color value (e.g., 0xff0000 for red)
44
+ * @returns This color instance for chaining
45
+ */
46
+ setHex(hex: number) {
47
+ this.#color.setHex(hex, SRGBColorSpace);
48
+ return this;
49
+ }
50
+
51
+ /**
52
+ * Sets the color from a CSS style string in sRGB color space.
53
+ * @param style - CSS color string (e.g., "#ff0000", "rgb(255, 0, 0)", "red")
54
+ * @returns This color instance for chaining
55
+ */
56
+ setStyle(style: string) {
57
+ this.#color.setStyle(style, SRGBColorSpace);
58
+ return this;
59
+ }
60
+
61
+ /**
62
+ * Copies this color's values to another Color instance.
63
+ * @param color - Target color to copy values into
64
+ * @returns The target color with copied values
65
+ */
66
+ copy(color: Color) {
67
+ color.#color = this.#color.clone();
68
+ return color as this;
69
+ }
70
+
71
+ /**
72
+ * Creates a new Color instance with the same values.
73
+ * @returns A new Color instance
74
+ */
75
+ clone() {
76
+ return this.copy(new Color());
77
+ }
78
+
79
+ /**
80
+ * Returns the color as an RGB array.
81
+ * @returns Tuple of [red, green, blue] values (0.0 to 1.0)
82
+ */
83
+ toArray(): [r: number, g: number, b: number] {
84
+ return this.#color.toArray() as [r: number, g: number, b: number];
85
+ }
86
+
87
+ /**
88
+ * Converts the color from linear to sRGB color space.
89
+ * @returns A new Color instance in sRGB color space
90
+ */
91
+ srgb() {
92
+ const copy = new Color();
93
+ copy.#color = new ThreeColor().copyLinearToSRGB(this.#color);
94
+ return copy as this;
95
+ }
96
+
97
+ /**
98
+ * Returns the color as a hexadecimal number.
99
+ * @returns Hexadecimal color value (e.g., 0xff0000 for red)
100
+ */
101
+ toHex(): number {
102
+ return this.#color.getHex();
103
+ }
104
+
105
+ /**
106
+ * Gets the underlying Three.js Color instance.
107
+ */
108
+ get raw() {
109
+ return this.#color;
110
+ }
111
+ }
@@ -0,0 +1,49 @@
1
+ import { CascadedDirectionalLights } from "@navaramap/three_csm";
2
+ import type { WebGLRenderer } from "three";
3
+ import { ShadowMapViewer } from "three-stdlib";
4
+
5
+ import type { Scenes } from "./scene";
6
+
7
+ export class ShadowMapViewers {
8
+ viewers: ShadowMapViewer[] = [];
9
+ lights: Scenes["light"];
10
+ enabled = false;
11
+
12
+ constructor(lights: Scenes["light"]) {
13
+ this.lights = lights;
14
+ }
15
+
16
+ render(renderer: WebGLRenderer) {
17
+ if (!this.enabled || !renderer.shadowMap.enabled) return;
18
+
19
+ // Create shadow map viewers for debugging
20
+ const csm = this.lights.children.find(
21
+ (c) => c instanceof CascadedDirectionalLights,
22
+ );
23
+
24
+ if (
25
+ this.viewers.length &&
26
+ csm?.cascadedLights.length === this.viewers.length
27
+ ) {
28
+ this.viewers.forEach((viewer) => {
29
+ if (viewer) {
30
+ viewer.render(renderer);
31
+ }
32
+ });
33
+ return;
34
+ }
35
+
36
+ this.viewers.length = 0;
37
+
38
+ if (!csm) return;
39
+ const lights = csm.cascadedLights;
40
+ lights.forEach((light, i) => {
41
+ if (light.shadow.map && light.shadow.map.texture) {
42
+ const viewer = new ShadowMapViewer(light);
43
+ viewer.position.set(0, 100 * i);
44
+ viewer.size.set(100, 100);
45
+ this.viewers.push(viewer);
46
+ }
47
+ });
48
+ }
49
+ }
@@ -0,0 +1,76 @@
1
+ import type { WebGLRenderer } from "three";
2
+ import { beforeEach, describe, expect, it, vi } from "vitest";
3
+
4
+ import { Atmosphere } from "./atmosphere";
5
+
6
+ const { loadAsyncMock } = vi.hoisted(() => ({
7
+ loadAsyncMock: vi.fn(),
8
+ }));
9
+
10
+ vi.mock("@takram/three-atmosphere", () => ({
11
+ PrecomputedTexturesLoader: class {
12
+ setType() {
13
+ return this;
14
+ }
15
+ loadAsync = loadAsyncMock;
16
+ },
17
+ getSunDirectionECEF: vi.fn(),
18
+ getMoonDirectionECEF: vi.fn(),
19
+ getECIToECEFRotationMatrix: vi.fn(),
20
+ }));
21
+
22
+ const createAtmosphere = () =>
23
+ new Atmosphere({} as unknown as WebGLRenderer, { date: new Date(0) });
24
+
25
+ const fakeTextures = () => ({}) as never;
26
+
27
+ describe("Atmosphere.initTextures", () => {
28
+ beforeEach(() => {
29
+ loadAsyncMock.mockReset();
30
+ });
31
+
32
+ it("shares a single load across concurrent calls", async () => {
33
+ loadAsyncMock.mockResolvedValue(fakeTextures());
34
+ const atmosphere = createAtmosphere();
35
+
36
+ await Promise.all([atmosphere.initTextures(), atmosphere.initTextures()]);
37
+
38
+ expect(loadAsyncMock).toHaveBeenCalledTimes(1);
39
+ expect(atmosphere.textures).toBeDefined();
40
+ });
41
+
42
+ it("returns immediately once textures are loaded", async () => {
43
+ loadAsyncMock.mockResolvedValue(fakeTextures());
44
+ const atmosphere = createAtmosphere();
45
+
46
+ await atmosphere.initTextures();
47
+ await atmosphere.initTextures();
48
+
49
+ expect(loadAsyncMock).toHaveBeenCalledTimes(1);
50
+ });
51
+
52
+ it("emits textureLoaded exactly once", async () => {
53
+ loadAsyncMock.mockResolvedValue(fakeTextures());
54
+ const atmosphere = createAtmosphere();
55
+ const onLoaded = vi.fn();
56
+ atmosphere.on("textureLoaded", onLoaded);
57
+
58
+ await Promise.all([atmosphere.initTextures(), atmosphere.initTextures()]);
59
+
60
+ expect(onLoaded).toHaveBeenCalledTimes(1);
61
+ });
62
+
63
+ it("allows retrying after a failed load", async () => {
64
+ loadAsyncMock.mockRejectedValueOnce(new Error("network error"));
65
+ loadAsyncMock.mockResolvedValueOnce(fakeTextures());
66
+ const atmosphere = createAtmosphere();
67
+
68
+ await expect(atmosphere.initTextures()).rejects.toThrow("network error");
69
+ expect(atmosphere.textures).toBeUndefined();
70
+
71
+ await atmosphere.initTextures();
72
+
73
+ expect(loadAsyncMock).toHaveBeenCalledTimes(2);
74
+ expect(atmosphere.textures).toBeDefined();
75
+ });
76
+ });
@@ -0,0 +1,364 @@
1
+ import { EventHandler, Observed, type XYZ } from "@navaramap/core";
2
+ import {
3
+ getECIToECEFRotationMatrix,
4
+ getMoonDirectionECEF,
5
+ getSunDirectionECEF,
6
+ PrecomputedTexturesLoader,
7
+ type AtmosphereOverlay,
8
+ type AtmosphereShadow,
9
+ type AtmosphereShadowLength,
10
+ type PrecomputedTextures,
11
+ } from "@takram/three-atmosphere";
12
+ import { Vector3, Matrix4, type WebGLRenderer } from "three";
13
+ import invariant from "tiny-invariant";
14
+
15
+ import { type ThreeViewCamera } from "./camera";
16
+ import { ATMOSPHERE_ASSETS_URL, STBN_URL } from "./constants";
17
+ import { shiftDateToElevation, shiftDateToHourAngle } from "./solar";
18
+
19
+ /**
20
+ * Events emitted by the {@link Atmosphere} class.
21
+ */
22
+ export type AtmosphereEvents = {
23
+ /** Emitted when the atmosphere needs to trigger a re-render. */
24
+ needsUpdate: () => void;
25
+ /** Emitted when precomputed atmosphere textures have been loaded. */
26
+ textureLoaded: () => void;
27
+ /** Emitted when the atmosphere is disposed. */
28
+ disposed: () => void;
29
+ /** Emitted when the sun direction changes. */
30
+ sunChanged: (sunDirection: Vector3) => void;
31
+ };
32
+
33
+ /**
34
+ * Configuration options for the {@link Atmosphere} class.
35
+ */
36
+ export type AtmosphereOptions = {
37
+ /** URL to load precomputed atmosphere textures from. */
38
+ atmosphereAssetsUrl?: string;
39
+ /** URL to load STBN (Spatio-Temporal Blue Noise) textures from. */
40
+ stbnUrl?: string;
41
+ /** Date used for calculating sun/moon positions. Defaults to current date. */
42
+ date?: Date;
43
+ };
44
+
45
+ /**
46
+ * Default values for {@link AtmosphereOptions}.
47
+ */
48
+ export const DEFAULT_ATMOSPHERE_OPTIONS: Required<AtmosphereOptions> = {
49
+ atmosphereAssetsUrl: ATMOSPHERE_ASSETS_URL,
50
+ stbnUrl: STBN_URL,
51
+ date: new Date(),
52
+ };
53
+
54
+ /**
55
+ * Context for atmosphere rendering.
56
+ *
57
+ * Manages sun/moon positions, precomputed atmosphere textures, and related state.
58
+ * Some variables are shared with Clouds and AerialPerspective.
59
+ */
60
+ export class Atmosphere extends EventHandler<AtmosphereEvents> {
61
+ /**
62
+ * @private
63
+ */
64
+ private renderer: WebGLRenderer;
65
+
66
+ /**
67
+ * Current sun direction in ECEF coordinates.
68
+ */
69
+ sunDirection = new Vector3();
70
+
71
+ /**
72
+ * Current moon direction in ECEF coordinates.
73
+ */
74
+ moonDirection = new Vector3();
75
+
76
+ /**
77
+ * @private
78
+ */
79
+ private rotationMatrix = new Matrix4();
80
+
81
+ /**
82
+ * Precomputed atmosphere textures used for rendering.
83
+ * Loaded asynchronously via {@link initTextures}.
84
+ */
85
+ textures?: PrecomputedTextures;
86
+
87
+ // Variables that come from Clouds.
88
+ overlay = new Observed<AtmosphereOverlay | null>(null);
89
+ shadow = new Observed<AtmosphereShadow | null>(null);
90
+ shadowLength = new Observed<AtmosphereShadowLength | null>(null);
91
+ enableShadows = new Observed<boolean>(true);
92
+
93
+ /**
94
+ * @private
95
+ */
96
+ private needsUpdate = false;
97
+
98
+ /**
99
+ * @private
100
+ */
101
+ private options: AtmosphereOptions;
102
+
103
+ /**
104
+ * @private
105
+ */
106
+ private _camera: ThreeViewCamera | undefined;
107
+
108
+ /**
109
+ * In-flight texture loading promise, shared across concurrent
110
+ * {@link initTextures} calls so the assets are fetched only once.
111
+ * @private
112
+ */
113
+ private texturesPromise: Promise<void> | undefined;
114
+
115
+ /**
116
+ * Creates a new Atmosphere instance.
117
+ * @param renderer - The WebGL renderer used for texture type detection.
118
+ * @param options - Configuration options for the atmosphere.
119
+ * @param camera - Camera reference used by {@link setDateAt}.
120
+ */
121
+ constructor(
122
+ renderer: WebGLRenderer,
123
+ options: AtmosphereOptions = {},
124
+ camera?: ThreeViewCamera,
125
+ ) {
126
+ super();
127
+
128
+ this.renderer = renderer;
129
+ this.options = { ...DEFAULT_ATMOSPHERE_OPTIONS, ...options };
130
+ this._camera = camera;
131
+
132
+ this.onUpdate();
133
+ }
134
+
135
+ /**
136
+ * Marks the atmosphere as needing an update.
137
+ * @private
138
+ */
139
+ onUpdate = () => {
140
+ this.needsUpdate = true;
141
+ this.emit("needsUpdate");
142
+ };
143
+
144
+ /**
145
+ * Loads precomputed atmosphere textures asynchronously.
146
+ * If textures are already loaded, this method returns immediately.
147
+ * @returns A promise that resolves when textures are loaded.
148
+ */
149
+ // TODO: Add an option to disable loading textures.
150
+ async initTextures() {
151
+ if (this.textures) return;
152
+
153
+ this.texturesPromise ??= new PrecomputedTexturesLoader()
154
+ .setType(this.renderer)
155
+ .loadAsync(
156
+ this.options.atmosphereAssetsUrl ??
157
+ DEFAULT_ATMOSPHERE_OPTIONS.atmosphereAssetsUrl,
158
+ )
159
+ .then((textures) => {
160
+ this.textures = textures;
161
+ this.emit("textureLoaded");
162
+ })
163
+ .finally(() => {
164
+ // Allow retrying after a failed load instead of caching the rejection.
165
+ this.texturesPromise = undefined;
166
+ });
167
+
168
+ await this.texturesPromise;
169
+ }
170
+
171
+ /**
172
+ * @private
173
+ */
174
+ async _init() {
175
+ await this.initTextures();
176
+ }
177
+
178
+ /**
179
+ * @private
180
+ */
181
+ _dispose() {
182
+ if (this.textures) {
183
+ this.textures.irradianceTexture.dispose();
184
+ this.textures.scatteringTexture.dispose();
185
+ this.textures.transmittanceTexture.dispose();
186
+ this.textures.singleMieScatteringTexture?.dispose();
187
+ this.textures.higherOrderScatteringTexture?.dispose();
188
+ this.textures = undefined;
189
+ }
190
+ this.emit("disposed");
191
+ }
192
+
193
+ /**
194
+ * Invokes the callback with precomputed textures immediately if already loaded,
195
+ * or registers a one-time listener to invoke it once textures are ready.
196
+ */
197
+ onTexturesReady(callback: (textures: PrecomputedTextures) => void): void {
198
+ if (this.textures) {
199
+ callback(this.textures);
200
+ } else {
201
+ this.once("textureLoaded", () => {
202
+ invariant(this.textures);
203
+ callback(this.textures);
204
+ });
205
+ }
206
+ }
207
+
208
+ /**
209
+ * Returns a clone of the current sun direction vector.
210
+ * @returns A new Vector3 representing the sun direction in ECEF coordinates.
211
+ */
212
+ getSunDirection(): Vector3 {
213
+ return this.sunDirection.clone();
214
+ }
215
+
216
+ /**
217
+ * Returns a clone of the current moon direction vector.
218
+ * @returns A new Vector3 representing the moon direction in ECEF coordinates.
219
+ */
220
+ getMoonDirection(): Vector3 {
221
+ return this.moonDirection.clone();
222
+ }
223
+
224
+ /**
225
+ * Returns a clone of the ECI to ECEF rotation matrix.
226
+ * @returns A new Matrix4 representing the rotation from ECI to ECEF coordinates.
227
+ */
228
+ getRotationMatrix(): Matrix4 {
229
+ return this.rotationMatrix.clone();
230
+ }
231
+
232
+ /**
233
+ * Updates sun/moon directions and rotation matrix if needed.
234
+ * @private
235
+ */
236
+ _update() {
237
+ if (this.needsUpdate) {
238
+ getSunDirectionECEF(this.date, this.sunDirection);
239
+ getMoonDirectionECEF(this.date, this.moonDirection);
240
+ getECIToECEFRotationMatrix(this.date, this.rotationMatrix);
241
+
242
+ this.emit("sunChanged", this.sunDirection.clone());
243
+ }
244
+
245
+ this.needsUpdate = false;
246
+ }
247
+
248
+ /**
249
+ * Determines whether a given position is on the night side of the Earth.
250
+ * @param position - The position in ECEF coordinates to check.
251
+ * @returns `true` if the position is on the night side, `false` otherwise.
252
+ */
253
+ isAtNight(position: XYZ): boolean {
254
+ const normalizedPosition = new Vector3(position.x, position.y, position.z)
255
+ .clone()
256
+ .normalize();
257
+ const dotProduct = normalizedPosition.dot(this.sunDirection);
258
+ return dotProduct < 0;
259
+ }
260
+
261
+ /**
262
+ * Gets the current date used for calculating sun/moon positions.
263
+ */
264
+ get date() {
265
+ return this.options.date ?? DEFAULT_ATMOSPHERE_OPTIONS.date;
266
+ }
267
+
268
+ /**
269
+ * Sets the date used for calculating sun/moon positions.
270
+ * Triggers an update to recalculate celestial body directions.
271
+ */
272
+ set date(v: Date) {
273
+ this.options.date = v;
274
+ this.onUpdate();
275
+ }
276
+
277
+ /**
278
+ * Adjusts `atmosphere.date` so that the local solar time at `to` matches the
279
+ * local solar time at `from`.
280
+ *
281
+ * The calculation is based on the sun's hour angle, which increases
282
+ * monotonically over a solar day, giving exactly one solution per day with no
283
+ * morning/afternoon ambiguity. The equation of time is accounted for
284
+ * automatically.
285
+ *
286
+ * @example
287
+ * // atmosphere.date shows 08:00 local solar time at Tokyo.
288
+ * view.atmosphere.setDateAt({ lng: 139.69 }, { lng: 0 });
289
+ * // → atmosphere.date is now 08:00 local solar time at London
290
+ *
291
+ * @param from - Source location. Only `lng` (degrees) affects the result.
292
+ * @param to - Target location. Only `lng` (degrees) affects the result.
293
+ */
294
+ setDateAt(
295
+ from: { lng: number; lat?: number },
296
+ to: { lng: number; lat?: number },
297
+ ): void {
298
+ this.date = shiftDateToHourAngle(this.date, from.lng, to.lng, to.lat);
299
+ }
300
+
301
+ /**
302
+ * Adjusts `atmosphere.date` so that the sun elevation at `to` matches the
303
+ * sun elevation at `from`.
304
+ *
305
+ * Morning/afternoon context is preserved. If the target elevation cannot be
306
+ * reached at `to` (e.g. polar night), the date is clamped to solar noon
307
+ * there.
308
+ *
309
+ * @example
310
+ * // atmosphere.date shows sun at 30° elevation over Tokyo.
311
+ * view.atmosphere.setElevationAt({ lat: 35.68, lng: 139.69 }, { lat: 51.5, lng: -0.12 });
312
+ * // → atmosphere.date adjusted so sun is also at 30° elevation over London
313
+ *
314
+ * @param from - Source location (both `lat` and `lng` required).
315
+ * @param to - Target location (both `lat` and `lng` required).
316
+ */
317
+ setElevationAt(
318
+ from: { lat: number; lng: number },
319
+ to: { lat: number; lng: number },
320
+ ): void {
321
+ this.date = shiftDateToElevation(
322
+ this.date,
323
+ from.lat,
324
+ from.lng,
325
+ to.lat,
326
+ to.lng,
327
+ );
328
+ }
329
+
330
+ /**
331
+ * Convenience wrapper for {@link setDateAt} that uses the camera position as
332
+ * `from`.
333
+ *
334
+ * @example
335
+ * // Camera is over Tokyo showing 08:00 local solar time.
336
+ * view.atmosphere.setDateFromCameraAt({ lng: 0 }); // adjust to London
337
+ * // → atmosphere.date is now 08:00 local solar time at London
338
+ *
339
+ * @param to - Target location. Only `lng` (degrees) affects the result.
340
+ */
341
+ setDateFromCameraAt(to: { lng: number; lat?: number }): void {
342
+ const { lng: fromLng } = this._camera?.positionGeographic ?? { lng: 0 };
343
+ this.setDateAt({ lng: fromLng }, to);
344
+ }
345
+
346
+ /**
347
+ * Convenience wrapper for {@link setElevationAt} that uses the camera
348
+ * position as `from`.
349
+ *
350
+ * @example
351
+ * // Camera is over Tokyo with sun at 30° elevation.
352
+ * view.atmosphere.setElevationFromCameraAt({ lat: 51.5, lng: -0.12 }); // adjust to London
353
+ * // → atmosphere.date adjusted so sun is also at 30° elevation over London
354
+ *
355
+ * @param to - Target location (both `lat` and `lng` required).
356
+ */
357
+ setElevationFromCameraAt(to: { lat: number; lng: number }): void {
358
+ const { lng: fromLng, lat: fromLat } = this._camera?.positionGeographic ?? {
359
+ lng: 0,
360
+ lat: 0,
361
+ };
362
+ this.setElevationAt({ lat: fromLat, lng: fromLng }, to);
363
+ }
364
+ }