From acb4113f09fbedc5888d1817a5867c9e1633346c Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Fri, 11 Jun 2021 14:27:30 +0300 Subject: [PATCH] QmlPuppet: Enable negative scaling in multiselection Scenerotation was queried from the node for each drag move, causing drift in the calculations. Locking the rotation at drag start makes negative scaling work nicely. Also enabled negative values on all axis scaling, since it makes no sense to block it there when single axis/planar scaling already allows it. Fixes: QDS-4493 Change-Id: I7a38a08556bd6d729974332d312aa4aa4e84ea30 Reviewed-by: Mahmoud Badri Reviewed-by: Thomas Hartmann --- .../qml/qmlpuppet/mockfiles/ScaleGizmo.qml | 2 -- .../qml2puppet/editor3d/generalhelper.cpp | 18 ++++++------------ .../qml2puppet/editor3d/generalhelper.h | 1 + 3 files changed, 7 insertions(+), 14 deletions(-) diff --git a/share/qtcreator/qml/qmlpuppet/mockfiles/ScaleGizmo.qml b/share/qtcreator/qml/qmlpuppet/mockfiles/ScaleGizmo.qml index 1b69a17ad17..1d050921591 100644 --- a/share/qtcreator/qml/qmlpuppet/mockfiles/ScaleGizmo.qml +++ b/share/qtcreator/qml/qmlpuppet/mockfiles/ScaleGizmo.qml @@ -201,8 +201,6 @@ Node { var scaler = 1.0 + (yDelta * 0.025); if (scaler === 0) scaler = 0.0001; - if (scaler < 0) - scaler = -scaler; return Qt.vector3d(scaler * _startScale.x, scaler * _startScale.y, scaler * _startScale.z); diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/editor3d/generalhelper.cpp b/share/qtcreator/qml/qmlpuppet/qml2puppet/editor3d/generalhelper.cpp index 09b2569e2db..d76d335fd7e 100644 --- a/share/qtcreator/qml/qmlpuppet/qml2puppet/editor3d/generalhelper.cpp +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/editor3d/generalhelper.cpp @@ -405,7 +405,8 @@ void GeneralHelper::setMultiSelectionTargets(QQuick3DNode *multiSelectRootNode, void GeneralHelper::resetMultiSelectionNode() { for (auto it = m_multiSelDataMap.begin(); it != m_multiSelDataMap.end(); ++it) - it.value() = {pivotScenePosition(it.key()), it.key()->scale(), it.key()->rotation()}; + it.value() = {pivotScenePosition(it.key()), it.key()->scale(), + it.key()->rotation(), it.key()->sceneRotation()}; m_multiSelNodeData = {}; if (!m_multiSelDataMap.isEmpty()) { @@ -448,16 +449,9 @@ void GeneralHelper::scaleMultiSelection(bool commit) // Offset the multiselected nodes in global space according to scale factor and scale them by // the same factor. - // TODO: The math below breaks down with negative scaling, so don't allow it for now - const QVector3D sceneScale = m_multiSelectRootNode->sceneScale(); - QVector3D fixedSceneScale = sceneScale; - for (int i = 0; i < 3; ++i) { - if (sceneScale[i] < 0.f) - fixedSceneScale[i] = -sceneScale[i]; - } - + const QVector3D sceneScale = m_multiSelectRootNode->scale(); const QVector3D unitVector {1.f, 1.f, 1.f}; - const QVector3D diffScale = (fixedSceneScale - unitVector); + const QVector3D diffScale = sceneScale - unitVector; for (auto it = m_multiSelDataMap.constBegin(); it != m_multiSelDataMap.constEnd(); ++it) { const QVector3D newGlobalPos = m_multiSelNodeData.startScenePos @@ -468,7 +462,7 @@ void GeneralHelper::scaleMultiSelection(bool commit) it.key()->setPosition(parentMat * newGlobalPos); QMatrix4x4 mat; - mat.rotate(it.key()->sceneRotation()); + mat.rotate(it.value().startSceneRot); auto scaleDim = [&](int dim) -> QVector3D { QVector3D dimScale; @@ -477,7 +471,7 @@ void GeneralHelper::scaleMultiSelection(bool commit) dimScale = (mat.inverted() * dimScale).normalized() * diffScaleDim; for (int i = 0; i < 3; ++i) dimScale[i] = qAbs(dimScale[i]); - if (fixedSceneScale[dim] < 1.0f) + if (sceneScale[dim] < 1.0f) dimScale = -dimScale; return dimScale; }; diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/editor3d/generalhelper.h b/share/qtcreator/qml/qmlpuppet/qml2puppet/editor3d/generalhelper.h index 22e37e2352a..05ec29249eb 100644 --- a/share/qtcreator/qml/qmlpuppet/qml2puppet/editor3d/generalhelper.h +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/editor3d/generalhelper.h @@ -132,6 +132,7 @@ private: QVector3D startScenePos; QVector3D startScale; QQuaternion startRot; + QQuaternion startSceneRot; }; QHash m_multiSelDataMap;