"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const THREE = require("three"); const three_1 = require("three"); const Orbit_1 = require("./Orbit"); /** * * 相机的控制. * ->切换相机 * ->设置视口大小 * ->旋转和移动相机. * * @export * @class ViewCameraManage */ class CameraUpdate { constructor() { this.m_CameraArray = new Map(); //视口显示的高度 this.m_ViewHeight = 10; //观察的位置 this.m_Target = new THREE.Vector3(); //观察向量 this.m_Direction = new THREE.Vector3(0, 0, -1); //观察的轨道. this.m_Orbit = new Orbit_1.Orbit(); this.m_CameraArray.set(THREE.OrthographicCamera, new THREE.OrthographicCamera(-2, 2, 2, -2, -100000, 100000)); this.m_CameraArray.set(THREE.PerspectiveCamera, new THREE.PerspectiveCamera(50, 1, 0.01, 10000)); this.m_CurCamera = this.m_CameraArray.get(THREE.OrthographicCamera); this.m_Orbit.UpdateRoValue(this.m_Direction); this.UpdateUp(); this.Update(); } get Aspect() { return this.m_Width / this.m_Height; } get Camera() { return this.m_CurCamera; } get ViewHeight() { return this.m_ViewHeight; } set ViewHeight(height) { this.m_ViewHeight = THREE.Math.clamp(height, 1e-8, 1e8); } SetSize(width, height) { this.m_Width = width; this.m_Height = height; } /** * 平移相机. * * @param {THREE.Vector3} mouseMove * @memberof CameraControl */ Pan(mouseMove) { mouseMove.y *= -1; mouseMove.multiplyScalar(-this.m_ViewHeight / this.m_Height); mouseMove.applyQuaternion(this.Camera.quaternion); this.m_Target.add(mouseMove); this.Update(); } Rotate(mouseMove, target) { this.m_Orbit.RoX -= mouseMove.y * 0.003; this.m_Orbit.RoZ -= mouseMove.x * 0.003; //缓存观察点 let oldTargetFormCameraSpace = target.clone().applyMatrix4(this.Camera.matrixWorldInverse); this.m_Orbit.UpdateDirection(this.m_Direction); this.UpdateUp(); this.Update(); //-----还原观察点 //得到新的观察点相对于相机的位置 let newTargetFormCameraSpace = target.clone().applyMatrix4(this.Camera.matrixWorldInverse); //减去原先的位置. 得到观测点在相机内移动的向量 newTargetFormCameraSpace.sub(oldTargetFormCameraSpace); //乘以相机的矩阵. 得到向量在世界坐标系的位置 newTargetFormCameraSpace.applyMatrix4(this.Camera.matrix); //因为使用的是点变换,所以减去基点,得到向量 newTargetFormCameraSpace.sub(this.Camera.position); //加上移动的向量. 使得观察点时钟在相机的某个位置 this.m_Target.add(newTargetFormCameraSpace); this.Update(); } Zoom(scale, scaleCenter) { if (this.Camera instanceof THREE.OrthographicCamera) { this.ViewHeight *= scale; if (scaleCenter) { this.m_Target.sub(scaleCenter); this.m_Target.multiplyScalar(scale); this.m_Target.add(scaleCenter); } } else if (this.Camera instanceof THREE.PerspectiveCamera) { let add = scale > 1 ? 1 : -1; add *= this.Camera.position.distanceTo(this.m_Target) / 10; this.m_Target.add(this.m_Direction.clone().multiplyScalar(-add)); } this.Update(); } ZoomExtensBox3(box3) { if (!box3) return; this.Camera.updateMatrixWorld(false); //变换到相机坐标系 box3.applyMatrix4(this.Camera.matrixWorldInverse); // box3.getCenter(this.m_Target); //世界坐标系 this.m_Target.applyMatrix4(this.Camera.matrix); //size let size = box3.getSize(new three_1.Vector3()); //宽高比 let aspectRatio = size.x / size.y; let viewAspectRatio = this.Aspect; // if (aspectRatio > viewAspectRatio) { this.m_ViewHeight = size.x / viewAspectRatio; } else { this.m_ViewHeight = size.y; } this.Update(); } LookAt(dir) { this.m_Orbit.UpdateRoValue(dir); this.m_Direction.copy(dir); this.UpdateUp(); this.Update(); } UpdateUp() { Orbit_1.Orbit.ComputUpDirection(this.m_Direction, this.Camera.up); } /** * 根据视口大小,设置相机视口范围. * * @returns * @memberof CameraControl */ Update() { this.Camera.position.copy(this.m_Target); if (this.Camera instanceof THREE.OrthographicCamera) { this.Camera.left = this.Aspect * this.m_ViewHeight / -2; this.Camera.right = this.Aspect * this.m_ViewHeight / 2; this.Camera.bottom = this.m_ViewHeight / -2; this.Camera.top = this.m_ViewHeight / 2; this.Camera.position.sub(this.m_Direction); } else if (this.Camera instanceof THREE.PerspectiveCamera) { this.Camera.aspect = this.Aspect; let distens = (this.m_ViewHeight / 2) / (Math.tan(THREE.Math.degToRad(this.Camera.fov) / 2)); this.Camera.position.sub(this.m_Direction.clone().multiplyScalar(distens)); } else { return; } this.Camera.lookAt(this.m_Target); this.Camera.updateProjectionMatrix(); this.Camera.updateMatrixWorld(false); } SwitchCamera() { if (this.Camera instanceof THREE.OrthographicCamera) { this.m_CurCamera = this.m_CameraArray.get(THREE.PerspectiveCamera); } else { this.m_CurCamera = this.m_CameraArray.get(THREE.OrthographicCamera); } this.UpdateUp(); this.Update(); } } exports.CameraUpdate = CameraUpdate; //# sourceMappingURL=CameraUpdate.js.map