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 <mahmoud.badri@qt.io>
Reviewed-by: Thomas Hartmann <thomas.hartmann@qt.io>
This commit is contained in:
Miikka Heikkinen
2021-06-11 14:27:30 +03:00
parent b73884bee5
commit acb4113f09
3 changed files with 7 additions and 14 deletions

View File

@@ -201,8 +201,6 @@ Node {
var scaler = 1.0 + (yDelta * 0.025); var scaler = 1.0 + (yDelta * 0.025);
if (scaler === 0) if (scaler === 0)
scaler = 0.0001; scaler = 0.0001;
if (scaler < 0)
scaler = -scaler;
return Qt.vector3d(scaler * _startScale.x, return Qt.vector3d(scaler * _startScale.x,
scaler * _startScale.y, scaler * _startScale.y,
scaler * _startScale.z); scaler * _startScale.z);

View File

@@ -405,7 +405,8 @@ void GeneralHelper::setMultiSelectionTargets(QQuick3DNode *multiSelectRootNode,
void GeneralHelper::resetMultiSelectionNode() void GeneralHelper::resetMultiSelectionNode()
{ {
for (auto it = m_multiSelDataMap.begin(); it != m_multiSelDataMap.end(); ++it) 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 = {}; m_multiSelNodeData = {};
if (!m_multiSelDataMap.isEmpty()) { 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 // Offset the multiselected nodes in global space according to scale factor and scale them by
// the same factor. // the same factor.
// TODO: The math below breaks down with negative scaling, so don't allow it for now const QVector3D sceneScale = m_multiSelectRootNode->scale();
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 unitVector {1.f, 1.f, 1.f}; 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) { for (auto it = m_multiSelDataMap.constBegin(); it != m_multiSelDataMap.constEnd(); ++it) {
const QVector3D newGlobalPos = m_multiSelNodeData.startScenePos const QVector3D newGlobalPos = m_multiSelNodeData.startScenePos
@@ -468,7 +462,7 @@ void GeneralHelper::scaleMultiSelection(bool commit)
it.key()->setPosition(parentMat * newGlobalPos); it.key()->setPosition(parentMat * newGlobalPos);
QMatrix4x4 mat; QMatrix4x4 mat;
mat.rotate(it.key()->sceneRotation()); mat.rotate(it.value().startSceneRot);
auto scaleDim = [&](int dim) -> QVector3D { auto scaleDim = [&](int dim) -> QVector3D {
QVector3D dimScale; QVector3D dimScale;
@@ -477,7 +471,7 @@ void GeneralHelper::scaleMultiSelection(bool commit)
dimScale = (mat.inverted() * dimScale).normalized() * diffScaleDim; dimScale = (mat.inverted() * dimScale).normalized() * diffScaleDim;
for (int i = 0; i < 3; ++i) for (int i = 0; i < 3; ++i)
dimScale[i] = qAbs(dimScale[i]); dimScale[i] = qAbs(dimScale[i]);
if (fixedSceneScale[dim] < 1.0f) if (sceneScale[dim] < 1.0f)
dimScale = -dimScale; dimScale = -dimScale;
return dimScale; return dimScale;
}; };

View File

@@ -132,6 +132,7 @@ private:
QVector3D startScenePos; QVector3D startScenePos;
QVector3D startScale; QVector3D startScale;
QQuaternion startRot; QQuaternion startRot;
QQuaternion startSceneRot;
}; };
QHash<QQuick3DNode *, MultiSelData> m_multiSelDataMap; QHash<QQuick3DNode *, MultiSelData> m_multiSelDataMap;