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>
This commit is contained in:
Miikka Heikkinen
2024-03-22 17:45:21 +02:00
parent 778688154d
commit 5a49c16694
6 changed files with 81 additions and 1 deletions

View File

@@ -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>

Binary file not shown.

After

Width:  |  Height:  |  Size: 172 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 202 B

View File

@@ -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) => {

View File

@@ -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

View File

@@ -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);