aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMiikka Heikkinen <miikka.heikkinen@qt.io>2024-03-22 17:45:21 +0200
committerMiikka Heikkinen <miikka.heikkinen@qt.io>2024-04-19 14:52:05 +0000
commit5a49c1669437ef2d4e1c2e284c912cb774495999 (patch)
treec0eac17c8882b22305e168d61d5ef65fb34b415c /src
parent778688154d55719b2b53ff8747003cd0fb18bf2e (diff)
QmlDesigner: Use space key to move close to object at crosshairs
When in fly mode in 3D view, crosshairs are shown in the middle of the active split. Pressing space in fly mode when there is a model at the crosshairs will move the camera close to the model. Fixes: QDS-12292 Change-Id: Id15c13458af3763f4e0712614cf9cf3ed695fb5d Reviewed-by: Qt CI Patch Build Bot <ci_patchbuild_bot@qt.io> Reviewed-by: Mahmoud Badri <mahmoud.badri@qt.io>
Diffstat (limited to 'src')
-rw-r--r--src/tools/qml2puppet/editor3d_qt6.qrc2
-rw-r--r--src/tools/qml2puppet/mockfiles/images/crosshair.pngbin0 -> 172 bytes
-rw-r--r--src/tools/qml2puppet/mockfiles/images/crosshair@2x.pngbin0 -> 202 bytes
-rw-r--r--src/tools/qml2puppet/mockfiles/qt6/EditCameraController.qml29
-rw-r--r--src/tools/qml2puppet/qml2puppet/editor3d/generalhelper.cpp49
-rw-r--r--src/tools/qml2puppet/qml2puppet/editor3d/generalhelper.h2
6 files changed, 81 insertions, 1 deletions
diff --git a/src/tools/qml2puppet/editor3d_qt6.qrc b/src/tools/qml2puppet/editor3d_qt6.qrc
index 2913fbe15e..d76b1941b9 100644
--- a/src/tools/qml2puppet/editor3d_qt6.qrc
+++ b/src/tools/qml2puppet/editor3d_qt6.qrc
@@ -8,6 +8,8 @@
<file>mockfiles/images/editor_camera@2x.png</file>
<file>mockfiles/images/editor_particlesystem.png</file>
<file>mockfiles/images/editor_particlesystem@2x.png</file>
+ <file>mockfiles/images/crosshair.png</file>
+ <file>mockfiles/images/crosshair@2x.png</file>
<file>mockfiles/images/directional.png</file>
<file>mockfiles/images/directional@2x.png</file>
<file>mockfiles/images/point.png</file>
diff --git a/src/tools/qml2puppet/mockfiles/images/crosshair.png b/src/tools/qml2puppet/mockfiles/images/crosshair.png
new file mode 100644
index 0000000000..6c30263513
--- /dev/null
+++ b/src/tools/qml2puppet/mockfiles/images/crosshair.png
Binary files differ
diff --git a/src/tools/qml2puppet/mockfiles/images/crosshair@2x.png b/src/tools/qml2puppet/mockfiles/images/crosshair@2x.png
new file mode 100644
index 0000000000..5340bf0846
--- /dev/null
+++ b/src/tools/qml2puppet/mockfiles/images/crosshair@2x.png
Binary files differ
diff --git a/src/tools/qml2puppet/mockfiles/qt6/EditCameraController.qml b/src/tools/qml2puppet/mockfiles/qt6/EditCameraController.qml
index 2d77aaf987..255d93e529 100644
--- a/src/tools/qml2puppet/mockfiles/qt6/EditCameraController.qml
+++ b/src/tools/qml2puppet/mockfiles/qt6/EditCameraController.qml
@@ -102,6 +102,23 @@ Item {
storeCameraState(0);
}
+ function approachObject()
+ {
+ if (!camera)
+ return;
+
+ var pickResult = _generalHelper.pickViewAt(view3d, width / 2, height / 2);
+ var resolvedResult = _generalHelper.resolvePick(pickResult.objectHit);
+
+ if (resolvedResult) {
+ var newLookAtAndZoom = _generalHelper.approachNode(camera, _defaultCameraLookAtDistance,
+ resolvedResult, view3D);
+ _lookAtPoint = newLookAtAndZoom.toVector3d();
+ _zoomFactor = newLookAtAndZoom.w;
+ storeCameraState(0);
+ }
+ }
+
function jumpToRotation(rotation)
{
let distance = camera.scenePosition.minus(_lookAtPoint).length()
@@ -240,6 +257,13 @@ Item {
}
}
+ Image {
+ anchors.centerIn: parent
+ source: "qrc:///qtquickplugin/mockfiles/images/crosshair.png"
+ visible: cameraCtrl.flyMode && viewRoot.activeSplit === cameraCtrl.splitId
+ opacity: 0.7
+ }
+
MouseArea {
id: mouseHandler
acceptedButtons: Qt.LeftButton | Qt.RightButton | Qt.MiddleButton
@@ -304,7 +328,10 @@ Item {
Keys.onPressed: (event) => {
event.accepted = true;
- _generalHelper.startCameraMove(cameraCtrl.camera, cameraCtrl.getMoveVectorForKey(event.key));
+ if (cameraCtrl.flyMode && event.key === Qt.Key_Space)
+ approachObject();
+ else
+ _generalHelper.startCameraMove(cameraCtrl.camera, cameraCtrl.getMoveVectorForKey(event.key));
}
Keys.onReleased: (event) => {
diff --git a/src/tools/qml2puppet/qml2puppet/editor3d/generalhelper.cpp b/src/tools/qml2puppet/qml2puppet/editor3d/generalhelper.cpp
index b33a480a45..dadd817633 100644
--- a/src/tools/qml2puppet/qml2puppet/editor3d/generalhelper.cpp
+++ b/src/tools/qml2puppet/qml2puppet/editor3d/generalhelper.cpp
@@ -398,6 +398,55 @@ QVector4D GeneralHelper::focusNodesToCamera(QQuick3DCamera *camera, float defaul
return QVector4D(lookAt, cameraZoomFactor);
}
+// Approaches the specified node without changing camera orientation
+QVector4D GeneralHelper::approachNode(
+ QQuick3DCamera *camera, float defaultLookAtDistance, QObject *node,
+ QQuick3DViewport *viewPort)
+{
+ auto node3d = qobject_cast<QQuick3DNode *>(node);
+ if (!camera || !node3d)
+ return QVector4D(0.f, 0.f, 0.f, 1.f);
+
+ QVector3D minBounds = maxVec;
+ QVector3D maxBounds = minVec;
+
+ getBounds(viewPort, node3d, minBounds, maxBounds); // Bounds are in node3d local coordinates
+
+ QVector3D extents = maxBounds - minBounds;
+ QVector3D focusLookAt = minBounds + (extents / 2.f);
+
+ if (node3d->parentNode()) {
+ QMatrix4x4 m = node3d->parentNode()->sceneTransform();
+ focusLookAt = m.map(focusLookAt);
+ }
+
+ float maxExtent = qSqrt(qreal(extents.x()) * qreal(extents.x())
+ + qreal(extents.y()) * qreal(extents.y())
+ + qreal(extents.z()) * qreal(extents.z()));
+
+ // Reset camera position to default zoom
+ QMatrix4x4 m = camera->sceneTransform();
+ const float *dataPtr(m.data());
+ QVector3D newLookVector(dataPtr[8], dataPtr[9], dataPtr[10]);
+ newLookVector.normalize();
+
+ // We don't want to change camera orientation, so calculate projection point on current
+ // camera look vector
+ QVector3D focusLookAtVector = focusLookAt - camera->position();
+ float dot = QVector3D::dotProduct(newLookVector, focusLookAtVector);
+ QVector3D newLookAt = camera->position() + dot * newLookVector;
+
+ newLookVector *= defaultLookAtDistance;
+ camera->setPosition(newLookAt + newLookVector);
+
+ float divisor = 1050.f;
+ float newZoomFactor = qBound(.01f, maxExtent / divisor, 100.f);
+ float cameraZoomFactor = zoomCamera(viewPort, camera, 0, defaultLookAtDistance, newLookAt,
+ newZoomFactor, false);
+
+ return QVector4D(newLookAt, cameraZoomFactor);
+}
+
// This function can be used to synchronously focus camera on a node, which doesn't have to be
// a selection box for bound calculations to work. This is used to focus the view for
// various preview image generations, where doing things asynchronously is not good
diff --git a/src/tools/qml2puppet/qml2puppet/editor3d/generalhelper.h b/src/tools/qml2puppet/qml2puppet/editor3d/generalhelper.h
index 5622918a64..62a95d86a6 100644
--- a/src/tools/qml2puppet/qml2puppet/editor3d/generalhelper.h
+++ b/src/tools/qml2puppet/qml2puppet/editor3d/generalhelper.h
@@ -70,6 +70,8 @@ public:
const QVariant &nodes, QQuick3DViewport *viewPort,
float oldZoom, bool updateZoom = true,
bool closeUp = false);
+ Q_INVOKABLE QVector4D approachNode(QQuick3DCamera *camera, float defaultLookAtDistance,
+ QObject *node, QQuick3DViewport *viewPort);
Q_INVOKABLE void calculateNodeBoundsAndFocusCamera(QQuick3DCamera *camera, QQuick3DNode *node,
QQuick3DViewport *viewPort,
float defaultLookAtDistance, bool closeUp);