Use the centroid of the selected pieces when rotating pieces.

This commit is contained in:
leo 2016-03-13 20:07:28 +00:00
parent 1902dff957
commit 2842cccf53
4 changed files with 107 additions and 99 deletions

View file

@ -2351,44 +2351,17 @@ void lcModel::RotateSelectedPieces(const lcVector3& Angles, bool Relative, bool
}
else
{
lcVector3 Min(FLT_MAX, FLT_MAX, FLT_MAX), 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())
continue;
if (Piece->IsFocused() && gMainWindow->GetRelativeTransform())
Focus = Piece;
Piece->CompareBoundingBox(Min, Max);
Selected = Piece;
NumSelected++;
}
lcVector3 Center;
lcMatrix33 RelativeRotation;
if (Focus)
Center = Focus->GetRotationCenter();
else if (NumSelected == 1)
Center = Selected->mModelWorld.GetTranslation();
else
Center = (Min + Max) / 2.0f;
GetMoveRotateTransform(Center, RelativeRotation);
lcMatrix33 WorldToFocusMatrix;
if (Focus && Relative)
if (Relative)
{
lcMatrix33 FocusToWorldMatrix = lcMatrix33(Focus->GetRelativeRotation());
WorldToFocusMatrix = lcMatrix33AffineInverse(FocusToWorldMatrix);
RotationMatrix = lcMul(RotationMatrix, FocusToWorldMatrix);
WorldToFocusMatrix = lcMatrix33AffineInverse(RelativeRotation);
RotationMatrix = lcMul(RotationMatrix, RelativeRotation);
}
else
WorldToFocusMatrix = lcMatrix33Identity();
@ -2708,6 +2681,84 @@ lcModel* lcModel::GetFirstSelectedSubmodel() const
return NULL;
}
bool lcModel::GetMoveRotateTransform(lcVector3& Center, lcMatrix33& RelativeRotation) const
{
bool Relative = gMainWindow->GetRelativeTransform();
int NumSelected = 0;
Center = lcVector3(0.0f, 0.0f, 0.0f);
RelativeRotation = lcMatrix33Identity();
for (int PieceIdx = 0; PieceIdx < mPieces.GetSize(); PieceIdx++)
{
lcPiece* Piece = mPieces[PieceIdx];
if (!Piece->IsSelected())
continue;
if (Piece->IsFocused() && Relative)
{
Center = Piece->GetRotationCenter();
RelativeRotation = Piece->GetRelativeRotation();
return true;
}
Center += Piece->mModelWorld.GetTranslation();
NumSelected++;
}
for (int CameraIdx = 0; CameraIdx < mCameras.GetSize(); CameraIdx++)
{
lcCamera* Camera = mCameras[CameraIdx];
if (!Camera->IsSelected())
continue;
if (Camera->IsFocused() && Relative)
{
Center = Camera->GetSectionPosition(Camera->GetFocusSection());
// RelativeRotation = Piece->GetRelativeRotation();
return true;
}
Center += Camera->GetSectionPosition(LC_CAMERA_SECTION_POSITION);
Center += Camera->GetSectionPosition(LC_CAMERA_SECTION_TARGET);
Center += Camera->GetSectionPosition(LC_CAMERA_SECTION_UPVECTOR);
NumSelected += 3;
}
for (int LightIdx = 0; LightIdx < mLights.GetSize(); LightIdx++)
{
lcLight* Light = mLights[LightIdx];
if (!Light->IsSelected())
continue;
if (Light->IsFocused() && Relative)
{
Center = Light->GetSectionPosition(Light->GetFocusSection());
// RelativeRotation = Piece->GetRelativeRotation();
return true;
}
Center += Light->GetSectionPosition(LC_LIGHT_SECTION_POSITION);
NumSelected++;
if (Light->IsSpotLight() || Light->IsDirectionalLight())
{
Center += Light->GetSectionPosition(LC_LIGHT_SECTION_TARGET);
NumSelected++;
}
}
if (NumSelected)
{
Center /= NumSelected;
return true;
}
return false;
}
bool lcModel::GetPieceFocusOrSelectionCenter(lcVector3& Center) const
{
lcVector3 Min(FLT_MAX, FLT_MAX, FLT_MAX), Max(-FLT_MAX, -FLT_MAX, -FLT_MAX);
@ -2742,28 +2793,6 @@ bool lcModel::GetPieceFocusOrSelectionCenter(lcVector3& Center) const
return NumSelected != 0;
}
bool lcModel::GetFocusOrSelectionCenter(lcVector3& Center) const
{
if (GetFocusPosition(Center))
return true;
if (GetSelectionCenter(Center))
return true;
Center = lcVector3(0.0f, 0.0f, 0.0f);
return false;
}
lcVector3 lcModel::GetFocusOrSelectionCenter() const
{
lcVector3 Center;
GetFocusOrSelectionCenter(Center);
return Center;
}
lcVector3 lcModel::GetSelectionOrModelCenter() const
{
lcVector3 Center;

View file

@ -247,9 +247,8 @@ public:
bool AnyPiecesSelected() const;
bool AnyObjectsSelected() const;
lcModel* GetFirstSelectedSubmodel() const;
bool GetMoveRotateTransform(lcVector3& Center, lcMatrix33& RelativeRotation) const;
bool GetPieceFocusOrSelectionCenter(lcVector3& Center) const;
bool GetFocusOrSelectionCenter(lcVector3& Center) const;
lcVector3 GetFocusOrSelectionCenter() const;
lcVector3 GetSelectionOrModelCenter() const;
bool GetFocusPosition(lcVector3& Position) const;
lcObject* GetFocusObject() const;

View file

@ -664,8 +664,9 @@ void View::DrawSelectMoveOverlay()
glDisable(GL_DEPTH_TEST);
lcMatrix33 RelativeRotation = mModel->GetRelativeRotation();
lcVector3 OverlayCenter = mModel->GetFocusOrSelectionCenter();
lcVector3 OverlayCenter;
lcMatrix33 RelativeRotation;
mModel->GetMoveRotateTransform(OverlayCenter, RelativeRotation);
bool AnyPiecesSelected = mModel->AnyPiecesSelected();
lcMatrix44 WorldMatrix = lcMatrix44(RelativeRotation, OverlayCenter);
@ -836,8 +837,9 @@ void View::DrawRotateOverlay()
int j;
lcMatrix33 RelativeRotation = mModel->GetRelativeRotation();
lcVector3 OverlayCenter = mModel->GetFocusOrSelectionCenter();
lcVector3 OverlayCenter;
lcMatrix33 RelativeRotation;
mModel->GetMoveRotateTransform(OverlayCenter, RelativeRotation);
lcVector3 MouseToolDistance = mModel->SnapRotation(mModel->GetMouseToolDistance());
bool HasAngle = false;
@ -1625,7 +1627,9 @@ lcTool View::GetCurrentTool() const
float View::GetOverlayScale() const
{
lcVector3 OverlayCenter = mModel->GetFocusOrSelectionCenter();
lcVector3 OverlayCenter;
lcMatrix33 RelativeRotation;
mModel->GetMoveRotateTransform(OverlayCenter, RelativeRotation);
lcVector3 ScreenPos = ProjectPoint(OverlayCenter);
ScreenPos[0] += 10.0f;
@ -1713,7 +1717,8 @@ void View::UpdateTrackTool()
NewTrackTool = (CurrentTool == LC_TOOL_MOVE) ? LC_TRACKTOOL_MOVE_XYZ : LC_TRACKTOOL_SELECT;
lcVector3 OverlayCenter;
if (!mModel->GetFocusOrSelectionCenter(OverlayCenter))
lcMatrix33 RelativeRotation;
if (!mModel->GetMoveRotateTransform(OverlayCenter, RelativeRotation))
break;
// Intersect the mouse with the 3 planes.
@ -1724,8 +1729,6 @@ void View::UpdateTrackTool()
lcVector3(0.0f, 0.0f, 1.0f),
};
lcMatrix33 RelativeRotation = mModel->GetRelativeRotation();
for (int i = 0; i < 3; i++)
PlaneNormals[i] = lcMul(PlaneNormals[i], RelativeRotation);
@ -1855,7 +1858,8 @@ void View::UpdateTrackTool()
NewTrackTool = LC_TRACKTOOL_ROTATE_XYZ;
lcVector3 OverlayCenter;
if (!mModel->GetFocusOrSelectionCenter(OverlayCenter))
lcMatrix33 RelativeRotation;
if (!mModel->GetMoveRotateTransform(OverlayCenter, RelativeRotation))
break;
// Calculate the distance from the mouse pointer to the center of the sphere.
@ -1920,8 +1924,6 @@ void View::UpdateTrackTool()
lcVector3(x1 + u2*(x2-x1), y1 + u2*(y2-y1), z1 + u2*(z2-z1))
};
lcMatrix33 RelativeRotation = mModel->GetRelativeRotation();
for (int i = 0; i < 2; i++)
{
lcVector3 Dist = Intersections[i] - OverlayCenter;
@ -2072,32 +2074,6 @@ void View::UpdateTrackTool()
if (Redraw)
gMainWindow->UpdateAllViews();
}
/*
if (CurrentTool != LC_TOOL_SELECT && CurrentTool != LC_TOOL_MOVE && CurrentTool != LC_TOOL_ROTATE)
return LC_TRACKTOOL_NONE;
int Viewport[4] = { 0, 0, mWidth, mHeight };
float Aspect = (float)Viewport[2]/(float)Viewport[3];
const lcMatrix44& ModelView = mCamera->mWorldView;
lcMatrix44 Projection = lcMatrix44Perspective(mCamera->mFOV, Aspect, mCamera->mNear, mCamera->mFar);
lcVector3 OverlayCenter = mModel->mActiveModel->GetFocusOrSelectionCenter();
lcVector3 ScreenPos = lcProjectPoint(OverlayCenter, ModelView, Projection, Viewport);
ScreenPos[0] += 10.0f;
lcVector3 Point = lcUnprojectPoint(ScreenPos, ModelView, Projection, Viewport);
lcVector3 Dist(Point - OverlayCenter);
float OverlayScale = Dist.Length() * 5.0f;
if (InterfaceScale)
*InterfaceScale = OverlayScale;
if (InterfaceCenter)
*InterfaceCenter = OverlayCenter;
*/
}
void View::StartTracking(lcTrackButton TrackButton)
@ -2557,7 +2533,10 @@ void View::OnMouseMove()
const lcVector3& CurrentEnd = Points[1];
const lcVector3& MouseDownStart = Points[2];
const lcVector3& MouseDownEnd = Points[3];
lcVector3 Center = mModel->GetFocusOrSelectionCenter();
lcVector3 Center;
lcMatrix33 RelativeRotation;
mModel->GetMoveRotateTransform(Center, RelativeRotation);
if (mTrackTool == LC_TRACKTOOL_MOVE_X || mTrackTool == LC_TRACKTOOL_MOVE_Y || mTrackTool == LC_TRACKTOOL_MOVE_Z)
{
@ -2569,7 +2548,6 @@ void View::OnMouseMove()
else
Direction = lcVector3(0.0f, 0.0f, 1.0f);
lcMatrix33 RelativeRotation = mModel->GetRelativeRotation();
Direction = lcMul(Direction, RelativeRotation);
lcVector3 Intersection;
@ -2593,7 +2571,6 @@ void View::OnMouseMove()
else
PlaneNormal = lcVector3(1.0f, 0.0f, 0.0f);
lcMatrix33 RelativeRotation = mModel->GetRelativeRotation();
PlaneNormal = lcMul(PlaneNormal, RelativeRotation);
lcVector4 Plane(PlaneNormal, -lcDot(PlaneNormal, Center));
lcVector3 Intersection;
@ -2618,7 +2595,6 @@ void View::OnMouseMove()
else
Direction = lcVector3(0.0f, 0.0f, -1.0f);
lcMatrix33 RelativeRotation = mModel->GetRelativeRotation();
Direction = lcMul(Direction, RelativeRotation);
lcVector3 Intersection;

View file

@ -591,7 +591,9 @@ void lcQPropertiesTree::slotReturnPressed()
if (Item == partPositionX || Item == partPositionY || Item == partPositionZ)
{
lcVector3 Center = Model->GetFocusOrSelectionCenter();
lcVector3 Center;
lcMatrix33 RelativeRotation;
Model->GetMoveRotateTransform(Center, RelativeRotation);
lcVector3 Position = Center;
float Value = Editor->text().toFloat();
@ -872,7 +874,9 @@ void lcQPropertiesTree::SetPiece(const lcArray<lcObject*>& Selection, lcObject*
lcPiece* Piece = (Focus && Focus->IsPiece()) ? (lcPiece*)Focus : NULL;
mFocus = Piece;
lcVector3 Position = Model->GetFocusOrSelectionCenter();
lcVector3 Position;
lcMatrix33 RelativeRotation;
Model->GetMoveRotateTransform(Position, RelativeRotation);
partPositionX->setText(1, lcFormatValue(Position[0]));
partPositionX->setData(0, PropertyValueRole, Position[0]);
partPositionY->setText(1, lcFormatValue(Position[1]));