forked from qt-creator/qt-creator
QmlDesigner: Add look-at gizmo to visualize 3D edit camera look-at pos
Look-at gizmo can be toggled from visibility toggles submenu. Look-at gizmo is hidden when fly mode crosshairs is visible. Fixes: QDS-12767 Change-Id: I2c71b23f14e403c9774498937764607cfea3bd1d Reviewed-by: Mahmoud Badri <mahmoud.badri@qt.io>
This commit is contained in:
@@ -36,6 +36,7 @@ enum class View3DActionType {
|
||||
OrientationToggle,
|
||||
EditLightToggle,
|
||||
ShowGrid,
|
||||
ShowLookAt,
|
||||
ShowSelectionBox,
|
||||
ShowIconGizmo,
|
||||
ShowCameraFrustum,
|
||||
|
@@ -135,6 +135,7 @@ void Edit3DView::updateActiveScene3D(const QVariantMap &sceneState)
|
||||
const QString orientationKey = QStringLiteral("globalOrientation");
|
||||
const QString editLightKey = QStringLiteral("showEditLight");
|
||||
const QString gridKey = QStringLiteral("showGrid");
|
||||
const QString showLookAtKey = QStringLiteral("showLookAt");
|
||||
const QString selectionBoxKey = QStringLiteral("showSelectionBox");
|
||||
const QString iconGizmoKey = QStringLiteral("showIconGizmo");
|
||||
const QString cameraFrustumKey = QStringLiteral("showCameraFrustum");
|
||||
@@ -189,6 +190,11 @@ void Edit3DView::updateActiveScene3D(const QVariantMap &sceneState)
|
||||
else
|
||||
m_showGridAction->action()->setChecked(false);
|
||||
|
||||
if (sceneState.contains(showLookAtKey))
|
||||
m_showLookAtAction->action()->setChecked(sceneState[showLookAtKey].toBool());
|
||||
else
|
||||
m_showLookAtAction->action()->setChecked(false);
|
||||
|
||||
if (sceneState.contains(selectionBoxKey))
|
||||
m_showSelectionBoxAction->action()->setChecked(sceneState[selectionBoxKey].toBool());
|
||||
else
|
||||
@@ -1040,6 +1046,18 @@ void Edit3DView::createEdit3DActions()
|
||||
nullptr,
|
||||
QCoreApplication::translate("ShowGridAction", "Toggle the visibility of the helper grid."));
|
||||
|
||||
m_showLookAtAction = std::make_unique<Edit3DAction>(
|
||||
QmlDesigner::Constants::EDIT3D_EDIT_SHOW_LOOKAT,
|
||||
View3DActionType::ShowLookAt,
|
||||
QCoreApplication::translate("ShowLookAtAction", "Show Look-at"),
|
||||
QKeySequence(Qt::Key_L),
|
||||
true,
|
||||
true,
|
||||
QIcon(),
|
||||
this,
|
||||
nullptr,
|
||||
QCoreApplication::translate("ShowLookAtAction", "Toggle the visibility of the edit camera look-at indicator."));
|
||||
|
||||
m_showSelectionBoxAction = std::make_unique<Edit3DAction>(
|
||||
QmlDesigner::Constants::EDIT3D_EDIT_SHOW_SELECTION_BOX,
|
||||
View3DActionType::ShowSelectionBox,
|
||||
@@ -1343,6 +1361,7 @@ void Edit3DView::createEdit3DActions()
|
||||
m_rightActions << m_resetAction.get();
|
||||
|
||||
m_visibilityToggleActions << m_showGridAction.get();
|
||||
m_visibilityToggleActions << m_showLookAtAction.get();
|
||||
m_visibilityToggleActions << m_showSelectionBoxAction.get();
|
||||
m_visibilityToggleActions << m_showIconGizmoAction.get();
|
||||
m_visibilityToggleActions << m_showCameraFrustumAction.get();
|
||||
|
@@ -159,6 +159,7 @@ private:
|
||||
std::unique_ptr<Edit3DAction> m_orientationModeAction;
|
||||
std::unique_ptr<Edit3DAction> m_editLightAction;
|
||||
std::unique_ptr<Edit3DAction> m_showGridAction;
|
||||
std::unique_ptr<Edit3DAction> m_showLookAtAction;
|
||||
std::unique_ptr<Edit3DAction> m_showSelectionBoxAction;
|
||||
std::unique_ptr<Edit3DAction> m_showIconGizmoAction;
|
||||
std::unique_ptr<Edit3DAction> m_showCameraFrustumAction;
|
||||
|
@@ -50,6 +50,7 @@ inline constexpr char EDIT3D_EDIT_CAMERA[] = "QmlDesigner.Editor3D.EditCameraTog
|
||||
inline constexpr char EDIT3D_ORIENTATION[] = "QmlDesigner.Editor3D.OrientationToggle";
|
||||
inline constexpr char EDIT3D_EDIT_LIGHT[] = "QmlDesigner.Editor3D.EditLightToggle";
|
||||
inline constexpr char EDIT3D_EDIT_SHOW_GRID[] = "QmlDesigner.Editor3D.ToggleGrid";
|
||||
inline constexpr char EDIT3D_EDIT_SHOW_LOOKAT[] = "QmlDesigner.Editor3D.ToggleLookAt";
|
||||
inline constexpr char EDIT3D_EDIT_SELECT_BACKGROUND_COLOR[]
|
||||
= "QmlDesigner.Editor3D.SelectBackgroundColor";
|
||||
inline constexpr char EDIT3D_EDIT_SELECT_GRID_COLOR[] = "QmlDesigner.Editor3D.SelectGridColor";
|
||||
|
@@ -93,6 +93,7 @@ extend_qtc_executable(qml2puppet
|
||||
linegeometry.cpp linegeometry.h
|
||||
icongizmoimageprovider.cpp icongizmoimageprovider.h
|
||||
boxgeometry.cpp boxgeometry.h
|
||||
lookatgeometry.cpp lookatgeometry.h
|
||||
)
|
||||
|
||||
find_package(Qt6 COMPONENTS Quick3DAssetImport QUIET)
|
||||
|
@@ -37,6 +37,7 @@
|
||||
<file>mockfiles/qt6/LightIconGizmo.qml</file>
|
||||
<file>mockfiles/qt6/LightModel.qml</file>
|
||||
<file>mockfiles/qt6/Line3D.qml</file>
|
||||
<file>mockfiles/qt6/LookAtGizmo.qml</file>
|
||||
<file>mockfiles/qt6/MaterialNodeView.qml</file>
|
||||
<file>mockfiles/qt6/ModelNode2DImageView.qml</file>
|
||||
<file>mockfiles/qt6/ModelNode3DImageView.qml</file>
|
||||
|
@@ -29,7 +29,7 @@ Item {
|
||||
readonly property real _keyPanAmount: 1.0
|
||||
property bool ignoreToolState: false
|
||||
property bool flyMode: viewRoot.flyMode
|
||||
property bool hasMovedInFlyMode: false
|
||||
property bool showCrosshairs: false
|
||||
|
||||
z: 10
|
||||
anchors.fill: parent
|
||||
@@ -175,14 +175,14 @@ Item {
|
||||
function rotateCamera(angles)
|
||||
{
|
||||
if (flyMode)
|
||||
hasMovedInFlyMode = true;
|
||||
showCrosshairs = true;
|
||||
cameraCtrl._lookAtPoint = _generalHelper.rotateCamera(camera, angles, _lookAtPoint);
|
||||
}
|
||||
|
||||
function moveCamera(moveVec)
|
||||
{
|
||||
if (flyMode)
|
||||
hasMovedInFlyMode = true;
|
||||
showCrosshairs = true;
|
||||
cameraCtrl._lookAtPoint = _generalHelper.moveCamera(camera, _lookAtPoint, moveVec);
|
||||
}
|
||||
|
||||
@@ -248,11 +248,15 @@ Item {
|
||||
cameraCtrl._dragging = false;
|
||||
cameraCtrl.storeCameraState(0);
|
||||
}
|
||||
hasMovedInFlyMode = false;
|
||||
showCrosshairs = false;
|
||||
_generalHelper.stopAllCameraMoves();
|
||||
_generalHelper.setCameraSpeedModifier(1.0);
|
||||
}
|
||||
|
||||
on_LookAtPointChanged: {
|
||||
viewRoot.overlayViews[splitId].lookAtGizmo.position = _lookAtPoint;
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: _generalHelper
|
||||
enabled: viewRoot.activeSplit === cameraCtrl.splitId
|
||||
@@ -268,7 +272,7 @@ Item {
|
||||
Image {
|
||||
anchors.centerIn: parent
|
||||
source: "qrc:///qtquickplugin/mockfiles/images/crosshair.png"
|
||||
visible: cameraCtrl.hasMovedInFlyMode && viewRoot.activeSplit === cameraCtrl.splitId
|
||||
visible: cameraCtrl.showCrosshairs && viewRoot.activeSplit === cameraCtrl.splitId
|
||||
opacity: 0.7
|
||||
}
|
||||
|
||||
|
@@ -25,6 +25,7 @@ Item {
|
||||
|
||||
property bool showEditLight: false
|
||||
property bool showGrid: true
|
||||
property bool showLookAt: true
|
||||
property bool showSelectionBox: true
|
||||
property bool showIconGizmo: true
|
||||
property bool showCameraFrustum: false
|
||||
@@ -66,6 +67,7 @@ Item {
|
||||
onShowEditLightChanged: _generalHelper.storeToolState(sceneId, "showEditLight", showEditLight)
|
||||
onGlobalOrientationChanged: _generalHelper.storeToolState(sceneId, "globalOrientation", globalOrientation)
|
||||
onShowGridChanged: _generalHelper.storeToolState(sceneId, "showGrid", showGrid);
|
||||
onShowLookAtChanged: _generalHelper.storeToolState(sceneId, "showLookAt", showLookAt);
|
||||
onSyncEnvBackgroundChanged: _generalHelper.storeToolState(sceneId, "syncEnvBackground", syncEnvBackground);
|
||||
onShowSelectionBoxChanged: _generalHelper.storeToolState(sceneId, "showSelectionBox", showSelectionBox);
|
||||
onShowIconGizmoChanged: _generalHelper.storeToolState(sceneId, "showIconGizmo", showIconGizmo);
|
||||
@@ -304,6 +306,11 @@ Item {
|
||||
else if (resetToDefault)
|
||||
showGrid = true;
|
||||
|
||||
if ("showLookAt" in toolStates)
|
||||
showLookAt = toolStates.showLookAt;
|
||||
else if (resetToDefault)
|
||||
showLookAt = true;
|
||||
|
||||
if ("syncEnvBackground" in toolStates) {
|
||||
syncEnvBackground = toolStates.syncEnvBackground;
|
||||
updateEnvBackground();
|
||||
@@ -393,6 +400,7 @@ Item {
|
||||
{
|
||||
_generalHelper.storeToolState(sceneId, "showEditLight", showEditLight)
|
||||
_generalHelper.storeToolState(sceneId, "showGrid", showGrid)
|
||||
_generalHelper.storeToolState(sceneId, "showLookAt", showLookAt)
|
||||
_generalHelper.storeToolState(sceneId, "syncEnvBackground", syncEnvBackground)
|
||||
_generalHelper.storeToolState(sceneId, "showSelectionBox", showSelectionBox)
|
||||
_generalHelper.storeToolState(sceneId, "showIconGizmo", showIconGizmo)
|
||||
|
27
src/tools/qml2puppet/mockfiles/qt6/LookAtGizmo.qml
Normal file
27
src/tools/qml2puppet/mockfiles/qt6/LookAtGizmo.qml
Normal file
@@ -0,0 +1,27 @@
|
||||
// Copyright (C) 2024 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
import QtQuick
|
||||
import QtQuick3D
|
||||
import LookAtGeometry
|
||||
|
||||
Node {
|
||||
id: root
|
||||
|
||||
property alias crossScale: lookAtGeometry.crossScale
|
||||
property alias color: lookAtMat.baseColor
|
||||
|
||||
Model {
|
||||
readonly property bool _edit3dLocked: true // Make this non-pickable
|
||||
geometry: LookAtGeometry {
|
||||
id: lookAtGeometry
|
||||
}
|
||||
materials: [
|
||||
PrincipledMaterial {
|
||||
id: lookAtMat
|
||||
lighting: DefaultMaterial.NoLighting
|
||||
cullMode: Material.NoCulling
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
@@ -12,6 +12,7 @@ View3D {
|
||||
property alias rotateGizmo: rotateGizmo
|
||||
property alias scaleGizmo: scaleGizmo
|
||||
property alias lightGizmo: lightGizmo
|
||||
property alias lookAtGizmo: lookAtGizmo
|
||||
|
||||
property var viewRoot: null
|
||||
property View3D editView: null
|
||||
@@ -484,6 +485,12 @@ View3D {
|
||||
position: pivotLine.startPos
|
||||
}
|
||||
|
||||
AutoScaleHelper {
|
||||
id: lookAtAutoScale
|
||||
view3D: overlayView
|
||||
position: lookAtGizmo.scenePosition
|
||||
}
|
||||
|
||||
MoveGizmo {
|
||||
id: moveGizmo
|
||||
scale: autoScale.getScale(Qt.vector3d(5, 5, 5))
|
||||
@@ -619,5 +626,14 @@ View3D {
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
LookAtGizmo {
|
||||
id: lookAtGizmo
|
||||
color: "#ddd600"
|
||||
scale: lookAtAutoScale.getScale(Qt.vector3d(10, 10, 10))
|
||||
visible: overlayView.viewRoot.showLookAt
|
||||
&& overlayView.isActive
|
||||
&& !overlayView.viewRoot.cameraControls[viewRoot.activeSplit].showCrosshairs
|
||||
}
|
||||
}
|
||||
}
|
||||
|
62
src/tools/qml2puppet/qml2puppet/editor3d/lookatgeometry.cpp
Normal file
62
src/tools/qml2puppet/qml2puppet/editor3d/lookatgeometry.cpp
Normal file
@@ -0,0 +1,62 @@
|
||||
// Copyright (C) 2024 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
#ifdef QUICK3D_MODULE
|
||||
|
||||
#include "lookatgeometry.h"
|
||||
|
||||
namespace QmlDesigner::Internal {
|
||||
|
||||
LookAtGeometry::LookAtGeometry()
|
||||
: GeometryBase()
|
||||
, m_crossScale(1.f, 1.f, 1.f)
|
||||
{
|
||||
}
|
||||
|
||||
LookAtGeometry::~LookAtGeometry()
|
||||
{
|
||||
}
|
||||
|
||||
QVector3D LookAtGeometry::crossScale() const
|
||||
{
|
||||
return m_crossScale;
|
||||
}
|
||||
|
||||
void LookAtGeometry::setCrossScale(const QVector3D &scale)
|
||||
{
|
||||
if (scale != m_crossScale) {
|
||||
m_crossScale = scale;
|
||||
emit crossScaleChanged();
|
||||
updateGeometry();
|
||||
}
|
||||
}
|
||||
|
||||
void LookAtGeometry::doUpdateGeometry()
|
||||
{
|
||||
GeometryBase::doUpdateGeometry();
|
||||
|
||||
QByteArray vertexData;
|
||||
vertexData.resize(6 * 3 * 4); // 6 vertices of 3 floats each 4 bytes
|
||||
float *dataPtr = reinterpret_cast<float *>(vertexData.data());
|
||||
|
||||
auto addVertex = [&dataPtr](float x, float y, float z) {
|
||||
dataPtr[0] = x;
|
||||
dataPtr[1] = y;
|
||||
dataPtr[2] = z;
|
||||
dataPtr += 3;
|
||||
};
|
||||
|
||||
addVertex(m_crossScale.x(), 0.f, 0.f);
|
||||
addVertex(-m_crossScale.x(), 0.f, 0.f);
|
||||
addVertex(0.f, m_crossScale.y(), 0.f);
|
||||
addVertex(0.f, -m_crossScale.y(), 0.f);
|
||||
addVertex(0.f, 0.f, m_crossScale.z());
|
||||
addVertex(0.f, 0.f, -m_crossScale.z());
|
||||
|
||||
setVertexData(vertexData);
|
||||
setBounds(-m_crossScale, m_crossScale);
|
||||
}
|
||||
|
||||
} // namespace QmlDesigner::Internal
|
||||
|
||||
#endif // QUICK3D_MODULE
|
42
src/tools/qml2puppet/qml2puppet/editor3d/lookatgeometry.h
Normal file
42
src/tools/qml2puppet/qml2puppet/editor3d/lookatgeometry.h
Normal file
@@ -0,0 +1,42 @@
|
||||
// Copyright (C) 2024 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifdef QUICK3D_MODULE
|
||||
|
||||
#include "geometrybase.h"
|
||||
|
||||
#include <QtGui/QVector3D>
|
||||
|
||||
namespace QmlDesigner::Internal {
|
||||
|
||||
class LookAtGeometry : public GeometryBase
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(QVector3D crossScale READ crossScale WRITE setCrossScale NOTIFY crossScaleChanged)
|
||||
|
||||
public:
|
||||
LookAtGeometry();
|
||||
~LookAtGeometry() override;
|
||||
|
||||
QVector3D crossScale() const;
|
||||
|
||||
public slots:
|
||||
void setCrossScale(const QVector3D &pos);
|
||||
|
||||
signals:
|
||||
void crossScaleChanged();
|
||||
|
||||
protected:
|
||||
void doUpdateGeometry() override;
|
||||
|
||||
private:
|
||||
QVector3D m_crossScale;
|
||||
};
|
||||
|
||||
} // namespace QmlDesigner::Internal
|
||||
|
||||
QML_DECLARE_TYPE(QmlDesigner::Internal::LookAtGeometry)
|
||||
|
||||
#endif // QUICK3D_MODULE
|
@@ -41,14 +41,15 @@
|
||||
#include "changeauxiliarycommand.h"
|
||||
|
||||
#include "../editor3d/boxgeometry.h"
|
||||
#include "../editor3d/generalhelper.h"
|
||||
#include "../editor3d/mousearea3d.h"
|
||||
#include "../editor3d/camerageometry.h"
|
||||
#include "../editor3d/lightgeometry.h"
|
||||
#include "../editor3d/generalhelper.h"
|
||||
#include "../editor3d/gridgeometry.h"
|
||||
#include "../editor3d/selectionboxgeometry.h"
|
||||
#include "../editor3d/linegeometry.h"
|
||||
#include "../editor3d/icongizmoimageprovider.h"
|
||||
#include "../editor3d/lightgeometry.h"
|
||||
#include "../editor3d/linegeometry.h"
|
||||
#include "../editor3d/lookatgeometry.h"
|
||||
#include "../editor3d/mousearea3d.h"
|
||||
#include "../editor3d/selectionboxgeometry.h"
|
||||
|
||||
#include <private/qquickdesignersupport_p.h>
|
||||
#include <qmlprivategate.h>
|
||||
@@ -526,6 +527,7 @@ void Qt5InformationNodeInstanceServer::createEditView3D()
|
||||
qmlRegisterType<QmlDesigner::Internal::SelectionBoxGeometry>("SelectionBoxGeometry", 1, 0, "SelectionBoxGeometry");
|
||||
qmlRegisterType<QmlDesigner::Internal::LineGeometry>("LineGeometry", 1, 0, "LineGeometry");
|
||||
qmlRegisterType<QmlDesigner::Internal::BoxGeometry>("BoxGeometry", 1, 0, "BoxGeometry");
|
||||
qmlRegisterType<QmlDesigner::Internal::LookAtGeometry>("LookAtGeometry", 1, 0, "LookAtGeometry");
|
||||
|
||||
auto helper = new QmlDesigner::Internal::GeneralHelper();
|
||||
QObject::connect(helper, &QmlDesigner::Internal::GeneralHelper::toolStateChanged,
|
||||
@@ -2533,6 +2535,9 @@ void Qt5InformationNodeInstanceServer::view3DAction(const View3DActionCommand &c
|
||||
case View3DActionType::ShowGrid:
|
||||
updatedToolState.insert("showGrid", command.isEnabled());
|
||||
break;
|
||||
case View3DActionType::ShowLookAt:
|
||||
updatedToolState.insert("showLookAt", command.isEnabled());
|
||||
break;
|
||||
case View3DActionType::ShowSelectionBox:
|
||||
updatedToolState.insert("showSelectionBox", command.isEnabled());
|
||||
break;
|
||||
|
Reference in New Issue
Block a user