From c865481068f602164f5b45577ff168c437d9df01 Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Thu, 17 Mar 2022 15:44:37 +0200 Subject: [PATCH] QmlDesigner: Add particle attractor visualization to 3D editor Particle attractors are visualized similarly to particle emitters, except that they are shown as blue instead of yellow when parent system is active. Fixes: QDS-6426 Change-Id: I085727dac7f3b4fa968e313b78db3f476941a7da Reviewed-by: Mahmoud Badri Reviewed-by: Thomas Hartmann --- .../qmlpuppet/mockfiles/qt6/ParticleEmitterGizmo.qml | 9 ++++++++- .../qmlpuppet/qml2puppet/editor3d/generalhelper.cpp | 11 ++++++++--- .../instances/qt5informationnodeinstanceserver.cpp | 12 ++++++++---- .../qmldesigner/components/edit3d/edit3dview.cpp | 4 ++-- .../designercore/instances/nodeinstanceview.cpp | 7 ++++--- 5 files changed, 30 insertions(+), 13 deletions(-) diff --git a/share/qtcreator/qml/qmlpuppet/mockfiles/qt6/ParticleEmitterGizmo.qml b/share/qtcreator/qml/qmlpuppet/mockfiles/qt6/ParticleEmitterGizmo.qml index a06a38a2024..9b19bf35261 100644 --- a/share/qtcreator/qml/qmlpuppet/mockfiles/qt6/ParticleEmitterGizmo.qml +++ b/share/qtcreator/qml/qmlpuppet/mockfiles/qt6/ParticleEmitterGizmo.qml @@ -27,6 +27,9 @@ import QtQuick import QtQuick3D import QtQuick3D.Particles3D +// Note: This gizmo is also used to visualize Attractor3D in addition to ParticleEmitter3D, +// as the two are very similar. + Node { id: root @@ -41,6 +44,7 @@ Node { property bool globalShow: false property bool canBeVisible: activeScene === scene && targetNode && !hidden && !systemHidden property bool partOfActiveSystem: root.targetNode && root.targetNode.system === activeParticleSystem + property bool isEmitter: targetNode && targetNode instanceof ParticleEmitter3D opacity: 0.15 @@ -120,7 +124,10 @@ Node { DefaultMaterial { id: defaultMaterial - diffuseColor: root.selected ? "#FF0000" : partOfActiveSystem ? "#FFFF00" : "#AAAAAA" + diffuseColor: root.selected ? "#FF0000" + : root.partOfActiveSystem + ? root.isEmitter ? "#FFFF00" : "#0000FF" + : "#AAAAAA" lighting: DefaultMaterial.NoLighting cullMode: Material.NoCulling } diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/editor3d/generalhelper.cpp b/share/qtcreator/qml/qmlpuppet/qml2puppet/editor3d/generalhelper.cpp index 1b1788e4acf..3b774c3f4a6 100644 --- a/share/qtcreator/qml/qmlpuppet/qml2puppet/editor3d/generalhelper.cpp +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/editor3d/generalhelper.cpp @@ -51,6 +51,7 @@ #include #include #include +#include #endif #include @@ -477,11 +478,15 @@ QQuick3DNode *GeneralHelper::createParticleEmitterGizmoModel(QQuick3DNode *emitt QQuick3DMaterial *material) const { #ifdef QUICK3D_PARTICLES_MODULE - auto e = qobject_cast(emitter); - if (!e || qobject_cast(e) || !material) + if (qobject_cast(emitter) || !material) return nullptr; - auto shape = qobject_cast(e->shape()); + QQuick3DParticleModelShape *shape = nullptr; + if (auto e = qobject_cast(emitter)) + shape = qobject_cast(e->shape()); + else if (auto a = qobject_cast(emitter)) + shape = qobject_cast(a->shape()); + if (shape && shape->delegate()) { if (auto model = qobject_cast( shape->delegate()->create(shape->delegate()->creationContext()))) { diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5informationnodeinstanceserver.cpp b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5informationnodeinstanceserver.cpp index 0d6c069faec..acc7894a963 100644 --- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5informationnodeinstanceserver.cpp +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5informationnodeinstanceserver.cpp @@ -113,6 +113,7 @@ #include #include #include +#include #include #endif @@ -775,7 +776,8 @@ void Qt5InformationNodeInstanceServer::handleNode3DDestroyed(QObject *obj) } else if (qobject_cast(obj)) { QMetaObject::invokeMethod(m_editView3DData.rootItem, "releaseParticleSystemGizmo", Q_ARG(QVariant, objectToVariant(obj))); - } else if (qobject_cast(obj) + } else if ((qobject_cast(obj) + || qobject_cast(obj)) && !qobject_cast(obj)) { QMetaObject::invokeMethod(m_editView3DData.rootItem, "releaseParticleEmitterGizmo", Q_ARG(QVariant, objectToVariant(obj))); @@ -887,7 +889,8 @@ void Qt5InformationNodeInstanceServer::resolveSceneRoots() QMetaObject::invokeMethod(m_editView3DData.rootItem, "updateParticleSystemGizmoScene", Q_ARG(QVariant, objectToVariant(newRoot)), Q_ARG(QVariant, objectToVariant(node))); - } else if (qobject_cast(node) + } else if ((qobject_cast(node) + || qobject_cast(node)) && !qobject_cast(node)) { QMetaObject::invokeMethod(m_editView3DData.rootItem, "updateParticleEmitterGizmoScene", Q_ARG(QVariant, objectToVariant(newRoot)), @@ -1469,7 +1472,8 @@ void Qt5InformationNodeInstanceServer::createCameraAndLightGizmos( lights[find3DSceneRoot(instance)] << instance.internalObject(); } else if (instance.isSubclassOf("QQuick3DParticleSystem")) { particleSystems[find3DSceneRoot(instance)] << instance.internalObject(); - } else if (instance.isSubclassOf("QQuick3DParticleEmitter") + } else if ((instance.isSubclassOf("QQuick3DParticleEmitter") + || instance.isSubclassOf("QQuick3DParticleAttractor")) && !instance.isSubclassOf("QQuick3DParticleTrailEmitter")) { particleEmitters[find3DSceneRoot(instance)] << instance.internalObject(); } @@ -2016,7 +2020,7 @@ void Qt5InformationNodeInstanceServer::changeSelection(const ChangeSelectionComm #ifdef QUICK3D_PARTICLES_MODULE || qobject_cast(object) || qobject_cast(object) - + || qobject_cast(object) #endif ) { return true; diff --git a/src/plugins/qmldesigner/components/edit3d/edit3dview.cpp b/src/plugins/qmldesigner/components/edit3d/edit3dview.cpp index dc4af0255fd..31056c0ed29 100644 --- a/src/plugins/qmldesigner/components/edit3d/edit3dview.cpp +++ b/src/plugins/qmldesigner/components/edit3d/edit3dview.cpp @@ -360,9 +360,9 @@ void Edit3DView::createEdit3DActions() m_showParticleEmitterAction = new Edit3DAction( QmlDesigner::Constants::EDIT3D_EDIT_SHOW_PARTICLE_EMITTER, View3DActionCommand::ShowParticleEmitter, - QCoreApplication::translate("ShowParticleEmitterAction", "Always Show Particle Emitters"), + QCoreApplication::translate("ShowParticleEmitterAction", "Always Show Particle Emitters And Attractors"), QKeySequence(Qt::Key_M), true, false, {}, {}, nullptr, - QCoreApplication::translate("ShowParticleEmitterAction", "Toggle between always showing the particle emitter visualization and only showing it when the emitter is selected.")); + QCoreApplication::translate("ShowParticleEmitterAction", "Toggle between always showing the particle emitter and attractor visualizations and only showing them when the emitter or attractor is selected.")); SelectionContextOperation resetTrigger = [this](const SelectionContext &) { m_particlesPlayAction->action()->setEnabled(particlemode); diff --git a/src/plugins/qmldesigner/designercore/instances/nodeinstanceview.cpp b/src/plugins/qmldesigner/designercore/instances/nodeinstanceview.cpp index 547d7ad8a60..cce625a2b3d 100644 --- a/src/plugins/qmldesigner/designercore/instances/nodeinstanceview.cpp +++ b/src/plugins/qmldesigner/designercore/instances/nodeinstanceview.cpp @@ -556,10 +556,11 @@ void NodeInstanceView::nodeReparented(const ModelNode &node, const NodeAbstractP m_nodeInstanceServer->reparentInstances( createReparentInstancesCommand(node, newPropertyParent, oldPropertyParent)); - // Reset puppet when particle emitter is reparented to work around issue in + // Reset puppet when particle emitter/affector is reparented to work around issue in // autodetecting the particle system it belongs to. QTBUG-101157 - if (node.isSubclassOf("QtQuick.Particles3D.ParticleEmitter3D") - && node.property("system").toBindingProperty().expression().isEmpty()) { + if ((node.isSubclassOf("QtQuick.Particles3D.ParticleEmitter3D") + || node.isSubclassOf("QtQuick.Particles3D.Affector3D")) + && node.property("system").toBindingProperty().expression().isEmpty()) { resetPuppet(); } }