diff options
author | Miikka Heikkinen <miikka.heikkinen@qt.io> | 2019-11-15 15:20:31 +0200 |
---|---|---|
committer | Miikka Heikkinen <miikka.heikkinen@qt.io> | 2019-11-22 10:47:42 +0000 |
commit | 77cb514a797ffa4ec0eb66fd6f397b0b053bde26 (patch) | |
tree | 320346e6a38826fec459b419219f68c1cd3f7170 /share/qtcreator/qml/qmlpuppet/qml2puppet/editor3d/generalhelper.cpp | |
parent | 668cd2091adf616448e424f60a463236014dc339 (diff) |
QmlDesigner: Implement better camera navigation in 3D edit view
Edit camera is now controlled as in Qt 3D Studio:
ALT + left button orbits camera.
ALT + middle button pans camera.
ALT + right button zooms camera.
Wheel zooms camera.
Task-number: QDS-1206
Change-Id: Ia72644073d172b00483ceed8bcc5ffb8dce68741
Reviewed-by: Thomas Hartmann <thomas.hartmann@qt.io>
Diffstat (limited to 'share/qtcreator/qml/qmlpuppet/qml2puppet/editor3d/generalhelper.cpp')
-rw-r--r-- | share/qtcreator/qml/qmlpuppet/qml2puppet/editor3d/generalhelper.cpp | 132 |
1 files changed, 132 insertions, 0 deletions
diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/editor3d/generalhelper.cpp b/share/qtcreator/qml/qmlpuppet/qml2puppet/editor3d/generalhelper.cpp new file mode 100644 index 00000000000..b4872ed48fb --- /dev/null +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/editor3d/generalhelper.cpp @@ -0,0 +1,132 @@ +/**************************************************************************** +** +** 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. +** +****************************************************************************/ +#include "generalhelper.h" + +#ifdef QUICK3D_MODULE + +#include <QtQuick3D/private/qquick3dorthographiccamera_p.h> +#include <QtQuick3D/private/qquick3dperspectivecamera_p.h> +#include <QtCore/qhash.h> +#include <QtGui/qmatrix4x4.h> + +namespace QmlDesigner { +namespace Internal { + +GeneralHelper::GeneralHelper() + : QObject() +{ + m_overlayUpdateTimer.setInterval(16); + m_overlayUpdateTimer.setSingleShot(true); + QObject::connect(&m_overlayUpdateTimer, &QTimer::timeout, + this, &GeneralHelper::overlayUpdateNeeded); +} + +void GeneralHelper::requestOverlayUpdate() +{ + if (!m_overlayUpdateTimer.isActive()) + m_overlayUpdateTimer.start(); +} + +QString GeneralHelper::generateUniqueName(const QString &nameRoot) +{ + static QHash<QString, int> counters; + int count = counters[nameRoot]++; + return QStringLiteral("%1_%2").arg(nameRoot).arg(count); +} + +void GeneralHelper::orbitCamera(QQuick3DCamera *camera, const QVector3D &startRotation, + const QVector3D &lookAtPoint, const QVector3D &pressPos, + const QVector3D ¤tPos) +{ + QVector3D dragVector = currentPos - pressPos; + + if (dragVector.length() < 0.001f) + return; + + camera->setRotation(startRotation); + QVector3D newRotation(dragVector.y(), dragVector.x(), 0.f); + newRotation *= 0.5f; // Emprically determined multiplier for nice drag + newRotation += startRotation; + + camera->setRotation(newRotation); + + const QVector3D oldLookVector = camera->position() - lookAtPoint; + QMatrix4x4 m = camera->sceneTransform(); + const float *dataPtr(m.data()); + QVector3D newLookVector(-dataPtr[8], -dataPtr[9], -dataPtr[10]); + newLookVector.normalize(); + newLookVector *= oldLookVector.length(); + + camera->setPosition(lookAtPoint + newLookVector); +} + +// Pans camera and returns the new look-at point +QVector3D GeneralHelper::panCamera(QQuick3DCamera *camera, const QMatrix4x4 startTransform, + const QVector3D &startPosition, const QVector3D &startLookAt, + const QVector3D &pressPos, const QVector3D ¤tPos, + float zoomFactor) +{ + QVector3D dragVector = currentPos - pressPos; + + if (dragVector.length() < 0.001f) + return startLookAt; + + const float *dataPtr(startTransform.data()); + const QVector3D xAxis = QVector3D(dataPtr[0], dataPtr[1], dataPtr[2]).normalized(); + const QVector3D yAxis = QVector3D(dataPtr[4], dataPtr[5], dataPtr[6]).normalized(); + const QVector3D xDelta = -1.f * xAxis * dragVector.x(); + const QVector3D yDelta = yAxis * dragVector.y(); + const QVector3D delta = (xDelta + yDelta) * zoomFactor; + + camera->setPosition(startPosition + delta); + return startLookAt + delta; +} + +float GeneralHelper::zoomCamera(QQuick3DCamera *camera, float distance, float defaultLookAtDistance, + const QVector3D &lookAt, float zoomFactor, bool relative) +{ + // Emprically determined divisor for nice zoom + float multiplier = 1.f + (distance / 40.f); + float newZoomFactor = relative ? qBound(.0001f, zoomFactor * multiplier, 10000.f) + : zoomFactor; + + if (qobject_cast<QQuick3DOrthographicCamera *>(camera)) { + // Ortho camera we can simply scale + camera->setScale(QVector3D(newZoomFactor, newZoomFactor, newZoomFactor)); + } else if (qobject_cast<QQuick3DPerspectiveCamera *>(camera)) { + // Perspective camera is zoomed by moving camera forward or backward while keeping the + // look-at point the same + const QVector3D lookAtVec = (camera->position() - lookAt).normalized(); + const float newDistance = defaultLookAtDistance * newZoomFactor; + camera->setPosition(lookAt + (lookAtVec * newDistance)); + } + + return newZoomFactor; +} + +} +} + +#endif // QUICK3D_MODULE |