@zendir/ui 0.5.0 → 0.6.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 (391) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/README.md +640 -631
  3. package/dist/_virtual/_rolldown/runtime.js +13 -0
  4. package/dist/index.js +17 -221
  5. package/dist/react/3d/CesiumCaptureSource.d.ts +0 -1
  6. package/dist/react/3d/CesiumCaptureSource.js +364 -283
  7. package/dist/react/3d/CesiumCaptureSource.js.map +1 -1
  8. package/dist/react/3d/ZenSpace3D.d.ts +2 -3
  9. package/dist/react/3d/ZenSpace3D.js +1681 -1237
  10. package/dist/react/3d/ZenSpace3D.js.map +1 -1
  11. package/dist/react/3d/ZenSpace3DCesium.d.ts +0 -1
  12. package/dist/react/3d/ZenSpace3DCesium.js +513 -560
  13. package/dist/react/3d/ZenSpace3DCesium.js.map +1 -1
  14. package/dist/react/3d/ZenSpace3DShaders.js +61 -66
  15. package/dist/react/3d/ZenSpace3DShaders.js.map +1 -1
  16. package/dist/react/3d/ZenSpace3DTypes.d.ts +19 -20
  17. package/dist/react/3d/ZenSpace3DUtils.d.ts +0 -1
  18. package/dist/react/3d/ZenSpace3DUtils.js +37 -24
  19. package/dist/react/3d/ZenSpace3DUtils.js.map +1 -1
  20. package/dist/react/3d/capturePngAnalysis.js +42 -36
  21. package/dist/react/3d/capturePngAnalysis.js.map +1 -1
  22. package/dist/react/3d/index.d.ts +3 -3
  23. package/dist/react/3d/index.js +5 -53
  24. package/dist/react/3d/threeLoader.d.ts +1 -1
  25. package/dist/react/3d/threeLoader.js +23 -18
  26. package/dist/react/3d/threeLoader.js.map +1 -1
  27. package/dist/react/astro/ClassificationBanner.d.ts +2 -3
  28. package/dist/react/astro/ClassificationBanner.js +95 -79
  29. package/dist/react/astro/ClassificationBanner.js.map +1 -1
  30. package/dist/react/astro/GlobalStatusBar.d.ts +0 -1
  31. package/dist/react/astro/GlobalStatusBar.js +157 -163
  32. package/dist/react/astro/GlobalStatusBar.js.map +1 -1
  33. package/dist/react/astro/MissionClock.d.ts +7 -8
  34. package/dist/react/astro/MissionClock.js +377 -400
  35. package/dist/react/astro/MissionClock.js.map +1 -1
  36. package/dist/react/astro/MonitoringIcon.d.ts +1 -2
  37. package/dist/react/astro/MonitoringIcon.js +422 -358
  38. package/dist/react/astro/MonitoringIcon.js.map +1 -1
  39. package/dist/react/astro/Notification.d.ts +1 -2
  40. package/dist/react/astro/Notification.js +229 -126
  41. package/dist/react/astro/Notification.js.map +1 -1
  42. package/dist/react/astro/Progress.d.ts +0 -1
  43. package/dist/react/astro/Progress.js +199 -141
  44. package/dist/react/astro/Progress.js.map +1 -1
  45. package/dist/react/astro/SimulationControls.d.ts +3 -4
  46. package/dist/react/astro/SimulationControls.js +596 -650
  47. package/dist/react/astro/SimulationControls.js.map +1 -1
  48. package/dist/react/astro/StatusIndicator.d.ts +0 -1
  49. package/dist/react/astro/StatusIndicator.js +236 -170
  50. package/dist/react/astro/StatusIndicator.js.map +1 -1
  51. package/dist/react/astro/UnifiedTimeline.d.ts +9 -10
  52. package/dist/react/astro/UnifiedTimeline.js +2345 -2392
  53. package/dist/react/astro/UnifiedTimeline.js.map +1 -1
  54. package/dist/react/astro/index.d.ts +5 -5
  55. package/dist/react/astro/index.js +1 -25
  56. package/dist/react/cards/AccessCard.d.ts +0 -1
  57. package/dist/react/cards/AccessCard.js +471 -405
  58. package/dist/react/cards/AccessCard.js.map +1 -1
  59. package/dist/react/cards/OrbitCard.d.ts +0 -1
  60. package/dist/react/cards/OrbitCard.js +487 -364
  61. package/dist/react/cards/OrbitCard.js.map +1 -1
  62. package/dist/react/cards/SpacecraftCard.d.ts +0 -1
  63. package/dist/react/cards/SpacecraftCard.js +813 -925
  64. package/dist/react/cards/SpacecraftCard.js.map +1 -1
  65. package/dist/react/cards/TelemetryCard.d.ts +0 -1
  66. package/dist/react/cards/TelemetryCard.js +1055 -732
  67. package/dist/react/cards/TelemetryCard.js.map +1 -1
  68. package/dist/react/cards/TelemetryStreamCard.d.ts +0 -1
  69. package/dist/react/cards/TelemetryStreamCard.js +323 -297
  70. package/dist/react/cards/TelemetryStreamCard.js.map +1 -1
  71. package/dist/react/cards/index.d.ts +1 -1
  72. package/dist/react/cards/index.js +1 -8
  73. package/dist/react/charts/GroundTrackMap.d.ts +6 -7
  74. package/dist/react/charts/GroundTrackMap.js +1377 -1256
  75. package/dist/react/charts/GroundTrackMap.js.map +1 -1
  76. package/dist/react/charts/GroundTrackMapLeaflet.d.ts +1 -2
  77. package/dist/react/charts/GroundTrackMapLeaflet.js +1065 -987
  78. package/dist/react/charts/GroundTrackMapLeaflet.js.map +1 -1
  79. package/dist/react/charts/groundTrackMapLeafletTiles.js +34 -25
  80. package/dist/react/charts/groundTrackMapLeafletTiles.js.map +1 -1
  81. package/dist/react/charts/groundTrackMapLeafletUtils.js +70 -61
  82. package/dist/react/charts/groundTrackMapLeafletUtils.js.map +1 -1
  83. package/dist/react/charts/index.d.ts +1 -1
  84. package/dist/react/charts/index.js +7 -100
  85. package/dist/react/charts/unified/AstroChart.d.ts +1 -2
  86. package/dist/react/charts/unified/AstroChart.js +1331 -1411
  87. package/dist/react/charts/unified/AstroChart.js.map +1 -1
  88. package/dist/react/charts/unified/PowerOverviewChart.d.ts +3 -3
  89. package/dist/react/charts/unified/PowerOverviewChart.js +495 -478
  90. package/dist/react/charts/unified/PowerOverviewChart.js.map +1 -1
  91. package/dist/react/charts/unified/domain.d.ts +12 -13
  92. package/dist/react/charts/unified/domain.js +3999 -3145
  93. package/dist/react/charts/unified/domain.js.map +1 -1
  94. package/dist/react/charts/unified/generators.d.ts +3 -4
  95. package/dist/react/charts/unified/generators.js +561 -498
  96. package/dist/react/charts/unified/generators.js.map +1 -1
  97. package/dist/react/charts/unified/index.d.ts +1 -1
  98. package/dist/react/charts/unified/presets.d.ts +14 -15
  99. package/dist/react/charts/unified/presets.js +857 -994
  100. package/dist/react/charts/unified/presets.js.map +1 -1
  101. package/dist/react/charts/unified/sync.d.ts +2 -3
  102. package/dist/react/charts/unified/sync.js +229 -195
  103. package/dist/react/charts/unified/sync.js.map +1 -1
  104. package/dist/react/charts/unified/theme.d.ts +11 -12
  105. package/dist/react/charts/unified/theme.js +606 -642
  106. package/dist/react/charts/unified/theme.js.map +1 -1
  107. package/dist/react/charts/unified/types.d.ts +32 -33
  108. package/dist/react/charts/unified/useChartStream.d.ts +1 -2
  109. package/dist/react/charts/unified/useChartStream.js +203 -216
  110. package/dist/react/charts/unified/useChartStream.js.map +1 -1
  111. package/dist/react/chatgpt/AppCard.d.ts +1 -2
  112. package/dist/react/chatgpt/index.d.ts +7 -7
  113. package/dist/react/chatgpt/index.js +160 -139
  114. package/dist/react/chatgpt/index.js.map +1 -1
  115. package/dist/react/context/CategoryContext.d.ts +0 -1
  116. package/dist/react/context/CategoryContext.js +78 -29
  117. package/dist/react/context/CategoryContext.js.map +1 -1
  118. package/dist/react/context/DisplaySettingsContext.d.ts +1 -2
  119. package/dist/react/context/DisplaySettingsContext.js +205 -156
  120. package/dist/react/context/DisplaySettingsContext.js.map +1 -1
  121. package/dist/react/context/SpatialSelectionContext.d.ts +0 -1
  122. package/dist/react/context/SpatialSelectionContext.js +36 -7
  123. package/dist/react/context/SpatialSelectionContext.js.map +1 -1
  124. package/dist/react/core/data/DataTable.d.ts +3 -4
  125. package/dist/react/core/data/DataTable.js +473 -440
  126. package/dist/react/core/data/DataTable.js.map +1 -1
  127. package/dist/react/core/data/DataValue.d.ts +4 -5
  128. package/dist/react/core/data/DataValue.js +605 -571
  129. package/dist/react/core/data/DataValue.js.map +1 -1
  130. package/dist/react/core/data/propertyConfig.d.ts +1 -2
  131. package/dist/react/core/data/propertyConfig.js +446 -382
  132. package/dist/react/core/data/propertyConfig.js.map +1 -1
  133. package/dist/react/core/display/AstroIcon.d.ts +4 -5
  134. package/dist/react/core/display/AstroIcon.js +339 -429
  135. package/dist/react/core/display/AstroIcon.js.map +1 -1
  136. package/dist/react/core/display/Badge.d.ts +2 -3
  137. package/dist/react/core/display/Badge.js +131 -131
  138. package/dist/react/core/display/Badge.js.map +1 -1
  139. package/dist/react/core/display/CardHeader.d.ts +0 -1
  140. package/dist/react/core/display/CardHeader.js +398 -311
  141. package/dist/react/core/display/CardHeader.js.map +1 -1
  142. package/dist/react/core/display/Container.d.ts +2 -3
  143. package/dist/react/core/display/Container.js +640 -668
  144. package/dist/react/core/display/Container.js.map +1 -1
  145. package/dist/react/core/display/CopyButton.d.ts +1 -2
  146. package/dist/react/core/display/CopyButton.js +158 -101
  147. package/dist/react/core/display/CopyButton.js.map +1 -1
  148. package/dist/react/core/display/GlassCard.d.ts +3 -4
  149. package/dist/react/core/display/GlassCard.js +416 -369
  150. package/dist/react/core/display/GlassCard.js.map +1 -1
  151. package/dist/react/core/display/HeaderIconWithStatus.d.ts +0 -1
  152. package/dist/react/core/display/HeaderIconWithStatus.js +152 -152
  153. package/dist/react/core/display/HeaderIconWithStatus.js.map +1 -1
  154. package/dist/react/core/display/Icon.d.ts +2 -3
  155. package/dist/react/core/display/Icon.js +172 -143
  156. package/dist/react/core/display/Icon.js.map +1 -1
  157. package/dist/react/core/display/Typography.d.ts +24 -25
  158. package/dist/react/core/display/Typography.js +360 -178
  159. package/dist/react/core/display/Typography.js.map +1 -1
  160. package/dist/react/core/feedback/ConfirmDialog.d.ts +1 -2
  161. package/dist/react/core/feedback/ConfirmDialog.js +343 -304
  162. package/dist/react/core/feedback/ConfirmDialog.js.map +1 -1
  163. package/dist/react/core/feedback/Dialog.d.ts +2 -3
  164. package/dist/react/core/feedback/Dialog.js +189 -197
  165. package/dist/react/core/feedback/Dialog.js.map +1 -1
  166. package/dist/react/core/feedback/Toast.d.ts +2 -3
  167. package/dist/react/core/feedback/Toast.js +346 -207
  168. package/dist/react/core/feedback/Toast.js.map +1 -1
  169. package/dist/react/core/index.d.ts +26 -26
  170. package/dist/react/core/index.js +7 -119
  171. package/dist/react/core/inputs/Button.d.ts +2 -3
  172. package/dist/react/core/inputs/Button.js +281 -304
  173. package/dist/react/core/inputs/Button.js.map +1 -1
  174. package/dist/react/core/inputs/Checkbox.d.ts +2 -3
  175. package/dist/react/core/inputs/Checkbox.js +139 -127
  176. package/dist/react/core/inputs/Checkbox.js.map +1 -1
  177. package/dist/react/core/inputs/Input.d.ts +3 -4
  178. package/dist/react/core/inputs/Input.js +277 -285
  179. package/dist/react/core/inputs/Input.js.map +1 -1
  180. package/dist/react/core/inputs/LimitsBar.d.ts +1 -2
  181. package/dist/react/core/inputs/LimitsBar.js +271 -196
  182. package/dist/react/core/inputs/LimitsBar.js.map +1 -1
  183. package/dist/react/core/inputs/NumberInput.d.ts +2 -3
  184. package/dist/react/core/inputs/NumberInput.js +531 -503
  185. package/dist/react/core/inputs/NumberInput.js.map +1 -1
  186. package/dist/react/core/inputs/PinInput.d.ts +2 -3
  187. package/dist/react/core/inputs/PinInput.js +224 -207
  188. package/dist/react/core/inputs/PinInput.js.map +1 -1
  189. package/dist/react/core/inputs/Select.d.ts +1 -2
  190. package/dist/react/core/inputs/Select.js +298 -299
  191. package/dist/react/core/inputs/Select.js.map +1 -1
  192. package/dist/react/core/inputs/Toggle.d.ts +2 -3
  193. package/dist/react/core/inputs/Toggle.js +142 -148
  194. package/dist/react/core/inputs/Toggle.js.map +1 -1
  195. package/dist/react/core/layout/Box.d.ts +3 -4
  196. package/dist/react/core/layout/Box.js +118 -122
  197. package/dist/react/core/layout/Box.js.map +1 -1
  198. package/dist/react/core/layout/Center.d.ts +0 -1
  199. package/dist/react/core/layout/Center.js +45 -32
  200. package/dist/react/core/layout/Center.js.map +1 -1
  201. package/dist/react/core/layout/Divider.d.ts +1 -2
  202. package/dist/react/core/layout/Divider.js +112 -106
  203. package/dist/react/core/layout/Divider.js.map +1 -1
  204. package/dist/react/core/layout/Flex.d.ts +4 -5
  205. package/dist/react/core/layout/Flex.js +120 -124
  206. package/dist/react/core/layout/Flex.js.map +1 -1
  207. package/dist/react/core/layout/Grid.d.ts +5 -6
  208. package/dist/react/core/layout/Grid.js +131 -138
  209. package/dist/react/core/layout/Grid.js.map +1 -1
  210. package/dist/react/core/layout/Spacer.d.ts +0 -1
  211. package/dist/react/core/layout/Spacer.js +36 -29
  212. package/dist/react/core/layout/Spacer.js.map +1 -1
  213. package/dist/react/core/layout/Stack.d.ts +4 -5
  214. package/dist/react/core/layout/Stack.js +127 -70
  215. package/dist/react/core/layout/Stack.js.map +1 -1
  216. package/dist/react/core/layout/responsive.d.ts +1 -2
  217. package/dist/react/core/layout/responsive.js +25 -19
  218. package/dist/react/core/layout/responsive.js.map +1 -1
  219. package/dist/react/core/layout/useBreakpoint.d.ts +1 -1
  220. package/dist/react/core/layout/useBreakpoint.js +119 -66
  221. package/dist/react/core/layout/useBreakpoint.js.map +1 -1
  222. package/dist/react/core/navigation/AppBar.d.ts +1 -2
  223. package/dist/react/core/navigation/AppBar.js +827 -805
  224. package/dist/react/core/navigation/AppBar.js.map +1 -1
  225. package/dist/react/core/navigation/Pagination.d.ts +2 -3
  226. package/dist/react/core/navigation/Pagination.js +207 -187
  227. package/dist/react/core/navigation/Pagination.js.map +1 -1
  228. package/dist/react/core/navigation/SideNav.d.ts +5 -6
  229. package/dist/react/core/navigation/SideNav.js +855 -629
  230. package/dist/react/core/navigation/SideNav.js.map +1 -1
  231. package/dist/react/core/navigation/Tabs.d.ts +0 -1
  232. package/dist/react/core/navigation/Tabs.js +113 -119
  233. package/dist/react/core/navigation/Tabs.js.map +1 -1
  234. package/dist/react/core/overlays/Popover.d.ts +2 -3
  235. package/dist/react/core/overlays/Popover.js +303 -282
  236. package/dist/react/core/overlays/Popover.js.map +1 -1
  237. package/dist/react/core/overlays/SidePanel.d.ts +1 -2
  238. package/dist/react/core/overlays/SidePanel.js +217 -212
  239. package/dist/react/core/overlays/SidePanel.js.map +1 -1
  240. package/dist/react/core/overlays/Tooltip.d.ts +1 -2
  241. package/dist/react/core/overlays/Tooltip.js +170 -176
  242. package/dist/react/core/overlays/Tooltip.js.map +1 -1
  243. package/dist/react/core/widgets/ActivityPlanner.d.ts +0 -1
  244. package/dist/react/core/widgets/ActivityPlanner.js +855 -517
  245. package/dist/react/core/widgets/ActivityPlanner.js.map +1 -1
  246. package/dist/react/core/widgets/Capture.d.ts +2 -3
  247. package/dist/react/core/widgets/Capture.js +965 -779
  248. package/dist/react/core/widgets/Capture.js.map +1 -1
  249. package/dist/react/core/widgets/ChatPanel.d.ts +16 -17
  250. package/dist/react/core/widgets/ChatPanel.js +1734 -1034
  251. package/dist/react/core/widgets/ChatPanel.js.map +1 -1
  252. package/dist/react/core/widgets/ColorPickerPanel.d.ts +0 -1
  253. package/dist/react/core/widgets/ColorPickerPanel.js +298 -287
  254. package/dist/react/core/widgets/ColorPickerPanel.js.map +1 -1
  255. package/dist/react/core/widgets/CommandBuilder.d.ts +2 -3
  256. package/dist/react/core/widgets/CommandBuilder.js +624 -516
  257. package/dist/react/core/widgets/CommandBuilder.js.map +1 -1
  258. package/dist/react/core/widgets/ConnectionForm.d.ts +2 -3
  259. package/dist/react/core/widgets/ConnectionForm.js +528 -492
  260. package/dist/react/core/widgets/ConnectionForm.js.map +1 -1
  261. package/dist/react/core/widgets/FileExplorer.d.ts +3 -4
  262. package/dist/react/core/widgets/FileExplorer.js +617 -505
  263. package/dist/react/core/widgets/FileExplorer.js.map +1 -1
  264. package/dist/react/core/widgets/HexViewer.d.ts +2 -3
  265. package/dist/react/core/widgets/HexViewer.js +1353 -1091
  266. package/dist/react/core/widgets/HexViewer.js.map +1 -1
  267. package/dist/react/core/widgets/ImageFrame.d.ts +1 -2
  268. package/dist/react/core/widgets/ImageFrame.js +230 -193
  269. package/dist/react/core/widgets/ImageFrame.js.map +1 -1
  270. package/dist/react/core/widgets/ImageGallery.d.ts +2 -1
  271. package/dist/react/core/widgets/ImageGallery.js +380 -314
  272. package/dist/react/core/widgets/ImageGallery.js.map +1 -1
  273. package/dist/react/core/widgets/ImagePanel.d.ts +0 -1
  274. package/dist/react/core/widgets/ImagePanel.js +110 -101
  275. package/dist/react/core/widgets/ImagePanel.js.map +1 -1
  276. package/dist/react/core/widgets/LogViewer.d.ts +2 -3
  277. package/dist/react/core/widgets/LogViewer.js +711 -607
  278. package/dist/react/core/widgets/LogViewer.js.map +1 -1
  279. package/dist/react/core/widgets/MessageStream.d.ts +3 -4
  280. package/dist/react/core/widgets/MessageStream.js +514 -444
  281. package/dist/react/core/widgets/MessageStream.js.map +1 -1
  282. package/dist/react/core/widgets/MissionCalendar.d.ts +3 -4
  283. package/dist/react/core/widgets/MissionCalendar.js +1488 -1020
  284. package/dist/react/core/widgets/MissionCalendar.js.map +1 -1
  285. package/dist/react/core/widgets/PacketViewer.d.ts +2 -3
  286. package/dist/react/core/widgets/PacketViewer.js +550 -421
  287. package/dist/react/core/widgets/PacketViewer.js.map +1 -1
  288. package/dist/react/core/widgets/capture-placeholder.png.js +6 -5
  289. package/dist/react/core/widgets/capture-placeholder.png.js.map +1 -1
  290. package/dist/react/hooks/index.d.ts +5 -5
  291. package/dist/react/hooks/useAccessWindows.d.ts +0 -1
  292. package/dist/react/hooks/useCompactMode.d.ts +1 -1
  293. package/dist/react/hooks/useCompactMode.js +104 -58
  294. package/dist/react/hooks/useCompactMode.js.map +1 -1
  295. package/dist/react/hooks/useGroundTrackHistory.d.ts +0 -1
  296. package/dist/react/hooks/useSimulationScene.d.ts +1 -2
  297. package/dist/react/hooks/useSimulationScene.js +481 -374
  298. package/dist/react/hooks/useSimulationScene.js.map +1 -1
  299. package/dist/react/index.d.ts +3 -3
  300. package/dist/react/panels/LayerControlPanel.d.ts +1 -2
  301. package/dist/react/panels/LayerControlPanel.js +223 -180
  302. package/dist/react/panels/LayerControlPanel.js.map +1 -1
  303. package/dist/react/panels/ObjectInventoryPanel.d.ts +2 -3
  304. package/dist/react/panels/ObjectInventoryPanel.js +315 -250
  305. package/dist/react/panels/ObjectInventoryPanel.js.map +1 -1
  306. package/dist/react/panels/index.d.ts +1 -1
  307. package/dist/react/panels/index.js +1 -6
  308. package/dist/react/shared/ErrorBoundary.d.ts +1 -2
  309. package/dist/react/shared/ErrorBoundary.js +170 -139
  310. package/dist/react/shared/ErrorBoundary.js.map +1 -1
  311. package/dist/react/shared/Skeleton.d.ts +1 -2
  312. package/dist/react/shared/Skeleton.js +300 -301
  313. package/dist/react/shared/Skeleton.js.map +1 -1
  314. package/dist/react/theme/ThemeProvider.d.ts +2 -321
  315. package/dist/react/theme/ThemeProvider.js +312 -939
  316. package/dist/react/theme/ThemeProvider.js.map +1 -1
  317. package/dist/react/theme/cardAccent.d.ts +1 -2
  318. package/dist/react/theme/cardAccent.js +196 -126
  319. package/dist/react/theme/cardAccent.js.map +1 -1
  320. package/dist/react/theme/config.d.ts +0 -1
  321. package/dist/react/theme/config.js +47 -25
  322. package/dist/react/theme/config.js.map +1 -1
  323. package/dist/react/theme/index.d.ts +2 -2
  324. package/dist/react/theme/index.js +1 -16
  325. package/dist/react/theme/types.d.ts +332 -0
  326. package/dist/react/theme/types.js +39 -0
  327. package/dist/react/theme/types.js.map +1 -0
  328. package/dist/react/types.d.ts +8 -8
  329. package/dist/react/types.js +147 -47
  330. package/dist/react/types.js.map +1 -1
  331. package/dist/react/utils/categoryPalette.d.ts +0 -1
  332. package/dist/react/utils/categoryPalette.js +91 -102
  333. package/dist/react/utils/categoryPalette.js.map +1 -1
  334. package/dist/react/utils/index.d.ts +5 -5
  335. package/dist/react/utils/index.js +457 -371
  336. package/dist/react/utils/index.js.map +1 -1
  337. package/dist/react/visualizations/EclipseTimerCard.d.ts +0 -1
  338. package/dist/react/visualizations/LinkBudgetCard.d.ts +0 -1
  339. package/dist/react/visualizations/NavBallCard.d.ts +0 -1
  340. package/dist/react/visualizations/PropulsionCard.d.ts +1 -2
  341. package/dist/react/visualizations/SensorFootprintCard.d.ts +1 -2
  342. package/dist/react/visualizations/ThermalHeatmapCard.d.ts +0 -1
  343. package/dist/react/visualizations/index.d.ts +3 -3
  344. package/dist/react.d.ts +2 -1
  345. package/dist/react.js +17 -221
  346. package/dist/shaders/atmosphere.frag.js +6 -5
  347. package/dist/shaders/atmosphere.frag.js.map +1 -1
  348. package/dist/shaders/atmosphere.vert.js +6 -5
  349. package/dist/shaders/atmosphere.vert.js.map +1 -1
  350. package/dist/shaders/stars.frag.js +6 -5
  351. package/dist/shaders/stars.frag.js.map +1 -1
  352. package/dist/shaders/stars.vert.js +6 -5
  353. package/dist/shaders/stars.vert.js.map +1 -1
  354. package/dist/style.css +217 -194
  355. package/dist/tokens/core.d.ts +159 -0
  356. package/dist/tokens/core.js +144 -0
  357. package/dist/tokens/core.js.map +1 -0
  358. package/dist/tokens/css-vars.d.ts +213 -2
  359. package/dist/tokens/css-vars.js +590 -227
  360. package/dist/tokens/css-vars.js.map +1 -1
  361. package/dist/tokens/index.d.ts +31 -228
  362. package/dist/tokens/index.js +281 -366
  363. package/dist/tokens/index.js.map +1 -1
  364. package/dist/tokens/palettes/astro.d.ts +129 -0
  365. package/dist/tokens/palettes/astro.js +112 -0
  366. package/dist/tokens/palettes/astro.js.map +1 -0
  367. package/dist/tokens/palettes/index.d.ts +288 -0
  368. package/dist/tokens/palettes/index.js +35 -0
  369. package/dist/tokens/palettes/index.js.map +1 -0
  370. package/dist/tokens/palettes/tailwind.d.ts +324 -0
  371. package/dist/tokens/palettes/tailwind.js +201 -0
  372. package/dist/tokens/palettes/tailwind.js.map +1 -0
  373. package/dist/tokens/palettes/zendir.d.ts +126 -0
  374. package/dist/tokens/palettes/zendir.js +92 -0
  375. package/dist/tokens/palettes/zendir.js.map +1 -0
  376. package/dist/tokens/themes.d.ts +30 -0
  377. package/dist/tokens/themes.js +704 -0
  378. package/dist/tokens/themes.js.map +1 -0
  379. package/dist/tokens/tokens.css +419 -41
  380. package/dist/types/index.d.ts +2 -2
  381. package/package.json +310 -313
  382. package/dist/index.js.map +0 -1
  383. package/dist/react/3d/index.js.map +0 -1
  384. package/dist/react/astro/index.js.map +0 -1
  385. package/dist/react/cards/index.js.map +0 -1
  386. package/dist/react/charts/index.js.map +0 -1
  387. package/dist/react/core/index.js.map +0 -1
  388. package/dist/react/panels/index.js.map +0 -1
  389. package/dist/react/theme/astro-tokens.d.ts +0 -153
  390. package/dist/react/theme/index.js.map +0 -1
  391. package/dist/react.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"ZenSpace3DCesium.js","sources":["../../../src/react/3d/ZenSpace3DCesium.tsx"],"sourcesContent":["/**\r\n * @zendir/ui - ZenSpace3D Cesium Backend\r\n *\r\n * Cesium-based 3D Earth/orbit view. Entities are reconciled **in-place** on\r\n * each data update (position changes only) to avoid the WebGL context churn\r\n * that occurs when entities are removed and re-added every polling tick.\r\n *\r\n * Layer visibility is controlled via the `layers` prop\r\n * (all default to \"sensible\" if the key is absent):\r\n *\r\n * layers.labels — spacecraft / GS name labels (default: false)\r\n * layers.coverage — coverage footprint ellipses + cones (default: false)\r\n * layers.orbits — orbit-path polylines (default: true)\r\n *\r\n * Coverage geometry sources (checked in order per satellite):\r\n * 1. Explicit `satelliteCoverages[].footprintPolygon` — ground polygon from SDK\r\n * 2. Explicit `satelliteCoverages[].halfAngle` — circular cone from half-angle\r\n * 3. Auto-computed circular ellipse from altitude (when layers.coverage = true)\r\n *\r\n * Additional explicit coverage options per `SatelliteCoverage`:\r\n * showCone — 3-D sensor cone from satellite to footprint\r\n * showNadirLine — dashed line from satellite to sub-satellite point\r\n */\r\n\r\nimport React, {\r\n useRef,\r\n useEffect,\r\n useImperativeHandle,\r\n forwardRef,\r\n useCallback,\r\n} from 'react';\r\nimport type {\r\n ZenSpace3DProps,\r\n ZenSpace3DHandle,\r\n ViewMode,\r\n Vector3D,\r\n SatelliteCoverage,\r\n} from './ZenSpace3DTypes';\r\n\r\n// ── Constants ─────────────────────────────────────────────────────────────────\r\n\r\nconst EARTH_RADIUS_KM = 6371;\r\n\r\n// ── Coordinate helpers ────────────────────────────────────────────────────────\r\n\r\n/**\r\n * Convert an ECI / J2000 position (km, Earth-centred) into a Cesium\r\n * `Cartesian3`. Cesium's Cartesian3 lives in the **ECEF (Earth-Fixed)**\r\n * frame — the same frame Cesium for Unreal exposes when its\r\n * `CesiumGeoreference` origin is set to `TrueOrigin (0,0,0)`. We rotate\r\n * ECI → ECEF using `Transforms.computeTemeToPseudoFixedMatrix(jd)`,\r\n * which is GMST-based and accurate to sub-arcsec for visualisation\r\n * (no IERS data required, fully synchronous).\r\n *\r\n * Returns `null` for non-finite inputs so callers can skip stale ticks\r\n * without crashing Cesium's Cartesian primitives.\r\n *\r\n * @param positionKm ECI position in km (Earth-centred).\r\n * @param julianDate Cesium JulianDate at which to evaluate Earth's rotation.\r\n * Caller is responsible for advancing this with sim time.\r\n */\r\nfunction eciKmToFixedCartesian3(\r\n Cesium: any,\r\n positionKm: Vector3D,\r\n julianDate: any,\r\n): any | null {\r\n if (\r\n !positionKm ||\r\n !Number.isFinite(positionKm.x) ||\r\n !Number.isFinite(positionKm.y) ||\r\n !Number.isFinite(positionKm.z)\r\n ) {\r\n return null;\r\n }\r\n // ECI position in metres — Cesium works in metres throughout.\r\n const eciM = new Cesium.Cartesian3(\r\n positionKm.x * 1000,\r\n positionKm.y * 1000,\r\n positionKm.z * 1000,\r\n );\r\n const rot = Cesium.Transforms.computeTemeToPseudoFixedMatrix(julianDate);\r\n if (!rot) {\r\n // Should never happen, but Transforms can return undefined for invalid\r\n // dates — fall back to treating the input as already-fixed so we never\r\n // crash the viewer on a stray NaN date.\r\n return eciM;\r\n }\r\n return Cesium.Matrix3.multiplyByVector(rot, eciM, new Cesium.Cartesian3());\r\n}\r\n\r\n/**\r\n * Sub-satellite (lat/lon) point + altitude (km) of an ECI position at a\r\n * given epoch. Used by coverage/cone code that needs to draw on Earth's\r\n * surface beneath the satellite.\r\n */\r\nfunction eciKmToSubSatellite(\r\n Cesium: any,\r\n positionKm: Vector3D,\r\n julianDate: any,\r\n): { latitude: number; longitude: number; altitude: number } | null {\r\n const fixed = eciKmToFixedCartesian3(Cesium, positionKm, julianDate);\r\n if (!fixed) return null;\r\n const carto = Cesium.Cartographic.fromCartesian(fixed);\r\n if (!carto || !Number.isFinite(carto.height)) return null;\r\n return {\r\n latitude: Cesium.Math.toDegrees(carto.latitude),\r\n longitude: Cesium.Math.toDegrees(carto.longitude),\r\n altitude: carto.height / 1000, // m → km\r\n };\r\n}\r\n\r\n// ── Coverage geometry ─────────────────────────────────────────────────────────\r\n\r\n/**\r\n * Circular coverage footprint radius (m) on Earth surface.\r\n *\r\n * Spherical geometry:\r\n * α = arcsin(R·cos(ε) / (R+h)) — nadir angle\r\n * λ = π/2 − ε − α — Earth central angle\r\n * radius = R · λ — arc length on surface\r\n */\r\nfunction autoFootprintRadiusM(altitudeKm: number, minElevDeg: number): number {\r\n if (altitudeKm <= 0) return 0;\r\n const R = EARTH_RADIUS_KM;\r\n const eps = (minElevDeg * Math.PI) / 180;\r\n const sinAlpha = (R * Math.cos(eps)) / (R + altitudeKm);\r\n if (sinAlpha >= 1) return 0;\r\n const alpha = Math.asin(sinAlpha);\r\n const lambda = Math.PI / 2 - eps - alpha;\r\n return R * 1000 * lambda;\r\n}\r\n\r\n/** Radius (m) of the footprint circle for a sensor with the given half-angle. */\r\nfunction halfAngleFootprintRadiusM(altitudeKm: number, halfAngleDeg: number): number {\r\n return altitudeKm * 1000 * Math.tan((halfAngleDeg * Math.PI) / 180);\r\n}\r\n\r\n// ── Entity helpers ────────────────────────────────────────────────────────────\r\n\r\ntype EntityMap = { current: Map<string, any> };\r\n\r\nfunction removeFromMap(viewer: any, id: string, map: EntityMap): void {\r\n if (map.current.has(id)) {\r\n try { viewer.entities.removeById(id); } catch (_) { /* already gone */ }\r\n map.current.delete(id);\r\n }\r\n}\r\n\r\nfunction makePointGraphics(Cesium: any, color: any, pixelSize = 8) {\r\n return {\r\n pixelSize,\r\n color,\r\n outlineColor: Cesium.Color.WHITE,\r\n outlineWidth: 1,\r\n scaleByDistance: new Cesium.NearFarScalar(1e6, 1.5, 5e7, 0.5),\r\n // Always render on top so satellites hidden behind Earth are still visible\r\n disableDepthTestDistance: Number.POSITIVE_INFINITY,\r\n };\r\n}\r\n\r\nfunction makeLabelOpts(Cesium: any, text: string, fillColor?: any) {\r\n return {\r\n text,\r\n font: '12px monospace',\r\n fillColor: fillColor ?? Cesium.Color.WHITE,\r\n outlineColor: Cesium.Color.BLACK,\r\n outlineWidth: 2,\r\n style: Cesium.LabelStyle.FILL_AND_OUTLINE,\r\n pixelOffset: new Cesium.Cartesian2(12, 0),\r\n scaleByDistance: new Cesium.NearFarScalar(1e6, 1.0, 5e7, 0.3),\r\n // Fade out label when camera is very far away\r\n distanceDisplayCondition: new Cesium.DistanceDisplayCondition(0, 3e7),\r\n disableDepthTestDistance: Number.POSITIVE_INFINITY,\r\n };\r\n}\r\n\r\n/** Add or update a circular ellipse entity on the Earth surface. */\r\nfunction upsertEllipse(\r\n viewer: any,\r\n Cesium: any,\r\n id: string,\r\n position: any,\r\n radiusM: number,\r\n color: any,\r\n map: EntityMap,\r\n): void {\r\n const existing = map.current.get(id);\r\n if (existing) {\r\n existing.position = new Cesium.ConstantPositionProperty(position);\r\n existing.ellipse.semiMajorAxis = new Cesium.ConstantProperty(radiusM);\r\n existing.ellipse.semiMinorAxis = new Cesium.ConstantProperty(radiusM);\r\n } else {\r\n const entity = viewer.entities.add({\r\n id,\r\n position,\r\n ellipse: {\r\n semiMajorAxis: radiusM,\r\n semiMinorAxis: radiusM,\r\n material: color.withAlpha(0.08),\r\n outline: true,\r\n outlineColor: color.withAlpha(0.5),\r\n outlineWidth: 1,\r\n height: 0,\r\n },\r\n });\r\n map.current.set(id, entity);\r\n }\r\n}\r\n\r\n/**\r\n * Render (or update in-place) the full coverage geometry for one satellite\r\n * from an explicit `SatelliteCoverage` record supplied by the Zendir SDK.\r\n */\r\nfunction renderExplicitCoverage(\r\n viewer: any,\r\n Cesium: any,\r\n satId: string,\r\n satPos3: Vector3D,\r\n cov: SatelliteCoverage,\r\n julianDate: any,\r\n covMap: EntityMap,\r\n coneMap: EntityMap,\r\n nadirMap: EntityMap,\r\n): void {\r\n const baseColor = cov.color\r\n ? Cesium.Color.fromCssColorString(cov.color)\r\n : Cesium.Color.CYAN;\r\n const opacity = cov.opacity ?? 0.2;\r\n\r\n const resolvedPos = cov.satellitePosition ?? satPos3;\r\n const satCesPos = eciKmToFixedCartesian3(Cesium, resolvedPos, julianDate);\r\n const subSat = eciKmToSubSatellite(Cesium, resolvedPos, julianDate);\r\n const latitude = subSat?.latitude ?? NaN;\r\n const longitude = subSat?.longitude ?? NaN;\r\n const altitude = subSat?.altitude ?? NaN;\r\n\r\n const nadirLat = cov.nadirPoint?.latitude ?? latitude;\r\n const nadirLon = cov.nadirPoint?.longitude ?? longitude;\r\n\r\n // ── Footprint polygon or circular ellipse ──────────────────────────────────\r\n const covId = `cov-${satId}`;\r\n if (cov.showFootprint !== false && cov.footprintPolygon && cov.footprintPolygon.length >= 3) {\r\n const positions = Cesium.Cartesian3.fromDegreesArray(\r\n cov.footprintPolygon.flatMap((pt) => [pt.longitude, pt.latitude]),\r\n );\r\n const existing = covMap.current.get(covId);\r\n if (existing) {\r\n existing.polygon.hierarchy = new Cesium.ConstantProperty(\r\n new Cesium.PolygonHierarchy(positions),\r\n );\r\n } else {\r\n const entity = viewer.entities.add({\r\n id: covId,\r\n polygon: {\r\n hierarchy: new Cesium.PolygonHierarchy(positions),\r\n material: baseColor.withAlpha(opacity),\r\n outline: true,\r\n outlineColor: baseColor.withAlpha(opacity * 3),\r\n height: 0,\r\n clampToGround: true,\r\n },\r\n });\r\n covMap.current.set(covId, entity);\r\n }\r\n } else if (\r\n cov.showFootprint !== false &&\r\n cov.halfAngle != null &&\r\n Number.isFinite(altitude) &&\r\n altitude > 0\r\n ) {\r\n const subSatPos = Cesium.Cartesian3.fromDegrees(nadirLon, nadirLat, 0);\r\n const radius = halfAngleFootprintRadiusM(altitude, cov.halfAngle);\r\n upsertEllipse(viewer, Cesium, covId, subSatPos, radius, baseColor, covMap);\r\n } else {\r\n removeFromMap(viewer, covId, covMap);\r\n }\r\n\r\n // ── Sensor cone (satellite → footprint, rendered as a Cesium cylinder) ─────\r\n const coneId = `cone-${satId}`;\r\n if (cov.showCone && satCesPos && Number.isFinite(altitude) && altitude > 0) {\r\n const radius = cov.halfAngle != null\r\n ? halfAngleFootprintRadiusM(altitude, cov.halfAngle)\r\n : autoFootprintRadiusM(altitude, 5);\r\n const coneLength = altitude * 1000; // km → m\r\n // Cylinder centered at mid-altitude between satellite and ground point\r\n const midPos = Cesium.Cartesian3.fromDegrees(nadirLon, nadirLat, coneLength / 2);\r\n const existing = coneMap.current.get(coneId);\r\n if (existing) {\r\n existing.position = new Cesium.ConstantPositionProperty(midPos);\r\n existing.cylinder.length = new Cesium.ConstantProperty(coneLength);\r\n existing.cylinder.bottomRadius = new Cesium.ConstantProperty(radius);\r\n } else {\r\n const entity = viewer.entities.add({\r\n id: coneId,\r\n position: midPos,\r\n cylinder: {\r\n length: coneLength,\r\n topRadius: 0,\r\n bottomRadius: radius,\r\n material: baseColor.withAlpha(0.06),\r\n outline: true,\r\n outlineColor: baseColor.withAlpha(0.25),\r\n numberOfVerticalLines: 12,\r\n },\r\n });\r\n coneMap.current.set(coneId, entity);\r\n }\r\n } else {\r\n removeFromMap(viewer, coneId, coneMap);\r\n }\r\n\r\n // ── Nadir line (satellite → sub-satellite point) ───────────────────────────\r\n const nadirId = `nadir-${satId}`;\r\n if (cov.showNadirLine && satCesPos) {\r\n const groundPos = Cesium.Cartesian3.fromDegrees(nadirLon, nadirLat, 0);\r\n const existing = nadirMap.current.get(nadirId);\r\n if (existing) {\r\n existing.polyline.positions = new Cesium.ConstantProperty([satCesPos, groundPos]);\r\n } else {\r\n const entity = viewer.entities.add({\r\n id: nadirId,\r\n polyline: {\r\n positions: [satCesPos, groundPos],\r\n width: 1,\r\n material: new Cesium.PolylineDashMaterialProperty({\r\n color: baseColor.withAlpha(0.5),\r\n dashLength: 8,\r\n }),\r\n },\r\n });\r\n nadirMap.current.set(nadirId, entity);\r\n }\r\n } else {\r\n removeFromMap(viewer, nadirId, nadirMap);\r\n }\r\n}\r\n\r\n// ── Component ─────────────────────────────────────────────────────────────────\r\n\r\nexport interface ZenSpace3DCesiumProps extends ZenSpace3DProps {\r\n /** Cesium module from dynamic import('cesium') */\r\n cesium: any;\r\n}\r\n\r\nexport const ZenSpace3DCesium = forwardRef<ZenSpace3DHandle, ZenSpace3DCesiumProps>(\r\n function ZenSpace3DCesium(\r\n {\r\n satellites = [],\r\n stations = [],\r\n groundStations = [],\r\n customObjects = [],\r\n orbitPaths = [],\r\n satelliteCoverages = [],\r\n view = 'earth-orbit',\r\n height = 600,\r\n callbacks,\r\n showTools = false,\r\n layers,\r\n visibility,\r\n referenceTime,\r\n cesium: Cesium,\r\n },\r\n ref,\r\n ) {\r\n const containerRef = useRef<HTMLDivElement>(null);\r\n const viewerRef = useRef<any>(null);\r\n\r\n // Stash callbacks in a ref so click/hover handlers never close over a stale\r\n // function reference — and never make the mount effect depend on them.\r\n const callbacksRef = useRef(callbacks);\r\n useEffect(() => { callbacksRef.current = callbacks; }, [callbacks]);\r\n\r\n // ── Entity maps for in-place reconciliation ────────────────────────────────\r\n // Each map: entity-id → Cesium entity object (only live entities live here).\r\n const satMapRef = useRef<Map<string, any>>(new Map()); // spacecraft + station dots\r\n const gsMapRef = useRef<Map<string, any>>(new Map()); // ground station dots\r\n const covMapRef = useRef<Map<string, any>>(new Map()); // coverage ellipses / polygons\r\n const coneMapRef = useRef<Map<string, any>>(new Map()); // sensor cones\r\n const nadirMapRef = useRef<Map<string, any>>(new Map()); // nadir lines\r\n const orbitMapRef = useRef<Map<string, any>>(new Map()); // orbit polylines\r\n\r\n // ── Latest ECI positions for satellite callback-properties ─────────────────\r\n // Satellites use CallbackPositionProperty so Cesium re-derives ECEF from the\r\n // stored ECI position on every rendered frame (using the current JulianDate).\r\n // This makes satellites track Earth's rotation smoothly between API poll ticks,\r\n // fixing the \"satellite frozen while Earth rotates\" bug.\r\n const eciPositionsRef = useRef<Map<string, Vector3D>>(new Map());\r\n\r\n // ── Layer visibility ──────────────────────────────────────────────────────\r\n // Render-flag layers (always-on by default for orbits; off by default for\r\n // labels/coverage). Derive primitives so the sync effect deps are cheap.\r\n const showLabels = layers?.labels === true; // off by default\r\n const showCoverage = layers?.coverage === true; // off by default\r\n const showOrbits = layers?.orbits !== false; // on by default\r\n\r\n // Object-group visibility — toggle whole categories of markers off without\r\n // unmounting them. Defaults to \"everything visible\" so existing consumers\r\n // who never set `visibility` are unaffected.\r\n const showSpacecraft = visibility?.spacecraft !== false;\r\n const showGroundStations = visibility?.groundStations !== false;\r\n const showCelestialBodies = visibility?.celestialBodies !== false;\r\n\r\n // ── Imperative handle ──────────────────────────────────────────────────────\r\n const focusOn = useCallback(\r\n (objectId: string, options?: { zoom?: number; animate?: boolean }) => {\r\n const viewer = viewerRef.current;\r\n if (!viewer) return;\r\n const entity = viewer.entities.getById(objectId);\r\n if (entity) {\r\n viewer.zoomTo(entity, { duration: options?.animate !== false ? 1.5 : 0 });\r\n }\r\n },\r\n [],\r\n );\r\n\r\n const setView = useCallback(\r\n (mode: ViewMode) => {\r\n const viewer = viewerRef.current;\r\n if (!viewer) return;\r\n if (mode === 'earth-orbit') {\r\n viewer.camera.flyTo({ destination: Cesium.Cartesian3.fromDegrees(0, 0, 2e7) });\r\n } else if (mode === 'solar-system') {\r\n viewer.camera.flyTo({ destination: Cesium.Cartesian3.fromDegrees(0, 0, 5e7) });\r\n }\r\n },\r\n [Cesium],\r\n );\r\n\r\n useImperativeHandle(\r\n ref,\r\n (): ZenSpace3DHandle => ({\r\n focusOn,\r\n flyTo: focusOn,\r\n setView,\r\n setTime: () => {},\r\n setTimeScale: () => {},\r\n togglePlay: () => {},\r\n setLayerVisibility: () => {},\r\n getCameraState: () => ({} as any),\r\n setCameraState: () => {},\r\n exportImage: () => '',\r\n exportScene: () => new Blob(),\r\n getVisibleObjects: () => [],\r\n findObjects: () => [],\r\n addObject: () => {},\r\n removeObject: () => {},\r\n updateObject: () => {},\r\n measureDistance: () => 0,\r\n }),\r\n [focusOn, setView],\r\n );\r\n\r\n // ── Mount effect: create Cesium Viewer + event handlers ONCE ──────────────\r\n //\r\n // Does NOT depend on the data arrays (satellites, orbitPaths, etc.) or on\r\n // `callbacks`. Both produce fresh references on every parent render / poll\r\n // tick. Including them would tear down + rebuild Cesium every 2 s, leaking\r\n // WebGL contexts until Chrome hits its hard cap (~16).\r\n useEffect(() => {\r\n if (!containerRef.current || !Cesium) return;\r\n\r\n // Clear maps in case this is a hot-reload remount\r\n satMapRef.current.clear();\r\n gsMapRef.current.clear();\r\n covMapRef.current.clear();\r\n coneMapRef.current.clear();\r\n nadirMapRef.current.clear();\r\n orbitMapRef.current.clear();\r\n eciPositionsRef.current.clear();\r\n\r\n const viewer = new Cesium.Viewer(containerRef.current, {\r\n baseLayerPicker: false,\r\n fullscreenButton: false,\r\n vrButton: false,\r\n geocoder: false,\r\n homeButton: !!showTools,\r\n sceneModePicker: false,\r\n timeline: false,\r\n navigationHelpButton: !!showTools,\r\n animation: false,\r\n scene3DOnly: true,\r\n useDefaultRenderLoop: true,\r\n requestRenderMode: false,\r\n });\r\n\r\n viewer.scene.globe.enableLighting = true;\r\n viewer.scene.backgroundColor = Cesium.Color.BLACK;\r\n\r\n // Surface the actual exception text on render-loop crashes. Without\r\n // this listener Cesium only shows \"An error occurred while rendering.\"\r\n // and the stack trace is buried.\r\n viewer.scene.renderError.addEventListener((scene: any, err: unknown) => {\r\n // eslint-disable-next-line no-console\r\n console.error('[ZenSpace3D] Cesium render error:', err);\r\n });\r\n\r\n // Advance the clock at 1× real time so Cesium continuously evaluates\r\n // ECI→ECEF for the correct current moment. Without this, the JulianDate\r\n // passed to satellite CallbackPositionProperty callbacks would be frozen\r\n // at the viewer-creation instant and satellites would drift relative to\r\n // Earth as wall-clock time advanced.\r\n viewer.clock.currentTime = Cesium.JulianDate.now();\r\n viewer.clock.multiplier = 1;\r\n viewer.clock.shouldAnimate = true;\r\n\r\n viewerRef.current = viewer;\r\n\r\n const handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);\r\n\r\n // Click → select\r\n handler.setInputAction((movement: any) => {\r\n const picked = viewer.scene.pick(movement.position);\r\n if (Cesium.defined(picked) && picked.id && callbacksRef.current?.onSelect) {\r\n callbacksRef.current.onSelect({\r\n id: picked.id.id,\r\n name: picked.id.name,\r\n category: 'satellite',\r\n position: { x: 0, y: 0, z: 0 },\r\n visualRadius: 0,\r\n });\r\n }\r\n }, Cesium.ScreenSpaceEventType.LEFT_CLICK);\r\n\r\n // Hover → onHover callback\r\n handler.setInputAction((movement: any) => {\r\n const picked = viewer.scene.pick(movement.endPosition);\r\n if (Cesium.defined(picked) && picked.id) {\r\n callbacksRef.current?.onHover?.({\r\n id: picked.id.id,\r\n name: picked.id.name,\r\n category: 'satellite',\r\n position: { x: 0, y: 0, z: 0 },\r\n visualRadius: 0,\r\n });\r\n } else {\r\n callbacksRef.current?.onHover?.(null);\r\n }\r\n }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);\r\n\r\n return () => {\r\n handler.destroy();\r\n satMapRef.current.clear();\r\n gsMapRef.current.clear();\r\n covMapRef.current.clear();\r\n coneMapRef.current.clear();\r\n nadirMapRef.current.clear();\r\n orbitMapRef.current.clear();\r\n eciPositionsRef.current.clear();\r\n viewer.destroy();\r\n viewerRef.current = null;\r\n };\r\n }, [Cesium, showTools]);\r\n\r\n // ── Sync effect: reconcile entities on data / layer changes ───────────────\r\n //\r\n // For existing satellites (same ID, new position): entity.position is\r\n // updated in-place via ConstantPositionProperty — no remove/add required.\r\n // Only genuinely new or removed satellites trigger entity creation/deletion.\r\n useEffect(() => {\r\n const viewer = viewerRef.current;\r\n if (!viewer || !Cesium) return;\r\n\r\n // JulianDate used for static ECI→ECEF snapshots in coverage/orbit\r\n // geometry. Satellite dot positions use CallbackPositionProperty and\r\n // re-evaluate this conversion per-frame from the viewer's live clock,\r\n // so they don't depend on `jd` here.\r\n const jd = referenceTime\r\n ? Cesium.JulianDate.fromDate(referenceTime)\r\n : Cesium.JulianDate.now();\r\n\r\n // ── Satellites + stations ────────────────────────────────────────────\r\n // When `visibility.spacecraft === false` the consumer wants the whole\r\n // group hidden — feed the loop an empty list so the cleanup pass below\r\n // sweeps existing entities without us having to duplicate the removal\r\n // logic here.\r\n const seenSats = new Set<string>();\r\n const renderedSats = showSpacecraft ? [...satellites, ...stations] : [];\r\n\r\n renderedSats.forEach((obj) => {\r\n const id = obj.id;\r\n const pos3 = (obj as any).position as Vector3D;\r\n if (!pos3) return;\r\n // Guard: reject placeholder/zero positions that haven't been seeded yet.\r\n if (!Number.isFinite(pos3.x) || !Number.isFinite(pos3.y) || !Number.isFinite(pos3.z)) return;\r\n\r\n // Store the latest ECI km position so the per-frame callback can\r\n // convert it to ECEF at the actual render time rather than at the\r\n // (stale) poll-tick time.\r\n eciPositionsRef.current.set(id, pos3);\r\n seenSats.add(id);\r\n\r\n const name = (obj as any).name ?? id;\r\n const existing = satMapRef.current.get(id);\r\n\r\n if (existing) {\r\n // ECI position already written to eciPositionsRef above — the\r\n // CallbackPositionProperty will pick it up on the next frame.\r\n // Only sync label visibility here.\r\n if (existing.label) {\r\n existing.label.show = new Cesium.ConstantProperty(showLabels);\r\n } else if (showLabels) {\r\n existing.label = new Cesium.LabelGraphics(makeLabelOpts(Cesium, name));\r\n }\r\n } else {\r\n // Use CallbackPositionProperty so Cesium re-evaluates the ECI→ECEF\r\n // transform on every rendered frame using the viewer's current\r\n // JulianDate. This keeps the satellite locked to the correct point\r\n // on the rotating Earth rather than drifting in inertial space.\r\n const capturedId = id; // capture for closure\r\n // The callback runs inside Cesium's render loop on every frame.\r\n // ANY exception here halts rendering (\"An error occurred while\r\n // rendering. Rendering has stopped.\"), so we defensively catch\r\n // and return undefined — Cesium treats that as \"position\r\n // unavailable\" and skips the entity for that frame.\r\n const posProperty = new Cesium.CallbackPositionProperty(\r\n (time: any) => {\r\n try {\r\n const eciKm = eciPositionsRef.current.get(capturedId);\r\n if (!eciKm) return undefined;\r\n const fixed = eciKmToFixedCartesian3(Cesium, eciKm, time);\r\n if (\r\n !fixed ||\r\n !Number.isFinite(fixed.x) ||\r\n !Number.isFinite(fixed.y) ||\r\n !Number.isFinite(fixed.z)\r\n ) {\r\n return undefined;\r\n }\r\n return fixed;\r\n } catch {\r\n return undefined;\r\n }\r\n },\r\n false, // not constant — must be re-evaluated every frame\r\n Cesium.ReferenceFrame.FIXED,\r\n );\r\n const entity = viewer.entities.add({\r\n id,\r\n name,\r\n position: posProperty,\r\n point: makePointGraphics(Cesium, Cesium.Color.CYAN),\r\n label: showLabels\r\n ? new Cesium.LabelGraphics(makeLabelOpts(Cesium, name))\r\n : undefined,\r\n });\r\n satMapRef.current.set(id, entity);\r\n }\r\n\r\n // ── Coverage ─────────────────────────────────────────────────────────\r\n const explicitCov = (satelliteCoverages ?? []).find((c) => c.satelliteId === id);\r\n if (explicitCov) {\r\n renderExplicitCoverage(\r\n viewer, Cesium, id, pos3, explicitCov, jd,\r\n covMapRef, coneMapRef, nadirMapRef,\r\n );\r\n } else if (showCoverage) {\r\n // Auto coverage: circular ellipse computed from sub-satellite point\r\n const subSat = eciKmToSubSatellite(Cesium, pos3, jd);\r\n if (subSat && subSat.altitude > 0) {\r\n const subSatPos = Cesium.Cartesian3.fromDegrees(subSat.longitude, subSat.latitude, 0);\r\n const radius = autoFootprintRadiusM(subSat.altitude, 5);\r\n upsertEllipse(viewer, Cesium, `cov-${id}`, subSatPos, radius, Cesium.Color.CYAN, covMapRef);\r\n }\r\n } else {\r\n removeFromMap(viewer, `cov-${id}`, covMapRef);\r\n removeFromMap(viewer, `cone-${id}`, coneMapRef);\r\n removeFromMap(viewer, `nadir-${id}`, nadirMapRef);\r\n }\r\n });\r\n\r\n // Remove stale satellite entities (+ associated coverage geometry + ECI position).\r\n satMapRef.current.forEach((_, id) => {\r\n if (!seenSats.has(id)) {\r\n eciPositionsRef.current.delete(id);\r\n removeFromMap(viewer, id, satMapRef);\r\n removeFromMap(viewer, `cov-${id}`, covMapRef);\r\n removeFromMap(viewer, `cone-${id}`, coneMapRef);\r\n removeFromMap(viewer, `nadir-${id}`, nadirMapRef);\r\n }\r\n });\r\n\r\n // ── Custom objects (planets, celestial bodies, etc.) ────────────────\r\n // Earth is already rendered by Cesium's globe — skip it by name.\r\n // Other celestial bodies (Moon, etc.) are rendered as orange dots.\r\n // When `visibility.celestialBodies === false`, feed an empty list so\r\n // the cleanup pass removes any existing custom-object entities.\r\n const seenCustom = new Set<string>();\r\n const renderedCustom = showCelestialBodies ? (customObjects ?? []) : [];\r\n renderedCustom.forEach((obj) => {\r\n if (/^earth$/i.test(obj.name ?? '')) return; // skip Earth\r\n const id = obj.id;\r\n const cesPos = eciKmToFixedCartesian3(Cesium, obj.position, jd);\r\n if (!cesPos) return;\r\n seenCustom.add(id);\r\n\r\n const existing = satMapRef.current.get(`custom-${id}`);\r\n if (existing) {\r\n existing.position = new Cesium.ConstantPositionProperty(cesPos);\r\n if (existing.label) {\r\n existing.label.show = new Cesium.ConstantProperty(showLabels);\r\n } else if (showLabels) {\r\n existing.label = new Cesium.LabelGraphics(\r\n makeLabelOpts(Cesium, obj.name ?? id, Cesium.Color.ORANGE),\r\n );\r\n }\r\n } else {\r\n const entity = viewer.entities.add({\r\n id: `custom-${id}`,\r\n name: obj.name,\r\n position: cesPos,\r\n point: makePointGraphics(Cesium, Cesium.Color.ORANGE, 10),\r\n label: showLabels\r\n ? new Cesium.LabelGraphics(makeLabelOpts(Cesium, obj.name ?? id, Cesium.Color.ORANGE))\r\n : undefined,\r\n });\r\n satMapRef.current.set(`custom-${id}`, entity);\r\n }\r\n });\r\n // Remove stale custom objects\r\n satMapRef.current.forEach((_, key) => {\r\n if (key.startsWith('custom-') && !seenCustom.has(key.slice(7))) {\r\n removeFromMap(viewer, key, satMapRef);\r\n }\r\n });\r\n\r\n // ── Ground stations ──────────────────────────────────────────────────\r\n // When `visibility.groundStations === false`, feed an empty list so\r\n // the cleanup pass removes any existing ground-station entities.\r\n const seenGs = new Set<string>();\r\n const renderedGs = showGroundStations ? (groundStations ?? []) : [];\r\n renderedGs.forEach((gs) => {\r\n if (!Number.isFinite(gs.longitude) || !Number.isFinite(gs.latitude)) return;\r\n seenGs.add(gs.id);\r\n const heightM = Number.isFinite((gs as any).elevation) ? (gs as any).elevation : 0;\r\n const gsPos = Cesium.Cartesian3.fromDegrees(gs.longitude, gs.latitude, heightM);\r\n const name = gs.name ?? gs.id;\r\n\r\n const existing = gsMapRef.current.get(gs.id);\r\n if (existing) {\r\n existing.position = new Cesium.ConstantPositionProperty(gsPos);\r\n if (existing.label) {\r\n existing.label.show = new Cesium.ConstantProperty(showLabels);\r\n } else if (showLabels) {\r\n existing.label = new Cesium.LabelGraphics(\r\n makeLabelOpts(Cesium, name, Cesium.Color.YELLOW),\r\n );\r\n }\r\n } else {\r\n const entity = viewer.entities.add({\r\n id: gs.id,\r\n name,\r\n position: gsPos,\r\n point: makePointGraphics(Cesium, Cesium.Color.YELLOW, 6),\r\n label: showLabels\r\n ? new Cesium.LabelGraphics(makeLabelOpts(Cesium, name, Cesium.Color.YELLOW))\r\n : undefined,\r\n });\r\n gsMapRef.current.set(gs.id, entity);\r\n }\r\n });\r\n\r\n gsMapRef.current.forEach((_, id) => {\r\n if (!seenGs.has(id)) removeFromMap(viewer, id, gsMapRef);\r\n });\r\n\r\n // ── Orbit paths ──────────────────────────────────────────────────────\r\n if (showOrbits) {\r\n const seenOrbits = new Set<string>();\r\n\r\n (orbitPaths ?? []).forEach((path) => {\r\n const orbitId = `orbit-${path.objectId}`;\r\n seenOrbits.add(orbitId);\r\n const positions = path.points\r\n .map((p) => eciKmToFixedCartesian3(Cesium, p, jd))\r\n .filter((p): p is NonNullable<typeof p> => p != null);\r\n if (positions.length < 2) return;\r\n\r\n const orbitColor = path.color\r\n ? Cesium.Color.fromCssColorString(path.color).withAlpha(0.65)\r\n : Cesium.Color.YELLOW.withAlpha(0.55);\r\n\r\n const existing = orbitMapRef.current.get(orbitId);\r\n if (existing) {\r\n existing.polyline.positions = new Cesium.ConstantProperty(positions);\r\n } else {\r\n const entity = viewer.entities.add({\r\n id: orbitId,\r\n name: path.objectId,\r\n polyline: {\r\n positions,\r\n width: 1.5,\r\n material: new Cesium.PolylineDashMaterialProperty({\r\n color: orbitColor,\r\n dashLength: 16,\r\n }),\r\n },\r\n });\r\n orbitMapRef.current.set(orbitId, entity);\r\n }\r\n });\r\n\r\n orbitMapRef.current.forEach((_, id) => {\r\n if (!seenOrbits.has(id)) removeFromMap(viewer, id, orbitMapRef);\r\n });\r\n } else {\r\n // Orbits turned off: remove all\r\n orbitMapRef.current.forEach((_, id) => removeFromMap(viewer, id, orbitMapRef));\r\n }\r\n }, [\r\n Cesium,\r\n satellites,\r\n stations,\r\n customObjects,\r\n groundStations,\r\n orbitPaths,\r\n satelliteCoverages,\r\n showLabels,\r\n showCoverage,\r\n showOrbits,\r\n showSpacecraft,\r\n showGroundStations,\r\n showCelestialBodies,\r\n referenceTime,\r\n ]);\r\n\r\n // ── React to `view` prop changes ──────────────────────────────────────────\r\n // The imperative `setView()` handle is exposed for ad-hoc fly-tos. When\r\n // the consumer drives the camera declaratively via the `view` prop\r\n // instead, fly to the matching default destination on each change.\r\n useEffect(() => {\r\n setView(view);\r\n // setView itself depends on Cesium (constant once mounted), so it's\r\n // stable enough to omit from the dep array — but include `view` itself.\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n }, [view]);\r\n\r\n const h = typeof height === 'number' ? `${height}px` : height;\r\n return (\r\n <div\r\n ref={containerRef}\r\n className=\"zendir-zenspace3d-cesium\"\r\n style={{ width: '100%', height: h, minHeight: 200 }}\r\n />\r\n );\r\n },\r\n);\r\n\r\nexport default ZenSpace3DCesium;\r\n"],"names":["ZenSpace3DCesium"],"mappings":"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"}
