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

@@ -3,6 +3,7 @@ import { MOON_RENDER_SCALE } from "./viewerConstants";
import type {
ShipSnapshot,
PlanetSnapshot,
MoonSnapshot,
Vector3Dto,
WorldSnapshot,
} from "./contracts";
@@ -176,7 +177,7 @@ export function computePlanetLocalPosition(planet: PlanetSnapshot, timeSeconds:
const eccentricAnomaly = meanAnomaly
+ (eccentricity * Math.sin(meanAnomaly))
+ (0.5 * eccentricity * eccentricity * Math.sin(2 * meanAnomaly));
const semiMajorAxis = planet.orbitRadius;
const semiMajorAxis = planet.orbitRadius * KILOMETERS_PER_AU;
const semiMinorAxis = semiMajorAxis * Math.sqrt(Math.max(1 - (eccentricity * eccentricity), 0.05));
const local = new THREE.Vector3(
semiMajorAxis * (Math.cos(eccentricAnomaly) - eccentricity),
@@ -190,47 +191,24 @@ export function computePlanetLocalPosition(planet: PlanetSnapshot, timeSeconds:
return local;
}
export function computeMoonOrbitRadius(planet: PlanetSnapshot, moonIndex: number, seed: number): number {
const spacing = planet.size * 1.4;
const variance = hashUnit(seed, `${planet.label}:${moonIndex}:radius`) * planet.size * 0.9;
return (planet.size * 1.8) + (moonIndex * spacing) + variance;
}
export function computeMoonOrbitSpeed(planet: PlanetSnapshot, moonIndex: number, seed: number): number {
const radius = computeMoonOrbitRadius(planet, moonIndex, seed);
return 0.9 / Math.sqrt(Math.max(radius, 1)) + (moonIndex * 0.003);
}
export function computeMoonLocalPosition(planet: PlanetSnapshot, moonIndex: number, timeSeconds: number, seed: number): THREE.Vector3 {
const orbitRadius = computeMoonOrbitRadius(planet, moonIndex, seed);
const speed = computeMoonOrbitSpeed(planet, moonIndex, seed);
const phase = hashUnit(seed, `${planet.label}:${moonIndex}:phase`) * Math.PI * 2;
const inclination = THREE.MathUtils.degToRad((hashUnit(seed, `${planet.label}:${moonIndex}:inclination`) - 0.5) * 28);
const node = THREE.MathUtils.degToRad(hashUnit(seed, `${planet.label}:${moonIndex}:node`) * 360);
const angle = phase + (timeSeconds * speed);
export function computeMoonLocalPosition(moon: MoonSnapshot, timeSeconds: number): THREE.Vector3 {
const angle = THREE.MathUtils.degToRad(moon.orbitPhaseAtEpoch) + (timeSeconds * moon.orbitSpeed);
const local = new THREE.Vector3(
Math.cos(angle) * orbitRadius,
Math.cos(angle) * moon.orbitRadius,
0,
Math.sin(angle) * orbitRadius,
Math.sin(angle) * moon.orbitRadius,
);
local.applyAxisAngle(new THREE.Vector3(1, 0, 0), inclination);
local.applyAxisAngle(new THREE.Vector3(0, 1, 0), node);
local.applyAxisAngle(new THREE.Vector3(1, 0, 0), THREE.MathUtils.degToRad(moon.orbitInclination));
local.applyAxisAngle(new THREE.Vector3(0, 1, 0), THREE.MathUtils.degToRad(moon.orbitLongitudeOfAscendingNode));
return local;
}
export function computeMoonSize(planet: PlanetSnapshot, moonIndex: number, seed: number): number {
const base = Math.max(2.2, planet.size * 0.11);
const variance = hashUnit(seed, `${planet.label}:${moonIndex}:size`) * Math.max(planet.size * 0.16, 2.5);
return Math.min(base + variance, planet.size * 0.42);
}
export function celestialRenderRadius(size: number, scale: number, minRadius: number, exponent = 1): number {
return Math.max(minRadius, Math.pow(Math.max(size, 0.1), exponent) * scale);
}
export function computeMoonRenderRadius(planet: PlanetSnapshot, moonIndex: number, seed: number): number {
return celestialRenderRadius(computeMoonSize(planet, moonIndex, seed), 0.00011, 0.025, 0.62);
export function computeMoonRenderRadius(moon: MoonSnapshot): number {
return celestialRenderRadius(moon.size, 0.00011, 0.025, 0.62);
}
export function starHaloOpacity(starKind: string): number {
@@ -251,7 +229,6 @@ export function resolveOrbitalAnchorPosition(
systemId: string,
anchor: OrbitalAnchor,
timeSeconds: number,
seed: number,
): THREE.Vector3 {
if (!world || anchor.kind === "star") {
return new THREE.Vector3();
@@ -268,5 +245,6 @@ export function resolveOrbitalAnchorPosition(
return planetPosition;
}
return planetPosition.add(computeMoonLocalPosition(planet, anchor.moonIndex, timeSeconds, seed));
const moon = planet.moons[anchor.moonIndex];
return planetPosition.add(computeMoonLocalPosition(moon, timeSeconds));
}