QmlDesigner: Implement adding a bundle texture as light probe

Fixes: QDS-8205
Change-Id: Icb57287fa36df5d44d59ffc64e26fa3d778d24d6
Reviewed-by: Miikka Heikkinen <miikka.heikkinen@qt.io>
This commit is contained in:
Mahmoud Badri
2022-11-08 17:29:52 +02:00
parent 08f8732108
commit bb64505cab
14 changed files with 138 additions and 25 deletions

View File

@@ -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)
}
}

View File

@@ -39,7 +39,7 @@ HelperWidgets.ScrollView {
ContentLibraryTextureContextMenu {
id: ctxMenu
// TODO
hasSceneEnv: root.model.hasSceneEnv
}
Repeater {

View File

@@ -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;

View File

@@ -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;

View File

@@ -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 <coreplugin/messagebox.h>
#include <enumeration.h>
#include <utils/algorithm.h>
#ifndef QMLDESIGNER_TEST
@@ -48,6 +51,8 @@ WidgetInfo ContentLibraryView::widgetInfo()
});
connect(m_widget, &ContentLibraryWidget::addTextureRequested, this,
[&] (const QString texPath, ContentLibraryWidget::AddTextureMode mode) {
executeInTransaction("ContentLibraryView::widgetInfo", [&] {
// copy image to project
AddFilesResult result = ModelNodeOperations::addImageToProject({texPath}, "images", false);
if (result == AddFilesResult::Failed) {
@@ -56,7 +61,10 @@ WidgetInfo ContentLibraryView::widgetInfo()
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,10 +76,16 @@ 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,6 +171,34 @@ void ContentLibraryView::importsChanged(const QList<Import> &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<ModelNode> &selectedNodeList,
const QList<ModelNode> &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

View File

@@ -30,6 +30,7 @@ public:
void modelAttached(Model *model) override;
void modelAboutToBeDetached(Model *model) override;
void importsChanged(const QList<Import> &addedImports, const QList<Import> &removedImports) override;
void active3DSceneChanged(qint32 sceneId) override;
void selectedNodesChanged(const QList<ModelNode> &selectedNodeList,
const QList<ModelNode> &lastSelectedNodeList) override;
void customNotification(const AbstractView *view, const QString &identifier,
@@ -46,6 +47,7 @@ private:
QList<ModelNode> m_bundleMaterialTargets;
QList<ModelNode> m_selectedModels; // selected 3D model nodes
ContentLibraryMaterial *m_draggedBundleMaterial = nullptr;
ModelNode m_activeSceneEnv;
bool m_bundleMaterialAddToSelected = false;
bool m_hasQuick3DImport = false;
};

View File

@@ -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<ContentLibraryMaterialsModel> ContentLibraryWidget::materialsModel() const
@@ -235,4 +235,14 @@ QPointer<ContentLibraryMaterialsModel> ContentLibraryWidget::materialsModel() co
return m_materialsModel;
}
QPointer<ContentLibraryTexturesModel> ContentLibraryWidget::texturesModel() const
{
return m_texturesModel;
}
QPointer<ContentLibraryTexturesModel> ContentLibraryWidget::environmentsModel() const
{
return m_environmentsModel;
}
} // namespace QmlDesigner

View File

@@ -36,14 +36,16 @@ public:
void setMaterialsModel(QPointer<ContentLibraryMaterialsModel> newMaterialsModel);
QPointer<ContentLibraryMaterialsModel> materialsModel() const;
QPointer<ContentLibraryTexturesModel> texturesModel() const;
QPointer<ContentLibraryTexturesModel> 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);

View File

@@ -11,7 +11,6 @@
#include "nodehints.h"
#include "seekerslider.h"
#include <auxiliarydataproperties.h>
#include <coreplugin/icore.h>
#include <coreplugin/messagebox.h>
#include <designeractionmanager.h>
@@ -110,7 +109,7 @@ void Edit3DView::updateActiveScene3D(const QVariantMap &sceneState)
if (sceneState.contains(sceneKey)) {
qint32 newActiveScene = sceneState[sceneKey].value<qint32>();
edit3DWidget()->canvas()->updateActiveScene(newActiveScene);
rootModelNode().setAuxiliaryData(active3dSceneProperty, newActiveScene);
model()->setActive3DSceneId(newActiveScene);
}
if (sceneState.contains(selectKey))

View File

@@ -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;

View File

@@ -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();

View File

@@ -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,

View File

@@ -6,9 +6,8 @@
#include "model_p.h"
#include <modelnode.h>
#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);

View File

@@ -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();