aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMiikka Heikkinen <[email protected]>2024-05-23 12:34:57 +0300
committerMiikka Heikkinen <[email protected]>2024-05-23 10:48:44 +0000
commit8bfe8056459d264cf2b83de0269f7034eb2f6b2b (patch)
tree34e670b4ae6d8a9199c401a5b8ac73982b18de65
parentd3452545796bdf4ee87daf5b24b42ecf7d6036af (diff)
QmlDesigner: Allow rotation of 3D import preview
3D import preview can now be rotated using left mouse button and dragging the preview image. This causes camera to orbit around the previewed model, similar to rotation to 3D edit view orbit camera. Close/Cancel button logic was also improved. Fixes: QDS-12795 Change-Id: I0c7d1ad28f8fe779b9bedc4bf76be704078d91a6 Reviewed-by: Mahmoud Badri <[email protected]>
-rw-r--r--src/libs/qmlpuppetcommunication/interfaces/nodeinstanceglobal.h3
-rw-r--r--src/plugins/qmldesigner/components/itemlibrary/import3dcanvas.cpp26
-rw-r--r--src/plugins/qmldesigner/components/itemlibrary/import3dcanvas.h7
-rw-r--r--src/plugins/qmldesigner/components/itemlibrary/itemlibraryassetimportdialog.cpp34
-rw-r--r--src/plugins/qmldesigner/components/itemlibrary/itemlibraryassetimportdialog.h3
-rw-r--r--src/tools/qml2puppet/qml2puppet/editor3d/generalhelper.cpp23
-rw-r--r--src/tools/qml2puppet/qml2puppet/editor3d/generalhelper.h11
-rw-r--r--src/tools/qml2puppet/qml2puppet/instances/nodeinstanceserver.h1
-rw-r--r--src/tools/qml2puppet/qml2puppet/instances/qt5import3dnodeinstanceserver.cpp55
-rw-r--r--src/tools/qml2puppet/qml2puppet/instances/qt5import3dnodeinstanceserver.h2
10 files changed, 129 insertions, 36 deletions
diff --git a/src/libs/qmlpuppetcommunication/interfaces/nodeinstanceglobal.h b/src/libs/qmlpuppetcommunication/interfaces/nodeinstanceglobal.h
index 06df0f79754..206fb760956 100644
--- a/src/libs/qmlpuppetcommunication/interfaces/nodeinstanceglobal.h
+++ b/src/libs/qmlpuppetcommunication/interfaces/nodeinstanceglobal.h
@@ -56,7 +56,8 @@ enum class View3DActionType {
EditCameraMove,
EditCameraStopAllMoves,
SetLastSceneEnvData,
- Import3dUpdatePreviewImage
+ Import3dUpdatePreviewImage,
+ Import3dRotatePreviewModel
};
constexpr bool isNanotraceEnabled()
diff --git a/src/plugins/qmldesigner/components/itemlibrary/import3dcanvas.cpp b/src/plugins/qmldesigner/components/itemlibrary/import3dcanvas.cpp
index 87014cbe603..608bf42eb36 100644
--- a/src/plugins/qmldesigner/components/itemlibrary/import3dcanvas.cpp
+++ b/src/plugins/qmldesigner/components/itemlibrary/import3dcanvas.cpp
@@ -5,6 +5,7 @@
#include <QImage>
#include <QLinearGradient>
+#include <QMouseEvent>
#include <QPainter>
namespace QmlDesigner {
@@ -52,5 +53,30 @@ void Import3dCanvas::resizeEvent(QResizeEvent *)
emit requestImageUpdate();
}
+void Import3dCanvas::mousePressEvent(QMouseEvent *e)
+{
+ if (e->buttons() == Qt::LeftButton)
+ m_dragPos = e->position();
+ else
+ m_dragPos = {};
+}
+
+void Import3dCanvas::mouseReleaseEvent(QMouseEvent *)
+{
+ m_dragPos = {};
+}
+
+void Import3dCanvas::mouseMoveEvent(QMouseEvent *e)
+{
+ if (m_dragPos.isNull())
+ return;
+
+ const QPointF curPos = e->position();
+ const QPointF delta = curPos - m_dragPos;
+
+ m_dragPos = curPos;
+
+ emit requestRotation(delta);
+}
}
diff --git a/src/plugins/qmldesigner/components/itemlibrary/import3dcanvas.h b/src/plugins/qmldesigner/components/itemlibrary/import3dcanvas.h
index 22bcc04d70f..72fb19acffc 100644
--- a/src/plugins/qmldesigner/components/itemlibrary/import3dcanvas.h
+++ b/src/plugins/qmldesigner/components/itemlibrary/import3dcanvas.h
@@ -4,7 +4,7 @@
#include <QEvent>
#include <QImage>
-#include <QPointer>
+#include <QPointF>
#include <QWidget>
namespace QmlDesigner {
@@ -20,13 +20,18 @@ public:
signals:
void requestImageUpdate();
+ void requestRotation(const QPointF &delta);
protected:
void paintEvent(QPaintEvent *e) override;
void resizeEvent(QResizeEvent *e) override;
+ void mousePressEvent(QMouseEvent *e) override;
+ void mouseReleaseEvent(QMouseEvent *e) override;
+ void mouseMoveEvent(QMouseEvent *e) override;
private:
QImage m_image;
+ QPointF m_dragPos;
};
} // namespace QmlDesigner
diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibraryassetimportdialog.cpp b/src/plugins/qmldesigner/components/itemlibrary/itemlibraryassetimportdialog.cpp
index 4e49cd2b807..8af81a7b82e 100644
--- a/src/plugins/qmldesigner/components/itemlibrary/itemlibraryassetimportdialog.cpp
+++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibraryassetimportdialog.cpp
@@ -221,6 +221,8 @@ ItemLibraryAssetImportDialog::ItemLibraryAssetImportDialog(
this, &ItemLibraryAssetImportDialog::updateUi);
connect(canvas(), &Import3dCanvas::requestImageUpdate,
this, &ItemLibraryAssetImportDialog::onRequestImageUpdate);
+ connect(canvas(), &Import3dCanvas::requestRotation,
+ this, &ItemLibraryAssetImportDialog::onRequestRotation);
connect(&m_importer, &ItemLibraryAssetImporter::errorReported,
this, &ItemLibraryAssetImportDialog::addError);
@@ -856,9 +858,10 @@ Rectangle {
width: %1
height: %2
- property string sceneModelName: "%3"
+ property alias sceneNode: sceneNode
property alias view3d: view3d
property string extents
+ property string sceneModelName: "%3"
gradient: Gradient {
GradientStop { position: 1.0; color: "#222222" }
@@ -877,9 +880,9 @@ Rectangle {
PerspectiveCamera {
id: viewCamera
- z: 600
- y: 600
x: 600
+ y: 600
+ z: 600
eulerRotation.x: -45
eulerRotation.y: -45
clipFar: 100000
@@ -889,6 +892,10 @@ Rectangle {
DirectionalLight {
rotation: viewCamera.rotation
}
+
+ Node {
+ id: sceneNode
+ }
}
Text {
@@ -1041,7 +1048,8 @@ void ItemLibraryAssetImportDialog::onImportReadyForPreview(const QString &path,
ui->acceptButton->setEnabled(true);
ui->importButton->setEnabled(true);
- addInfo(tr("Generating import preview for %1.").arg(compName));
+ addInfo(tr("Import is ready for preview."));
+ addInfo(tr("Click \"Accept\" to finish the import or adjust options an click \"Import\" to import again."));
}
void ItemLibraryAssetImportDialog::onRequestImageUpdate()
@@ -1050,6 +1058,12 @@ void ItemLibraryAssetImportDialog::onRequestImageUpdate()
m_nodeInstanceView->view3DAction(View3DActionType::Import3dUpdatePreviewImage, canvas()->size());
}
+void ItemLibraryAssetImportDialog::onRequestRotation(const QPointF &delta)
+{
+ if (m_nodeInstanceView)
+ m_nodeInstanceView->view3DAction(View3DActionType::Import3dRotatePreviewModel, delta);
+}
+
void ItemLibraryAssetImportDialog::onImportNearlyFinished()
{
// Canceling import is no longer doable
@@ -1063,19 +1077,29 @@ void ItemLibraryAssetImportDialog::onImportFinished()
QString interruptStr = tr("Import interrupted.");
addError(interruptStr);
setImportProgress(0, interruptStr);
+ if (m_explicitClose)
+ QTimer::singleShot(1000, this, &ItemLibraryAssetImportDialog::doClose);
} else {
QString doneStr = tr("Import done.");
addInfo(doneStr);
setImportProgress(100, doneStr);
if (m_closeOnFinish) {
// Add small delay to allow user to visually confirm import finishing
- QTimer::singleShot(1000, this, &ItemLibraryAssetImportDialog::onClose);
+ QTimer::singleShot(1000, this, &ItemLibraryAssetImportDialog::doClose);
}
}
}
void ItemLibraryAssetImportDialog::onClose()
{
+ ui->importButton->setEnabled(false);
+ ui->acceptButton->setEnabled(false);
+ m_explicitClose = true;
+ doClose();
+}
+
+void ItemLibraryAssetImportDialog::doClose()
+{
if (m_importer.isImporting()) {
addInfo(tr("Canceling import."));
m_importer.cancelImport();
diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibraryassetimportdialog.h b/src/plugins/qmldesigner/components/itemlibrary/itemlibraryassetimportdialog.h
index efbd189c2fd..635be6db696 100644
--- a/src/plugins/qmldesigner/components/itemlibrary/itemlibraryassetimportdialog.h
+++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibraryassetimportdialog.h
@@ -68,9 +68,11 @@ private:
void setImportProgress(int value, const QString &text);
void onImportReadyForPreview(const QString &path, const QString &compName);
void onRequestImageUpdate();
+ void onRequestRotation(const QPointF &delta);
void onImportNearlyFinished();
void onImportFinished();
void onClose();
+ void doClose();
void onAccept();
void toggleAdvanced();
@@ -116,5 +118,6 @@ private:
OptionsData m_advancedData;
bool m_advancedMode = false;
int m_dialogHeight = 350;
+ bool m_explicitClose = false;
};
}
diff --git a/src/tools/qml2puppet/qml2puppet/editor3d/generalhelper.cpp b/src/tools/qml2puppet/qml2puppet/editor3d/generalhelper.cpp
index 1ccea6049c8..3baf91c1464 100644
--- a/src/tools/qml2puppet/qml2puppet/editor3d/generalhelper.cpp
+++ b/src/tools/qml2puppet/qml2puppet/editor3d/generalhelper.cpp
@@ -462,17 +462,19 @@ QVector4D GeneralHelper::approachNode(
// a selection box for bound calculations to work. This is used to focus the view for
// various preview image generations, where doing things asynchronously is not good
// and recalculating bounds for every frame is not a problem.
-QVector3D GeneralHelper::calculateNodeBoundsAndFocusCamera(
- QQuick3DCamera *camera, QQuick3DNode *node, QQuick3DViewport *viewPort,
- float defaultLookAtDistance, bool closeUp)
+void GeneralHelper::calculateBoundsAndFocusCamera(QQuick3DCamera *camera, QQuick3DNode *node,
+ QQuick3DViewport *viewPort,
+ float defaultLookAtDistance,
+ bool closeUp, QVector3D &lookAt,
+ QVector3D &extents)
{
QVector3D minBounds;
QVector3D maxBounds;
getBounds(viewPort, node, minBounds, maxBounds);
- QVector3D extents = maxBounds - minBounds;
- QVector3D lookAt = minBounds + (extents / 2.f);
+ extents = maxBounds - minBounds;
+ lookAt = minBounds + (extents / 2.f);
float maxExtent = qSqrt(qreal(extents.x()) * qreal(extents.x())
+ qreal(extents.y()) * qreal(extents.y())
+ qreal(extents.z()) * qreal(extents.z()));
@@ -506,8 +508,17 @@ QVector3D GeneralHelper::calculateNodeBoundsAndFocusCamera(
perspectiveCamera->setClipFar(maxDist * 1.01);
}
}
+}
- return extents;
+void GeneralHelper::calculateNodeBoundsAndFocusCamera(QQuick3DCamera *camera, QQuick3DNode *node,
+ QQuick3DViewport *viewPort,
+ float defaultLookAtDistance,
+ bool closeUp)
+{
+ QVector3D extents;
+ QVector3D lookAt;
+ calculateBoundsAndFocusCamera(camera, node, viewPort, defaultLookAtDistance, closeUp,
+ lookAt, extents);
}
// Aligns any cameras found in nodes list to a camera.
diff --git a/src/tools/qml2puppet/qml2puppet/editor3d/generalhelper.h b/src/tools/qml2puppet/qml2puppet/editor3d/generalhelper.h
index 996a06488f4..f1b57f4122f 100644
--- a/src/tools/qml2puppet/qml2puppet/editor3d/generalhelper.h
+++ b/src/tools/qml2puppet/qml2puppet/editor3d/generalhelper.h
@@ -72,11 +72,12 @@ public:
bool closeUp = false);
Q_INVOKABLE QVector4D approachNode(QQuick3DCamera *camera, float defaultLookAtDistance,
QObject *node, QQuick3DViewport *viewPort);
- Q_INVOKABLE QVector3D calculateNodeBoundsAndFocusCamera(QQuick3DCamera *camera,
- QQuick3DNode *node,
- QQuick3DViewport *viewPort,
- float defaultLookAtDistance,
- bool closeUp);
+ void calculateBoundsAndFocusCamera(QQuick3DCamera *camera, QQuick3DNode *node,
+ QQuick3DViewport *viewPort, float defaultLookAtDistance,
+ bool closeUp, QVector3D &lookAt, QVector3D &extents);
+ Q_INVOKABLE void calculateNodeBoundsAndFocusCamera(QQuick3DCamera *camera, QQuick3DNode *node,
+ QQuick3DViewport *viewPort,
+ float defaultLookAtDistance, bool closeUp);
Q_INVOKABLE void alignCameras(QQuick3DCamera *camera, const QVariant &nodes);
Q_INVOKABLE QVector4D alignView(QQuick3DCamera *camera, const QVariant &nodes,
const QVector3D &lookAtPoint, float defaultLookAtDistance);
diff --git a/src/tools/qml2puppet/qml2puppet/instances/nodeinstanceserver.h b/src/tools/qml2puppet/qml2puppet/instances/nodeinstanceserver.h
index 65542dedc25..09c87b3af92 100644
--- a/src/tools/qml2puppet/qml2puppet/instances/nodeinstanceserver.h
+++ b/src/tools/qml2puppet/qml2puppet/instances/nodeinstanceserver.h
@@ -258,6 +258,7 @@ protected:
void setRenderTimerInterval(int timerInterval);
int renderTimerInterval() const;
void setSlowRenderTimerInterval(int timerInterval);
+ TimerMode timerMode() const { return m_timerMode; }
virtual void initializeView() = 0;
virtual void initializeAuxiliaryViews();
diff --git a/src/tools/qml2puppet/qml2puppet/instances/qt5import3dnodeinstanceserver.cpp b/src/tools/qml2puppet/qml2puppet/instances/qt5import3dnodeinstanceserver.cpp
index b5afa949ec2..5d45a881af5 100644
--- a/src/tools/qml2puppet/qml2puppet/instances/qt5import3dnodeinstanceserver.cpp
+++ b/src/tools/qml2puppet/qml2puppet/instances/qt5import3dnodeinstanceserver.cpp
@@ -68,6 +68,19 @@ void Qt5Import3dNodeInstanceServer::view3DAction([[maybe_unused]] const View3DAc
}
break;
}
+ case View3DActionType::Import3dRotatePreviewModel: {
+ QObject *obj = rootItem();
+ QQmlProperty sceneNodeProp(obj, "sceneNode", context());
+ auto sceneNode = sceneNodeProp.read().value<QQuick3DNode *>();
+ if (sceneNode) {
+ QPointF delta = command.value().toPointF();
+ m_generalHelper->orbitCamera(m_view3D->camera(), m_view3D->camera()->eulerRotation(),
+ m_lookAt, {}, {float(delta.x()), float(delta.y()), 0.f});
+ m_keepRendering = true;
+ startRenderTimer();
+ }
+ break;
+ }
default:
break;
}
@@ -75,12 +88,10 @@ void Qt5Import3dNodeInstanceServer::view3DAction([[maybe_unused]] const View3DAc
void Qt5Import3dNodeInstanceServer::startRenderTimer()
{
- if (timerId() != 0)
- killTimer(timerId());
-
- int timerId = startTimer(renderTimerInterval());
+ if (m_keepRendering && timerMode() == TimerMode::NormalTimer)
+ return;
- setTimerId(timerId);
+ NodeInstanceServer::startRenderTimer();
}
void Qt5Import3dNodeInstanceServer::cleanup()
@@ -126,24 +137,28 @@ void Qt5Import3dNodeInstanceServer::render()
m_view3D = qobject_cast<QQuick3DViewport *>(viewObj);
if (m_view3D) {
QQmlProperty sceneModelNameProp(obj, "sceneModelName", context());
- QString sceneModelName = sceneModelNameProp.read().toString();
- QFileInfo fi(fileUrl().toLocalFile());
- QString compPath = fi.absolutePath() + '/' + sceneModelName + ".qml";
- QQmlComponent comp(engine(), compPath, QQmlComponent::PreferSynchronous);
- m_previewNode = qobject_cast<QQuick3DNode *>(comp.create(context()));
- if (m_previewNode) {
- engine()->setObjectOwnership(m_previewNode, QJSEngine::CppOwnership);
- m_previewNode->setParent(m_view3D);
- m_view3D->setImportScene(m_previewNode);
+ QQmlProperty sceneNodeProp(obj, "sceneNode", context());
+ auto sceneNode = sceneNodeProp.read().value<QQuick3DNode *>();
+ if (sceneNode) {
+ QString sceneModelName = sceneModelNameProp.read().toString();
+ QFileInfo fi(fileUrl().toLocalFile());
+ QString compPath = fi.absolutePath() + '/' + sceneModelName + ".qml";
+ QQmlComponent comp(engine(), compPath, QQmlComponent::PreferSynchronous);
+ m_previewNode = qobject_cast<QQuick3DNode *>(comp.create(context()));
+ if (m_previewNode) {
+ engine()->setObjectOwnership(m_previewNode, QJSEngine::CppOwnership);
+ m_previewNode->setParentItem(sceneNode);
+ m_previewNode->setParent(sceneNode);
+ }
}
}
}
// Render scene once to ensure geometries are intialized so bounds calculations work correctly
if (m_renderCount == 2 && m_view3D) {
- QVector3D extents =
- m_generalHelper->calculateNodeBoundsAndFocusCamera(m_view3D->camera(), m_previewNode,
- m_view3D, 1040, false);
+ QVector3D extents;
+ m_generalHelper->calculateBoundsAndFocusCamera(m_view3D->camera(), m_previewNode,
+ m_view3D, 1050, false, m_lookAt, extents);
auto getExtentStr = [&extents](int idx) -> QString {
int prec = 0;
float val = extents[idx];
@@ -176,7 +191,11 @@ void Qt5Import3dNodeInstanceServer::render()
nodeInstanceClient()->handlePuppetToCreatorCommand(
{PuppetToCreatorCommand::Import3DPreviewImage,
QVariant::fromValue(imgContainer)});
- slowDownRenderTimer(); // No more renders needed for now
+
+ if (!m_keepRendering)
+ slowDownRenderTimer();
+
+ m_keepRendering = false;
}
#else
slowDownRenderTimer();
diff --git a/src/tools/qml2puppet/qml2puppet/instances/qt5import3dnodeinstanceserver.h b/src/tools/qml2puppet/qml2puppet/instances/qt5import3dnodeinstanceserver.h
index bc3506ea3c0..a68401ef9fd 100644
--- a/src/tools/qml2puppet/qml2puppet/instances/qt5import3dnodeinstanceserver.h
+++ b/src/tools/qml2puppet/qml2puppet/instances/qt5import3dnodeinstanceserver.h
@@ -35,11 +35,13 @@ private:
void cleanup();
int m_renderCount = 0;
+ bool m_keepRendering = false;
#ifdef QUICK3D_MODULE
QQuick3DViewport *m_view3D = nullptr;
Internal::GeneralHelper *m_generalHelper = nullptr;
QQuick3DNode *m_previewNode = nullptr;
+ QVector3D m_lookAt;
#endif
};