Changed how zoom extents work.

This commit is contained in:
leo 2015-02-14 20:47:50 +00:00
parent ced7e21d38
commit 141696ec8c
5 changed files with 47 additions and 28 deletions

View file

@ -739,7 +739,7 @@ void lcCamera::ZoomExtents(float Aspect, const lcVector3& Center, const lcVector
{
lcVector3 Position(mPosition + Center - mTargetPosition);
lcMatrix44 Projection = lcMatrix44Perspective(m_fovy, Aspect, m_zNear, m_zFar);
lcMatrix44 Projection = lcMatrix44Perspective(m_fovy, Aspect, m_zNear, m_zFar); // todo: doesn't work on ortho cameras, and review all places where lcMatrix44Perspective is called
mPosition = lcZoomExtents(Position, mWorldView, Projection, Points, NumPoints);
mTargetPosition = Center;
@ -754,23 +754,14 @@ void lcCamera::ZoomExtents(float Aspect, const lcVector3& Center, const lcVector
UpdatePosition(Step);
}
void lcCamera::ZoomRegion(const lcVector3* Points, float RatioX, float RatioY, lcStep Step, bool AddKey)
void lcCamera::ZoomRegion(const lcMatrix44& ProjectionMatrix, const lcVector3& Position, const lcVector3& TargetPosition, const lcVector3* Corners, lcStep Step, bool AddKey)
{
// Center camera.
lcVector3 Eye = mPosition;
Eye = Eye + (Points[0] - Points[1]);
lcMatrix44 WorldView = lcMatrix44LookAt(Position, TargetPosition, mUpVector);
lcVector3 Target = mTargetPosition;
Target = Target + (Points[0] - Points[1]);
mPosition = lcZoomExtents(Position, WorldView, ProjectionMatrix, Corners, 2);
mTargetPosition = TargetPosition;
mOrthoTarget = TargetPosition;
// Zoom in/out.
float ZoomFactor = -lcMax(RatioX, RatioY) + 0.75f;
lcVector3 Dir = Points[1] - Points[2];
mPosition = Eye + Dir * ZoomFactor;
mTargetPosition = Target + Dir * ZoomFactor;
// Change the camera and redraw.
if (IsSimple())
AddKey = false;

View file

@ -263,7 +263,7 @@ public:
void CopyPosition(const lcCamera* camera);
void ZoomExtents(float Aspect, const lcVector3& Center, const lcVector3* Points, int NumPoints, lcStep Step, bool AddKey);
void ZoomRegion(const lcVector3* Points, float RatioX, float RatioY, lcStep Step, bool AddKey);
void ZoomRegion(const lcMatrix44& ProjectionMatrix, const lcVector3& Position, const lcVector3& TargetPosition, const lcVector3* Corners, lcStep Step, bool AddKey);
void Zoom(float Distance, lcStep Step, bool AddKey);
void Pan(const lcVector3& Distance, lcStep Step, bool AddKey);
void Orbit(float DistanceX, float DistanceY, const lcVector3& CenterPosition, lcStep Step, bool AddKey);

View file

@ -2473,6 +2473,23 @@ lcVector3 lcModel::GetFocusOrSelectionCenter() const
return Center;
}
lcVector3 lcModel::GetSelectionOrModelCenter() const
{
lcVector3 Center;
if (!GetSelectionCenter(Center))
{
float BoundingBox[6];
if (GetPiecesBoundingBox(BoundingBox))
Center = lcVector3((BoundingBox[0] + BoundingBox[3]) / 2, (BoundingBox[1] + BoundingBox[4]) / 2, (BoundingBox[2] + BoundingBox[5]) / 2);
else
Center = lcVector3(0.0f, 0.0f, 0.0f);
}
return Center;
}
bool lcModel::GetFocusPosition(lcVector3& Position) const
{
lcObject* FocusObject = GetFocusObject();
@ -3250,9 +3267,9 @@ void lcModel::UpdateRollTool(lcCamera* Camera, float Mouse)
gMainWindow->UpdateAllViews();
}
void lcModel::ZoomRegionToolClicked(lcCamera* Camera, const lcVector3* Points, float RatioX, float RatioY)
void lcModel::ZoomRegionToolClicked(lcCamera* Camera, const lcMatrix44& ProjectionMatrix, const lcVector3& Position, const lcVector3& TargetPosition, const lcVector3* Corners)
{
Camera->ZoomRegion(Points, RatioX, RatioY, mCurrentStep, gMainWindow->GetAddKeys());
Camera->ZoomRegion(ProjectionMatrix, Position, TargetPosition, Corners, mCurrentStep, gMainWindow->GetAddKeys());
gMainWindow->UpdateFocusObject(GetFocusObject());
gMainWindow->UpdateAllViews();

View file

@ -232,6 +232,7 @@ public:
bool GetPieceFocusOrSelectionCenter(lcVector3& Center) const;
bool GetFocusOrSelectionCenter(lcVector3& Center) const;
lcVector3 GetFocusOrSelectionCenter() const;
lcVector3 GetSelectionOrModelCenter() const;
bool GetFocusPosition(lcVector3& Position) const;
lcObject* GetFocusObject() const;
bool GetSelectionCenter(lcVector3& Center) const;
@ -284,7 +285,7 @@ public:
void UpdatePanTool(lcCamera* Camera, const lcVector3& Distance);
void UpdateOrbitTool(lcCamera* Camera, float MouseX, float MouseY);
void UpdateRollTool(lcCamera* Camera, float Mouse);
void ZoomRegionToolClicked(lcCamera* Camera, const lcVector3* Points, float RatioX, float RatioY);
void ZoomRegionToolClicked(lcCamera* Camera, const lcMatrix44& ProjectionMatrix, const lcVector3& Position, const lcVector3& TargetPosition, const lcVector3* Corners);
void LookAt(lcCamera* Camera);
void ZoomExtents(lcCamera* Camera, float Aspect);
void Zoom(lcCamera* Camera, float Amount);

View file

@ -1922,19 +1922,29 @@ void View::StopTracking(bool Accept)
case LC_TOOL_ZOOM_REGION:
{
lcVector3 Points[3] =
if (mInputState.x == mMouseDownX || mInputState.y == mMouseDownY)
break;
lcVector3 Points[6] =
{
lcVector3((mMouseDownX + lcMin(mInputState.x, mWidth - 1)) / 2, (mMouseDownY + lcMin(mInputState.y, mHeight - 1)) / 2, 0.9f),
lcVector3((float)mWidth / 2.0f, (float)mHeight / 2.0f, 0.9f),
lcVector3((float)mWidth / 2.0f, (float)mHeight / 2.0f, 0.1f),
lcVector3((mMouseDownX + lcMin(mInputState.x, mWidth - 1)) / 2, (mMouseDownY + lcMin(mInputState.y, mHeight - 1)) / 2, 0.0f),
lcVector3((mMouseDownX + lcMin(mInputState.x, mWidth - 1)) / 2, (mMouseDownY + lcMin(mInputState.y, mHeight - 1)) / 2, 1.0f),
lcVector3((float)mInputState.x, (float)mInputState.y, 0.0f),
lcVector3((float)mInputState.x, (float)mInputState.y, 1.0f),
lcVector3(mMouseDownX, mMouseDownY, 0.0f),
lcVector3(mMouseDownX, mMouseDownY, 1.0f)
};
UnprojectPoints(Points, 3);
UnprojectPoints(Points, 5);
float RatioX = (mMouseDownX - mInputState.x) / mWidth;
float RatioY = (mMouseDownY - mInputState.y) / mHeight;
lcVector3 Center = mModel->GetSelectionOrModelCenter();
mModel->ZoomRegionToolClicked(mCamera, Points, fabsf(RatioX), fabsf(RatioY));
lcVector3 PlaneNormal(mCamera->mPosition - mCamera->mTargetPosition);
lcVector4 Plane(PlaneNormal, -lcDot(PlaneNormal, Center));
lcVector3 Target, Corners[2];
if (lcLinePlaneIntersection(&Target, Points[0], Points[1], Plane) && lcLinePlaneIntersection(&Corners[0], Points[2], Points[3], Plane) && lcLinePlaneIntersection(&Corners[1], Points[3], Points[4], Plane))
mModel->ZoomRegionToolClicked(mCamera, GetProjectionMatrix(), Points[0], Target, Corners);
}
break;
}
@ -2405,7 +2415,7 @@ void View::OnMouseMove()
const lcVector3& CurrentEnd = Points[1];
const lcVector3& MouseDownStart = Points[2];
const lcVector3& MouseDownEnd = Points[3];
lcVector3 Center = mModel->GetFocusOrSelectionCenter();
lcVector3 Center = mModel->GetSelectionOrModelCenter();
lcVector3 PlaneNormal(mCamera->mPosition - mCamera->mTargetPosition);
lcVector4 Plane(PlaneNormal, -lcDot(PlaneNormal, Center));