Rotate pivot points.

This commit is contained in:
leo 2015-12-15 01:57:22 +00:00
parent a035bf7ed1
commit dfc94a42e5
3 changed files with 97 additions and 83 deletions

View file

@ -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)

View file

@ -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;

View file

@ -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