mirror of
https://github.com/Krafpy/KSP-MGA-Planner.git
synced 2025-12-05 20:40:13 -08:00
Modified the file structure to have the `index.html` at the root of the repository. Needed for Github Pages.
119 lines
4.7 KiB
JavaScript
119 lines
4.7 KiB
JavaScript
import { OrbitingBody, CelestialBody } from "./body.js";
|
|
import { createLine, createOrbitPoints, createSprite } from "../utilities/geometry.js";
|
|
export class SolarSystem {
|
|
constructor(sun, bodies, config) {
|
|
this.config = config;
|
|
this._orbiting = new Map();
|
|
this._objects = new Map();
|
|
this._orbits = new Map();
|
|
this.sun = new CelestialBody(sun);
|
|
for (const data of bodies) {
|
|
const { orbiting } = data;
|
|
const attractor = orbiting == 0 ? this.sun : this._orbiting.get(orbiting);
|
|
const body = new OrbitingBody(data, attractor, this.config.orbit);
|
|
this._orbiting.set(body.id, body);
|
|
attractor.orbiters.push(body);
|
|
}
|
|
}
|
|
get orbiting() {
|
|
return [...this._orbiting.values()];
|
|
}
|
|
get bodies() {
|
|
return [this.sun, ...this.orbiting];
|
|
}
|
|
get data() {
|
|
const data = [];
|
|
for (const body of this.bodies) {
|
|
data.push(body.data);
|
|
}
|
|
return data;
|
|
}
|
|
bodyFromName(name) {
|
|
for (const body of [this.sun, ...this.orbiting]) {
|
|
if (body.name == name)
|
|
return body;
|
|
}
|
|
throw `No body with name ${name}`;
|
|
}
|
|
bodyFromId(id) {
|
|
if (id == 0) {
|
|
return this.sun;
|
|
}
|
|
else {
|
|
const body = this._orbiting.get(id);
|
|
if (!body)
|
|
throw `No body with id ${id}`;
|
|
return body;
|
|
}
|
|
}
|
|
objectsOfBody(id) {
|
|
const object = this._objects.get(id);
|
|
if (!object)
|
|
throw `No 3D objects from body of id ${id}`;
|
|
return object;
|
|
}
|
|
fillSceneObjects(scene, canvas) {
|
|
const textureLoader = new THREE.TextureLoader();
|
|
return new Promise((resolve, _) => {
|
|
const loaded = (texture) => {
|
|
const material = new THREE.SpriteMaterial({
|
|
map: texture
|
|
});
|
|
const { scale } = this.config.rendering;
|
|
const { satSampPoints, planetSampPoints, lineWidth } = this.config.orbit;
|
|
const { planetFarSize, satFarSize } = this.config.solarSystem;
|
|
const sunSprite = createSprite(material, this.sun.color, true, scale * this.sun.radius * 2);
|
|
const sunGroup = new THREE.Group();
|
|
sunGroup.add(sunSprite);
|
|
this._objects.set(0, sunGroup);
|
|
for (const body of this.orbiting) {
|
|
const { radius, orbit, color, attractor } = body;
|
|
const parentGroup = this._objects.get(attractor.id);
|
|
const bodyGroup = new THREE.Group();
|
|
const samplePts = attractor.id == 0 ? planetSampPoints : satSampPoints;
|
|
const spriteSize = attractor.id == 0 ? planetFarSize : satFarSize;
|
|
const orbitPoints = createOrbitPoints(orbit, samplePts, scale);
|
|
const ellipse = createLine(orbitPoints, canvas, {
|
|
color: color,
|
|
linewidth: lineWidth,
|
|
});
|
|
parentGroup.add(ellipse);
|
|
this._orbits.set(body.id, ellipse);
|
|
bodyGroup.add(createSprite(material, color, true, scale * radius * 2));
|
|
bodyGroup.add(createSprite(material, color, false, spriteSize));
|
|
parentGroup.add(bodyGroup);
|
|
this._objects.set(body.id, bodyGroup);
|
|
}
|
|
scene.add(sunGroup);
|
|
resolve(true);
|
|
};
|
|
textureLoader.load("sprites/circle-512.png", loaded);
|
|
});
|
|
}
|
|
set date(date) {
|
|
for (const body of this.orbiting) {
|
|
const group = this._objects.get(body.id);
|
|
const pos = body.positionAtDate(date).multiplyScalar(this.config.rendering.scale);
|
|
group.position.copy(pos);
|
|
}
|
|
}
|
|
updateSatellitesDisplay(camController) {
|
|
for (const body of this.orbiting) {
|
|
if (body.attractor.id != 0) {
|
|
const { satDispRadii } = this.config.solarSystem;
|
|
const { scale } = this.config.rendering;
|
|
const camPos = camController.camera.position;
|
|
const objPos = new THREE.Vector3();
|
|
const group = this._objects.get(body.id);
|
|
group.getWorldPosition(objPos);
|
|
const dstToCam = objPos.distanceTo(camPos);
|
|
const thresh = scale * satDispRadii * body.orbit.semiMajorAxis;
|
|
const visible = dstToCam < thresh;
|
|
const ellipse = this._orbits.get(body.id);
|
|
ellipse.visible = visible;
|
|
group.visible = visible;
|
|
}
|
|
}
|
|
}
|
|
}
|