@zendir/ui 0.1.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 +19 -0
- package/LICENSE +21 -0
- package/README.md +589 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.js +421 -0
- package/dist/index.js.map +1 -0
- package/dist/react/3d/EarthViewer.d.ts +46 -0
- package/dist/react/3d/EarthViewer.js +836 -0
- package/dist/react/3d/EarthViewer.js.map +1 -0
- package/dist/react/3d/SolarSystemViewer.d.ts +43 -0
- package/dist/react/3d/SolarSystemViewer.js +372 -0
- package/dist/react/3d/SolarSystemViewer.js.map +1 -0
- package/dist/react/3d/ZenSpace3D.d.ts +16 -0
- package/dist/react/3d/ZenSpace3D.js +1253 -0
- package/dist/react/3d/ZenSpace3D.js.map +1 -0
- package/dist/react/3d/ZenSpace3DCesium.d.ts +9 -0
- package/dist/react/3d/ZenSpace3DCesium.js +186 -0
- package/dist/react/3d/ZenSpace3DCesium.js.map +1 -0
- package/dist/react/3d/ZenSpace3DShaders.d.ts +78 -0
- package/dist/react/3d/ZenSpace3DShaders.js +94 -0
- package/dist/react/3d/ZenSpace3DShaders.js.map +1 -0
- package/dist/react/3d/ZenSpace3DTypes.d.ts +614 -0
- package/dist/react/3d/ZenSpace3DUtils.d.ts +183 -0
- package/dist/react/3d/ZenSpace3DUtils.js +213 -0
- package/dist/react/3d/ZenSpace3DUtils.js.map +1 -0
- package/dist/react/3d/index.d.ts +23 -0
- package/dist/react/3d/threeLoader.d.ts +22 -0
- package/dist/react/3d/threeLoader.js +18 -0
- package/dist/react/3d/threeLoader.js.map +1 -0
- package/dist/react/astro/ClassificationBanner.d.ts +25 -0
- package/dist/react/astro/ClassificationBanner.js +83 -0
- package/dist/react/astro/ClassificationBanner.js.map +1 -0
- package/dist/react/astro/GlobalStatusBar.d.ts +42 -0
- package/dist/react/astro/GlobalStatusBar.js +165 -0
- package/dist/react/astro/GlobalStatusBar.js.map +1 -0
- package/dist/react/astro/MissionClock.d.ts +169 -0
- package/dist/react/astro/MissionClock.js +411 -0
- package/dist/react/astro/MissionClock.js.map +1 -0
- package/dist/react/astro/MonitoringIcon.d.ts +60 -0
- package/dist/react/astro/MonitoringIcon.js +369 -0
- package/dist/react/astro/MonitoringIcon.js.map +1 -0
- package/dist/react/astro/Notification.d.ts +42 -0
- package/dist/react/astro/Notification.js +156 -0
- package/dist/react/astro/Notification.js.map +1 -0
- package/dist/react/astro/Progress.d.ts +39 -0
- package/dist/react/astro/Progress.js +149 -0
- package/dist/react/astro/Progress.js.map +1 -0
- package/dist/react/astro/SimulationControls.d.ts +136 -0
- package/dist/react/astro/SimulationControls.js +668 -0
- package/dist/react/astro/SimulationControls.js.map +1 -0
- package/dist/react/astro/StatusIndicator.d.ts +34 -0
- package/dist/react/astro/StatusIndicator.js +189 -0
- package/dist/react/astro/StatusIndicator.js.map +1 -0
- package/dist/react/astro/UnifiedTimeline.d.ts +106 -0
- package/dist/react/astro/UnifiedTimeline.js +1768 -0
- package/dist/react/astro/UnifiedTimeline.js.map +1 -0
- package/dist/react/astro/index.d.ts +63 -0
- package/dist/react/cards/AccessCard.d.ts +37 -0
- package/dist/react/cards/AccessCard.js +410 -0
- package/dist/react/cards/AccessCard.js.map +1 -0
- package/dist/react/cards/OrbitCard.d.ts +31 -0
- package/dist/react/cards/OrbitCard.js +372 -0
- package/dist/react/cards/OrbitCard.js.map +1 -0
- package/dist/react/cards/SpacecraftCard.d.ts +54 -0
- package/dist/react/cards/SpacecraftCard.js +941 -0
- package/dist/react/cards/SpacecraftCard.js.map +1 -0
- package/dist/react/cards/TelemetryCard.d.ts +40 -0
- package/dist/react/cards/TelemetryCard.js +742 -0
- package/dist/react/cards/TelemetryCard.js.map +1 -0
- package/dist/react/cards/TelemetryStreamCard.d.ts +59 -0
- package/dist/react/cards/TelemetryStreamCard.js +309 -0
- package/dist/react/cards/TelemetryStreamCard.js.map +1 -0
- package/dist/react/cards/index.d.ts +13 -0
- package/dist/react/charts/GroundTrackMap.d.ts +112 -0
- package/dist/react/charts/GroundTrackMap.js +1123 -0
- package/dist/react/charts/GroundTrackMap.js.map +1 -0
- package/dist/react/charts/GroundTrackMapLeaflet.d.ts +26 -0
- package/dist/react/charts/GroundTrackMapLeaflet.js +571 -0
- package/dist/react/charts/GroundTrackMapLeaflet.js.map +1 -0
- package/dist/react/charts/groundTrackMapLeafletTiles.d.ts +22 -0
- package/dist/react/charts/groundTrackMapLeafletTiles.js +11 -0
- package/dist/react/charts/groundTrackMapLeafletTiles.js.map +1 -0
- package/dist/react/charts/groundTrackMapLeafletUtils.d.ts +24 -0
- package/dist/react/charts/groundTrackMapLeafletUtils.js +109 -0
- package/dist/react/charts/groundTrackMapLeafletUtils.js.map +1 -0
- package/dist/react/charts/index.d.ts +10 -0
- package/dist/react/charts/unified/AstroChart.d.ts +24 -0
- package/dist/react/charts/unified/AstroChart.js +1405 -0
- package/dist/react/charts/unified/AstroChart.js.map +1 -0
- package/dist/react/charts/unified/PowerOverviewChart.d.ts +73 -0
- package/dist/react/charts/unified/PowerOverviewChart.js +488 -0
- package/dist/react/charts/unified/PowerOverviewChart.js.map +1 -0
- package/dist/react/charts/unified/domain.d.ts +845 -0
- package/dist/react/charts/unified/domain.js +3168 -0
- package/dist/react/charts/unified/domain.js.map +1 -0
- package/dist/react/charts/unified/generators.d.ts +276 -0
- package/dist/react/charts/unified/generators.js +518 -0
- package/dist/react/charts/unified/generators.js.map +1 -0
- package/dist/react/charts/unified/index.d.ts +55 -0
- package/dist/react/charts/unified/presets.d.ts +290 -0
- package/dist/react/charts/unified/presets.js +999 -0
- package/dist/react/charts/unified/presets.js.map +1 -0
- package/dist/react/charts/unified/sync.d.ts +69 -0
- package/dist/react/charts/unified/sync.js +219 -0
- package/dist/react/charts/unified/sync.js.map +1 -0
- package/dist/react/charts/unified/theme.d.ts +447 -0
- package/dist/react/charts/unified/theme.js +562 -0
- package/dist/react/charts/unified/theme.js.map +1 -0
- package/dist/react/charts/unified/types.d.ts +826 -0
- package/dist/react/charts/unified/useChartStream.d.ts +58 -0
- package/dist/react/charts/unified/useChartStream.js +226 -0
- package/dist/react/charts/unified/useChartStream.js.map +1 -0
- package/dist/react/chatgpt/AppCard.d.ts +59 -0
- package/dist/react/chatgpt/AppCard.js +306 -0
- package/dist/react/chatgpt/AppCard.js.map +1 -0
- package/dist/react/chatgpt/ChatGPTCard.d.ts +6 -0
- package/dist/react/chatgpt/index.d.ts +167 -0
- package/dist/react/chatgpt/index.js +166 -0
- package/dist/react/chatgpt/index.js.map +1 -0
- package/dist/react/context/DisplaySettingsContext.d.ts +107 -0
- package/dist/react/context/DisplaySettingsContext.js +169 -0
- package/dist/react/context/DisplaySettingsContext.js.map +1 -0
- package/dist/react/context/index.d.ts +5 -0
- package/dist/react/core/ActivityPlanner.d.ts +45 -0
- package/dist/react/core/ActivityPlanner.js +532 -0
- package/dist/react/core/ActivityPlanner.js.map +1 -0
- package/dist/react/core/AppBar.d.ts +71 -0
- package/dist/react/core/AppBar.js +817 -0
- package/dist/react/core/AppBar.js.map +1 -0
- package/dist/react/core/AstroIcon.d.ts +84 -0
- package/dist/react/core/AstroIcon.js +1243 -0
- package/dist/react/core/AstroIcon.js.map +1 -0
- package/dist/react/core/Badge.d.ts +27 -0
- package/dist/react/core/Badge.js +134 -0
- package/dist/react/core/Badge.js.map +1 -0
- package/dist/react/core/Button.d.ts +26 -0
- package/dist/react/core/Button.js +306 -0
- package/dist/react/core/Button.js.map +1 -0
- package/dist/react/core/CardHeader.d.ts +34 -0
- package/dist/react/core/CardHeader.js +316 -0
- package/dist/react/core/CardHeader.js.map +1 -0
- package/dist/react/core/ChatPanel.d.ts +627 -0
- package/dist/react/core/ChatPanel.js +1144 -0
- package/dist/react/core/ChatPanel.js.map +1 -0
- package/dist/react/core/Checkbox.d.ts +26 -0
- package/dist/react/core/Checkbox.js +130 -0
- package/dist/react/core/Checkbox.js.map +1 -0
- package/dist/react/core/ColorPickerPanel.d.ts +25 -0
- package/dist/react/core/ColorPickerPanel.js +293 -0
- package/dist/react/core/ColorPickerPanel.js.map +1 -0
- package/dist/react/core/CommandBuilder.d.ts +74 -0
- package/dist/react/core/CommandBuilder.js +518 -0
- package/dist/react/core/CommandBuilder.js.map +1 -0
- package/dist/react/core/ConfirmDialog.d.ts +45 -0
- package/dist/react/core/ConfirmDialog.js +315 -0
- package/dist/react/core/ConfirmDialog.js.map +1 -0
- package/dist/react/core/ConnectionForm.d.ts +57 -0
- package/dist/react/core/ConnectionForm.js +496 -0
- package/dist/react/core/ConnectionForm.js.map +1 -0
- package/dist/react/core/Container.d.ts +51 -0
- package/dist/react/core/Container.js +670 -0
- package/dist/react/core/Container.js.map +1 -0
- package/dist/react/core/CopyButton.d.ts +39 -0
- package/dist/react/core/CopyButton.js +105 -0
- package/dist/react/core/CopyButton.js.map +1 -0
- package/dist/react/core/DataTable.d.ts +113 -0
- package/dist/react/core/DataTable.js +446 -0
- package/dist/react/core/DataTable.js.map +1 -0
- package/dist/react/core/DataValue.d.ts +64 -0
- package/dist/react/core/DataValue.js +545 -0
- package/dist/react/core/DataValue.js.map +1 -0
- package/dist/react/core/Dialog.d.ts +32 -0
- package/dist/react/core/Dialog.js +201 -0
- package/dist/react/core/Dialog.js.map +1 -0
- package/dist/react/core/FileExplorer.d.ts +65 -0
- package/dist/react/core/FileExplorer.js +520 -0
- package/dist/react/core/FileExplorer.js.map +1 -0
- package/dist/react/core/GlassCard.d.ts +129 -0
- package/dist/react/core/GlassCard.js +375 -0
- package/dist/react/core/GlassCard.js.map +1 -0
- package/dist/react/core/HeaderIconWithStatus.d.ts +39 -0
- package/dist/react/core/HeaderIconWithStatus.js +157 -0
- package/dist/react/core/HeaderIconWithStatus.js.map +1 -0
- package/dist/react/core/HexViewer.d.ts +143 -0
- package/dist/react/core/HexViewer.js +1106 -0
- package/dist/react/core/HexViewer.js.map +1 -0
- package/dist/react/core/Icon.d.ts +32 -0
- package/dist/react/core/Icon.js +142 -0
- package/dist/react/core/Icon.js.map +1 -0
- package/dist/react/core/ImageGallery.d.ts +41 -0
- package/dist/react/core/ImageGallery.js +320 -0
- package/dist/react/core/ImageGallery.js.map +1 -0
- package/dist/react/core/Input.d.ts +38 -0
- package/dist/react/core/Input.js +288 -0
- package/dist/react/core/Input.js.map +1 -0
- package/dist/react/core/LimitsBar.d.ts +51 -0
- package/dist/react/core/LimitsBar.js +200 -0
- package/dist/react/core/LimitsBar.js.map +1 -0
- package/dist/react/core/LogViewer.d.ts +61 -0
- package/dist/react/core/LogViewer.js +599 -0
- package/dist/react/core/LogViewer.js.map +1 -0
- package/dist/react/core/MessageStream.d.ts +58 -0
- package/dist/react/core/MessageStream.js +455 -0
- package/dist/react/core/MessageStream.js.map +1 -0
- package/dist/react/core/MissionCalendar.d.ts +81 -0
- package/dist/react/core/MissionCalendar.js +1049 -0
- package/dist/react/core/MissionCalendar.js.map +1 -0
- package/dist/react/core/NumberInput.d.ts +85 -0
- package/dist/react/core/NumberInput.js +507 -0
- package/dist/react/core/NumberInput.js.map +1 -0
- package/dist/react/core/PacketViewer.d.ts +73 -0
- package/dist/react/core/PacketViewer.js +431 -0
- package/dist/react/core/PacketViewer.js.map +1 -0
- package/dist/react/core/Pagination.d.ts +30 -0
- package/dist/react/core/Pagination.js +190 -0
- package/dist/react/core/Pagination.js.map +1 -0
- package/dist/react/core/PinInput.d.ts +41 -0
- package/dist/react/core/PinInput.js +210 -0
- package/dist/react/core/PinInput.js.map +1 -0
- package/dist/react/core/Popover.d.ts +55 -0
- package/dist/react/core/Popover.js +288 -0
- package/dist/react/core/Popover.js.map +1 -0
- package/dist/react/core/Select.d.ts +42 -0
- package/dist/react/core/Select.js +303 -0
- package/dist/react/core/Select.js.map +1 -0
- package/dist/react/core/SideNav.d.ts +103 -0
- package/dist/react/core/SideNav.js +551 -0
- package/dist/react/core/SideNav.js.map +1 -0
- package/dist/react/core/SidePanel.d.ts +33 -0
- package/dist/react/core/SidePanel.js +199 -0
- package/dist/react/core/SidePanel.js.map +1 -0
- package/dist/react/core/Tabs.d.ts +47 -0
- package/dist/react/core/Tabs.js +129 -0
- package/dist/react/core/Tabs.js.map +1 -0
- package/dist/react/core/Toast.d.ts +56 -0
- package/dist/react/core/Toast.js +229 -0
- package/dist/react/core/Toast.js.map +1 -0
- package/dist/react/core/Toggle.d.ts +22 -0
- package/dist/react/core/Toggle.js +151 -0
- package/dist/react/core/Toggle.js.map +1 -0
- package/dist/react/core/Tooltip.d.ts +19 -0
- package/dist/react/core/Tooltip.js +179 -0
- package/dist/react/core/Tooltip.js.map +1 -0
- package/dist/react/core/Typography.d.ts +127 -0
- package/dist/react/core/Typography.js +187 -0
- package/dist/react/core/Typography.js.map +1 -0
- package/dist/react/core/index.d.ts +108 -0
- package/dist/react/core/layout/Box.d.ts +77 -0
- package/dist/react/core/layout/Box.js +126 -0
- package/dist/react/core/layout/Box.js.map +1 -0
- package/dist/react/core/layout/Center.d.ts +20 -0
- package/dist/react/core/layout/Center.js +34 -0
- package/dist/react/core/layout/Center.js.map +1 -0
- package/dist/react/core/layout/Divider.d.ts +16 -0
- package/dist/react/core/layout/Divider.js +108 -0
- package/dist/react/core/layout/Divider.js.map +1 -0
- package/dist/react/core/layout/Flex.d.ts +30 -0
- package/dist/react/core/layout/Flex.js +128 -0
- package/dist/react/core/layout/Flex.js.map +1 -0
- package/dist/react/core/layout/Grid.d.ts +36 -0
- package/dist/react/core/layout/Grid.js +142 -0
- package/dist/react/core/layout/Grid.js.map +1 -0
- package/dist/react/core/layout/Spacer.d.ts +8 -0
- package/dist/react/core/layout/Spacer.js +31 -0
- package/dist/react/core/layout/Spacer.js.map +1 -0
- package/dist/react/core/layout/Stack.d.ts +54 -0
- package/dist/react/core/layout/Stack.js +74 -0
- package/dist/react/core/layout/Stack.js.map +1 -0
- package/dist/react/core/layout/index.d.ts +38 -0
- package/dist/react/core/layout/responsive.d.ts +23 -0
- package/dist/react/core/layout/responsive.js +26 -0
- package/dist/react/core/layout/responsive.js.map +1 -0
- package/dist/react/core/layout/useBreakpoint.d.ts +77 -0
- package/dist/react/core/layout/useBreakpoint.js +73 -0
- package/dist/react/core/layout/useBreakpoint.js.map +1 -0
- package/dist/react/core/propertyConfig.d.ts +443 -0
- package/dist/react/core/propertyConfig.js +399 -0
- package/dist/react/core/propertyConfig.js.map +1 -0
- package/dist/react/hooks/index.d.ts +21 -0
- package/dist/react/hooks/useAccessWindows.d.ts +66 -0
- package/dist/react/hooks/useCompactMode.d.ts +82 -0
- package/dist/react/hooks/useCompactMode.js +62 -0
- package/dist/react/hooks/useCompactMode.js.map +1 -0
- package/dist/react/hooks/useLiveSelection.d.ts +57 -0
- package/dist/react/hooks/useSimulationPlayback.d.ts +97 -0
- package/dist/react/hooks/useSimulationTime.d.ts +61 -0
- package/dist/react/hooks/useSpacecraftPosition.d.ts +50 -0
- package/dist/react/hooks/useSpacecraftPosition.js +89 -0
- package/dist/react/hooks/useSpacecraftPosition.js.map +1 -0
- package/dist/react/hooks/useTelemetry.d.ts +55 -0
- package/dist/react/hooks/useTelemetry.js +73 -0
- package/dist/react/hooks/useTelemetry.js.map +1 -0
- package/dist/react/hooks/useZendirSession.d.ts +109 -0
- package/dist/react/hooks/useZendirSession.js +148 -0
- package/dist/react/hooks/useZendirSession.js.map +1 -0
- package/dist/react/index.d.ts +74 -0
- package/dist/react/shared/ErrorBoundary.d.ts +63 -0
- package/dist/react/shared/ErrorBoundary.js +142 -0
- package/dist/react/shared/ErrorBoundary.js.map +1 -0
- package/dist/react/shared/Skeleton.d.ts +110 -0
- package/dist/react/shared/Skeleton.js +324 -0
- package/dist/react/shared/Skeleton.js.map +1 -0
- package/dist/react/shared/index.d.ts +12 -0
- package/dist/react/theme/ThemeProvider.d.ts +385 -0
- package/dist/react/theme/ThemeProvider.js +1096 -0
- package/dist/react/theme/ThemeProvider.js.map +1 -0
- package/dist/react/theme/astro-tokens.d.ts +153 -0
- package/dist/react/theme/cardAccent.d.ts +75 -0
- package/dist/react/theme/cardAccent.js +137 -0
- package/dist/react/theme/cardAccent.js.map +1 -0
- package/dist/react/theme/config.d.ts +39 -0
- package/dist/react/theme/index.d.ts +9 -0
- package/dist/react/types.d.ts +360 -0
- package/dist/react/types.js +58 -0
- package/dist/react/types.js.map +1 -0
- package/dist/react/utils/index.d.ts +247 -0
- package/dist/react/utils/index.js +423 -0
- package/dist/react/utils/index.js.map +1 -0
- package/dist/react/visualizations/EclipseTimerCard.d.ts +17 -0
- package/dist/react/visualizations/EclipseTimerCard.js +250 -0
- package/dist/react/visualizations/EclipseTimerCard.js.map +1 -0
- package/dist/react/visualizations/LinkBudgetCard.d.ts +50 -0
- package/dist/react/visualizations/LinkBudgetCard.js +444 -0
- package/dist/react/visualizations/LinkBudgetCard.js.map +1 -0
- package/dist/react/visualizations/NavBallCard.d.ts +17 -0
- package/dist/react/visualizations/NavBallCard.js +243 -0
- package/dist/react/visualizations/NavBallCard.js.map +1 -0
- package/dist/react/visualizations/PropulsionCard.d.ts +37 -0
- package/dist/react/visualizations/PropulsionCard.js +298 -0
- package/dist/react/visualizations/PropulsionCard.js.map +1 -0
- package/dist/react/visualizations/SensorFootprintCard.d.ts +33 -0
- package/dist/react/visualizations/SensorFootprintCard.js +326 -0
- package/dist/react/visualizations/SensorFootprintCard.js.map +1 -0
- package/dist/react/visualizations/ThermalHeatmapCard.d.ts +38 -0
- package/dist/react/visualizations/ThermalHeatmapCard.js +372 -0
- package/dist/react/visualizations/ThermalHeatmapCard.js.map +1 -0
- package/dist/react/visualizations/index.d.ts +17 -0
- package/dist/react.d.ts +1 -0
- package/dist/react.js +421 -0
- package/dist/react.js.map +1 -0
- package/dist/shaders/atmosphere.frag.js +5 -0
- package/dist/shaders/atmosphere.frag.js.map +1 -0
- package/dist/shaders/atmosphere.vert.js +5 -0
- package/dist/shaders/atmosphere.vert.js.map +1 -0
- package/dist/shaders/stars.frag.js +5 -0
- package/dist/shaders/stars.frag.js.map +1 -0
- package/dist/shaders/stars.vert.js +5 -0
- package/dist/shaders/stars.vert.js.map +1 -0
- package/dist/style.css +143 -0
- package/dist/tokens/index.d.ts +296 -0
- package/dist/tokens/index.js +263 -0
- package/dist/tokens/index.js.map +1 -0
- package/dist/tokens/tokens.css +155 -0
- package/dist/types/index.d.ts +23 -0
- package/dist/types.d.ts +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/package.json +220 -0
- package/sdk-stub.js +22 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ZenSpace3D.js","sources":["../../../src/react/3d/ZenSpace3D.tsx"],"sourcesContent":["/**\n * @zendir/ui - ZenSpace3D Component (Optimized)\n * \n * Professional 3D space visualization with smooth interactions.\n * Optimized for performance with settings from EarthViewer.\n */\n\nimport React, {\n useRef,\n useEffect,\n useState,\n useCallback,\n useImperativeHandle,\n forwardRef,\n useMemo,\n} from 'react';\nimport { useTheme } from '../theme';\nimport { AstroIcon, type AstroIconName } from '../core/AstroIcon';\nimport type { GroundStation as _GroundStation } from '../types';\nimport type {\n ZenSpace3DProps,\n ZenSpace3DHandle,\n ViewMode,\n SpaceObject,\n Vector3D,\n CameraState,\n LayerVisibility,\n SelectionState,\n OverpassInfo,\n} from './ZenSpace3DTypes';\nimport {\n latLonAltToCartesian,\n SCENE_EARTH_RADIUS,\n KM_TO_SCENE,\n easeOutCubic,\n formatDuration,\n} from './ZenSpace3DUtils';\n\n// Import shaders as raw text (like EarthViewer)\nimport atmosphereVertexShader from '../../shaders/atmosphere.vert?raw';\nimport atmosphereFragmentShader from '../../shaders/atmosphere.frag?raw';\nimport starsVertexShader from '../../shaders/stars.vert?raw';\nimport starsFragmentShader from '../../shaders/stars.frag?raw';\nimport { loadThree, ThreeModule } from './threeLoader';\nimport { ZenSpace3DCesium } from './ZenSpace3DCesium';\n\n// =============================================================================\n// Communication Link Types\n// =============================================================================\n\nexport interface CommunicationLink {\n id: string;\n fromId: string;\n toId: string;\n type: 'uplink' | 'downlink' | 'crosslink' | 'relay';\n status: 'active' | 'idle' | 'blocked';\n color?: string;\n bandwidth?: number;\n latency?: number;\n signalStrength?: number;\n}\n\n// =============================================================================\n// Configuration - Optimized for smooth interactions\n// =============================================================================\n\nconst DEFAULT_LAYERS: LayerVisibility = {\n planets: true,\n moons: true,\n satellites: true,\n debris: false,\n stations: true,\n asteroids: false,\n groundStations: true,\n orbits: true,\n labels: true,\n constellations: false,\n coverage: true,\n atmosphere: true,\n stars: true,\n grid: false,\n terminator: true,\n};\n\nconst CAMERA_TRANSITION_DURATION = 2000;\nconst STARS_COUNT = 5000; // Reduced from 8000\nconst EARTH_SEGMENTS = 64; // Reduced from 128\nconst EARTH_SEGMENTS_V = 32; // Reduced from 64\nconst SPHERICAL_SUBDIVISIONS = 16; // Subdivisions for curved edges on coverage\n\nfunction checkWebGLCapabilities(): { available: boolean; version: number } {\n try {\n const canvas = document.createElement('canvas');\n const gl2 = canvas.getContext('webgl2');\n if (gl2) return { available: true, version: 2 };\n const gl = canvas.getContext('webgl');\n if (gl) return { available: true, version: 1 };\n } catch { /* WebGL not available */ }\n return { available: false, version: 0 };\n}\n\n// =============================================================================\n// Spherical Geometry Helpers - For realistic curved coverage on sphere\n// =============================================================================\n\n/**\n * Spherical linear interpolation (SLERP) between two unit vectors\n * Creates smooth arc along the sphere surface\n */\nfunction slerp(v1: { x: number; y: number; z: number }, v2: { x: number; y: number; z: number }, t: number): { x: number; y: number; z: number } {\n // Normalize inputs\n const len1 = Math.sqrt(v1.x * v1.x + v1.y * v1.y + v1.z * v1.z);\n const len2 = Math.sqrt(v2.x * v2.x + v2.y * v2.y + v2.z * v2.z);\n \n // Handle zero-length vectors\n if (len1 < 0.0001 || len2 < 0.0001) {\n return { x: v1.x, y: v1.y, z: v1.z };\n }\n \n const n1 = { x: v1.x / len1, y: v1.y / len1, z: v1.z / len1 };\n const n2 = { x: v2.x / len2, y: v2.y / len2, z: v2.z / len2 };\n \n // Calculate angle between vectors\n let dot = n1.x * n2.x + n1.y * n2.y + n1.z * n2.z;\n dot = Math.max(-1, Math.min(1, dot)); // Clamp for numerical stability\n const theta = Math.acos(dot);\n \n if (theta < 0.001) {\n // Vectors are nearly parallel, use linear interpolation\n return {\n x: n1.x + t * (n2.x - n1.x),\n y: n1.y + t * (n2.y - n1.y),\n z: n1.z + t * (n2.z - n1.z)\n };\n }\n \n const sinTheta = Math.sin(theta);\n if (Math.abs(sinTheta) < 0.0001) {\n // Near zero sin, use linear interpolation\n return {\n x: n1.x + t * (n2.x - n1.x),\n y: n1.y + t * (n2.y - n1.y),\n z: n1.z + t * (n2.z - n1.z)\n };\n }\n \n const a = Math.sin((1 - t) * theta) / sinTheta;\n const b = Math.sin(t * theta) / sinTheta;\n \n return {\n x: a * n1.x + b * n2.x,\n y: a * n1.y + b * n2.y,\n z: a * n1.z + b * n2.z\n };\n}\n\n/**\n * Subdivide polygon edges along great circles for spherical rendering\n * Takes corner points and returns a densely sampled spherical polygon\n */\nfunction subdivideSphericalPolygon(\n corners: Array<{ x: number; y: number; z: number }>,\n subdivisions: number,\n radius: number\n): Array<{ x: number; y: number; z: number }> {\n if (corners.length < 3 || subdivisions < 1 || radius <= 0) {\n return corners; // Return as-is if invalid params\n }\n \n const result: Array<{ x: number; y: number; z: number }> = [];\n \n for (let i = 0; i < corners.length; i++) {\n const p1 = corners[i];\n const p2 = corners[(i + 1) % corners.length];\n \n // Validate points\n if (!isFinite(p1.x) || !isFinite(p1.y) || !isFinite(p1.z) ||\n !isFinite(p2.x) || !isFinite(p2.y) || !isFinite(p2.z)) {\n continue; // Skip invalid points\n }\n \n // Add interpolated points along the great circle arc\n for (let j = 0; j < subdivisions; j++) {\n const t = j / subdivisions;\n const interpolated = slerp(p1, p2, t);\n \n // Validate interpolation result\n if (!isFinite(interpolated.x) || !isFinite(interpolated.y) || !isFinite(interpolated.z)) {\n continue;\n }\n \n // Project onto sphere surface at given radius\n const len = Math.sqrt(interpolated.x ** 2 + interpolated.y ** 2 + interpolated.z ** 2);\n if (len < 0.0001) continue; // Skip zero-length vectors\n \n result.push({\n x: (interpolated.x / len) * radius,\n y: (interpolated.y / len) * radius,\n z: (interpolated.z / len) * radius\n });\n }\n }\n \n return result.length > 0 ? result : corners; // Fallback to original if all failed\n}\n\n// =============================================================================\n// Satellite Shape Builders (simplified for performance)\n// =============================================================================\n\nfunction createSatelliteShape(THREE: ThreeModule, category: string, size: number): any {\n const group = new THREE.Group();\n \n if (category === 'station') {\n // Simple station shape\n const geo = new THREE.BoxGeometry(size * 1.2, size * 0.6, size * 0.6);\n const mat = new THREE.MeshBasicMaterial({ color: 0xcccccc });\n group.add(new THREE.Mesh(geo, mat));\n \n // Solar panels\n const panelGeo = new THREE.BoxGeometry(size * 2.5, size * 0.03, size * 0.6);\n const panelMat = new THREE.MeshBasicMaterial({ color: 0x1a4a7a });\n const leftPanel = new THREE.Mesh(panelGeo, panelMat);\n leftPanel.position.x = -size * 1.5;\n group.add(leftPanel);\n const rightPanel = new THREE.Mesh(panelGeo, panelMat);\n rightPanel.position.x = size * 1.5;\n group.add(rightPanel);\n \n } else if (category === 'satellite') {\n // Simple satellite\n const geo = new THREE.BoxGeometry(size * 0.5, size * 0.5, size * 0.6);\n const mat = new THREE.MeshBasicMaterial({ color: 0xaaaaaa });\n group.add(new THREE.Mesh(geo, mat));\n \n const panelGeo = new THREE.BoxGeometry(size * 1.2, size * 0.02, size * 0.4);\n const panelMat = new THREE.MeshBasicMaterial({ color: 0x1a3a6a });\n const leftPanel = new THREE.Mesh(panelGeo, panelMat);\n leftPanel.position.x = -size * 0.7;\n group.add(leftPanel);\n const rightPanel = new THREE.Mesh(panelGeo, panelMat);\n rightPanel.position.x = size * 0.7;\n group.add(rightPanel);\n \n } else if (category === 'debris') {\n const geo = new THREE.IcosahedronGeometry(size * 0.3, 0);\n const mat = new THREE.MeshBasicMaterial({ color: 0x666666 });\n group.add(new THREE.Mesh(geo, mat));\n } else {\n const geo = new THREE.SphereGeometry(size * 0.4, 8, 6);\n const mat = new THREE.MeshBasicMaterial({ color: 0x888888 });\n group.add(new THREE.Mesh(geo, mat));\n }\n \n return group;\n}\n\n// =============================================================================\n// Component\n// =============================================================================\n\nexport const ZenSpace3D = forwardRef<ZenSpace3DHandle, ZenSpace3DProps>(\n function ZenSpace3D(props, ref) {\n // Prefer Cesium when available (default 3D backend); fall back to Three.js\n const [cesiumModule, setCesiumModule] = useState<unknown>(null);\n useEffect(() => {\n // Cesium is optional peer; fallback to Three.js when not installed\n import('cesium').then((m) => setCesiumModule(m)).catch(() => setCesiumModule(null));\n }, []);\n if (cesiumModule) {\n return <ZenSpace3DCesium ref={ref} cesium={cesiumModule} {...props} />;\n }\n return <ZenSpace3DThree ref={ref} {...props} />;\n }\n);\n\n// Three.js implementation — separate component so hook count is consistent (avoids React #300)\nconst ZenSpace3DThree = forwardRef<ZenSpace3DHandle, ZenSpace3DProps>(function ZenSpace3DThree(props, ref) {\n const {\n satellites = [],\n debris = [],\n stations = [],\n groundStations = [],\n customObjects = [],\n view = 'earth-orbit',\n focusedObjectId,\n initialCamera,\n sunDirection,\n planetPositions,\n visibilityCones = [],\n satelliteCoverages = [],\n overpasses: _overpasses = [],\n orbitPaths = [],\n orbitDesignArcs: _orbitDesignArcs = [],\n communicationLinks = [],\n showAxisHelper = false,\n layers: layerOverrides,\n showTools = true,\n showInfoPanel = true,\n width = '100%',\n height = 600,\n callbacks,\n maxObjects = 10000,\n className = '',\n style,\n } = props;\n\n const { tokens: _tokens } = useTheme();\n const [webglCapabilities] = useState(() => checkWebGLCapabilities());\n\n // Refs\n const containerRef = useRef<HTMLDivElement>(null);\n const rendererRef = useRef<any>(null);\n const sceneRef = useRef<any>(null);\n const cameraRef = useRef<any>(null);\n const controlsRef = useRef<any>(null);\n const animationRef = useRef<number | null>(null);\n const raycasterRef = useRef<any>(null);\n const mouseRef = useRef<any>(null);\n \n const earthRef = useRef<any>(null);\n const starsMaterialRef = useRef<any>(null);\n const atmosphereMaterialRef = useRef<any>(null);\n const objectsGroupRef = useRef<any>(null);\n const linksGroupRef = useRef<any>(null);\n const conesGroupRef = useRef<any>(null);\n const orbitsGroupRef = useRef<any>(null);\n const planetsGroupRef = useRef<any>(null);\n \n const timeRef = useRef(0);\n const focusTransitionRef = useRef<any>(null);\n const isUserInteractingRef = useRef(false);\n const objectMeshMapRef = useRef<Map<string, any>>(new Map());\n const isAnimatingRef = useRef(false); // Guard against multiple animation loops\n const _sceneInitializedRef = useRef(false); // Prevent duplicate initialization\n\n // State\n const [THREE, setTHREE] = useState<ThreeModule | null>(null);\n const threeRef = useRef<ThreeModule | null>(null);\n threeRef.current = THREE;\n const [OrbitControlsClass, setOrbitControlsClass] = useState<any>(null);\n const [isLoading, setIsLoading] = useState(true);\n const [error, setError] = useState<string | null>(null);\n \n const [layers, setLayers] = useState<LayerVisibility>({ ...DEFAULT_LAYERS, ...layerOverrides });\n const [selection, setSelection] = useState<SelectionState>({ selectedId: null, selectedObject: null, hoveredId: null });\n const [hoverTooltip, setHoverTooltip] = useState<{ visible: boolean; x: number; y: number; object: any }>({ visible: false, x: 0, y: 0, object: null });\n const [currentView, setCurrentView] = useState<ViewMode>(view);\n \n // Ref for view to prevent initScene recreation (fixes flickering on view change)\n const currentViewRef = useRef<ViewMode>(view);\n\n const effectiveLayers = useMemo(() => ({ ...layers, ...layerOverrides }), [layers, layerOverrides]);\n\n useEffect(() => { \n setCurrentView(view); \n currentViewRef.current = view;\n }, [view]);\n\n // ==========================================================================\n // Load Three.js\n // ==========================================================================\n \n useEffect(() => {\n if (!webglCapabilities.available) { setIsLoading(false); return; }\n\n loadThree()\n .then(({ THREE: threeModule, OrbitControls: controls }) => {\n setTHREE(threeModule);\n setOrbitControlsClass(() => controls);\n })\n .catch((err) => {\n if (import.meta.env.DEV) {\n console.error('Failed to load Three.js:', err);\n }\n setError('Failed to load 3D library');\n setIsLoading(false);\n });\n }, [webglCapabilities.available]);\n\n // ==========================================================================\n // Initialize Scene (Optimized like EarthViewer)\n // ==========================================================================\n \n const initScene = useCallback(() => {\n if (!THREE || !containerRef.current || !OrbitControlsClass) return;\n \n // Clean up any existing scene first (prevents duplicates)\n if (rendererRef.current) {\n isAnimatingRef.current = false;\n if (animationRef.current) {\n cancelAnimationFrame(animationRef.current);\n animationRef.current = null;\n }\n controlsRef.current?.dispose();\n rendererRef.current.dispose();\n if (containerRef.current?.contains(rendererRef.current.domElement)) {\n containerRef.current.removeChild(rendererRef.current.domElement);\n }\n }\n\n const container = containerRef.current;\n const rect = container.getBoundingClientRect();\n const w = rect.width;\n const h = typeof height === 'number' ? height : rect.height;\n\n // Scene\n const scene = new THREE.Scene();\n sceneRef.current = scene;\n\n // Use ref for view mode to prevent initScene recreation (fixes flickering)\n const viewMode = currentViewRef.current;\n \n // Camera (adjusted per view mode)\n const farClip = viewMode === 'solar-system' ? 1000000 : 100000;\n const camera = new THREE.PerspectiveCamera(45, w / h, 1, farClip);\n // Solar system: position to see inner planets, Earth orbit view: standard distance\n const initialDistance = viewMode === 'solar-system' ? 5000 : 10000;\n camera.position.set(0, initialDistance * 0.3, initialDistance);\n cameraRef.current = camera;\n\n if (initialCamera?.position) {\n camera.position.set(initialCamera.position.x, initialCamera.position.y, initialCamera.position.z);\n }\n\n // Renderer (optimized settings - preserveDrawingBuffer prevents flickering)\n const renderer = new THREE.WebGLRenderer({ \n antialias: true, \n alpha: true,\n powerPreference: 'high-performance',\n preserveDrawingBuffer: true, // Prevents flickering from buffer swaps\n });\n renderer.setSize(w, h);\n renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));\n container.appendChild(renderer.domElement);\n rendererRef.current = renderer;\n\n // Controls (smooth damping, adjusted per view)\n const controls = new OrbitControlsClass(camera, renderer.domElement);\n controls.enableDamping = true;\n controls.dampingFactor = 0.05;\n controls.rotateSpeed = 0.5;\n controls.minDistance = viewMode === 'solar-system' ? 500 : 3050; // Very close to Earth/objects\n controls.maxDistance = viewMode === 'solar-system' ? 100000 : 25000;\n controls.enablePan = viewMode === 'solar-system'; // Allow pan in solar system\n let interactionTimer: ReturnType<typeof setTimeout>;\n const handleControlStart = () => { isUserInteractingRef.current = true; };\n const handleControlEnd = () => {\n clearTimeout(interactionTimer);\n interactionTimer = setTimeout(() => { isUserInteractingRef.current = false; }, 3000);\n };\n controls.addEventListener('start', handleControlStart);\n controls.addEventListener('end', handleControlEnd);\n controlsRef.current = controls;\n\n raycasterRef.current = new THREE.Raycaster();\n mouseRef.current = new THREE.Vector2();\n\n // Groups\n objectsGroupRef.current = new THREE.Group();\n objectsGroupRef.current.name = 'objects';\n scene.add(objectsGroupRef.current);\n\n linksGroupRef.current = new THREE.Group();\n linksGroupRef.current.name = 'links';\n scene.add(linksGroupRef.current);\n\n conesGroupRef.current = new THREE.Group();\n conesGroupRef.current.name = 'cones';\n scene.add(conesGroupRef.current);\n\n orbitsGroupRef.current = new THREE.Group();\n orbitsGroupRef.current.name = 'orbits';\n scene.add(orbitsGroupRef.current);\n\n planetsGroupRef.current = new THREE.Group();\n planetsGroupRef.current.name = 'planets';\n scene.add(planetsGroupRef.current);\n\n if (viewMode === 'solar-system') {\n createSolarSystem(THREE, scene);\n } else {\n createEarth(THREE, scene);\n createAtmosphere(THREE, scene);\n }\n \n createStars(THREE, scene);\n createLighting(THREE, scene);\n \n if (showAxisHelper && viewMode !== 'solar-system') {\n createAxisHelper(THREE, scene);\n }\n\n setIsLoading(false);\n\n return () => {\n clearTimeout(interactionTimer);\n if (animationRef.current) cancelAnimationFrame(animationRef.current);\n controls.removeEventListener('start', handleControlStart);\n controls.removeEventListener('end', handleControlEnd);\n controls.dispose();\n renderer.dispose();\n if (container.contains(renderer.domElement)) container.removeChild(renderer.domElement);\n };\n }, [THREE, OrbitControlsClass, height, initialCamera, showAxisHelper]); // Uses currentViewRef to prevent recreation\n\n // ==========================================================================\n // Create Solar System (scaled for visibility)\n // ==========================================================================\n \n const createSolarSystem = useCallback((THREE: ThreeModule, _scene: unknown) => {\n const planetsGroup = planetsGroupRef.current;\n if (!planetsGroup) return;\n\n // Scale factor to make solar system viewable (1 unit = ~1000 km)\n const DISTANCE_SCALE = 0.000005;\n const SIZE_SCALE = 0.01;\n\n // Sun (emissive glow)\n const sunRadius = 696340 * SIZE_SCALE;\n const sunGeo = new THREE.SphereGeometry(sunRadius, 32, 24);\n const sunMat = new THREE.MeshBasicMaterial({ color: 0xffdd44 });\n const sunMesh = new THREE.Mesh(sunGeo, sunMat);\n sunMesh.name = 'sun';\n sunMesh.userData = { objectId: 'sun', planetId: 'sun', isPlanet: true, isSelectable: true };\n planetsGroup.add(sunMesh);\n\n // Sun glow\n const glowGeo = new THREE.SphereGeometry(sunRadius * 1.3, 24, 16);\n const glowMat = new THREE.MeshBasicMaterial({ color: 0xffaa00, transparent: true, opacity: 0.2 });\n planetsGroup.add(new THREE.Mesh(glowGeo, glowMat));\n\n // Planets with proper scaling\n const configs = [\n { id: 'mercury', color: 0x8c7853, radius: 2439.7, distance: 57900000 },\n { id: 'venus', color: 0xffc649, radius: 6051.8, distance: 108200000 },\n { id: 'earth', color: 0x6b93d6, radius: 6371, distance: 149600000 },\n { id: 'mars', color: 0xc1440e, radius: 3389.5, distance: 227900000 },\n { id: 'jupiter', color: 0xd8ca9d, radius: 69911, distance: 778500000 },\n { id: 'saturn', color: 0xf4d59e, radius: 58232, distance: 1434000000 },\n { id: 'uranus', color: 0xd1e7e7, radius: 25362, distance: 2871000000 },\n { id: 'neptune', color: 0x5b5ddf, radius: 24622, distance: 4495000000 },\n ];\n\n configs.forEach(c => {\n // Make inner planets larger for visibility\n const visualScale = c.distance < 300000000 ? 15 : 5;\n const planetRadius = c.radius * SIZE_SCALE * visualScale;\n const geo = new THREE.SphereGeometry(planetRadius, 24, 16);\n const mat = new THREE.MeshPhongMaterial({ color: c.color, shininess: 30 });\n const mesh = new THREE.Mesh(geo, mat);\n \n const orbitDist = c.distance * DISTANCE_SCALE;\n mesh.position.x = orbitDist;\n mesh.name = c.id;\n mesh.userData = { objectId: c.id, planetId: c.id, isPlanet: true, isSelectable: true, data: { id: c.id, name: c.id.charAt(0).toUpperCase() + c.id.slice(1), category: 'planet' } };\n planetsGroup.add(mesh);\n objectMeshMapRef.current.set(c.id, mesh);\n\n // Saturn's rings\n if (c.id === 'saturn') {\n const ringGeo = new THREE.RingGeometry(planetRadius * 1.4, planetRadius * 2.2, 32);\n const ringMat = new THREE.MeshBasicMaterial({ color: 0xc9b896, transparent: true, opacity: 0.6, side: THREE.DoubleSide });\n const ring = new THREE.Mesh(ringGeo, ringMat);\n ring.rotation.x = Math.PI / 2.5;\n ring.position.copy(mesh.position);\n planetsGroup.add(ring);\n }\n\n // Orbit line\n const points: any[] = [];\n for (let i = 0; i <= 64; i++) {\n const angle = (i / 64) * Math.PI * 2;\n points.push(new THREE.Vector3(orbitDist * Math.cos(angle), 0, orbitDist * Math.sin(angle)));\n }\n const orbitGeo = new THREE.BufferGeometry().setFromPoints(points);\n const orbitMat = new THREE.LineBasicMaterial({ color: 0x444466, transparent: true, opacity: 0.3 });\n planetsGroup.add(new THREE.Line(orbitGeo, orbitMat));\n });\n\n // Add a point light at Sun\n const sunLight = new THREE.PointLight(0xffffee, 2, 100000);\n sunLight.position.set(0, 0, 0);\n planetsGroup.add(sunLight);\n }, []);\n\n // ==========================================================================\n // Create Earth (optimized segments like EarthViewer)\n // ==========================================================================\n \n const createEarth = useCallback((THREE: ThreeModule, scene: any) => {\n const earthGeometry = new THREE.SphereGeometry(SCENE_EARTH_RADIUS, EARTH_SEGMENTS, EARTH_SEGMENTS_V);\n const earthMaterial = new THREE.MeshPhongMaterial({ color: 0x2244aa, shininess: 10 });\n\n const textureLoader = new THREE.TextureLoader();\n textureLoader.load('/world.topo.jpg', (texture: any) => {\n texture.wrapS = THREE.RepeatWrapping;\n texture.wrapT = THREE.ClampToEdgeWrapping;\n texture.minFilter = THREE.LinearFilter;\n texture.magFilter = THREE.LinearFilter;\n earthMaterial.map = texture;\n earthMaterial.needsUpdate = true;\n }, undefined, () => {});\n\n const earth = new THREE.Mesh(earthGeometry, earthMaterial);\n earth.rotation.y = -Math.PI / 2 + Math.PI;\n earth.name = 'earth';\n scene.add(earth);\n earthRef.current = earth;\n }, []);\n\n // ==========================================================================\n // Create Atmosphere (sun-reactive glow)\n // ==========================================================================\n \n const createAtmosphere = useCallback((THREE: ThreeModule, scene: any) => {\n if (!effectiveLayers.atmosphere) return;\n \n // Default sun direction (can be updated via props)\n const defaultSunDir = new THREE.Vector3(1, 0.3, 0.5).normalize();\n \n const atmosphereGeometry = new THREE.SphereGeometry(SCENE_EARTH_RADIUS * 1.15, 32, 16);\n const atmosphereMaterial = new THREE.ShaderMaterial({\n uniforms: {\n uSunDirection: { value: defaultSunDir },\n },\n vertexShader: atmosphereVertexShader,\n fragmentShader: atmosphereFragmentShader,\n blending: THREE.AdditiveBlending,\n side: THREE.BackSide,\n transparent: true,\n depthWrite: false,\n });\n const atmosphere = new THREE.Mesh(atmosphereGeometry, atmosphereMaterial);\n atmosphere.rotation.y = -Math.PI / 2;\n atmosphere.name = 'atmosphere';\n scene.add(atmosphere);\n \n // Store ref for dynamic updates\n atmosphereMaterialRef.current = atmosphereMaterial;\n }, [effectiveLayers.atmosphere]);\n\n // ==========================================================================\n // Create Stars (optimized like EarthViewer)\n // ==========================================================================\n \n const createStars = useCallback((THREE: ThreeModule, scene: any) => {\n const starsGeometry = new THREE.BufferGeometry();\n const starsDist = currentView === 'solar-system' ? 50000000000 : 50000;\n const positions = new Float32Array(STARS_COUNT * 3);\n const opacities = new Float32Array(STARS_COUNT);\n\n for (let i = 0; i < STARS_COUNT; i++) {\n const radius = starsDist + Math.random() * starsDist;\n const theta = Math.random() * Math.PI * 2;\n const phi = Math.acos(2 * Math.random() - 1);\n\n positions[i * 3] = radius * Math.sin(phi) * Math.cos(theta);\n positions[i * 3 + 1] = radius * Math.sin(phi) * Math.sin(theta);\n positions[i * 3 + 2] = radius * Math.cos(phi);\n opacities[i] = Math.random();\n }\n\n starsGeometry.setAttribute('position', new THREE.BufferAttribute(positions, 3));\n starsGeometry.setAttribute('opacity', new THREE.BufferAttribute(opacities, 1));\n\n const starsMaterial = new THREE.ShaderMaterial({\n uniforms: { time: { value: 0 } },\n vertexShader: starsVertexShader,\n fragmentShader: starsFragmentShader,\n transparent: true,\n depthWrite: false,\n blending: THREE.AdditiveBlending,\n });\n\n scene.add(new THREE.Points(starsGeometry, starsMaterial));\n starsMaterialRef.current = starsMaterial;\n }, [currentView]);\n\n // ==========================================================================\n // Create Lighting (simple like EarthViewer)\n // ==========================================================================\n \n const createLighting = useCallback((THREE: ThreeModule, scene: any) => {\n scene.add(new THREE.AmbientLight(0x404040, 0.6));\n const sunLight = new THREE.DirectionalLight(0xffffff, 1.2);\n sunLight.position.set(10000, 5000, 10000);\n scene.add(sunLight);\n }, []);\n\n // ==========================================================================\n // Create Axis Helper\n // ==========================================================================\n \n const createAxisHelper = useCallback((THREE: ThreeModule, scene: any) => {\n const len = SCENE_EARTH_RADIUS * 1.5;\n const group = new THREE.Group();\n \n [\n { color: 0xff3333, dir: [1, 0, 0] },\n { color: 0x33ff33, dir: [0, 1, 0] },\n { color: 0x3333ff, dir: [0, 0, 1] },\n ].forEach(({ color, dir }) => {\n const points = [new THREE.Vector3(0, 0, 0), new THREE.Vector3(dir[0] * len, dir[1] * len, dir[2] * len)];\n const geo = new THREE.BufferGeometry().setFromPoints(points);\n const mat = new THREE.LineBasicMaterial({ color });\n group.add(new THREE.Line(geo, mat));\n });\n \n scene.add(group);\n }, []);\n\n // ==========================================================================\n // Update Objects\n // ==========================================================================\n \n const updateObjects = useCallback(() => {\n if (!THREE || !objectsGroupRef.current || currentView === 'solar-system') return;\n\n const group = objectsGroupRef.current;\n const meshMap = objectMeshMapRef.current;\n\n // Clear\n while (group.children.length > 0) {\n const child = group.children[0];\n group.remove(child);\n }\n meshMap.clear();\n\n const allObjects: SpaceObject[] = [...satellites, ...debris, ...stations, ...customObjects];\n\n allObjects.slice(0, maxObjects).forEach((obj) => {\n const categoryLayer = obj.category === 'satellite' ? 'satellites' :\n obj.category === 'debris' ? 'debris' :\n obj.category === 'station' ? 'stations' : 'satellites';\n \n if (!effectiveLayers[categoryLayer]) return;\n\n let size = 50;\n if (obj.category === 'station') size = 100;\n else if (obj.category === 'debris') size = 25;\n\n const satelliteGroup = createSatelliteShape(THREE, obj.category, size);\n satelliteGroup.position.set(obj.position.x, obj.position.y, obj.position.z);\n satelliteGroup.lookAt(0, 0, 0);\n satelliteGroup.userData = { objectId: obj.id, category: obj.category, data: obj, isSelectable: true };\n satelliteGroup.name = obj.id;\n \n group.add(satelliteGroup);\n meshMap.set(obj.id, satelliteGroup);\n });\n }, [THREE, satellites, debris, stations, customObjects, maxObjects, effectiveLayers, currentView]);\n\n // ==========================================================================\n // Update Ground Stations\n // ==========================================================================\n \n const updateGroundStations = useCallback(() => {\n if (!THREE || !objectsGroupRef.current || currentView === 'solar-system') return;\n if (!effectiveLayers.groundStations) return;\n\n groundStations.forEach((gs) => {\n const pos = latLonAltToCartesian(gs.latitude, gs.longitude, 0);\n \n // Simple marker\n const geo = new THREE.SphereGeometry(35, 8, 6);\n const mat = new THREE.MeshBasicMaterial({ color: 0x00ffff });\n const marker = new THREE.Mesh(geo, mat);\n marker.position.set(pos.x, pos.y, pos.z);\n marker.userData = { objectId: gs.id, category: 'groundStation', data: gs, isSelectable: true };\n \n objectsGroupRef.current.add(marker);\n objectMeshMapRef.current.set(gs.id, marker);\n\n // Glow ring\n const ringGeo = new THREE.RingGeometry(45, 65, 16);\n const ringMat = new THREE.MeshBasicMaterial({ color: 0x00ffff, transparent: true, opacity: 0.4, side: THREE.DoubleSide });\n const ring = new THREE.Mesh(ringGeo, ringMat);\n ring.position.set(pos.x, pos.y, pos.z);\n ring.lookAt(0, 0, 0);\n objectsGroupRef.current.add(ring);\n });\n }, [THREE, groundStations, effectiveLayers.groundStations, currentView]);\n\n // ==========================================================================\n // Update Coverage (Realistic satellite-to-ground cones + legacy region cones)\n // ==========================================================================\n \n const updateCoverage = useCallback(() => {\n const T = threeRef.current;\n if (!T || !conesGroupRef.current || currentView === 'solar-system') return;\n\n // Clear existing\n while (conesGroupRef.current.children.length > 0) {\n conesGroupRef.current.remove(conesGroupRef.current.children[0]);\n }\n\n if (!effectiveLayers.coverage) return;\n\n // ========================================\n // Satellite Coverage Visualization (NASA-style)\n // Renders coverage data provided by Zendir SDK\n // ========================================\n satelliteCoverages.forEach((coverage) => {\n // Get satellite position\n let satPos: any;\n if (coverage.satellitePosition) {\n satPos = new T.Vector3(coverage.satellitePosition.x, coverage.satellitePosition.y, coverage.satellitePosition.z);\n } else {\n const satMesh = objectMeshMapRef.current.get(coverage.satelliteId);\n if (!satMesh) return;\n satPos = satMesh.position.clone();\n }\n\n const satDistance = satPos.length();\n const coneColor = new T.Color(coverage.color || '#22d3ee');\n const highlightColor = new T.Color(coverage.color || '#22d3ee').multiplyScalar(1.3);\n\n // ====== 1. Render footprint border only (no filled plane - it cuts through sphere) ======\n if (coverage.footprintPolygon && coverage.footprintPolygon.length >= 3 && coverage.showFootprint !== false) {\n const cornerPoints = coverage.footprintPolygon.map(pt => latLonAltToCartesian(pt.latitude, pt.longitude, 0));\n \n // Curved border (follows sphere curvature via SLERP)\n const borderPts = subdivideSphericalPolygon(cornerPoints, SPHERICAL_SUBDIVISIONS, SCENE_EARTH_RADIUS * 1.003)\n .map(pt => new T.Vector3(pt.x, pt.y, pt.z));\n borderPts.push(borderPts[0].clone());\n const borderGeo = new T.BufferGeometry().setFromPoints(borderPts);\n const borderMat = new T.LineBasicMaterial({ color: highlightColor, transparent: true, opacity: 0.95, linewidth: 2 });\n conesGroupRef.current.add(new T.Line(borderGeo, borderMat));\n\n // Outer glow (slightly larger radius for glow effect)\n const glowPts = subdivideSphericalPolygon(cornerPoints, SPHERICAL_SUBDIVISIONS, SCENE_EARTH_RADIUS * 1.005)\n .map(pt => new T.Vector3(pt.x, pt.y, pt.z));\n glowPts.push(glowPts[0].clone());\n const glowGeo = new T.BufferGeometry().setFromPoints(glowPts);\n const glowMat = new T.LineBasicMaterial({ color: coneColor, transparent: true, opacity: 0.4 });\n conesGroupRef.current.add(new T.Line(glowGeo, glowMat));\n\n // Cone lines from satellite to corners (lines only, no filled surface)\n if (coverage.showCone !== false) {\n for (const corner of cornerPoints) {\n const edgePt = new T.Vector3(corner.x, corner.y, corner.z).normalize().multiplyScalar(SCENE_EARTH_RADIUS);\n const lineGeo = new T.BufferGeometry().setFromPoints([satPos, edgePt]);\n const lineMat = new T.LineBasicMaterial({ color: coneColor, transparent: true, opacity: 0.4 });\n conesGroupRef.current.add(new T.Line(lineGeo, lineMat));\n }\n }\n }\n\n // ====== 2. Simple cone (when no polygon, just halfAngle) ======\n else if (coverage.halfAngle && coverage.showCone !== false) {\n const halfAngleRad = coverage.halfAngle * (Math.PI / 180);\n const coneHeight = satDistance - SCENE_EARTH_RADIUS * 0.98;\n const coneRadius = coneHeight * Math.tan(halfAngleRad);\n\n // Cone mesh\n const coneGeo = new T.ConeGeometry(coneRadius, coneHeight, 48, 1, true);\n const coneMat = new T.MeshBasicMaterial({\n color: coneColor,\n transparent: true,\n opacity: 0.12,\n side: T.DoubleSide,\n depthWrite: false,\n });\n const cone = new T.Mesh(coneGeo, coneMat);\n cone.position.copy(satPos);\n cone.lookAt(0, 0, 0);\n cone.rotateX(Math.PI / 2);\n cone.translateY(-coneHeight / 2);\n conesGroupRef.current.add(cone);\n\n // Footprint circle\n if (coverage.showFootprint !== false) {\n const nadirDir = satPos.clone().normalize();\n const footprintPos = nadirDir.clone().multiplyScalar(SCENE_EARTH_RADIUS * 1.003);\n const footprintRadius = coneRadius * (SCENE_EARTH_RADIUS / satDistance);\n \n // Filled circle\n const footGeo = new T.CircleGeometry(footprintRadius, 64);\n const footMat = new T.MeshBasicMaterial({\n color: coneColor, transparent: true, opacity: 0.3, side: T.DoubleSide, depthWrite: false\n });\n const footprint = new T.Mesh(footGeo, footMat);\n footprint.position.copy(footprintPos);\n footprint.lookAt(satPos);\n conesGroupRef.current.add(footprint);\n\n // Edge ring\n const ringGeo = new T.RingGeometry(footprintRadius * 0.97, footprintRadius, 64);\n const ringMat = new T.MeshBasicMaterial({\n color: highlightColor, transparent: true, opacity: 0.7, side: T.DoubleSide\n });\n const ring = new T.Mesh(ringGeo, ringMat);\n ring.position.copy(footprintPos);\n ring.lookAt(satPos);\n conesGroupRef.current.add(ring);\n }\n }\n\n // ====== 3. Nadir line ======\n if (coverage.showNadirLine !== false) {\n let nadirGroundPoint: any;\n if (coverage.nadirPoint) {\n const np = latLonAltToCartesian(coverage.nadirPoint.latitude, coverage.nadirPoint.longitude, 0);\n nadirGroundPoint = new T.Vector3(np.x, np.y, np.z);\n } else {\n nadirGroundPoint = satPos.clone().normalize().multiplyScalar(SCENE_EARTH_RADIUS);\n }\n const lineGeo = new T.BufferGeometry().setFromPoints([satPos, nadirGroundPoint]);\n const lineMat = new T.LineBasicMaterial({ color: highlightColor, transparent: true, opacity: 0.7 });\n conesGroupRef.current.add(new T.Line(lineGeo, lineMat));\n }\n });\n\n // ========================================\n // Legacy Region-based Visibility Cones\n // ========================================\n visibilityCones.forEach((cone) => {\n const pos = latLonAltToCartesian(cone.center.latitude, cone.center.longitude, 0);\n \n const coneHeight = 1000 * KM_TO_SCENE;\n const minElev = cone.minElevation || 10;\n const coneRadius = coneHeight * Math.tan((90 - minElev) * (Math.PI / 180) * 0.4);\n const coneColor = new T.Color(cone.color || '#22d3ee');\n \n const coneGeo = new T.ConeGeometry(coneRadius, coneHeight, 24, 1, true);\n const coneMat = new T.MeshBasicMaterial({\n color: coneColor,\n transparent: true,\n opacity: cone.opacity || 0.12,\n side: T.DoubleSide,\n depthWrite: false,\n });\n \n const coneMesh = new T.Mesh(coneGeo, coneMat);\n coneMesh.position.set(pos.x, pos.y, pos.z);\n coneMesh.lookAt(0, 0, 0);\n coneMesh.rotateX(-Math.PI / 2);\n coneMesh.translateY(coneHeight / 2);\n conesGroupRef.current.add(coneMesh);\n\n // Footprint ring\n const footGeo = new T.RingGeometry(coneRadius * 0.7, coneRadius * 0.9, 32);\n const footMat = new T.MeshBasicMaterial({\n color: coneColor,\n transparent: true,\n opacity: 0.3,\n side: T.DoubleSide,\n });\n const foot = new T.Mesh(footGeo, footMat);\n foot.position.set(pos.x * 1.002, pos.y * 1.002, pos.z * 1.002);\n foot.lookAt(0, 0, 0);\n conesGroupRef.current.add(foot);\n });\n }, [visibilityCones, satelliteCoverages, effectiveLayers.coverage, currentView]);\n\n // ==========================================================================\n // Update Communication Links\n // ==========================================================================\n \n const updateLinks = useCallback(() => {\n if (!THREE || !linksGroupRef.current || currentView === 'solar-system') return;\n\n while (linksGroupRef.current.children.length > 0) {\n linksGroupRef.current.remove(linksGroupRef.current.children[0]);\n }\n\n communicationLinks.forEach((link) => {\n const fromMesh = objectMeshMapRef.current.get(link.fromId);\n const toMesh = objectMeshMapRef.current.get(link.toId);\n if (!fromMesh || !toMesh) return;\n\n const color = link.color || (link.status === 'active' ? '#00ff88' : '#666666');\n const geo = new THREE.BufferGeometry().setFromPoints([fromMesh.position.clone(), toMesh.position.clone()]);\n \n // Dashed animated line\n const mat = new THREE.LineDashedMaterial({ \n color: new THREE.Color(color), \n transparent: true, \n opacity: link.status === 'active' ? 0.8 : 0.4,\n dashSize: 30,\n gapSize: 20,\n });\n \n const line = new THREE.Line(geo, mat);\n line.computeLineDistances(); // Required for dashed lines - must be on Line, not geometry\n line.userData = { isAnimatedLink: true };\n linksGroupRef.current.add(line);\n });\n }, [THREE, communicationLinks, currentView]);\n\n // ==========================================================================\n // Update Orbits\n // ==========================================================================\n \n const updateOrbits = useCallback(() => {\n if (!THREE || !orbitsGroupRef.current || currentView === 'solar-system') return;\n\n while (orbitsGroupRef.current.children.length > 0) {\n orbitsGroupRef.current.remove(orbitsGroupRef.current.children[0]);\n }\n\n if (!effectiveLayers.orbits) return;\n\n orbitPaths.forEach((path) => {\n if (path.points.length < 2) return;\n const points = path.points.map(p => new THREE.Vector3(p.x, p.y, p.z));\n const geo = new THREE.BufferGeometry().setFromPoints(points);\n const mat = new THREE.LineBasicMaterial({ color: new THREE.Color(path.color || '#888888'), transparent: true, opacity: 0.5 });\n orbitsGroupRef.current.add(new THREE.Line(geo, mat));\n });\n }, [THREE, orbitPaths, effectiveLayers.orbits, currentView]);\n\n // ==========================================================================\n // Mouse Handlers\n // ==========================================================================\n \n const handleMouseMove = useCallback((event: MouseEvent) => {\n if (!containerRef.current || !raycasterRef.current || !cameraRef.current) return;\n\n const rect = containerRef.current.getBoundingClientRect();\n mouseRef.current.set(\n ((event.clientX - rect.left) / rect.width) * 2 - 1,\n -((event.clientY - rect.top) / rect.height) * 2 + 1\n );\n\n raycasterRef.current.setFromCamera(mouseRef.current, cameraRef.current);\n\n const selectables: any[] = [];\n objectsGroupRef.current?.traverse((obj: any) => { if (obj.userData?.isSelectable) selectables.push(obj); });\n\n const intersects = raycasterRef.current.intersectObjects(selectables, true);\n\n if (intersects.length > 0) {\n let hit = intersects[0].object;\n while (hit && !hit.userData?.objectId) hit = hit.parent;\n \n if (hit?.userData) {\n setHoverTooltip({ visible: true, x: event.clientX - rect.left, y: event.clientY - rect.top, object: hit.userData.data });\n if (containerRef.current) containerRef.current.style.cursor = 'pointer';\n return;\n }\n }\n \n setHoverTooltip({ visible: false, x: 0, y: 0, object: null });\n if (containerRef.current) containerRef.current.style.cursor = 'grab';\n }, []);\n\n const handleClick = useCallback((event: MouseEvent) => {\n if (!containerRef.current || !raycasterRef.current || !cameraRef.current) return;\n\n const rect = containerRef.current.getBoundingClientRect();\n mouseRef.current.set(\n ((event.clientX - rect.left) / rect.width) * 2 - 1,\n -((event.clientY - rect.top) / rect.height) * 2 + 1\n );\n\n raycasterRef.current.setFromCamera(mouseRef.current, cameraRef.current);\n\n // Check objects group\n const selectables: any[] = [];\n objectsGroupRef.current?.traverse((obj: any) => { if (obj.userData?.isSelectable) selectables.push(obj); });\n // Also check planets group for solar system view\n planetsGroupRef.current?.traverse((obj: any) => { if (obj.userData?.isSelectable) selectables.push(obj); });\n\n const intersects = raycasterRef.current.intersectObjects(selectables, true);\n\n if (intersects.length > 0) {\n let hit = intersects[0].object;\n while (hit && !hit.userData?.objectId) hit = hit.parent;\n \n if (hit?.userData?.objectId) {\n const objectId = hit.userData.objectId;\n setSelection({ selectedId: objectId, selectedObject: hit.userData.data, hoveredId: null });\n callbacks?.onSelect?.(hit.userData.data);\n \n // Fly to the clicked object\n flyTo(objectId, { animate: true });\n return;\n }\n }\n \n setSelection({ selectedId: null, selectedObject: null, hoveredId: null });\n callbacks?.onSelect?.(null);\n }, [callbacks]);\n\n // ==========================================================================\n // Fly To Object (comprehensive camera navigation)\n // ==========================================================================\n \n const flyTo = useCallback((objectId: string, options?: { zoom?: number; animate?: boolean; distance?: number; offset?: Vector3D }) => {\n if (!THREE || !cameraRef.current || !controlsRef.current) return;\n\n const mesh = objectMeshMapRef.current.get(objectId);\n if (!mesh) {\n if (import.meta.env.DEV) {\n console.warn(`flyTo: Object \"${objectId}\" not found`);\n }\n return;\n }\n\n const targetPos = mesh.position.clone();\n const camera = cameraRef.current;\n const controls = controlsRef.current;\n const category = mesh.userData?.category;\n const isGroundStation = category === 'groundStation';\n\n // Determine viewing distance based on object type\n let viewDistance: number;\n if (options?.distance) {\n viewDistance = options.distance;\n } else {\n // Auto-calculate based on object size/type\n const isPlanet = mesh.userData?.isPlanet;\n const targetDist = targetPos.length();\n \n if (isPlanet) {\n // For planets, get closer based on planet size\n const planetRadius = mesh.geometry?.parameters?.radius || 100;\n viewDistance = planetRadius * 5;\n } else if (isGroundStation) {\n // Ground stations - close view from above\n viewDistance = 200;\n } else if (category === 'station') {\n // Space stations - extremely close side view\n viewDistance = 80;\n } else if (category === 'satellite') {\n // Satellites - extremely close side view\n viewDistance = 60;\n } else if (targetDist > SCENE_EARTH_RADIUS * 2) {\n // Far object (high orbit) - close view\n viewDistance = 150;\n } else {\n // Near-Earth object - very close view\n viewDistance = 100 * (options?.zoom || 1);\n }\n }\n\n // Calculate camera position - offset from object\n let cameraTargetPos: any;\n if (options?.offset) {\n cameraTargetPos = targetPos.clone().add(new THREE.Vector3(options.offset.x, options.offset.y, options.offset.z));\n } else if (isGroundStation) {\n // Ground station: view from above (radially outward from Earth center)\n const upDir = targetPos.clone().normalize();\n cameraTargetPos = targetPos.clone().add(upDir.multiplyScalar(viewDistance));\n } else {\n // Satellites/stations: view from the side\n const dir = targetPos.clone().normalize();\n const side = new THREE.Vector3(-dir.z, 0.2, dir.x).normalize();\n cameraTargetPos = targetPos.clone().add(side.multiplyScalar(viewDistance));\n }\n\n if (options?.animate !== false) {\n focusTransitionRef.current = {\n startTime: Date.now(),\n startPos: { x: camera.position.x, y: camera.position.y, z: camera.position.z },\n targetPos: { x: cameraTargetPos.x, y: cameraTargetPos.y, z: cameraTargetPos.z },\n startTarget: { x: controls.target.x, y: controls.target.y, z: controls.target.z },\n targetTarget: { x: targetPos.x, y: targetPos.y, z: targetPos.z },\n duration: CAMERA_TRANSITION_DURATION,\n isActive: true,\n };\n } else {\n camera.position.copy(cameraTargetPos);\n controls.target.copy(targetPos);\n controls.update();\n }\n\n // Fire callback\n callbacks?.onFocus?.(mesh.userData?.data || { id: objectId });\n }, [THREE, callbacks]);\n\n // Alias for backward compatibility\n const focusOn = flyTo;\n\n // ==========================================================================\n // Animation\n // ==========================================================================\n \n const animate = useCallback(() => {\n // Guard: Only one animation loop should run at a time\n if (!isAnimatingRef.current) return;\n if (!rendererRef.current || !sceneRef.current || !cameraRef.current) return;\n\n const camera = cameraRef.current;\n const controls = controlsRef.current;\n\n // Transition\n if (focusTransitionRef.current?.isActive) {\n const t = focusTransitionRef.current;\n const progress = Math.min((Date.now() - t.startTime) / t.duration, 1);\n const e = easeOutCubic(progress);\n\n camera.position.x = t.startPos.x + (t.targetPos.x - t.startPos.x) * e;\n camera.position.y = t.startPos.y + (t.targetPos.y - t.startPos.y) * e;\n camera.position.z = t.startPos.z + (t.targetPos.z - t.startPos.z) * e;\n\n controls.target.x = t.startTarget.x + (t.targetTarget.x - t.startTarget.x) * e;\n controls.target.y = t.startTarget.y + (t.targetTarget.y - t.startTarget.y) * e;\n controls.target.z = t.startTarget.z + (t.targetTarget.z - t.startTarget.z) * e;\n\n if (progress >= 1) t.isActive = false;\n }\n\n if (controls) controls.update();\n\n timeRef.current += 0.016;\n if (starsMaterialRef.current) starsMaterialRef.current.uniforms.time.value = timeRef.current;\n\n // Animate communication link dashes (moving dotted lines)\n if (linksGroupRef.current) {\n linksGroupRef.current.children.forEach((child: any) => {\n if (child.userData?.isAnimatedLink && child.material) {\n child.material.dashOffset -= 1.5; // Speed of animation\n }\n });\n }\n\n rendererRef.current.render(sceneRef.current, camera);\n animationRef.current = requestAnimationFrame(animate);\n }, []);\n\n // ==========================================================================\n // Imperative Handle\n // ==========================================================================\n \n useImperativeHandle(ref, () => ({\n focusOn,\n flyTo,\n setView: (mode: ViewMode) => setCurrentView(mode),\n setTime: () => {},\n setTimeScale: () => {},\n togglePlay: () => {},\n setLayerVisibility: (layer: keyof LayerVisibility, visible: boolean) => setLayers(prev => ({ ...prev, [layer]: visible })),\n getCameraState: (): CameraState => {\n if (!cameraRef.current) return { position: { x: 0, y: 0, z: 10000 }, target: { x: 0, y: 0, z: 0 }, up: { x: 0, y: 1, z: 0 }, fov: 45, near: 0.1, far: 100000 };\n const c = cameraRef.current;\n return { position: { x: c.position.x, y: c.position.y, z: c.position.z }, target: { x: controlsRef.current?.target.x || 0, y: controlsRef.current?.target.y || 0, z: controlsRef.current?.target.z || 0 }, up: { x: c.up.x, y: c.up.y, z: c.up.z }, fov: c.fov, near: c.near, far: c.far };\n },\n setCameraState: (state: Partial<CameraState>) => {\n if (!cameraRef.current) return;\n if (state.position) cameraRef.current.position.set(state.position.x, state.position.y, state.position.z);\n if (state.target && controlsRef.current) controlsRef.current.target.set(state.target.x, state.target.y, state.target.z);\n },\n exportImage: (format: 'png' | 'jpeg' = 'png'): string => rendererRef.current?.domElement.toDataURL(`image/${format}`) || '',\n exportScene: (): Blob => new Blob(),\n getVisibleObjects: (): SpaceObject[] => [...satellites, ...debris, ...stations, ...customObjects],\n findObjects: (q: string): SpaceObject[] => [...satellites, ...debris, ...stations, ...customObjects].filter(obj => obj.name.toLowerCase().includes(q.toLowerCase()) || obj.id.toLowerCase().includes(q.toLowerCase())),\n addObject: () => {},\n removeObject: () => {},\n updateObject: () => {},\n measureDistance: (_from: string | Vector3D, _to: string | Vector3D): number => 0,\n }), [satellites, debris, stations, customObjects, focusOn]);\n\n // ==========================================================================\n // Effects\n // ==========================================================================\n \n useEffect(() => { if (THREE && OrbitControlsClass) return initScene(); }, [THREE, OrbitControlsClass, initScene]);\n\n useEffect(() => {\n if (!isLoading && THREE) {\n // Cancel any existing animation loop first (prevents stacking)\n if (animationRef.current) {\n cancelAnimationFrame(animationRef.current);\n animationRef.current = null;\n }\n \n // Start animation loop with guard\n isAnimatingRef.current = true;\n animate();\n \n return () => {\n // Stop animation loop cleanly\n isAnimatingRef.current = false;\n if (animationRef.current) {\n cancelAnimationFrame(animationRef.current);\n animationRef.current = null;\n }\n };\n }\n }, [isLoading, THREE, animate]);\n\n useEffect(() => {\n if (THREE && !isLoading) {\n updateObjects();\n updateGroundStations();\n updateCoverage();\n updateOrbits();\n updateLinks();\n }\n }, [THREE, isLoading, updateObjects, updateGroundStations, updateCoverage, updateOrbits, updateLinks]);\n\n useEffect(() => {\n const container = containerRef.current;\n if (!container || isLoading) return;\n container.addEventListener('mousemove', handleMouseMove);\n container.addEventListener('click', handleClick);\n return () => { container.removeEventListener('mousemove', handleMouseMove); container.removeEventListener('click', handleClick); };\n }, [isLoading, handleMouseMove, handleClick]);\n\n useEffect(() => {\n const handleResize = () => {\n if (!containerRef.current || !rendererRef.current || !cameraRef.current) return;\n const rect = containerRef.current.getBoundingClientRect();\n const h = typeof height === 'number' ? height : rect.height;\n cameraRef.current.aspect = rect.width / h;\n cameraRef.current.updateProjectionMatrix();\n rendererRef.current.setSize(rect.width, h);\n };\n window.addEventListener('resize', handleResize);\n return () => window.removeEventListener('resize', handleResize);\n }, [height]);\n\n useEffect(() => { if (focusedObjectId) focusOn(focusedObjectId, { animate: true }); }, [focusedObjectId, focusOn]);\n\n // Update sun direction for atmosphere glow (from Zendir SDK)\n useEffect(() => {\n if (THREE && atmosphereMaterialRef.current && sunDirection) {\n const dir = new THREE.Vector3(sunDirection.x, sunDirection.y, sunDirection.z).normalize();\n atmosphereMaterialRef.current.uniforms.uSunDirection.value = dir;\n }\n }, [THREE, sunDirection]);\n\n // Update planet positions from Zendir SDK\n useEffect(() => {\n if (!THREE || !planetPositions || !planetsGroupRef.current) return;\n \n planetsGroupRef.current.traverse((child: any) => {\n if (child.userData?.planetId && planetPositions[child.userData.planetId]) {\n const pos = planetPositions[child.userData.planetId];\n child.position.set(pos.x, pos.y, pos.z);\n }\n });\n }, [THREE, planetPositions]);\n\n // ==========================================================================\n // Render\n // ==========================================================================\n \n if (!webglCapabilities.available) {\n return (\n <div className={`zenspace3d-fallback ${className}`} style={{ width, height: typeof height === 'number' ? height : 600, display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', backgroundColor: '#030508', borderRadius: 8, fontFamily: 'ui-monospace, monospace', ...style }}>\n <div style={{ marginBottom: 16 }}>\n <AstroIcon name=\"public\" size=\"large\" label=\"Globe\" style={{ color: '#22d3ee', opacity: 0.5 }} />\n </div>\n <div style={{ color: '#b8bcc8' /* WCAG: improved contrast */, fontSize: 14 }}>WebGL is not available</div>\n </div>\n );\n }\n\n if (error) return <div style={{ width, height, display: 'flex', alignItems: 'center', justifyContent: 'center', backgroundColor: '#0a0a0f', color: '#ff4444' }}><p>Error: {error}</p></div>;\n\n return (\n <div className={`zenspace3d ${className}`} style={{ width, height: typeof height === 'number' ? height : '100%', position: 'relative', backgroundColor: '#000', borderRadius: 8, overflow: 'hidden', cursor: 'grab', ...style }}>\n <div ref={containerRef} style={{ width: '100%', height: '100%' }} />\n\n {isLoading && <div style={{ position: 'absolute', top: 0, left: 0, right: 0, bottom: 0, display: 'flex', alignItems: 'center', justifyContent: 'center', backgroundColor: 'rgba(0,0,0,0.9)' }}><div style={{ color: '#22d3ee', fontSize: 14 }}>Loading...</div></div>}\n\n {showTools && !isLoading && (\n <div style={{ position: 'absolute', top: 12, left: 12, display: 'flex', flexDirection: 'column', gap: 4 }}>\n <LayerBtn icon=\"satellite\" label=\"Satellites\" active={layers.satellites} onClick={() => setLayers(l => ({ ...l, satellites: !l.satellites }))} />\n <LayerBtn icon=\"home\" label=\"Stations\" active={layers.stations} onClick={() => setLayers(l => ({ ...l, stations: !l.stations }))} />\n <LayerBtn icon=\"antenna\" label=\"Ground\" active={layers.groundStations} onClick={() => setLayers(l => ({ ...l, groundStations: !l.groundStations }))} />\n <LayerBtn icon=\"timeline\" label=\"Orbits\" active={layers.orbits} onClick={() => setLayers(l => ({ ...l, orbits: !l.orbits }))} />\n <LayerBtn icon=\"signal-cellular-4-bar\" label=\"Coverage\" active={layers.coverage} onClick={() => setLayers(l => ({ ...l, coverage: !l.coverage }))} />\n </div>\n )}\n\n {!isLoading && (\n <ObjectLegend \n currentView={currentView}\n satellites={satellites}\n stations={stations}\n groundStations={groundStations}\n onObjectClick={(id, objectData) => {\n // Same behavior as clicking in 3D: select, callback, fly\n setSelection({ selectedId: id, selectedObject: objectData, hoveredId: null });\n callbacks?.onSelect?.(objectData);\n flyTo(id, { animate: true });\n }}\n />\n )}\n\n {hoverTooltip.visible && hoverTooltip.object && (\n <div style={{ \n position: 'absolute', \n left: hoverTooltip.x + 15, \n top: hoverTooltip.y - 10, \n backgroundColor: 'rgba(20, 25, 35, 0.95)', \n color: '#e4e4e7', \n padding: '10px 14px', \n borderRadius: 4, \n fontSize: 12, \n fontFamily: 'system-ui, -apple-system, sans-serif', \n boxShadow: '0 4px 20px rgba(0,0,0,0.5)',\n pointerEvents: 'none', \n zIndex: 100,\n minWidth: 140,\n }}>\n <div style={{ color: '#ffffff', fontWeight: 500, marginBottom: 4 }}>\n {hoverTooltip.object.name || hoverTooltip.object.targetName || 'Unknown'}\n </div>\n {hoverTooltip.object.category && (\n <div style={{ color: '#9ca3af', fontSize: 11 }}>{hoverTooltip.object.category}</div>\n )}\n {hoverTooltip.object.overpassTime && (\n <div style={{ color: '#9ca3af', fontSize: 11, marginTop: 4 }}>\n Overpass time: {hoverTooltip.object.overpassTime}\n </div>\n )}\n </div>\n )}\n\n {/* Overpass labels removed - now shown only on hover */}\n\n {showInfoPanel && selection.selectedObject && (\n <div style={{ position: 'absolute', bottom: 16, right: 12, backgroundColor: 'rgba(0,0,0,0.9)', color: '#e4e4e7', padding: '14px 18px', borderRadius: 10, fontSize: 12, fontFamily: 'ui-monospace, monospace', border: '1px solid rgba(34,211,238,0.3)', minWidth: 180 }}>\n <div style={{ color: '#22d3ee', fontWeight: 500, marginBottom: 8 }}>{selection.selectedObject.name}</div>\n <div style={{ color: '#b8bcc8' /* WCAG: improved contrast */, fontSize: 10 }}>{selection.selectedObject.category}</div>\n <button onClick={() => setSelection({ selectedId: null, selectedObject: null, hoveredId: null })} style={{ marginTop: 10, padding: '5px 10px', backgroundColor: 'rgba(255,255,255,0.1)', border: 'none', borderRadius: 4, color: '#a1a1aa', cursor: 'pointer', fontSize: 10, width: '100%' }}>Close</button>\n </div>\n )}\n\n {!isLoading && <div style={{ position: 'absolute', bottom: 12, left: 12, backgroundColor: 'rgba(0,0,0,0.5)', color: '#b8bcc8' /* WCAG: improved contrast */, padding: '5px 10px', borderRadius: 6, fontSize: 10 }}>Drag to rotate • Scroll to zoom</div>}\n </div>\n );\n }\n);\n\n// =============================================================================\n// Sub-Components\n// =============================================================================\n\nfunction LayerBtn({ icon, label, active, onClick }: { icon: AstroIconName; label: string; active: boolean; onClick: () => void }) {\n return (\n <button \n onClick={onClick} \n aria-label={`Toggle ${label} layer`}\n aria-pressed={active}\n style={{ \n display: 'flex', \n alignItems: 'center', \n gap: 6, \n padding: '6px 10px', \n backgroundColor: active ? 'rgba(34,211,238,0.15)' : 'rgba(0,0,0,0.7)', \n border: active ? '1px solid rgba(34,211,238,0.4)' : '1px solid rgba(255,255,255,0.1)', \n borderRadius: 6, \n cursor: 'pointer', \n fontSize: '0.6875rem', // 11px in rem\n color: active ? '#22d3ee' : '#b8bcc8', // WCAG: improved contrast from #71717a\n minWidth: 110,\n }}\n >\n <span aria-hidden=\"true\"><AstroIcon name={icon} size=\"extra-small\" label=\"\" /></span>\n <span>{label}</span>\n </button>\n );\n}\n\nfunction _OverpassLabel({ overpass, index }: { overpass: OverpassInfo; index: number }) {\n return (\n <div style={{ position: 'absolute', top: 70 + index * 60, left: '28%', backgroundColor: 'rgba(0,0,0,0.85)', color: '#e4e4e7', padding: '8px 12px', borderRadius: 6, fontSize: 11, fontFamily: 'ui-monospace, monospace', border: '1px solid rgba(34,211,238,0.3)', pointerEvents: 'none' }}>\n <div style={{ fontWeight: 500, marginBottom: 2 }}>{overpass.targetName}</div>\n <div style={{ color: '#22d3ee' }}>Overpass: {formatDuration(overpass.timeToOverpass)}</div>\n </div>\n );\n}\n\nfunction ObjectLegend({ currentView, satellites, stations, groundStations, onObjectClick }: {\n currentView: string;\n satellites: any[];\n stations: any[];\n groundStations: any[];\n onObjectClick: (id: string, objectData: any) => void;\n}) {\n const [hoveredSection, setHoveredSection] = React.useState<string | null>(null);\n const [pinnedSection, setPinnedSection] = React.useState<string | null>(null);\n\n // Show section if hovered OR pinned\n const isExpanded = (section: string) => hoveredSection === section || pinnedSection === section;\n\n // Click toggles pin state\n const togglePin = (section: string) => {\n setPinnedSection(prev => prev === section ? null : section);\n };\n\n const sectionStyle: React.CSSProperties = {\n cursor: 'pointer',\n padding: '4px 0',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n transition: 'background-color 0.15s',\n };\n\n const itemStyle: React.CSSProperties = {\n padding: '3px 8px',\n marginLeft: 12,\n cursor: 'pointer',\n borderRadius: 4,\n fontSize: 10,\n color: '#a1a1aa',\n transition: 'all 0.15s',\n };\n\n return (\n <div style={{ \n position: 'absolute', \n top: 12, \n right: 12, \n backgroundColor: 'rgba(0,0,0,0.85)', \n color: '#e4e4e7', \n padding: '10px 14px', \n borderRadius: 8, \n fontSize: 11, \n fontFamily: 'ui-monospace, monospace',\n minWidth: 160,\n maxHeight: 400,\n overflowY: 'auto',\n }}>\n <div style={{ color: '#b8bcc8' /* WCAG: improved contrast */, fontSize: 10, marginBottom: 8 }}>\n {currentView === 'solar-system' ? 'Solar System' : 'Earth Orbit'}\n </div>\n\n {satellites.length > 0 && (\n <div\n onMouseEnter={() => setHoveredSection('satellites')}\n onMouseLeave={() => setHoveredSection(null)}\n >\n <div \n style={{\n ...sectionStyle,\n backgroundColor: isExpanded('satellites') ? 'rgba(255,255,255,0.05)' : 'transparent',\n }}\n onClick={() => togglePin('satellites')}\n >\n <span><span style={{ color: '#00ff88' }}>●</span> {satellites.length} Satellites</span>\n <span style={{ color: pinnedSection === 'satellites' ? '#00ff88' : '#666', fontSize: 9 }}>\n {isExpanded('satellites') ? '▼' : '▶'}{pinnedSection === 'satellites' ? <><AstroIcon name=\"bookmark\" size=\"extra-small\" label=\"\" style={{ marginLeft: 4, verticalAlign: 'middle' }} /></> : null}\n </span>\n </div>\n {isExpanded('satellites') && (\n <div style={{ marginBottom: 4, paddingBottom: 4 }}>\n {satellites.map(sat => (\n <div\n key={sat.id}\n style={itemStyle}\n onClick={(e) => { e.stopPropagation(); onObjectClick(sat.id, sat); }}\n onMouseEnter={(e) => { e.currentTarget.style.backgroundColor = 'rgba(0,255,136,0.15)'; e.currentTarget.style.color = '#00ff88'; }}\n onMouseLeave={(e) => { e.currentTarget.style.backgroundColor = 'transparent'; e.currentTarget.style.color = '#a1a1aa'; }}\n >\n {sat.name || sat.id}\n </div>\n ))}\n </div>\n )}\n </div>\n )}\n\n {stations.length > 0 && (\n <div\n onMouseEnter={() => setHoveredSection('stations')}\n onMouseLeave={() => setHoveredSection(null)}\n >\n <div \n style={{\n ...sectionStyle,\n backgroundColor: isExpanded('stations') ? 'rgba(255,255,255,0.05)' : 'transparent',\n }}\n onClick={() => togglePin('stations')}\n >\n <span><span style={{ color: '#ffd700' }}>●</span> {stations.length} Stations</span>\n <span style={{ color: pinnedSection === 'stations' ? '#ffd700' : '#666', fontSize: 9 }}>\n {isExpanded('stations') ? '▼' : '▶'}{pinnedSection === 'stations' ? <><AstroIcon name=\"bookmark\" size=\"extra-small\" label=\"\" style={{ marginLeft: 4, verticalAlign: 'middle' }} /></> : null}\n </span>\n </div>\n {isExpanded('stations') && (\n <div style={{ marginBottom: 4, paddingBottom: 4 }}>\n {stations.map(st => (\n <div\n key={st.id}\n style={itemStyle}\n onClick={(e) => { e.stopPropagation(); onObjectClick(st.id, st); }}\n onMouseEnter={(e) => { e.currentTarget.style.backgroundColor = 'rgba(255,215,0,0.15)'; e.currentTarget.style.color = '#ffd700'; }}\n onMouseLeave={(e) => { e.currentTarget.style.backgroundColor = 'transparent'; e.currentTarget.style.color = '#a1a1aa'; }}\n >\n {st.name || st.id}\n </div>\n ))}\n </div>\n )}\n </div>\n )}\n\n {groundStations.length > 0 && (\n <div\n onMouseEnter={() => setHoveredSection('groundStations')}\n onMouseLeave={() => setHoveredSection(null)}\n >\n <div \n style={{\n ...sectionStyle,\n backgroundColor: isExpanded('groundStations') ? 'rgba(255,255,255,0.05)' : 'transparent',\n }}\n onClick={() => togglePin('groundStations')}\n >\n <span><span style={{ color: '#00ffff' }}>▲</span> {groundStations.length} Ground Stations</span>\n <span style={{ color: pinnedSection === 'groundStations' ? '#00ffff' : '#666', fontSize: 9 }}>\n {isExpanded('groundStations') ? '▼' : '▶'}{pinnedSection === 'groundStations' ? <><AstroIcon name=\"bookmark\" size=\"extra-small\" label=\"\" style={{ marginLeft: 4, verticalAlign: 'middle' }} /></> : null}\n </span>\n </div>\n {isExpanded('groundStations') && (\n <div style={{ marginBottom: 4, paddingBottom: 4 }}>\n {groundStations.map(gs => (\n <div\n key={gs.id}\n style={itemStyle}\n onClick={(e) => { e.stopPropagation(); onObjectClick(gs.id, gs); }}\n onMouseEnter={(e) => { e.currentTarget.style.backgroundColor = 'rgba(0,255,255,0.15)'; e.currentTarget.style.color = '#00ffff'; }}\n onMouseLeave={(e) => { e.currentTarget.style.backgroundColor = 'transparent'; e.currentTarget.style.color = '#a1a1aa'; }}\n >\n {gs.name || gs.id}\n </div>\n ))}\n </div>\n )}\n </div>\n )}\n </div>\n );\n}\n\nexport default ZenSpace3D;\n"],"names":["ZenSpace3D","ZenSpace3DThree","THREE","_a"],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { default as React } from 'react';
|
|
2
|
+
import { ZenSpace3DProps, ZenSpace3DHandle } from './ZenSpace3DTypes';
|
|
3
|
+
|
|
4
|
+
export interface ZenSpace3DCesiumProps extends ZenSpace3DProps {
|
|
5
|
+
/** Cesium module from dynamic import('cesium') */
|
|
6
|
+
cesium: any;
|
|
7
|
+
}
|
|
8
|
+
export declare const ZenSpace3DCesium: React.ForwardRefExoticComponent<ZenSpace3DCesiumProps & React.RefAttributes<ZenSpace3DHandle>>;
|
|
9
|
+
export default ZenSpace3DCesium;
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
import { jsx } from "react/jsx-runtime";
|
|
2
|
+
import { forwardRef, useRef, useCallback, useImperativeHandle, useEffect } from "react";
|
|
3
|
+
import { cartesianToLatLonAlt, SCENE_EARTH_RADIUS } from "./ZenSpace3DUtils.js";
|
|
4
|
+
function sceneToCartesian3(Cesium, position) {
|
|
5
|
+
const { latitude, longitude, altitude } = cartesianToLatLonAlt(position, SCENE_EARTH_RADIUS);
|
|
6
|
+
return Cesium.Cartesian3.fromDegrees(longitude, latitude, altitude * 1e3);
|
|
7
|
+
}
|
|
8
|
+
const ZenSpace3DCesium = forwardRef(
|
|
9
|
+
function ZenSpace3DCesium2({
|
|
10
|
+
satellites = [],
|
|
11
|
+
stations = [],
|
|
12
|
+
groundStations = [],
|
|
13
|
+
orbitPaths = [],
|
|
14
|
+
view = "earth-orbit",
|
|
15
|
+
height = 600,
|
|
16
|
+
callbacks,
|
|
17
|
+
showTools = false,
|
|
18
|
+
showInfoPanel = false,
|
|
19
|
+
layers,
|
|
20
|
+
cesium: Cesium
|
|
21
|
+
}, ref) {
|
|
22
|
+
const containerRef = useRef(null);
|
|
23
|
+
const viewerRef = useRef(null);
|
|
24
|
+
const entityIdsRef = useRef([]);
|
|
25
|
+
const focusOn = useCallback(
|
|
26
|
+
(objectId, options) => {
|
|
27
|
+
const viewer = viewerRef.current;
|
|
28
|
+
if (!viewer) return;
|
|
29
|
+
const entity = viewer.entities.getById(objectId);
|
|
30
|
+
if (entity) {
|
|
31
|
+
viewer.zoomTo(entity, { duration: (options == null ? void 0 : options.animate) !== false ? 1.5 : 0 });
|
|
32
|
+
}
|
|
33
|
+
},
|
|
34
|
+
[]
|
|
35
|
+
);
|
|
36
|
+
const setView = useCallback((mode) => {
|
|
37
|
+
const viewer = viewerRef.current;
|
|
38
|
+
if (!viewer) return;
|
|
39
|
+
if (mode === "earth-orbit") {
|
|
40
|
+
viewer.camera.flyTo({ destination: Cesium.Cartesian3.fromDegrees(0, 0, 2e7) });
|
|
41
|
+
} else if (mode === "solar-system") {
|
|
42
|
+
viewer.camera.flyTo({ destination: Cesium.Cartesian3.fromDegrees(0, 0, 5e7) });
|
|
43
|
+
}
|
|
44
|
+
}, [Cesium]);
|
|
45
|
+
useImperativeHandle(
|
|
46
|
+
ref,
|
|
47
|
+
() => ({
|
|
48
|
+
focusOn,
|
|
49
|
+
flyTo: focusOn,
|
|
50
|
+
setView,
|
|
51
|
+
setTime: () => {
|
|
52
|
+
},
|
|
53
|
+
setTimeScale: () => {
|
|
54
|
+
},
|
|
55
|
+
togglePlay: () => {
|
|
56
|
+
},
|
|
57
|
+
setLayerVisibility: () => {
|
|
58
|
+
},
|
|
59
|
+
getCameraState: () => ({}),
|
|
60
|
+
setCameraState: () => {
|
|
61
|
+
},
|
|
62
|
+
exportImage: () => "",
|
|
63
|
+
exportScene: () => new Blob(),
|
|
64
|
+
getVisibleObjects: () => [],
|
|
65
|
+
findObjects: () => [],
|
|
66
|
+
addObject: () => {
|
|
67
|
+
},
|
|
68
|
+
removeObject: () => {
|
|
69
|
+
},
|
|
70
|
+
updateObject: () => {
|
|
71
|
+
},
|
|
72
|
+
measureDistance: () => 0
|
|
73
|
+
}),
|
|
74
|
+
[focusOn, setView]
|
|
75
|
+
);
|
|
76
|
+
useEffect(() => {
|
|
77
|
+
if (!containerRef.current || !Cesium) return;
|
|
78
|
+
const viewer = new Cesium.Viewer(containerRef.current, {
|
|
79
|
+
baseLayerPicker: false,
|
|
80
|
+
fullscreenButton: false,
|
|
81
|
+
vrButton: false,
|
|
82
|
+
geocoder: false,
|
|
83
|
+
homeButton: !!showTools,
|
|
84
|
+
sceneModePicker: false,
|
|
85
|
+
timeline: false,
|
|
86
|
+
navigationHelpButton: !!showTools,
|
|
87
|
+
animation: false,
|
|
88
|
+
scene3DOnly: true,
|
|
89
|
+
useDefaultRenderLoop: true,
|
|
90
|
+
requestRenderMode: false
|
|
91
|
+
});
|
|
92
|
+
viewer.scene.globe.enableLighting = true;
|
|
93
|
+
viewer.scene.backgroundColor = Cesium.Color.BLACK;
|
|
94
|
+
viewerRef.current = viewer;
|
|
95
|
+
const toRemove = [];
|
|
96
|
+
[...satellites, ...stations].forEach((obj) => {
|
|
97
|
+
const id = obj.id;
|
|
98
|
+
const pos = obj.position;
|
|
99
|
+
if (!pos) return;
|
|
100
|
+
const position = sceneToCartesian3(Cesium, pos);
|
|
101
|
+
viewer.entities.add({
|
|
102
|
+
id,
|
|
103
|
+
name: obj.name,
|
|
104
|
+
position,
|
|
105
|
+
point: {
|
|
106
|
+
pixelSize: 8,
|
|
107
|
+
color: Cesium.Color.CYAN,
|
|
108
|
+
outlineColor: Cesium.Color.WHITE,
|
|
109
|
+
outlineWidth: 1
|
|
110
|
+
}
|
|
111
|
+
});
|
|
112
|
+
toRemove.push(id);
|
|
113
|
+
});
|
|
114
|
+
(groundStations || []).forEach((gs) => {
|
|
115
|
+
const position = Cesium.Cartesian3.fromDegrees(
|
|
116
|
+
gs.longitude,
|
|
117
|
+
gs.latitude,
|
|
118
|
+
gs.elevation ?? 0
|
|
119
|
+
);
|
|
120
|
+
viewer.entities.add({
|
|
121
|
+
id: gs.id,
|
|
122
|
+
name: gs.name,
|
|
123
|
+
position,
|
|
124
|
+
point: {
|
|
125
|
+
pixelSize: 6,
|
|
126
|
+
color: Cesium.Color.BLUE,
|
|
127
|
+
outlineColor: Cesium.Color.WHITE,
|
|
128
|
+
outlineWidth: 1
|
|
129
|
+
}
|
|
130
|
+
});
|
|
131
|
+
toRemove.push(gs.id);
|
|
132
|
+
});
|
|
133
|
+
(orbitPaths || []).forEach((path) => {
|
|
134
|
+
const positions = path.points.map((p) => sceneToCartesian3(Cesium, p));
|
|
135
|
+
viewer.entities.add({
|
|
136
|
+
id: `orbit-${path.objectId}`,
|
|
137
|
+
name: path.objectId,
|
|
138
|
+
polyline: {
|
|
139
|
+
positions,
|
|
140
|
+
width: 2,
|
|
141
|
+
material: Cesium.Color.YELLOW
|
|
142
|
+
}
|
|
143
|
+
});
|
|
144
|
+
toRemove.push(`orbit-${path.objectId}`);
|
|
145
|
+
});
|
|
146
|
+
entityIdsRef.current = toRemove;
|
|
147
|
+
const handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
|
|
148
|
+
handler.setInputAction((movement) => {
|
|
149
|
+
const picked = viewer.scene.pick(movement.position);
|
|
150
|
+
if (Cesium.defined(picked) && picked.id && (callbacks == null ? void 0 : callbacks.onSelect)) {
|
|
151
|
+
callbacks.onSelect({
|
|
152
|
+
id: picked.id.id,
|
|
153
|
+
name: picked.id.name,
|
|
154
|
+
category: "satellite",
|
|
155
|
+
position: { x: 0, y: 0, z: 0 },
|
|
156
|
+
visualRadius: 0
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
}, Cesium.ScreenSpaceEventType.LEFT_CLICK);
|
|
160
|
+
return () => {
|
|
161
|
+
handler.destroy();
|
|
162
|
+
entityIdsRef.current.forEach((id) => {
|
|
163
|
+
try {
|
|
164
|
+
viewer.entities.removeById(id);
|
|
165
|
+
} catch (_) {
|
|
166
|
+
}
|
|
167
|
+
});
|
|
168
|
+
viewer.destroy();
|
|
169
|
+
viewerRef.current = null;
|
|
170
|
+
};
|
|
171
|
+
}, [Cesium, satellites, stations, groundStations, orbitPaths, callbacks, showTools]);
|
|
172
|
+
const h = typeof height === "number" ? `${height}px` : height;
|
|
173
|
+
return /* @__PURE__ */ jsx(
|
|
174
|
+
"div",
|
|
175
|
+
{
|
|
176
|
+
ref: containerRef,
|
|
177
|
+
className: "zendir-zenspace3d-cesium",
|
|
178
|
+
style: { width: "100%", height: h, minHeight: 200 }
|
|
179
|
+
}
|
|
180
|
+
);
|
|
181
|
+
}
|
|
182
|
+
);
|
|
183
|
+
export {
|
|
184
|
+
ZenSpace3DCesium
|
|
185
|
+
};
|
|
186
|
+
//# sourceMappingURL=ZenSpace3DCesium.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ZenSpace3DCesium.js","sources":["../../../src/react/3d/ZenSpace3DCesium.tsx"],"sourcesContent":["/**\r\n * @zendir/ui - ZenSpace3D Cesium Backend\r\n *\r\n * Cesium-based 3D Earth/orbit view. Used as default when cesium is installed.\r\n * Converts scene/ECI positions to WGS84 for Cesium entities.\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 { cartesianToLatLonAlt, SCENE_EARTH_RADIUS } from './ZenSpace3DUtils';\r\nimport type { ZenSpace3DProps, ZenSpace3DHandle, ViewMode, Vector3D } from './ZenSpace3DTypes';\r\n\r\n/** Convert scene position (x,y,z) to Cesium Cartesian3 (WGS84) */\r\nfunction sceneToCartesian3(Cesium: any, position: Vector3D): any {\r\n const { latitude, longitude, altitude } = cartesianToLatLonAlt(position, SCENE_EARTH_RADIUS);\r\n return Cesium.Cartesian3.fromDegrees(longitude, latitude, altitude * 1000); // altitude km -> m\r\n}\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 orbitPaths = [],\r\n view = 'earth-orbit',\r\n height = 600,\r\n callbacks,\r\n showTools = false,\r\n showInfoPanel = false,\r\n layers,\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 const entityIdsRef = useRef<string[]>([]);\r\n\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((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 }, [Cesium]);\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 useEffect(() => {\r\n if (!containerRef.current || !Cesium) return;\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 viewerRef.current = viewer;\r\n\r\n const toRemove: string[] = [];\r\n\r\n // Satellites + stations (position as scene x,y,z)\r\n [...satellites, ...stations].forEach((obj) => {\r\n const id = obj.id;\r\n const pos = (obj as { position: Vector3D }).position;\r\n if (!pos) return;\r\n const position = sceneToCartesian3(Cesium, pos);\r\n viewer.entities.add({\r\n id,\r\n name: (obj as { name?: string }).name,\r\n position,\r\n point: {\r\n pixelSize: 8,\r\n color: Cesium.Color.CYAN,\r\n outlineColor: Cesium.Color.WHITE,\r\n outlineWidth: 1,\r\n },\r\n });\r\n toRemove.push(id);\r\n });\r\n\r\n // Ground stations (lat/lon)\r\n (groundStations || []).forEach((gs) => {\r\n const position = Cesium.Cartesian3.fromDegrees(\r\n gs.longitude,\r\n gs.latitude,\r\n (gs as { elevation?: number }).elevation ?? 0\r\n );\r\n viewer.entities.add({\r\n id: gs.id,\r\n name: gs.name,\r\n position,\r\n point: {\r\n pixelSize: 6,\r\n color: Cesium.Color.BLUE,\r\n outlineColor: Cesium.Color.WHITE,\r\n outlineWidth: 1,\r\n },\r\n });\r\n toRemove.push(gs.id);\r\n });\r\n\r\n // Orbit paths\r\n (orbitPaths || []).forEach((path) => {\r\n const positions = path.points.map((p) => sceneToCartesian3(Cesium, p));\r\n viewer.entities.add({\r\n id: `orbit-${path.objectId}`,\r\n name: path.objectId,\r\n polyline: {\r\n positions,\r\n width: 2,\r\n material: Cesium.Color.YELLOW,\r\n },\r\n });\r\n toRemove.push(`orbit-${path.objectId}`);\r\n });\r\n\r\n entityIdsRef.current = toRemove;\r\n\r\n // Click to select\r\n const handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);\r\n handler.setInputAction((movement: any) => {\r\n const picked = viewer.scene.pick(movement.position);\r\n if (Cesium.defined(picked) && picked.id && callbacks?.onSelect) {\r\n callbacks.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 return () => {\r\n handler.destroy();\r\n entityIdsRef.current.forEach((id) => {\r\n try {\r\n viewer.entities.removeById(id);\r\n } catch (_) {}\r\n });\r\n viewer.destroy();\r\n viewerRef.current = null;\r\n };\r\n }, [Cesium, satellites, stations, groundStations, orbitPaths, callbacks, showTools]);\r\n\r\n const h = typeof height === 'number' ? `${height}px` : height;\r\n return (\r\n <div\r\n ref={containerRef}\r\n className=\"zendir-zenspace3d-cesium\"\r\n style={{ width: '100%', height: h, minHeight: 200 }}\r\n />\r\n );\r\n }\r\n);\r\n\r\nexport default ZenSpace3DCesium;\r\n"],"names":["ZenSpace3DCesium"],"mappings":"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"}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @zendir/ui - ZenSpace3D Shaders
|
|
3
|
+
*
|
|
4
|
+
* Advanced GLSL shaders for atmosphere, glow effects, coverage visualization,
|
|
5
|
+
* and other space rendering effects.
|
|
6
|
+
*/
|
|
7
|
+
export declare 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";
|
|
8
|
+
export declare 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";
|
|
9
|
+
export declare 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";
|
|
10
|
+
export declare 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";
|
|
11
|
+
export declare 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";
|
|
12
|
+
export declare 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";
|
|
13
|
+
export declare 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";
|
|
14
|
+
export declare 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";
|
|
15
|
+
export declare 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";
|
|
16
|
+
export declare 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";
|
|
17
|
+
export declare 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";
|
|
18
|
+
export declare 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";
|
|
19
|
+
export declare const selectionRingVertexShader = "\nvarying vec2 vUv;\n\nvoid main() {\n vUv = uv;\n gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\n}\n";
|
|
20
|
+
export declare 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";
|
|
21
|
+
export declare 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";
|
|
22
|
+
export declare 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";
|
|
23
|
+
export declare const gridVertexShader = "\nvarying vec3 vPosition;\n\nvoid main() {\n vPosition = position;\n gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\n}\n";
|
|
24
|
+
export declare 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";
|
|
25
|
+
export declare 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";
|
|
26
|
+
export declare 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";
|
|
27
|
+
export declare 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";
|
|
28
|
+
export declare const debrisFragmentShader = "\nvarying vec3 vColor;\nvarying float vSize;\n\nvoid main() {\n gl_FragColor = vec4(vColor, 1.0);\n}\n";
|
|
29
|
+
export interface AtmosphereUniforms {
|
|
30
|
+
glowColor: {
|
|
31
|
+
value: [number, number, number];
|
|
32
|
+
};
|
|
33
|
+
glowIntensity: {
|
|
34
|
+
value: number;
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
export interface StarsUniforms {
|
|
38
|
+
time: {
|
|
39
|
+
value: number;
|
|
40
|
+
};
|
|
41
|
+
pointSize: {
|
|
42
|
+
value: number;
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
export interface CoverageUniforms {
|
|
46
|
+
coverageMap: {
|
|
47
|
+
value: unknown;
|
|
48
|
+
};
|
|
49
|
+
lowColor: {
|
|
50
|
+
value: [number, number, number];
|
|
51
|
+
};
|
|
52
|
+
highColor: {
|
|
53
|
+
value: [number, number, number];
|
|
54
|
+
};
|
|
55
|
+
opacity: {
|
|
56
|
+
value: number;
|
|
57
|
+
};
|
|
58
|
+
time: {
|
|
59
|
+
value: number;
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
export interface VisibilityConeUniforms {
|
|
63
|
+
coneColor: {
|
|
64
|
+
value: [number, number, number];
|
|
65
|
+
};
|
|
66
|
+
coneOpacity: {
|
|
67
|
+
value: number;
|
|
68
|
+
};
|
|
69
|
+
time: {
|
|
70
|
+
value: number;
|
|
71
|
+
};
|
|
72
|
+
apexPosition: {
|
|
73
|
+
value: [number, number, number];
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
export declare function createAtmosphereUniforms(color?: [number, number, number], intensity?: number): AtmosphereUniforms;
|
|
77
|
+
export declare function createStarsUniforms(pointSize?: number): StarsUniforms;
|
|
78
|
+
export declare function createVisibilityConeUniforms(color?: [number, number, number], opacity?: number): VisibilityConeUniforms;
|