diff --git a/src/viewer/scene/CameraControl/lib/controllers/PivotController.js b/src/viewer/scene/CameraControl/lib/controllers/PivotController.js index 4c50248d1c..984cddb733 100644 --- a/src/viewer/scene/CameraControl/lib/controllers/PivotController.js +++ b/src/viewer/scene/CameraControl/lib/controllers/PivotController.js @@ -1,5 +1,8 @@ import {math} from "../../../math/math.js"; +const tempVec3a = math.vec3(); +const tempVec3b = math.vec3(); + /** @private */ class PivotController { @@ -82,11 +85,14 @@ class PivotController { * * @param {Number[]} worldPos The World-space pivot position. */ - startPivot(worldPos) { + startPivot() { - const camera = this._scene.camera; + if (this._cameraLookingDownwards()) { + this._pivoting = false; + return false; + } - this.setPivotPos(worldPos || camera.look); + const camera = this._scene.camera; let lookat = math.lookAtMat4v(camera.eye, camera.look, camera.worldUp); math.transformPoint3(lookat, this._pivotWorldPos, this._cameraOffset); @@ -113,6 +119,14 @@ class PivotController { this._pivoting = true; } + _cameraLookingDownwards() { // Returns true if angle between camera viewing direction and World-space "up" axis is too small + const camera = this._scene.camera; + const forwardAxis = math.normalizeVec3(math.subVec3(camera.look, camera.eye, tempVec3a)); + const rightAxis = math.cross3Vec3(forwardAxis, camera.worldUp, tempVec3b); + let rightAxisLen = math.sqLenVec3(rightAxis); + return (rightAxisLen <= 0.0001); + } + /** * Returns true if we are currently pivoting. * diff --git a/src/viewer/scene/CameraControl/lib/handlers/KeyboardAxisViewHandler.js b/src/viewer/scene/CameraControl/lib/handlers/KeyboardAxisViewHandler.js index e0ea81704f..0a3804af27 100644 --- a/src/viewer/scene/CameraControl/lib/handlers/KeyboardAxisViewHandler.js +++ b/src/viewer/scene/CameraControl/lib/handlers/KeyboardAxisViewHandler.js @@ -92,7 +92,7 @@ class KeyboardAxisViewHandler { } if ((!configs.firstPerson) && configs.followPointer) { - controllers.pivotController.startPivot(center); + controllers.pivotController.setPivotPos(center); } if (controllers.cameraFlight.duration > 0) { diff --git a/src/viewer/scene/CameraControl/lib/handlers/MousePickHandler.js b/src/viewer/scene/CameraControl/lib/handlers/MousePickHandler.js index ea2d69f3dd..997a0c5776 100644 --- a/src/viewer/scene/CameraControl/lib/handlers/MousePickHandler.js +++ b/src/viewer/scene/CameraControl/lib/handlers/MousePickHandler.js @@ -146,8 +146,10 @@ class MousePickHandler { if (e.which === 1) {// Left button if (pickController.pickResult) { - pivotController.startPivot(pickController.pickResult.worldPos); + pivotController.setPivotPos(pickController.pickResult.worldPos); + pivotController.startPivot(); } else { + pivotController.setPivotPos(scene.camera.look); pivotController.startPivot(); // Continue to use last pivot point } } @@ -245,8 +247,10 @@ class MousePickHandler { cameraControl.fire("pickedSurface", pickController.pickResult, true); if ((!configs.firstPerson) && configs.followPointer) { - controllers.pivotController.startPivot(pickController.pickResult.worldPos); - controllers.pivotController.showPivot(); + controllers.pivotController.setPivotPos(pickController.pickResult.worldPos); + if (controllers.pivotController.startPivot()) { + controllers.pivotController.showPivot(); + } } } } else { @@ -288,8 +292,11 @@ class MousePickHandler { const pickedEntityAABB = pickController.pickResult.entity.aabb; const pickedEntityCenterPos = math.getAABB3Center(pickedEntityAABB); - controllers.pivotController.startPivot(pickedEntityCenterPos); - controllers.pivotController.showPivot(); + controllers.pivotController.setPivotPos(pickedEntityCenterPos); + + if (controllers.pivotController.startPivot()) { + controllers.pivotController.showPivot(); + } } } @@ -308,8 +315,11 @@ class MousePickHandler { const sceneAABB = scene.aabb; const sceneCenterPos = math.getAABB3Center(sceneAABB); - controllers.pivotController.startPivot(sceneCenterPos); - controllers.pivotController.showPivot(); + controllers.pivotController.setPivotPos(sceneCenterPos); + + if (controllers.pivotController.startPivot()) { + controllers.pivotController.showPivot(); + } } } } diff --git a/src/viewer/scene/CameraControl/lib/handlers/TouchPanRotateAndDollyHandler.js b/src/viewer/scene/CameraControl/lib/handlers/TouchPanRotateAndDollyHandler.js index eea1cd2b18..8e08f849c3 100644 --- a/src/viewer/scene/CameraControl/lib/handlers/TouchPanRotateAndDollyHandler.js +++ b/src/viewer/scene/CameraControl/lib/handlers/TouchPanRotateAndDollyHandler.js @@ -53,14 +53,18 @@ class TouchPanRotateAndDollyHandler { pickController.update(); if (!configs.planView) { - if (pickController.picked && pickController.pickedSurface && pickController.pickResult) { + if (pickController.picked && pickController.pickedSurface && pickController.pickResult && pickController.pickResult.worldPos) { - pivotController.startPivot(pickController.pickResult.worldPos); - pivotController.showPivot(); + pivotController.setPivotPos(pickController.pickResult.worldPos); + + if (pivotController.startPivot()) { + pivotController.showPivot(); + } } else { - pivotController.startPivot(); // Continue to use last pivot point - pivotController.showPivot(); + if (pivotController.startPivot()) { // Continue to use last pivot point + pivotController.showPivot(); + } } } }