mirror of
https://github.com/leozide/leocad
synced 2025-01-29 20:34:50 +01:00
Rotate pivot points.
This commit is contained in:
parent
a035bf7ed1
commit
dfc94a42e5
3 changed files with 97 additions and 83 deletions
|
@ -2299,38 +2299,8 @@ void lcModel::RotateSelectedPieces(const lcVector3& Angles, bool Relative, bool
|
|||
if (Angles.LengthSquared() < 0.001f)
|
||||
return;
|
||||
|
||||
float Bounds[6] = { FLT_MAX, FLT_MAX, FLT_MAX, -FLT_MAX, -FLT_MAX, -FLT_MAX };
|
||||
lcPiece* Focus = NULL;
|
||||
lcPiece* Selected = NULL;
|
||||
int NumSelected = 0;
|
||||
|
||||
for (int PieceIdx = 0; PieceIdx < mPieces.GetSize(); PieceIdx++)
|
||||
{
|
||||
lcPiece* Piece = mPieces[PieceIdx];
|
||||
|
||||
if (Piece->IsSelected())
|
||||
{
|
||||
if (Piece->IsFocused())
|
||||
Focus = Piece;
|
||||
|
||||
Piece->CompareBoundingBox(Bounds);
|
||||
|
||||
Selected = Piece;
|
||||
NumSelected++;
|
||||
}
|
||||
}
|
||||
|
||||
lcVector3 Center;
|
||||
|
||||
if (Focus)
|
||||
Center = Focus->GetRotationCenter();
|
||||
else if (NumSelected == 1)
|
||||
Center = Selected->GetRotationCenter();
|
||||
else
|
||||
Center = lcVector3((Bounds[0] + Bounds[3]) / 2.0f, (Bounds[1] + Bounds[4]) / 2.0f, (Bounds[2] + Bounds[5]) / 2.0f);
|
||||
|
||||
lcMatrix33 RotationMatrix = lcMatrix33Identity();
|
||||
lcMatrix33 WorldToFocusMatrix;
|
||||
bool Rotated = false;
|
||||
|
||||
if (Angles[0] != 0.0f)
|
||||
RotationMatrix = lcMul(lcMatrix33RotationX(Angles[0] * LC_DTOR), RotationMatrix);
|
||||
|
@ -2341,45 +2311,88 @@ void lcModel::RotateSelectedPieces(const lcVector3& Angles, bool Relative, bool
|
|||
if (Angles[2] != 0.0f)
|
||||
RotationMatrix = lcMul(lcMatrix33RotationZ(Angles[2] * LC_DTOR), RotationMatrix);
|
||||
|
||||
if (!gMainWindow->GetRelativeTransform())
|
||||
Focus = NULL;
|
||||
|
||||
if (Focus && Relative)
|
||||
if (AlternateButtonDrag)
|
||||
{
|
||||
lcMatrix33 FocusToWorldMatrix = lcMatrix33(Focus->mModelWorld);
|
||||
WorldToFocusMatrix = lcMatrix33AffineInverse(FocusToWorldMatrix);
|
||||
lcObject* Focus = GetFocusObject();
|
||||
|
||||
RotationMatrix = lcMul(RotationMatrix, FocusToWorldMatrix);
|
||||
if (Focus && Focus->IsPiece())
|
||||
{
|
||||
((lcPiece*)Focus)->RotatePivot(RotationMatrix);
|
||||
Rotated = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
WorldToFocusMatrix = lcMatrix33Identity();
|
||||
|
||||
bool Rotated = false;
|
||||
|
||||
for (int PieceIdx = 0; PieceIdx < mPieces.GetSize(); PieceIdx++)
|
||||
{
|
||||
lcPiece* Piece = mPieces[PieceIdx];
|
||||
float Bounds[6] = { FLT_MAX, FLT_MAX, FLT_MAX, -FLT_MAX, -FLT_MAX, -FLT_MAX };
|
||||
lcPiece* Focus = NULL;
|
||||
lcPiece* Selected = NULL;
|
||||
int NumSelected = 0;
|
||||
|
||||
if (!Piece->IsSelected())
|
||||
continue;
|
||||
for (int PieceIdx = 0; PieceIdx < mPieces.GetSize(); PieceIdx++)
|
||||
{
|
||||
lcPiece* Piece = mPieces[PieceIdx];
|
||||
|
||||
lcVector3 Distance = Piece->mModelWorld.GetTranslation() - Center;
|
||||
lcMatrix33 LocalToWorldMatrix = lcMatrix33(Piece->mModelWorld);
|
||||
if (Piece->IsSelected())
|
||||
{
|
||||
if (Piece->IsFocused())
|
||||
Focus = Piece;
|
||||
|
||||
lcMatrix33 LocalToFocusMatrix = lcMul(LocalToWorldMatrix, WorldToFocusMatrix);
|
||||
lcMatrix33 NewLocalToWorldMatrix = lcMul(LocalToFocusMatrix, RotationMatrix);
|
||||
Piece->CompareBoundingBox(Bounds);
|
||||
|
||||
lcMatrix33 WorldToLocalMatrix = lcMatrix33AffineInverse(LocalToWorldMatrix);
|
||||
Selected = Piece;
|
||||
NumSelected++;
|
||||
}
|
||||
}
|
||||
|
||||
Distance = lcMul(Distance, WorldToLocalMatrix);
|
||||
Distance = lcMul(Distance, NewLocalToWorldMatrix);
|
||||
lcVector3 Center;
|
||||
|
||||
NewLocalToWorldMatrix.Orthonormalize();
|
||||
if (Focus)
|
||||
Center = Focus->GetRotationCenter();
|
||||
else if (NumSelected == 1)
|
||||
Center = Selected->mModelWorld.GetTranslation();
|
||||
else
|
||||
Center = lcVector3((Bounds[0] + Bounds[3]) / 2.0f, (Bounds[1] + Bounds[4]) / 2.0f, (Bounds[2] + Bounds[5]) / 2.0f);
|
||||
|
||||
Piece->SetPosition(Center + Distance, mCurrentStep, gMainWindow->GetAddKeys());
|
||||
Piece->SetRotation(NewLocalToWorldMatrix, mCurrentStep, gMainWindow->GetAddKeys());
|
||||
Piece->UpdatePosition(mCurrentStep);
|
||||
Rotated = true;
|
||||
lcMatrix33 WorldToFocusMatrix;
|
||||
|
||||
if (!gMainWindow->GetRelativeTransform())
|
||||
Focus = NULL;
|
||||
|
||||
if (Focus && Relative)
|
||||
{
|
||||
lcMatrix33 FocusToWorldMatrix = lcMatrix33(Focus->mModelWorld);
|
||||
WorldToFocusMatrix = lcMatrix33AffineInverse(FocusToWorldMatrix);
|
||||
|
||||
RotationMatrix = lcMul(RotationMatrix, FocusToWorldMatrix);
|
||||
}
|
||||
else
|
||||
WorldToFocusMatrix = lcMatrix33Identity();
|
||||
|
||||
for (int PieceIdx = 0; PieceIdx < mPieces.GetSize(); PieceIdx++)
|
||||
{
|
||||
lcPiece* Piece = mPieces[PieceIdx];
|
||||
|
||||
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->UpdatePosition(mCurrentStep);
|
||||
Rotated = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (Rotated && Update)
|
||||
|
|
|
@ -16,7 +16,6 @@
|
|||
#include "lc_context.h"
|
||||
#include "lc_qutils.h"
|
||||
|
||||
#define LC_PIECE_PIVOT_POINT_SIZE 10.0f
|
||||
#define LC_PIECE_CONTROL_POINT_SIZE 10.0f
|
||||
|
||||
lcPiece::lcPiece(PieceInfo* Info)
|
||||
|
@ -497,32 +496,25 @@ void lcPiece::DrawInterface(lcContext* Context) const
|
|||
|
||||
if (IsPivotPointVisible())
|
||||
{
|
||||
float Verts[8 * 3];
|
||||
float* CurVert = Verts;
|
||||
|
||||
lcVector3 Min = lcMul31(lcVector3(-LC_PIECE_PIVOT_POINT_SIZE, -LC_PIECE_PIVOT_POINT_SIZE, -LC_PIECE_PIVOT_POINT_SIZE), mPivotMatrix);
|
||||
lcVector3 Max = lcMul31(lcVector3(LC_PIECE_PIVOT_POINT_SIZE, LC_PIECE_PIVOT_POINT_SIZE, LC_PIECE_PIVOT_POINT_SIZE), mPivotMatrix);
|
||||
|
||||
*CurVert++ = Min[0]; *CurVert++ = Min[1]; *CurVert++ = Min[2];
|
||||
*CurVert++ = Min[0]; *CurVert++ = Max[1]; *CurVert++ = Min[2];
|
||||
*CurVert++ = Max[0]; *CurVert++ = Max[1]; *CurVert++ = Min[2];
|
||||
*CurVert++ = Max[0]; *CurVert++ = Min[1]; *CurVert++ = Min[2];
|
||||
*CurVert++ = Min[0]; *CurVert++ = Min[1]; *CurVert++ = Max[2];
|
||||
*CurVert++ = Min[0]; *CurVert++ = Max[1]; *CurVert++ = Max[2];
|
||||
*CurVert++ = Max[0]; *CurVert++ = Max[1]; *CurVert++ = Max[2];
|
||||
*CurVert++ = Max[0]; *CurVert++ = Min[1]; *CurVert++ = Max[2];
|
||||
|
||||
const GLushort Indices[36] =
|
||||
const float Size = 5.0f;
|
||||
const float Verts[8 * 3] =
|
||||
{
|
||||
0, 1, 2, 0, 2, 3, 7, 6, 5, 7, 5, 4, 0, 1, 5, 0, 5, 4,
|
||||
2, 3, 7, 2, 7, 6, 0, 3, 7, 0, 7, 4, 1, 2, 6, 1, 6, 5
|
||||
-Size, -Size, -Size, -Size, Size, -Size, Size, Size, -Size, Size, -Size, -Size,
|
||||
-Size, -Size, Size, -Size, Size, Size, Size, Size, Size, Size, -Size, Size
|
||||
};
|
||||
|
||||
const GLushort Indices[24] =
|
||||
{
|
||||
0, 1, 1, 2, 2, 3, 3, 0, 4, 5, 5, 6, 6, 7, 7, 4, 0, 4, 1, 5, 2, 6, 3, 7
|
||||
};
|
||||
|
||||
Context->SetWorldMatrix(lcMul(mPivotMatrix, mModelWorld));
|
||||
|
||||
Context->SetVertexBufferPointer(Verts);
|
||||
Context->SetVertexFormat(0, 3, 0, 0);
|
||||
Context->SetIndexBufferPointer(Indices);
|
||||
|
||||
Context->DrawIndexedPrimitives(GL_TRIANGLES, 36, GL_UNSIGNED_SHORT, 0);
|
||||
Context->DrawIndexedPrimitives(GL_LINES, 24, GL_UNSIGNED_SHORT, 0);
|
||||
}
|
||||
|
||||
if (AreControlPointsVisible())
|
||||
|
@ -596,6 +588,15 @@ void lcPiece::Move(lcStep Step, bool AddKey, const lcVector3& Distance, bool Mov
|
|||
}
|
||||
}
|
||||
|
||||
void lcPiece::RotatePivot(const lcMatrix33& RotationMatrix)
|
||||
{
|
||||
lcMatrix33 NewPivotRotationMatrix = lcMul(RotationMatrix, lcMatrix33(mPivotMatrix));
|
||||
NewPivotRotationMatrix.Orthonormalize();
|
||||
|
||||
mPivotMatrix = lcMatrix44(NewPivotRotationMatrix, mPivotMatrix.GetTranslation());
|
||||
mState |= LC_PIECE_PIVOT_POINT_VALID;
|
||||
}
|
||||
|
||||
const char* lcPiece::GetName() const
|
||||
{
|
||||
return mPieceInfo->m_strDescription;
|
||||
|
|
|
@ -270,7 +270,10 @@ public:
|
|||
switch (Section)
|
||||
{
|
||||
case LC_PIECE_SECTION_POSITION:
|
||||
return mModelWorld.GetTranslation();
|
||||
if (mState & LC_PIECE_PIVOT_POINT_VALID)
|
||||
return lcMul(mPivotMatrix, mModelWorld).GetTranslation();
|
||||
else
|
||||
return mModelWorld.GetTranslation();
|
||||
|
||||
case LC_PIECE_SECTION_CONTROL_POINT_1:
|
||||
return lcMul31(mControlPoints[0].Position, mModelWorld);
|
||||
|
@ -342,6 +345,7 @@ public:
|
|||
|
||||
void UpdatePosition(lcStep Step);
|
||||
void Move(lcStep Step, bool AddKey, const lcVector3& Distance, bool MovePivotPoint);
|
||||
void RotatePivot(const lcMatrix33& RotationMatrix);
|
||||
|
||||
lcGroup* GetTopGroup();
|
||||
|
||||
|
@ -401,13 +405,9 @@ public:
|
|||
lcVector3 GetRotationCenter() const
|
||||
{
|
||||
if (mState & LC_PIECE_PIVOT_POINT_VALID)
|
||||
{
|
||||
return lcMul(mModelWorld, mPivotMatrix).GetTranslation();
|
||||
}
|
||||
else
|
||||
{
|
||||
return mModelWorld.GetTranslation();
|
||||
}
|
||||
}
|
||||
|
||||
lcMatrix44 GetRelativeRotation() const
|
||||
|
|
Loading…
Add table
Reference in a new issue