Browse Source

摄像机操作问题

master
修宁 6 months ago
parent
commit
69ab8ca93e
  1. 68
      src/core/engine/Viewport.ts

68
src/core/engine/Viewport.ts

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

Loading…
Cancel
Save