调整建筑外观模型默认摆放

This commit is contained in:
lyf
2026-06-28 01:29:13 +08:00
parent 1ad77fcf48
commit ac07f7fc15

View File

@@ -66,6 +66,12 @@ import type {
type ViewMode = 'overview' | 'floor' | 'multi'
type CameraPreset = 'top' | 'oblique'
type TouchGestureMode = 'orbit' | 'pan'
interface CameraFitOptions {
distanceFactor?: number
targetOffsetRatio?: THREE.Vector3
screenOffsetRatio?: THREE.Vector2
up?: THREE.Vector3
}
type FloorIndexItem = GuideModelFloorAsset
@@ -1630,7 +1636,12 @@ const disableAutoSwitchTemporarily = (durationMs: number) => {
}, 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
isProgrammaticCameraChange = true
@@ -1639,15 +1650,37 @@ const setCameraView = (center: THREE.Vector3, maxDim: number, direction: THREE.V
}
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
try {
camera.near = Math.max(0.1, maxDim / 1000)
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()
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.maxDistance = Math.max(20, maxDim * 8)
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 direction = preset === 'top'
? 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 = () => {