1
+ {"version":3,"file":"ZenSpace3DCesium.js","names":[],"sources":["../../../src/react/3d/ZenSpace3DCesium.tsx"],"sourcesContent":["/**\n * @zendir/ui - ZenSpace3D Cesium Backend\n *\n * Cesium-based 3D Earth/orbit view. Entities are reconciled **in-place** on\n * each data update (position changes only) to avoid the WebGL context churn\n * that occurs when entities are removed and re-added every polling tick.\n *\n * Layer visibility is controlled via the `layers` prop\n * (all default to \"sensible\" if the key is absent):\n *\n * layers.labels — spacecraft / GS name labels (default: false)\n * layers.coverage — coverage footprint ellipses + cones (default: false)\n * layers.orbits — orbit-path polylines (default: true)\n *\n * Coverage geometry sources (checked in order per satellite):\n * 1. Explicit `satelliteCoverages[].footprintPolygon` — ground polygon from SDK\n * 2. Explicit `satelliteCoverages[].halfAngle` — circular cone from half-angle\n * 3. Auto-computed circular ellipse from altitude (when layers.coverage = true)\n *\n * Additional explicit coverage options per `SatelliteCoverage`:\n * showCone — 3-D sensor cone from satellite to footprint\n * showNadirLine — dashed line from satellite to sub-satellite point\n */\n\nimport React, {\n useRef,\n useEffect,\n useImperativeHandle,\n forwardRef,\n useCallback,\n} from \"react\";\nimport type {\n ZenSpace3DProps,\n ZenSpace3DHandle,\n ViewMode,\n Vector3D,\n SatelliteCoverage,\n} from \"./ZenSpace3DTypes\";\n\n// ── Constants ─────────────────────────────────────────────────────────────────\n\nconst EARTH_RADIUS_KM = 6371;\n\n// ── Coordinate helpers ────────────────────────────────────────────────────────\n\n/**\n * Convert an ECI / J2000 position (km, Earth-centred) into a Cesium\n * `Cartesian3`. Cesium's Cartesian3 lives in the **ECEF (Earth-Fixed)**\n * frame — the same frame Cesium for Unreal exposes when its\n * `CesiumGeoreference` origin is set to `TrueOrigin (0,0,0)`. We rotate\n * ECI → ECEF using `Transforms.computeTemeToPseudoFixedMatrix(jd)`,\n * which is GMST-based and accurate to sub-arcsec for visualisation\n * (no IERS data required, fully synchronous).\n *\n * Returns `null` for non-finite inputs so callers can skip stale ticks\n * without crashing Cesium's Cartesian primitives.\n *\n * @param positionKm ECI position in km (Earth-centred).\n * @param julianDate Cesium JulianDate at which to evaluate Earth's rotation.\n * Caller is responsible for advancing this with sim time.\n */\nfunction eciKmToFixedCartesian3(\n Cesium: any,\n positionKm: Vector3D,\n julianDate: any,\n): any | null {\n if (\n !positionKm ||\n !Number.isFinite(positionKm.x) ||\n !Number.isFinite(positionKm.y) ||\n !Number.isFinite(positionKm.z)\n ) {\n return null;\n }\n // ECI position in metres — Cesium works in metres throughout.\n const eciM = new Cesium.Cartesian3(\n positionKm.x * 1000,\n positionKm.y * 1000,\n positionKm.z * 1000,\n );\n const rot = Cesium.Transforms.computeTemeToPseudoFixedMatrix(julianDate);\n if (!rot) {\n // Should never happen, but Transforms can return undefined for invalid\n // dates — fall back to treating the input as already-fixed so we never\n // crash the viewer on a stray NaN date.\n return eciM;\n }\n return Cesium.Matrix3.multiplyByVector(rot, eciM, new Cesium.Cartesian3());\n}\n\n/**\n * Sub-satellite (lat/lon) point + altitude (km) of an ECI position at a\n * given epoch. Used by coverage/cone code that needs to draw on Earth's\n * surface beneath the satellite.\n */\nfunction eciKmToSubSatellite(\n Cesium: any,\n positionKm: Vector3D,\n julianDate: any,\n): { latitude: number; longitude: number; altitude: number } | null {\n const fixed = eciKmToFixedCartesian3(Cesium, positionKm, julianDate);\n if (!fixed) return null;\n const carto = Cesium.Cartographic.fromCartesian(fixed);\n if (!carto || !Number.isFinite(carto.height)) return null;\n return {\n latitude: Cesium.Math.toDegrees(carto.latitude),\n longitude: Cesium.Math.toDegrees(carto.longitude),\n altitude: carto.height / 1000, // m → km\n };\n}\n\n// ── Coverage geometry ─────────────────────────────────────────────────────────\n\n/**\n * Circular coverage footprint radius (m) on Earth surface.\n *\n * Spherical geometry:\n * α = arcsin(R·cos(ε) / (R+h)) — nadir angle\n * λ = π/2 − ε − α — Earth central angle\n * radius = R · λ — arc length on surface\n */\nfunction autoFootprintRadiusM(altitudeKm: number, minElevDeg: number): number {\n if (altitudeKm <= 0) return 0;\n const R = EARTH_RADIUS_KM;\n const eps = (minElevDeg * Math.PI) / 180;\n const sinAlpha = (R * Math.cos(eps)) / (R + altitudeKm);\n if (sinAlpha >= 1) return 0;\n const alpha = Math.asin(sinAlpha);\n const lambda = Math.PI / 2 - eps - alpha;\n return R * 1000 * lambda;\n}\n\n/** Radius (m) of the footprint circle for a sensor with the given half-angle. */\nfunction halfAngleFootprintRadiusM(\n altitudeKm: number,\n halfAngleDeg: number,\n): number {\n return altitudeKm * 1000 * Math.tan((halfAngleDeg * Math.PI) / 180);\n}\n\n// ── Entity helpers ────────────────────────────────────────────────────────────\n\ntype EntityMap = { current: Map<string, any> };\n\nfunction removeFromMap(viewer: any, id: string, map: EntityMap): void {\n if (map.current.has(id)) {\n try {\n viewer.entities.removeById(id);\n } catch (_) {\n /* already gone */\n }\n map.current.delete(id);\n }\n}\n\nfunction makePointGraphics(Cesium: any, color: any, pixelSize = 8) {\n return {\n pixelSize,\n color,\n outlineColor: Cesium.Color.WHITE,\n outlineWidth: 1,\n scaleByDistance: new Cesium.NearFarScalar(1e6, 1.5, 5e7, 0.5),\n // Always render on top so satellites hidden behind Earth are still visible\n disableDepthTestDistance: Number.POSITIVE_INFINITY,\n };\n}\n\nfunction makeLabelOpts(Cesium: any, text: string, fillColor?: any) {\n return {\n text,\n font: \"12px monospace\",\n fillColor: fillColor ?? Cesium.Color.WHITE,\n outlineColor: Cesium.Color.BLACK,\n outlineWidth: 2,\n style: Cesium.LabelStyle.FILL_AND_OUTLINE,\n pixelOffset: new Cesium.Cartesian2(12, 0),\n scaleByDistance: new Cesium.NearFarScalar(1e6, 1.0, 5e7, 0.3),\n // Fade out label when camera is very far away\n distanceDisplayCondition: new Cesium.DistanceDisplayCondition(0, 3e7),\n disableDepthTestDistance: Number.POSITIVE_INFINITY,\n };\n}\n\n/** Add or update a circular ellipse entity on the Earth surface. */\nfunction upsertEllipse(\n viewer: any,\n Cesium: any,\n id: string,\n position: any,\n radiusM: number,\n color: any,\n map: EntityMap,\n): void {\n const existing = map.current.get(id);\n if (existing) {\n existing.position = new Cesium.ConstantPositionProperty(position);\n existing.ellipse.semiMajorAxis = new Cesium.ConstantProperty(radiusM);\n existing.ellipse.semiMinorAxis = new Cesium.ConstantProperty(radiusM);\n } else {\n const entity = viewer.entities.add({\n id,\n position,\n ellipse: {\n semiMajorAxis: radiusM,\n semiMinorAxis: radiusM,\n material: color.withAlpha(0.08),\n outline: true,\n outlineColor: color.withAlpha(0.5),\n outlineWidth: 1,\n height: 0,\n },\n });\n map.current.set(id, entity);\n }\n}\n\n/**\n * Render (or update in-place) the full coverage geometry for one satellite\n * from an explicit `SatelliteCoverage` record supplied by the Zendir SDK.\n */\nfunction renderExplicitCoverage(\n viewer: any,\n Cesium: any,\n satId: string,\n satPos3: Vector3D,\n cov: SatelliteCoverage,\n julianDate: any,\n covMap: EntityMap,\n coneMap: EntityMap,\n nadirMap: EntityMap,\n): void {\n const baseColor = cov.color\n ? Cesium.Color.fromCssColorString(cov.color)\n : Cesium.Color.CYAN;\n const opacity = cov.opacity ?? 0.2;\n\n const resolvedPos = cov.satellitePosition ?? satPos3;\n const satCesPos = eciKmToFixedCartesian3(Cesium, resolvedPos, julianDate);\n const subSat = eciKmToSubSatellite(Cesium, resolvedPos, julianDate);\n const latitude = subSat?.latitude ?? NaN;\n const longitude = subSat?.longitude ?? NaN;\n const altitude = subSat?.altitude ?? NaN;\n\n const nadirLat = cov.nadirPoint?.latitude ?? latitude;\n const nadirLon = cov.nadirPoint?.longitude ?? longitude;\n\n // ── Footprint polygon or circular ellipse ──────────────────────────────────\n const covId = `cov-${satId}`;\n if (\n cov.showFootprint !== false &&\n cov.footprintPolygon &&\n cov.footprintPolygon.length >= 3\n ) {\n const positions = Cesium.Cartesian3.fromDegreesArray(\n cov.footprintPolygon.flatMap((pt) => [pt.longitude, pt.latitude]),\n );\n const existing = covMap.current.get(covId);\n if (existing) {\n existing.polygon.hierarchy = new Cesium.ConstantProperty(\n new Cesium.PolygonHierarchy(positions),\n );\n } else {\n const entity = viewer.entities.add({\n id: covId,\n polygon: {\n hierarchy: new Cesium.PolygonHierarchy(positions),\n material: baseColor.withAlpha(opacity),\n outline: true,\n outlineColor: baseColor.withAlpha(opacity * 3),\n height: 0,\n clampToGround: true,\n },\n });\n covMap.current.set(covId, entity);\n }\n } else if (\n cov.showFootprint !== false &&\n cov.halfAngle != null &&\n Number.isFinite(altitude) &&\n altitude > 0\n ) {\n const subSatPos = Cesium.Cartesian3.fromDegrees(nadirLon, nadirLat, 0);\n const radius = halfAngleFootprintRadiusM(altitude, cov.halfAngle);\n upsertEllipse(viewer, Cesium, covId, subSatPos, radius, baseColor, covMap);\n } else {\n removeFromMap(viewer, covId, covMap);\n }\n\n // ── Sensor cone (satellite → footprint, rendered as a Cesium cylinder) ─────\n const coneId = `cone-${satId}`;\n if (cov.showCone && satCesPos && Number.isFinite(altitude) && altitude > 0) {\n const radius =\n cov.halfAngle != null\n ? halfAngleFootprintRadiusM(altitude, cov.halfAngle)\n : autoFootprintRadiusM(altitude, 5);\n const coneLength = altitude * 1000; // km → m\n // Cylinder centered at mid-altitude between satellite and ground point\n const midPos = Cesium.Cartesian3.fromDegrees(\n nadirLon,\n nadirLat,\n coneLength / 2,\n );\n const existing = coneMap.current.get(coneId);\n if (existing) {\n existing.position = new Cesium.ConstantPositionProperty(midPos);\n existing.cylinder.length = new Cesium.ConstantProperty(coneLength);\n existing.cylinder.bottomRadius = new Cesium.ConstantProperty(radius);\n } else {\n const entity = viewer.entities.add({\n id: coneId,\n position: midPos,\n cylinder: {\n length: coneLength,\n topRadius: 0,\n bottomRadius: radius,\n material: baseColor.withAlpha(0.06),\n outline: true,\n outlineColor: baseColor.withAlpha(0.25),\n numberOfVerticalLines: 12,\n },\n });\n coneMap.current.set(coneId, entity);\n }\n } else {\n removeFromMap(viewer, coneId, coneMap);\n }\n\n // ── Nadir line (satellite → sub-satellite point) ───────────────────────────\n const nadirId = `nadir-${satId}`;\n if (cov.showNadirLine && satCesPos) {\n const groundPos = Cesium.Cartesian3.fromDegrees(nadirLon, nadirLat, 0);\n const existing = nadirMap.current.get(nadirId);\n if (existing) {\n existing.polyline.positions = new Cesium.ConstantProperty([\n satCesPos,\n groundPos,\n ]);\n } else {\n const entity = viewer.entities.add({\n id: nadirId,\n polyline: {\n positions: [satCesPos, groundPos],\n width: 1,\n material: new Cesium.PolylineDashMaterialProperty({\n color: baseColor.withAlpha(0.5),\n dashLength: 8,\n }),\n },\n });\n nadirMap.current.set(nadirId, entity);\n }\n } else {\n removeFromMap(viewer, nadirId, nadirMap);\n }\n}\n\n// ── Component ─────────────────────────────────────────────────────────────────\n\nexport interface ZenSpace3DCesiumProps extends ZenSpace3DProps {\n /** Cesium module from dynamic import('cesium') */\n cesium: any;\n}\n\nexport const ZenSpace3DCesium = forwardRef<\n ZenSpace3DHandle,\n ZenSpace3DCesiumProps\n>(function ZenSpace3DCesium(\n {\n satellites = [],\n stations = [],\n groundStations = [],\n customObjects = [],\n orbitPaths = [],\n satelliteCoverages = [],\n view = \"earth-orbit\",\n height = 600,\n callbacks,\n showTools = false,\n layers,\n visibility,\n referenceTime,\n cesium: Cesium,\n },\n ref,\n) {\n const containerRef = useRef<HTMLDivElement>(null);\n const viewerRef = useRef<any>(null);\n\n // Stash callbacks in a ref so click/hover handlers never close over a stale\n // function reference — and never make the mount effect depend on them.\n const callbacksRef = useRef(callbacks);\n useEffect(() => {\n callbacksRef.current = callbacks;\n }, [callbacks]);\n\n // ── Entity maps for in-place reconciliation ────────────────────────────────\n // Each map: entity-id → Cesium entity object (only live entities live here).\n const satMapRef = useRef<Map<string, any>>(new Map()); // spacecraft + station dots\n const gsMapRef = useRef<Map<string, any>>(new Map()); // ground station dots\n const covMapRef = useRef<Map<string, any>>(new Map()); // coverage ellipses / polygons\n const coneMapRef = useRef<Map<string, any>>(new Map()); // sensor cones\n const nadirMapRef = useRef<Map<string, any>>(new Map()); // nadir lines\n const orbitMapRef = useRef<Map<string, any>>(new Map()); // orbit polylines\n\n // ── Latest ECI positions for satellite callback-properties ─────────────────\n // Satellites use CallbackPositionProperty so Cesium re-derives ECEF from the\n // stored ECI position on every rendered frame (using the current JulianDate).\n // This makes satellites track Earth's rotation smoothly between API poll ticks,\n // fixing the \"satellite frozen while Earth rotates\" bug.\n const eciPositionsRef = useRef<Map<string, Vector3D>>(new Map());\n\n // ── Layer visibility ──────────────────────────────────────────────────────\n // Render-flag layers (always-on by default for orbits; off by default for\n // labels/coverage). Derive primitives so the sync effect deps are cheap.\n const showLabels = layers?.labels === true; // off by default\n const showCoverage = layers?.coverage === true; // off by default\n const showOrbits = layers?.orbits !== false; // on by default\n\n // Object-group visibility — toggle whole categories of markers off without\n // unmounting them. Defaults to \"everything visible\" so existing consumers\n // who never set `visibility` are unaffected.\n const showSpacecraft = visibility?.spacecraft !== false;\n const showGroundStations = visibility?.groundStations !== false;\n const showCelestialBodies = visibility?.celestialBodies !== false;\n\n // ── Imperative handle ──────────────────────────────────────────────────────\n const focusOn = useCallback(\n (objectId: string, options?: { zoom?: number; animate?: boolean }) => {\n const viewer = viewerRef.current;\n if (!viewer) return;\n const entity = viewer.entities.getById(objectId);\n if (entity) {\n viewer.zoomTo(entity, {\n duration: options?.animate !== false ? 1.5 : 0,\n });\n }\n },\n [],\n );\n\n const setView = useCallback(\n (mode: ViewMode) => {\n const viewer = viewerRef.current;\n if (!viewer) return;\n if (mode === \"earth-orbit\") {\n viewer.camera.flyTo({\n destination: Cesium.Cartesian3.fromDegrees(0, 0, 2e7),\n });\n } else if (mode === \"solar-system\") {\n viewer.camera.flyTo({\n destination: Cesium.Cartesian3.fromDegrees(0, 0, 5e7),\n });\n }\n },\n [Cesium],\n );\n\n useImperativeHandle(\n ref,\n (): ZenSpace3DHandle => ({\n focusOn,\n flyTo: focusOn,\n setView,\n setTime: () => {},\n setTimeScale: () => {},\n togglePlay: () => {},\n setLayerVisibility: () => {},\n getCameraState: () => ({}) as any,\n setCameraState: () => {},\n exportImage: () => \"\",\n exportScene: () => new Blob(),\n getVisibleObjects: () => [],\n findObjects: () => [],\n addObject: () => {},\n removeObject: () => {},\n updateObject: () => {},\n measureDistance: () => 0,\n }),\n [focusOn, setView],\n );\n\n // ── Mount effect: create Cesium Viewer + event handlers ONCE ──────────────\n //\n // Does NOT depend on the data arrays (satellites, orbitPaths, etc.) or on\n // `callbacks`. Both produce fresh references on every parent render / poll\n // tick. Including them would tear down + rebuild Cesium every 2 s, leaking\n // WebGL contexts until Chrome hits its hard cap (~16).\n useEffect(() => {\n if (!containerRef.current || !Cesium) return;\n\n // Clear maps in case this is a hot-reload remount\n satMapRef.current.clear();\n gsMapRef.current.clear();\n covMapRef.current.clear();\n coneMapRef.current.clear();\n nadirMapRef.current.clear();\n orbitMapRef.current.clear();\n eciPositionsRef.current.clear();\n\n const viewer = new Cesium.Viewer(containerRef.current, {\n baseLayerPicker: false,\n fullscreenButton: false,\n vrButton: false,\n geocoder: false,\n homeButton: !!showTools,\n sceneModePicker: false,\n timeline: false,\n navigationHelpButton: !!showTools,\n animation: false,\n scene3DOnly: true,\n useDefaultRenderLoop: true,\n requestRenderMode: false,\n });\n\n viewer.scene.globe.enableLighting = true;\n viewer.scene.backgroundColor = Cesium.Color.BLACK;\n\n // Surface the actual exception text on render-loop crashes. Without\n // this listener Cesium only shows \"An error occurred while rendering.\"\n // and the stack trace is buried.\n viewer.scene.renderError.addEventListener((scene: any, err: unknown) => {\n // eslint-disable-next-line no-console\n console.error(\"[ZenSpace3D] Cesium render error:\", err);\n });\n\n // Advance the clock at 1× real time so Cesium continuously evaluates\n // ECI→ECEF for the correct current moment. Without this, the JulianDate\n // passed to satellite CallbackPositionProperty callbacks would be frozen\n // at the viewer-creation instant and satellites would drift relative to\n // Earth as wall-clock time advanced.\n viewer.clock.currentTime = Cesium.JulianDate.now();\n viewer.clock.multiplier = 1;\n viewer.clock.shouldAnimate = true;\n\n viewerRef.current = viewer;\n\n const handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);\n\n // Click → select\n handler.setInputAction((movement: any) => {\n const picked = viewer.scene.pick(movement.position);\n if (\n Cesium.defined(picked) &&\n picked.id &&\n callbacksRef.current?.onSelect\n ) {\n callbacksRef.current.onSelect({\n id: picked.id.id,\n name: picked.id.name,\n category: \"satellite\",\n position: { x: 0, y: 0, z: 0 },\n visualRadius: 0,\n });\n }\n }, Cesium.ScreenSpaceEventType.LEFT_CLICK);\n\n // Hover → onHover callback\n handler.setInputAction((movement: any) => {\n const picked = viewer.scene.pick(movement.endPosition);\n if (Cesium.defined(picked) && picked.id) {\n callbacksRef.current?.onHover?.({\n id: picked.id.id,\n name: picked.id.name,\n category: \"satellite\",\n position: { x: 0, y: 0, z: 0 },\n visualRadius: 0,\n });\n } else {\n callbacksRef.current?.onHover?.(null);\n }\n }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);\n\n return () => {\n handler.destroy();\n satMapRef.current.clear();\n gsMapRef.current.clear();\n covMapRef.current.clear();\n coneMapRef.current.clear();\n nadirMapRef.current.clear();\n orbitMapRef.current.clear();\n eciPositionsRef.current.clear();\n viewer.destroy();\n viewerRef.current = null;\n };\n }, [Cesium, showTools]);\n\n // ── Sync effect: reconcile entities on data / layer changes ───────────────\n //\n // For existing satellites (same ID, new position): entity.position is\n // updated in-place via ConstantPositionProperty — no remove/add required.\n // Only genuinely new or removed satellites trigger entity creation/deletion.\n useEffect(() => {\n const viewer = viewerRef.current;\n if (!viewer || !Cesium) return;\n\n // JulianDate used for static ECI→ECEF snapshots in coverage/orbit\n // geometry. Satellite dot positions use CallbackPositionProperty and\n // re-evaluate this conversion per-frame from the viewer's live clock,\n // so they don't depend on `jd` here.\n const jd = referenceTime\n ? Cesium.JulianDate.fromDate(referenceTime)\n : Cesium.JulianDate.now();\n\n // ── Satellites + stations ────────────────────────────────────────────\n // When `visibility.spacecraft === false` the consumer wants the whole\n // group hidden — feed the loop an empty list so the cleanup pass below\n // sweeps existing entities without us having to duplicate the removal\n // logic here.\n const seenSats = new Set<string>();\n const renderedSats = showSpacecraft ? [...satellites, ...stations] : [];\n\n renderedSats.forEach((obj) => {\n const id = obj.id;\n const pos3 = (obj as any).position as Vector3D;\n if (!pos3) return;\n // Guard: reject placeholder/zero positions that haven't been seeded yet.\n if (\n !Number.isFinite(pos3.x) ||\n !Number.isFinite(pos3.y) ||\n !Number.isFinite(pos3.z)\n )\n return;\n\n // Store the latest ECI km position so the per-frame callback can\n // convert it to ECEF at the actual render time rather than at the\n // (stale) poll-tick time.\n eciPositionsRef.current.set(id, pos3);\n seenSats.add(id);\n\n const name = (obj as any).name ?? id;\n const existing = satMapRef.current.get(id);\n\n if (existing) {\n // ECI position already written to eciPositionsRef above — the\n // CallbackPositionProperty will pick it up on the next frame.\n // Only sync label visibility here.\n if (existing.label) {\n existing.label.show = new Cesium.ConstantProperty(showLabels);\n } else if (showLabels) {\n existing.label = new Cesium.LabelGraphics(\n makeLabelOpts(Cesium, name),\n );\n }\n } else {\n // Use CallbackPositionProperty so Cesium re-evaluates the ECI→ECEF\n // transform on every rendered frame using the viewer's current\n // JulianDate. This keeps the satellite locked to the correct point\n // on the rotating Earth rather than drifting in inertial space.\n const capturedId = id; // capture for closure\n // The callback runs inside Cesium's render loop on every frame.\n // ANY exception here halts rendering (\"An error occurred while\n // rendering. Rendering has stopped.\"), so we defensively catch\n // and return undefined — Cesium treats that as \"position\n // unavailable\" and skips the entity for that frame.\n const posProperty = new Cesium.CallbackPositionProperty(\n (time: any) => {\n try {\n const eciKm = eciPositionsRef.current.get(capturedId);\n if (!eciKm) return undefined;\n const fixed = eciKmToFixedCartesian3(Cesium, eciKm, time);\n if (\n !fixed ||\n !Number.isFinite(fixed.x) ||\n !Number.isFinite(fixed.y) ||\n !Number.isFinite(fixed.z)\n ) {\n return undefined;\n }\n return fixed;\n } catch {\n return undefined;\n }\n },\n false, // not constant — must be re-evaluated every frame\n Cesium.ReferenceFrame.FIXED,\n );\n const entity = viewer.entities.add({\n id,\n name,\n position: posProperty,\n point: makePointGraphics(Cesium, Cesium.Color.CYAN),\n label: showLabels\n ? new Cesium.LabelGraphics(makeLabelOpts(Cesium, name))\n : undefined,\n });\n satMapRef.current.set(id, entity);\n }\n\n // ── Coverage ─────────────────────────────────────────────────────────\n const explicitCov = (satelliteCoverages ?? []).find(\n (c) => c.satelliteId === id,\n );\n if (explicitCov) {\n renderExplicitCoverage(\n viewer,\n Cesium,\n id,\n pos3,\n explicitCov,\n jd,\n covMapRef,\n coneMapRef,\n nadirMapRef,\n );\n } else if (showCoverage) {\n // Auto coverage: circular ellipse computed from sub-satellite point\n const subSat = eciKmToSubSatellite(Cesium, pos3, jd);\n if (subSat && subSat.altitude > 0) {\n const subSatPos = Cesium.Cartesian3.fromDegrees(\n subSat.longitude,\n subSat.latitude,\n 0,\n );\n const radius = autoFootprintRadiusM(subSat.altitude, 5);\n upsertEllipse(\n viewer,\n Cesium,\n `cov-${id}`,\n subSatPos,\n radius,\n Cesium.Color.CYAN,\n covMapRef,\n );\n }\n } else {\n removeFromMap(viewer, `cov-${id}`, covMapRef);\n removeFromMap(viewer, `cone-${id}`, coneMapRef);\n removeFromMap(viewer, `nadir-${id}`, nadirMapRef);\n }\n });\n\n // Remove stale satellite entities (+ associated coverage geometry + ECI position).\n satMapRef.current.forEach((_, id) => {\n if (!seenSats.has(id)) {\n eciPositionsRef.current.delete(id);\n removeFromMap(viewer, id, satMapRef);\n removeFromMap(viewer, `cov-${id}`, covMapRef);\n removeFromMap(viewer, `cone-${id}`, coneMapRef);\n removeFromMap(viewer, `nadir-${id}`, nadirMapRef);\n }\n });\n\n // ── Custom objects (planets, celestial bodies, etc.) ────────────────\n // Earth is already rendered by Cesium's globe — skip it by name.\n // Other celestial bodies (Moon, etc.) are rendered as orange dots.\n // When `visibility.celestialBodies === false`, feed an empty list so\n // the cleanup pass removes any existing custom-object entities.\n const seenCustom = new Set<string>();\n const renderedCustom = showCelestialBodies ? (customObjects ?? []) : [];\n renderedCustom.forEach((obj) => {\n if (/^earth$/i.test(obj.name ?? \"\")) return; // skip Earth\n const id = obj.id;\n const cesPos = eciKmToFixedCartesian3(Cesium, obj.position, jd);\n if (!cesPos) return;\n seenCustom.add(id);\n\n const existing = satMapRef.current.get(`custom-${id}`);\n if (existing) {\n existing.position = new Cesium.ConstantPositionProperty(cesPos);\n if (existing.label) {\n existing.label.show = new Cesium.ConstantProperty(showLabels);\n } else if (showLabels) {\n existing.label = new Cesium.LabelGraphics(\n makeLabelOpts(Cesium, obj.name ?? id, Cesium.Color.ORANGE),\n );\n }\n } else {\n const entity = viewer.entities.add({\n id: `custom-${id}`,\n name: obj.name,\n position: cesPos,\n point: makePointGraphics(Cesium, Cesium.Color.ORANGE, 10),\n label: showLabels\n ? new Cesium.LabelGraphics(\n makeLabelOpts(Cesium, obj.name ?? id, Cesium.Color.ORANGE),\n )\n : undefined,\n });\n satMapRef.current.set(`custom-${id}`, entity);\n }\n });\n // Remove stale custom objects\n satMapRef.current.forEach((_, key) => {\n if (key.startsWith(\"custom-\") && !seenCustom.has(key.slice(7))) {\n removeFromMap(viewer, key, satMapRef);\n }\n });\n\n // ── Ground stations ──────────────────────────────────────────────────\n // When `visibility.groundStations === false`, feed an empty list so\n // the cleanup pass removes any existing ground-station entities.\n const seenGs = new Set<string>();\n const renderedGs = showGroundStations ? (groundStations ?? []) : [];\n renderedGs.forEach((gs) => {\n if (!Number.isFinite(gs.longitude) || !Number.isFinite(gs.latitude))\n return;\n seenGs.add(gs.id);\n const heightM = Number.isFinite((gs as any).elevation)\n ? (gs as any).elevation\n : 0;\n const gsPos = Cesium.Cartesian3.fromDegrees(\n gs.longitude,\n gs.latitude,\n heightM,\n );\n const name = gs.name ?? gs.id;\n\n const existing = gsMapRef.current.get(gs.id);\n if (existing) {\n existing.position = new Cesium.ConstantPositionProperty(gsPos);\n if (existing.label) {\n existing.label.show = new Cesium.ConstantProperty(showLabels);\n } else if (showLabels) {\n existing.label = new Cesium.LabelGraphics(\n makeLabelOpts(Cesium, name, Cesium.Color.YELLOW),\n );\n }\n } else {\n const entity = viewer.entities.add({\n id: gs.id,\n name,\n position: gsPos,\n point: makePointGraphics(Cesium, Cesium.Color.YELLOW, 6),\n label: showLabels\n ? new Cesium.LabelGraphics(\n makeLabelOpts(Cesium, name, Cesium.Color.YELLOW),\n )\n : undefined,\n });\n gsMapRef.current.set(gs.id, entity);\n }\n });\n\n gsMapRef.current.forEach((_, id) => {\n if (!seenGs.has(id)) removeFromMap(viewer, id, gsMapRef);\n });\n\n // ── Orbit paths ──────────────────────────────────────────────────────\n if (showOrbits) {\n const seenOrbits = new Set<string>();\n\n (orbitPaths ?? []).forEach((path) => {\n const orbitId = `orbit-${path.objectId}`;\n seenOrbits.add(orbitId);\n const positions = path.points\n .map((p) => eciKmToFixedCartesian3(Cesium, p, jd))\n .filter((p): p is NonNullable<typeof p> => p != null);\n if (positions.length < 2) return;\n\n const orbitColor = path.color\n ? Cesium.Color.fromCssColorString(path.color).withAlpha(0.65)\n : Cesium.Color.YELLOW.withAlpha(0.55);\n\n const existing = orbitMapRef.current.get(orbitId);\n if (existing) {\n existing.polyline.positions = new Cesium.ConstantProperty(positions);\n } else {\n const entity = viewer.entities.add({\n id: orbitId,\n name: path.objectId,\n polyline: {\n positions,\n width: 1.5,\n material: new Cesium.PolylineDashMaterialProperty({\n color: orbitColor,\n dashLength: 16,\n }),\n },\n });\n orbitMapRef.current.set(orbitId, entity);\n }\n });\n\n orbitMapRef.current.forEach((_, id) => {\n if (!seenOrbits.has(id)) removeFromMap(viewer, id, orbitMapRef);\n });\n } else {\n // Orbits turned off: remove all\n orbitMapRef.current.forEach((_, id) =>\n removeFromMap(viewer, id, orbitMapRef),\n );\n }\n }, [\n Cesium,\n satellites,\n stations,\n customObjects,\n groundStations,\n orbitPaths,\n satelliteCoverages,\n showLabels,\n showCoverage,\n showOrbits,\n showSpacecraft,\n showGroundStations,\n showCelestialBodies,\n referenceTime,\n ]);\n\n // ── React to `view` prop changes ──────────────────────────────────────────\n // The imperative `setView()` handle is exposed for ad-hoc fly-tos. When\n // the consumer drives the camera declaratively via the `view` prop\n // instead, fly to the matching default destination on each change.\n useEffect(() => {\n setView(view);\n // setView itself depends on Cesium (constant once mounted), so it's\n // stable enough to omit from the dep array — but include `view` itself.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [view]);\n\n const h = typeof height === \"number\" ? `${height}px` : height;\n return (\n <div\n ref={containerRef}\n className=\"zendir-zenspace3d-cesium\"\n style={{ width: \"100%\", height: h, minHeight: 200 }}\n />\n );\n});\n\nexport default ZenSpace3DCesium;\n"],"mappings":"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"}
@@ -1,4 +1,11 @@
1
- const atmosphereVertexShader = `
1
+ //#region src/react/3d/ZenSpace3DShaders.ts
2
+ /**
3
+ * @zendir/ui - ZenSpace3D Shaders
4
+ *
5
+ * Advanced GLSL shaders for atmosphere, glow effects, coverage visualization,
6
+ * and other space rendering effects.
7
+ */
8
+ var atmosphereVertexShader = `
2
9
  varying vec3 vNormal;
