import { CameraControls } from "@react-three/drei"; import { useThree } from "@react-three/fiber"; import { q } from "@thorium/context/AppContext"; import { astronomicalUnitToKilometer, type Kilometer } from "@thorium/utils/unitTypes"; import CameraControlsClass from "camera-controls"; import * as React from "react"; import { Suspense, useEffect } from "react"; import { useParams } from "react-router"; import { Box3, Vector3 } from "three"; import { useExternalCameraControl } from "./CameraControls"; import Disc from "./Disc"; import { PolarGrid } from "./PolarGrid"; import { useGetStarmapStore } from "./starmapStore"; import { useSystemIds } from "./useSystemIds"; const ACTION = CameraControlsClass.ACTION; // 10% further than Neptune's orbit export const SOLAR_SYSTEM_MAX_DISTANCE: Kilometer = 4_000_000_000 * 1.1; function HabitableZone({ systemId }: { systemId: string }) { const [pluginId, solarSystemId] = useSystemIds(); const [system] = q.plugin.starmap.get.useNetRequest({ pluginId, solarSystemId: solarSystemId || systemId, }); const scaleUnit = astronomicalUnitToKilometer(1); if (!system) return null; const { habitableZoneInner, habitableZoneOuter, stars } = system; return stars.length > 0 ? ( ) : null; } export function SolarSystemMap({ systemId, skyboxKey, children, minDistance = 1, maxDistance = SOLAR_SYSTEM_MAX_DISTANCE, }: { systemId?: string; skyboxKey: string; children?: React.ReactNode; minDistance?: number; maxDistance?: number; }) { const pluginId = useParams().pluginId; const useStarmapStore = useGetStarmapStore(); const { camera } = useThree(); const controlsEnabled = useStarmapStore((s) => s.cameraControlsEnabled); const cameraView = useStarmapStore((s) => s.cameraView); const orbitControls = React.useRef(null); useEffect(() => { useStarmapStore.setState({ skyboxKey: skyboxKey || "blank" }); }, [skyboxKey, useStarmapStore]); useEffect(() => { // Set the initial camera position orbitControls.current?.setPosition(0, 50_000, 0); const max = SOLAR_SYSTEM_MAX_DISTANCE * 0.75; orbitControls.current?.setBoundary( new Box3(new Vector3(-max, -max, -max), new Vector3(max, max, max)), ); useStarmapStore.getState().setCameraControlsEnabled(true); }, [camera, useStarmapStore]); useEffect(() => { if (cameraView === "2d") { orbitControls.current?.rotatePolarTo(0, true); orbitControls.current?.rotateAzimuthTo(0, true); } }, [cameraView]); useExternalCameraControl(orbitControls); const viewingMode = useStarmapStore((store) => store.viewingMode); const isViewscreen = viewingMode === "viewscreen"; return ( {!pluginId || !systemId ? null : } {!isViewscreen && ( <> )} {children} ); }