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 <mahmoud.badri@qt.io>
Reviewed-by: Qt CI Patch Build Bot <ci_patchbuild_bot@qt.io>
This commit is contained in:
Miikka Heikkinen
2024-04-26 12:33:39 +03:00
parent 97b646e30a
commit 1cf6e7844a
5 changed files with 103 additions and 17 deletions

View File

@@ -207,7 +207,16 @@ void Edit3DCanvas::mouseMoveEvent(QMouseEvent *e)
void Edit3DCanvas::wheelEvent(QWheelEvent *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); QWidget::wheelEvent(e);
} }

View File

@@ -26,10 +26,9 @@ Item {
readonly property vector3d _defaultCameraPosition: Qt.vector3d(0, 600, 600) readonly property vector3d _defaultCameraPosition: Qt.vector3d(0, 600, 600)
readonly property vector3d _defaultCameraRotation: Qt.vector3d(-45, 0, 0) readonly property vector3d _defaultCameraRotation: Qt.vector3d(-45, 0, 0)
readonly property real _defaultCameraLookAtDistance: _defaultCameraPosition.length() readonly property real _defaultCameraLookAtDistance: _defaultCameraPosition.length()
readonly property real _keyPanAmount: _generalHelper.cameraSpeed readonly property real _keyPanAmount: 1.0
property bool ignoreToolState: false property bool ignoreToolState: false
property bool flyMode: viewRoot.flyMode property bool flyMode: viewRoot.flyMode
property real _cameraSpeedModifier: 1
z: 10 z: 10
anchors.fill: parent anchors.fill: parent
@@ -245,15 +244,16 @@ Item {
cameraCtrl.storeCameraState(0); cameraCtrl.storeCameraState(0);
} }
_generalHelper.stopAllCameraMoves() _generalHelper.stopAllCameraMoves()
cameraCtrl._cameraSpeedModifier = 1 _generalHelper.setCameraSpeedModifier(1.0);
} }
Connections { Connections {
target: _generalHelper target: _generalHelper
enabled: viewRoot.activeSplit === cameraCtrl.splitId enabled: viewRoot.activeSplit === cameraCtrl.splitId
function onRequestCameraMove(camera, moveVec) { function onRequestCameraMove(camera, moveVec) {
if (camera === cameraCtrl.camera) { if (camera === cameraCtrl.camera) {
cameraCtrl.moveCamera(moveVec.times(_cameraSpeedModifier)); cameraCtrl.moveCamera(moveVec);
_generalHelper.requestRender(); _generalHelper.requestRender();
} }
} }
@@ -319,7 +319,7 @@ Item {
onWheel: (wheel) => { onWheel: (wheel) => {
if (cameraCtrl.flyMode && cameraCtrl.splitId !== viewRoot.activeSplit) if (cameraCtrl.flyMode && cameraCtrl.splitId !== viewRoot.activeSplit)
return; return;
viewRoot.activeSplit = cameraCtrl.splitId viewRoot.activeSplit = cameraCtrl.splitId;
if (cameraCtrl.camera) { if (cameraCtrl.camera) {
// Empirically determined divisor for nice zoom // Empirically determined divisor for nice zoom
cameraCtrl.zoomRelative(wheel.angleDelta.y / -40); cameraCtrl.zoomRelative(wheel.angleDelta.y / -40);
@@ -330,11 +330,11 @@ Item {
function setCameraSpeed(event) { function setCameraSpeed(event) {
if (event.modifiers === Qt.AltModifier) if (event.modifiers === Qt.AltModifier)
cameraCtrl._cameraSpeedModifier = 0.5 _generalHelper.setCameraSpeedModifier(0.5);
else if (event.modifiers === Qt.ShiftModifier) else if (event.modifiers === Qt.ShiftModifier)
cameraCtrl._cameraSpeedModifier = 2 _generalHelper.setCameraSpeedModifier(2.0);
else else
cameraCtrl._cameraSpeedModifier = 1 _generalHelper.setCameraSpeedModifier(1.0);
} }
Keys.onPressed: (event) => { Keys.onPressed: (event) => {

View File

@@ -38,6 +38,7 @@ Item {
property bool syncEnvBackground: false property bool syncEnvBackground: false
property bool splitView: false property bool splitView: false
property bool flyMode: false property bool flyMode: false
property bool showCameraSpeed: false
enum SelectionMode { Item, Group } enum SelectionMode { Item, Group }
enum TransformMode { Move, Rotate, Scale } enum TransformMode { Move, Rotate, Scale }
@@ -353,10 +354,13 @@ Item {
cameraControls[i].restoreDefaultState(); cameraControls[i].restoreDefaultState();
} }
if ("flyMode" in toolStates) if ("flyMode" in toolStates) {
flyMode = toolStates.flyMode; flyMode = toolStates.flyMode;
else if (resetToDefault) viewRoot.showCameraSpeed = false;
} else if (resetToDefault) {
flyMode = false; flyMode = false;
viewRoot.showCameraSpeed = false;
}
if ("splitView" in toolStates) if ("splitView" in toolStates)
splitView = toolStates.splitView; splitView = toolStates.splitView;
@@ -638,7 +642,6 @@ Item {
{ {
for (var i = 0; i < 4; ++i) for (var i = 0; i < 4; ++i)
overlayViews[i].handleHiddenStateChange(node); overlayViews[i].handleHiddenStateChange(node);
} }
function onUpdateDragTooltip() function onUpdateDragTooltip()
@@ -651,6 +654,18 @@ Item {
{ {
updateEnvBackground(); 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. // Shared nodes of the overlay, set as importScene on all overlay views.
@@ -1058,6 +1073,38 @@ Item {
color: "white" color: "white"
visible: viewRoot.fps > 0 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) => { Keys.onPressed: (event) => {

View File

@@ -163,16 +163,17 @@ QVector3D GeneralHelper::moveCamera(QQuick3DCamera *camera, const QVector3D &sta
if (moveVector.length() < 0.001f) if (moveVector.length() < 0.001f)
return startLookAt; return startLookAt;
QVector3D speedVector = moveVector * m_cameraSpeed * m_cameraSpeedModifier;
QMatrix4x4 m = camera->sceneTransform(); // Works because edit camera is at scene root QMatrix4x4 m = camera->sceneTransform(); // Works because edit camera is at scene root
const float *dataPtr(m.data()); const float *dataPtr(m.data());
const QVector3D xAxis = QVector3D(dataPtr[0], dataPtr[1], dataPtr[2]).normalized(); const QVector3D xAxis = QVector3D(dataPtr[0], dataPtr[1], dataPtr[2]).normalized();
const QVector3D yAxis = QVector3D(dataPtr[4], dataPtr[5], dataPtr[6]).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 zAxis = QVector3D(dataPtr[8], dataPtr[9], dataPtr[10]).normalized();
const QVector3D xDelta = xAxis * moveVector.x(); const QVector3D xDelta = xAxis * speedVector.x();
const QVector3D yDelta = yAxis * moveVector.y(); const QVector3D yDelta = yAxis * speedVector.y();
const QVector3D zDelta = zAxis * moveVector.z(); const QVector3D zDelta = zAxis * speedVector.z();
// Delta multiplier for nice default speed in default scene const QVector3D delta = (yDelta - xDelta - zDelta);
const QVector3D delta = (yDelta - xDelta - zDelta) * .5f;
camera->setPosition(camera->position() + delta); 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 QString GeneralHelper::formatVectorDragTooltip(const QVector3D &vec, const QString &suffix) const
{ {
return QObject::tr("x:%L1 y:%L2 z:%L3%L4") 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()); && 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;
}
}
} }
} }

View File

@@ -139,6 +139,7 @@ public:
void setSnapRotationInterval(double interval) { m_snapRotationInterval = interval; } void setSnapRotationInterval(double interval) { m_snapRotationInterval = interval; }
void setSnapScaleInterval(double interval) { m_snapScaleInterval = interval / 100.; } void setSnapScaleInterval(double interval) { m_snapScaleInterval = interval / 100.; }
void setCameraSpeed(double speed); void setCameraSpeed(double speed);
Q_INVOKABLE void setCameraSpeedModifier(double modifier);
Q_INVOKABLE QString snapPositionDragTooltip(const QVector3D &pos) const; Q_INVOKABLE QString snapPositionDragTooltip(const QVector3D &pos) const;
Q_INVOKABLE QString snapRotationDragTooltip(double angle) 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 compareVectors(const QVector3D &v1, const QVector3D &v2) const;
Q_INVOKABLE bool compareQuaternions(const QQuaternion &q1, const QQuaternion &q2) const; Q_INVOKABLE bool compareQuaternions(const QQuaternion &q1, const QQuaternion &q2) const;
Q_INVOKABLE void requestTimerEvent(const QString &timerId, qint64 delay);
signals: signals:
void overlayUpdateNeeded(); void overlayUpdateNeeded();
void toolStateChanged(const QString &sceneId, const QString &tool, const QVariant &toolState); void toolStateChanged(const QString &sceneId, const QString &tool, const QVariant &toolState);
@@ -167,6 +170,7 @@ signals:
void requestCameraMove(QQuick3DCamera *camera, const QVector3D &moveVector); void requestCameraMove(QQuick3DCamera *camera, const QVector3D &moveVector);
void requestRender(); void requestRender();
void cameraSpeedChanged(); void cameraSpeedChanged();
void requestedTimerEvent(const QString &timerId);
private: private:
void handlePendingToolStateUpdate(); void handlePendingToolStateUpdate();
@@ -224,6 +228,7 @@ private:
double m_cameraSpeedModifier = 1.; double m_cameraSpeedModifier = 1.;
QVariant m_bgColor; QVariant m_bgColor;
QHash<QString, QTimer *> m_eventTimers;
}; };
} }