3
10
  varying vec3 vPosition;
4
11
  varying float vIntensity;
@@ -15,7 +22,7 @@ void main() {
15
22
  gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
16
23
  }
17
24
  `;
18
- const atmosphereFragmentShader = `
25
+ var atmosphereFragmentShader = `
19
26
  varying vec3 vNormal;
20
27
  varying vec3 vPosition;
21
28
  varying float vIntensity;
@@ -36,7 +43,7 @@ void main() {
36
43
  gl_FragColor = vec4(color, alpha);
37
44
  }
38
45
  `;
39
- const starsVertexShader = `
46
+ var starsVertexShader = `
40
47
  attribute float opacity;
41
48
  attribute float size;
42
49
  attribute vec3 customColor;
@@ -65,7 +72,7 @@ void main() {
65
72
  gl_Position = projectionMatrix * mvPosition;
66
73
  }
67
74
  `;
68
- const starsFragmentShader = `
75
+ var starsFragmentShader = `
69
76
  varying float vOpacity;
70
77
  varying vec3 vColor;
71
78
 
@@ -85,7 +92,7 @@ void main() {
85
92
  gl_FragColor = vec4(color, alpha);
86
93
  }
87
94
  `;
88
- const coverageVertexShader = `
95
+ var coverageVertexShader = `
89
96
  varying vec2 vUv;
