feat: improved visualisation and x4 data import

This commit is contained in:
2026-03-18 20:58:17 -04:00
parent 358122a74a
commit f98c47a8a7
45 changed files with 32840 additions and 1482 deletions

View File

@@ -4,7 +4,6 @@ import {
DISPLAY_UNITS_PER_LIGHT_YEAR,
KILOMETERS_PER_AU,
computeMoonLocalPosition,
computeMoonSize,
computePlanetLocalPosition,
currentWorldTimeSeconds,
resolveOrbitalAnchorPosition,
@@ -16,6 +15,7 @@ import {
resolveShipHeading,
updateSystemStarPresentation,
getAnimatedShipLocalPosition,
iconWorldScale,
} from "./viewerPresentation";
import { rawObject } from "./viewerScenePrimitives";
import type {
@@ -114,7 +114,15 @@ export function updateWorldPresentation(context: WorldPresentationContext) {
visual.mesh.setPosition(context.toDisplayLocalPosition(animatedLocalPosition));
visual.icon.setPosition(rawObject(visual.mesh).position.clone());
visual.mesh.setVisible(visual.systemId === context.activeSystemId);
visual.icon.setVisible(visual.systemId === context.activeSystemId);
const iconWorldPos = visual.icon.getWorldPosition(new THREE.Vector3());
const distToIcon = context.camera.position.distanceTo(iconWorldPos);
const isNearPlanetLagrange = /-l[12]$/.test(visual.id);
const inCluster = !isNearPlanetLagrange || distToIcon < 400;
visual.icon.setVisible(visual.systemId === context.activeSystemId && inCluster);
const t = THREE.MathUtils.clamp(distToIcon / 300, 0, 1);
const rawCelestialScale = visual.iconBaseScale * t * Math.sqrt(t);
const celestialIconScale = THREE.MathUtils.clamp(rawCelestialScale, iconWorldScale(distToIcon, context.camera, 15), iconWorldScale(distToIcon, context.camera, 100));
visual.icon.setScaleScalar(celestialIconScale);
}
for (const visual of context.stationVisuals.values()) {
@@ -351,13 +359,12 @@ export function resolveOrbitalAnchor(context: WorldOrbitalContext, systemId: str
bestAnchor = { kind: "planet", planetIndex };
}
const moonCount = Math.min(planet.moonCount, 12);
for (let moonIndex = 0; moonIndex < moonCount; moonIndex += 1) {
for (const [moonIndex, moon] of planet.moons.entries()) {
const moonPosition = planetPosition
.clone()
.add(computeMoonLocalPosition(planet, moonIndex, nowSeconds, context.world.seed));
.add(computeMoonLocalPosition(moon, nowSeconds));
const moonDistance = localPosition.distanceTo(moonPosition);
const moonThreshold = Math.max(computeMoonSize(planet, moonIndex, context.world.seed) * 14, 80);
const moonThreshold = Math.max(moon.size * 14, 80);
if (moonDistance < moonThreshold && moonDistance < bestDistance) {
bestDistance = moonDistance;
bestAnchor = { kind: "moon", planetIndex, moonIndex };
@@ -417,9 +424,15 @@ export function computeCelestialLocalPositionById(
const parentInitialPosition = toThreeVector(parentCelestial.orbitalAnchor);
const relativeOffset = basePosition.clone().sub(parentInitialPosition);
const initialAngle = Math.atan2(parentInitialPosition.z, parentInitialPosition.x);
const currentAngle = Math.atan2(parentCurrentPosition.z, parentCurrentPosition.x);
const rotatedOffset = relativeOffset.applyAxisAngle(new THREE.Vector3(0, 1, 0), currentAngle - initialAngle);
const initialDir = parentInitialPosition.clone().normalize();
const currentDir = parentCurrentPosition.clone().normalize();
let rotatedOffset: THREE.Vector3;
if (initialDir.lengthSq() > 0.0001 && currentDir.lengthSq() > 0.0001) {
const quaternion = new THREE.Quaternion().setFromUnitVectors(initialDir, currentDir);
rotatedOffset = relativeOffset.clone().applyQuaternion(quaternion);
} else {
rotatedOffset = relativeOffset.clone();
}
return parentCurrentPosition.clone().add(rotatedOffset);
}
@@ -486,7 +499,7 @@ function computeStructureLocalPosition(
}
function getOrbitalAnchorPosition(context: WorldOrbitalContext, systemId: string, anchor: OrbitalAnchor, timeSeconds: number) {
return resolveOrbitalAnchorPosition(context.world, systemId, anchor, timeSeconds, context.worldSeed);
return resolveOrbitalAnchorPosition(context.world, systemId, anchor, timeSeconds);
}
function resolveStructureAnimatedLocalPosition(context: WorldOrbitalContext, visual: StructureVisual, timeSeconds: number) {