forked from qt-creator/qt-creator
There is no need to double the viewport anymore when calculating orthographic camera frustum visualization, Qt6 correctly accounts for device pixel ratio in ortho projection. Even in Qt5, the old hack only made frustum visualization correct for hdpi screens while breaking it for regular screens. Also fixed zoom factor handling for orthographic edit camera mode. Task-number: QDS-5469 Change-Id: Ie53b5dfa2fbcc00f098ea64e5a6673e4b7af0963 Reviewed-by: Thomas Hartmann <thomas.hartmann@qt.io> Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
192 lines
7.3 KiB
QML
192 lines
7.3 KiB
QML
/****************************************************************************
|
|
**
|
|
** Copyright (C) 2019 The Qt Company Ltd.
|
|
** Contact: https://www.qt.io/licensing/
|
|
**
|
|
** This file is part of Qt Creator.
|
|
**
|
|
** Commercial License Usage
|
|
** Licensees holding valid commercial Qt licenses may use this file in
|
|
** accordance with the commercial license agreement provided with the
|
|
** Software or, alternatively, in accordance with the terms contained in
|
|
** a written agreement between you and The Qt Company. For licensing terms
|
|
** and conditions see https://www.qt.io/terms-conditions. For further
|
|
** information use the contact form at https://www.qt.io/contact-us.
|
|
**
|
|
** GNU General Public License Usage
|
|
** Alternatively, this file may be used under the terms of the GNU
|
|
** General Public License version 3 as published by the Free Software
|
|
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
|
** included in the packaging of this file. Please review the following
|
|
** information to ensure the GNU General Public License requirements will
|
|
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
|
**
|
|
****************************************************************************/
|
|
|
|
import QtQuick 6.0
|
|
import QtQuick3D 6.0
|
|
|
|
Item {
|
|
id: cameraCtrl
|
|
|
|
property Camera camera: null
|
|
property View3D view3d: null
|
|
property string sceneId
|
|
property vector3d _lookAtPoint
|
|
property vector3d _pressPoint
|
|
property vector3d _prevPoint
|
|
property vector3d _startRotation
|
|
property vector3d _startPosition
|
|
property vector3d _startLookAtPoint
|
|
property matrix4x4 _startTransform
|
|
property bool _dragging
|
|
property int _button
|
|
property real _zoomFactor: 1
|
|
property Camera _prevCamera: null
|
|
readonly property vector3d _defaultCameraPosition: Qt.vector3d(0, 600, 600)
|
|
readonly property vector3d _defaultCameraRotation: Qt.vector3d(-45, 0, 0)
|
|
readonly property real _defaultCameraLookAtDistance: _defaultCameraPosition.length()
|
|
property bool ignoreToolState: false
|
|
|
|
function restoreCameraState(cameraState)
|
|
{
|
|
if (!camera || ignoreToolState)
|
|
return;
|
|
|
|
_lookAtPoint = cameraState[0];
|
|
_zoomFactor = cameraState[1];
|
|
camera.position = cameraState[2];
|
|
camera.rotation = cameraState[3];
|
|
_generalHelper.zoomCamera(view3d, camera, 0, _defaultCameraLookAtDistance, _lookAtPoint,
|
|
_zoomFactor, false);
|
|
}
|
|
|
|
function restoreDefaultState()
|
|
{
|
|
if (!camera)
|
|
return;
|
|
|
|
_lookAtPoint = Qt.vector3d(0, 0, 0);
|
|
_zoomFactor = 1;
|
|
camera.position = _defaultCameraPosition;
|
|
camera.eulerRotation = _defaultCameraRotation;
|
|
_generalHelper.zoomCamera(view3d, camera, 0, _defaultCameraLookAtDistance, _lookAtPoint,
|
|
_zoomFactor, false);
|
|
}
|
|
|
|
function storeCameraState(delay)
|
|
{
|
|
if (!camera || ignoreToolState)
|
|
return;
|
|
|
|
var cameraState = [];
|
|
cameraState[0] = _lookAtPoint;
|
|
cameraState[1] = _zoomFactor;
|
|
cameraState[2] = camera.position;
|
|
cameraState[3] = camera.rotation;
|
|
_generalHelper.storeToolState(sceneId, "editCamState", cameraState, delay);
|
|
}
|
|
|
|
|
|
function focusObject(targetNodes, rotation, updateZoom, closeUp)
|
|
{
|
|
if (!camera)
|
|
return;
|
|
|
|
// targetNodes could be a list of nodes or a single node
|
|
var nodes = [];
|
|
if (targetNodes instanceof Node)
|
|
nodes.push(targetNodes);
|
|
else
|
|
nodes = targetNodes
|
|
|
|
camera.eulerRotation = rotation;
|
|
var newLookAtAndZoom = _generalHelper.focusNodesToCamera(
|
|
camera, _defaultCameraLookAtDistance, nodes, view3d, _zoomFactor,
|
|
updateZoom, closeUp);
|
|
_lookAtPoint = newLookAtAndZoom.toVector3d();
|
|
_zoomFactor = newLookAtAndZoom.w;
|
|
storeCameraState(0);
|
|
}
|
|
|
|
function zoomRelative(distance)
|
|
{
|
|
if (!camera)
|
|
return;
|
|
|
|
_zoomFactor = _generalHelper.zoomCamera(view3d, camera, distance, _defaultCameraLookAtDistance,
|
|
_lookAtPoint, _zoomFactor, true);
|
|
}
|
|
|
|
onCameraChanged: {
|
|
if (camera && _prevCamera) {
|
|
// Reset zoom on previous camera to ensure it's properties are good to copy to new cam
|
|
_generalHelper.zoomCamera(view3d, _prevCamera, 0, _defaultCameraLookAtDistance, _lookAtPoint,
|
|
1, false);
|
|
|
|
camera.position = _prevCamera.position;
|
|
camera.rotation = _prevCamera.rotation;
|
|
|
|
// Apply correct zoom to new camera
|
|
_generalHelper.zoomCamera(view3d, camera, 0, _defaultCameraLookAtDistance, _lookAtPoint,
|
|
_zoomFactor, false);
|
|
}
|
|
_prevCamera = camera;
|
|
}
|
|
|
|
MouseArea {
|
|
id: mouseHandler
|
|
acceptedButtons: Qt.LeftButton | Qt.RightButton | Qt.MiddleButton
|
|
hoverEnabled: false
|
|
anchors.fill: parent
|
|
onPositionChanged: (mouse)=> {
|
|
if (cameraCtrl.camera && mouse.modifiers === Qt.AltModifier && cameraCtrl._dragging) {
|
|
var currentPoint = Qt.vector3d(mouse.x, mouse.y, 0);
|
|
if (cameraCtrl._button == Qt.LeftButton) {
|
|
_generalHelper.orbitCamera(cameraCtrl.camera, cameraCtrl._startRotation,
|
|
cameraCtrl._lookAtPoint, cameraCtrl._pressPoint,
|
|
currentPoint);
|
|
} else if (cameraCtrl._button == Qt.MiddleButton) {
|
|
cameraCtrl._lookAtPoint = _generalHelper.panCamera(
|
|
cameraCtrl.camera, cameraCtrl._startTransform,
|
|
cameraCtrl._startPosition, cameraCtrl._startLookAtPoint,
|
|
cameraCtrl._pressPoint, currentPoint, _zoomFactor);
|
|
} else if (cameraCtrl._button == Qt.RightButton) {
|
|
cameraCtrl.zoomRelative(currentPoint.y - cameraCtrl._prevPoint.y)
|
|
cameraCtrl._prevPoint = currentPoint;
|
|
}
|
|
}
|
|
}
|
|
onPressed: (mouse)=> {
|
|
if (cameraCtrl.camera && mouse.modifiers === Qt.AltModifier) {
|
|
cameraCtrl._dragging = true;
|
|
cameraCtrl._startRotation = cameraCtrl.camera.eulerRotation;
|
|
cameraCtrl._startPosition = cameraCtrl.camera.position;
|
|
cameraCtrl._startLookAtPoint = _lookAtPoint;
|
|
cameraCtrl._pressPoint = Qt.vector3d(mouse.x, mouse.y, 0);
|
|
cameraCtrl._prevPoint = cameraCtrl._pressPoint;
|
|
cameraCtrl._button = mouse.button;
|
|
cameraCtrl._startTransform = cameraCtrl.camera.sceneTransform;
|
|
} else {
|
|
mouse.accepted = false;
|
|
}
|
|
}
|
|
|
|
function handleRelease() {
|
|
cameraCtrl._dragging = false;
|
|
cameraCtrl.storeCameraState(0);
|
|
}
|
|
|
|
onReleased: handleRelease()
|
|
onCanceled: handleRelease()
|
|
|
|
onWheel: (wheel)=> {
|
|
if (cameraCtrl.camera) {
|
|
// Empirically determined divisor for nice zoom
|
|
cameraCtrl.zoomRelative(wheel.angleDelta.y / -40);
|
|
cameraCtrl.storeCameraState(500);
|
|
}
|
|
}
|
|
}
|
|
}
|