90
97
  varying vec3 vNormal;
91
98
  varying vec3 vPosition;
@@ -98,7 +105,7 @@ void main() {
98
105
  gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
99
106
  }
100
107
  `;
101
- const coverageFragmentShader = `
108
+ var coverageFragmentShader = `
102
109
  uniform sampler2D coverageMap;
103
110
  uniform vec3 lowColor;
104
111
  uniform vec3 highColor;
@@ -132,7 +139,7 @@ void main() {
132
139
  gl_FragColor = vec4(color, coverage * opacity);
133
140
  }
134
141
  `;
135
- const visibilityConeVertexShader = `
142
+ var visibilityConeVertexShader = `
136
143
  varying vec3 vPosition;
137
144
  varying vec3 vNormal;
138
145
  varying float vDistFromApex;
@@ -147,7 +154,7 @@ void main() {
147
154
  gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
148
155
  }
149
156
  `;
150
- const visibilityConeFragmentShader = `
157
+ var visibilityConeFragmentShader = `
151
158
  uniform vec3 coneColor;
152
159
  uniform float coneOpacity;
153
160
  uniform float time;
@@ -174,7 +181,7 @@ void main() {
174
181
  gl_FragColor = vec4(coneColor, alpha);
175
182
  }
176
183
  `;
177
- const orbitLineVertexShader = `
184
+ var orbitLineVertexShader = `
178
185
  attribute float lineDistance;
