Files
space-game/apps/viewer/src/viewerSystemLayer.ts

69 lines
2.1 KiB
TypeScript

import * as THREE from "three";
import type {
CelestialVisual,
ClaimVisual,
ConstructionSiteVisual,
NodeVisual,
PlanetVisual,
Selectable,
ShipVisual,
StructureVisual,
} from "./viewerTypes";
/**
* System rendering layer.
* Scene coordinate unit: km * DISPLAY_UNITS_PER_KILOMETER * ACTIVE_SYSTEM_DETAIL_SCALE.
* Camera far plane covers a solar system.
* Only the active system's objects are visible; inactive system objects are hidden in place.
*/
export class SystemLayer {
readonly scene = new THREE.Scene();
readonly camera = new THREE.PerspectiveCamera(50, 1, 0.000005, 300000);
readonly celestialGroup = new THREE.Group();
readonly nodeGroup = new THREE.Group();
readonly stationGroup = new THREE.Group();
readonly claimGroup = new THREE.Group();
readonly constructionSiteGroup = new THREE.Group();
readonly shipGroup = new THREE.Group();
readonly selectableTargets = new Map<THREE.Object3D, Selectable>();
readonly planetVisuals: PlanetVisual[] = [];
readonly shipVisuals = new Map<string, ShipVisual>();
readonly celestialVisuals = new Map<string, CelestialVisual>();
readonly nodeVisuals = new Map<string, NodeVisual>();
readonly stationVisuals = new Map<string, StructureVisual>();
readonly claimVisuals = new Map<string, ClaimVisual>();
readonly constructionSiteVisuals = new Map<string, ConstructionSiteVisual>();
constructor() {
this.scene.add(new THREE.AmbientLight(0x90a6c0, 0.55));
const keyLight = new THREE.DirectionalLight(0xdcecff, 1.3);
keyLight.position.set(1000, 1200, 800);
this.scene.add(keyLight);
this.scene.add(
this.celestialGroup,
this.nodeGroup,
this.stationGroup,
this.claimGroup,
this.constructionSiteGroup,
this.shipGroup,
);
}
updateCamera(systemFocus: THREE.Vector3, orbitOffset: THREE.Vector3) {
this.camera.position.copy(systemFocus).add(orbitOffset);
this.camera.lookAt(systemFocus);
}
onResize(aspect: number) {
this.camera.aspect = aspect;
this.camera.updateProjectionMatrix();
}
render(renderer: THREE.WebGLRenderer) {
renderer.render(this.scene, this.camera);
}
}