Files
KSP-MGA-Planner/dist/main/objects/system.js
Krafpy 8da935b047 2D physics fix and error handling consistency
- Reimplemented 2D orbital mechanics functions in physics-2d.ts
and encaspulated inside a `Physics2D` namespace.
- Deleted physics.ts and moved the required functions into physics-3d.ts
Further cleaning and reimplemntation will be done on the physics-3d.ts
content.
- Forced consistency on error handling : every raised error throws
an `Error` object.
- Commented sections relative to 2D physics and sequence generation.
2021-12-19 17:19:30 +01: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 new Error(`No body with name ${name}`);
}
bodyFromId(id) {
if (id == 0) {
return this.sun;
}
else {
const body = this._orbiting.get(id);
if (!body)
throw new Error(`No body with id ${id}`);
return body;
}
}
objectsOfBody(id) {
const object = this._objects.get(id);
if (!object)
throw new Error(`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;
}
}
}
}