UNPKG

mapillary-js

Version:

WebGL JavaScript library for displaying street level imagery from mapillary.com

93 lines (72 loc) 2.9 kB
import * as THREE from "three"; import { InteractiveWaitingState, IRotation, IState, StateBase, TraversingState, WaitingState, } from "../../State"; import { Camera, } from "../../Geo"; export class EarthState extends StateBase { constructor(state: IState) { super(state); const viewingDirection: THREE.Vector3 = this._camera.lookat .clone() .sub(this._camera.position) .normalize(); this._camera.lookat.copy(this._camera.position); this._camera.position.z = state.camera.position.z + 20; this._camera.position.x = state.camera.position.x - 16 * viewingDirection.x; this._camera.position.y = state.camera.position.y - 16 * viewingDirection.y; this._camera.up.set(0, 0, 1); } public traverse(): StateBase { return new TraversingState(this); } public wait(): StateBase { return new WaitingState(this); } public waitInteractively(): StateBase { return new InteractiveWaitingState(this); } public dolly(delta: number): void { const camera: Camera = this._camera; const offset: THREE.Vector3 = new THREE.Vector3() .copy(camera.position) .sub(camera.lookat); const length: number = offset.length(); const scaled: number = length * Math.pow(2, -delta); const clipped: number = Math.max(1, Math.min(scaled, 1000)); offset.normalize(); offset.multiplyScalar(clipped); camera.position.copy(camera.lookat).add(offset); } public orbit(rotation: IRotation): void { const camera: Camera = this._camera; const q: THREE.Quaternion = new THREE.Quaternion().setFromUnitVectors(camera.up, new THREE.Vector3( 0, 0, 1 )); const qInverse: THREE.Quaternion = q.clone().inverse(); const offset: THREE.Vector3 = new THREE.Vector3(); offset.copy(camera.position).sub(camera.lookat); offset.applyQuaternion(q); const length: number = offset.length(); let phi: number = Math.atan2(offset.y, offset.x); phi += rotation.phi; let theta: number = Math.atan2(Math.sqrt(offset.x * offset.x + offset.y * offset.y), offset.z); theta += rotation.theta; theta = Math.max(0.1, Math.min(Math.PI - 0.1, theta)); offset.x = Math.sin(theta) * Math.cos(phi); offset.y = Math.sin(theta) * Math.sin(phi); offset.z = Math.cos(theta); offset.applyQuaternion(qInverse); camera.position.copy(camera.lookat).add(offset.multiplyScalar(length)); } public truck(direction: number[]): void { this._camera.position.add(new THREE.Vector3().fromArray(direction)); this._camera.lookat.add(new THREE.Vector3().fromArray(direction)); } public update(): void { /*noop*/ } } export default EarthState;