forked from qt-creator/qt-creator
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:
@@ -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);
|
||||||
|
@@ -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;
|
||||||
};
|
};
|
||||||
|
@@ -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;
|
||||||
|
Reference in New Issue
Block a user