mirror of
https://github.com/Krafpy/KSP-MGA-Planner.git
synced 2026-01-07 02:04:57 -08:00
The circularization step is now taken in account, with custom altitude. Double click offset on navigators other than Chrome has been fixed.
80 lines
3.0 KiB
JavaScript
80 lines
3.0 KiB
JavaScript
export class CameraController extends THREE.OrbitControls {
|
|
constructor(camera, canvas, system, config) {
|
|
super(camera, canvas);
|
|
this.camera = camera;
|
|
this.canvas = canvas;
|
|
this.system = system;
|
|
this.config = config;
|
|
this._lastTargetPos = new THREE.Vector3();
|
|
this.camera.position.set(0, 0, this.config.camera.startDist);
|
|
this.maxDistance = this.config.camera.maxDist;
|
|
this.enableDamping = true;
|
|
this.dampingFactor = this.config.camera.dampingFactor;
|
|
this.rotateSpeed = this.config.camera.rotateSpeed;
|
|
this.enablePan = false;
|
|
canvas.addEventListener('dblclick', e => this.onDoubleClick(e));
|
|
canvas.onselectstart = () => false;
|
|
canvas.onmousedown = e => {
|
|
if (e.button == 1) {
|
|
e.preventDefault();
|
|
}
|
|
};
|
|
}
|
|
get targetBody() {
|
|
return this._targetBody;
|
|
}
|
|
set targetBody(body) {
|
|
const { scale } = this.config.rendering;
|
|
const { minDistRadii } = this.config.camera;
|
|
this.minDistance = body.radius * scale * minDistRadii;
|
|
this._targetBody = body;
|
|
this.centerOnTarget();
|
|
}
|
|
centerOnTarget() {
|
|
const center = new THREE.Vector3();
|
|
const objects = this.system.objectsOfBody(this._targetBody.id);
|
|
objects.getWorldPosition(center);
|
|
const rot = this.camera.rotation.clone();
|
|
const disp = center.clone().sub(this._lastTargetPos);
|
|
this.target.copy(center);
|
|
this._lastTargetPos.copy(center);
|
|
this.camera.rotation.copy(rot);
|
|
this.camera.position.add(disp);
|
|
}
|
|
onDoubleClick(event) {
|
|
const rect = this.canvas.getBoundingClientRect();
|
|
const w2 = this.canvas.clientWidth * 0.5;
|
|
const h2 = this.canvas.clientHeight * 0.5;
|
|
const mouse = new THREE.Vector2(event.clientX - rect.left - w2, event.clientY - rect.top - h2);
|
|
mouse.y *= -1;
|
|
let minDst = Infinity;
|
|
let tgBody = this.system.sun;
|
|
const { mouseFocusDst } = this.config.solarSystem;
|
|
for (const body of this.system.bodies) {
|
|
const objects = this.system.objectsOfBody(body.id);
|
|
const screenPos = this.toScreenPosition(objects);
|
|
const dst = screenPos.distanceTo(mouse);
|
|
if (objects.visible && dst < mouseFocusDst) {
|
|
if (dst < minDst) {
|
|
minDst = dst;
|
|
tgBody = body;
|
|
}
|
|
}
|
|
}
|
|
if (minDst >= 0)
|
|
this.targetBody = tgBody;
|
|
}
|
|
toScreenPosition(obj) {
|
|
const vec = new THREE.Vector3();
|
|
const w2 = 0.5 * this.canvas.clientWidth;
|
|
const h2 = 0.5 * this.canvas.clientHeight;
|
|
this.camera.updateMatrixWorld();
|
|
obj.updateMatrixWorld();
|
|
vec.setFromMatrixPosition(obj.matrixWorld);
|
|
vec.project(this.camera);
|
|
vec.x = (vec.x * w2);
|
|
vec.y = (vec.y * h2);
|
|
return new THREE.Vector2(vec.x, vec.y);
|
|
}
|
|
}
|