QmlDesigner: Fix issues with adding texture as light probe

Changed resolving the currently active scene environment to be done
on demand instead of trying to track it realtime, since resolving it
is relatively cheap operation, so it doesn't cause noticeable delay
at context menu opening. The alternative would be to implement multiple
different notification handlers in ContentLibraryView, which would slow
down all operations and would be much more complex to ensure all edge
cases are covered.

Fixes: QDS-8437
Change-Id: Ib33cd1ad549d836b9d780f9b0f92e70d223e2a25
Reviewed-by: Mahmoud Badri <mahmoud.badri@qt.io>
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
This commit is contained in:
Miikka Heikkinen
2022-11-28 16:51:42 +02:00
parent 86ed12e729
commit 26c1747ae6
5 changed files with 49 additions and 31 deletions

View File

@@ -15,6 +15,7 @@ StudioControls.Menu {
function popupMenu(targetTexture = null)
{
this.targetTexture = targetTexture
rootView.updateSceneEnvState();
popup()
}

View File

@@ -3,7 +3,6 @@
#include "contentlibraryview.h"
#include "bindingproperty.h"
#include "contentlibrarybundleimporter.h"
#include "contentlibrarywidget.h"
#include "contentlibrarymaterial.h"
@@ -88,11 +87,14 @@ WidgetInfo ContentLibraryView::widgetInfo()
}
// 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(texNode.id());
VariantProperty bgModeProp = m_activeSceneEnv.variantProperty("backgroundMode");
bgModeProp.setValue(QVariant::fromValue(Enumeration("SceneEnvironment", "SkyBox")));
if (mode == ContentLibraryWidget::AddTextureMode::LightProbe && m_sceneId != -1) {
QmlObjectNode sceneEnv = resolveSceneEnv();
if (sceneEnv.isValid()) {
sceneEnv.setBindingProperty("lightProbe", texNode.id());
sceneEnv.setVariantProperty("backgroundMode",
QVariant::fromValue(Enumeration("SceneEnvironment",
"SkyBox")));
}
}
QTimer::singleShot(0, this, [this, texNode]() {
if (model() && texNode.isValid())
@@ -101,6 +103,9 @@ WidgetInfo ContentLibraryView::widgetInfo()
});
});
connect(m_widget, &ContentLibraryWidget::updateSceneEnvStateRequested,
this, &ContentLibraryView::resolveSceneEnv);
ContentLibraryMaterialsModel *materialsModel = m_widget->materialsModel().data();
connect(materialsModel, &ContentLibraryMaterialsModel::applyToSelectedTriggered, this,
@@ -187,30 +192,7 @@ void ContentLibraryView::importsChanged(const QList<Import> &addedImports, const
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);
m_sceneId = sceneId;
}
void ContentLibraryView::selectedNodesChanged(const QList<ModelNode> &selectedNodeList,
@@ -361,6 +343,33 @@ ModelNode ContentLibraryView::createMaterial(const NodeMetaInfo &metaInfo)
return newMatNode;
}
ModelNode ContentLibraryView::resolveSceneEnv()
{
ModelNode activeSceneEnv;
if (m_sceneId != -1) {
ModelNode activeScene = active3DSceneNode();
if (activeScene.isValid()) {
QmlObjectNode view3D;
if (activeScene.metaInfo().isQtQuick3DView3D()) {
view3D = activeScene;
} else {
ModelNode sceneParent = activeScene.parentProperty().parentModelNode();
if (sceneParent.metaInfo().isQtQuick3DView3D())
view3D = sceneParent;
}
if (view3D.isValid())
activeSceneEnv = modelNodeForId(view3D.expression("environment"));
}
}
const bool sceneEnvExists = activeSceneEnv.isValid();
m_widget->texturesModel()->setHasSceneEnv(sceneEnvExists);
m_widget->environmentsModel()->setHasSceneEnv(sceneEnvExists);
return activeSceneEnv;
}
void ContentLibraryView::updateBundleMaterialsImportedState()
{
using namespace Utils;

View File

@@ -43,15 +43,16 @@ private:
void applyBundleMaterialToDropTarget(const ModelNode &bundleMat, const NodeMetaInfo &metaInfo = {});
ModelNode getBundleMaterialDefaultInstance(const TypeName &type);
ModelNode createMaterial(const NodeMetaInfo &metaInfo);
ModelNode resolveSceneEnv();
QPointer<ContentLibraryWidget> m_widget;
QList<ModelNode> m_bundleMaterialTargets;
QList<ModelNode> m_selectedModels; // selected 3D model nodes
ContentLibraryMaterial *m_draggedBundleMaterial = nullptr;
ContentLibraryTexture *m_draggedBundleTexture = nullptr;
ModelNode m_activeSceneEnv;
bool m_bundleMaterialAddToSelected = false;
bool m_hasQuick3DImport = false;
qint32 m_sceneId = -1;
};
} // namespace QmlDesigner

View File

@@ -221,6 +221,11 @@ void ContentLibraryWidget::addLightProbe(ContentLibraryTexture *tex)
emit addTextureRequested(tex->path(), AddTextureMode::LightProbe);
}
void ContentLibraryWidget::updateSceneEnvState()
{
emit updateSceneEnvStateRequested();
}
QPointer<ContentLibraryMaterialsModel> ContentLibraryWidget::materialsModel() const
{
return m_materialsModel;

View File

@@ -44,6 +44,7 @@ public:
Q_INVOKABLE void addImage(QmlDesigner::ContentLibraryTexture *tex);
Q_INVOKABLE void addTexture(QmlDesigner::ContentLibraryTexture *tex);
Q_INVOKABLE void addLightProbe(QmlDesigner::ContentLibraryTexture *tex);
Q_INVOKABLE void updateSceneEnvState();
enum class AddTextureMode { Image, Texture, LightProbe };
@@ -51,6 +52,7 @@ signals:
void bundleMaterialDragStarted(QmlDesigner::ContentLibraryMaterial *bundleMat);
void bundleTextureDragStarted(QmlDesigner::ContentLibraryTexture *bundleTex);
void addTextureRequested(const QString texPath, QmlDesigner::ContentLibraryWidget::AddTextureMode mode);
void updateSceneEnvStateRequested();
protected:
bool eventFilter(QObject *obj, QEvent *event) override;