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; }; }