aboutsummaryrefslogtreecommitdiffstats
path: root/share/qtcreator/qml/qmlpuppet/qml2puppet/editor3d/mousearea3d.cpp
diff options
context:
space:
mode:
authorMiikka Heikkinen <miikka.heikkinen@qt.io>2019-11-05 15:38:12 +0200
committerMiikka Heikkinen <miikka.heikkinen@qt.io>2019-11-08 12:54:06 +0000
commit862b7fa35c7e8cbc0e0b2367b83a1b63dbc43e70 (patch)
tree4f6b5f89bf8ec86499c7d07f171f8da94c5322eb /share/qtcreator/qml/qmlpuppet/qml2puppet/editor3d/mousearea3d.cpp
parentc67965fb2932a129ba6aa87875007fd5b70b24fd (diff)
QmlDesigner: Add planar move and scale handles to gizmos
Change-Id: Icae60ec35fc84d731243a005e97b174fa9a94815 Reviewed-by: Thomas Hartmann <thomas.hartmann@qt.io> Reviewed-by: Mahmoud Badri <mahmoud.badri@qt.io>
Diffstat (limited to 'share/qtcreator/qml/qmlpuppet/qml2puppet/editor3d/mousearea3d.cpp')
-rw-r--r--share/qtcreator/qml/qmlpuppet/qml2puppet/editor3d/mousearea3d.cpp67
1 files changed, 37 insertions, 30 deletions
diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/editor3d/mousearea3d.cpp b/share/qtcreator/qml/qmlpuppet/qml2puppet/editor3d/mousearea3d.cpp
index fe84ed13a6..d4135de973 100644
--- a/share/qtcreator/qml/qmlpuppet/qml2puppet/editor3d/mousearea3d.cpp
+++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/editor3d/mousearea3d.cpp
@@ -204,34 +204,36 @@ QVector3D MouseArea3D::rayIntersectsPlane(const QVector3D &rayPos0,
return rayPos0 + distanceFromRayPos0ToPlane * rayDirection;
}
-// Get a new scale based on a relative scene distance along an axis (used to adjust scale via drag)
-// This function never returns a negative scaling
+// Get a new scale based on a relative scene distance along a drag axis.
+// This function never returns a negative scaling.
+// Note that scaling a rotated object in global coordinate space can't be meaningfully done without
+// distorting the object beyond what current scale property can represent, so global scaling is
+// effectively same as local scaling.
QVector3D MouseArea3D::getNewScale(QQuick3DNode *node, const QVector3D &startScale,
const QVector3D &pressPos,
- const QVector3D &sceneRelativeDistance, float scaler)
+ const QVector3D &sceneRelativeDistance, bool global)
{
if (node) {
// Note: This only returns correct scale when scale is positive
auto getScale = [&](const QMatrix4x4 &m) -> QVector3D {
return QVector3D(m.column(0).length(), m.column(1).length(), m.column(2).length());
};
- const float constantDragScaler = 0.1f;
const float nonZeroValue = 0.0001f;
- if (qFuzzyIsNull(scaler))
- scaler = nonZeroValue;
-
const QVector3D scenePos = node->scenePosition();
const QMatrix4x4 parentTransform = node->parentNode()->sceneTransform();
QMatrix4x4 newTransform = node->sceneTransform();
- QVector3D normalRelDist = sceneRelativeDistance.normalized();
- float direction = QVector3D::dotProduct((pressPos - scenePos).normalized(), normalRelDist);
- float magnitude = constantDragScaler * sceneRelativeDistance.length() / scaler;
-
- // Reset everything but rotation to ensure translation and scale do not affect rotate below
- newTransform(0,3) = 0;
- newTransform(1,3) = 0;
- newTransform(2,3) = 0;
+ const QVector3D nodeToPressPos = pressPos - scenePos;
+ const QVector3D nodeToRelPos = nodeToPressPos + sceneRelativeDistance;
+ const float sceneToPressLen = nodeToPressPos.length();
+ QVector3D scaleDirVector = nodeToRelPos;
+ float magnitude = (scaleDirVector.length() / sceneToPressLen);
+ scaleDirVector.normalize();
+
+ // Reset everything but rotation to ensure translation and scale don't affect rotation below
+ newTransform(0, 3) = 0;
+ newTransform(1, 3) = 0;
+ newTransform(2, 3) = 0;
QVector3D curScale = getScale(newTransform);
if (qFuzzyIsNull(curScale.x()))
curScale.setX(nonZeroValue);
@@ -241,24 +243,29 @@ QVector3D MouseArea3D::getNewScale(QQuick3DNode *node, const QVector3D &startSca
curScale.setZ(nonZeroValue);
newTransform.scale({1.f / curScale.x(), 1.f / curScale.y(), 1.f / curScale.z()});
- // Rotate relative distance according to object rotation
- normalRelDist = newTransform.inverted().map(normalRelDist).normalized();
+ // Rotate the local scale vector so that scale axes are parallel to global axes for easier
+ // scale vector manipulation
+ if (!global)
+ scaleDirVector = newTransform.inverted().map(scaleDirVector).normalized();
// Ensure scaling is always positive/negative according to direction
- normalRelDist.setX(qAbs(normalRelDist.x()));
- normalRelDist.setY(qAbs(normalRelDist.y()));
- normalRelDist.setZ(qAbs(normalRelDist.z()));
- QVector3D scaleVec = normalRelDist;
+ scaleDirVector.setX(qAbs(scaleDirVector.x()));
+ scaleDirVector.setY(qAbs(scaleDirVector.y()));
+ scaleDirVector.setZ(qAbs(scaleDirVector.z()));
+
+ // Make sure the longest scale vec axis is equal to 1 before applying magnitude to avoid
+ // initial jump in size when planar drag starts
+ float maxDir = qMax(qMax(scaleDirVector.x(), scaleDirVector.y()), scaleDirVector.z());
+ QVector3D scaleVec = scaleDirVector / maxDir;
scaleVec *= magnitude;
- if (direction > 0) {
- scaleVec.setX(scaleVec.x() + 1.f);
- scaleVec.setY(scaleVec.y() + 1.f);
- scaleVec.setZ(scaleVec.z() + 1.f);
- } else {
- scaleVec.setX(1.f - scaleVec.x());
- scaleVec.setY(1.f - scaleVec.y());
- scaleVec.setZ(1.f - scaleVec.z());
- }
+
+ // Zero axes on scale vector indicate directions we don't want scaling to affect
+ if (qFuzzyIsNull(scaleVec.x()))
+ scaleVec.setX(1.f);
+ if (qFuzzyIsNull(scaleVec.y()))
+ scaleVec.setY(1.f);
+ if (qFuzzyIsNull(scaleVec.z()))
+ scaleVec.setZ(1.f);
scaleVec *= startScale;
newTransform = parentTransform;