调整建筑外观模型默认摆放
This commit is contained in:
@@ -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 = () => {
|
||||
|
||||
Reference in New Issue
Block a user