Ensure camera state is committed after smooth zoom completion

This commit is contained in:
2026-04-30 02:37:43 +02:00
parent 57843e56a3
commit 5910e934a6

View File

@@ -917,6 +917,7 @@ export class ViewportHost {
private panelId: ViewportPanelId = "topLeft"; private panelId: ViewportPanelId = "topLeft";
private targetPerspectiveCameraRadius: number | null = null; private targetPerspectiveCameraRadius: number | null = null;
private targetOrthographicCameraZoom: number | null = null; private targetOrthographicCameraZoom: number | null = null;
private pendingSmoothZoomCameraStateCommit = false;
private creationPreview: CreationViewportToolPreview | null = null; private creationPreview: CreationViewportToolPreview | null = null;
private currentTerrainBrushState: ArmedTerrainBrushState | null = null; private currentTerrainBrushState: ArmedTerrainBrushState | null = null;
private terrainBrushHover: TerrainBrushHit | null = null; private terrainBrushHover: TerrainBrushHit | null = null;
@@ -1806,6 +1807,7 @@ export class ViewportHost {
this.lastCameraStateTraceSnapshot = this.lastCameraStateTraceSnapshot =
cloneViewportPanelCameraState(nextCameraState); cloneViewportPanelCameraState(nextCameraState);
this.pendingSmoothZoomCameraStateCommit = false;
this.cameraStateChangeHandler?.(nextCameraState); this.cameraStateChangeHandler?.(nextCameraState);
} }
@@ -1823,9 +1825,12 @@ export class ViewportHost {
private cancelSmoothZoom() { private cancelSmoothZoom() {
this.targetPerspectiveCameraRadius = null; this.targetPerspectiveCameraRadius = null;
this.targetOrthographicCameraZoom = null; this.targetOrthographicCameraZoom = null;
this.pendingSmoothZoomCameraStateCommit = false;
} }
private finishSmoothZoom() { private finishSmoothZoom() {
const shouldCommitCameraState = this.pendingSmoothZoomCameraStateCommit;
if (this.targetPerspectiveCameraRadius !== null) { if (this.targetPerspectiveCameraRadius !== null) {
this.cameraSpherical.radius = this.targetPerspectiveCameraRadius; this.cameraSpherical.radius = this.targetPerspectiveCameraRadius;
this.targetPerspectiveCameraRadius = null; this.targetPerspectiveCameraRadius = null;
@@ -1835,6 +1840,11 @@ export class ViewportHost {
this.orthographicCamera.zoom = this.targetOrthographicCameraZoom; this.orthographicCamera.zoom = this.targetOrthographicCameraZoom;
this.targetOrthographicCameraZoom = null; this.targetOrthographicCameraZoom = null;
} }
if (shouldCommitCameraState) {
this.applyViewModePose();
this.emitCameraStateChange();
}
} }
private stepSmoothZoomValue( private stepSmoothZoomValue(
@@ -1876,11 +1886,13 @@ export class ViewportHost {
private updateSmoothZoom(dt: number) { private updateSmoothZoom(dt: number) {
const response = this.getSmoothZoomFrameResponse(dt); const response = this.getSmoothZoomFrameResponse(dt);
let zoomWasActive = false;
if ( if (
this.viewMode === "perspective" && this.viewMode === "perspective" &&
this.targetPerspectiveCameraRadius !== null this.targetPerspectiveCameraRadius !== null
) { ) {
zoomWasActive = true;
const nextRadius = this.stepSmoothZoomValue( const nextRadius = this.stepSmoothZoomValue(
this.cameraSpherical.radius, this.cameraSpherical.radius,
this.targetPerspectiveCameraRadius, this.targetPerspectiveCameraRadius,
@@ -1897,6 +1909,7 @@ export class ViewportHost {
isOrthographicViewportViewMode(this.viewMode) && isOrthographicViewportViewMode(this.viewMode) &&
this.targetOrthographicCameraZoom !== null this.targetOrthographicCameraZoom !== null
) { ) {
zoomWasActive = true;
const nextZoom = this.stepSmoothZoomValue( const nextZoom = this.stepSmoothZoomValue(
this.orthographicCamera.zoom, this.orthographicCamera.zoom,
this.targetOrthographicCameraZoom, this.targetOrthographicCameraZoom,
@@ -1908,6 +1921,15 @@ export class ViewportHost {
} }
this.applyOrthographicCameraPose(); this.applyOrthographicCameraPose();
} }
if (
zoomWasActive &&
this.pendingSmoothZoomCameraStateCommit &&
this.targetPerspectiveCameraRadius === null &&
this.targetOrthographicCameraZoom === null
) {
this.emitCameraStateChange();
}
} }
private updatePerspectiveCameraSphericalFromPose() { private updatePerspectiveCameraSphericalFromPose() {
@@ -10347,6 +10369,7 @@ export class ViewportHost {
private handleWheel = (event: WheelEvent) => { private handleWheel = (event: WheelEvent) => {
event.preventDefault(); event.preventDefault();
this.pendingSmoothZoomCameraStateCommit = true;
if (this.viewMode === "perspective") { if (this.viewMode === "perspective") {
this.targetPerspectiveCameraRadius = this.clampPerspectiveCameraRadius( this.targetPerspectiveCameraRadius = this.clampPerspectiveCameraRadius(
@@ -10363,7 +10386,11 @@ export class ViewportHost {
this.targetPerspectiveCameraRadius = null; this.targetPerspectiveCameraRadius = null;
} }
this.applyPerspectiveCameraPose(); this.applyPerspectiveCameraPose();
this.emitCameraStateChange();
if (this.targetPerspectiveCameraRadius === null) {
this.emitCameraStateChange();
}
return; return;
} }
@@ -10381,7 +10408,10 @@ export class ViewportHost {
this.targetOrthographicCameraZoom = null; this.targetOrthographicCameraZoom = null;
} }
this.applyOrthographicCameraPose(); this.applyOrthographicCameraPose();
this.emitCameraStateChange();
if (this.targetOrthographicCameraZoom === null) {
this.emitCameraStateChange();
}
}; };
private handleAuxClick = (event: MouseEvent) => { private handleAuxClick = (event: MouseEvent) => {