@zendir/ui 0.2.21 → 0.3.1

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 (322) hide show
  1. package/CHANGELOG.md +183 -1
  2. package/README.md +70 -28
  3. package/dist/index.d.ts +1 -1
  4. package/dist/index.js +73 -64
  5. package/dist/index.js.map +1 -1
  6. package/dist/react/3d/CesiumCaptureSource.d.ts +1 -1
  7. package/dist/react/3d/CesiumCaptureSource.js +1 -1
  8. package/dist/react/3d/CesiumCaptureSource.js.map +1 -1
  9. package/dist/react/3d/ZenSpace3D.js +1254 -0
  10. package/dist/react/3d/ZenSpace3D.js.map +1 -0
  11. package/dist/react/3d/ZenSpace3DCesium.js +579 -0
  12. package/dist/react/3d/ZenSpace3DCesium.js.map +1 -0
  13. package/dist/react/3d/ZenSpace3DShaders.js +478 -0
  14. package/dist/react/3d/ZenSpace3DShaders.js.map +1 -0
  15. package/dist/react/3d/ZenSpace3DTypes.d.ts +28 -1
  16. package/dist/react/3d/ZenSpace3DUtils.d.ts +17 -173
  17. package/dist/react/3d/ZenSpace3DUtils.js +20 -1
  18. package/dist/react/3d/ZenSpace3DUtils.js.map +1 -1
  19. package/dist/react/3d/capturePngAnalysis.js +42 -0
  20. package/dist/react/3d/capturePngAnalysis.js.map +1 -0
  21. package/dist/react/3d/index.d.ts +6 -12
  22. package/dist/react/3d/index.js +57 -0
  23. package/dist/react/3d/index.js.map +1 -0
  24. package/dist/react/3d/threeLoader.js +22 -0
  25. package/dist/react/3d/threeLoader.js.map +1 -0
  26. package/dist/react/astro/ClassificationBanner.js +1 -1
  27. package/dist/react/astro/GlobalStatusBar.js +1 -1
  28. package/dist/react/astro/MissionClock.js +8 -5
  29. package/dist/react/astro/MissionClock.js.map +1 -1
  30. package/dist/react/astro/MonitoringIcon.js +2 -2
  31. package/dist/react/astro/MonitoringIcon.js.map +1 -1
  32. package/dist/react/astro/Notification.js +1 -1
  33. package/dist/react/astro/Progress.js +1 -1
  34. package/dist/react/astro/SimulationControls.js +3 -3
  35. package/dist/react/astro/SimulationControls.js.map +1 -1
  36. package/dist/react/astro/StatusIndicator.js +1 -1
  37. package/dist/react/astro/UnifiedTimeline.js +5 -5
  38. package/dist/react/astro/UnifiedTimeline.js.map +1 -1
  39. package/dist/react/astro/index.js +34 -0
  40. package/dist/react/astro/index.js.map +1 -0
  41. package/dist/react/cards/AccessCard.js +410 -0
  42. package/dist/react/cards/AccessCard.js.map +1 -0
  43. package/dist/react/cards/OrbitCard.js +372 -0
  44. package/dist/react/cards/OrbitCard.js.map +1 -0
  45. package/dist/react/cards/SpacecraftCard.js +941 -0
  46. package/dist/react/cards/SpacecraftCard.js.map +1 -0
  47. package/dist/react/cards/TelemetryCard.js +742 -0
  48. package/dist/react/cards/TelemetryCard.js.map +1 -0
  49. package/dist/react/cards/TelemetryStreamCard.js +309 -0
  50. package/dist/react/cards/TelemetryStreamCard.js.map +1 -0
  51. package/dist/react/cards/index.js +13 -0
  52. package/dist/react/cards/index.js.map +1 -0
  53. package/dist/react/charts/GroundTrackMap.d.ts +2 -15
  54. package/dist/react/charts/GroundTrackMap.js +1 -1
  55. package/dist/react/charts/GroundTrackMap.js.map +1 -1
  56. package/dist/react/charts/GroundTrackMapLeaflet.js +1 -1
  57. package/dist/react/charts/index.js +104 -0
  58. package/dist/react/charts/index.js.map +1 -0
  59. package/dist/react/charts/unified/AstroChart.js +35 -14
  60. package/dist/react/charts/unified/AstroChart.js.map +1 -1
  61. package/dist/react/charts/unified/PowerOverviewChart.js +488 -0
  62. package/dist/react/charts/unified/PowerOverviewChart.js.map +1 -0
  63. package/dist/react/charts/unified/domain.js +3168 -0
  64. package/dist/react/charts/unified/domain.js.map +1 -0
  65. package/dist/react/charts/unified/generators.js +518 -0
  66. package/dist/react/charts/unified/generators.js.map +1 -0
  67. package/dist/react/charts/unified/presets.js +1000 -0
  68. package/dist/react/charts/unified/presets.js.map +1 -0
  69. package/dist/react/charts/unified/sync.js +219 -0
  70. package/dist/react/charts/unified/sync.js.map +1 -0
  71. package/dist/react/charts/unified/theme.js +331 -4
  72. package/dist/react/charts/unified/theme.js.map +1 -1
  73. package/dist/react/charts/unified/useChartStream.js +226 -0
  74. package/dist/react/charts/unified/useChartStream.js.map +1 -0
  75. package/dist/react/chatgpt/AppCard.d.ts +0 -4
  76. package/dist/react/chatgpt/index.d.ts +0 -19
  77. package/dist/react/chatgpt/index.js +163 -0
  78. package/dist/react/chatgpt/index.js.map +1 -0
  79. package/dist/react/context/SpatialSelectionContext.d.ts +40 -0
  80. package/dist/react/context/SpatialSelectionContext.js +10 -0
  81. package/dist/react/context/SpatialSelectionContext.js.map +1 -0
  82. package/dist/react/context/index.d.ts +2 -0
  83. package/dist/react/core/{DataTable.d.ts → data/DataTable.d.ts} +1 -1
  84. package/dist/react/core/{DataTable.js → data/DataTable.js} +4 -4
  85. package/dist/react/core/data/DataTable.js.map +1 -0
  86. package/dist/react/core/{DataValue.d.ts → data/DataValue.d.ts} +2 -2
  87. package/dist/react/core/{DataValue.js → data/DataValue.js} +2 -2
  88. package/dist/react/core/data/DataValue.js.map +1 -0
  89. package/dist/react/core/{propertyConfig.d.ts → data/propertyConfig.d.ts} +2 -2
  90. package/dist/react/core/data/propertyConfig.js.map +1 -0
  91. package/dist/react/core/{AstroIcon.js → display/AstroIcon.js} +1 -1
  92. package/dist/react/core/display/AstroIcon.js.map +1 -0
  93. package/dist/react/core/{Badge.d.ts → display/Badge.d.ts} +1 -1
  94. package/dist/react/core/{Badge.js → display/Badge.js} +2 -2
  95. package/dist/react/core/display/Badge.js.map +1 -0
  96. package/dist/react/core/{CardHeader.d.ts → display/CardHeader.d.ts} +1 -1
  97. package/dist/react/core/{CardHeader.js → display/CardHeader.js} +2 -2
  98. package/dist/react/core/display/CardHeader.js.map +1 -0
  99. package/dist/react/core/{Container.d.ts → display/Container.d.ts} +1 -1
  100. package/dist/react/core/{Container.js → display/Container.js} +3 -3
  101. package/dist/react/core/display/Container.js.map +1 -0
  102. package/dist/react/core/{CopyButton.js → display/CopyButton.js} +1 -1
  103. package/dist/react/core/display/CopyButton.js.map +1 -0
  104. package/dist/react/core/{GlassCard.d.ts → display/GlassCard.d.ts} +1 -1
  105. package/dist/react/core/{GlassCard.js → display/GlassCard.js} +2 -2
  106. package/dist/react/core/display/GlassCard.js.map +1 -0
  107. package/dist/react/core/{HeaderIconWithStatus.d.ts → display/HeaderIconWithStatus.d.ts} +1 -1
  108. package/dist/react/core/{HeaderIconWithStatus.js → display/HeaderIconWithStatus.js} +1 -1
  109. package/dist/react/core/display/HeaderIconWithStatus.js.map +1 -0
  110. package/dist/react/core/{Icon.d.ts → display/Icon.d.ts} +1 -1
  111. package/dist/react/core/{Icon.js → display/Icon.js} +1 -1
  112. package/dist/react/core/display/Icon.js.map +1 -0
  113. package/dist/react/core/{Typography.d.ts → display/Typography.d.ts} +13 -4
  114. package/dist/react/core/{Typography.js → display/Typography.js} +1 -1
  115. package/dist/react/core/display/Typography.js.map +1 -0
  116. package/dist/react/core/{ConfirmDialog.js → feedback/ConfirmDialog.js} +1 -1
  117. package/dist/react/core/feedback/ConfirmDialog.js.map +1 -0
  118. package/dist/react/core/{Dialog.js → feedback/Dialog.js} +2 -2
  119. package/dist/react/core/feedback/Dialog.js.map +1 -0
  120. package/dist/react/core/{Toast.js → feedback/Toast.js} +3 -3
  121. package/dist/react/core/feedback/Toast.js.map +1 -0
  122. package/dist/react/core/index.d.ts +85 -85
  123. package/dist/react/core/index.js +161 -0
  124. package/dist/react/core/index.js.map +1 -0
  125. package/dist/react/core/{Button.js → inputs/Button.js} +2 -2
  126. package/dist/react/core/inputs/Button.js.map +1 -0
  127. package/dist/react/core/{Checkbox.js → inputs/Checkbox.js} +2 -2
  128. package/dist/react/core/inputs/Checkbox.js.map +1 -0
  129. package/dist/react/core/{Input.d.ts → inputs/Input.d.ts} +1 -1
  130. package/dist/react/core/{Input.js → inputs/Input.js} +3 -3
  131. package/dist/react/core/inputs/Input.js.map +1 -0
  132. package/dist/react/core/{LimitsBar.js → inputs/LimitsBar.js} +1 -1
  133. package/dist/react/core/inputs/LimitsBar.js.map +1 -0
  134. package/dist/react/core/{NumberInput.d.ts → inputs/NumberInput.d.ts} +2 -2
  135. package/dist/react/core/{NumberInput.js → inputs/NumberInput.js} +3 -3
  136. package/dist/react/core/inputs/NumberInput.js.map +1 -0
  137. package/dist/react/core/{PinInput.js → inputs/PinInput.js} +2 -2
  138. package/dist/react/core/inputs/PinInput.js.map +1 -0
  139. package/dist/react/core/{Select.js → inputs/Select.js} +3 -3
  140. package/dist/react/core/inputs/Select.js.map +1 -0
  141. package/dist/react/core/{Toggle.js → inputs/Toggle.js} +2 -2
  142. package/dist/react/core/inputs/Toggle.js.map +1 -0
  143. package/dist/react/core/layout/Box.js +1 -1
  144. package/dist/react/core/layout/Flex.js +1 -1
  145. package/dist/react/core/layout/Grid.js +1 -1
  146. package/dist/react/core/layout/Stack.js +1 -1
  147. package/dist/react/core/{AppBar.d.ts → navigation/AppBar.d.ts} +1 -1
  148. package/dist/react/core/{AppBar.js → navigation/AppBar.js} +7 -7
  149. package/dist/react/core/navigation/AppBar.js.map +1 -0
  150. package/dist/react/core/{Pagination.js → navigation/Pagination.js} +2 -2
  151. package/dist/react/core/navigation/Pagination.js.map +1 -0
  152. package/dist/react/core/{SideNav.d.ts → navigation/SideNav.d.ts} +1 -1
  153. package/dist/react/core/{SideNav.js → navigation/SideNav.js} +3 -3
  154. package/dist/react/core/navigation/SideNav.js.map +1 -0
  155. package/dist/react/core/{Tabs.js → navigation/Tabs.js} +2 -2
  156. package/dist/react/core/navigation/Tabs.js.map +1 -0
  157. package/dist/react/core/{Popover.js → overlays/Popover.js} +1 -1
  158. package/dist/react/core/overlays/Popover.js.map +1 -0
  159. package/dist/react/core/{SidePanel.js → overlays/SidePanel.js} +3 -3
  160. package/dist/react/core/overlays/SidePanel.js.map +1 -0
  161. package/dist/react/core/{Tooltip.js → overlays/Tooltip.js} +2 -2
  162. package/dist/react/core/overlays/Tooltip.js.map +1 -0
  163. package/dist/react/core/{ActivityPlanner.js → widgets/ActivityPlanner.js} +1 -1
  164. package/dist/react/core/widgets/ActivityPlanner.js.map +1 -0
  165. package/dist/react/core/{Capture.js → widgets/Capture.js} +3 -3
  166. package/dist/react/core/widgets/Capture.js.map +1 -0
  167. package/dist/react/core/{ChatPanel.d.ts → widgets/ChatPanel.d.ts} +1 -1
  168. package/dist/react/core/{ChatPanel.js → widgets/ChatPanel.js} +2 -2
  169. package/dist/react/core/widgets/ChatPanel.js.map +1 -0
  170. package/dist/react/core/{ColorPickerPanel.d.ts → widgets/ColorPickerPanel.d.ts} +1 -1
  171. package/dist/react/core/{ColorPickerPanel.js → widgets/ColorPickerPanel.js} +3 -3
  172. package/dist/react/core/widgets/ColorPickerPanel.js.map +1 -0
  173. package/dist/react/core/{CommandBuilder.js → widgets/CommandBuilder.js} +1 -1
  174. package/dist/react/core/widgets/CommandBuilder.js.map +1 -0
  175. package/dist/react/core/{ConnectionForm.d.ts → widgets/ConnectionForm.d.ts} +1 -1
  176. package/dist/react/core/{ConnectionForm.js → widgets/ConnectionForm.js} +2 -2
  177. package/dist/react/core/widgets/ConnectionForm.js.map +1 -0
  178. package/dist/react/core/{FileExplorer.js → widgets/FileExplorer.js} +2 -2
  179. package/dist/react/core/widgets/FileExplorer.js.map +1 -0
  180. package/dist/react/core/{HexViewer.js → widgets/HexViewer.js} +1 -1
  181. package/dist/react/core/widgets/HexViewer.js.map +1 -0
  182. package/dist/react/core/{ImageGallery.d.ts → widgets/ImageGallery.d.ts} +1 -1
  183. package/dist/react/core/{ImageGallery.js → widgets/ImageGallery.js} +3 -3
  184. package/dist/react/core/widgets/ImageGallery.js.map +1 -0
  185. package/dist/react/core/{LogViewer.d.ts → widgets/LogViewer.d.ts} +13 -3
  186. package/dist/react/core/{LogViewer.js → widgets/LogViewer.js} +28 -8
  187. package/dist/react/core/widgets/LogViewer.js.map +1 -0
  188. package/dist/react/core/{MessageStream.d.ts → widgets/MessageStream.d.ts} +2 -2
  189. package/dist/react/core/{MessageStream.js → widgets/MessageStream.js} +4 -4
  190. package/dist/react/core/widgets/MessageStream.js.map +1 -0
  191. package/dist/react/core/{MissionCalendar.js → widgets/MissionCalendar.js} +2 -2
  192. package/dist/react/core/widgets/MissionCalendar.js.map +1 -0
  193. package/dist/react/core/{PacketViewer.js → widgets/PacketViewer.js} +1 -1
  194. package/dist/react/core/widgets/PacketViewer.js.map +1 -0
  195. package/dist/react/core/widgets/capture-placeholder.png.js.map +1 -0
  196. package/dist/react/hooks/index.d.ts +9 -11
  197. package/dist/react/hooks/useAccessWindows.d.ts +15 -19
  198. package/dist/react/hooks/useCompactMode.js +1 -1
  199. package/dist/react/hooks/useGroundTrackHistory.d.ts +34 -0
  200. package/dist/react/hooks/useSimulationScene.d.ts +141 -0
  201. package/dist/react/hooks/useSimulationScene.js +401 -0
  202. package/dist/react/hooks/useSimulationScene.js.map +1 -0
  203. package/dist/react/hooks/useZendirSession.d.ts +44 -69
  204. package/dist/react/index.d.ts +7 -3
  205. package/dist/react/panels/LayerControlPanel.d.ts +54 -0
  206. package/dist/react/panels/LayerControlPanel.js +184 -0
  207. package/dist/react/panels/LayerControlPanel.js.map +1 -0
  208. package/dist/react/panels/ObjectInventoryPanel.d.ts +57 -0
  209. package/dist/react/panels/ObjectInventoryPanel.js +261 -0
  210. package/dist/react/panels/ObjectInventoryPanel.js.map +1 -0
  211. package/dist/react/panels/index.d.ts +15 -0
  212. package/dist/react/panels/index.js +8 -0
  213. package/dist/react/panels/index.js.map +1 -0
  214. package/dist/react/theme/ThemeProvider.d.ts +2 -0
  215. package/dist/react/theme/ThemeProvider.js +50 -72
  216. package/dist/react/theme/ThemeProvider.js.map +1 -1
  217. package/dist/react/theme/config.js +30 -0
  218. package/dist/react/theme/config.js.map +1 -0
  219. package/dist/react/theme/index.js +19 -0
  220. package/dist/react/theme/index.js.map +1 -0
  221. package/dist/react/types.d.ts +32 -3
  222. package/dist/react/types.js.map +1 -1
  223. package/dist/react/utils/index.js +8 -0
  224. package/dist/react/utils/index.js.map +1 -1
  225. package/dist/react.js +73 -64
  226. package/dist/react.js.map +1 -1
  227. package/dist/shaders/atmosphere.frag.js +5 -0
  228. package/dist/shaders/atmosphere.frag.js.map +1 -0
  229. package/dist/shaders/atmosphere.vert.js +5 -0
  230. package/dist/shaders/atmosphere.vert.js.map +1 -0
  231. package/dist/shaders/stars.frag.js +5 -0
  232. package/dist/shaders/stars.frag.js.map +1 -0
  233. package/dist/shaders/stars.vert.js +5 -0
  234. package/dist/shaders/stars.vert.js.map +1 -0
  235. package/dist/style.css +6 -4
  236. package/dist/tokens/css-vars.d.ts +91 -0
  237. package/dist/tokens/css-vars.js +228 -0
  238. package/dist/tokens/css-vars.js.map +1 -0
  239. package/dist/tokens/index.d.ts +71 -18
  240. package/dist/tokens/index.js +206 -97
  241. package/dist/tokens/index.js.map +1 -1
  242. package/dist/tokens/tokens.css +50 -50
  243. package/package.json +70 -58
  244. package/sdk-stub.js +10 -5
  245. package/dist/react/3d/EarthViewer.d.ts +0 -46
  246. package/dist/react/3d/SolarSystemViewer.d.ts +0 -43
  247. package/dist/react/chatgpt/ChatGPTCard.d.ts +0 -6
  248. package/dist/react/core/ActivityPlanner.js.map +0 -1
  249. package/dist/react/core/AppBar.js.map +0 -1
  250. package/dist/react/core/AstroIcon.js.map +0 -1
  251. package/dist/react/core/Badge.js.map +0 -1
  252. package/dist/react/core/Button.js.map +0 -1
  253. package/dist/react/core/Capture.js.map +0 -1
  254. package/dist/react/core/CardHeader.js.map +0 -1
  255. package/dist/react/core/ChatPanel.js.map +0 -1
  256. package/dist/react/core/Checkbox.js.map +0 -1
  257. package/dist/react/core/ColorPickerPanel.js.map +0 -1
  258. package/dist/react/core/CommandBuilder.js.map +0 -1
  259. package/dist/react/core/ConfirmDialog.js.map +0 -1
  260. package/dist/react/core/ConnectionForm.js.map +0 -1
  261. package/dist/react/core/Container.js.map +0 -1
  262. package/dist/react/core/CopyButton.js.map +0 -1
  263. package/dist/react/core/DataTable.js.map +0 -1
  264. package/dist/react/core/DataValue.js.map +0 -1
  265. package/dist/react/core/Dialog.js.map +0 -1
  266. package/dist/react/core/FileExplorer.js.map +0 -1
  267. package/dist/react/core/GlassCard.js.map +0 -1
  268. package/dist/react/core/HeaderIconWithStatus.js.map +0 -1
  269. package/dist/react/core/HexViewer.js.map +0 -1
  270. package/dist/react/core/Icon.js.map +0 -1
  271. package/dist/react/core/ImageGallery.js.map +0 -1
  272. package/dist/react/core/Input.js.map +0 -1
  273. package/dist/react/core/LimitsBar.js.map +0 -1
  274. package/dist/react/core/LogViewer.js.map +0 -1
  275. package/dist/react/core/MessageStream.js.map +0 -1
  276. package/dist/react/core/MissionCalendar.js.map +0 -1
  277. package/dist/react/core/NumberInput.js.map +0 -1
  278. package/dist/react/core/PacketViewer.js.map +0 -1
  279. package/dist/react/core/Pagination.js.map +0 -1
  280. package/dist/react/core/PinInput.js.map +0 -1
  281. package/dist/react/core/Popover.js.map +0 -1
  282. package/dist/react/core/Select.js.map +0 -1
  283. package/dist/react/core/SideNav.js.map +0 -1
  284. package/dist/react/core/SidePanel.js.map +0 -1
  285. package/dist/react/core/Tabs.js.map +0 -1
  286. package/dist/react/core/Toast.js.map +0 -1
  287. package/dist/react/core/Toggle.js.map +0 -1
  288. package/dist/react/core/Tooltip.js.map +0 -1
  289. package/dist/react/core/Typography.js.map +0 -1
  290. package/dist/react/core/capture-placeholder.png.js.map +0 -1
  291. package/dist/react/core/propertyConfig.js.map +0 -1
  292. package/dist/react/hooks/useSimulationTime.d.ts +0 -61
  293. package/dist/react/hooks/useSpacecraftPosition.d.ts +0 -50
  294. package/dist/react/hooks/useTelemetry.d.ts +0 -55
  295. package/dist/types.d.ts +0 -1
  296. package/dist/types.js +0 -2
  297. package/dist/types.js.map +0 -1
  298. /package/dist/react/core/{propertyConfig.js → data/propertyConfig.js} +0 -0
  299. /package/dist/react/core/{AstroIcon.d.ts → display/AstroIcon.d.ts} +0 -0
  300. /package/dist/react/core/{CopyButton.d.ts → display/CopyButton.d.ts} +0 -0
  301. /package/dist/react/core/{ConfirmDialog.d.ts → feedback/ConfirmDialog.d.ts} +0 -0
  302. /package/dist/react/core/{Dialog.d.ts → feedback/Dialog.d.ts} +0 -0
  303. /package/dist/react/core/{Toast.d.ts → feedback/Toast.d.ts} +0 -0
  304. /package/dist/react/core/{Button.d.ts → inputs/Button.d.ts} +0 -0
  305. /package/dist/react/core/{Checkbox.d.ts → inputs/Checkbox.d.ts} +0 -0
  306. /package/dist/react/core/{LimitsBar.d.ts → inputs/LimitsBar.d.ts} +0 -0
  307. /package/dist/react/core/{PinInput.d.ts → inputs/PinInput.d.ts} +0 -0
  308. /package/dist/react/core/{Select.d.ts → inputs/Select.d.ts} +0 -0
  309. /package/dist/react/core/{Toggle.d.ts → inputs/Toggle.d.ts} +0 -0
  310. /package/dist/react/core/{Pagination.d.ts → navigation/Pagination.d.ts} +0 -0
  311. /package/dist/react/core/{Tabs.d.ts → navigation/Tabs.d.ts} +0 -0
  312. /package/dist/react/core/{Popover.d.ts → overlays/Popover.d.ts} +0 -0
  313. /package/dist/react/core/{SidePanel.d.ts → overlays/SidePanel.d.ts} +0 -0
  314. /package/dist/react/core/{Tooltip.d.ts → overlays/Tooltip.d.ts} +0 -0
  315. /package/dist/react/core/{ActivityPlanner.d.ts → widgets/ActivityPlanner.d.ts} +0 -0
  316. /package/dist/react/core/{Capture.d.ts → widgets/Capture.d.ts} +0 -0
  317. /package/dist/react/core/{CommandBuilder.d.ts → widgets/CommandBuilder.d.ts} +0 -0
  318. /package/dist/react/core/{FileExplorer.d.ts → widgets/FileExplorer.d.ts} +0 -0
  319. /package/dist/react/core/{HexViewer.d.ts → widgets/HexViewer.d.ts} +0 -0
  320. /package/dist/react/core/{MissionCalendar.d.ts → widgets/MissionCalendar.d.ts} +0 -0
  321. /package/dist/react/core/{PacketViewer.d.ts → widgets/PacketViewer.d.ts} +0 -0
  322. /package/dist/react/core/{capture-placeholder.png.js → widgets/capture-placeholder.png.js} +0 -0
