修复楼层切换后无法返回建筑外观
Some checks failed
CI / verify (push) Has been cancelled

This commit is contained in:
lyf
2026-07-13 19:51:58 +08:00
parent e48a8bb626
commit f2ee41fe44
2 changed files with 36 additions and 0 deletions

View File

@@ -543,6 +543,8 @@ const poiAmbientLabelServiceSpacingPx = 72
const modelLoadRetryDelaysMs = [300, 900]
const adjacentPreloadDelayMs = 900
const manualAutoSwitchPauseMs = 1500
const autoSwitchExitDistanceRatio = 0.2
const autoSwitchExitDistanceMarginRatio = 0.08
const poiMarkerVisualLiftFactor = 0.92
const poiAmbientLabelLiftFactor = 2.1
const poiFocusLabelLiftFactor = 2.72
@@ -3275,6 +3277,18 @@ const resetAutoSwitchDistanceTracking = () => {
autoSwitchStateMachine.reset(activeView.value)
}
const ensureFloorAutoExitZoomRange = () => {
if (!controls) return
const distance = controls.getDistance()
if (!Number.isFinite(distance) || distance <= 0) return
// 楼层退出以当前距离的 120% 为阈值;参考外观相机正好处于原 600 上限时,
// 必须预留额外缩小空间,否则切层后无法满足自动返回外观的条件。
const requiredMaxDistance = distance * (1 + autoSwitchExitDistanceRatio + autoSwitchExitDistanceMarginRatio)
controls.maxDistance = Math.max(controls.maxDistance, requiredMaxDistance)
}
const handleWheelIntent = (event: WheelEvent) => {
if (!controls || activeView.value !== 'overview' || event.deltaY === 0) return
@@ -3368,6 +3382,7 @@ const autoSwitchStateMachine = new GuideAutoSwitchStateMachine({
exitHoldMs: 400,
intentTimeoutMs: 2000,
reverseToleranceRatio: 0.008,
exitRatio: autoSwitchExitDistanceRatio,
cooldownMs: props.autoSwitchCooldown,
canSwitch: canRunAutoSwitch,
onSwitchRequested: requestAutoSwitch
@@ -3752,6 +3767,7 @@ const applyIndoorInitialModelTransform = (model: THREE.Object3D) => {
const resetCamera = () => {
applyReferenceOverviewCameraState()
if (activeView.value === 'floor' && controls) {
ensureFloorAutoExitZoomRange()
autoSwitchStateMachine.setFloorInitialDistance(controls.getDistance())
}
refreshPoiVisibilityByDistance()
@@ -4060,6 +4076,7 @@ const commitPreparedFloorScene = (
}
recordCameraSnapshotRestoration(cameraSnapshot, `floor:${expectedFloorId}`)
if (controls) {
ensureFloorAutoExitZoomRange()
autoSwitchStateMachine.setFloorInitialDistance(controls.getDistance())
}
options.onCameraStable?.()

View File

@@ -168,6 +168,21 @@ const showOverview = async (page: Page, testInfo: TestInfo, name: string) => {
assertStableTransition(before, after)
}
const exitOverviewWithZoomControl = async (page: Page, testInfo: TestInfo, name: string) => {
const before = await getReport(page)
await screenshot(page, testInfo, `${name}-before`)
await page.getByText('', { exact: true }).click()
await expect.poll(async () => (await getReport(page)).activeView, { timeout: 10_000 }).toBe('overview')
const after = await getReport(page)
await screenshot(page, testInfo, `${name}-after`)
expect(after.isCameraTweening).toBe(false)
expect(after.modelRoot, 'the overview model must stay committed').not.toBeNull()
expect(after.modelRoot!.maxError).toBeLessThan(1e-12)
expect(after.camera.distance).toBeGreaterThanOrEqual(before.camera.distance * 1.2)
}
const normalizeFloorKey = (value: string) => value.trim().toLowerCase().replace(/[^a-z0-9.-]/g, '')
const resolveRequiredFloorId = (floors: FloorReport[], requested: string) => {
@@ -213,4 +228,8 @@ test('ordinary exterior and floor switches preserve the GLB_METER camera project
await switchFloor(page, testInfo, l1Point5, 'exterior-l1point5')
await showOverview(page, testInfo, 'l1point5-exterior')
await switchFloor(page, testInfo, l1, 'exterior-l1-auto-exit')
await switchFloor(page, testInfo, l2, 'l1-l2-auto-exit')
await exitOverviewWithZoomControl(page, testInfo, 'l2-exterior-auto-exit')
})