@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.
- package/CHANGELOG.md +20 -0
- package/README.md +640 -631
- package/dist/_virtual/_rolldown/runtime.js +13 -0
- package/dist/index.js +17 -221
- package/dist/react/3d/CesiumCaptureSource.d.ts +0 -1
- package/dist/react/3d/CesiumCaptureSource.js +364 -283
- package/dist/react/3d/CesiumCaptureSource.js.map +1 -1
- package/dist/react/3d/ZenSpace3D.d.ts +2 -3
- package/dist/react/3d/ZenSpace3D.js +1681 -1237
- package/dist/react/3d/ZenSpace3D.js.map +1 -1
- package/dist/react/3d/ZenSpace3DCesium.d.ts +0 -1
- package/dist/react/3d/ZenSpace3DCesium.js +513 -560
- package/dist/react/3d/ZenSpace3DCesium.js.map +1 -1
- package/dist/react/3d/ZenSpace3DShaders.js +61 -66
- package/dist/react/3d/ZenSpace3DShaders.js.map +1 -1
- package/dist/react/3d/ZenSpace3DTypes.d.ts +19 -20
- package/dist/react/3d/ZenSpace3DUtils.d.ts +0 -1
- package/dist/react/3d/ZenSpace3DUtils.js +37 -24
- package/dist/react/3d/ZenSpace3DUtils.js.map +1 -1
- package/dist/react/3d/capturePngAnalysis.js +42 -36
- package/dist/react/3d/capturePngAnalysis.js.map +1 -1
- package/dist/react/3d/index.d.ts +3 -3
- package/dist/react/3d/index.js +5 -53
- package/dist/react/3d/threeLoader.d.ts +1 -1
- package/dist/react/3d/threeLoader.js +23 -18
- package/dist/react/3d/threeLoader.js.map +1 -1
- package/dist/react/astro/ClassificationBanner.d.ts +2 -3
- package/dist/react/astro/ClassificationBanner.js +95 -79
- package/dist/react/astro/ClassificationBanner.js.map +1 -1
- package/dist/react/astro/GlobalStatusBar.d.ts +0 -1
- package/dist/react/astro/GlobalStatusBar.js +157 -163
- package/dist/react/astro/GlobalStatusBar.js.map +1 -1
- package/dist/react/astro/MissionClock.d.ts +7 -8
- package/dist/react/astro/MissionClock.js +377 -400
- package/dist/react/astro/MissionClock.js.map +1 -1
- package/dist/react/astro/MonitoringIcon.d.ts +1 -2
- package/dist/react/astro/MonitoringIcon.js +422 -358
- package/dist/react/astro/MonitoringIcon.js.map +1 -1
- package/dist/react/astro/Notification.d.ts +1 -2
- package/dist/react/astro/Notification.js +229 -126
- package/dist/react/astro/Notification.js.map +1 -1
- package/dist/react/astro/Progress.d.ts +0 -1
- package/dist/react/astro/Progress.js +199 -141
- package/dist/react/astro/Progress.js.map +1 -1
- package/dist/react/astro/SimulationControls.d.ts +3 -4
- package/dist/react/astro/SimulationControls.js +596 -650
- package/dist/react/astro/SimulationControls.js.map +1 -1
- package/dist/react/astro/StatusIndicator.d.ts +0 -1
- package/dist/react/astro/StatusIndicator.js +236 -170
- package/dist/react/astro/StatusIndicator.js.map +1 -1
- package/dist/react/astro/UnifiedTimeline.d.ts +9 -10
- package/dist/react/astro/UnifiedTimeline.js +2345 -2392
- package/dist/react/astro/UnifiedTimeline.js.map +1 -1
- package/dist/react/astro/index.d.ts +5 -5
- package/dist/react/astro/index.js +1 -25
- package/dist/react/cards/AccessCard.d.ts +0 -1
- package/dist/react/cards/AccessCard.js +471 -405
- package/dist/react/cards/AccessCard.js.map +1 -1
- package/dist/react/cards/OrbitCard.d.ts +0 -1
- package/dist/react/cards/OrbitCard.js +487 -364
- package/dist/react/cards/OrbitCard.js.map +1 -1
- package/dist/react/cards/SpacecraftCard.d.ts +0 -1
- package/dist/react/cards/SpacecraftCard.js +813 -925
- package/dist/react/cards/SpacecraftCard.js.map +1 -1
- package/dist/react/cards/TelemetryCard.d.ts +0 -1
- package/dist/react/cards/TelemetryCard.js +1055 -732
- package/dist/react/cards/TelemetryCard.js.map +1 -1
- package/dist/react/cards/TelemetryStreamCard.d.ts +0 -1
- package/dist/react/cards/TelemetryStreamCard.js +323 -297
- package/dist/react/cards/TelemetryStreamCard.js.map +1 -1
- package/dist/react/cards/index.d.ts +1 -1
- package/dist/react/cards/index.js +1 -8
- package/dist/react/charts/GroundTrackMap.d.ts +6 -7
- package/dist/react/charts/GroundTrackMap.js +1377 -1256
- package/dist/react/charts/GroundTrackMap.js.map +1 -1
- package/dist/react/charts/GroundTrackMapLeaflet.d.ts +1 -2
- package/dist/react/charts/GroundTrackMapLeaflet.js +1065 -987
- package/dist/react/charts/GroundTrackMapLeaflet.js.map +1 -1
- package/dist/react/charts/groundTrackMapLeafletTiles.js +34 -25
- package/dist/react/charts/groundTrackMapLeafletTiles.js.map +1 -1
- package/dist/react/charts/groundTrackMapLeafletUtils.js +70 -61
- package/dist/react/charts/groundTrackMapLeafletUtils.js.map +1 -1
- package/dist/react/charts/index.d.ts +1 -1
- package/dist/react/charts/index.js +7 -100
- package/dist/react/charts/unified/AstroChart.d.ts +1 -2
- package/dist/react/charts/unified/AstroChart.js +1331 -1411
- package/dist/react/charts/unified/AstroChart.js.map +1 -1
- package/dist/react/charts/unified/PowerOverviewChart.d.ts +3 -3
- package/dist/react/charts/unified/PowerOverviewChart.js +495 -478
- package/dist/react/charts/unified/PowerOverviewChart.js.map +1 -1
- package/dist/react/charts/unified/domain.d.ts +12 -13
- package/dist/react/charts/unified/domain.js +3999 -3145
- package/dist/react/charts/unified/domain.js.map +1 -1
- package/dist/react/charts/unified/generators.d.ts +3 -4
- package/dist/react/charts/unified/generators.js +561 -498
- package/dist/react/charts/unified/generators.js.map +1 -1
- package/dist/react/charts/unified/index.d.ts +1 -1
- package/dist/react/charts/unified/presets.d.ts +14 -15
- package/dist/react/charts/unified/presets.js +857 -994
- package/dist/react/charts/unified/presets.js.map +1 -1
- package/dist/react/charts/unified/sync.d.ts +2 -3
- package/dist/react/charts/unified/sync.js +229 -195
- package/dist/react/charts/unified/sync.js.map +1 -1
- package/dist/react/charts/unified/theme.d.ts +11 -12
- package/dist/react/charts/unified/theme.js +606 -642
- package/dist/react/charts/unified/theme.js.map +1 -1
- package/dist/react/charts/unified/types.d.ts +32 -33
- package/dist/react/charts/unified/useChartStream.d.ts +1 -2
- package/dist/react/charts/unified/useChartStream.js +203 -216
- package/dist/react/charts/unified/useChartStream.js.map +1 -1
- package/dist/react/chatgpt/AppCard.d.ts +1 -2
- package/dist/react/chatgpt/index.d.ts +7 -7
- package/dist/react/chatgpt/index.js +160 -139
- package/dist/react/chatgpt/index.js.map +1 -1
- package/dist/react/context/CategoryContext.d.ts +0 -1
- package/dist/react/context/CategoryContext.js +78 -29
- package/dist/react/context/CategoryContext.js.map +1 -1
- package/dist/react/context/DisplaySettingsContext.d.ts +1 -2
- package/dist/react/context/DisplaySettingsContext.js +205 -156
- package/dist/react/context/DisplaySettingsContext.js.map +1 -1
- package/dist/react/context/SpatialSelectionContext.d.ts +0 -1
- package/dist/react/context/SpatialSelectionContext.js +36 -7
- package/dist/react/context/SpatialSelectionContext.js.map +1 -1
- package/dist/react/core/data/DataTable.d.ts +3 -4
- package/dist/react/core/data/DataTable.js +473 -440
- package/dist/react/core/data/DataTable.js.map +1 -1
- package/dist/react/core/data/DataValue.d.ts +4 -5
- package/dist/react/core/data/DataValue.js +605 -571
- package/dist/react/core/data/DataValue.js.map +1 -1
- package/dist/react/core/data/propertyConfig.d.ts +1 -2
- package/dist/react/core/data/propertyConfig.js +446 -382
- package/dist/react/core/data/propertyConfig.js.map +1 -1
- package/dist/react/core/display/AstroIcon.d.ts +4 -5
- package/dist/react/core/display/AstroIcon.js +339 -429
- package/dist/react/core/display/AstroIcon.js.map +1 -1
- package/dist/react/core/display/Badge.d.ts +2 -3
- package/dist/react/core/display/Badge.js +131 -131
- package/dist/react/core/display/Badge.js.map +1 -1
- package/dist/react/core/display/CardHeader.d.ts +0 -1
- package/dist/react/core/display/CardHeader.js +398 -311
- package/dist/react/core/display/CardHeader.js.map +1 -1
- package/dist/react/core/display/Container.d.ts +2 -3
- package/dist/react/core/display/Container.js +640 -668
- package/dist/react/core/display/Container.js.map +1 -1
- package/dist/react/core/display/CopyButton.d.ts +1 -2
- package/dist/react/core/display/CopyButton.js +158 -101
- package/dist/react/core/display/CopyButton.js.map +1 -1
- package/dist/react/core/display/GlassCard.d.ts +3 -4
- package/dist/react/core/display/GlassCard.js +416 -369
- package/dist/react/core/display/GlassCard.js.map +1 -1
- package/dist/react/core/display/HeaderIconWithStatus.d.ts +0 -1
- package/dist/react/core/display/HeaderIconWithStatus.js +152 -152
- package/dist/react/core/display/HeaderIconWithStatus.js.map +1 -1
- package/dist/react/core/display/Icon.d.ts +2 -3
- package/dist/react/core/display/Icon.js +172 -143
- package/dist/react/core/display/Icon.js.map +1 -1
- package/dist/react/core/display/Typography.d.ts +24 -25
- package/dist/react/core/display/Typography.js +360 -178
- package/dist/react/core/display/Typography.js.map +1 -1
- package/dist/react/core/feedback/ConfirmDialog.d.ts +1 -2
- package/dist/react/core/feedback/ConfirmDialog.js +343 -304
- package/dist/react/core/feedback/ConfirmDialog.js.map +1 -1
- package/dist/react/core/feedback/Dialog.d.ts +2 -3
- package/dist/react/core/feedback/Dialog.js +189 -197
- package/dist/react/core/feedback/Dialog.js.map +1 -1
- package/dist/react/core/feedback/Toast.d.ts +2 -3
- package/dist/react/core/feedback/Toast.js +346 -207
- package/dist/react/core/feedback/Toast.js.map +1 -1
- package/dist/react/core/index.d.ts +26 -26
- package/dist/react/core/index.js +7 -119
- package/dist/react/core/inputs/Button.d.ts +2 -3
- package/dist/react/core/inputs/Button.js +281 -304
- package/dist/react/core/inputs/Button.js.map +1 -1
- package/dist/react/core/inputs/Checkbox.d.ts +2 -3
- package/dist/react/core/inputs/Checkbox.js +139 -127
- package/dist/react/core/inputs/Checkbox.js.map +1 -1
- package/dist/react/core/inputs/Input.d.ts +3 -4
- package/dist/react/core/inputs/Input.js +277 -285
- package/dist/react/core/inputs/Input.js.map +1 -1
- package/dist/react/core/inputs/LimitsBar.d.ts +1 -2
- package/dist/react/core/inputs/LimitsBar.js +271 -196
- package/dist/react/core/inputs/LimitsBar.js.map +1 -1
- package/dist/react/core/inputs/NumberInput.d.ts +2 -3
- package/dist/react/core/inputs/NumberInput.js +531 -503
- package/dist/react/core/inputs/NumberInput.js.map +1 -1
- package/dist/react/core/inputs/PinInput.d.ts +2 -3
- package/dist/react/core/inputs/PinInput.js +224 -207
- package/dist/react/core/inputs/PinInput.js.map +1 -1
- package/dist/react/core/inputs/Select.d.ts +1 -2
- package/dist/react/core/inputs/Select.js +298 -299
- package/dist/react/core/inputs/Select.js.map +1 -1
- package/dist/react/core/inputs/Toggle.d.ts +2 -3
- package/dist/react/core/inputs/Toggle.js +142 -148
- package/dist/react/core/inputs/Toggle.js.map +1 -1
- package/dist/react/core/layout/Box.d.ts +3 -4
- package/dist/react/core/layout/Box.js +118 -122
- package/dist/react/core/layout/Box.js.map +1 -1
- package/dist/react/core/layout/Center.d.ts +0 -1
- package/dist/react/core/layout/Center.js +45 -32
- package/dist/react/core/layout/Center.js.map +1 -1
- package/dist/react/core/layout/Divider.d.ts +1 -2
- package/dist/react/core/layout/Divider.js +112 -106
- package/dist/react/core/layout/Divider.js.map +1 -1
- package/dist/react/core/layout/Flex.d.ts +4 -5
- package/dist/react/core/layout/Flex.js +120 -124
- package/dist/react/core/layout/Flex.js.map +1 -1
- package/dist/react/core/layout/Grid.d.ts +5 -6
- package/dist/react/core/layout/Grid.js +131 -138
- package/dist/react/core/layout/Grid.js.map +1 -1
- package/dist/react/core/layout/Spacer.d.ts +0 -1
- package/dist/react/core/layout/Spacer.js +36 -29
- package/dist/react/core/layout/Spacer.js.map +1 -1
- package/dist/react/core/layout/Stack.d.ts +4 -5
- package/dist/react/core/layout/Stack.js +127 -70
- package/dist/react/core/layout/Stack.js.map +1 -1
- package/dist/react/core/layout/responsive.d.ts +1 -2
- package/dist/react/core/layout/responsive.js +25 -19
- package/dist/react/core/layout/responsive.js.map +1 -1
- package/dist/react/core/layout/useBreakpoint.d.ts +1 -1
- package/dist/react/core/layout/useBreakpoint.js +119 -66
- package/dist/react/core/layout/useBreakpoint.js.map +1 -1
- package/dist/react/core/navigation/AppBar.d.ts +1 -2
- package/dist/react/core/navigation/AppBar.js +827 -805
- package/dist/react/core/navigation/AppBar.js.map +1 -1
- package/dist/react/core/navigation/Pagination.d.ts +2 -3
- package/dist/react/core/navigation/Pagination.js +207 -187
- package/dist/react/core/navigation/Pagination.js.map +1 -1
- package/dist/react/core/navigation/SideNav.d.ts +5 -6
- package/dist/react/core/navigation/SideNav.js +855 -629
- package/dist/react/core/navigation/SideNav.js.map +1 -1
- package/dist/react/core/navigation/Tabs.d.ts +0 -1
- package/dist/react/core/navigation/Tabs.js +113 -119
- package/dist/react/core/navigation/Tabs.js.map +1 -1
- package/dist/react/core/overlays/Popover.d.ts +2 -3
- package/dist/react/core/overlays/Popover.js +303 -282
- package/dist/react/core/overlays/Popover.js.map +1 -1
- package/dist/react/core/overlays/SidePanel.d.ts +1 -2
- package/dist/react/core/overlays/SidePanel.js +217 -212
- package/dist/react/core/overlays/SidePanel.js.map +1 -1
- package/dist/react/core/overlays/Tooltip.d.ts +1 -2
- package/dist/react/core/overlays/Tooltip.js +170 -176
- package/dist/react/core/overlays/Tooltip.js.map +1 -1
- package/dist/react/core/widgets/ActivityPlanner.d.ts +0 -1
- package/dist/react/core/widgets/ActivityPlanner.js +855 -517
- package/dist/react/core/widgets/ActivityPlanner.js.map +1 -1
- package/dist/react/core/widgets/Capture.d.ts +2 -3
- package/dist/react/core/widgets/Capture.js +965 -779
- package/dist/react/core/widgets/Capture.js.map +1 -1
- package/dist/react/core/widgets/ChatPanel.d.ts +16 -17
- package/dist/react/core/widgets/ChatPanel.js +1734 -1034
- package/dist/react/core/widgets/ChatPanel.js.map +1 -1
- package/dist/react/core/widgets/ColorPickerPanel.d.ts +0 -1
- package/dist/react/core/widgets/ColorPickerPanel.js +298 -287
- package/dist/react/core/widgets/ColorPickerPanel.js.map +1 -1
- package/dist/react/core/widgets/CommandBuilder.d.ts +2 -3
- package/dist/react/core/widgets/CommandBuilder.js +624 -516
- package/dist/react/core/widgets/CommandBuilder.js.map +1 -1
- package/dist/react/core/widgets/ConnectionForm.d.ts +2 -3
- package/dist/react/core/widgets/ConnectionForm.js +528 -492
- package/dist/react/core/widgets/ConnectionForm.js.map +1 -1
- package/dist/react/core/widgets/FileExplorer.d.ts +3 -4
- package/dist/react/core/widgets/FileExplorer.js +617 -505
- package/dist/react/core/widgets/FileExplorer.js.map +1 -1
- package/dist/react/core/widgets/HexViewer.d.ts +2 -3
- package/dist/react/core/widgets/HexViewer.js +1353 -1091
- package/dist/react/core/widgets/HexViewer.js.map +1 -1
- package/dist/react/core/widgets/ImageFrame.d.ts +1 -2
- package/dist/react/core/widgets/ImageFrame.js +230 -193
- package/dist/react/core/widgets/ImageFrame.js.map +1 -1
- package/dist/react/core/widgets/ImageGallery.d.ts +2 -1
- package/dist/react/core/widgets/ImageGallery.js +380 -314
- package/dist/react/core/widgets/ImageGallery.js.map +1 -1
- package/dist/react/core/widgets/ImagePanel.d.ts +0 -1
- package/dist/react/core/widgets/ImagePanel.js +110 -101
- package/dist/react/core/widgets/ImagePanel.js.map +1 -1
- package/dist/react/core/widgets/LogViewer.d.ts +2 -3
- package/dist/react/core/widgets/LogViewer.js +711 -607
- package/dist/react/core/widgets/LogViewer.js.map +1 -1
- package/dist/react/core/widgets/MessageStream.d.ts +3 -4
- package/dist/react/core/widgets/MessageStream.js +514 -444
- package/dist/react/core/widgets/MessageStream.js.map +1 -1
- package/dist/react/core/widgets/MissionCalendar.d.ts +3 -4
- package/dist/react/core/widgets/MissionCalendar.js +1488 -1020
- package/dist/react/core/widgets/MissionCalendar.js.map +1 -1
- package/dist/react/core/widgets/PacketViewer.d.ts +2 -3
- package/dist/react/core/widgets/PacketViewer.js +550 -421
- package/dist/react/core/widgets/PacketViewer.js.map +1 -1
- package/dist/react/core/widgets/capture-placeholder.png.js +6 -5
- package/dist/react/core/widgets/capture-placeholder.png.js.map +1 -1
- package/dist/react/hooks/index.d.ts +5 -5
- package/dist/react/hooks/useAccessWindows.d.ts +0 -1
- package/dist/react/hooks/useCompactMode.d.ts +1 -1
- package/dist/react/hooks/useCompactMode.js +104 -58
- package/dist/react/hooks/useCompactMode.js.map +1 -1
- package/dist/react/hooks/useGroundTrackHistory.d.ts +0 -1
- package/dist/react/hooks/useSimulationScene.d.ts +1 -2
- package/dist/react/hooks/useSimulationScene.js +481 -374
- package/dist/react/hooks/useSimulationScene.js.map +1 -1
- package/dist/react/index.d.ts +3 -3
- package/dist/react/panels/LayerControlPanel.d.ts +1 -2
- package/dist/react/panels/LayerControlPanel.js +223 -180
- package/dist/react/panels/LayerControlPanel.js.map +1 -1
- package/dist/react/panels/ObjectInventoryPanel.d.ts +2 -3
- package/dist/react/panels/ObjectInventoryPanel.js +315 -250
- package/dist/react/panels/ObjectInventoryPanel.js.map +1 -1
- package/dist/react/panels/index.d.ts +1 -1
- package/dist/react/panels/index.js +1 -6
- package/dist/react/shared/ErrorBoundary.d.ts +1 -2
- package/dist/react/shared/ErrorBoundary.js +170 -139
- package/dist/react/shared/ErrorBoundary.js.map +1 -1
- package/dist/react/shared/Skeleton.d.ts +1 -2
- package/dist/react/shared/Skeleton.js +300 -301
- package/dist/react/shared/Skeleton.js.map +1 -1
- package/dist/react/theme/ThemeProvider.d.ts +2 -321
- package/dist/react/theme/ThemeProvider.js +312 -939
- package/dist/react/theme/ThemeProvider.js.map +1 -1
- package/dist/react/theme/cardAccent.d.ts +1 -2
- package/dist/react/theme/cardAccent.js +196 -126
- package/dist/react/theme/cardAccent.js.map +1 -1
- package/dist/react/theme/config.d.ts +0 -1
- package/dist/react/theme/config.js +47 -25
- package/dist/react/theme/config.js.map +1 -1
- package/dist/react/theme/index.d.ts +2 -2
- package/dist/react/theme/index.js +1 -16
- package/dist/react/theme/types.d.ts +332 -0
- package/dist/react/theme/types.js +39 -0
- package/dist/react/theme/types.js.map +1 -0
- package/dist/react/types.d.ts +8 -8
- package/dist/react/types.js +147 -47
- package/dist/react/types.js.map +1 -1
- package/dist/react/utils/categoryPalette.d.ts +0 -1
- package/dist/react/utils/categoryPalette.js +91 -102
- package/dist/react/utils/categoryPalette.js.map +1 -1
- package/dist/react/utils/index.d.ts +5 -5
- package/dist/react/utils/index.js +457 -371
- package/dist/react/utils/index.js.map +1 -1
- package/dist/react/visualizations/EclipseTimerCard.d.ts +0 -1
- package/dist/react/visualizations/LinkBudgetCard.d.ts +0 -1
- package/dist/react/visualizations/NavBallCard.d.ts +0 -1
- package/dist/react/visualizations/PropulsionCard.d.ts +1 -2
- package/dist/react/visualizations/SensorFootprintCard.d.ts +1 -2
- package/dist/react/visualizations/ThermalHeatmapCard.d.ts +0 -1
- package/dist/react/visualizations/index.d.ts +3 -3
- package/dist/react.d.ts +2 -1
- package/dist/react.js +17 -221
- package/dist/shaders/atmosphere.frag.js +6 -5
- package/dist/shaders/atmosphere.frag.js.map +1 -1
- package/dist/shaders/atmosphere.vert.js +6 -5
- package/dist/shaders/atmosphere.vert.js.map +1 -1
- package/dist/shaders/stars.frag.js +6 -5
- package/dist/shaders/stars.frag.js.map +1 -1
- package/dist/shaders/stars.vert.js +6 -5
- package/dist/shaders/stars.vert.js.map +1 -1
- package/dist/style.css +217 -194
- package/dist/tokens/core.d.ts +159 -0
- package/dist/tokens/core.js +144 -0
- package/dist/tokens/core.js.map +1 -0
- package/dist/tokens/css-vars.d.ts +213 -2
- package/dist/tokens/css-vars.js +590 -227
- package/dist/tokens/css-vars.js.map +1 -1
- package/dist/tokens/index.d.ts +31 -228
- package/dist/tokens/index.js +281 -366
- package/dist/tokens/index.js.map +1 -1
- package/dist/tokens/palettes/astro.d.ts +129 -0
- package/dist/tokens/palettes/astro.js +112 -0
- package/dist/tokens/palettes/astro.js.map +1 -0
- package/dist/tokens/palettes/index.d.ts +288 -0
- package/dist/tokens/palettes/index.js +35 -0
- package/dist/tokens/palettes/index.js.map +1 -0
- package/dist/tokens/palettes/tailwind.d.ts +324 -0
- package/dist/tokens/palettes/tailwind.js +201 -0
- package/dist/tokens/palettes/tailwind.js.map +1 -0
- package/dist/tokens/palettes/zendir.d.ts +126 -0
- package/dist/tokens/palettes/zendir.js +92 -0
- package/dist/tokens/palettes/zendir.js.map +1 -0
- package/dist/tokens/themes.d.ts +30 -0
- package/dist/tokens/themes.js +704 -0
- package/dist/tokens/themes.js.map +1 -0
- package/dist/tokens/tokens.css +419 -41
- package/dist/types/index.d.ts +2 -2
- package/package.json +310 -313
- package/dist/index.js.map +0 -1
- package/dist/react/3d/index.js.map +0 -1
- package/dist/react/astro/index.js.map +0 -1
- package/dist/react/cards/index.js.map +0 -1
- package/dist/react/charts/index.js.map +0 -1
- package/dist/react/core/index.js.map +0 -1
- package/dist/react/panels/index.js.map +0 -1
- package/dist/react/theme/astro-tokens.d.ts +0 -153
- package/dist/react/theme/index.js.map +0 -1
- 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":";;AAyCA,MAAM,kBAAkB;AAoBxB,SAAS,uBACP,QACA,YACA,YACY;AACZ,MACE,CAAC,cACD,CAAC,OAAO,SAAS,WAAW,CAAC,KAC7B,CAAC,OAAO,SAAS,WAAW,CAAC,KAC7B,CAAC,OAAO,SAAS,WAAW,CAAC,GAC7B;AACA,WAAO;AAAA,EACT;AAEA,QAAM,OAAO,IAAI,OAAO;AAAA,IACtB,WAAW,IAAI;AAAA,IACf,WAAW,IAAI;AAAA,IACf,WAAW,IAAI;AAAA,EAAA;AAEjB,QAAM,MAAM,OAAO,WAAW,+BAA+B,UAAU;AACvE,MAAI,CAAC,KAAK;AAIR,WAAO;AAAA,EACT;AACA,SAAO,OAAO,QAAQ,iBAAiB,KAAK,MAAM,IAAI,OAAO,YAAY;AAC3E;AAOA,SAAS,oBACP,QACA,YACA,YACkE;AAClE,QAAM,QAAQ,uBAAuB,QAAQ,YAAY,UAAU;AACnE,MAAI,CAAC,MAAO,QAAO;AACnB,QAAM,QAAQ,OAAO,aAAa,cAAc,KAAK;AACrD,MAAI,CAAC,SAAS,CAAC,OAAO,SAAS,MAAM,MAAM,EAAG,QAAO;AACrD,SAAO;AAAA,IACL,UAAU,OAAO,KAAK,UAAU,MAAM,QAAQ;AAAA,IAC9C,WAAW,OAAO,KAAK,UAAU,MAAM,SAAS;AAAA,IAChD,UAAU,MAAM,SAAS;AAAA;AAAA,EAAA;AAE7B;AAYA,SAAS,qBAAqB,YAAoB,YAA4B;AAC5E,MAAI,cAAc,EAAG,QAAO;AAC5B,QAAM,IAAI;AACV,QAAM,MAAO,aAAa,KAAK,KAAM;AACrC,QAAM,WAAY,IAAI,KAAK,IAAI,GAAG,KAAM,IAAI;AAC5C,MAAI,YAAY,EAAG,QAAO;AAC1B,QAAM,QAAQ,KAAK,KAAK,QAAQ;AAChC,QAAM,SAAS,KAAK,KAAK,IAAI,MAAM;AACnC,SAAO,IAAI,MAAO;AACpB;AAGA,SAAS,0BAA0B,YAAoB,cAA8B;AACnF,SAAO,aAAa,MAAO,KAAK,IAAK,eAAe,KAAK,KAAM,GAAG;AACpE;AAMA,SAAS,cAAc,QAAa,IAAY,KAAsB;AACpE,MAAI,IAAI,QAAQ,IAAI,EAAE,GAAG;AACvB,QAAI;AAAE,aAAO,SAAS,WAAW,EAAE;AAAA,IAAG,SAAS,GAAG;AAAA,IAAqB;AACvE,QAAI,QAAQ,OAAO,EAAE;AAAA,EACvB;AACF;AAEA,SAAS,kBAAkB,QAAa,OAAY,YAAY,GAAG;AACjE,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,cAAc,OAAO,MAAM;AAAA,IAC3B,cAAc;AAAA,IACd,iBAAiB,IAAI,OAAO,cAAc,KAAK,KAAK,KAAK,GAAG;AAAA;AAAA,IAE5D,0BAA0B,OAAO;AAAA,EAAA;AAErC;AAEA,SAAS,cAAc,QAAa,MAAc,WAAiB;AACjE,SAAO;AAAA,IACL;AAAA,IACA,MAAM;AAAA,IACN,WAAW,aAAa,OAAO,MAAM;AAAA,IACrC,cAAc,OAAO,MAAM;AAAA,IAC3B,cAAc;AAAA,IACd,OAAO,OAAO,WAAW;AAAA,IACzB,aAAa,IAAI,OAAO,WAAW,IAAI,CAAC;AAAA,IACxC,iBAAiB,IAAI,OAAO,cAAc,KAAK,GAAK,KAAK,GAAG;AAAA;AAAA,IAE5D,0BAA0B,IAAI,OAAO,yBAAyB,GAAG,GAAG;AAAA,IACpE,0BAA0B,OAAO;AAAA,EAAA;AAErC;AAGA,SAAS,cACP,QACA,QACA,IACA,UACA,SACA,OACA,KACM;AACN,QAAM,WAAW,IAAI,QAAQ,IAAI,EAAE;AACnC,MAAI,UAAU;AACZ,aAAS,WAAW,IAAI,OAAO,yBAAyB,QAAQ;AAChE,aAAS,QAAQ,gBAAgB,IAAI,OAAO,iBAAiB,OAAO;AACpE,aAAS,QAAQ,gBAAgB,IAAI,OAAO,iBAAiB,OAAO;AAAA,EACtE,OAAO;AACL,UAAM,SAAS,OAAO,SAAS,IAAI;AAAA,MACjC;AAAA,MACA;AAAA,MACA,SAAS;AAAA,QACP,eAAe;AAAA,QACf,eAAe;AAAA,QACf,UAAU,MAAM,UAAU,IAAI;AAAA,QAC9B,SAAS;AAAA,QACT,cAAc,MAAM,UAAU,GAAG;AAAA,QACjC,cAAc;AAAA,QACd,QAAQ;AAAA,MAAA;AAAA,IACV,CACD;AACD,QAAI,QAAQ,IAAI,IAAI,MAAM;AAAA,EAC5B;AACF;AAMA,SAAS,uBACP,QACA,QACA,OACA,SACA,KACA,YACA,QACA,SACA,UACM;;AACN,QAAM,YAAY,IAAI,QAClB,OAAO,MAAM,mBAAmB,IAAI,KAAK,IACzC,OAAO,MAAM;AACjB,QAAM,UAAU,IAAI,WAAW;AAE/B,QAAM,cAAc,IAAI,qBAAqB;AAC7C,QAAM,YAAY,uBAAuB,QAAQ,aAAa,UAAU;AACxE,QAAM,SAAS,oBAAoB,QAAQ,aAAa,UAAU;AAClE,QAAM,YAAW,iCAAQ,aAAY;AACrC,QAAM,aAAY,iCAAQ,cAAa;AACvC,QAAM,YAAW,iCAAQ,aAAY;AAErC,QAAM,aAAW,SAAI,eAAJ,mBAAgB,aAAY;AAC7C,QAAM,aAAW,SAAI,eAAJ,mBAAgB,cAAa;AAG9C,QAAM,QAAQ,OAAO,KAAK;AAC1B,MAAI,IAAI,kBAAkB,SAAS,IAAI,oBAAoB,IAAI,iBAAiB,UAAU,GAAG;AAC3F,UAAM,YAAY,OAAO,WAAW;AAAA,MAClC,IAAI,iBAAiB,QAAQ,CAAC,OAAO,CAAC,GAAG,WAAW,GAAG,QAAQ,CAAC;AAAA,IAAA;AAElE,UAAM,WAAW,OAAO,QAAQ,IAAI,KAAK;AACzC,QAAI,UAAU;AACZ,eAAS,QAAQ,YAAY,IAAI,OAAO;AAAA,QACtC,IAAI,OAAO,iBAAiB,SAAS;AAAA,MAAA;AAAA,IAEzC,OAAO;AACL,YAAM,SAAS,OAAO,SAAS,IAAI;AAAA,QACjC,IAAI;AAAA,QACJ,SAAS;AAAA,UACP,WAAW,IAAI,OAAO,iBAAiB,SAAS;AAAA,UAChD,UAAU,UAAU,UAAU,OAAO;AAAA,UACrC,SAAS;AAAA,UACT,cAAc,UAAU,UAAU,UAAU,CAAC;AAAA,UAC7C,QAAQ;AAAA,UACR,eAAe;AAAA,QAAA;AAAA,MACjB,CACD;AACD,aAAO,QAAQ,IAAI,OAAO,MAAM;AAAA,IAClC;AAAA,EACF,WACE,IAAI,kBAAkB,SACtB,IAAI,aAAa,QACjB,OAAO,SAAS,QAAQ,KACxB,WAAW,GACX;AACA,UAAM,YAAY,OAAO,WAAW,YAAY,UAAU,UAAU,CAAC;AACrE,UAAM,SAAS,0BAA0B,UAAU,IAAI,SAAS;AAChE,kBAAc,QAAQ,QAAQ,OAAO,WAAW,QAAQ,WAAW,MAAM;AAAA,EAC3E,OAAO;AACL,kBAAc,QAAQ,OAAO,MAAM;AAAA,EACrC;AAGA,QAAM,SAAS,QAAQ,KAAK;AAC5B,MAAI,IAAI,YAAY,aAAa,OAAO,SAAS,QAAQ,KAAK,WAAW,GAAG;AAC1E,UAAM,SAAS,IAAI,aAAa,OAC5B,0BAA0B,UAAU,IAAI,SAAS,IACjD,qBAAqB,UAAU,CAAC;AACpC,UAAM,aAAa,WAAW;AAE9B,UAAM,SAAS,OAAO,WAAW,YAAY,UAAU,UAAU,aAAa,CAAC;AAC/E,UAAM,WAAW,QAAQ,QAAQ,IAAI,MAAM;AAC3C,QAAI,UAAU;AACZ,eAAS,WAAW,IAAI,OAAO,yBAAyB,MAAM;AAC9D,eAAS,SAAS,SAAS,IAAI,OAAO,iBAAiB,UAAU;AACjE,eAAS,SAAS,eAAe,IAAI,OAAO,iBAAiB,MAAM;AAAA,IACrE,OAAO;AACL,YAAM,SAAS,OAAO,SAAS,IAAI;AAAA,QACjC,IAAI;AAAA,QACJ,UAAU;AAAA,QACV,UAAU;AAAA,UACR,QAAQ;AAAA,UACR,WAAW;AAAA,UACX,cAAc;AAAA,UACd,UAAU,UAAU,UAAU,IAAI;AAAA,UAClC,SAAS;AAAA,UACT,cAAc,UAAU,UAAU,IAAI;AAAA,UACtC,uBAAuB;AAAA,QAAA;AAAA,MACzB,CACD;AACD,cAAQ,QAAQ,IAAI,QAAQ,MAAM;AAAA,IACpC;AAAA,EACF,OAAO;AACL,kBAAc,QAAQ,QAAQ,OAAO;AAAA,EACvC;AAGA,QAAM,UAAU,SAAS,KAAK;AAC9B,MAAI,IAAI,iBAAiB,WAAW;AAClC,UAAM,YAAY,OAAO,WAAW,YAAY,UAAU,UAAU,CAAC;AACrE,UAAM,WAAW,SAAS,QAAQ,IAAI,OAAO;AAC7C,QAAI,UAAU;AACZ,eAAS,SAAS,YAAY,IAAI,OAAO,iBAAiB,CAAC,WAAW,SAAS,CAAC;AAAA,IAClF,OAAO;AACL,YAAM,SAAS,OAAO,SAAS,IAAI;AAAA,QACjC,IAAI;AAAA,QACJ,UAAU;AAAA,UACR,WAAW,CAAC,WAAW,SAAS;AAAA,UAChC,OAAO;AAAA,UACP,UAAU,IAAI,OAAO,6BAA6B;AAAA,YAChD,OAAO,UAAU,UAAU,GAAG;AAAA,YAC9B,YAAY;AAAA,UAAA,CACb;AAAA,QAAA;AAAA,MACH,CACD;AACD,eAAS,QAAQ,IAAI,SAAS,MAAM;AAAA,IACtC;AAAA,EACF,OAAO;AACL,kBAAc,QAAQ,SAAS,QAAQ;AAAA,EACzC;AACF;AASO,MAAM,mBAAmB;AAAA,EAC9B,SAASA,kBACP;AAAA,IACE,aAAa,CAAA;AAAA,IACb,WAAW,CAAA;AAAA,IACX,iBAAiB,CAAA;AAAA,IACjB,gBAAgB,CAAA;AAAA,IAChB,aAAa,CAAA;AAAA,IACb,qBAAqB,CAAA;AAAA,IACrB,OAAO;AAAA,IACP,SAAS;AAAA,IACT;AAAA,IACA,YAAY;AAAA,IACZ;AAAA,IACA;AAAA,IACA;AAAA,IACA,QAAQ;AAAA,EAAA,GAEV,KACA;AACA,UAAM,eAAe,OAAuB,IAAI;AAChD,UAAM,YAAY,OAAY,IAAI;AAIlC,UAAM,eAAe,OAAO,SAAS;AACrC,cAAU,MAAM;AAAE,mBAAa,UAAU;AAAA,IAAW,GAAG,CAAC,SAAS,CAAC;AAIlE,UAAM,YAAc,OAAyB,oBAAI,KAAK;AACtD,UAAM,WAAc,OAAyB,oBAAI,KAAK;AACtD,UAAM,YAAc,OAAyB,oBAAI,KAAK;AACtD,UAAM,aAAc,OAAyB,oBAAI,KAAK;AACtD,UAAM,cAAc,OAAyB,oBAAI,KAAK;AACtD,UAAM,cAAc,OAAyB,oBAAI,KAAK;AAOtD,UAAM,kBAAkB,OAA8B,oBAAI,KAAK;AAK/D,UAAM,cAAe,iCAAQ,YAAa;AAC1C,UAAM,gBAAe,iCAAQ,cAAa;AAC1C,UAAM,cAAe,iCAAQ,YAAa;AAK1C,UAAM,kBAAsB,yCAAY,gBAAoB;AAC5D,UAAM,sBAAsB,yCAAY,oBAAoB;AAC5D,UAAM,uBAAsB,yCAAY,qBAAoB;AAG5D,UAAM,UAAU;AAAA,MACd,CAAC,UAAkB,YAAmD;AACpE,cAAM,SAAS,UAAU;AACzB,YAAI,CAAC,OAAQ;AACb,cAAM,SAAS,OAAO,SAAS,QAAQ,QAAQ;AAC/C,YAAI,QAAQ;AACV,iBAAO,OAAO,QAAQ,EAAE,WAAU,mCAAS,aAAY,QAAQ,MAAM,GAAG;AAAA,QAC1E;AAAA,MACF;AAAA,MACA,CAAA;AAAA,IAAC;AAGH,UAAM,UAAU;AAAA,MACd,CAAC,SAAmB;AAClB,cAAM,SAAS,UAAU;AACzB,YAAI,CAAC,OAAQ;AACb,YAAI,SAAS,eAAe;AAC1B,iBAAO,OAAO,MAAM,EAAE,aAAa,OAAO,WAAW,YAAY,GAAG,GAAG,GAAG,EAAA,CAAG;AAAA,QAC/E,WAAW,SAAS,gBAAgB;AAClC,iBAAO,OAAO,MAAM,EAAE,aAAa,OAAO,WAAW,YAAY,GAAG,GAAG,GAAG,EAAA,CAAG;AAAA,QAC/E;AAAA,MACF;AAAA,MACA,CAAC,MAAM;AAAA,IAAA;AAGT;AAAA,MACE;AAAA,MACA,OAAyB;AAAA,QACvB;AAAA,QACA,OAAO;AAAA,QACP;AAAA,QACA,SAAS,MAAM;AAAA,QAAC;AAAA,QAChB,cAAc,MAAM;AAAA,QAAC;AAAA,QACrB,YAAY,MAAM;AAAA,QAAC;AAAA,QACnB,oBAAoB,MAAM;AAAA,QAAC;AAAA,QAC3B,gBAAgB,OAAO,CAAA;AAAA,QACvB,gBAAgB,MAAM;AAAA,QAAC;AAAA,QACvB,aAAa,MAAM;AAAA,QACnB,aAAa,MAAM,IAAI,KAAA;AAAA,QACvB,mBAAmB,MAAM,CAAA;AAAA,QACzB,aAAa,MAAM,CAAA;AAAA,QACnB,WAAW,MAAM;AAAA,QAAC;AAAA,QAClB,cAAc,MAAM;AAAA,QAAC;AAAA,QACrB,cAAc,MAAM;AAAA,QAAC;AAAA,QACrB,iBAAiB,MAAM;AAAA,MAAA;AAAA,MAEzB,CAAC,SAAS,OAAO;AAAA,IAAA;AASnB,cAAU,MAAM;AACd,UAAI,CAAC,aAAa,WAAW,CAAC,OAAQ;AAGtC,gBAAU,QAAQ,MAAA;AAClB,eAAS,QAAQ,MAAA;AACjB,gBAAU,QAAQ,MAAA;AAClB,iBAAW,QAAQ,MAAA;AACnB,kBAAY,QAAQ,MAAA;AACpB,kBAAY,QAAQ,MAAA;AACpB,sBAAgB,QAAQ,MAAA;AAExB,YAAM,SAAS,IAAI,OAAO,OAAO,aAAa,SAAS;AAAA,QACrD,iBAAiB;AAAA,QACjB,kBAAkB;AAAA,QAClB,UAAU;AAAA,QACV,UAAU;AAAA,QACV,YAAY,CAAC,CAAC;AAAA,QACd,iBAAiB;AAAA,QACjB,UAAU;AAAA,QACV,sBAAsB,CAAC,CAAC;AAAA,QACxB,WAAW;AAAA,QACX,aAAa;AAAA,QACb,sBAAsB;AAAA,QACtB,mBAAmB;AAAA,MAAA,CACpB;AAED,aAAO,MAAM,MAAM,iBAAiB;AACpC,aAAO,MAAM,kBAAkB,OAAO,MAAM;AAK5C,aAAO,MAAM,YAAY,iBAAiB,CAAC,OAAY,QAAiB;AAEtE,gBAAQ,MAAM,qCAAqC,GAAG;AAAA,MACxD,CAAC;AAOD,aAAO,MAAM,cAAc,OAAO,WAAW,IAAA;AAC7C,aAAO,MAAM,aAAc;AAC3B,aAAO,MAAM,gBAAgB;AAE7B,gBAAU,UAAU;AAEpB,YAAM,UAAU,IAAI,OAAO,wBAAwB,OAAO,MAAM,MAAM;AAGtE,cAAQ,eAAe,CAAC,aAAkB;;AACxC,cAAM,SAAS,OAAO,MAAM,KAAK,SAAS,QAAQ;AAClD,YAAI,OAAO,QAAQ,MAAM,KAAK,OAAO,QAAM,kBAAa,YAAb,mBAAsB,WAAU;AACzE,uBAAa,QAAQ,SAAS;AAAA,YAC5B,IAAI,OAAO,GAAG;AAAA,YACd,MAAM,OAAO,GAAG;AAAA,YAChB,UAAU;AAAA,YACV,UAAU,EAAE,GAAG,GAAG,GAAG,GAAG,GAAG,EAAA;AAAA,YAC3B,cAAc;AAAA,UAAA,CACf;AAAA,QACH;AAAA,MACF,GAAG,OAAO,qBAAqB,UAAU;AAGzC,cAAQ,eAAe,CAAC,aAAkB;;AACxC,cAAM,SAAS,OAAO,MAAM,KAAK,SAAS,WAAW;AACrD,YAAI,OAAO,QAAQ,MAAM,KAAK,OAAO,IAAI;AACvC,mCAAa,YAAb,mBAAsB,YAAtB,4BAAgC;AAAA,YAC9B,IAAI,OAAO,GAAG;AAAA,YACd,MAAM,OAAO,GAAG;AAAA,YAChB,UAAU;AAAA,YACV,UAAU,EAAE,GAAG,GAAG,GAAG,GAAG,GAAG,EAAA;AAAA,YAC3B,cAAc;AAAA,UAAA;AAAA,QAElB,OAAO;AACL,mCAAa,YAAb,mBAAsB,YAAtB,4BAAgC;AAAA,QAClC;AAAA,MACF,GAAG,OAAO,qBAAqB,UAAU;AAEzC,aAAO,MAAM;AACX,gBAAQ,QAAA;AACR,kBAAU,QAAQ,MAAA;AAClB,iBAAS,QAAQ,MAAA;AACjB,kBAAU,QAAQ,MAAA;AAClB,mBAAW,QAAQ,MAAA;AACnB,oBAAY,QAAQ,MAAA;AACpB,oBAAY,QAAQ,MAAA;AACpB,wBAAgB,QAAQ,MAAA;AACxB,eAAO,QAAA;AACP,kBAAU,UAAU;AAAA,MACtB;AAAA,IACF,GAAG,CAAC,QAAQ,SAAS,CAAC;AAOtB,cAAU,MAAM;AACd,YAAM,SAAS,UAAU;AACzB,UAAI,CAAC,UAAU,CAAC,OAAQ;AAMxB,YAAM,KAAK,gBACP,OAAO,WAAW,SAAS,aAAa,IACxC,OAAO,WAAW,IAAA;AAOtB,YAAM,+BAAe,IAAA;AACrB,YAAM,eAAe,iBAAiB,CAAC,GAAG,YAAY,GAAG,QAAQ,IAAI,CAAA;AAErE,mBAAa,QAAQ,CAAC,QAAQ;AAC5B,cAAM,KAAK,IAAI;AACf,cAAM,OAAQ,IAAY;AAC1B,YAAI,CAAC,KAAM;AAEX,YAAI,CAAC,OAAO,SAAS,KAAK,CAAC,KAAK,CAAC,OAAO,SAAS,KAAK,CAAC,KAAK,CAAC,OAAO,SAAS,KAAK,CAAC,EAAG;AAKtF,wBAAgB,QAAQ,IAAI,IAAI,IAAI;AACpC,iBAAS,IAAI,EAAE;AAEf,cAAM,OAAQ,IAAY,QAAQ;AAClC,cAAM,WAAW,UAAU,QAAQ,IAAI,EAAE;AAEzC,YAAI,UAAU;AAIZ,cAAI,SAAS,OAAO;AAClB,qBAAS,MAAM,OAAO,IAAI,OAAO,iBAAiB,UAAU;AAAA,UAC9D,WAAW,YAAY;AACrB,qBAAS,QAAQ,IAAI,OAAO,cAAc,cAAc,QAAQ,IAAI,CAAC;AAAA,UACvE;AAAA,QACF,OAAO;AAKL,gBAAM,aAAa;AAMnB,gBAAM,cAAc,IAAI,OAAO;AAAA,YAC7B,CAAC,SAAc;AACb,kBAAI;AACF,sBAAM,QAAQ,gBAAgB,QAAQ,IAAI,UAAU;AACpD,oBAAI,CAAC,MAAO,QAAO;AACnB,sBAAM,QAAQ,uBAAuB,QAAQ,OAAO,IAAI;AACxD,oBACE,CAAC,SACD,CAAC,OAAO,SAAS,MAAM,CAAC,KACxB,CAAC,OAAO,SAAS,MAAM,CAAC,KACxB,CAAC,OAAO,SAAS,MAAM,CAAC,GACxB;AACA,yBAAO;AAAA,gBACT;AACA,uBAAO;AAAA,cACT,QAAQ;AACN,uBAAO;AAAA,cACT;AAAA,YACF;AAAA,YACA;AAAA;AAAA,YACA,OAAO,eAAe;AAAA,UAAA;AAExB,gBAAM,SAAS,OAAO,SAAS,IAAI;AAAA,YACjC;AAAA,YACA;AAAA,YACA,UAAU;AAAA,YACV,OAAO,kBAAkB,QAAQ,OAAO,MAAM,IAAI;AAAA,YAClD,OAAO,aACH,IAAI,OAAO,cAAc,cAAc,QAAQ,IAAI,CAAC,IACpD;AAAA,UAAA,CACL;AACD,oBAAU,QAAQ,IAAI,IAAI,MAAM;AAAA,QAClC;AAGA,cAAM,eAAe,sBAAsB,IAAI,KAAK,CAAC,MAAM,EAAE,gBAAgB,EAAE;AAC/E,YAAI,aAAa;AACf;AAAA,YACE;AAAA,YAAQ;AAAA,YAAQ;AAAA,YAAI;AAAA,YAAM;AAAA,YAAa;AAAA,YACvC;AAAA,YAAW;AAAA,YAAY;AAAA,UAAA;AAAA,QAE3B,WAAW,cAAc;AAEvB,gBAAM,SAAS,oBAAoB,QAAQ,MAAM,EAAE;AACnD,cAAI,UAAU,OAAO,WAAW,GAAG;AACjC,kBAAM,YAAY,OAAO,WAAW,YAAY,OAAO,WAAW,OAAO,UAAU,CAAC;AACpF,kBAAM,SAAS,qBAAqB,OAAO,UAAU,CAAC;AACtD,0BAAc,QAAQ,QAAQ,OAAO,EAAE,IAAI,WAAW,QAAQ,OAAO,MAAM,MAAM,SAAS;AAAA,UAC5F;AAAA,QACF,OAAO;AACL,wBAAc,QAAQ,OAAO,EAAE,IAAI,SAAS;AAC5C,wBAAc,QAAQ,QAAQ,EAAE,IAAI,UAAU;AAC9C,wBAAc,QAAQ,SAAS,EAAE,IAAI,WAAW;AAAA,QAClD;AAAA,MACF,CAAC;AAGD,gBAAU,QAAQ,QAAQ,CAAC,GAAG,OAAO;AACnC,YAAI,CAAC,SAAS,IAAI,EAAE,GAAG;AACrB,0BAAgB,QAAQ,OAAO,EAAE;AACjC,wBAAc,QAAQ,IAAI,SAAS;AACnC,wBAAc,QAAQ,OAAO,EAAE,IAAI,SAAS;AAC5C,wBAAc,QAAQ,QAAQ,EAAE,IAAI,UAAU;AAC9C,wBAAc,QAAQ,SAAS,EAAE,IAAI,WAAW;AAAA,QAClD;AAAA,MACF,CAAC;AAOD,YAAM,iCAAiB,IAAA;AACvB,YAAM,iBAAiB,sBAAuB,iBAAiB,CAAA,IAAM,CAAA;AACrE,qBAAe,QAAQ,CAAC,QAAQ;AAC9B,YAAI,WAAW,KAAK,IAAI,QAAQ,EAAE,EAAG;AACrC,cAAM,KAAK,IAAI;AACf,cAAM,SAAS,uBAAuB,QAAQ,IAAI,UAAU,EAAE;AAC9D,YAAI,CAAC,OAAQ;AACb,mBAAW,IAAI,EAAE;AAEjB,cAAM,WAAW,UAAU,QAAQ,IAAI,UAAU,EAAE,EAAE;AACrD,YAAI,UAAU;AACZ,mBAAS,WAAW,IAAI,OAAO,yBAAyB,MAAM;AAC9D,cAAI,SAAS,OAAO;AAClB,qBAAS,MAAM,OAAO,IAAI,OAAO,iBAAiB,UAAU;AAAA,UAC9D,WAAW,YAAY;AACrB,qBAAS,QAAQ,IAAI,OAAO;AAAA,cAC1B,cAAc,QAAQ,IAAI,QAAQ,IAAI,OAAO,MAAM,MAAM;AAAA,YAAA;AAAA,UAE7D;AAAA,QACF,OAAO;AACL,gBAAM,SAAS,OAAO,SAAS,IAAI;AAAA,YACjC,IAAI,UAAU,EAAE;AAAA,YAChB,MAAM,IAAI;AAAA,YACV,UAAU;AAAA,YACV,OAAO,kBAAkB,QAAQ,OAAO,MAAM,QAAQ,EAAE;AAAA,YACxD,OAAO,aACH,IAAI,OAAO,cAAc,cAAc,QAAQ,IAAI,QAAQ,IAAI,OAAO,MAAM,MAAM,CAAC,IACnF;AAAA,UAAA,CACL;AACD,oBAAU,QAAQ,IAAI,UAAU,EAAE,IAAI,MAAM;AAAA,QAC9C;AAAA,MACF,CAAC;AAED,gBAAU,QAAQ,QAAQ,CAAC,GAAG,QAAQ;AACpC,YAAI,IAAI,WAAW,SAAS,KAAK,CAAC,WAAW,IAAI,IAAI,MAAM,CAAC,CAAC,GAAG;AAC9D,wBAAc,QAAQ,KAAK,SAAS;AAAA,QACtC;AAAA,MACF,CAAC;AAKD,YAAM,6BAAa,IAAA;AACnB,YAAM,aAAa,qBAAsB,kBAAkB,CAAA,IAAM,CAAA;AACjE,iBAAW,QAAQ,CAAC,OAAO;AACzB,YAAI,CAAC,OAAO,SAAS,GAAG,SAAS,KAAK,CAAC,OAAO,SAAS,GAAG,QAAQ,EAAG;AACrE,eAAO,IAAI,GAAG,EAAE;AAChB,cAAM,UAAU,OAAO,SAAU,GAAW,SAAS,IAAK,GAAW,YAAY;AACjF,cAAM,QAAQ,OAAO,WAAW,YAAY,GAAG,WAAW,GAAG,UAAU,OAAO;AAC9E,cAAM,OAAO,GAAG,QAAQ,GAAG;AAE3B,cAAM,WAAW,SAAS,QAAQ,IAAI,GAAG,EAAE;AAC3C,YAAI,UAAU;AACZ,mBAAS,WAAW,IAAI,OAAO,yBAAyB,KAAK;AAC7D,cAAI,SAAS,OAAO;AAClB,qBAAS,MAAM,OAAO,IAAI,OAAO,iBAAiB,UAAU;AAAA,UAC9D,WAAW,YAAY;AACrB,qBAAS,QAAQ,IAAI,OAAO;AAAA,cAC1B,cAAc,QAAQ,MAAM,OAAO,MAAM,MAAM;AAAA,YAAA;AAAA,UAEnD;AAAA,QACF,OAAO;AACL,gBAAM,SAAS,OAAO,SAAS,IAAI;AAAA,YACjC,IAAI,GAAG;AAAA,YACP;AAAA,YACA,UAAU;AAAA,YACV,OAAO,kBAAkB,QAAQ,OAAO,MAAM,QAAQ,CAAC;AAAA,YACvD,OAAO,aACH,IAAI,OAAO,cAAc,cAAc,QAAQ,MAAM,OAAO,MAAM,MAAM,CAAC,IACzE;AAAA,UAAA,CACL;AACD,mBAAS,QAAQ,IAAI,GAAG,IAAI,MAAM;AAAA,QACpC;AAAA,MACF,CAAC;AAED,eAAS,QAAQ,QAAQ,CAAC,GAAG,OAAO;AAClC,YAAI,CAAC,OAAO,IAAI,EAAE,EAAG,eAAc,QAAQ,IAAI,QAAQ;AAAA,MACzD,CAAC;AAGD,UAAI,YAAY;AACd,cAAM,iCAAiB,IAAA;AAEvB,SAAC,cAAc,CAAA,GAAI,QAAQ,CAAC,SAAS;AACnC,gBAAM,UAAU,SAAS,KAAK,QAAQ;AACtC,qBAAW,IAAI,OAAO;AACtB,gBAAM,YAAY,KAAK,OACpB,IAAI,CAAC,MAAM,uBAAuB,QAAQ,GAAG,EAAE,CAAC,EAChD,OAAO,CAAC,MAAkC,KAAK,IAAI;AACtD,cAAI,UAAU,SAAS,EAAG;AAE1B,gBAAM,aAAa,KAAK,QACpB,OAAO,MAAM,mBAAmB,KAAK,KAAK,EAAE,UAAU,IAAI,IAC1D,OAAO,MAAM,OAAO,UAAU,IAAI;AAEtC,gBAAM,WAAW,YAAY,QAAQ,IAAI,OAAO;AAChD,cAAI,UAAU;AACZ,qBAAS,SAAS,YAAY,IAAI,OAAO,iBAAiB,SAAS;AAAA,UACrE,OAAO;AACL,kBAAM,SAAS,OAAO,SAAS,IAAI;AAAA,cACjC,IAAI;AAAA,cACJ,MAAM,KAAK;AAAA,cACX,UAAU;AAAA,gBACR;AAAA,gBACA,OAAO;AAAA,gBACP,UAAU,IAAI,OAAO,6BAA6B;AAAA,kBAChD,OAAO;AAAA,kBACP,YAAY;AAAA,gBAAA,CACb;AAAA,cAAA;AAAA,YACH,CACD;AACD,wBAAY,QAAQ,IAAI,SAAS,MAAM;AAAA,UACzC;AAAA,QACF,CAAC;AAED,oBAAY,QAAQ,QAAQ,CAAC,GAAG,OAAO;AACrC,cAAI,CAAC,WAAW,IAAI,EAAE,EAAG,eAAc,QAAQ,IAAI,WAAW;AAAA,QAChE,CAAC;AAAA,MACH,OAAO;AAEL,oBAAY,QAAQ,QAAQ,CAAC,GAAG,OAAO,cAAc,QAAQ,IAAI,WAAW,CAAC;AAAA,MAC/E;AAAA,IACF,GAAG;AAAA,MACD;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IAAA,CACD;AAMD,cAAU,MAAM;AACd,cAAQ,IAAI;AAAA,IAId,GAAG,CAAC,IAAI,CAAC;AAET,UAAM,IAAI,OAAO,WAAW,WAAW,GAAG,MAAM,OAAO;AACvD,WACE;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,KAAK;AAAA,QACL,WAAU;AAAA,QACV,OAAO,EAAE,OAAO,QAAQ,QAAQ,GAAG,WAAW,IAAA;AAAA,MAAI;AAAA,IAAA;AAAA,EAGxD;AACF;"}
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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 = [
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
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
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
449
|
+
return {
|
|
450
|
+
time: { value: 0 },
|
|
451
|
+
pointSize: { value: pointSize }
|
|
452
|
+
};
|
|
442
453
|
}
|
|
443
|
-
function createVisibilityConeUniforms(color = [
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
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
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
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"}
|