179
186
  varying float vLineDistance;
180
187
  varying float vOpacity;
@@ -195,7 +202,7 @@ void main() {
195
202
  gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
196
203
  }
197
204
  `;
198
- const orbitLineFragmentShader = `
205
+ var orbitLineFragmentShader = `
199
206
  uniform vec3 lineColor;
200
207
  uniform float lineOpacity;
201
208
 
@@ -206,7 +213,7 @@ void main() {
206
213
  gl_FragColor = vec4(lineColor, lineOpacity * vOpacity);
207
214
  }
208
215
  `;
209
- const objectGlowVertexShader = `
216
+ var objectGlowVertexShader = `
210
217
  varying vec3 vNormal;
211
218
  varying vec3 vViewPosition;
212
219
 
@@ -218,7 +225,7 @@ void main() {
218
225
  gl_Position = projectionMatrix * mvPosition;
219
226
  }
220
227
  `;
221
- const objectGlowFragmentShader = `
228
+ var objectGlowFragmentShader = `
222
229
  uniform vec3 glowColor;
223
230
  uniform float glowIntensity;
224
231
  uniform float glowPower;
@@ -236,7 +243,7 @@ void main() {
236
243
  gl_FragColor = vec4(color, alpha);
237
244
  }
238
245
  `;
239
- const selectionRingVertexShader = `
246
+ var selectionRingVertexShader = `
240
247
  varying vec2 vUv;
