diff --git a/common/lc_model.cpp b/common/lc_model.cpp index 2aada15f..35a8907b 100644 --- a/common/lc_model.cpp +++ b/common/lc_model.cpp @@ -2243,20 +2243,37 @@ void lcModel::MoveSelectedObjects(const lcVector3& PieceDistance, const lcVector { lcVector3 TransformedPieceDistance = lcMul(PieceDistance, RelativeRotation); - for (int PieceIdx = 0; PieceIdx < mPieces.GetSize(); PieceIdx++) + if (AlternateButtonDrag) { - lcPiece* Piece = mPieces[PieceIdx]; - - if (Piece->IsSelected()) + for (int PieceIdx = 0; PieceIdx < mPieces.GetSize(); PieceIdx++) { - Piece->Move(mCurrentStep, gMainWindow->GetAddKeys(), TransformedPieceDistance, AlternateButtonDrag); - Piece->UpdatePosition(mCurrentStep); - Moved = true; + lcPiece* Piece = mPieces[PieceIdx]; + + if (Piece->IsFocused()) + { + Piece->MovePivotPoint(TransformedPieceDistance); + Moved = true; + break; + } + } + } + else + { + for (int PieceIdx = 0; PieceIdx < mPieces.GetSize(); PieceIdx++) + { + lcPiece* Piece = mPieces[PieceIdx]; + + if (Piece->IsSelected()) + { + Piece->Move(mCurrentStep, gMainWindow->GetAddKeys(), TransformedPieceDistance); + Piece->UpdatePosition(mCurrentStep); + Moved = true; + } } } } - if (ObjectDistance.LengthSquared() >= 0.001f) + if (ObjectDistance.LengthSquared() >= 0.001f && !AlternateButtonDrag) { lcVector3 TransformedObjectDistance = lcMul(ObjectDistance, RelativeRotation); @@ -2317,7 +2334,7 @@ void lcModel::RotateSelectedPieces(const lcVector3& Angles, bool Relative, bool if (Focus && Focus->IsPiece()) { - ((lcPiece*)Focus)->RotatePivot(RotationMatrix); + ((lcPiece*)Focus)->RotatePivotPoint(RotationMatrix); Rotated = true; } } @@ -2332,16 +2349,16 @@ void lcModel::RotateSelectedPieces(const lcVector3& Angles, bool Relative, bool { lcPiece* Piece = mPieces[PieceIdx]; - if (Piece->IsSelected()) - { - if (Piece->IsFocused()) - Focus = Piece; + if (!Piece->IsSelected()) + continue; - Piece->CompareBoundingBox(Bounds); + if (Piece->IsFocused() && gMainWindow->GetRelativeTransform()) + Focus = Piece; - Selected = Piece; - NumSelected++; - } + Piece->CompareBoundingBox(Bounds); + + Selected = Piece; + NumSelected++; } lcVector3 Center; @@ -2355,12 +2372,9 @@ void lcModel::RotateSelectedPieces(const lcVector3& Angles, bool Relative, bool lcMatrix33 WorldToFocusMatrix; - if (!gMainWindow->GetRelativeTransform()) - Focus = NULL; - if (Focus && Relative) { - lcMatrix33 FocusToWorldMatrix = lcMatrix33(Focus->mModelWorld); + lcMatrix33 FocusToWorldMatrix = lcMatrix33(Focus->GetRelativeRotation()); WorldToFocusMatrix = lcMatrix33AffineInverse(FocusToWorldMatrix); RotationMatrix = lcMul(RotationMatrix, FocusToWorldMatrix); @@ -2375,21 +2389,7 @@ void lcModel::RotateSelectedPieces(const lcVector3& Angles, bool Relative, bool if (!Piece->IsSelected()) continue; - lcVector3 Distance = Piece->mModelWorld.GetTranslation() - Center; - lcMatrix33 LocalToWorldMatrix = lcMatrix33(Piece->mModelWorld); - - lcMatrix33 LocalToFocusMatrix = lcMul(LocalToWorldMatrix, WorldToFocusMatrix); - lcMatrix33 NewLocalToWorldMatrix = lcMul(LocalToFocusMatrix, RotationMatrix); - - lcMatrix33 WorldToLocalMatrix = lcMatrix33AffineInverse(LocalToWorldMatrix); - - Distance = lcMul(Distance, WorldToLocalMatrix); - Distance = lcMul(Distance, NewLocalToWorldMatrix); - - NewLocalToWorldMatrix.Orthonormalize(); - - Piece->SetPosition(Center + Distance, mCurrentStep, gMainWindow->GetAddKeys()); - Piece->SetRotation(NewLocalToWorldMatrix, mCurrentStep, gMainWindow->GetAddKeys()); + Piece->Rotate(mCurrentStep, gMainWindow->GetAddKeys(), RotationMatrix, Center, WorldToFocusMatrix); Piece->UpdatePosition(mCurrentStep); Rotated = true; } diff --git a/common/piece.cpp b/common/piece.cpp index 5ed90302..a41bb3a9 100644 --- a/common/piece.cpp +++ b/common/piece.cpp @@ -559,25 +559,17 @@ void lcPiece::DrawInterface(lcContext* Context) const } } -void lcPiece::Move(lcStep Step, bool AddKey, const lcVector3& Distance, bool MovePivotPoint) +void lcPiece::Move(lcStep Step, bool AddKey, const lcVector3& Distance) { lcuint32 Section = GetFocusSection(); if (Section == LC_PIECE_SECTION_POSITION || Section == LC_PIECE_SECTION_INVALID) { - if (!MovePivotPoint) - { - lcVector3 Position = mModelWorld.GetTranslation() + Distance; + lcVector3 Position = mModelWorld.GetTranslation() + Distance; - ChangeKey(mPositionKeys, Position, Step, AddKey); + SetPosition(Position, Step, AddKey); - mModelWorld.SetTranslation(Position); - } - else - { - mState |= LC_PIECE_PIVOT_POINT_VALID; - mPivotMatrix.SetTranslation(mPivotMatrix.GetTranslation() + Distance); - } + mModelWorld.SetTranslation(Position); } else { @@ -588,8 +580,39 @@ void lcPiece::Move(lcStep Step, bool AddKey, const lcVector3& Distance, bool Mov } } -void lcPiece::RotatePivot(const lcMatrix33& RotationMatrix) +void lcPiece::Rotate(lcStep Step, bool AddKey, const lcMatrix33& RotationMatrix, const lcVector3& Center, const lcMatrix33& RotationFrame) { + lcVector3 Distance = mModelWorld.GetTranslation() - Center; + lcMatrix33 LocalToWorldMatrix = lcMatrix33(mModelWorld); + + lcMatrix33 LocalToFocusMatrix = lcMul(LocalToWorldMatrix, RotationFrame); + lcMatrix33 NewLocalToWorldMatrix = lcMul(LocalToFocusMatrix, RotationMatrix); + + lcMatrix33 WorldToLocalMatrix = lcMatrix33AffineInverse(LocalToWorldMatrix); + + Distance = lcMul(Distance, WorldToLocalMatrix); + Distance = lcMul(Distance, NewLocalToWorldMatrix); + + NewLocalToWorldMatrix.Orthonormalize(); + + SetPosition(Center + Distance, Step, AddKey); + SetRotation(NewLocalToWorldMatrix, Step, AddKey); +} + +void lcPiece::MovePivotPoint(const lcVector3& Distance) +{ + if (!IsFocused(LC_PIECE_SECTION_POSITION)) + return; + + mPivotMatrix.SetTranslation(mPivotMatrix.GetTranslation() + Distance); + mState |= LC_PIECE_PIVOT_POINT_VALID; +} + +void lcPiece::RotatePivotPoint(const lcMatrix33& RotationMatrix) +{ + if (!IsFocused(LC_PIECE_SECTION_POSITION)) + return; + lcMatrix33 NewPivotRotationMatrix = lcMul(RotationMatrix, lcMatrix33(mPivotMatrix)); NewPivotRotationMatrix.Orthonormalize(); diff --git a/common/piece.h b/common/piece.h index 7b4c3640..b7760eda 100644 --- a/common/piece.h +++ b/common/piece.h @@ -186,51 +186,71 @@ public: virtual void SetFocused(lcuint32 Section, bool Focused) { - lcuint32 Bits = 0; - switch (Section) { case LC_PIECE_SECTION_POSITION: - Bits = LC_PIECE_POSITION_SELECTED | LC_PIECE_POSITION_FOCUSED; + if (Focused) + mState |= (LC_PIECE_POSITION_SELECTED | LC_PIECE_POSITION_FOCUSED); + else + mState &= ~LC_PIECE_POSITION_FOCUSED; break; case LC_PIECE_SECTION_CONTROL_POINT_1: - Bits = LC_PIECE_CONTROL_POINT_1_SELECTED | LC_PIECE_CONTROL_POINT_1_FOCUSED; + if (Focused) + mState |= (LC_PIECE_CONTROL_POINT_1_SELECTED | LC_PIECE_CONTROL_POINT_1_FOCUSED); + else + mState &= ~LC_PIECE_CONTROL_POINT_1_FOCUSED; break; case LC_PIECE_SECTION_CONTROL_POINT_2: - Bits = LC_PIECE_CONTROL_POINT_2_SELECTED | LC_PIECE_CONTROL_POINT_2_FOCUSED; + if (Focused) + mState |= (LC_PIECE_CONTROL_POINT_2_SELECTED | LC_PIECE_CONTROL_POINT_2_FOCUSED); + else + mState &= ~LC_PIECE_CONTROL_POINT_2_FOCUSED; break; case LC_PIECE_SECTION_CONTROL_POINT_3: - Bits = LC_PIECE_CONTROL_POINT_3_SELECTED | LC_PIECE_CONTROL_POINT_3_FOCUSED; + if (Focused) + mState |= (LC_PIECE_CONTROL_POINT_3_SELECTED | LC_PIECE_CONTROL_POINT_3_FOCUSED); + else + mState &= ~LC_PIECE_CONTROL_POINT_3_FOCUSED; break; case LC_PIECE_SECTION_CONTROL_POINT_4: - Bits = LC_PIECE_CONTROL_POINT_4_SELECTED | LC_PIECE_CONTROL_POINT_4_FOCUSED; + if (Focused) + mState |= (LC_PIECE_CONTROL_POINT_4_SELECTED | LC_PIECE_CONTROL_POINT_4_FOCUSED); + else + mState &= ~LC_PIECE_CONTROL_POINT_4_FOCUSED; break; case LC_PIECE_SECTION_CONTROL_POINT_5: - Bits = LC_PIECE_CONTROL_POINT_5_SELECTED | LC_PIECE_CONTROL_POINT_5_FOCUSED; + if (Focused) + mState |= (LC_PIECE_CONTROL_POINT_5_SELECTED | LC_PIECE_CONTROL_POINT_5_FOCUSED); + else + mState &= ~LC_PIECE_CONTROL_POINT_5_FOCUSED; break; case LC_PIECE_SECTION_CONTROL_POINT_6: - Bits = LC_PIECE_CONTROL_POINT_6_SELECTED | LC_PIECE_CONTROL_POINT_6_FOCUSED; + if (Focused) + mState |= (LC_PIECE_CONTROL_POINT_6_SELECTED | LC_PIECE_CONTROL_POINT_6_FOCUSED); + else + mState &= ~LC_PIECE_CONTROL_POINT_6_FOCUSED; break; case LC_PIECE_SECTION_CONTROL_POINT_7: - Bits = LC_PIECE_CONTROL_POINT_7_SELECTED | LC_PIECE_CONTROL_POINT_7_FOCUSED; + if (Focused) + mState |= (LC_PIECE_CONTROL_POINT_7_SELECTED | LC_PIECE_CONTROL_POINT_7_FOCUSED); + else + mState &= ~LC_PIECE_CONTROL_POINT_7_FOCUSED; break; case LC_PIECE_SECTION_CONTROL_POINT_8: - Bits = LC_PIECE_CONTROL_POINT_8_SELECTED | LC_PIECE_CONTROL_POINT_8_FOCUSED; + if (Focused) + mState |= (LC_PIECE_CONTROL_POINT_8_SELECTED | LC_PIECE_CONTROL_POINT_8_FOCUSED); + else + mState &= ~LC_PIECE_CONTROL_POINT_8_FOCUSED; break; } - - if (Focused) - mState |= Bits; - else - mState &= ~Bits; } virtual lcuint32 GetFocusSection() const @@ -344,8 +364,10 @@ public: bool FileLoad(lcFile& file); void UpdatePosition(lcStep Step); - void Move(lcStep Step, bool AddKey, const lcVector3& Distance, bool MovePivotPoint); - void RotatePivot(const lcMatrix33& RotationMatrix); + void Move(lcStep Step, bool AddKey, const lcVector3& Distance); + void Rotate(lcStep Step, bool AddKey, const lcMatrix33& RotationMatrix, const lcVector3& Center, const lcMatrix33& RotationFrame); + void MovePivotPoint(const lcVector3& Distance); + void RotatePivotPoint(const lcMatrix33& RotationMatrix); lcGroup* GetTopGroup(); @@ -405,7 +427,7 @@ public: lcVector3 GetRotationCenter() const { if (mState & LC_PIECE_PIVOT_POINT_VALID) - return lcMul(mModelWorld, mPivotMatrix).GetTranslation(); + return lcMul31(mPivotMatrix.GetTranslation(), mModelWorld); else return mModelWorld.GetTranslation(); }