diff --git a/src/libs/qmlpuppetcommunication/interfaces/nodeinstanceglobal.h b/src/libs/qmlpuppetcommunication/interfaces/nodeinstanceglobal.h index 206fb760956..d248e5e6fd1 100644 --- a/src/libs/qmlpuppetcommunication/interfaces/nodeinstanceglobal.h +++ b/src/libs/qmlpuppetcommunication/interfaces/nodeinstanceglobal.h @@ -36,6 +36,7 @@ enum class View3DActionType { OrientationToggle, EditLightToggle, ShowGrid, + ShowLookAt, ShowSelectionBox, ShowIconGizmo, ShowCameraFrustum, diff --git a/src/plugins/qmldesigner/components/edit3d/edit3dview.cpp b/src/plugins/qmldesigner/components/edit3d/edit3dview.cpp index a78ff758613..bb7404f2522 100644 --- a/src/plugins/qmldesigner/components/edit3d/edit3dview.cpp +++ b/src/plugins/qmldesigner/components/edit3d/edit3dview.cpp @@ -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( + 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( 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(); diff --git a/src/plugins/qmldesigner/components/edit3d/edit3dview.h b/src/plugins/qmldesigner/components/edit3d/edit3dview.h index a76607f003e..755efc0ae38 100644 --- a/src/plugins/qmldesigner/components/edit3d/edit3dview.h +++ b/src/plugins/qmldesigner/components/edit3d/edit3dview.h @@ -159,6 +159,7 @@ private: std::unique_ptr m_orientationModeAction; std::unique_ptr m_editLightAction; std::unique_ptr m_showGridAction; + std::unique_ptr m_showLookAtAction; std::unique_ptr m_showSelectionBoxAction; std::unique_ptr m_showIconGizmoAction; std::unique_ptr m_showCameraFrustumAction; diff --git a/src/plugins/qmldesigner/qmldesignerconstants.h b/src/plugins/qmldesigner/qmldesignerconstants.h index 537e65c5b41..c0d69bef656 100644 --- a/src/plugins/qmldesigner/qmldesignerconstants.h +++ b/src/plugins/qmldesigner/qmldesignerconstants.h @@ -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"; diff --git a/src/tools/qml2puppet/CMakeLists.txt b/src/tools/qml2puppet/CMakeLists.txt index 26fd0b6dd21..a4e3e44174e 100644 --- a/src/tools/qml2puppet/CMakeLists.txt +++ b/src/tools/qml2puppet/CMakeLists.txt @@ -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) diff --git a/src/tools/qml2puppet/editor3d_qt6.qrc b/src/tools/qml2puppet/editor3d_qt6.qrc index c437bad9adf..85df241f162 100644 --- a/src/tools/qml2puppet/editor3d_qt6.qrc +++ b/src/tools/qml2puppet/editor3d_qt6.qrc @@ -37,6 +37,7 @@ mockfiles/qt6/LightIconGizmo.qml mockfiles/qt6/LightModel.qml mockfiles/qt6/Line3D.qml + mockfiles/qt6/LookAtGizmo.qml mockfiles/qt6/MaterialNodeView.qml mockfiles/qt6/ModelNode2DImageView.qml mockfiles/qt6/ModelNode3DImageView.qml diff --git a/src/tools/qml2puppet/mockfiles/qt6/EditCameraController.qml b/src/tools/qml2puppet/mockfiles/qt6/EditCameraController.qml index 31e9a7cfaca..36d67c534d1 100644 --- a/src/tools/qml2puppet/mockfiles/qt6/EditCameraController.qml +++ b/src/tools/qml2puppet/mockfiles/qt6/EditCameraController.qml @@ -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 } diff --git a/src/tools/qml2puppet/mockfiles/qt6/EditView3D.qml b/src/tools/qml2puppet/mockfiles/qt6/EditView3D.qml index c4dc15ab5eb..751d21c0e8a 100644 --- a/src/tools/qml2puppet/mockfiles/qt6/EditView3D.qml +++ b/src/tools/qml2puppet/mockfiles/qt6/EditView3D.qml @@ -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) diff --git a/src/tools/qml2puppet/mockfiles/qt6/LookAtGizmo.qml b/src/tools/qml2puppet/mockfiles/qt6/LookAtGizmo.qml new file mode 100644 index 00000000000..71527d9fb3d --- /dev/null +++ b/src/tools/qml2puppet/mockfiles/qt6/LookAtGizmo.qml @@ -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 + } + ] + } +} diff --git a/src/tools/qml2puppet/mockfiles/qt6/OverlayView3D.qml b/src/tools/qml2puppet/mockfiles/qt6/OverlayView3D.qml index 71f2250b7ca..464e0b6b79c 100644 --- a/src/tools/qml2puppet/mockfiles/qt6/OverlayView3D.qml +++ b/src/tools/qml2puppet/mockfiles/qt6/OverlayView3D.qml @@ -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 + } } } diff --git a/src/tools/qml2puppet/qml2puppet/editor3d/lookatgeometry.cpp b/src/tools/qml2puppet/qml2puppet/editor3d/lookatgeometry.cpp new file mode 100644 index 00000000000..b569f6ea5ab --- /dev/null +++ b/src/tools/qml2puppet/qml2puppet/editor3d/lookatgeometry.cpp @@ -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(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 diff --git a/src/tools/qml2puppet/qml2puppet/editor3d/lookatgeometry.h b/src/tools/qml2puppet/qml2puppet/editor3d/lookatgeometry.h new file mode 100644 index 00000000000..e881c2750e1 --- /dev/null +++ b/src/tools/qml2puppet/qml2puppet/editor3d/lookatgeometry.h @@ -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 + +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 diff --git a/src/tools/qml2puppet/qml2puppet/instances/qt5informationnodeinstanceserver.cpp b/src/tools/qml2puppet/qml2puppet/instances/qt5informationnodeinstanceserver.cpp index d4353fc8f23..9549f59d3f3 100644 --- a/src/tools/qml2puppet/qml2puppet/instances/qt5informationnodeinstanceserver.cpp +++ b/src/tools/qml2puppet/qml2puppet/instances/qt5informationnodeinstanceserver.cpp @@ -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 #include @@ -526,6 +527,7 @@ void Qt5InformationNodeInstanceServer::createEditView3D() qmlRegisterType("SelectionBoxGeometry", 1, 0, "SelectionBoxGeometry"); qmlRegisterType("LineGeometry", 1, 0, "LineGeometry"); qmlRegisterType("BoxGeometry", 1, 0, "BoxGeometry"); + qmlRegisterType("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;