@@ -0,0 +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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"}
@@ -0,0 +1,478 @@
1
+ const atmosphereVertexShader = `
2
+ varying vec3 vNormal;
3
+ varying vec3 vPosition;
4
+ varying float vIntensity;
5
+
6
+ void main() {
7
+ vNormal = normalize(normalMatrix * normal);
8
+ vPosition = position;
9
+
10
+ // Calculate intensity based on view angle
11
+ vec4 worldPosition = modelMatrix * vec4(position, 1.0);
12
+ vec3 viewDirection = normalize(cameraPosition - worldPosition.xyz);
13
+ vIntensity = pow(0.65 - dot(vNormal, viewDirection), 2.0);
14
+
15
+ gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
16
+ }
17
+ `;
18
+ const atmosphereFragmentShader = `
19
+ varying vec3 vNormal;
20
+ varying vec3 vPosition;
21
+ varying float vIntensity;
22
+
23
+ uniform vec3 glowColor;
24
+ uniform float glowIntensity;
25
+
26
+ void main() {
27
+ // Fresnel-based glow
28
+ float intensity = vIntensity * glowIntensity;
29
+
30
+ // Add subtle color variation
31
+ vec3 color = glowColor * intensity;
32
+
33
+ // Fade at edges for smoother blending
34
+ float alpha = intensity * 0.8;
35
+
36
+ gl_FragColor = vec4(color, alpha);
37
+ }
38
+ `;
39
+ const starsVertexShader = `
40
+ attribute float opacity;
41
+ attribute float size;
42
+ attribute vec3 customColor;
43
+
44
+ varying float vOpacity;
45
+ varying vec3 vColor;
46
+
47
+ uniform float time;
48
+ uniform float pointSize;
49
+
50
+ void main() {
51
+ vOpacity = opacity;
52
+ vColor = customColor;
53
+
54
+ // Twinkle effect
55
+ float twinkle = sin(time * (0.5 + opacity * 2.0) + opacity * 100.0) * 0.5 + 0.5;
56
+ vOpacity = opacity * (0.6 + twinkle * 0.4);
57
+
58
+ vec4 mvPosition = modelViewMatrix * vec4(position, 1.0);
59
+
60
+ // Size attenuation
61
+ float sizeMultiplier = size > 0.0 ? size : 1.0;
62
+ gl_PointSize = pointSize * sizeMultiplier * (300.0 / -mvPosition.z);
63
+ gl_PointSize = clamp(gl_PointSize, 0.5, 8.0);
64
+
65
+ gl_Position = projectionMatrix * mvPosition;
66
+ }
67
+ `;
68
+ const starsFragmentShader = `
69
+ varying float vOpacity;
70
+ varying vec3 vColor;
71
+
72
+ void main() {
73
+ // Circular point with soft edge
74
+ vec2 center = gl_PointCoord - vec2(0.5);
75
+ float dist = length(center);
76
+
77
+ if (dist > 0.5) discard;
78
+
79
+ // Soft glow falloff
80
+ float alpha = smoothstep(0.5, 0.0, dist) * vOpacity;
81
+
82
+ // Apply color
83
+ vec3 color = vColor.r > 0.0 ? vColor : vec3(1.0, 1.0, 1.0);
84
+
85
+ gl_FragColor = vec4(color, alpha);
86
+ }
87
+ `;
88
+ const coverageVertexShader = `
89
+ varying vec2 vUv;
90
+ varying vec3 vNormal;
91
+ varying vec3 vPosition;
92
+
93
+ void main() {
94
+ vUv = uv;
95
+ vNormal = normalize(normalMatrix * normal);
96
+ vPosition = (modelMatrix * vec4(position, 1.0)).xyz;
97
+
98
+ gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
99
+ }
100
+ `;
101
+ const coverageFragmentShader = `
102
+ uniform sampler2D coverageMap;
103
+ uniform vec3 lowColor;
104
+ uniform vec3 highColor;
105
+ uniform float opacity;
106
+ uniform float time;
107
+
108
+ varying vec2 vUv;
109
+ varying vec3 vNormal;
110
+ varying vec3 vPosition;
111
+
112
+ void main() {
113
+ // Sample coverage value
114
+ float coverage = texture2D(coverageMap, vUv).r;
115
+
116
+ // Animated pulse for active areas
117
+ float pulse = sin(time * 2.0) * 0.1 + 0.9;
118
+ coverage *= coverage > 0.5 ? pulse : 1.0;
119
+
120
+ // Color gradient
121
+ vec3 color = mix(lowColor, highColor, coverage);
122
+
123
+ // Fresnel edge highlight
124
+ vec3 viewDir = normalize(cameraPosition - vPosition);
125
+ float fresnel = pow(1.0 - dot(vNormal, viewDir), 2.0);
126
+ color += vec3(0.1, 0.3, 0.5) * fresnel * coverage;
127
+
128
+ // Hexagon pattern overlay (subtle)
129
+ float hexPattern = fract(vUv.x * 20.0 + vUv.y * 10.0);
130
+ color *= 0.95 + hexPattern * 0.05;
131
+
132
+ gl_FragColor = vec4(color, coverage * opacity);
133
+ }
134
+ `;
135
+ const visibilityConeVertexShader = `
136
+ varying vec3 vPosition;
137
+ varying vec3 vNormal;
138
+ varying float vDistFromApex;
139
+
140
+ uniform vec3 apexPosition;
141
+
142
+ void main() {
143
+ vPosition = (modelMatrix * vec4(position, 1.0)).xyz;
144
+ vNormal = normalize(normalMatrix * normal);
145
+ vDistFromApex = distance(position, apexPosition);
146
+
147
+ gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
148
+ }
149
+ `;
150
+ const visibilityConeFragmentShader = `
151
+ uniform vec3 coneColor;
152
+ uniform float coneOpacity;
153
+ uniform float time;
154
+
155
+ varying vec3 vPosition;
156
+ varying vec3 vNormal;
157
+ varying float vDistFromApex;
158
+
159
+ void main() {
160
+ // Fresnel effect for edge visibility
161
+ vec3 viewDir = normalize(cameraPosition - vPosition);
162
+ float fresnel = pow(1.0 - abs(dot(vNormal, viewDir)), 2.0);
163
+
164
+ // Animated scan line effect
165
+ float scan = fract(vDistFromApex * 0.001 - time * 0.5);
166
+ scan = smoothstep(0.0, 0.1, scan) * smoothstep(0.2, 0.1, scan);
167
+
168
+ // Distance-based opacity (fade towards apex)
169
+ float distFade = smoothstep(0.0, 500.0, vDistFromApex);
170
+
171
+ // Combine effects
172
+ float alpha = (fresnel * 0.3 + 0.1 + scan * 0.2) * coneOpacity * distFade;
173
+
174
+ gl_FragColor = vec4(coneColor, alpha);
175
+ }
176
+ `;
177
+ const orbitLineVertexShader = `
178
+ attribute float lineDistance;
179
+ varying float vLineDistance;
180
+ varying float vOpacity;
181
+
182
+ uniform float totalLength;
183
+ uniform float time;
184
+ uniform float dashScale;
185
+
186
+ void main() {
187
+ vLineDistance = lineDistance;
188
+
189
+ // Animated dash effect
190
+ float animOffset = mod(time * 0.5, 1.0) * totalLength;
191
+ float dashPos = mod(lineDistance + animOffset, dashScale);
192
+ vOpacity = smoothstep(0.0, dashScale * 0.3, dashPos) *
193
+ smoothstep(dashScale, dashScale * 0.7, dashPos);
194
+
195
+ gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
196
+ }
197
+ `;
198
+ const orbitLineFragmentShader = `
199
+ uniform vec3 lineColor;
200
+ uniform float lineOpacity;
201
+
202
+ varying float vLineDistance;
203
+ varying float vOpacity;
204
+
205
+ void main() {
206
+ gl_FragColor = vec4(lineColor, lineOpacity * vOpacity);
207
+ }
208
+ `;
209
+ const objectGlowVertexShader = `
210
+ varying vec3 vNormal;
211
+ varying vec3 vViewPosition;
212
+
213
+ void main() {
214
+ vNormal = normalize(normalMatrix * normal);
215
+ vec4 mvPosition = modelViewMatrix * vec4(position, 1.0);
216
+ vViewPosition = -mvPosition.xyz;
217
+
218
+ gl_Position = projectionMatrix * mvPosition;
219
+ }
220
+ `;
221
+ const objectGlowFragmentShader = `
222
+ uniform vec3 glowColor;
223
+ uniform float glowIntensity;
224
+ uniform float glowPower;
225
+
226
+ varying vec3 vNormal;
227
+ varying vec3 vViewPosition;
228
+
229
+ void main() {
230
+ vec3 viewDir = normalize(vViewPosition);
231
+ float fresnel = pow(1.0 - abs(dot(vNormal, viewDir)), glowPower);
232
+
233
+ vec3 color = glowColor * glowIntensity * fresnel;
234
+ float alpha = fresnel * glowIntensity;
235
+
236
+ gl_FragColor = vec4(color, alpha);
237
+ }
238
+ `;
239
+ const selectionRingVertexShader = `
240
+ varying vec2 vUv;
241
+
242
+ void main() {
243
+ vUv = uv;
244
+ gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
245
+ }
246
+ `;
247
+ const selectionRingFragmentShader = `
248
+ uniform vec3 ringColor;
249
+ uniform float time;
250
+ uniform float ringWidth;
251
+ uniform float ringRadius;
252
+
253
+ varying vec2 vUv;
254
+
255
+ void main() {
256
+ vec2 center = vUv - vec2(0.5);
257
+ float dist = length(center);
258
+
259
+ // Ring shape
260
+ float ring = smoothstep(ringRadius - ringWidth, ringRadius, dist) *
261
+ smoothstep(ringRadius + ringWidth, ringRadius, dist);
262
+
263
+ // Animated rotation
264
+ float angle = atan(center.y, center.x);
265
+ float rotatingDash = sin(angle * 8.0 - time * 3.0) * 0.5 + 0.5;
266
+
267
+ // Pulse effect
268
+ float pulse = sin(time * 2.0) * 0.2 + 0.8;
269
+
270
+ float alpha = ring * rotatingDash * pulse;
271
+
272
+ gl_FragColor = vec4(ringColor, alpha);
273
+ }
274
+ `;
275
+ const terminatorVertexShader = `
276
+ varying vec3 vWorldPosition;
277
+ varying vec3 vNormal;
278
+
279
+ void main() {
280
+ vWorldPosition = (modelMatrix * vec4(position, 1.0)).xyz;
281
+ vNormal = normalize(normalMatrix * normal);
282
+
283
+ gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
284
+ }
285
+ `;
286
+ const terminatorFragmentShader = `
287
+ uniform vec3 sunDirection;
288
+ uniform sampler2D dayTexture;
289
+ uniform sampler2D nightTexture;
290
+
291
+ varying vec3 vWorldPosition;
292
+ varying vec3 vNormal;
293
+
294
+ void main() {
295
+ // Calculate sun illumination
296
+ float sunDot = dot(vNormal, sunDirection);
297
+
298
+ // Smooth transition at terminator
299
+ float dayFactor = smoothstep(-0.1, 0.2, sunDot);
300
+
301
+ // Sample textures (simplified - using world position for UV)
302
+ vec2 uv = vec2(
303
+ atan(vWorldPosition.z, vWorldPosition.x) / (2.0 * 3.14159) + 0.5,
304
+ asin(vWorldPosition.y / length(vWorldPosition)) / 3.14159 + 0.5
305
+ );
306
+
307
+ vec4 dayColor = texture2D(dayTexture, uv);
308
+ vec4 nightColor = texture2D(nightTexture, uv);
309
+
310
+ // Blend day and night
311
+ vec4 color = mix(nightColor, dayColor, dayFactor);
312
+
313
+ // Add city lights glow on night side
314
+ float nightGlow = (1.0 - dayFactor) * nightColor.r * 0.5;
315
+ color.rgb += vec3(1.0, 0.9, 0.7) * nightGlow;
316
+
317
+ gl_FragColor = color;
318
+ }
319
+ `;
320
+ const gridVertexShader = `
321
+ varying vec3 vPosition;
322
+
323
+ void main() {
324
+ vPosition = position;
325
+ gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
326
+ }
327
+ `;
328
+ const gridFragmentShader = `
329
+ uniform vec3 gridColor;
330
+ uniform float gridOpacity;
331
+ uniform float gridSpacing;
332
+ uniform float lineWidth;
333
+
334
+ varying vec3 vPosition;
335
+
336
+ void main() {
337
+ // Convert position to lat/lon
338
+ float lat = asin(vPosition.y / length(vPosition)) * 57.2958; // rad to deg
339
+ float lon = atan(vPosition.z, vPosition.x) * 57.2958;
340
+
341
+ // Create grid lines
342
+ float latLine = abs(mod(lat + 90.0, gridSpacing) - gridSpacing * 0.5);
343
+ float lonLine = abs(mod(lon + 180.0, gridSpacing) - gridSpacing * 0.5);
344
+
345
+ float line = min(latLine, lonLine);
346
+ float alpha = smoothstep(lineWidth, 0.0, line) * gridOpacity;
347
+
348
+ // Highlight equator and prime meridian
349
+ float equator = smoothstep(1.0, 0.0, abs(lat));
350
+ float primeMeridian = smoothstep(1.0, 0.0, abs(lon));
351
+ alpha += (equator + primeMeridian) * 0.3;
352
+
353
+ gl_FragColor = vec4(gridColor, alpha);
354
+ }
355
+ `;
356
+ const planetRingVertexShader = `
357
+ varying vec2 vUv;
358
+ varying vec3 vWorldPosition;
359
+
360
+ void main() {
361
+ vUv = uv;
362
+ vWorldPosition = (modelMatrix * vec4(position, 1.0)).xyz;
363
+
364
+ gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
365
+ }
366
+ `;
367
+ const planetRingFragmentShader = `
368
+ uniform vec3 ringColor;
369
+ uniform float innerRadius;
370
+ uniform float outerRadius;
371
+ uniform float ringOpacity;
372
+ uniform vec3 sunDirection;
373
+
374
+ varying vec2 vUv;
375
+ varying vec3 vWorldPosition;
376
+
377
+ void main() {
378
+ vec2 center = vUv - vec2(0.5);
379
+ float dist = length(center) * 2.0;
380
+
381
+ // Ring bands
382
+ float normalizedDist = (dist - innerRadius) / (outerRadius - innerRadius);
383
+
384
+ if (normalizedDist < 0.0 || normalizedDist > 1.0) discard;
385
+
386
+ // Create ring bands pattern
387
+ float bands = sin(normalizedDist * 50.0) * 0.3 + 0.7;
388
+ float gaps = step(0.3, fract(normalizedDist * 5.0));
389
+
390
+ // Simple shadow from planet
391
+ float shadow = smoothstep(0.3, 0.5, dist);
392
+
393
+ float alpha = bands * gaps * ringOpacity * shadow;
394
+
395
+ gl_FragColor = vec4(ringColor, alpha);
396
+ }
397
+ `;
398
+ const debrisVertexShader = `
399
+ attribute vec3 instancePosition;
400
+ attribute float instanceSize;
401
+ attribute vec3 instanceColor;
402
+
403
+ varying vec3 vColor;
404
+ varying float vSize;
405
+
406
+ uniform float time;
407
+
408
+ void main() {
409
+ vColor = instanceColor;
410
+ vSize = instanceSize;
411
+
412
+ // Apply instance transform
413
+ vec3 transformed = position * instanceSize + instancePosition;
414
+
415
+ // Slight rotation animation
416
+ float angle = time * 0.5 + instancePosition.x * 0.01;
417
+ mat2 rot = mat2(cos(angle), -sin(angle), sin(angle), cos(angle));
418
+ transformed.xz = rot * transformed.xz;
419
+
420
+ gl_Position = projectionMatrix * modelViewMatrix * vec4(transformed, 1.0);
421
+ }
422
+ `;
423
+ const debrisFragmentShader = `
424
+ varying vec3 vColor;
425
+ varying float vSize;
426
+
427
+ void main() {
428
+ gl_FragColor = vec4(vColor, 1.0);
429
+ }
430
+ `;
431
+ function createAtmosphereUniforms(color = [0.3, 0.6, 1], intensity = 1.5) {
432
+ return {
433
+ glowColor: { value: color },
434
+ glowIntensity: { value: intensity }
435
+ };
436
+ }
437
+ function createStarsUniforms(pointSize = 2) {
438
+ return {
439
+ time: { value: 0 },
440
+ pointSize: { value: pointSize }
441
+ };
442
+ }
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
+ };
450
+ }
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
@@ -0,0 +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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"}