Files
KSP-MGA-Planner/dist/main/objects/camera.js
2022-10-08 14:53:15 +02:00

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, this.config.camera.startDist, 0);
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);
}
}