|
import type { Camera } from "../cameras/Camera"; |
|
import { EventDispatcher } from "../core/EventDispatcher"; |
|
import { Matrix3 } from "../math/Matrix3"; |
|
import { Quaternion } from "../math/Quaternion"; |
|
import { Vector3 } from "../math/Vector3"; |
|
|
|
class OrbitControls extends EventDispatcher { |
|
camera: Camera; |
|
domElement: HTMLElement; |
|
|
|
target: Vector3 = new Vector3(); |
|
alpha: number = 0; |
|
beta: number = 0; |
|
radius: number = 5; |
|
|
|
desiredTarget: Vector3; |
|
desiredAlpha: number; |
|
desiredBeta: number; |
|
desiredRadius: number; |
|
|
|
minBeta: number = (5 * Math.PI) / 180; |
|
maxBeta: number = (85 * Math.PI) / 180; |
|
minZoom: number = 0.1; |
|
maxZoom: number = 30; |
|
orbitSpeed: number = 1; |
|
panSpeed: number = 1; |
|
zoomSpeed: number = 1; |
|
dampening: number = 10; |
|
|
|
constructor(camera: Camera, domElement: HTMLElement) { |
|
super(); |
|
|
|
this.camera = camera; |
|
this.domElement = domElement; |
|
|
|
this.desiredTarget = this.target.clone(); |
|
this.desiredAlpha = this.alpha; |
|
this.desiredBeta = this.beta; |
|
this.desiredRadius = this.radius; |
|
} |
|
|
|
lerp(a: number, b: number, t: number) { |
|
return (1 - t) * a + t * b; |
|
} |
|
|
|
pan(dx: number, dy: number) { |
|
const R = this.camera.rotation.buffer; |
|
const right = new Vector3(R[0], R[3], R[6]); |
|
const up = new Vector3(R[1], R[4], R[7]); |
|
this.desiredTarget.add(right.multiply(dx)); |
|
this.desiredTarget.add(up.multiply(dy)); |
|
} |
|
|
|
update(deltaTime: number) { |
|
this.alpha = this.lerp(this.alpha, this.desiredAlpha, this.dampening * deltaTime); |
|
this.beta = this.lerp(this.beta, this.desiredBeta, this.dampening * deltaTime); |
|
this.radius = this.lerp(this.radius, this.desiredRadius, this.dampening * deltaTime); |
|
this.target = this.target.lerp(this.desiredTarget, this.dampening * deltaTime); |
|
|
|
const x = this.target.x + this.radius * Math.sin(this.alpha) * Math.cos(this.beta); |
|
const y = this.target.y - this.radius * Math.sin(this.beta); |
|
const z = this.target.z - this.radius * Math.cos(this.alpha) * Math.cos(this.beta); |
|
this.camera.position.set(x, y, z); |
|
|
|
const direction = this.target.clone().subtract(this.camera.position).normalize(); |
|
const rx = Math.asin(-direction.y); |
|
const ry = Math.atan2(direction.x, direction.z); |
|
this.camera.rotation = Matrix3.RotationFromEuler(new Vector3(rx, ry, 0)); |
|
} |
|
} |
|
|
|
export { OrbitControls }; |
|
|