forked from qt-creator/qt-creator
QmlDesigner: Implement better camera navigation in 3D edit view
Edit camera is now controlled as in Qt 3D Studio: ALT + left button orbits camera. ALT + middle button pans camera. ALT + right button zooms camera. Wheel zooms camera. Task-number: QDS-1206 Change-Id: Ia72644073d172b00483ceed8bcc5ffb8dce68741 Reviewed-by: Thomas Hartmann <thomas.hartmann@qt.io>
This commit is contained in:
@@ -46,7 +46,7 @@ Node {
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: designStudioNativeCameraControlHelper
|
||||
target: _generalHelper
|
||||
onOverlayUpdateNeeded: updateScale()
|
||||
}
|
||||
|
||||
|
118
share/qtcreator/qml/qmlpuppet/mockfiles/EditCameraController.qml
Normal file
118
share/qtcreator/qml/qmlpuppet/mockfiles/EditCameraController.qml
Normal file
@@ -0,0 +1,118 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2019 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of Qt Creator.
|
||||
**
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
import QtQuick 2.12
|
||||
import QtQuick3D 1.0
|
||||
|
||||
Item {
|
||||
id: cameraCtrl
|
||||
|
||||
property Camera camera: null
|
||||
|
||||
property vector3d _lookAtPoint
|
||||
property vector3d _pressPoint
|
||||
property vector3d _prevPoint
|
||||
property vector3d _startRotation
|
||||
property vector3d _startPosition
|
||||
property vector3d _startLookAtPoint
|
||||
property matrix4x4 _startTransform
|
||||
property bool _dragging
|
||||
property int _button
|
||||
property real _zoomFactor: 1
|
||||
property real _defaultCameraLookAtDistance: 0
|
||||
property Camera _prevCamera: null
|
||||
|
||||
function zoomRelative(distance)
|
||||
{
|
||||
_zoomFactor = _generalHelper.zoomCamera(camera, distance, _defaultCameraLookAtDistance,
|
||||
_lookAtPoint, _zoomFactor, true);
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
cameraCtrl._defaultCameraLookAtDistance = cameraCtrl.camera.position.length();
|
||||
}
|
||||
|
||||
onCameraChanged: {
|
||||
if (_prevCamera) {
|
||||
// Reset zoom on previous camera to ensure it's properties are good to copy to new cam
|
||||
_generalHelper.zoomCamera(_prevCamera, 0, _defaultCameraLookAtDistance, _lookAtPoint,
|
||||
1, false);
|
||||
|
||||
camera.position = _prevCamera.position;
|
||||
camera.rotation = _prevCamera.rotation;
|
||||
|
||||
// Apply correct zoom to new camera
|
||||
_generalHelper.zoomCamera(camera, 0, _defaultCameraLookAtDistance, _lookAtPoint,
|
||||
_zoomFactor, false);
|
||||
}
|
||||
_prevCamera = camera;
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
id: mouseHandler
|
||||
acceptedButtons: Qt.LeftButton | Qt.RightButton | Qt.MiddleButton
|
||||
hoverEnabled: false
|
||||
anchors.fill: parent
|
||||
onPositionChanged: {
|
||||
if (mouse.modifiers === Qt.AltModifier && cameraCtrl._dragging) {
|
||||
var currentPoint = Qt.vector3d(mouse.x, mouse.y, 0);
|
||||
if (cameraCtrl._button == Qt.LeftButton) {
|
||||
_generalHelper.orbitCamera(cameraCtrl.camera, cameraCtrl._startRotation,
|
||||
cameraCtrl._lookAtPoint, cameraCtrl._pressPoint,
|
||||
currentPoint);
|
||||
} else if (cameraCtrl._button == Qt.MiddleButton) {
|
||||
cameraCtrl._lookAtPoint = _generalHelper.panCamera(
|
||||
cameraCtrl.camera, cameraCtrl._startTransform,
|
||||
cameraCtrl._startPosition, cameraCtrl._startLookAtPoint,
|
||||
cameraCtrl._pressPoint, currentPoint, _zoomFactor);
|
||||
} else if (cameraCtrl._button == Qt.RightButton) {
|
||||
cameraCtrl.zoomRelative(currentPoint.y - cameraCtrl._prevPoint.y)
|
||||
cameraCtrl._prevPoint = currentPoint;
|
||||
}
|
||||
}
|
||||
}
|
||||
onPressed: {
|
||||
if (mouse.modifiers === Qt.AltModifier) {
|
||||
cameraCtrl._dragging = true;
|
||||
cameraCtrl._startRotation = cameraCtrl.camera.rotation;
|
||||
cameraCtrl._startPosition = cameraCtrl.camera.position;
|
||||
cameraCtrl._startLookAtPoint = _lookAtPoint;
|
||||
cameraCtrl._pressPoint = Qt.vector3d(mouse.x, mouse.y, 0);
|
||||
cameraCtrl._prevPoint = cameraCtrl._pressPoint;
|
||||
cameraCtrl._button = mouse.button;
|
||||
cameraCtrl._startTransform = cameraCtrl.camera.sceneTransform;
|
||||
} else {
|
||||
mouse.accepted = false;
|
||||
}
|
||||
}
|
||||
|
||||
onReleased: cameraCtrl._dragging = false;
|
||||
onCanceled: cameraCtrl._dragging = false;
|
||||
onWheel: {
|
||||
// Emprically determined divisor for nice zoom
|
||||
cameraCtrl.zoomRelative(wheel.angleDelta.y / -40);
|
||||
}
|
||||
}
|
||||
}
|
@@ -26,7 +26,6 @@
|
||||
import QtQuick 2.12
|
||||
import QtQuick.Window 2.0
|
||||
import QtQuick3D 1.0
|
||||
import QtQuick3D.Helpers 1.0
|
||||
import QtQuick.Controls 2.0
|
||||
import QtGraphicalEffects 1.0
|
||||
|
||||
@@ -78,7 +77,7 @@ Window {
|
||||
{
|
||||
var component = Qt.createComponent("CameraGizmo.qml");
|
||||
if (component.status === Component.Ready) {
|
||||
var geometryName = designStudioNativeCameraControlHelper.generateUniqueName("CameraGeometry");
|
||||
var geometryName = _generalHelper.generateUniqueName("CameraGeometry");
|
||||
var gizmo = component.createObject(
|
||||
overlayScene,
|
||||
{"view3D": overlayView, "targetNode": obj, "geometryName": geometryName,
|
||||
@@ -92,10 +91,10 @@ Window {
|
||||
|
||||
// Work-around the fact that the projection matrix for the camera is not calculated until
|
||||
// the first frame is rendered, so any initial calls to mapFrom3DScene() will fail.
|
||||
Component.onCompleted: designStudioNativeCameraControlHelper.requestOverlayUpdate();
|
||||
Component.onCompleted: _generalHelper.requestOverlayUpdate();
|
||||
|
||||
onWidthChanged: designStudioNativeCameraControlHelper.requestOverlayUpdate();
|
||||
onHeightChanged: designStudioNativeCameraControlHelper.requestOverlayUpdate();
|
||||
onWidthChanged: _generalHelper.requestOverlayUpdate();
|
||||
onHeightChanged: _generalHelper.requestOverlayUpdate();
|
||||
|
||||
Node {
|
||||
id: overlayScene
|
||||
@@ -114,6 +113,7 @@ Window {
|
||||
clipNear: editOrthoCamera.clipNear
|
||||
position: editOrthoCamera.position
|
||||
rotation: editOrthoCamera.rotation
|
||||
scale: editOrthoCamera.scale
|
||||
}
|
||||
|
||||
MoveGizmo {
|
||||
@@ -209,11 +209,14 @@ Window {
|
||||
linearFade: 0
|
||||
}
|
||||
|
||||
// Initial camera position and rotation should be such that they look at origin.
|
||||
// Otherwise EditCameraController._lookAtPoint needs to be initialized to correct
|
||||
// point.
|
||||
PerspectiveCamera {
|
||||
id: editPerspectiveCamera
|
||||
z: -600
|
||||
y: 200
|
||||
rotation.x: 30
|
||||
y: 600
|
||||
rotation.x: 45
|
||||
clipFar: 100000
|
||||
clipNear: 1
|
||||
}
|
||||
@@ -221,8 +224,8 @@ Window {
|
||||
OrthographicCamera {
|
||||
id: editOrthoCamera
|
||||
z: -600
|
||||
y: 200
|
||||
rotation.x: 30
|
||||
y: 600
|
||||
rotation.x: 45
|
||||
clipFar: 100000
|
||||
clipNear: 1
|
||||
}
|
||||
@@ -273,19 +276,10 @@ Window {
|
||||
}
|
||||
}
|
||||
|
||||
WasdController {
|
||||
EditCameraController {
|
||||
id: cameraControl
|
||||
controlledObject: editView.camera
|
||||
acceptedButtons: Qt.RightButton
|
||||
|
||||
onInputsNeedProcessingChanged: designStudioNativeCameraControlHelper.enabled
|
||||
= cameraControl.inputsNeedProcessing
|
||||
|
||||
// Use separate native timer as QML timers don't work inside Qt Design Studio
|
||||
Connections {
|
||||
target: designStudioNativeCameraControlHelper
|
||||
onUpdateInputs: cameraControl.processInputs()
|
||||
}
|
||||
camera: editView.camera
|
||||
anchors.fill: parent
|
||||
}
|
||||
}
|
||||
|
||||
@@ -365,39 +359,25 @@ Window {
|
||||
id: editLightCheckbox
|
||||
checked: false
|
||||
text: qsTr("Use Edit View Light")
|
||||
onCheckedChanged: cameraControl.forceActiveFocus()
|
||||
}
|
||||
|
||||
CheckBox {
|
||||
id: usePerspectiveCheckbox
|
||||
checked: true
|
||||
text: qsTr("Use Perspective Projection")
|
||||
onCheckedChanged: {
|
||||
// Since WasdController always acts on active camera, we need to update pos/rot
|
||||
// to the other camera when we change
|
||||
if (checked) {
|
||||
editPerspectiveCamera.position = editOrthoCamera.position;
|
||||
editPerspectiveCamera.rotation = editOrthoCamera.rotation;
|
||||
} else {
|
||||
editOrthoCamera.position = editPerspectiveCamera.position;
|
||||
editOrthoCamera.rotation = editPerspectiveCamera.rotation;
|
||||
}
|
||||
designStudioNativeCameraControlHelper.requestOverlayUpdate();
|
||||
cameraControl.forceActiveFocus();
|
||||
}
|
||||
onCheckedChanged: _generalHelper.requestOverlayUpdate()
|
||||
}
|
||||
|
||||
CheckBox {
|
||||
id: globalControl
|
||||
checked: true
|
||||
text: qsTr("Use Global Orientation")
|
||||
onCheckedChanged: cameraControl.forceActiveFocus()
|
||||
}
|
||||
}
|
||||
|
||||
Text {
|
||||
id: helpText
|
||||
text: qsTr("Camera: W,A,S,D,R,F,right mouse drag")
|
||||
text: qsTr("Camera controls: ALT + mouse press and drag. Left: Rotate, Middle: Pan, Right/Wheel: Zoom.")
|
||||
anchors.bottom: parent.bottom
|
||||
}
|
||||
}
|
||||
|
@@ -49,7 +49,7 @@ Item {
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: designStudioNativeCameraControlHelper
|
||||
target: _generalHelper
|
||||
onOverlayUpdateNeeded: updateOverlay()
|
||||
}
|
||||
|
||||
|
@@ -1,78 +0,0 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2019 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of Qt Creator.
|
||||
**
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
****************************************************************************/
|
||||
#include "cameracontrolhelper.h"
|
||||
|
||||
#include <QHash>
|
||||
|
||||
namespace QmlDesigner {
|
||||
namespace Internal {
|
||||
|
||||
CameraControlHelper::CameraControlHelper()
|
||||
: QObject()
|
||||
{
|
||||
m_inputUpdateTimer.setInterval(16);
|
||||
QObject::connect(&m_inputUpdateTimer, &QTimer::timeout,
|
||||
this, &CameraControlHelper::handleUpdateTimer);
|
||||
|
||||
m_overlayUpdateTimer.setInterval(16);
|
||||
m_overlayUpdateTimer.setSingleShot(true);
|
||||
QObject::connect(&m_overlayUpdateTimer, &QTimer::timeout,
|
||||
this, &CameraControlHelper::overlayUpdateNeeded);
|
||||
}
|
||||
|
||||
bool CameraControlHelper::enabled()
|
||||
{
|
||||
return m_enabled;
|
||||
}
|
||||
|
||||
void CameraControlHelper::handleUpdateTimer()
|
||||
{
|
||||
emit updateInputs();
|
||||
}
|
||||
|
||||
void CameraControlHelper::setEnabled(bool enabled)
|
||||
{
|
||||
if (enabled)
|
||||
m_inputUpdateTimer.start();
|
||||
else
|
||||
m_inputUpdateTimer.stop();
|
||||
m_enabled = enabled;
|
||||
}
|
||||
|
||||
void CameraControlHelper::requestOverlayUpdate()
|
||||
{
|
||||
if (!m_overlayUpdateTimer.isActive())
|
||||
m_overlayUpdateTimer.start();
|
||||
}
|
||||
|
||||
QString CameraControlHelper::generateUniqueName(const QString &nameRoot)
|
||||
{
|
||||
static QHash<QString, int> counters;
|
||||
int count = counters[nameRoot]++;
|
||||
return QStringLiteral("%1_%2").arg(nameRoot).arg(count);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@@ -1,9 +1,9 @@
|
||||
HEADERS += $$PWD/cameracontrolhelper.h \
|
||||
HEADERS += $$PWD/generalhelper.h \
|
||||
$$PWD/mousearea3d.h \
|
||||
$$PWD/camerageometry.h \
|
||||
$$PWD/gridgeometry.h
|
||||
|
||||
SOURCES += $$PWD/cameracontrolhelper.cpp \
|
||||
SOURCES += $$PWD/generalhelper.cpp \
|
||||
$$PWD/mousearea3d.cpp \
|
||||
$$PWD/camerageometry.cpp \
|
||||
$$PWD/gridgeometry.cpp
|
||||
|
@@ -0,0 +1,132 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2019 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of Qt Creator.
|
||||
**
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
****************************************************************************/
|
||||
#include "generalhelper.h"
|
||||
|
||||
#ifdef QUICK3D_MODULE
|
||||
|
||||
#include <QtQuick3D/private/qquick3dorthographiccamera_p.h>
|
||||
#include <QtQuick3D/private/qquick3dperspectivecamera_p.h>
|
||||
#include <QtCore/qhash.h>
|
||||
#include <QtGui/qmatrix4x4.h>
|
||||
|
||||
namespace QmlDesigner {
|
||||
namespace Internal {
|
||||
|
||||
GeneralHelper::GeneralHelper()
|
||||
: QObject()
|
||||
{
|
||||
m_overlayUpdateTimer.setInterval(16);
|
||||
m_overlayUpdateTimer.setSingleShot(true);
|
||||
QObject::connect(&m_overlayUpdateTimer, &QTimer::timeout,
|
||||
this, &GeneralHelper::overlayUpdateNeeded);
|
||||
}
|
||||
|
||||
void GeneralHelper::requestOverlayUpdate()
|
||||
{
|
||||
if (!m_overlayUpdateTimer.isActive())
|
||||
m_overlayUpdateTimer.start();
|
||||
}
|
||||
|
||||
QString GeneralHelper::generateUniqueName(const QString &nameRoot)
|
||||
{
|
||||
static QHash<QString, int> counters;
|
||||
int count = counters[nameRoot]++;
|
||||
return QStringLiteral("%1_%2").arg(nameRoot).arg(count);
|
||||
}
|
||||
|
||||
void GeneralHelper::orbitCamera(QQuick3DCamera *camera, const QVector3D &startRotation,
|
||||
const QVector3D &lookAtPoint, const QVector3D &pressPos,
|
||||
const QVector3D ¤tPos)
|
||||
{
|
||||
QVector3D dragVector = currentPos - pressPos;
|
||||
|
||||
if (dragVector.length() < 0.001f)
|
||||
return;
|
||||
|
||||
camera->setRotation(startRotation);
|
||||
QVector3D newRotation(dragVector.y(), dragVector.x(), 0.f);
|
||||
newRotation *= 0.5f; // Emprically determined multiplier for nice drag
|
||||
newRotation += startRotation;
|
||||
|
||||
camera->setRotation(newRotation);
|
||||
|
||||
const QVector3D oldLookVector = camera->position() - lookAtPoint;
|
||||
QMatrix4x4 m = camera->sceneTransform();
|
||||
const float *dataPtr(m.data());
|
||||
QVector3D newLookVector(-dataPtr[8], -dataPtr[9], -dataPtr[10]);
|
||||
newLookVector.normalize();
|
||||
newLookVector *= oldLookVector.length();
|
||||
|
||||
camera->setPosition(lookAtPoint + newLookVector);
|
||||
}
|
||||
|
||||
// Pans camera and returns the new look-at point
|
||||
QVector3D GeneralHelper::panCamera(QQuick3DCamera *camera, const QMatrix4x4 startTransform,
|
||||
const QVector3D &startPosition, const QVector3D &startLookAt,
|
||||
const QVector3D &pressPos, const QVector3D ¤tPos,
|
||||
float zoomFactor)
|
||||
{
|
||||
QVector3D dragVector = currentPos - pressPos;
|
||||
|
||||
if (dragVector.length() < 0.001f)
|
||||
return startLookAt;
|
||||
|
||||
const float *dataPtr(startTransform.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 xDelta = -1.f * xAxis * dragVector.x();
|
||||
const QVector3D yDelta = yAxis * dragVector.y();
|
||||
const QVector3D delta = (xDelta + yDelta) * zoomFactor;
|
||||
|
||||
camera->setPosition(startPosition + delta);
|
||||
return startLookAt + delta;
|
||||
}
|
||||
|
||||
float GeneralHelper::zoomCamera(QQuick3DCamera *camera, float distance, float defaultLookAtDistance,
|
||||
const QVector3D &lookAt, float zoomFactor, bool relative)
|
||||
{
|
||||
// Emprically determined divisor for nice zoom
|
||||
float multiplier = 1.f + (distance / 40.f);
|
||||
float newZoomFactor = relative ? qBound(.0001f, zoomFactor * multiplier, 10000.f)
|
||||
: zoomFactor;
|
||||
|
||||
if (qobject_cast<QQuick3DOrthographicCamera *>(camera)) {
|
||||
// Ortho camera we can simply scale
|
||||
camera->setScale(QVector3D(newZoomFactor, newZoomFactor, newZoomFactor));
|
||||
} else if (qobject_cast<QQuick3DPerspectiveCamera *>(camera)) {
|
||||
// Perspective camera is zoomed by moving camera forward or backward while keeping the
|
||||
// look-at point the same
|
||||
const QVector3D lookAtVec = (camera->position() - lookAt).normalized();
|
||||
const float newDistance = defaultLookAtDistance * newZoomFactor;
|
||||
camera->setPosition(lookAt + (lookAtVec * newDistance));
|
||||
}
|
||||
|
||||
return newZoomFactor;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif // QUICK3D_MODULE
|
@@ -25,38 +25,43 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QtCore/QObject>
|
||||
#include <QtCore/QTimer>
|
||||
#ifdef QUICK3D_MODULE
|
||||
|
||||
#include <QtQuick3D/private/qquick3dcamera_p.h>
|
||||
#include <QtCore/qobject.h>
|
||||
#include <QtCore/qtimer.h>
|
||||
|
||||
namespace QmlDesigner {
|
||||
namespace Internal {
|
||||
class CameraControlHelper : public QObject
|
||||
class GeneralHelper : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(bool enabled READ enabled WRITE setEnabled NOTIFY enabledChanged)
|
||||
|
||||
public:
|
||||
CameraControlHelper();
|
||||
|
||||
bool enabled();
|
||||
void setEnabled(bool enabled);
|
||||
GeneralHelper();
|
||||
|
||||
Q_INVOKABLE void requestOverlayUpdate();
|
||||
Q_INVOKABLE QString generateUniqueName(const QString &nameRoot);
|
||||
|
||||
public slots:
|
||||
void handleUpdateTimer();
|
||||
Q_INVOKABLE void orbitCamera(QQuick3DCamera *camera, const QVector3D &startRotation,
|
||||
const QVector3D &lookAtPoint, const QVector3D &pressPos,
|
||||
const QVector3D ¤tPos);
|
||||
Q_INVOKABLE QVector3D panCamera(QQuick3DCamera *camera, const QMatrix4x4 startTransform,
|
||||
const QVector3D &startPosition, const QVector3D &startLookAt,
|
||||
const QVector3D &pressPos, const QVector3D ¤tPos,
|
||||
float zoomFactor);
|
||||
Q_INVOKABLE float zoomCamera(QQuick3DCamera *camera, float distance,
|
||||
float defaultLookAtDistance, const QVector3D &lookAt,
|
||||
float zoomFactor, bool relative);
|
||||
|
||||
signals:
|
||||
void updateInputs();
|
||||
void enabledChanged(bool enabled);
|
||||
void overlayUpdateNeeded();
|
||||
|
||||
private:
|
||||
bool m_enabled = false;
|
||||
QTimer m_inputUpdateTimer;
|
||||
QTimer m_overlayUpdateTimer;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif // QUICK3D_MODULE
|
@@ -37,7 +37,6 @@ namespace QmlDesigner {
|
||||
namespace Internal {
|
||||
|
||||
MouseArea3D *MouseArea3D::s_mouseGrab = nullptr;
|
||||
static const qreal s_mouseDragMultiplier = .02;
|
||||
|
||||
MouseArea3D::MouseArea3D(QQuick3DNode *parent)
|
||||
: QQuick3DNode(parent)
|
||||
@@ -340,7 +339,7 @@ qreal QmlDesigner::Internal::MouseArea3D::getNewRotationAngle(
|
||||
dragDir = (screenDragDir - nodePos).normalized();
|
||||
const QVector3D pressToCurrent = (currentPos - pressPos);
|
||||
float magnitude = QVector3D::dotProduct(pressToCurrent, dragDir);
|
||||
qreal angle = -s_mouseDragMultiplier * qreal(magnitude);
|
||||
qreal angle = -mouseDragMultiplier() * qreal(magnitude);
|
||||
return angle;
|
||||
} else {
|
||||
const QVector3D nodeToPress = (pressPos - nodePos).normalized();
|
||||
@@ -397,7 +396,7 @@ void MouseArea3D::applyFreeRotation(QQuick3DNode *node, const QVector3D &startRo
|
||||
|
||||
QVector3D finalAxis = (dragVector.x() * yAxis + dragVector.y() * xAxis);
|
||||
|
||||
qreal degrees = qRadiansToDegrees(qreal(finalAxis.length()) * s_mouseDragMultiplier);
|
||||
qreal degrees = qRadiansToDegrees(qreal(finalAxis.length()) * mouseDragMultiplier());
|
||||
|
||||
finalAxis.normalize();
|
||||
|
||||
|
@@ -51,7 +51,7 @@ class MouseArea3D : public QQuick3DNode
|
||||
Q_PROPERTY(bool hovering READ hovering NOTIFY hoveringChanged)
|
||||
Q_PROPERTY(bool dragging READ dragging NOTIFY draggingChanged)
|
||||
Q_PROPERTY(int priority READ priority WRITE setPriority NOTIFY priorityChanged)
|
||||
Q_PROPERTY(int active READ active WRITE setActive NOTIFY activeChanged)
|
||||
Q_PROPERTY(bool active READ active WRITE setActive NOTIFY activeChanged)
|
||||
Q_PROPERTY(QPointF circlePickArea READ circlePickArea WRITE setCirclePickArea NOTIFY circlePickAreaChanged)
|
||||
Q_PROPERTY(qreal minAngle READ minAngle WRITE setMinAngle NOTIFY minAngleChanged)
|
||||
Q_PROPERTY(QQuick3DNode *pickNode READ pickNode WRITE setPickNode NOTIFY pickNodeChanged)
|
||||
@@ -77,6 +77,8 @@ public:
|
||||
qreal minAngle() const;
|
||||
QQuick3DNode *pickNode() const;
|
||||
|
||||
static qreal mouseDragMultiplier() { return .02; }
|
||||
|
||||
public slots:
|
||||
void setView3D(QQuick3DViewport *view3D);
|
||||
void setGrabsMouse(bool grabsMouse);
|
||||
@@ -157,7 +159,7 @@ private:
|
||||
QVector3D getMousePosInPlane(const QPointF &mousePosInView) const;
|
||||
|
||||
static MouseArea3D *s_mouseGrab;
|
||||
bool m_grabsMouse;
|
||||
bool m_grabsMouse = false;
|
||||
QVector3D m_mousePosInPlane;
|
||||
QPointF m_circlePickArea;
|
||||
qreal m_minAngle = 0.;
|
||||
|
@@ -62,7 +62,7 @@
|
||||
#include <drop3dlibraryitemcommand.h>
|
||||
|
||||
#include "dummycontextobject.h"
|
||||
#include "../editor3d/cameracontrolhelper.h"
|
||||
#include "../editor3d/generalhelper.h"
|
||||
#include "../editor3d/mousearea3d.h"
|
||||
#include "../editor3d/camerageometry.h"
|
||||
#include "../editor3d/gridgeometry.h"
|
||||
@@ -104,10 +104,9 @@ bool Qt5InformationNodeInstanceServer::eventFilter(QObject *, QEvent *event)
|
||||
|
||||
QObject *Qt5InformationNodeInstanceServer::createEditView3D(QQmlEngine *engine)
|
||||
{
|
||||
auto helper = new QmlDesigner::Internal::CameraControlHelper();
|
||||
engine->rootContext()->setContextProperty("designStudioNativeCameraControlHelper", helper);
|
||||
|
||||
#ifdef QUICK3D_MODULE
|
||||
auto helper = new QmlDesigner::Internal::GeneralHelper();
|
||||
engine->rootContext()->setContextProperty("_generalHelper", helper);
|
||||
qmlRegisterType<QmlDesigner::Internal::MouseArea3D>("MouseArea3D", 1, 0, "MouseArea3D");
|
||||
qmlRegisterType<QmlDesigner::Internal::CameraGeometry>("CameraGeometry", 1, 0, "CameraGeometry");
|
||||
qmlRegisterType<QmlDesigner::Internal::GridGeometry>("GridGeometry", 1, 0, "GridGeometry");
|
||||
|
@@ -8,6 +8,7 @@
|
||||
<file>mockfiles/GenericBackend.qml</file>
|
||||
<file>mockfiles/Dialog.qml</file>
|
||||
<file>mockfiles/EditView3D.qml</file>
|
||||
<file>mockfiles/EditCameraController.qml</file>
|
||||
<file>mockfiles/Arrow.qml</file>
|
||||
<file>mockfiles/AutoScaleHelper.qml</file>
|
||||
<file>mockfiles/MoveGizmo.qml</file>
|
||||
|
@@ -108,7 +108,7 @@ extend_qtc_executable(qml2puppet
|
||||
extend_qtc_executable(qml2puppet
|
||||
SOURCES_PREFIX "${SRCDIR}/qml2puppet/editor3d"
|
||||
SOURCES
|
||||
cameracontrolhelper.cpp cameracontrolhelper.h
|
||||
generalhelper.cpp generalhelper.h
|
||||
mousearea3d.cpp mousearea3d.h
|
||||
camerageometry.cpp camerageometry.h
|
||||
gridgeometry.cpp gridgeometry.h
|
||||
|
@@ -197,8 +197,8 @@ QtcTool {
|
||||
"instances/qt5testnodeinstanceserver.h",
|
||||
"instances/servernodeinstance.cpp",
|
||||
"instances/servernodeinstance.h",
|
||||
"editor3d/cameracontrolhelper.cpp",
|
||||
"editor3d/cameracontrolhelper.h",
|
||||
"editor3d/generalhelper.cpp",
|
||||
"editor3d/generalhelper.h",
|
||||
"editor3d/mousearea3d.cpp",
|
||||
"editor3d/mousearea3d.h",
|
||||
"editor3d/camerageometry.cpp",
|
||||
|
Reference in New Issue
Block a user