From 1cf6e7844a1836e649b5dcac54cb4d847882a812 Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Fri, 26 Apr 2024 12:33:39 +0300 Subject: [PATCH] QmlDesigner: Change wheel to adjust camera speed in fly mode in 3D view Mouse wheel no longer zooms 3D view when done in fly mode. Instead, it adjusts the camera speed value. Fixes: QDS-12291 Change-Id: I0bb5960d67cb25d545d3ac2ce2567c75f057ea72 Reviewed-by: Mahmoud Badri Reviewed-by: Qt CI Patch Build Bot --- .../components/edit3d/edit3dcanvas.cpp | 11 +++- .../mockfiles/qt6/EditCameraController.qml | 16 +++--- .../qml2puppet/mockfiles/qt6/EditView3D.qml | 53 +++++++++++++++++-- .../qml2puppet/editor3d/generalhelper.cpp | 35 ++++++++++-- .../qml2puppet/editor3d/generalhelper.h | 5 ++ 5 files changed, 103 insertions(+), 17 deletions(-) diff --git a/src/plugins/qmldesigner/components/edit3d/edit3dcanvas.cpp b/src/plugins/qmldesigner/components/edit3d/edit3dcanvas.cpp index ef2e2ee7b56..4f4f08f1e18 100644 --- a/src/plugins/qmldesigner/components/edit3d/edit3dcanvas.cpp +++ b/src/plugins/qmldesigner/components/edit3d/edit3dcanvas.cpp @@ -207,7 +207,16 @@ void Edit3DCanvas::mouseMoveEvent(QMouseEvent *e) void Edit3DCanvas::wheelEvent(QWheelEvent *e) { - m_parent->view()->sendInputEvent(e); + if (m_flyMode) { + // In fly mode, wheel controls the camera speed slider (value range 1-100) + double speed; + double mult; + m_parent->view()->getCameraSpeedAuxData(speed, mult); + speed = qMin(100., qMax(1., speed + double(e->angleDelta().y()) / 40.)); + m_parent->view()->setCameraSpeedAuxData(speed, mult); + } else { + m_parent->view()->sendInputEvent(e); + } QWidget::wheelEvent(e); } diff --git a/src/tools/qml2puppet/mockfiles/qt6/EditCameraController.qml b/src/tools/qml2puppet/mockfiles/qt6/EditCameraController.qml index f840b5044a5..bbc50a18e56 100644 --- a/src/tools/qml2puppet/mockfiles/qt6/EditCameraController.qml +++ b/src/tools/qml2puppet/mockfiles/qt6/EditCameraController.qml @@ -26,10 +26,9 @@ Item { readonly property vector3d _defaultCameraPosition: Qt.vector3d(0, 600, 600) readonly property vector3d _defaultCameraRotation: Qt.vector3d(-45, 0, 0) readonly property real _defaultCameraLookAtDistance: _defaultCameraPosition.length() - readonly property real _keyPanAmount: _generalHelper.cameraSpeed + readonly property real _keyPanAmount: 1.0 property bool ignoreToolState: false property bool flyMode: viewRoot.flyMode - property real _cameraSpeedModifier: 1 z: 10 anchors.fill: parent @@ -245,15 +244,16 @@ Item { cameraCtrl.storeCameraState(0); } _generalHelper.stopAllCameraMoves() - cameraCtrl._cameraSpeedModifier = 1 + _generalHelper.setCameraSpeedModifier(1.0); } Connections { target: _generalHelper enabled: viewRoot.activeSplit === cameraCtrl.splitId + function onRequestCameraMove(camera, moveVec) { if (camera === cameraCtrl.camera) { - cameraCtrl.moveCamera(moveVec.times(_cameraSpeedModifier)); + cameraCtrl.moveCamera(moveVec); _generalHelper.requestRender(); } } @@ -319,7 +319,7 @@ Item { onWheel: (wheel) => { if (cameraCtrl.flyMode && cameraCtrl.splitId !== viewRoot.activeSplit) return; - viewRoot.activeSplit = cameraCtrl.splitId + viewRoot.activeSplit = cameraCtrl.splitId; if (cameraCtrl.camera) { // Empirically determined divisor for nice zoom cameraCtrl.zoomRelative(wheel.angleDelta.y / -40); @@ -330,11 +330,11 @@ Item { function setCameraSpeed(event) { if (event.modifiers === Qt.AltModifier) - cameraCtrl._cameraSpeedModifier = 0.5 + _generalHelper.setCameraSpeedModifier(0.5); else if (event.modifiers === Qt.ShiftModifier) - cameraCtrl._cameraSpeedModifier = 2 + _generalHelper.setCameraSpeedModifier(2.0); else - cameraCtrl._cameraSpeedModifier = 1 + _generalHelper.setCameraSpeedModifier(1.0); } Keys.onPressed: (event) => { diff --git a/src/tools/qml2puppet/mockfiles/qt6/EditView3D.qml b/src/tools/qml2puppet/mockfiles/qt6/EditView3D.qml index 23fc1c6a78e..e3448ff77cc 100644 --- a/src/tools/qml2puppet/mockfiles/qt6/EditView3D.qml +++ b/src/tools/qml2puppet/mockfiles/qt6/EditView3D.qml @@ -38,6 +38,7 @@ Item { property bool syncEnvBackground: false property bool splitView: false property bool flyMode: false + property bool showCameraSpeed: false enum SelectionMode { Item, Group } enum TransformMode { Move, Rotate, Scale } @@ -353,10 +354,13 @@ Item { cameraControls[i].restoreDefaultState(); } - if ("flyMode" in toolStates) + if ("flyMode" in toolStates) { flyMode = toolStates.flyMode; - else if (resetToDefault) + viewRoot.showCameraSpeed = false; + } else if (resetToDefault) { flyMode = false; + viewRoot.showCameraSpeed = false; + } if ("splitView" in toolStates) splitView = toolStates.splitView; @@ -638,7 +642,6 @@ Item { { for (var i = 0; i < 4; ++i) overlayViews[i].handleHiddenStateChange(node); - } function onUpdateDragTooltip() @@ -651,6 +654,18 @@ Item { { updateEnvBackground(); } + + function onCameraSpeedChanged() { + _generalHelper.requestTimerEvent("hideSpeed", 1000); + viewRoot.showCameraSpeed = true + } + + function onRequestedTimerEvent(timerId) { + if (timerId === "hideSpeed") { + viewRoot.showCameraSpeed = false; + _generalHelper.requestRender(); + } + } } // Shared nodes of the overlay, set as importScene on all overlay views. @@ -1058,6 +1073,38 @@ Item { color: "white" visible: viewRoot.fps > 0 } + + Rectangle { + id: cameraSpeedLabel + width: 120 + height: 65 + anchors.centerIn: parent + opacity: 0.6 + radius: 10 + color: "white" + visible: flyMode && viewRoot.showCameraSpeed + enabled: false + + Column { + anchors.fill: parent + anchors.margins: 8 + spacing: 2 + Text { + width: parent.width + horizontalAlignment: Text.AlignHCenter + text: "Camera Speed" + font.pixelSize: 16 + } + Text { + width: parent.width + height: 20 + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + font.pixelSize: 20 + text: _generalHelper.cameraSpeed.toLocaleString(Qt.locale(), 'f', 1) + } + } + } } Keys.onPressed: (event) => { diff --git a/src/tools/qml2puppet/qml2puppet/editor3d/generalhelper.cpp b/src/tools/qml2puppet/qml2puppet/editor3d/generalhelper.cpp index dadd8176330..00f96f51949 100644 --- a/src/tools/qml2puppet/qml2puppet/editor3d/generalhelper.cpp +++ b/src/tools/qml2puppet/qml2puppet/editor3d/generalhelper.cpp @@ -163,16 +163,17 @@ QVector3D GeneralHelper::moveCamera(QQuick3DCamera *camera, const QVector3D &sta if (moveVector.length() < 0.001f) return startLookAt; + QVector3D speedVector = moveVector * m_cameraSpeed * m_cameraSpeedModifier; + QMatrix4x4 m = camera->sceneTransform(); // Works because edit camera is at scene root const float *dataPtr(m.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 zAxis = QVector3D(dataPtr[8], dataPtr[9], dataPtr[10]).normalized(); - const QVector3D xDelta = xAxis * moveVector.x(); - const QVector3D yDelta = yAxis * moveVector.y(); - const QVector3D zDelta = zAxis * moveVector.z(); - // Delta multiplier for nice default speed in default scene - const QVector3D delta = (yDelta - xDelta - zDelta) * .5f; + const QVector3D xDelta = xAxis * speedVector.x(); + const QVector3D yDelta = yAxis * speedVector.y(); + const QVector3D zDelta = zAxis * speedVector.z(); + const QVector3D delta = (yDelta - xDelta - zDelta); camera->setPosition(camera->position() + delta); @@ -1187,6 +1188,11 @@ void GeneralHelper::setCameraSpeed(double speed) } } +void GeneralHelper::setCameraSpeedModifier(double modifier) +{ + m_cameraSpeedModifier = modifier; +} + QString GeneralHelper::formatVectorDragTooltip(const QVector3D &vec, const QString &suffix) const { return QObject::tr("x:%L1 y:%L2 z:%L3%L4") @@ -1414,6 +1420,25 @@ bool GeneralHelper::compareQuaternions(const QQuaternion &q1, const QQuaternion && qFuzzyCompare(q1.z(), q2.z()) && qFuzzyCompare(q1.scalar(), q2.scalar()); } +void GeneralHelper::requestTimerEvent(const QString &timerId, qint64 delay) +{ + if (m_eventTimers.contains(timerId)) { + m_eventTimers[timerId]->start(delay); + } else { + auto timer = new QTimer; + timer->setInterval(delay); + timer->setSingleShot(true); + connect(timer, &QTimer::timeout, this, [this, timerId]() { + if (m_eventTimers.contains(timerId)) { + QTimer *timer = m_eventTimers.take(timerId); + timer->deleteLater(); + } + emit requestedTimerEvent(timerId); + }); + m_eventTimers[timerId] = timer; + } +} + } } diff --git a/src/tools/qml2puppet/qml2puppet/editor3d/generalhelper.h b/src/tools/qml2puppet/qml2puppet/editor3d/generalhelper.h index 558e0363df2..10ed28aa721 100644 --- a/src/tools/qml2puppet/qml2puppet/editor3d/generalhelper.h +++ b/src/tools/qml2puppet/qml2puppet/editor3d/generalhelper.h @@ -139,6 +139,7 @@ public: void setSnapRotationInterval(double interval) { m_snapRotationInterval = interval; } void setSnapScaleInterval(double interval) { m_snapScaleInterval = interval / 100.; } void setCameraSpeed(double speed); + Q_INVOKABLE void setCameraSpeedModifier(double modifier); Q_INVOKABLE QString snapPositionDragTooltip(const QVector3D &pos) const; Q_INVOKABLE QString snapRotationDragTooltip(double angle) const; @@ -154,6 +155,8 @@ public: Q_INVOKABLE bool compareVectors(const QVector3D &v1, const QVector3D &v2) const; Q_INVOKABLE bool compareQuaternions(const QQuaternion &q1, const QQuaternion &q2) const; + Q_INVOKABLE void requestTimerEvent(const QString &timerId, qint64 delay); + signals: void overlayUpdateNeeded(); void toolStateChanged(const QString &sceneId, const QString &tool, const QVariant &toolState); @@ -167,6 +170,7 @@ signals: void requestCameraMove(QQuick3DCamera *camera, const QVector3D &moveVector); void requestRender(); void cameraSpeedChanged(); + void requestedTimerEvent(const QString &timerId); private: void handlePendingToolStateUpdate(); @@ -224,6 +228,7 @@ private: double m_cameraSpeedModifier = 1.; QVariant m_bgColor; + QHash m_eventTimers; }; }