diff --git a/common/lc_commands.cpp b/common/lc_commands.cpp index 5f9a86ed..678dda71 100644 --- a/common/lc_commands.cpp +++ b/common/lc_commands.cpp @@ -297,6 +297,13 @@ lcCommand gCommands[LC_NUM_COMMANDS] = QT_TRANSLATE_NOOP("Status", "Move and rotate objects relative to the one that has focus"), "" }, + // LC_EDIT_TRANSFORM_LOCAL + { + QT_TRANSLATE_NOOP("Action", "Edit.TransformLocal"), + QT_TRANSLATE_NOOP("Menu", "Local Transforms"), + QT_TRANSLATE_NOOP("Status", "Rotate pieces around their individual pivot point"), + "" + }, // LC_EDIT_SNAP_MOVE_TOGGLE { QT_TRANSLATE_NOOP("Action", "Edit.Snap.Toggle"), diff --git a/common/lc_commands.h b/common/lc_commands.h index 2a5846d3..f14c9784 100644 --- a/common/lc_commands.h +++ b/common/lc_commands.h @@ -48,6 +48,7 @@ enum lcCommandId LC_EDIT_SELECTION_PIECE_COLOR, LC_EDIT_SELECTION_MODE_LAST = LC_EDIT_SELECTION_PIECE_COLOR, LC_EDIT_TRANSFORM_RELATIVE, + LC_EDIT_TRANSFORM_LOCAL, LC_EDIT_SNAP_MOVE_TOGGLE, LC_EDIT_SNAP_MOVE_XY0, LC_EDIT_SNAP_MOVE_XY1, diff --git a/common/lc_mainwindow.cpp b/common/lc_mainwindow.cpp index 5ecb55f5..9d009bd9 100644 --- a/common/lc_mainwindow.cpp +++ b/common/lc_mainwindow.cpp @@ -100,6 +100,7 @@ lcMainWindow::lcMainWindow() mMoveZSnapIndex = 3; mAngleSnapIndex = 5; mRelativeTransform = true; + mLocalTransform = false; mCurrentPieceInfo = nullptr; mSelectionMode = lcSelectionMode::SINGLE; mModelTabWidget = nullptr; @@ -1659,6 +1660,11 @@ void lcMainWindow::SetRelativeTransform(bool RelativeTransform) UpdateAllViews(); } +void lcMainWindow::SetLocalTransform(bool SelectionTransform) +{ + mLocalTransform = SelectionTransform; +} + void lcMainWindow::SetTransformType(lcTransformType TransformType) { mTransformType = TransformType; @@ -3076,6 +3082,10 @@ void lcMainWindow::HandleCommand(lcCommandId CommandId) SetRelativeTransform(!GetRelativeTransform()); break; + case LC_EDIT_TRANSFORM_LOCAL: + SetLocalTransform(!GetLocalTransform()); + break; + case LC_EDIT_SNAP_MOVE_TOGGLE: SetMoveSnapEnabled(!mMoveSnapEnabled); break; diff --git a/common/lc_mainwindow.h b/common/lc_mainwindow.h index 3206390f..aced6c3a 100644 --- a/common/lc_mainwindow.h +++ b/common/lc_mainwindow.h @@ -192,6 +192,11 @@ public: return mRelativeTransform; } + bool GetLocalTransform() const + { + return mLocalTransform; + } + lcSelectionMode GetSelectionMode() const { return mSelectionMode; @@ -286,6 +291,7 @@ public: void SetMoveZSnapIndex(int Index); void SetAngleSnapIndex(int Index); void SetRelativeTransform(bool RelativeTransform); + void SetLocalTransform(bool SelectionTransform); void SetCurrentPieceInfo(PieceInfo* Info); void SetShadingMode(lcShadingMode ShadingMode); void SetSelectionMode(lcSelectionMode SelectionMode); @@ -402,6 +408,7 @@ protected: int mMoveZSnapIndex; int mAngleSnapIndex; bool mRelativeTransform; + bool mLocalTransform; PieceInfo* mCurrentPieceInfo; lcSelectionMode mSelectionMode; int mModelTabWidgetContextMenuIndex; diff --git a/common/lc_model.cpp b/common/lc_model.cpp index 058a6d89..f39d99ff 100644 --- a/common/lc_model.cpp +++ b/common/lc_model.cpp @@ -2825,7 +2825,7 @@ void lcModel::MoveSelectedObjects(const lcVector3& PieceDistance, const lcVector } } -void lcModel::RotateSelectedPieces(const lcVector3& Angles, bool Relative, bool AlternateButtonDrag, bool Update, bool Checkpoint) +void lcModel::RotateSelectedPieces(const lcVector3& Angles, bool Relative, bool RotatePivotPoint, bool Update, bool Checkpoint) { if (Angles.LengthSquared() < 0.001f) return; @@ -2842,7 +2842,7 @@ void lcModel::RotateSelectedPieces(const lcVector3& Angles, bool Relative, bool if (Angles[2] != 0.0f) RotationMatrix = lcMul(lcMatrix33RotationZ(Angles[2] * LC_DTOR), RotationMatrix); - if (AlternateButtonDrag) + if (RotatePivotPoint) { lcObject* Focus = GetFocusObject(); @@ -2854,29 +2854,60 @@ void lcModel::RotateSelectedPieces(const lcVector3& Angles, bool Relative, bool } else { - lcVector3 Center; - lcMatrix33 RelativeRotation; - - GetMoveRotateTransform(Center, RelativeRotation); - - lcMatrix33 WorldToFocusMatrix; - - if (Relative) + if (!gMainWindow->GetLocalTransform()) { - WorldToFocusMatrix = lcMatrix33AffineInverse(RelativeRotation); - RotationMatrix = lcMul(RotationMatrix, RelativeRotation); + lcVector3 Center; + lcMatrix33 RelativeRotation; + + GetMoveRotateTransform(Center, RelativeRotation); + + lcMatrix33 WorldToFocusMatrix; + + if (Relative) + { + WorldToFocusMatrix = lcMatrix33AffineInverse(RelativeRotation); + RotationMatrix = lcMul(RotationMatrix, RelativeRotation); + } + else + WorldToFocusMatrix = lcMatrix33Identity(); + + for (lcPiece* Piece : mPieces) + { + if (!Piece->IsSelected()) + continue; + + Piece->Rotate(mCurrentStep, gMainWindow->GetAddKeys(), RotationMatrix, Center, WorldToFocusMatrix); + Piece->UpdatePosition(mCurrentStep); + Rotated = true; + } } else - WorldToFocusMatrix = lcMatrix33Identity(); - - for (lcPiece* Piece : mPieces) { - if (!Piece->IsSelected()) - continue; + for (lcPiece* Piece : mPieces) + { + if (!Piece->IsSelected()) + continue; - Piece->Rotate(mCurrentStep, gMainWindow->GetAddKeys(), RotationMatrix, Center, WorldToFocusMatrix); - Piece->UpdatePosition(mCurrentStep); - Rotated = true; + const lcVector3 Center = Piece->GetRotationCenter(); + lcMatrix33 WorldToFocusMatrix; + lcMatrix33 RelativeRotationMatrix; + + if (Relative) + { + lcMatrix33 RelativeRotation = Piece->GetRelativeRotation(); + WorldToFocusMatrix = lcMatrix33AffineInverse(RelativeRotation); + RelativeRotationMatrix = lcMul(RotationMatrix, RelativeRotation); + } + else + { + WorldToFocusMatrix = lcMatrix33Identity(); + RelativeRotationMatrix = RotationMatrix; + } + + Piece->Rotate(mCurrentStep, gMainWindow->GetAddKeys(), RelativeRotationMatrix, Center, WorldToFocusMatrix); + Piece->UpdatePosition(mCurrentStep); + Rotated = true; + } } } diff --git a/common/lc_model.h b/common/lc_model.h index 58e1bb17..210a3c3c 100644 --- a/common/lc_model.h +++ b/common/lc_model.h @@ -321,7 +321,7 @@ public: } void MoveSelectedObjects(const lcVector3& PieceDistance, const lcVector3& ObjectDistance, bool Relative, bool AlternateButtonDrag, bool Update, bool Checkpoint); - void RotateSelectedPieces(const lcVector3& Angles, bool Relative, bool AlternateButtonDrag, bool Update, bool Checkpoint); + void RotateSelectedPieces(const lcVector3& Angles, bool Relative, bool RotatePivotPoint, bool Update, bool Checkpoint); void ScaleSelectedPieces(const float Scale, bool Update, bool Checkpoint); void TransformSelectedObjects(lcTransformType TransformType, const lcVector3& Transform); void SetSelectedPiecesColorIndex(int ColorIndex);