diff --git a/src/modelwidget.cpp b/src/modelwidget.cpp index c0747ca7..d4fa0347 100644 --- a/src/modelwidget.cpp +++ b/src/modelwidget.cpp @@ -1,11 +1,12 @@ -#include "modelwidget.h" -#include "ds3file.h" -#include "skeletongraphicswidget.h" #include #include #include #include #include +#include "modelwidget.h" +#include "ds3file.h" +#include "skeletongraphicswidget.h" +#include "modelwidget.h" // Modifed from http://doc.qt.io/qt-5/qtopengl-hellogl2-glwidget-cpp.html @@ -63,14 +64,6 @@ ModelWidget::~ModelWidget() cleanup(); } -static void qNormalizeAngle(int &angle) -{ - while (angle < 0) - angle += 360 * 16; - while (angle > 360 * 16) - angle -= 360 * 16; -} - void ModelWidget::setXRotation(int angle) { qNormalizeAngle(angle); diff --git a/src/skeletongraphicswidget.cpp b/src/skeletongraphicswidget.cpp index cda7d97c..18c8c9d9 100644 --- a/src/skeletongraphicswidget.cpp +++ b/src/skeletongraphicswidget.cpp @@ -8,6 +8,7 @@ #include #include #include +#include #include "skeletongraphicswidget.h" #include "theme.h" #include "util.h" @@ -29,7 +30,8 @@ SkeletonGraphicsWidget::SkeletonGraphicsWidget(const SkeletonDocument *document) m_lastAddedZ(0), m_selectionItem(nullptr), m_rangeSelectionStarted(false), - m_mouseEventFromSelf(false) + m_mouseEventFromSelf(false), + m_lastRot(0) { setRenderHint(QPainter::Antialiasing, false); setBackgroundBrush(QBrush(QWidget::palette().color(QWidget::backgroundRole()), Qt::SolidPattern)); @@ -485,12 +487,36 @@ bool SkeletonGraphicsWidget::mouseMove(QMouseEvent *event) float byY = sceneRadiusToUnified(mouseScenePos.y() - m_lastScenePos.y()); std::set nodeItems; readMergedSkeletonNodeSetFromRangeSelection(&nodeItems); - for (const auto &it: nodeItems) { - SkeletonGraphicsNodeItem *nodeItem = it; - if (SkeletonProfile::Main == nodeItem->profile()) { - emit moveNodeBy(nodeItem->id(), byX, byY, 0); - } else { - emit moveNodeBy(nodeItem->id(), 0, byY, byX); + if (QGuiApplication::queryKeyboardModifiers().testFlag(Qt::ShiftModifier)) { + QVector2D center = centerOfNodeItemSet(nodeItems); + int degreeX = (mouseScenePos.x() - m_lastScenePos.x()); + qNormalizeAngle(degreeX); + for (const auto &it: nodeItems) { + SkeletonGraphicsNodeItem *nodeItem = it; + QMatrix4x4 mat; + QVector3D centerPoint(center.x(), center.y(), 0); + QPointF nodeOrigin = nodeItem->origin(); + QVector3D nodeOriginPoint(nodeOrigin.x(), nodeOrigin.y(), 0); + QVector3D p = nodeOriginPoint - centerPoint; + mat.rotate(degreeX, 0, 0, 1); + p = mat * p; + QVector3D finalPoint = p + centerPoint; + byX = sceneRadiusToUnified(finalPoint.x() - nodeOrigin.x()); + byY = sceneRadiusToUnified(finalPoint.y() - nodeOrigin.y()); + if (SkeletonProfile::Main == nodeItem->profile()) { + emit moveNodeBy(nodeItem->id(), byX, byY, 0); + } else { + emit moveNodeBy(nodeItem->id(), 0, byY, byX); + } + } + } else { + for (const auto &it: nodeItems) { + SkeletonGraphicsNodeItem *nodeItem = it; + if (SkeletonProfile::Main == nodeItem->profile()) { + emit moveNodeBy(nodeItem->id(), byX, byY, 0); + } else { + emit moveNodeBy(nodeItem->id(), 0, byY, byX); + } } } m_lastScenePos = mouseScenePos; @@ -609,6 +635,7 @@ bool SkeletonGraphicsWidget::mouseRelease(QMouseEvent *event) } if (m_moveStarted) { m_moveStarted = false; + m_lastRot = 0; if (m_moveHappened) emit groupOperationAdded(); } diff --git a/src/skeletongraphicswidget.h b/src/skeletongraphicswidget.h index f2964116..ed74f956 100644 --- a/src/skeletongraphicswidget.h +++ b/src/skeletongraphicswidget.h @@ -363,6 +363,7 @@ private: std::set m_rangeSelectionSet; bool m_mouseEventFromSelf; bool m_moveHappened; + int m_lastRot; }; class SkeletonGraphicsContainerWidget : public QWidget diff --git a/src/util.cpp b/src/util.cpp index 37eefc8b..f5a40108 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -18,3 +18,12 @@ bool isFloatEqual(float a, float b) { return fabs(a - b) <= 0.000001; } + +void qNormalizeAngle(int &angle) +{ + while (angle < 0) + angle += 360 * 16; + while (angle > 360 * 16) + angle -= 360 * 16; +} + diff --git a/src/util.h b/src/util.h index 841c717a..0e857993 100644 --- a/src/util.h +++ b/src/util.h @@ -11,5 +11,6 @@ QString valueOfKeyInMapOrEmpty(const std::map &map, const QString &key); bool isTrueValueString(const QString &str); bool isFloatEqual(float a, float b); +void qNormalizeAngle(int &angle); #endif