调整建筑外观模型默认摆放
This commit is contained in:
@@ -66,6 +66,12 @@ import type {
|
|||||||
type ViewMode = 'overview' | 'floor' | 'multi'
|
type ViewMode = 'overview' | 'floor' | 'multi'
|
||||||
type CameraPreset = 'top' | 'oblique'
|
type CameraPreset = 'top' | 'oblique'
|
||||||
type TouchGestureMode = 'orbit' | 'pan'
|
type TouchGestureMode = 'orbit' | 'pan'
|
||||||
|
interface CameraFitOptions {
|
||||||
|
distanceFactor?: number
|
||||||
|
targetOffsetRatio?: THREE.Vector3
|
||||||
|
screenOffsetRatio?: THREE.Vector2
|
||||||
|
up?: THREE.Vector3
|
||||||
|
}
|
||||||
|
|
||||||
type FloorIndexItem = GuideModelFloorAsset
|
type FloorIndexItem = GuideModelFloorAsset
|
||||||
|
|
||||||
@@ -1630,7 +1636,12 @@ const disableAutoSwitchTemporarily = (durationMs: number) => {
|
|||||||
}, durationMs)
|
}, durationMs)
|
||||||
}
|
}
|
||||||
|
|
||||||
const setCameraView = (center: THREE.Vector3, maxDim: number, direction: THREE.Vector3, distanceFactor = 0.58) => {
|
const setCameraView = (
|
||||||
|
center: THREE.Vector3,
|
||||||
|
maxDim: number,
|
||||||
|
direction: THREE.Vector3,
|
||||||
|
options: CameraFitOptions = {}
|
||||||
|
) => {
|
||||||
if (!camera || !controls) return
|
if (!camera || !controls) return
|
||||||
|
|
||||||
isProgrammaticCameraChange = true
|
isProgrammaticCameraChange = true
|
||||||
@@ -1639,15 +1650,37 @@ const setCameraView = (center: THREE.Vector3, maxDim: number, direction: THREE.V
|
|||||||
}
|
}
|
||||||
|
|
||||||
const fov = camera.fov * (Math.PI / 180)
|
const fov = camera.fov * (Math.PI / 180)
|
||||||
|
const distanceFactor = options.distanceFactor ?? 0.58
|
||||||
|
const targetOffset = options.targetOffsetRatio
|
||||||
|
? new THREE.Vector3(
|
||||||
|
options.targetOffsetRatio.x * maxDim,
|
||||||
|
options.targetOffsetRatio.y * maxDim,
|
||||||
|
options.targetOffsetRatio.z * maxDim
|
||||||
|
)
|
||||||
|
: new THREE.Vector3()
|
||||||
|
const targetCenter = center.clone().add(targetOffset)
|
||||||
const distance = Math.abs(maxDim / Math.sin(fov / 2)) * distanceFactor
|
const distance = Math.abs(maxDim / Math.sin(fov / 2)) * distanceFactor
|
||||||
|
|
||||||
try {
|
try {
|
||||||
camera.near = Math.max(0.1, maxDim / 1000)
|
camera.near = Math.max(0.1, maxDim / 1000)
|
||||||
camera.far = Math.max(10000, maxDim * 20)
|
camera.far = Math.max(10000, maxDim * 20)
|
||||||
camera.position.copy(center).add(direction.normalize().multiplyScalar(distance))
|
camera.up.copy(options.up || new THREE.Vector3(0, 1, 0))
|
||||||
|
camera.position.copy(targetCenter).add(direction.normalize().multiplyScalar(distance))
|
||||||
camera.updateProjectionMatrix()
|
camera.updateProjectionMatrix()
|
||||||
|
|
||||||
controls.target.copy(center)
|
controls.target.copy(targetCenter)
|
||||||
|
if (options.screenOffsetRatio) {
|
||||||
|
const viewDirection = controls.target.clone().sub(camera.position).normalize()
|
||||||
|
const cameraRight = new THREE.Vector3().crossVectors(viewDirection, camera.up).normalize()
|
||||||
|
const viewHeight = 2 * distance * Math.tan(fov / 2)
|
||||||
|
const viewWidth = viewHeight * camera.aspect
|
||||||
|
const screenOffset = cameraRight
|
||||||
|
.multiplyScalar(options.screenOffsetRatio.x * viewWidth)
|
||||||
|
.add(camera.up.clone().multiplyScalar(options.screenOffsetRatio.y * viewHeight))
|
||||||
|
|
||||||
|
camera.position.add(screenOffset)
|
||||||
|
controls.target.add(screenOffset)
|
||||||
|
}
|
||||||
controls.minDistance = Math.max(2, maxDim * 0.08)
|
controls.minDistance = Math.max(2, maxDim * 0.08)
|
||||||
controls.maxDistance = Math.max(20, maxDim * 8)
|
controls.maxDistance = Math.max(20, maxDim * 8)
|
||||||
controls.update()
|
controls.update()
|
||||||
@@ -1668,9 +1701,18 @@ const fitCameraToObject = (object: THREE.Object3D, preset: CameraPreset = 'obliq
|
|||||||
const maxDim = Math.max(size.x, size.y, size.z, 1)
|
const maxDim = Math.max(size.x, size.y, size.z, 1)
|
||||||
const direction = preset === 'top'
|
const direction = preset === 'top'
|
||||||
? new THREE.Vector3(0.02, 1, 0.02)
|
? new THREE.Vector3(0.02, 1, 0.02)
|
||||||
: new THREE.Vector3(0.85, 0.62, 1)
|
: activeView.value === 'overview'
|
||||||
|
? new THREE.Vector3(-0.16, 1, 0.18)
|
||||||
|
: new THREE.Vector3(0.85, 0.62, 1)
|
||||||
|
const overviewFitOptions: CameraFitOptions = activeView.value === 'overview'
|
||||||
|
? {
|
||||||
|
distanceFactor: 1.1,
|
||||||
|
screenOffsetRatio: new THREE.Vector2(-0.085, 0.065),
|
||||||
|
up: new THREE.Vector3(-0.82, 0, -0.57)
|
||||||
|
}
|
||||||
|
: {}
|
||||||
|
|
||||||
setCameraView(center, maxDim, direction)
|
setCameraView(center, maxDim, direction, overviewFitOptions)
|
||||||
}
|
}
|
||||||
|
|
||||||
const resetCamera = () => {
|
const resetCamera = () => {
|
||||||
|
|||||||
Reference in New Issue
Block a user