import { OrbitalElements, GroundStation } from '../types'; export type ViewMode = "solar-system" | "earth-orbit" | "moon" | "mars" | "custom"; export type CameraMode = "free" | "follow" | "orbit" | "cinematic"; export type ObjectCategory = "planet" | "moon" | "satellite" | "debris" | "station" | "asteroid" | "comet" | "groundStation" | "constellation"; export interface SpaceObject { /** Unique identifier */ id: string; /** Display name */ name: string; /** Object category */ category: ObjectCategory; /** NORAD catalog ID (for tracked objects) */ noradId?: number; /** International designator */ intlDesignator?: string; /** Position in ECI coordinates (km) */ position: Vector3D; /** Velocity in ECI coordinates (km/s) */ velocity?: Vector3D; /** Visual radius for rendering (km) */ visualRadius: number; /** Color override */ color?: string; /** Additional metadata */ metadata?: Record; } export interface Satellite extends SpaceObject { category: "satellite"; /** Two-Line Element set */ tle?: TLEData; /** Orbital elements */ orbitalElements?: OrbitalElements; /** Operator/owner */ operator?: string; /** Launch date */ launchDate?: string; /** Operational status */ status?: "operational" | "inactive" | "decaying" | "unknown"; /** Constellation membership */ constellation?: string; } export interface Debris extends SpaceObject { category: "debris"; /** Radar cross-section (m²) */ rcs?: number; /** Source event (fragmentation, collision, etc.) */ sourceEvent?: string; /** Estimated size category */ sizeCategory?: "small" | "medium" | "large"; } export interface SpaceStation extends SpaceObject { category: "station"; /** Station type */ stationType?: "iss" | "tiangong" | "commercial" | "other"; /** Current crew count */ crewCount?: number; /** Docked vehicles */ dockedVehicles?: string[]; } export interface Asteroid extends SpaceObject { category: "asteroid"; /** Spectral type */ spectralType?: string; /** Absolute magnitude */ absoluteMagnitude?: number; /** Estimated diameter (km) */ diameter?: number; /** Is potentially hazardous */ isPHA?: boolean; /** Close approach data */ closeApproach?: CloseApproachData; } export interface TLEData { line1: string; line2: string; epoch: Date; /** Mean motion (revolutions/day) */ meanMotion: number; /** Eccentricity */ eccentricity: number; /** Inclination (degrees) */ inclination: number; /** RAAN (degrees) */ raan: number; /** Argument of perigee (degrees) */ argOfPerigee: number; /** Mean anomaly (degrees) */ meanAnomaly: number; /** B* drag term */ bstar: number; } /** * Legacy visibility cone (ground-station based) * @deprecated Use SatelliteCoverage for realistic satellite-to-ground cones */ export interface VisibilityCone { /** Ground station or region ID */ id: string; /** Center position (lat, lon) */ center: { latitude: number; longitude: number; }; /** Minimum elevation angle (degrees) */ minElevation: number; /** Cone color */ color?: string; /** Cone opacity */ opacity?: number; /** Label text */ label?: string; } /** * Satellite coverage/sensor visualization * * This is a VISUALIZATION type - all geometry data comes from Zendir SDK. * The SDK computes the actual coverage; this component just renders it. * * ## SDK Compatibility * * The `footprintPolygon` should come from Zendir SDK's sensor/coverage calculations. * You can provide just the corner vertices (e.g., 4 points for a rectangular FOV) * and the component will automatically interpolate along great circles to create * a properly curved footprint that follows the Earth's spherical surface. * * Example SDK integration: * ```typescript * const coverage = await zendirClient.getSensorCoverage(satelliteId, sensorId); * // coverage.footprintPolygon contains the boundary vertices * ``` * * ## Rendering Approach * * Uses spherical linear interpolation (SLERP) to subdivide polygon edges, * ensuring the rendered coverage follows the sphere's curvature rather than * cutting through it as a flat plane would. */ export interface SatelliteCoverage { /** Unique coverage ID */ id: string; /** Satellite ID this coverage belongs to */ satelliteId: string; /** Sensor/instrument name */ sensorName?: string; /** * Satellite position in scene coordinates (x, y, z) * If not provided, will look up from satelliteId in scene */ satellitePosition?: { x: number; y: number; z: number; }; /** * Nadir/boresight point on Earth surface (lat, lon) * This is where the sensor center points (from SDK) */ nadirPoint?: { latitude: number; longitude: number; }; /** * Footprint polygon corner vertices (lat, lon) - the coverage boundary on Earth * * Computed by Zendir SDK based on sensor FOV, pointing, and satellite position. * Only corner points are needed (e.g., 4 points for rectangular coverage). * The UI automatically interpolates along great circles for spherical accuracy. * * For best results, provide vertices in clockwise or counter-clockwise order. */ footprintPolygon?: Array<{ latitude: number; longitude: number; }>; /** * Cone geometry (alternative to footprint polygon) * Half-angle of sensor field of view in degrees * Used to render a simple circular cone if no footprint polygon provided */ halfAngle?: number; /** Cone/footprint color */ color?: string; /** Opacity (0-1) */ opacity?: number; /** Show nadir line from satellite to ground */ showNadirLine?: boolean; /** Show filled footprint area */ showFootprint?: boolean; /** Show cone beam from satellite */ showCone?: boolean; /** Coverage target/region name (for tooltip) */ targetName?: string; /** Overpass time string (from SDK, e.g., "0.01:06") */ overpassTime?: string; /** Is currently active/in view */ isActive?: boolean; } export interface CoverageRegion { /** Region identifier */ id: string; /** Region name */ name: string; /** Polygon vertices (lat, lon pairs) */ polygon?: Array<{ latitude: number; longitude: number; }>; /** Or circular region */ center?: { latitude: number; longitude: number; }; radius?: number; /** Coverage quality/value */ value?: number; /** Color */ color?: string; } export interface OverpassInfo { /** Region/station ID */ targetId: string; /** Target name */ targetName: string; /** Time until next overpass (seconds) */ timeToOverpass: number; /** Overpass duration (seconds) */ duration: number; /** Maximum elevation during pass */ maxElevation?: number; } export interface CoverageHexGrid { /** Grid resolution (H3 resolution 0-15) */ resolution: number; /** Hexagon data */ hexagons: Array<{ /** H3 index or center coordinates */ id: string; /** Coverage value (0-1) */ value: number; /** Center lat/lon */ center: { latitude: number; longitude: number; }; }>; /** Color scale */ colorScale?: { min: string; max: string; }; } export interface CoverageCell { /** Cell identifier */ id: string; /** Center latitude */ latitude: number; /** Center longitude */ longitude: number; /** Coverage value (0-1, used for heatmap color) */ value: number; /** Custom color override */ color?: string; } export interface OrbitDesignArc { /** Arc identifier */ id: string; /** Orbital altitude (km) */ radius: number; /** Start angle (radians) */ startAngle: number; /** End angle (radians) */ endAngle: number; /** Inclination (degrees) */ inclination?: number; /** Arc color */ color?: string; /** Number of segments */ segments?: number; /** Arc label */ label?: string; } export interface OrbitPath { /** Object ID */ objectId: string; /** Array of position points */ points: Vector3D[]; /** Time span (seconds) */ timeSpan: number; /** Is future prediction */ isFuture?: boolean; /** Orbit color */ color?: string; } export interface ManeuverNode { /** Maneuver ID */ id: string; /** Execution time */ time: Date; /** Delta-V vector (km/s) */ deltaV: Vector3D; /** Maneuver type */ type?: "prograde" | "retrograde" | "normal" | "antinormal" | "radial" | "antiradial"; /** Planned/executed */ status?: "planned" | "executed"; } export interface CloseApproachData { /** Time of closest approach */ time: Date; /** Distance (km) */ distance: number; /** Relative velocity (km/s) */ relativeVelocity: number; /** Target body */ body?: string; } export interface TimeState { /** Current simulation time */ currentTime: Date; /** Time scale (1 = realtime, 60 = 1min/sec, etc.) */ timeScale: number; /** Is playing */ isPlaying: boolean; /** Reference epoch */ epoch?: Date; } export type ToolType = "select" | "measure" | "orbit-designer" | "coverage-analysis" | "conjunction-warning"; export interface ToolState { activeTool: ToolType; measurementPoints?: Vector3D[]; orbitDesignerState?: { inclination: number; altitude: number; eccentricity: number; }; } export interface LayerVisibility { planets: boolean; moons: boolean; satellites: boolean; debris: boolean; stations: boolean; asteroids: boolean; groundStations: boolean; orbits: boolean; labels: boolean; constellations: boolean; coverage: boolean; atmosphere: boolean; stars: boolean; grid: boolean; terminator: boolean; } export interface SelectionState { /** Selected object ID */ selectedId: string | null; /** Selected object data */ selectedObject: SpaceObject | null; /** Hovered object ID */ hoveredId: string | null; /** Multi-selection IDs */ multiSelect?: string[]; } export interface CameraState { /** Camera position (km from origin) */ position: Vector3D; /** Look-at target (km from origin) */ target: Vector3D; /** Up vector */ up: Vector3D; /** Field of view (degrees) */ fov: number; /** Near clipping plane */ near: number; /** Far clipping plane */ far: number; } export interface SceneConfig { /** Earth radius in scene units */ earthRadius: number; /** Scale factor (km to scene units) */ scaleFactor: number; /** Maximum render distance */ maxDistance: number; /** LOD thresholds */ lodThresholds: { high: number; medium: number; low: number; }; } export interface ZenSpace3DCallbacks { /** Object selection changed */ onSelect?: (object: SpaceObject | null) => void; /** Object hovered */ onHover?: (object: SpaceObject | null) => void; /** Object double-clicked */ onDoubleClick?: (object: SpaceObject) => void; /** Camera focused on object (flyTo completed) */ onFocus?: (object: SpaceObject | { id: string; }) => void; /** Time changed */ onTimeChange?: (time: Date) => void; /** View/camera changed */ onViewChange?: (state: CameraState) => void; /** Measurement completed */ onMeasure?: (distance: number, from: Vector3D, to: Vector3D) => void; /** Tool action */ onToolAction?: (tool: ToolType, data: unknown) => void; } export interface ZenSpace3DProps { /** Satellite objects */ satellites?: Satellite[]; /** Debris objects */ debris?: Debris[]; /** Space stations */ stations?: SpaceStation[]; /** Ground stations */ groundStations?: GroundStation[]; /** Asteroids (for Solar System view) */ asteroids?: Asteroid[]; /** Custom space objects */ customObjects?: SpaceObject[]; /** Initial view mode */ view?: ViewMode; /** Camera mode */ cameraMode?: CameraMode; /** Focused object ID */ focusedObjectId?: string; /** Initial camera state override */ initialCamera?: Partial; /** Initial simulation time */ initialTime?: Date; /** Time scale (1 = realtime) */ timeScale?: number; /** Auto-play on mount */ autoPlay?: boolean; /** * Reference time used to convert ECI / J2000 positions into the * Earth-Fixed (ECEF) frame Cesium renders. Should be the **simulation * clock as a real UTC Date** (sim epoch + sim seconds) so the * sub-satellite point on Earth lines up with the actual ground track. * * If omitted, the Cesium backend falls back to wall-clock now — * geometry stays self-consistent but the ground track will drift from * the engine's truth as Earth rotates. */ referenceTime?: Date; /** * Sun direction vector for lighting and atmosphere effects * Typically from Zendir SDK sun position calculation * @example { x: 1, y: 0.3, z: 0.5 } // normalized direction to sun */ sunDirection?: { x: number; y: number; z: number; }; /** * Planet positions for solar system view (from Zendir SDK) * Keys are planet IDs, values are positions */ planetPositions?: Record; /** Legacy visibility cones (region-based) */ visibilityCones?: VisibilityCone[]; /** Satellite coverage cones (realistic satellite-to-ground) - Zendir SDK compatible */ satelliteCoverages?: SatelliteCoverage[]; /** Coverage regions */ coverageRegions?: CoverageRegion[]; /** Coverage hex grid */ coverageHexGrid?: CoverageHexGrid; /** Overpass information */ overpasses?: OverpassInfo[]; /** Orbit paths to display */ orbitPaths?: OrbitPath[]; /** Orbit design arcs (colored arc segments) */ orbitDesignArcs?: OrbitDesignArc[]; /** Communication links between objects */ communicationLinks?: Array<{ id: string; fromId: string; toId: string; type: "uplink" | "downlink" | "crosslink" | "relay"; status: "active" | "idle" | "blocked"; color?: string; bandwidth?: number; latency?: number; signalStrength?: number; }>; /** Show XYZ axis helper */ showAxisHelper?: boolean; /** Maneuver nodes */ maneuverNodes?: ManeuverNode[]; /** * Render-flag layers — affect HOW objects are drawn. * `labels` — name labels next to satellite / GS markers (default off) * `coverage` — sensor footprint ellipses + cones (default off) * `orbits` — historical orbit polylines (default on) */ layers?: Partial; /** * Object-group visibility — toggle WHOLE categories on/off without * unmounting the viewer. Defaults to "everything visible". Drives the * upcoming `` — also usable directly for headless * apps that want pre-set visibility. */ visibility?: { spacecraft?: boolean; groundStations?: boolean; celestialBodies?: boolean; }; /** Show controls panel */ showControls?: boolean; /** Show timeline */ showTimeline?: boolean; /** Show tools panel */ showTools?: boolean; /** Show info panel on selection */ showInfoPanel?: boolean; /** Show legend */ showLegend?: boolean; /** Show stats (FPS, object count) */ showStats?: boolean; /** Available tools */ tools?: ToolType[]; /** Canvas width */ width?: number | string; /** Canvas height */ height?: number | string; /** Theme override */ theme?: "dark" | "light" | "purple-hue"; /** Event callbacks */ callbacks?: ZenSpace3DCallbacks; /** Maximum objects to render (for performance) */ maxObjects?: number; /** Enable post-processing effects */ enablePostProcessing?: boolean; /** Pixel ratio limit */ maxPixelRatio?: number; /** MCP context for tool integration */ mcpContext?: unknown; /** Custom scene configuration */ sceneConfig?: Partial; /** Custom CSS class */ className?: string; /** Custom inline styles */ style?: React.CSSProperties; } export interface ZenSpace3DHandle { /** Focus camera on object (legacy alias for flyTo) */ focusOn: (objectId: string, options?: { zoom?: number; animate?: boolean; }) => void; /** * Fly camera to an object with smooth animation * @param objectId - ID of target object (satellite, station, planet, etc.) * @param options.animate - Whether to animate the transition (default: true) * @param options.distance - Override viewing distance * @param options.offset - Custom camera offset from target */ flyTo: (objectId: string, options?: { animate?: boolean; distance?: number; offset?: { x: number; y: number; z: number; }; }) => void; /** Set view mode */ setView: (mode: ViewMode) => void; /** Set time */ setTime: (time: Date) => void; /** Set time scale */ setTimeScale: (scale: number) => void; /** Play/pause */ togglePlay: () => void; /** Set layer visibility */ setLayerVisibility: (layer: keyof LayerVisibility, visible: boolean) => void; /** Get current camera state */ getCameraState: () => CameraState; /** Set camera state */ setCameraState: (state: Partial) => void; /** Export screenshot */ exportImage: (format?: "png" | "jpeg") => string; /** Export 3D scene */ exportScene: (format?: "glb" | "gltf") => Blob; /** Get visible objects */ getVisibleObjects: () => SpaceObject[]; /** Find objects by query */ findObjects: (query: string) => SpaceObject[]; /** Add object dynamically */ addObject: (object: SpaceObject) => void; /** Remove object dynamically */ removeObject: (objectId: string) => void; /** Update object */ updateObject: (objectId: string, updates: Partial) => void; /** Measure distance between two points/objects */ measureDistance: (from: string | Vector3D, to: string | Vector3D) => number; } export interface Vector3D { x: number; y: number; z: number; } export interface LatLonAlt { latitude: number; longitude: number; altitude: number; } export interface SphericalCoords { radius: number; theta: number; phi: number; } export interface SceneObject { id: string; mesh: unknown; data: SpaceObject; lod: "high" | "medium" | "low" | "point"; visible: boolean; lastUpdate: number; } export interface OrbitLineObject { id: string; line: unknown; objectId: string; points: Vector3D[]; } export interface LabelObject { id: string; sprite: unknown; text: string; objectId: string; }