mirror of
https://github.com/Krafpy/KSP-MGA-Planner.git
synced 2025-12-30 06:31:18 -08:00
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, 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);
|
|
}
|
|
}
|