174 lines
6.1 KiB
JavaScript
174 lines
6.1 KiB
JavaScript
"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_MinViewHeight = 10;
|
|
this.m_MaxViewHeight = 3e4;
|
|
this.m_CameraArray.set(THREE.OrthographicCamera, new THREE.OrthographicCamera(-2, 2, 2, -2, -1e6, 1e6));
|
|
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, this.m_MinViewHeight, this.m_MaxViewHeight);
|
|
}
|
|
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_ViewHeight < this.m_MaxViewHeight) {
|
|
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
|