241
248
 
242
249
  void main() {
@@ -244,7 +251,7 @@ void main() {
244
251
  gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
245
252
  }
246
253
  `;
247
- const selectionRingFragmentShader = `
254
+ var selectionRingFragmentShader = `
248
255
  uniform vec3 ringColor;
249
256
  uniform float time;
250
257
  uniform float ringWidth;
@@ -272,7 +279,7 @@ void main() {
272
279
  gl_FragColor = vec4(ringColor, alpha);
273
280
  }
274
281
  `;
275
- const terminatorVertexShader = `
282
+ var terminatorVertexShader = `
276
283
  varying vec3 vWorldPosition;
277
284
  varying vec3 vNormal;
278
285
 
@@ -283,7 +290,7 @@ void main() {
283
290
  gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
284
291
  }
285
292
  `;
286
- const terminatorFragmentShader = `
293
+ var terminatorFragmentShader = `
287
294
  uniform vec3 sunDirection;
288
295
  uniform sampler2D dayTexture;
289
296
  uniform sampler2D nightTexture;
@@ -317,7 +324,7 @@ void main() {
317
324
  gl_FragColor = color;
318
325
  }
319
326
  `;
320
- const gridVertexShader = `
327
+ var gridVertexShader = `
321
328
  varying vec3 vPosition;
322
329
 
323
330
  void main() {
@@ -325,7 +332,7 @@ void main() {
325
332
  gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
326
333
  }
327
334
  `;
328
- const gridFragmentShader = `
335
+ var gridFragmentShader = `
329
336
  uniform vec3 gridColor;
330
337
  uniform float gridOpacity;
331
338
  uniform float gridSpacing;
@@ -353,7 +360,7 @@ void main() {
353
360
  gl_FragColor = vec4(gridColor, alpha);
354
361
  }
355
362
  `;
356
- const planetRingVertexShader = `
363
+ var planetRingVertexShader = `
357
364
  varying vec2 vUv;
358
365
  varying vec3 vWorldPosition;
359
366
 
@@ -364,7 +371,7 @@ void main() {
364
371
  gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
365
372
  }
366
373
  `;
367
- const planetRingFragmentShader = `
374
+ var planetRingFragmentShader = `
368
375
  uniform vec3 ringColor;
369
376
  uniform float innerRadius;
370
377
  uniform float outerRadius;
@@ -395,7 +402,7 @@ void main() {
395
402
  gl_FragColor = vec4(ringColor, alpha);
396
403
  }
397
404
  `;
398
- const debrisVertexShader = `
405
+ var debrisVertexShader = `
399
406
  attribute vec3 instancePosition;
400
407
  attribute float instanceSize;
401
408
  attribute vec3 instanceColor;
@@ -420,7 +427,7 @@ void main() {
420
427
  gl_Position = projectionMatrix * modelViewMatrix * vec4(transformed, 1.0);
421
428
  }
422
429
  `;
423
- const debrisFragmentShader = `
430
+ var debrisFragmentShader = `
424
431
  varying vec3 vColor;
425
432
  varying float vSize;
426
433
 
@@ -428,51 +435,39 @@ void main() {
428
435
  gl_FragColor = vec4(vColor, 1.0);
429
436
  }
430
437
  `;
431
- function createAtmosphereUniforms(color = [0.3, 0.6, 1], intensity = 1.5) {
432
- return {
433
- glowColor: { value: color },
434
- glowIntensity: { value: intensity }
435
- };
438
+ function createAtmosphereUniforms(color = [
439
+ .3,
440
+ .6,
441
+ 1
442
+ ], intensity = 1.5) {
443
+ return {
444
+ glowColor: { value: color },
445
+ glowIntensity: { value: intensity }
446
+ };
436
447
  }
437
448
  function createStarsUniforms(pointSize = 2) {
438
- return {
439
- time: { value: 0 },
440
- pointSize: { value: pointSize }
441
- };
449
+ return {
450
+ time: { value: 0 },
451
+ pointSize: { value: pointSize }
452
+ };
442
453
  }
443
- function createVisibilityConeUniforms(color = [0.2, 0.8, 0.9], opacity = 0.3) {
444
- return {
445
- coneColor: { value: color },
446
- coneOpacity: { value: opacity },
447
- time: { value: 0 },
448
- apexPosition: { value: [0, 0, 0] }
449
- };
454
+ function createVisibilityConeUniforms(color = [
455
+ .2,
456
+ .8,
457
+ .9
458
+ ], opacity = .3) {
459
+ return {
460
+ coneColor: { value: color },
461
+ coneOpacity: { value: opacity },
462
+ time: { value: 0 },
463
+ apexPosition: { value: [
464
+ 0,
465
+ 0,
466
+ 0
467
+ ] }
468
+ };
450
469
  }
451
- export {
452
- atmosphereFragmentShader,
453
- atmosphereVertexShader,
454
- coverageFragmentShader,
455
- coverageVertexShader,
456
- createAtmosphereUniforms,
457
- createStarsUniforms,
458
- createVisibilityConeUniforms,
459
- debrisFragmentShader,
460
- debrisVertexShader,
461
- gridFragmentShader,
462
- gridVertexShader,
463
- objectGlowFragmentShader,
464
- objectGlowVertexShader,
465
- orbitLineFragmentShader,
466
- orbitLineVertexShader,
467
- planetRingFragmentShader,
468
- planetRingVertexShader,
469
- selectionRingFragmentShader,
470
- selectionRingVertexShader,
471
- starsFragmentShader,
472
- starsVertexShader,
473
- terminatorFragmentShader,
474
- terminatorVertexShader,
475
- visibilityConeFragmentShader,
476
- visibilityConeVertexShader
477
- };
478
- //# sourceMappingURL=ZenSpace3DShaders.js.map
470
+ //#endregion
471
+ export { atmosphereFragmentShader, atmosphereVertexShader, coverageFragmentShader, coverageVertexShader, createAtmosphereUniforms, createStarsUniforms, createVisibilityConeUniforms, debrisFragmentShader, debrisVertexShader, gridFragmentShader, gridVertexShader, objectGlowFragmentShader, objectGlowVertexShader, orbitLineFragmentShader, orbitLineVertexShader, planetRingFragmentShader, planetRingVertexShader, selectionRingFragmentShader, selectionRingVertexShader, starsFragmentShader, starsVertexShader, terminatorFragmentShader, terminatorVertexShader, visibilityConeFragmentShader, visibilityConeVertexShader };
472
+
473
+ //# sourceMappingURL=ZenSpace3DShaders.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ZenSpace3DShaders.js","sources":["../../../src/react/3d/ZenSpace3DShaders.ts"],"sourcesContent":["/**\r\n * @zendir/ui - ZenSpace3D Shaders\r\n * \r\n * Advanced GLSL shaders for atmosphere, glow effects, coverage visualization,\r\n * and other space rendering effects.\r\n */\r\n\r\n// =============================================================================\r\n// Atmosphere Shader (Enhanced from original)\r\n// =============================================================================\r\n\r\nexport const atmosphereVertexShader = `\r\nvarying vec3 vNormal;\r\nvarying vec3 vPosition;\r\nvarying float vIntensity;\r\n\r\nvoid main() {\r\n vNormal = normalize(normalMatrix * normal);\r\n vPosition = position;\r\n \r\n // Calculate intensity based on view angle\r\n vec4 worldPosition = modelMatrix * vec4(position, 1.0);\r\n vec3 viewDirection = normalize(cameraPosition - worldPosition.xyz);\r\n vIntensity = pow(0.65 - dot(vNormal, viewDirection), 2.0);\r\n \r\n gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\r\n}\r\n`;\r\n\r\nexport const atmosphereFragmentShader = `\r\nvarying vec3 vNormal;\r\nvarying vec3 vPosition;\r\nvarying float vIntensity;\r\n\r\nuniform vec3 glowColor;\r\nuniform float glowIntensity;\r\n\r\nvoid main() {\r\n // Fresnel-based glow\r\n float intensity = vIntensity * glowIntensity;\r\n \r\n // Add subtle color variation\r\n vec3 color = glowColor * intensity;\r\n \r\n // Fade at edges for smoother blending\r\n float alpha = intensity * 0.8;\r\n \r\n gl_FragColor = vec4(color, alpha);\r\n}\r\n`;\r\n\r\n// =============================================================================\r\n// Enhanced Stars Shader (Twinkling with nebula)\r\n// =============================================================================\r\n\r\nexport const starsVertexShader = `\r\nattribute float opacity;\r\nattribute float size;\r\nattribute vec3 customColor;\r\n\r\nvarying float vOpacity;\r\nvarying vec3 vColor;\r\n\r\nuniform float time;\r\nuniform float pointSize;\r\n\r\nvoid main() {\r\n vOpacity = opacity;\r\n vColor = customColor;\r\n \r\n // Twinkle effect\r\n float twinkle = sin(time * (0.5 + opacity * 2.0) + opacity * 100.0) * 0.5 + 0.5;\r\n vOpacity = opacity * (0.6 + twinkle * 0.4);\r\n \r\n vec4 mvPosition = modelViewMatrix * vec4(position, 1.0);\r\n \r\n // Size attenuation\r\n float sizeMultiplier = size > 0.0 ? size : 1.0;\r\n gl_PointSize = pointSize * sizeMultiplier * (300.0 / -mvPosition.z);\r\n gl_PointSize = clamp(gl_PointSize, 0.5, 8.0);\r\n \r\n gl_Position = projectionMatrix * mvPosition;\r\n}\r\n`;\r\n\r\nexport const starsFragmentShader = `\r\nvarying float vOpacity;\r\nvarying vec3 vColor;\r\n\r\nvoid main() {\r\n // Circular point with soft edge\r\n vec2 center = gl_PointCoord - vec2(0.5);\r\n float dist = length(center);\r\n \r\n if (dist > 0.5) discard;\r\n \r\n // Soft glow falloff\r\n float alpha = smoothstep(0.5, 0.0, dist) * vOpacity;\r\n \r\n // Apply color\r\n vec3 color = vColor.r > 0.0 ? vColor : vec3(1.0, 1.0, 1.0);\r\n \r\n gl_FragColor = vec4(color, alpha);\r\n}\r\n`;\r\n\r\n// =============================================================================\r\n// Coverage Heatmap Shader\r\n// =============================================================================\r\n\r\nexport const coverageVertexShader = `\r\nvarying vec2 vUv;\r\nvarying vec3 vNormal;\r\nvarying vec3 vPosition;\r\n\r\nvoid main() {\r\n vUv = uv;\r\n vNormal = normalize(normalMatrix * normal);\r\n vPosition = (modelMatrix * vec4(position, 1.0)).xyz;\r\n \r\n gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\r\n}\r\n`;\r\n\r\nexport const coverageFragmentShader = `\r\nuniform sampler2D coverageMap;\r\nuniform vec3 lowColor;\r\nuniform vec3 highColor;\r\nuniform float opacity;\r\nuniform float time;\r\n\r\nvarying vec2 vUv;\r\nvarying vec3 vNormal;\r\nvarying vec3 vPosition;\r\n\r\nvoid main() {\r\n // Sample coverage value\r\n float coverage = texture2D(coverageMap, vUv).r;\r\n \r\n // Animated pulse for active areas\r\n float pulse = sin(time * 2.0) * 0.1 + 0.9;\r\n coverage *= coverage > 0.5 ? pulse : 1.0;\r\n \r\n // Color gradient\r\n vec3 color = mix(lowColor, highColor, coverage);\r\n \r\n // Fresnel edge highlight\r\n vec3 viewDir = normalize(cameraPosition - vPosition);\r\n float fresnel = pow(1.0 - dot(vNormal, viewDir), 2.0);\r\n color += vec3(0.1, 0.3, 0.5) * fresnel * coverage;\r\n \r\n // Hexagon pattern overlay (subtle)\r\n float hexPattern = fract(vUv.x * 20.0 + vUv.y * 10.0);\r\n color *= 0.95 + hexPattern * 0.05;\r\n \r\n gl_FragColor = vec4(color, coverage * opacity);\r\n}\r\n`;\r\n\r\n// =============================================================================\r\n// Visibility Cone Shader\r\n// =============================================================================\r\n\r\nexport const visibilityConeVertexShader = `\r\nvarying vec3 vPosition;\r\nvarying vec3 vNormal;\r\nvarying float vDistFromApex;\r\n\r\nuniform vec3 apexPosition;\r\n\r\nvoid main() {\r\n vPosition = (modelMatrix * vec4(position, 1.0)).xyz;\r\n vNormal = normalize(normalMatrix * normal);\r\n vDistFromApex = distance(position, apexPosition);\r\n \r\n gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\r\n}\r\n`;\r\n\r\nexport const visibilityConeFragmentShader = `\r\nuniform vec3 coneColor;\r\nuniform float coneOpacity;\r\nuniform float time;\r\n\r\nvarying vec3 vPosition;\r\nvarying vec3 vNormal;\r\nvarying float vDistFromApex;\r\n\r\nvoid main() {\r\n // Fresnel effect for edge visibility\r\n vec3 viewDir = normalize(cameraPosition - vPosition);\r\n float fresnel = pow(1.0 - abs(dot(vNormal, viewDir)), 2.0);\r\n \r\n // Animated scan line effect\r\n float scan = fract(vDistFromApex * 0.001 - time * 0.5);\r\n scan = smoothstep(0.0, 0.1, scan) * smoothstep(0.2, 0.1, scan);\r\n \r\n // Distance-based opacity (fade towards apex)\r\n float distFade = smoothstep(0.0, 500.0, vDistFromApex);\r\n \r\n // Combine effects\r\n float alpha = (fresnel * 0.3 + 0.1 + scan * 0.2) * coneOpacity * distFade;\r\n \r\n gl_FragColor = vec4(coneColor, alpha);\r\n}\r\n`;\r\n\r\n// =============================================================================\r\n// Orbit Line Shader\r\n// =============================================================================\r\n\r\nexport const orbitLineVertexShader = `\r\nattribute float lineDistance;\r\nvarying float vLineDistance;\r\nvarying float vOpacity;\r\n\r\nuniform float totalLength;\r\nuniform float time;\r\nuniform float dashScale;\r\n\r\nvoid main() {\r\n vLineDistance = lineDistance;\r\n \r\n // Animated dash effect\r\n float animOffset = mod(time * 0.5, 1.0) * totalLength;\r\n float dashPos = mod(lineDistance + animOffset, dashScale);\r\n vOpacity = smoothstep(0.0, dashScale * 0.3, dashPos) * \r\n smoothstep(dashScale, dashScale * 0.7, dashPos);\r\n \r\n gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\r\n}\r\n`;\r\n\r\nexport const orbitLineFragmentShader = `\r\nuniform vec3 lineColor;\r\nuniform float lineOpacity;\r\n\r\nvarying float vLineDistance;\r\nvarying float vOpacity;\r\n\r\nvoid main() {\r\n gl_FragColor = vec4(lineColor, lineOpacity * vOpacity);\r\n}\r\n`;\r\n\r\n// =============================================================================\r\n// Satellite/Object Glow Shader\r\n// =============================================================================\r\n\r\nexport const objectGlowVertexShader = `\r\nvarying vec3 vNormal;\r\nvarying vec3 vViewPosition;\r\n\r\nvoid main() {\r\n vNormal = normalize(normalMatrix * normal);\r\n vec4 mvPosition = modelViewMatrix * vec4(position, 1.0);\r\n vViewPosition = -mvPosition.xyz;\r\n \r\n gl_Position = projectionMatrix * mvPosition;\r\n}\r\n`;\r\n\r\nexport const objectGlowFragmentShader = `\r\nuniform vec3 glowColor;\r\nuniform float glowIntensity;\r\nuniform float glowPower;\r\n\r\nvarying vec3 vNormal;\r\nvarying vec3 vViewPosition;\r\n\r\nvoid main() {\r\n vec3 viewDir = normalize(vViewPosition);\r\n float fresnel = pow(1.0 - abs(dot(vNormal, viewDir)), glowPower);\r\n \r\n vec3 color = glowColor * glowIntensity * fresnel;\r\n float alpha = fresnel * glowIntensity;\r\n \r\n gl_FragColor = vec4(color, alpha);\r\n}\r\n`;\r\n\r\n// =============================================================================\r\n// Selection Ring Shader\r\n// =============================================================================\r\n\r\nexport const selectionRingVertexShader = `\r\nvarying vec2 vUv;\r\n\r\nvoid main() {\r\n vUv = uv;\r\n gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\r\n}\r\n`;\r\n\r\nexport const selectionRingFragmentShader = `\r\nuniform vec3 ringColor;\r\nuniform float time;\r\nuniform float ringWidth;\r\nuniform float ringRadius;\r\n\r\nvarying vec2 vUv;\r\n\r\nvoid main() {\r\n vec2 center = vUv - vec2(0.5);\r\n float dist = length(center);\r\n \r\n // Ring shape\r\n float ring = smoothstep(ringRadius - ringWidth, ringRadius, dist) *\r\n smoothstep(ringRadius + ringWidth, ringRadius, dist);\r\n \r\n // Animated rotation\r\n float angle = atan(center.y, center.x);\r\n float rotatingDash = sin(angle * 8.0 - time * 3.0) * 0.5 + 0.5;\r\n \r\n // Pulse effect\r\n float pulse = sin(time * 2.0) * 0.2 + 0.8;\r\n \r\n float alpha = ring * rotatingDash * pulse;\r\n \r\n gl_FragColor = vec4(ringColor, alpha);\r\n}\r\n`;\r\n\r\n// =============================================================================\r\n// Terminator (Day/Night) Shader\r\n// =============================================================================\r\n\r\nexport const terminatorVertexShader = `\r\nvarying vec3 vWorldPosition;\r\nvarying vec3 vNormal;\r\n\r\nvoid main() {\r\n vWorldPosition = (modelMatrix * vec4(position, 1.0)).xyz;\r\n vNormal = normalize(normalMatrix * normal);\r\n \r\n gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\r\n}\r\n`;\r\n\r\nexport const terminatorFragmentShader = `\r\nuniform vec3 sunDirection;\r\nuniform sampler2D dayTexture;\r\nuniform sampler2D nightTexture;\r\n\r\nvarying vec3 vWorldPosition;\r\nvarying vec3 vNormal;\r\n\r\nvoid main() {\r\n // Calculate sun illumination\r\n float sunDot = dot(vNormal, sunDirection);\r\n \r\n // Smooth transition at terminator\r\n float dayFactor = smoothstep(-0.1, 0.2, sunDot);\r\n \r\n // Sample textures (simplified - using world position for UV)\r\n vec2 uv = vec2(\r\n atan(vWorldPosition.z, vWorldPosition.x) / (2.0 * 3.14159) + 0.5,\r\n asin(vWorldPosition.y / length(vWorldPosition)) / 3.14159 + 0.5\r\n );\r\n \r\n vec4 dayColor = texture2D(dayTexture, uv);\r\n vec4 nightColor = texture2D(nightTexture, uv);\r\n \r\n // Blend day and night\r\n vec4 color = mix(nightColor, dayColor, dayFactor);\r\n \r\n // Add city lights glow on night side\r\n float nightGlow = (1.0 - dayFactor) * nightColor.r * 0.5;\r\n color.rgb += vec3(1.0, 0.9, 0.7) * nightGlow;\r\n \r\n gl_FragColor = color;\r\n}\r\n`;\r\n\r\n// =============================================================================\r\n// Grid Shader (Lat/Lon lines)\r\n// =============================================================================\r\n\r\nexport const gridVertexShader = `\r\nvarying vec3 vPosition;\r\n\r\nvoid main() {\r\n vPosition = position;\r\n gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\r\n}\r\n`;\r\n\r\nexport const gridFragmentShader = `\r\nuniform vec3 gridColor;\r\nuniform float gridOpacity;\r\nuniform float gridSpacing;\r\nuniform float lineWidth;\r\n\r\nvarying vec3 vPosition;\r\n\r\nvoid main() {\r\n // Convert position to lat/lon\r\n float lat = asin(vPosition.y / length(vPosition)) * 57.2958; // rad to deg\r\n float lon = atan(vPosition.z, vPosition.x) * 57.2958;\r\n \r\n // Create grid lines\r\n float latLine = abs(mod(lat + 90.0, gridSpacing) - gridSpacing * 0.5);\r\n float lonLine = abs(mod(lon + 180.0, gridSpacing) - gridSpacing * 0.5);\r\n \r\n float line = min(latLine, lonLine);\r\n float alpha = smoothstep(lineWidth, 0.0, line) * gridOpacity;\r\n \r\n // Highlight equator and prime meridian\r\n float equator = smoothstep(1.0, 0.0, abs(lat));\r\n float primeMeridian = smoothstep(1.0, 0.0, abs(lon));\r\n alpha += (equator + primeMeridian) * 0.3;\r\n \r\n gl_FragColor = vec4(gridColor, alpha);\r\n}\r\n`;\r\n\r\n// =============================================================================\r\n// Planet Ring Shader (Saturn-like)\r\n// =============================================================================\r\n\r\nexport const planetRingVertexShader = `\r\nvarying vec2 vUv;\r\nvarying vec3 vWorldPosition;\r\n\r\nvoid main() {\r\n vUv = uv;\r\n vWorldPosition = (modelMatrix * vec4(position, 1.0)).xyz;\r\n \r\n gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\r\n}\r\n`;\r\n\r\nexport const planetRingFragmentShader = `\r\nuniform vec3 ringColor;\r\nuniform float innerRadius;\r\nuniform float outerRadius;\r\nuniform float ringOpacity;\r\nuniform vec3 sunDirection;\r\n\r\nvarying vec2 vUv;\r\nvarying vec3 vWorldPosition;\r\n\r\nvoid main() {\r\n vec2 center = vUv - vec2(0.5);\r\n float dist = length(center) * 2.0;\r\n \r\n // Ring bands\r\n float normalizedDist = (dist - innerRadius) / (outerRadius - innerRadius);\r\n \r\n if (normalizedDist < 0.0 || normalizedDist > 1.0) discard;\r\n \r\n // Create ring bands pattern\r\n float bands = sin(normalizedDist * 50.0) * 0.3 + 0.7;\r\n float gaps = step(0.3, fract(normalizedDist * 5.0));\r\n \r\n // Simple shadow from planet\r\n float shadow = smoothstep(0.3, 0.5, dist);\r\n \r\n float alpha = bands * gaps * ringOpacity * shadow;\r\n \r\n gl_FragColor = vec4(ringColor, alpha);\r\n}\r\n`;\r\n\r\n// =============================================================================\r\n// Debris Field Shader (for instanced rendering)\r\n// =============================================================================\r\n\r\nexport const debrisVertexShader = `\r\nattribute vec3 instancePosition;\r\nattribute float instanceSize;\r\nattribute vec3 instanceColor;\r\n\r\nvarying vec3 vColor;\r\nvarying float vSize;\r\n\r\nuniform float time;\r\n\r\nvoid main() {\r\n vColor = instanceColor;\r\n vSize = instanceSize;\r\n \r\n // Apply instance transform\r\n vec3 transformed = position * instanceSize + instancePosition;\r\n \r\n // Slight rotation animation\r\n float angle = time * 0.5 + instancePosition.x * 0.01;\r\n mat2 rot = mat2(cos(angle), -sin(angle), sin(angle), cos(angle));\r\n transformed.xz = rot * transformed.xz;\r\n \r\n gl_Position = projectionMatrix * modelViewMatrix * vec4(transformed, 1.0);\r\n}\r\n`;\r\n\r\nexport const debrisFragmentShader = `\r\nvarying vec3 vColor;\r\nvarying float vSize;\r\n\r\nvoid main() {\r\n gl_FragColor = vec4(vColor, 1.0);\r\n}\r\n`;\r\n\r\n// =============================================================================\r\n// Shader Uniforms Helpers\r\n// =============================================================================\r\n\r\nexport interface AtmosphereUniforms {\r\n glowColor: { value: [number, number, number] };\r\n glowIntensity: { value: number };\r\n}\r\n\r\nexport interface StarsUniforms {\r\n time: { value: number };\r\n pointSize: { value: number };\r\n}\r\n\r\nexport interface CoverageUniforms {\r\n coverageMap: { value: unknown };\r\n lowColor: { value: [number, number, number] };\r\n highColor: { value: [number, number, number] };\r\n opacity: { value: number };\r\n time: { value: number };\r\n}\r\n\r\nexport interface VisibilityConeUniforms {\r\n coneColor: { value: [number, number, number] };\r\n coneOpacity: { value: number };\r\n time: { value: number };\r\n apexPosition: { value: [number, number, number] };\r\n}\r\n\r\nexport function createAtmosphereUniforms(\r\n color: [number, number, number] = [0.3, 0.6, 1.0],\r\n intensity: number = 1.5\r\n): AtmosphereUniforms {\r\n return {\r\n glowColor: { value: color },\r\n glowIntensity: { value: intensity },\r\n };\r\n}\r\n\r\nexport function createStarsUniforms(pointSize: number = 2.0): StarsUniforms {\r\n return {\r\n time: { value: 0 },\r\n pointSize: { value: pointSize },\r\n };\r\n}\r\n\r\nexport function createVisibilityConeUniforms(\r\n color: [number, number, number] = [0.2, 0.8, 0.9],\r\n opacity: number = 0.3\r\n): VisibilityConeUniforms {\r\n return {\r\n coneColor: { value: color },\r\n coneOpacity: { value: opacity },\r\n time: { value: 0 },\r\n apexPosition: { value: [0, 0, 0] },\r\n };\r\n}\r\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ZenSpace3DShaders.js","names":[],"sources":["../../../src/react/3d/ZenSpace3DShaders.ts"],"sourcesContent":["/**\n * @zendir/ui - ZenSpace3D Shaders\n *\n * Advanced GLSL shaders for atmosphere, glow effects, coverage visualization,\n * and other space rendering effects.\n */\n\n// =============================================================================\n// Atmosphere Shader (Enhanced from original)\n// =============================================================================\n\nexport const atmosphereVertexShader = `\nvarying vec3 vNormal;\nvarying vec3 vPosition;\nvarying float vIntensity;\n\nvoid main() {\n vNormal = normalize(normalMatrix * normal);\n vPosition = position;\n \n // Calculate intensity based on view angle\n vec4 worldPosition = modelMatrix * vec4(position, 1.0);\n vec3 viewDirection = normalize(cameraPosition - worldPosition.xyz);\n vIntensity = pow(0.65 - dot(vNormal, viewDirection), 2.0);\n \n gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\n}\n`;\n\nexport const atmosphereFragmentShader = `\nvarying vec3 vNormal;\nvarying vec3 vPosition;\nvarying float vIntensity;\n\nuniform vec3 glowColor;\nuniform float glowIntensity;\n\nvoid main() {\n // Fresnel-based glow\n float intensity = vIntensity * glowIntensity;\n \n // Add subtle color variation\n vec3 color = glowColor * intensity;\n \n // Fade at edges for smoother blending\n float alpha = intensity * 0.8;\n \n gl_FragColor = vec4(color, alpha);\n}\n`;\n\n// =============================================================================\n// Enhanced Stars Shader (Twinkling with nebula)\n// =============================================================================\n\nexport const starsVertexShader = `\nattribute float opacity;\nattribute float size;\nattribute vec3 customColor;\n\nvarying float vOpacity;\nvarying vec3 vColor;\n\nuniform float time;\nuniform float pointSize;\n\nvoid main() {\n vOpacity = opacity;\n vColor = customColor;\n \n // Twinkle effect\n float twinkle = sin(time * (0.5 + opacity * 2.0) + opacity * 100.0) * 0.5 + 0.5;\n vOpacity = opacity * (0.6 + twinkle * 0.4);\n \n vec4 mvPosition = modelViewMatrix * vec4(position, 1.0);\n \n // Size attenuation\n float sizeMultiplier = size > 0.0 ? size : 1.0;\n gl_PointSize = pointSize * sizeMultiplier * (300.0 / -mvPosition.z);\n gl_PointSize = clamp(gl_PointSize, 0.5, 8.0);\n \n gl_Position = projectionMatrix * mvPosition;\n}\n`;\n\nexport const starsFragmentShader = `\nvarying float vOpacity;\nvarying vec3 vColor;\n\nvoid main() {\n // Circular point with soft edge\n vec2 center = gl_PointCoord - vec2(0.5);\n float dist = length(center);\n \n if (dist > 0.5) discard;\n \n // Soft glow falloff\n float alpha = smoothstep(0.5, 0.0, dist) * vOpacity;\n \n // Apply color\n vec3 color = vColor.r > 0.0 ? vColor : vec3(1.0, 1.0, 1.0);\n \n gl_FragColor = vec4(color, alpha);\n}\n`;\n\n// =============================================================================\n// Coverage Heatmap Shader\n// =============================================================================\n\nexport const coverageVertexShader = `\nvarying vec2 vUv;\nvarying vec3 vNormal;\nvarying vec3 vPosition;\n\nvoid main() {\n vUv = uv;\n vNormal = normalize(normalMatrix * normal);\n vPosition = (modelMatrix * vec4(position, 1.0)).xyz;\n \n gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\n}\n`;\n\nexport const coverageFragmentShader = `\nuniform sampler2D coverageMap;\nuniform vec3 lowColor;\nuniform vec3 highColor;\nuniform float opacity;\nuniform float time;\n\nvarying vec2 vUv;\nvarying vec3 vNormal;\nvarying vec3 vPosition;\n\nvoid main() {\n // Sample coverage value\n float coverage = texture2D(coverageMap, vUv).r;\n \n // Animated pulse for active areas\n float pulse = sin(time * 2.0) * 0.1 + 0.9;\n coverage *= coverage > 0.5 ? pulse : 1.0;\n \n // Color gradient\n vec3 color = mix(lowColor, highColor, coverage);\n \n // Fresnel edge highlight\n vec3 viewDir = normalize(cameraPosition - vPosition);\n float fresnel = pow(1.0 - dot(vNormal, viewDir), 2.0);\n color += vec3(0.1, 0.3, 0.5) * fresnel * coverage;\n \n // Hexagon pattern overlay (subtle)\n float hexPattern = fract(vUv.x * 20.0 + vUv.y * 10.0);\n color *= 0.95 + hexPattern * 0.05;\n \n gl_FragColor = vec4(color, coverage * opacity);\n}\n`;\n\n// =============================================================================\n// Visibility Cone Shader\n// =============================================================================\n\nexport const visibilityConeVertexShader = `\nvarying vec3 vPosition;\nvarying vec3 vNormal;\nvarying float vDistFromApex;\n\nuniform vec3 apexPosition;\n\nvoid main() {\n vPosition = (modelMatrix * vec4(position, 1.0)).xyz;\n vNormal = normalize(normalMatrix * normal);\n vDistFromApex = distance(position, apexPosition);\n \n gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\n}\n`;\n\nexport const visibilityConeFragmentShader = `\nuniform vec3 coneColor;\nuniform float coneOpacity;\nuniform float time;\n\nvarying vec3 vPosition;\nvarying vec3 vNormal;\nvarying float vDistFromApex;\n\nvoid main() {\n // Fresnel effect for edge visibility\n vec3 viewDir = normalize(cameraPosition - vPosition);\n float fresnel = pow(1.0 - abs(dot(vNormal, viewDir)), 2.0);\n \n // Animated scan line effect\n float scan = fract(vDistFromApex * 0.001 - time * 0.5);\n scan = smoothstep(0.0, 0.1, scan) * smoothstep(0.2, 0.1, scan);\n \n // Distance-based opacity (fade towards apex)\n float distFade = smoothstep(0.0, 500.0, vDistFromApex);\n \n // Combine effects\n float alpha = (fresnel * 0.3 + 0.1 + scan * 0.2) * coneOpacity * distFade;\n \n gl_FragColor = vec4(coneColor, alpha);\n}\n`;\n\n// =============================================================================\n// Orbit Line Shader\n// =============================================================================\n\nexport const orbitLineVertexShader = `\nattribute float lineDistance;\nvarying float vLineDistance;\nvarying float vOpacity;\n\nuniform float totalLength;\nuniform float time;\nuniform float dashScale;\n\nvoid main() {\n vLineDistance = lineDistance;\n \n // Animated dash effect\n float animOffset = mod(time * 0.5, 1.0) * totalLength;\n float dashPos = mod(lineDistance + animOffset, dashScale);\n vOpacity = smoothstep(0.0, dashScale * 0.3, dashPos) * \n smoothstep(dashScale, dashScale * 0.7, dashPos);\n \n gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\n}\n`;\n\nexport const orbitLineFragmentShader = `\nuniform vec3 lineColor;\nuniform float lineOpacity;\n\nvarying float vLineDistance;\nvarying float vOpacity;\n\nvoid main() {\n gl_FragColor = vec4(lineColor, lineOpacity * vOpacity);\n}\n`;\n\n// =============================================================================\n// Satellite/Object Glow Shader\n// =============================================================================\n\nexport const objectGlowVertexShader = `\nvarying vec3 vNormal;\nvarying vec3 vViewPosition;\n\nvoid main() {\n vNormal = normalize(normalMatrix * normal);\n vec4 mvPosition = modelViewMatrix * vec4(position, 1.0);\n vViewPosition = -mvPosition.xyz;\n \n gl_Position = projectionMatrix * mvPosition;\n}\n`;\n\nexport const objectGlowFragmentShader = `\nuniform vec3 glowColor;\nuniform float glowIntensity;\nuniform float glowPower;\n\nvarying vec3 vNormal;\nvarying vec3 vViewPosition;\n\nvoid main() {\n vec3 viewDir = normalize(vViewPosition);\n float fresnel = pow(1.0 - abs(dot(vNormal, viewDir)), glowPower);\n \n vec3 color = glowColor * glowIntensity * fresnel;\n float alpha = fresnel * glowIntensity;\n \n gl_FragColor = vec4(color, alpha);\n}\n`;\n\n// =============================================================================\n// Selection Ring Shader\n// =============================================================================\n\nexport const selectionRingVertexShader = `\nvarying vec2 vUv;\n\nvoid main() {\n vUv = uv;\n gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\n}\n`;\n\nexport const selectionRingFragmentShader = `\nuniform vec3 ringColor;\nuniform float time;\nuniform float ringWidth;\nuniform float ringRadius;\n\nvarying vec2 vUv;\n\nvoid main() {\n vec2 center = vUv - vec2(0.5);\n float dist = length(center);\n \n // Ring shape\n float ring = smoothstep(ringRadius - ringWidth, ringRadius, dist) *\n smoothstep(ringRadius + ringWidth, ringRadius, dist);\n \n // Animated rotation\n float angle = atan(center.y, center.x);\n float rotatingDash = sin(angle * 8.0 - time * 3.0) * 0.5 + 0.5;\n \n // Pulse effect\n float pulse = sin(time * 2.0) * 0.2 + 0.8;\n \n float alpha = ring * rotatingDash * pulse;\n \n gl_FragColor = vec4(ringColor, alpha);\n}\n`;\n\n// =============================================================================\n// Terminator (Day/Night) Shader\n// =============================================================================\n\nexport const terminatorVertexShader = `\nvarying vec3 vWorldPosition;\nvarying vec3 vNormal;\n\nvoid main() {\n vWorldPosition = (modelMatrix * vec4(position, 1.0)).xyz;\n vNormal = normalize(normalMatrix * normal);\n \n gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\n}\n`;\n\nexport const terminatorFragmentShader = `\nuniform vec3 sunDirection;\nuniform sampler2D dayTexture;\nuniform sampler2D nightTexture;\n\nvarying vec3 vWorldPosition;\nvarying vec3 vNormal;\n\nvoid main() {\n // Calculate sun illumination\n float sunDot = dot(vNormal, sunDirection);\n \n // Smooth transition at terminator\n float dayFactor = smoothstep(-0.1, 0.2, sunDot);\n \n // Sample textures (simplified - using world position for UV)\n vec2 uv = vec2(\n atan(vWorldPosition.z, vWorldPosition.x) / (2.0 * 3.14159) + 0.5,\n asin(vWorldPosition.y / length(vWorldPosition)) / 3.14159 + 0.5\n );\n \n vec4 dayColor = texture2D(dayTexture, uv);\n vec4 nightColor = texture2D(nightTexture, uv);\n \n // Blend day and night\n vec4 color = mix(nightColor, dayColor, dayFactor);\n \n // Add city lights glow on night side\n float nightGlow = (1.0 - dayFactor) * nightColor.r * 0.5;\n color.rgb += vec3(1.0, 0.9, 0.7) * nightGlow;\n \n gl_FragColor = color;\n}\n`;\n\n// =============================================================================\n// Grid Shader (Lat/Lon lines)\n// =============================================================================\n\nexport const gridVertexShader = `\nvarying vec3 vPosition;\n\nvoid main() {\n vPosition = position;\n gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\n}\n`;\n\nexport const gridFragmentShader = `\nuniform vec3 gridColor;\nuniform float gridOpacity;\nuniform float gridSpacing;\nuniform float lineWidth;\n\nvarying vec3 vPosition;\n\nvoid main() {\n // Convert position to lat/lon\n float lat = asin(vPosition.y / length(vPosition)) * 57.2958; // rad to deg\n float lon = atan(vPosition.z, vPosition.x) * 57.2958;\n \n // Create grid lines\n float latLine = abs(mod(lat + 90.0, gridSpacing) - gridSpacing * 0.5);\n float lonLine = abs(mod(lon + 180.0, gridSpacing) - gridSpacing * 0.5);\n \n float line = min(latLine, lonLine);\n float alpha = smoothstep(lineWidth, 0.0, line) * gridOpacity;\n \n // Highlight equator and prime meridian\n float equator = smoothstep(1.0, 0.0, abs(lat));\n float primeMeridian = smoothstep(1.0, 0.0, abs(lon));\n alpha += (equator + primeMeridian) * 0.3;\n \n gl_FragColor = vec4(gridColor, alpha);\n}\n`;\n\n// =============================================================================\n// Planet Ring Shader (Saturn-like)\n// =============================================================================\n\nexport const planetRingVertexShader = `\nvarying vec2 vUv;\nvarying vec3 vWorldPosition;\n\nvoid main() {\n vUv = uv;\n vWorldPosition = (modelMatrix * vec4(position, 1.0)).xyz;\n \n gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\n}\n`;\n\nexport const planetRingFragmentShader = `\nuniform vec3 ringColor;\nuniform float innerRadius;\nuniform float outerRadius;\nuniform float ringOpacity;\nuniform vec3 sunDirection;\n\nvarying vec2 vUv;\nvarying vec3 vWorldPosition;\n\nvoid main() {\n vec2 center = vUv - vec2(0.5);\n float dist = length(center) * 2.0;\n \n // Ring bands\n float normalizedDist = (dist - innerRadius) / (outerRadius - innerRadius);\n \n if (normalizedDist < 0.0 || normalizedDist > 1.0) discard;\n \n // Create ring bands pattern\n float bands = sin(normalizedDist * 50.0) * 0.3 + 0.7;\n float gaps = step(0.3, fract(normalizedDist * 5.0));\n \n // Simple shadow from planet\n float shadow = smoothstep(0.3, 0.5, dist);\n \n float alpha = bands * gaps * ringOpacity * shadow;\n \n gl_FragColor = vec4(ringColor, alpha);\n}\n`;\n\n// =============================================================================\n// Debris Field Shader (for instanced rendering)\n// =============================================================================\n\nexport const debrisVertexShader = `\nattribute vec3 instancePosition;\nattribute float instanceSize;\nattribute vec3 instanceColor;\n\nvarying vec3 vColor;\nvarying float vSize;\n\nuniform float time;\n\nvoid main() {\n vColor = instanceColor;\n vSize = instanceSize;\n \n // Apply instance transform\n vec3 transformed = position * instanceSize + instancePosition;\n \n // Slight rotation animation\n float angle = time * 0.5 + instancePosition.x * 0.01;\n mat2 rot = mat2(cos(angle), -sin(angle), sin(angle), cos(angle));\n transformed.xz = rot * transformed.xz;\n \n gl_Position = projectionMatrix * modelViewMatrix * vec4(transformed, 1.0);\n}\n`;\n\nexport const debrisFragmentShader = `\nvarying vec3 vColor;\nvarying float vSize;\n\nvoid main() {\n gl_FragColor = vec4(vColor, 1.0);\n}\n`;\n\n// =============================================================================\n// Shader Uniforms Helpers\n// =============================================================================\n\nexport interface AtmosphereUniforms {\n glowColor: { value: [number, number, number] };\n glowIntensity: { value: number };\n}\n\nexport interface StarsUniforms {\n time: { value: number };\n pointSize: { value: number };\n}\n\nexport interface CoverageUniforms {\n coverageMap: { value: unknown };\n lowColor: { value: [number, number, number] };\n highColor: { value: [number, number, number] };\n opacity: { value: number };\n time: { value: number };\n}\n\nexport interface VisibilityConeUniforms {\n coneColor: { value: [number, number, number] };\n coneOpacity: { value: number };\n time: { value: number };\n apexPosition: { value: [number, number, number] };\n}\n\nexport function createAtmosphereUniforms(\n color: [number, number, number] = [0.3, 0.6, 1.0],\n intensity: number = 1.5,\n): AtmosphereUniforms {\n return {\n glowColor: { value: color },\n glowIntensity: { value: intensity },\n };\n}\n\nexport function createStarsUniforms(pointSize: number = 2.0): StarsUniforms {\n return {\n time: { value: 0 },\n pointSize: { value: pointSize },\n };\n}\n\nexport function createVisibilityConeUniforms(\n color: [number, number, number] = [0.2, 0.8, 0.9],\n opacity: number = 0.3,\n): VisibilityConeUniforms {\n return {\n coneColor: { value: color },\n coneOpacity: { value: opacity },\n time: { value: 0 },\n apexPosition: { value: [0, 0, 0] },\n };\n}\n"],"mappings":";;;;;;;AAWA,IAAa,yBAAyB;;;;;;;;;;;;;;;;;AAkBtC,IAAa,2BAA2B;;;;;;;;;;;;;;;;;;;;;AA0BxC,IAAa,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA8BjC,IAAa,sBAAsB;;;;;;;;;;;;;;;;;;;;AAyBnC,IAAa,uBAAuB;;;;;;;;;;;;;AAcpC,IAAa,yBAAyB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAuCtC,IAAa,6BAA6B;;;;;;;;;;;;;;;AAgB1C,IAAa,+BAA+B;;;;;;;;;;;;;;;;;;;;;;;;;;;AAgC5C,IAAa,wBAAwB;;;;;;;;;;;;;;;;;;;;;AAsBrC,IAAa,0BAA0B;;;;;;;;;;;AAgBvC,IAAa,yBAAyB;;;;;;;;;;;;AAatC,IAAa,2BAA2B;;;;;;;;;;;;;;;;;;AAuBxC,IAAa,4BAA4B;;;;;;;;AASzC,IAAa,8BAA8B;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAiC3C,IAAa,yBAAyB;;;;;;;;;;;AAYtC,IAAa,2BAA2B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAuCxC,IAAa,mBAAmB;;;;;;;;AAShC,IAAa,qBAAqB;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAiClC,IAAa,yBAAyB;;;;;;;;;;;AAYtC,IAAa,2BAA2B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAoCxC,IAAa,qBAAqB;;;;;;;;;;;;;;;;;;;;;;;;;AA0BlC,IAAa,uBAAuB;;;;;;;;AAsCpC,SAAgB,yBACd,QAAkC;CAAC;CAAK;CAAK;AAAG,GAChD,YAAoB,KACA;CACpB,OAAO;EACL,WAAW,EAAE,OAAO,MAAM;EAC1B,eAAe,EAAE,OAAO,UAAU;CACpC;AACF;AAEA,SAAgB,oBAAoB,YAAoB,GAAoB;CAC1E,OAAO;EACL,MAAM,EAAE,OAAO,EAAE;EACjB,WAAW,EAAE,OAAO,UAAU;CAChC;AACF;AAEA,SAAgB,6BACd,QAAkC;CAAC;CAAK;CAAK;AAAG,GAChD,UAAkB,IACM;CACxB,OAAO;EACL,WAAW,EAAE,OAAO,MAAM;EAC1B,aAAa,EAAE,OAAO,QAAQ;EAC9B,MAAM,EAAE,OAAO,EAAE;EACjB,cAAc,EAAE,OAAO;GAAC;GAAG;GAAG;EAAC,EAAE;CACnC;AACF"}