|
|
|
@ -23,6 +23,7 @@ import type LineSegmentManager from '@/core/manager/LineSegmentManager.ts' |
|
|
|
import type { Object3DLike } from '@/types/ModelTypes.ts' |
|
|
|
import type InstanceMeshManager from '@/core/manager/InstanceMeshManager.ts' |
|
|
|
import ItemFindManager from '@/core/manager/ItemFindManager.ts' |
|
|
|
import { MapControls } from 'three/examples/jsm/controls/MapControls' |
|
|
|
|
|
|
|
/** |
|
|
|
* 视窗对象 |
|
|
|
@ -251,6 +252,7 @@ export default class Viewport { |
|
|
|
window['camera'] = this.camera |
|
|
|
window['renderer'] = this.renderer |
|
|
|
window['controls'] = this.controls |
|
|
|
this.state.isReady = true |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
@ -310,7 +312,8 @@ export default class Viewport { |
|
|
|
this.controls = null |
|
|
|
} |
|
|
|
|
|
|
|
// ============================ 创建正交相机
|
|
|
|
// ============================ 创建2D正交相机
|
|
|
|
// 模拟俯视2D的模式, 操作也用2D模式
|
|
|
|
const viewerDom = this.viewerDom |
|
|
|
const cameraNew = new THREE.OrthographicCamera( |
|
|
|
viewerDom.clientWidth / -2, |
|
|
|
@ -320,36 +323,34 @@ export default class Viewport { |
|
|
|
1, |
|
|
|
500 |
|
|
|
) |
|
|
|
cameraNew.position.set(0, 60, 0) |
|
|
|
cameraNew.lookAt(0, 0, 0) |
|
|
|
cameraNew.zoom = 60 |
|
|
|
this.camera = cameraNew |
|
|
|
this.scene.add(this.camera) |
|
|
|
|
|
|
|
// ============================ 创建控制器
|
|
|
|
const controlsNew = new OrbitControls( |
|
|
|
this.camera, |
|
|
|
this.renderer.domElement |
|
|
|
) |
|
|
|
controlsNew.enableDamping = false |
|
|
|
controlsNew.enableZoom = true |
|
|
|
controlsNew.enableRotate = false |
|
|
|
controlsNew.mouseButtons = { LEFT: THREE.MOUSE.PAN, RIGHT: THREE.MOUSE.PAN } // 鼠标中键平移
|
|
|
|
controlsNew.screenSpacePanning = false // 定义平移时如何平移相机的位置 控制不上下移动
|
|
|
|
controlsNew.listenToKeyEvents(viewerDom) // 监听键盘事件
|
|
|
|
controlsNew.keys = { LEFT: 'KeyA', UP: 'KeyW', RIGHT: 'KeyD', BOTTOM: 'KeyS' } |
|
|
|
controlsNew.addEventListener('change', this.syncCameraState.bind(this)) |
|
|
|
controlsNew.panSpeed = 1 |
|
|
|
controlsNew.keyPanSpeed = 20 // normal 7
|
|
|
|
controlsNew.minDistance = 0.1 |
|
|
|
controlsNew.maxDistance = 1000 |
|
|
|
const controlsNew = new MapControls(this.camera, this.renderer.domElement) |
|
|
|
controlsNew.enableRotate = false // 禁止旋转
|
|
|
|
controlsNew.enableZoom = true // 启用缩放
|
|
|
|
// controlsNew.zoomSpeed = 0.5 // 调整缩放速度
|
|
|
|
// controlsNew.panSpeed = 0.5 // 调整平移速度
|
|
|
|
controlsNew.mouseButtons = { |
|
|
|
LEFT: THREE.MOUSE.PAN, |
|
|
|
RIGHT: THREE.MOUSE.PAN |
|
|
|
} |
|
|
|
controlsNew.addEventListener('change', () => { |
|
|
|
this.syncCameraState() |
|
|
|
}) |
|
|
|
this.controls = controlsNew |
|
|
|
|
|
|
|
cameraNew.updateProjectionMatrix() |
|
|
|
|
|
|
|
window['camera'] = this.camera |
|
|
|
window['controls'] = this.controls |
|
|
|
|
|
|
|
if (this.camera instanceof THREE.OrthographicCamera) { |
|
|
|
this.camera.position.set(0, 100, 0) |
|
|
|
this.camera.lookAt(0, 0, 0) |
|
|
|
this.camera.zoom = 34 |
|
|
|
this.camera.updateProjectionMatrix() |
|
|
|
} |
|
|
|
|
|
|
|
this.syncCameraState() |
|
|
|
} |
|
|
|
|
|
|
|
@ -385,9 +386,9 @@ export default class Viewport { |
|
|
|
syncCameraState() { |
|
|
|
if (this.camera) { |
|
|
|
const camera = this.camera |
|
|
|
if (this.camera instanceof THREE.PerspectiveCamera) { |
|
|
|
if (this.camera instanceof THREE.OrthographicCamera) { |
|
|
|
this.state.camera.position.x = camera.position.x |
|
|
|
this.state.camera.position.y = (camera as THREE.PerspectiveCamera).zoom // this.getEffectiveViewDistance()
|
|
|
|
this.state.camera.position.y = (camera as THREE.OrthographicCamera).zoom // this.getEffectiveViewDistance()
|
|
|
|
this.state.camera.position.z = camera.position.z |
|
|
|
|
|
|
|
} else { |
|
|
|
@ -412,14 +413,21 @@ export default class Viewport { |
|
|
|
// return viewHeight / (2 * Math.tan(THREE.MathUtils.degToRad(referenceFOV) / 2))
|
|
|
|
// }
|
|
|
|
|
|
|
|
/** |
|
|
|
* 摄像机追踪到指定位置 |
|
|
|
*/ |
|
|
|
cameraToEntity(id: string) { |
|
|
|
const { tf } = this.entityManager.findItemById(id) |
|
|
|
// 移动正交相机去往目标点
|
|
|
|
if (this.camera instanceof THREE.OrthographicCamera) { |
|
|
|
this.camera.position.set(tf[0][0], 60, tf[0][2]) |
|
|
|
this.camera.lookAt(tf[0][0], 0, tf[0][2]) |
|
|
|
this.camera.zoom = 60 |
|
|
|
const targetX = tf[0][0] |
|
|
|
const targetZ = tf[0][2] |
|
|
|
|
|
|
|
this.controls.target.set(targetX, 0, targetZ) |
|
|
|
this.camera.position.set(targetX, 60, targetZ) // y 可以固定一个值,比如 60
|
|
|
|
this.camera.zoom = 34 |
|
|
|
this.camera.updateProjectionMatrix() |
|
|
|
this.controls.update() |
|
|
|
|
|
|
|
} else if (this.camera instanceof THREE.PerspectiveCamera) { |
|
|
|
this.camera.position.set(tf[0][0], tf[1][1] + 10, tf[2][2]) |
|
|
|
@ -474,15 +482,15 @@ export default class Viewport { |
|
|
|
* 根据可视化范围更新网格的透明度 |
|
|
|
*/ |
|
|
|
updateGridVisibility() { |
|
|
|
if (this.camera === undefined || !(this.camera instanceof THREE.PerspectiveCamera)) { |
|
|
|
if (this.camera === undefined || !(this.camera instanceof THREE.OrthographicCamera)) { |
|
|
|
// 如果没有相机或相机不是透视相机,则不更新网格可见性
|
|
|
|
this.gridHelper.visible = true |
|
|
|
this.gridHelper.material.opacity = 1 |
|
|
|
return |
|
|
|
} |
|
|
|
const cameraDistance = this.state.camera.position.y |
|
|
|
const maxVisibleDistance = 4 // 网格完全不可见的最小距离
|
|
|
|
const fadeStartDistance = 9 // 开始淡出的最大距离
|
|
|
|
const maxVisibleDistance = 8 // 网格完全不可见的最小距离
|
|
|
|
const fadeStartDistance = 35 // 开始淡出的最大距离
|
|
|
|
|
|
|
|
let opacity |
|
|
|
if (cameraDistance >= fadeStartDistance) { |
|
|
|
|