From bb64505cab8754e114231e8947cad1444db74014 Mon Sep 17 00:00:00 2001 From: Mahmoud Badri Date: Tue, 8 Nov 2022 17:29:52 +0200 Subject: [PATCH] QmlDesigner: Implement adding a bundle texture as light probe Fixes: QDS-8205 Change-Id: Icb57287fa36df5d44d59ffc64e26fa3d778d24d6 Reviewed-by: Miikka Heikkinen --- .../ContentLibraryTextureContextMenu.qml | 7 +- .../ContentLibraryTexturesView.qml | 2 +- .../contentlibrarytexturesmodel.cpp | 14 ++++ .../contentlibrarytexturesmodel.h | 6 ++ .../contentlibrary/contentlibraryview.cpp | 68 +++++++++++++++---- .../contentlibrary/contentlibraryview.h | 2 + .../contentlibrary/contentlibrarywidget.cpp | 14 +++- .../contentlibrary/contentlibrarywidget.h | 6 +- .../components/edit3d/edit3dview.cpp | 3 +- .../designercore/include/abstractview.h | 3 + .../qmldesigner/designercore/include/model.h | 2 + .../designercore/model/abstractview.cpp | 16 +++++ .../qmldesigner/designercore/model/model.cpp | 18 ++++- .../qmldesigner/designercore/model/model_p.h | 2 + 14 files changed, 138 insertions(+), 25 deletions(-) diff --git a/share/qtcreator/qmldesigner/contentLibraryQmlSource/ContentLibraryTextureContextMenu.qml b/share/qtcreator/qmldesigner/contentLibraryQmlSource/ContentLibraryTextureContextMenu.qml index 373b2108084..61bd0ebfd7e 100644 --- a/share/qtcreator/qmldesigner/contentLibraryQmlSource/ContentLibraryTextureContextMenu.qml +++ b/share/qtcreator/qmldesigner/contentLibraryQmlSource/ContentLibraryTextureContextMenu.qml @@ -10,6 +10,7 @@ StudioControls.Menu { id: root property var targetTexture: null + property bool hasSceneEnv: false function popupMenu(targetTexture = null) { @@ -32,8 +33,8 @@ StudioControls.Menu { } StudioControls.MenuItem { - text: qsTr("Add scene environment") - enabled: root.targetTexture - onTriggered: rootView.addEnv(root.targetTexture) + text: qsTr("Add light probe") + enabled: root.hasSceneEnv && root.targetTexture + onTriggered: rootView.addLightProbe(root.targetTexture) } } diff --git a/share/qtcreator/qmldesigner/contentLibraryQmlSource/ContentLibraryTexturesView.qml b/share/qtcreator/qmldesigner/contentLibraryQmlSource/ContentLibraryTexturesView.qml index 469a4170e20..4e2854a48bf 100644 --- a/share/qtcreator/qmldesigner/contentLibraryQmlSource/ContentLibraryTexturesView.qml +++ b/share/qtcreator/qmldesigner/contentLibraryQmlSource/ContentLibraryTexturesView.qml @@ -39,7 +39,7 @@ HelperWidgets.ScrollView { ContentLibraryTextureContextMenu { id: ctxMenu - // TODO + hasSceneEnv: root.model.hasSceneEnv } Repeater { diff --git a/src/plugins/qmldesigner/components/contentlibrary/contentlibrarytexturesmodel.cpp b/src/plugins/qmldesigner/components/contentlibrary/contentlibrarytexturesmodel.cpp index 38c9522879b..4d793e4e2bd 100644 --- a/src/plugins/qmldesigner/components/contentlibrary/contentlibrarytexturesmodel.cpp +++ b/src/plugins/qmldesigner/components/contentlibrary/contentlibrarytexturesmodel.cpp @@ -115,6 +115,20 @@ void ContentLibraryTexturesModel::setHasMaterialRoot(bool b) emit hasMaterialRootChanged(); } +bool ContentLibraryTexturesModel::hasSceneEnv() const +{ + return m_hasSceneEnv; +} + +void ContentLibraryTexturesModel::setHasSceneEnv(bool b) +{ + if (b == m_hasSceneEnv) + return; + + m_hasSceneEnv = b; + emit hasSceneEnvChanged(); +} + bool ContentLibraryTexturesModel::matBundleExists() const { return m_texBundleLoaded && m_quick3dMajorVersion == 6 && m_quick3dMinorVersion >= 3; diff --git a/src/plugins/qmldesigner/components/contentlibrary/contentlibrarytexturesmodel.h b/src/plugins/qmldesigner/components/contentlibrary/contentlibrarytexturesmodel.h index 8009dd3ff80..ca5e7a6963b 100644 --- a/src/plugins/qmldesigner/components/contentlibrary/contentlibrarytexturesmodel.h +++ b/src/plugins/qmldesigner/components/contentlibrary/contentlibrarytexturesmodel.h @@ -18,6 +18,7 @@ class ContentLibraryTexturesModel : public QAbstractListModel Q_PROPERTY(bool hasQuick3DImport READ hasQuick3DImport WRITE setHasQuick3DImport NOTIFY hasQuick3DImportChanged) Q_PROPERTY(bool hasModelSelection READ hasModelSelection WRITE setHasModelSelection NOTIFY hasModelSelectionChanged) Q_PROPERTY(bool hasMaterialRoot READ hasMaterialRoot WRITE setHasMaterialRoot NOTIFY hasMaterialRootChanged) + Q_PROPERTY(bool hasSceneEnv READ hasSceneEnv WRITE setHasSceneEnv NOTIFY hasSceneEnvChanged) public: ContentLibraryTexturesModel(QObject *parent = nullptr); @@ -42,6 +43,9 @@ public: bool hasModelSelection() const; void setHasModelSelection(bool b); + bool hasSceneEnv() const; + void setHasSceneEnv(bool b); + void resetModel(); void loadTextureBundle(const QString &bundlePath); @@ -54,6 +58,7 @@ signals: void hasMaterialRootChanged(); void materialVisibleChanged(); void matBundleExistsChanged(); + void hasSceneEnvChanged(); private: bool isValidIndex(int idx) const; @@ -66,6 +71,7 @@ private: bool m_hasQuick3DImport = false; bool m_texBundleLoaded = false; bool m_hasModelSelection = false; + bool m_hasSceneEnv = false; int m_quick3dMajorVersion = -1; int m_quick3dMinorVersion = -1; diff --git a/src/plugins/qmldesigner/components/contentlibrary/contentlibraryview.cpp b/src/plugins/qmldesigner/components/contentlibrary/contentlibraryview.cpp index fe035cee345..28aa071a8ec 100644 --- a/src/plugins/qmldesigner/components/contentlibrary/contentlibraryview.cpp +++ b/src/plugins/qmldesigner/components/contentlibrary/contentlibraryview.cpp @@ -3,16 +3,19 @@ #include "contentlibraryview.h" +#include "bindingproperty.h" #include "contentlibrarybundleimporter.h" #include "contentlibrarywidget.h" #include "contentlibrarymaterial.h" #include "contentlibrarymaterialsmodel.h" +#include "contentlibrarytexturesmodel.h" #include "modelnodeoperations.h" #include "nodelistproperty.h" #include "qmlobjectnode.h" #include "variantproperty.h" #include +#include #include #ifndef QMLDESIGNER_TEST @@ -48,15 +51,20 @@ WidgetInfo ContentLibraryView::widgetInfo() }); connect(m_widget, &ContentLibraryWidget::addTextureRequested, this, [&] (const QString texPath, ContentLibraryWidget::AddTextureMode mode) { - AddFilesResult result = ModelNodeOperations::addImageToProject({texPath}, "images", false); + executeInTransaction("ContentLibraryView::widgetInfo", [&] { + // copy image to project + AddFilesResult result = ModelNodeOperations::addImageToProject({texPath}, "images", false); - if (result == AddFilesResult::Failed) { - Core::AsynchronousMessageBox::warning(tr("Failed to Add Texture"), - tr("Could not add %1 to project.").arg(texPath)); - return; - } + if (result == AddFilesResult::Failed) { + Core::AsynchronousMessageBox::warning(tr("Failed to Add Texture"), + tr("Could not add %1 to project.").arg(texPath)); + return; + } - if (mode == ContentLibraryWidget::AddTextureMode::Texture) { + if (mode == ContentLibraryWidget::AddTextureMode::Image) + return; + + // create a texture from the image ModelNode matLib = materialLibraryNode(); if (!matLib.isValid()) return; @@ -68,9 +76,15 @@ WidgetInfo ContentLibraryView::widgetInfo() VariantProperty sourceProp = newTexNode.variantProperty("source"); sourceProp.setValue(QLatin1String("images/%1").arg(texPath.split('/').last())); matLib.defaultNodeListProperty().reparentHere(newTexNode); - } else if (mode == ContentLibraryWidget::AddTextureMode::Environment) { - // TODO: assign as env - } + + // assign the texture as scene environment's light probe + if (mode == ContentLibraryWidget::AddTextureMode::LightProbe && m_activeSceneEnv.isValid()) { + BindingProperty lightProbeProp = m_activeSceneEnv.bindingProperty("lightProbe"); + lightProbeProp.setExpression(newTexNode.id()); + VariantProperty bgModeProp = m_activeSceneEnv.variantProperty("backgroundMode"); + bgModeProp.setValue(QVariant::fromValue(Enumeration("SceneEnvironment", "SkyBox"))); + } + }); }); ContentLibraryMaterialsModel *materialsModel = m_widget->materialsModel().data(); @@ -99,7 +113,7 @@ WidgetInfo ContentLibraryView::widgetInfo() connect(materialsModel, &ContentLibraryMaterialsModel::bundleMaterialAboutToUnimport, this, [&] (const QmlDesigner::TypeName &type) { // delete instances of the bundle material that is about to be unimported - executeInTransaction("MaterialBrowserView::widgetInfo", [&] { + executeInTransaction("ContentLibraryView::widgetInfo", [&] { ModelNode matLib = materialLibraryNode(); if (!matLib.isValid()) return; @@ -157,8 +171,36 @@ void ContentLibraryView::importsChanged(const QList &addedImports, const m_widget->materialsModel()->setHasQuick3DImport(m_hasQuick3DImport); } +void ContentLibraryView::active3DSceneChanged(qint32 sceneId) +{ + m_activeSceneEnv = {}; + bool sceneEnvExists = false; + if (sceneId != -1) { + ModelNode activeScene = active3DSceneNode(); + if (activeScene.isValid()) { + ModelNode view3D; + if (activeScene.metaInfo().isQtQuick3DView3D()) { + view3D = activeScene; + } else { + ModelNode sceneParent = activeScene.parentProperty().parentModelNode(); + if (sceneParent.metaInfo().isQtQuick3DView3D()) + view3D = sceneParent; + } + + if (view3D.isValid()) { + m_activeSceneEnv = modelNodeForId(view3D.bindingProperty("environment").expression()); + if (m_activeSceneEnv.isValid()) + sceneEnvExists = true; + } + } + } + + m_widget->texturesModel()->setHasSceneEnv(sceneEnvExists); + m_widget->environmentsModel()->setHasSceneEnv(sceneEnvExists); +} + void ContentLibraryView::selectedNodesChanged(const QList &selectedNodeList, - const QList &lastSelectedNodeList) + const QList &lastSelectedNodeList) { Q_UNUSED(lastSelectedNodeList) @@ -204,7 +246,7 @@ void ContentLibraryView::applyBundleMaterialToDropTarget(const ModelNode &bundle if (!bundleMat.isValid() && !metaInfo.isValid()) return; - executeInTransaction("MaterialBrowserView::applyBundleMaterialToDropTarget", [&] { + executeInTransaction("ContentLibraryView::applyBundleMaterialToDropTarget", [&] { ModelNode newMatNode = metaInfo.isValid() ? createMaterial(metaInfo) : bundleMat; // TODO: unify this logic as it exist elsewhere also diff --git a/src/plugins/qmldesigner/components/contentlibrary/contentlibraryview.h b/src/plugins/qmldesigner/components/contentlibrary/contentlibraryview.h index 8ece6a76d05..a55d7d772fa 100644 --- a/src/plugins/qmldesigner/components/contentlibrary/contentlibraryview.h +++ b/src/plugins/qmldesigner/components/contentlibrary/contentlibraryview.h @@ -30,6 +30,7 @@ public: void modelAttached(Model *model) override; void modelAboutToBeDetached(Model *model) override; void importsChanged(const QList &addedImports, const QList &removedImports) override; + void active3DSceneChanged(qint32 sceneId) override; void selectedNodesChanged(const QList &selectedNodeList, const QList &lastSelectedNodeList) override; void customNotification(const AbstractView *view, const QString &identifier, @@ -46,6 +47,7 @@ private: QList m_bundleMaterialTargets; QList m_selectedModels; // selected 3D model nodes ContentLibraryMaterial *m_draggedBundleMaterial = nullptr; + ModelNode m_activeSceneEnv; bool m_bundleMaterialAddToSelected = false; bool m_hasQuick3DImport = false; }; diff --git a/src/plugins/qmldesigner/components/contentlibrary/contentlibrarywidget.cpp b/src/plugins/qmldesigner/components/contentlibrary/contentlibrarywidget.cpp index 02d116811eb..99a24e70b40 100644 --- a/src/plugins/qmldesigner/components/contentlibrary/contentlibrarywidget.cpp +++ b/src/plugins/qmldesigner/components/contentlibrary/contentlibrarywidget.cpp @@ -225,9 +225,9 @@ void ContentLibraryWidget::addTexture(ContentLibraryTexture *tex) emit addTextureRequested(tex->path(), AddTextureMode::Texture); } -void ContentLibraryWidget::addEnv(ContentLibraryTexture *tex) +void ContentLibraryWidget::addLightProbe(ContentLibraryTexture *tex) { - emit addTextureRequested(tex->path(), AddTextureMode::Environment); + emit addTextureRequested(tex->path(), AddTextureMode::LightProbe); } QPointer ContentLibraryWidget::materialsModel() const @@ -235,4 +235,14 @@ QPointer ContentLibraryWidget::materialsModel() co return m_materialsModel; } +QPointer ContentLibraryWidget::texturesModel() const +{ + return m_texturesModel; +} + +QPointer ContentLibraryWidget::environmentsModel() const +{ + return m_environmentsModel; +} + } // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/components/contentlibrary/contentlibrarywidget.h b/src/plugins/qmldesigner/components/contentlibrary/contentlibrarywidget.h index 3eb470b7ae3..1c14794c6c2 100644 --- a/src/plugins/qmldesigner/components/contentlibrary/contentlibrarywidget.h +++ b/src/plugins/qmldesigner/components/contentlibrary/contentlibrarywidget.h @@ -36,14 +36,16 @@ public: void setMaterialsModel(QPointer newMaterialsModel); QPointer materialsModel() const; + QPointer texturesModel() const; + QPointer environmentsModel() const; Q_INVOKABLE void startDragMaterial(QmlDesigner::ContentLibraryMaterial *mat, const QPointF &mousePos); Q_INVOKABLE void startDragTexture(QmlDesigner::ContentLibraryTexture *tex, const QPointF &mousePos); Q_INVOKABLE void addImage(QmlDesigner::ContentLibraryTexture *tex); Q_INVOKABLE void addTexture(QmlDesigner::ContentLibraryTexture *tex); - Q_INVOKABLE void addEnv(QmlDesigner::ContentLibraryTexture *tex); + Q_INVOKABLE void addLightProbe(QmlDesigner::ContentLibraryTexture *tex); - enum class AddTextureMode { Image, Texture, Environment }; + enum class AddTextureMode { Image, Texture, LightProbe }; signals: void bundleMaterialDragStarted(QmlDesigner::ContentLibraryMaterial *bundleMat); diff --git a/src/plugins/qmldesigner/components/edit3d/edit3dview.cpp b/src/plugins/qmldesigner/components/edit3d/edit3dview.cpp index c734b0e362c..cbf78003754 100644 --- a/src/plugins/qmldesigner/components/edit3d/edit3dview.cpp +++ b/src/plugins/qmldesigner/components/edit3d/edit3dview.cpp @@ -11,7 +11,6 @@ #include "nodehints.h" #include "seekerslider.h" -#include #include #include #include @@ -110,7 +109,7 @@ void Edit3DView::updateActiveScene3D(const QVariantMap &sceneState) if (sceneState.contains(sceneKey)) { qint32 newActiveScene = sceneState[sceneKey].value(); edit3DWidget()->canvas()->updateActiveScene(newActiveScene); - rootModelNode().setAuxiliaryData(active3dSceneProperty, newActiveScene); + model()->setActive3DSceneId(newActiveScene); } if (sceneState.contains(selectKey)) diff --git a/src/plugins/qmldesigner/designercore/include/abstractview.h b/src/plugins/qmldesigner/designercore/include/abstractview.h index b67533acf91..2afc56e6e0a 100644 --- a/src/plugins/qmldesigner/designercore/include/abstractview.h +++ b/src/plugins/qmldesigner/designercore/include/abstractview.h @@ -219,6 +219,8 @@ public: virtual void view3DAction(View3DActionType type, const QVariant &value); + virtual void active3DSceneChanged(qint32 sceneId); + virtual void dragStarted(QMimeData *mimeData); virtual void dragEnded(); @@ -226,6 +228,7 @@ public: void ensureMaterialLibraryNode(); ModelNode materialLibraryNode(); + ModelNode active3DSceneNode(); void assignMaterialTo3dModel(const ModelNode &modelNode, const ModelNode &materialNode = {}); const NodeInstanceView *nodeInstanceView() const; diff --git a/src/plugins/qmldesigner/designercore/include/model.h b/src/plugins/qmldesigner/designercore/include/model.h index 6c1f10c6886..e22dbe70b6e 100644 --- a/src/plugins/qmldesigner/designercore/include/model.h +++ b/src/plugins/qmldesigner/designercore/include/model.h @@ -148,6 +148,8 @@ public: QString generateNewId(const QString &prefixName, const QString &fallbackPrefix = "element") const; QString generateIdFromName(const QString &name, const QString &fallbackId = "element") const; + void setActive3DSceneId(qint32 sceneId); + void startDrag(QMimeData *mimeData, const QPixmap &icon); void endDrag(); diff --git a/src/plugins/qmldesigner/designercore/model/abstractview.cpp b/src/plugins/qmldesigner/designercore/model/abstractview.cpp index 0dd4695ad76..8f937f97958 100644 --- a/src/plugins/qmldesigner/designercore/model/abstractview.cpp +++ b/src/plugins/qmldesigner/designercore/model/abstractview.cpp @@ -3,6 +3,7 @@ #include "abstractview.h" +#include "auxiliarydataproperties.h" #include "model.h" #include "model_p.h" #include "internalnode_p.h" @@ -392,6 +393,8 @@ void AbstractView::modelNodePreviewPixmapChanged(const ModelNode & /*node*/, con void AbstractView::view3DAction(View3DActionType, const QVariant &) {} +void AbstractView::active3DSceneChanged(qint32 /*sceneId*/) {} + void AbstractView::dragStarted(QMimeData * /*mimeData*/) {} void AbstractView::dragEnded() {} @@ -843,6 +846,19 @@ ModelNode AbstractView::materialLibraryNode() return modelNodeForId(Constants::MATERIAL_LIB_ID); } +ModelNode AbstractView::active3DSceneNode() +{ + auto activeSceneAux = rootModelNode().auxiliaryData(active3dSceneProperty); + if (activeSceneAux) { + int activeScene = activeSceneAux->toInt(); + + if (hasModelNodeForInternalId(activeScene)) + return modelNodeForInternalId(activeScene); + } + + return {}; +} + // Assigns given material to a 3D model. // The assigned material is also inserted into material library if not already there. // If given material is not valid, first existing material from material library is used, diff --git a/src/plugins/qmldesigner/designercore/model/model.cpp b/src/plugins/qmldesigner/designercore/model/model.cpp index 57005fb2c6e..d0f5353d471 100644 --- a/src/plugins/qmldesigner/designercore/model/model.cpp +++ b/src/plugins/qmldesigner/designercore/model/model.cpp @@ -6,9 +6,8 @@ #include "model_p.h" #include - - #include "abstractview.h" +#include "auxiliarydataproperties.h" #include "internalnodeabstractproperty.h" #include "internalnodelistproperty.h" #include "internalproperty.h" @@ -571,6 +570,11 @@ void ModelPrivate::notifyView3DAction(View3DActionType type, const QVariant &val notifyNormalViewsLast([&](AbstractView *view) { view->view3DAction(type, value); }); } +void ModelPrivate::notifyActive3DSceneIdChanged(qint32 sceneId) +{ + notifyInstanceChanges([&](AbstractView *view) { view->active3DSceneChanged(sceneId); }); +} + void ModelPrivate::notifyDragStarted(QMimeData *mimeData) { notifyInstanceChanges([&](AbstractView *view) { view->dragStarted(mimeData); }); @@ -1582,6 +1586,16 @@ QString Model::generateIdFromName(const QString &name, const QString &fallbackId return newId; } +void Model::setActive3DSceneId(qint32 sceneId) +{ + auto activeSceneAux = d->rootNode()->auxiliaryData(active3dSceneProperty); + if (activeSceneAux && activeSceneAux->toInt() == sceneId) + return; + + d->rootNode()->setAuxiliaryData(active3dSceneProperty, sceneId); + d->notifyActive3DSceneIdChanged(sceneId); +} + void Model::startDrag(QMimeData *mimeData, const QPixmap &icon) { d->notifyDragStarted(mimeData); diff --git a/src/plugins/qmldesigner/designercore/model/model_p.h b/src/plugins/qmldesigner/designercore/model/model_p.h index 9901e1bfa10..c2715cbf192 100644 --- a/src/plugins/qmldesigner/designercore/model/model_p.h +++ b/src/plugins/qmldesigner/designercore/model/model_p.h @@ -177,6 +177,8 @@ public: void notifyNodeAtPosResult(const ModelNode &modelNode, const QVector3D &pos3d); void notifyView3DAction(View3DActionType type, const QVariant &value); + void notifyActive3DSceneIdChanged(qint32 sceneId); + void notifyDragStarted(QMimeData *mimeData); void notifyDragEnded();