Files
KSP-MGA-Planner/dist/main/objects/system.js
Krafpy 824af087c1 Modified file structure.
Modified the file structure to have the `index.html` at the root
of the repository. Needed for Github Pages.
2021-08-15 21:31:25 +02:00

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;
}
}
}
}