feat: improved visualisation and x4 data import
This commit is contained in:
@@ -2,6 +2,14 @@ import * as THREE from "three";
|
||||
import { ACTIVE_SYSTEM_DETAIL_SCALE, PROJECTED_GALAXY_RADIUS } from "./viewerConstants";
|
||||
import { computeMoonLocalPosition, computePlanetLocalPosition, currentWorldTimeSeconds, scaleLocalVector } from "./viewerMath";
|
||||
import type { PlanetVisual, ShipVisual, SystemVisual, WorldState } from "./viewerTypes";
|
||||
import { rawObject } from "./viewerScenePrimitives";
|
||||
|
||||
const MIN_ICON_PIXELS = 25;
|
||||
const MAX_ICON_PIXELS = 50;
|
||||
|
||||
export function iconWorldScale(distToCamera: number, camera: THREE.PerspectiveCamera, pixels: number): number {
|
||||
return pixels * distToCamera * 2 * Math.tan((camera.fov * Math.PI / 180) / 2) / window.innerHeight;
|
||||
}
|
||||
|
||||
export function getAnimatedShipLocalPosition(visual: ShipVisual, now = performance.now()) {
|
||||
const elapsedMs = now - visual.receivedAtMs;
|
||||
@@ -26,6 +34,7 @@ export function updatePlanetPresentation(
|
||||
world: WorldState | undefined,
|
||||
worldTimeSyncMs: number,
|
||||
planetVisuals: PlanetVisual[],
|
||||
systemCamera: THREE.PerspectiveCamera,
|
||||
) {
|
||||
const nowSeconds = currentWorldTimeSeconds(world, worldTimeSyncMs);
|
||||
// In systemScene all positions use scaleLocalVector * ACTIVE_SYSTEM_DETAIL_SCALE.
|
||||
@@ -34,23 +43,44 @@ export function updatePlanetPresentation(
|
||||
const position = scaleLocalVector(computePlanetLocalPosition(visual.planet, nowSeconds))
|
||||
.multiplyScalar(ACTIVE_SYSTEM_DETAIL_SCALE);
|
||||
|
||||
visual.orbit.setScaleScalar(ACTIVE_SYSTEM_DETAIL_SCALE);
|
||||
visual.orbit.setPosition(new THREE.Vector3(0, 0, 0));
|
||||
visual.mesh.setPosition(position);
|
||||
visual.icon.setPosition(position);
|
||||
const iconWorldPos = visual.icon.getWorldPosition(new THREE.Vector3());
|
||||
const distToIcon = systemCamera.position.distanceTo(iconWorldPos);
|
||||
const t = THREE.MathUtils.clamp(distToIcon / 300, 0, 1);
|
||||
const rawScale = visual.iconBaseScale * t * Math.sqrt(t);
|
||||
const planetIconScale = THREE.MathUtils.clamp(rawScale, iconWorldScale(distToIcon, systemCamera, MIN_ICON_PIXELS), iconWorldScale(distToIcon, systemCamera, MAX_ICON_PIXELS));
|
||||
visual.icon.setScaleScalar(planetIconScale);
|
||||
if (visual.ring) {
|
||||
visual.ring.setPosition(position);
|
||||
}
|
||||
|
||||
const distToPlanet = systemCamera.position.distanceTo(position);
|
||||
const moonOrbitOpacity = THREE.MathUtils.clamp(1 - distToPlanet / 500, 0, 1) * 0.18;
|
||||
|
||||
const clusterVisible = distToPlanet < 300;
|
||||
for (const [moonIndex, moon] of visual.moons.entries()) {
|
||||
moon.orbit.setPosition(position);
|
||||
moon.orbit.setScaleScalar(ACTIVE_SYSTEM_DETAIL_SCALE);
|
||||
moon.mesh.setPosition(
|
||||
position.clone().add(
|
||||
scaleLocalVector(computeMoonLocalPosition(visual.planet, moonIndex, nowSeconds, world?.seed ?? 1))
|
||||
.multiplyScalar(ACTIVE_SYSTEM_DETAIL_SCALE),
|
||||
),
|
||||
const moonPos = position.clone().add(
|
||||
scaleLocalVector(computeMoonLocalPosition(visual.planet.moons[moonIndex], nowSeconds))
|
||||
.multiplyScalar(ACTIVE_SYSTEM_DETAIL_SCALE),
|
||||
);
|
||||
moon.mesh.setPosition(moonPos);
|
||||
moon.mesh.setVisible(clusterVisible);
|
||||
moon.icon.setPosition(moonPos);
|
||||
moon.icon.setVisible(clusterVisible);
|
||||
if (clusterVisible) {
|
||||
const iconWorldPos = moon.icon.getWorldPosition(new THREE.Vector3());
|
||||
const moonDist = systemCamera.position.distanceTo(iconWorldPos);
|
||||
const t = THREE.MathUtils.clamp(moonDist / 120, 0, 1);
|
||||
const rawMoonScale = moon.iconBaseScale * t * Math.sqrt(t);
|
||||
const moonIconScale = THREE.MathUtils.clamp(rawMoonScale, iconWorldScale(moonDist, systemCamera, MIN_ICON_PIXELS), iconWorldScale(moonDist, systemCamera, MAX_ICON_PIXELS));
|
||||
moon.icon.setScaleScalar(moonIconScale);
|
||||
}
|
||||
moon.orbit.setPosition(position);
|
||||
const orbitObj = rawObject(moon.orbit);
|
||||
if (orbitObj instanceof THREE.LineLoop) {
|
||||
(orbitObj.material as THREE.LineBasicMaterial).opacity = moonOrbitOpacity;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user