From 418481f8c80595677cb78abaeb3382921d4a6fbc Mon Sep 17 00:00:00 2001 From: leo Date: Tue, 17 Dec 2013 02:43:16 +0000 Subject: [PATCH] Orthographic projection option. --- common/camera.cpp | 102 ++++++++--- common/camera.h | 6 +- common/lc_array.h | 390 ++++++++++++++++++++--------------------- common/lc_commands.cpp | 28 +++ common/lc_commands.h | 6 + common/lc_mainwindow.h | 1 + common/lc_math.h | 8 + common/project.cpp | 257 ++++++++++++--------------- common/view.cpp | 19 ++ common/view.h | 7 + leocad.pro | 3 + qt/lc_qmainwindow.cpp | 20 +++ qt/lc_qmainwindow.h | 2 + qt/qtmain.cpp | 8 + 14 files changed, 492 insertions(+), 365 deletions(-) diff --git a/common/camera.cpp b/common/camera.cpp index 1733a69f..131e79ef 100644 --- a/common/camera.cpp +++ b/common/camera.cpp @@ -101,6 +101,7 @@ Camera::Camera(bool Simple) { mPosition = lcVector3(-10.0f, -10.0f, 5.0f); mTargetPosition = lcVector3(0.0f, 0.0f, 0.0f); + mOrthoTarget = mTargetPosition; mUpVector = lcVector3(-0.2357f, -0.2357f, 0.94281f); ChangeKey(1, false, true, mPosition, LC_CK_EYE); @@ -373,6 +374,7 @@ void Camera::Move(unsigned short nTime, bool bAnimation, bool bAddKey, float dx, if (IsEyeSelected()) { mPosition += MoveVec; + lcAlign(mOrthoTarget, mPosition, mTargetPosition); if (!IsSimple()) ChangeKey(nTime, bAnimation, bAddKey, mPosition, LC_CK_EYE); @@ -468,6 +470,7 @@ void Camera::CopyPosition(const Camera* camera) mWorldView = camera->mWorldView; mPosition = camera->mPosition; mTargetPosition = camera->mTargetPosition; + mOrthoTarget = camera->mOrthoTarget; mUpVector = camera->mUpVector; } @@ -521,9 +524,38 @@ void Camera::Render(float fLineWidth) glPopMatrix(); + lcMatrix44 TargetMat = ViewWorld; + float box[24][3] = + { + { 0.2f, 0.2f, 0.2f }, { -0.2f, 0.2f, 0.2f }, + { -0.2f, 0.2f, 0.2f }, { -0.2f, -0.2f, 0.2f }, + { -0.2f, -0.2f, 0.2f }, { 0.2f, -0.2f, 0.2f }, + { 0.2f, -0.2f, 0.2f }, { 0.2f, 0.2f, 0.2f }, + { 0.2f, 0.2f, -0.2f }, { -0.2f, 0.2f, -0.2f }, + { -0.2f, 0.2f, -0.2f }, { -0.2f, -0.2f, -0.2f }, + { -0.2f, -0.2f, -0.2f }, { 0.2f, -0.2f, -0.2f }, + { 0.2f, -0.2f, -0.2f }, { 0.2f, 0.2f, -0.2f }, + { 0.2f, 0.2f, 0.2f }, { 0.2f, 0.2f, -0.2f }, + { -0.2f, 0.2f, 0.2f }, { -0.2f, 0.2f, -0.2f }, + { -0.2f, -0.2f, 0.2f }, { -0.2f, -0.2f, -0.2f }, + { 0.2f, -0.2f, 0.2f }, { 0.2f, -0.2f, -0.2f } + }; +/* + // Draw ortho target. + glPushMatrix(); + TargetMat.SetTranslation(mOrthoTarget); + glMultMatrixf(TargetMat); + + glLineWidth(1.0f); + glColor4f(1.0f, 0.0f, 0.0f, 1.0f); + + glEnableClientState(GL_VERTEX_ARRAY); + glVertexPointer(3, GL_FLOAT, 0, box); + glDrawArrays(GL_LINES, 0, 24); + glPopMatrix(); +*/ // Draw target. glPushMatrix(); - lcMatrix44 TargetMat = ViewWorld; TargetMat.SetTranslation(mTargetPosition); glMultMatrixf(TargetMat); @@ -542,21 +574,6 @@ void Camera::Render(float fLineWidth) } glEnableClientState(GL_VERTEX_ARRAY); - float box[24][3] = - { - { 0.2f, 0.2f, 0.2f }, { -0.2f, 0.2f, 0.2f }, - { -0.2f, 0.2f, 0.2f }, { -0.2f, -0.2f, 0.2f }, - { -0.2f, -0.2f, 0.2f }, { 0.2f, -0.2f, 0.2f }, - { 0.2f, -0.2f, 0.2f }, { 0.2f, 0.2f, 0.2f }, - { 0.2f, 0.2f, -0.2f }, { -0.2f, 0.2f, -0.2f }, - { -0.2f, 0.2f, -0.2f }, { -0.2f, -0.2f, -0.2f }, - { -0.2f, -0.2f, -0.2f }, { 0.2f, -0.2f, -0.2f }, - { 0.2f, -0.2f, -0.2f }, { 0.2f, 0.2f, -0.2f }, - { 0.2f, 0.2f, 0.2f }, { 0.2f, 0.2f, -0.2f }, - { -0.2f, 0.2f, 0.2f }, { -0.2f, 0.2f, -0.2f }, - { -0.2f, -0.2f, 0.2f }, { -0.2f, -0.2f, -0.2f }, - { 0.2f, -0.2f, 0.2f }, { 0.2f, -0.2f, -0.2f } - }; glVertexPointer(3, GL_FLOAT, 0, box); glDrawArrays(GL_LINES, 0, 24); glPopMatrix(); @@ -639,23 +656,15 @@ bool Camera::IntersectsVolume(const lcVector4 Planes[6]) const return lcBoundingBoxIntersectsVolume(Min, Max, LocalPlanes); } -void Camera::LoadProjection(float fAspect) +void Camera::LoadProjection(const lcProjection& projection) { if (m_pTR != NULL) m_pTR->BeginTile(); else { glMatrixMode(GL_PROJECTION); - glLoadMatrixf(lcMatrix44Perspective(m_fovy, fAspect, m_zNear, m_zFar)); -/* - ymax = 10;//(m_zFar-m_zNear)*tan(DTOR*m_fovy)/3; - ymin = -ymax; - xmin = ymin * fAspect; - xmax = ymax * fAspect; - znear = -60; - zfar = 60; - glOrtho(xmin, xmax, ymin, ymax, znear, zfar); -*/ + mProjection = projection; + glLoadMatrixf((lcMatrix44&)mProjection); } glMatrixMode(GL_MODELVIEW); @@ -674,6 +683,7 @@ void Camera::ZoomExtents(View* view, const lcVector3& Center, const lcVector3* P mPosition = lcZoomExtents(Position, mWorldView, Projection, Points, NumPoints); mTargetPosition = Center; + mOrthoTarget = mTargetPosition; if (!IsSimple()) { @@ -734,7 +744,13 @@ void Camera::DoZoom(int dy, int mouse, unsigned short nTime, bool bAnimation, bo FrontVector.Normalize(); FrontVector *= -2.0f * dy / (21 - mouse); - // TODO: option to move eye, target or both + // Don't zoom ortho in if it would cross the ortho focal plane. + if (mProjection.GetType() == lcProjection::Ortho) + { + if ((dy > 0) && (lcDot(mPosition + FrontVector - mOrthoTarget, mPosition - mOrthoTarget) <= 0)) + return; + } + mPosition += FrontVector; mTargetPosition += FrontVector; @@ -755,6 +771,7 @@ void Camera::DoPan(int dx, int dy, int mouse, unsigned short nTime, bool bAnimat lcVector3 MoveVec = (SideVector * (2.0f * dx / (21 - mouse))) + (mUpVector * (-2.0f * dy / (21 - mouse))); mPosition += MoveVec; mTargetPosition += MoveVec; + mOrthoTarget += MoveVec; if (!IsSimple()) { @@ -786,6 +803,8 @@ void Camera::DoRotate(int dx, int dy, int mouse, unsigned short nTime, bool bAni mPosition = lcMul31(mPosition - CenterPosition, transform) + CenterPosition; mTargetPosition = lcMul31(mTargetPosition - CenterPosition, transform) + CenterPosition; + lcAlign(mOrthoTarget, mPosition, mTargetPosition); + mUpVector = lcMul31(mUpVector, transform); if (!IsSimple()) @@ -836,6 +855,7 @@ void Camera::SetViewpoint(LC_VIEWPOINT Viewpoint, unsigned short nTime, bool bAn mPosition = Positions[Viewpoint]; mTargetPosition = lcVector3(0, 0, 0); + mOrthoTarget = mTargetPosition; mUpVector = Ups[Viewpoint]; if (!IsSimple()) @@ -880,3 +900,29 @@ bool Camera::EndTile() return false; } + +void Camera::SetFocalPoint(const lcVector3& focus, unsigned short nTime, bool bAnimation, bool bAddKey) +{ + if (mProjection.GetType() == lcProjection::Ortho) + { + lcVector3 FocusVector = focus; + lcAlign(FocusVector, mPosition, mTargetPosition); + lcAlign(mOrthoTarget, mPosition, mTargetPosition); + lcVector3 TranslateVector = FocusVector - mOrthoTarget; + mPosition += TranslateVector; + mTargetPosition += TranslateVector; + mOrthoTarget = FocusVector; + } + else + { + mOrthoTarget = focus; + } + + if (!IsSimple()) + { + ChangeKey(nTime, bAnimation, bAddKey, mPosition, LC_CK_EYE); + ChangeKey(nTime, bAnimation, bAddKey, mTargetPosition, LC_CK_TARGET); + } + + UpdatePosition(nTime, bAnimation); +} diff --git a/common/camera.h b/common/camera.h index 473bc1da..432c0bd3 100644 --- a/common/camera.h +++ b/common/camera.h @@ -4,6 +4,7 @@ #include "object.h" #include "lc_math.h" #include "lc_array.h" +#include "lc_projection.h" #define LC_CAMERA_HIDDEN 0x01 #define LC_CAMERA_SELECTED 0x02 @@ -143,7 +144,7 @@ public: void UpdatePosition(unsigned short nTime, bool bAnimation); void CopyPosition(const Camera* camera); void Render(float fLineWidth); - void LoadProjection(float fAspect); + void LoadProjection(const lcProjection& projection); void ZoomExtents(View* view, const lcVector3& Center, const lcVector3* Points, int NumPoints, unsigned short nTime, bool bAnimation, bool bAddKey); void ZoomRegion(View* view, float Left, float Right, float Bottom, float Top, unsigned short nTime, bool bAnimation, bool bAddKey); @@ -153,6 +154,7 @@ public: void DoRoll(int dx, int mouse, unsigned short nTime, bool bAnimation, bool bAddKey); void Move(unsigned short nTime, bool bAnimation, bool bAddKey, float x, float y, float z); void SetViewpoint(LC_VIEWPOINT Viewpoint, unsigned short nTime, bool bAnimation, bool bAddKey); + void SetFocalPoint(const lcVector3& focus, unsigned short nTime, bool bAnimation, bool bAddKey); void StartTiledRendering(int tw, int th, int iw, int ih, float fAspect); void GetTileInfo(int* row, int* col, int* width, int* height); @@ -168,6 +170,8 @@ public: lcVector3 mPosition; lcVector3 mTargetPosition; lcVector3 mUpVector; + lcVector3 mOrthoTarget; + lcProjection mProjection; protected: void Initialize(); diff --git a/common/lc_array.h b/common/lc_array.h index ecf5235f..0f50e64d 100644 --- a/common/lc_array.h +++ b/common/lc_array.h @@ -1,195 +1,195 @@ -#ifndef _LC_ARRAY_H_ -#define _LC_ARRAY_H_ - -template -class lcArray -{ -public: - typedef int (*lcArrayCompareFunc)(const T& a, const T& b); - - lcArray(int Size = 0, int Grow = 16) - { - mData = NULL; - mLength = 0; - mAlloc = 0; - mGrow = Grow; - - if (Size != 0) - AllocGrow(Size); - } - - ~lcArray() - { - delete[] mData; - } - - lcArray& operator=(const lcArray& Array) - { - mLength = Array.mLength; - mAlloc = Array.mAlloc; - mGrow = Array.mGrow; - - delete[] mData; - mData = new T[mAlloc]; - - for (int i = 0; i < mLength; i++) - mData[i] = Array.mData[i]; - - return *this; - } - - lcArray& operator+=(const lcArray& Array) - { - AllocGrow(Array.mLength); - - for (int i = 0; i < Array.mLength; i++) - mData[mLength + i] = Array.mData[i]; - - mLength += Array.mLength; - return *this; - } - - T& operator[](int Index) const - { - return mData[Index]; - } - - int GetSize() const - { - return mLength; - } - - void SetSize(int NewSize) - { - if (NewSize > mAlloc) - AllocGrow(NewSize - mAlloc); - - mLength = NewSize; - } - - void AllocGrow(int Grow) - { - if ((mLength + Grow) > mAlloc) - { - int NewSize = ((mLength + Grow + mGrow - 1) / mGrow) * mGrow; - T* NewData = new T[NewSize]; - - for (int i = 0; i < mLength; i++) - NewData[i] = mData[i]; - - delete[] mData; - mData = NewData; - mAlloc = NewSize; - } - } - - void Add(const T& NewItem) - { - AllocGrow(1); - mData[mLength++] = NewItem; - } - - T& Add() - { - AllocGrow(1); - return mData[mLength++]; - } - - void AddSorted(const T& Obj, lcArrayCompareFunc CompareFunc) - { - for (int i = 0; i < mLength; i++) - { - if (CompareFunc(Obj, mData[i]) < 0) - { - InsertAt(i, Obj); - return; - } - } - - Add(Obj); - } - - void InsertAt(int Index, const T& NewItem) - { - if (Index >= mLength) - AllocGrow(Index - mLength + 1); - else - AllocGrow(1); - - mLength++; - for (int i = mLength - 1; i > Index; i--) - mData[i] = mData[i - 1]; - - mData[Index] = NewItem; - } - - void RemoveIndex(int Index) - { - mLength--; - - for (int i = Index; i < mLength; i++) - mData[i] = mData[i + 1]; - } - - void Remove(const T& Item) - { - for (int i = 0; i < mLength; i++) - { - if (mData[i] == Item) - { - RemoveIndex(i); - return; - } - } - } - - void RemoveAll() - { - mLength = 0; - } - - int FindIndex(const T& Item) const - { - for (int i = 0; i < mLength; i++) - if (mData[i] == Item) - return i; - - return -1; - } - - void Sort(lcArrayCompareFunc CompareFunc) - { - if (mLength <= 1) - return; - - int i = 1; - bool Flipped; - - do - { - Flipped = false; - - for (int j = mLength - 1; j >= i; --j) - { - T& a = mData[j]; - T& b = mData[j - 1]; - - if (CompareFunc(b, a) > 0) - { - T Tmp = b; - mData[j - 1] = a; - mData[j] = Tmp; - Flipped = true; - } - } - } while ((++i < mLength) && Flipped); - } - -protected: - T* mData; - int mLength; - int mAlloc; - int mGrow; -}; - -#endif // _LC_ARRAY_H_ +#ifndef _LC_ARRAY_H_ +#define _LC_ARRAY_H_ + +template +class lcArray +{ +public: + typedef int (*lcArrayCompareFunc)(const T& a, const T& b); + + lcArray(int Size = 0, int Grow = 16) + { + mData = NULL; + mLength = 0; + mAlloc = 0; + mGrow = Grow; + + if (Size != 0) + AllocGrow(Size); + } + + ~lcArray() + { + delete[] mData; + } + + lcArray& operator=(const lcArray& Array) + { + mLength = Array.mLength; + mAlloc = Array.mAlloc; + mGrow = Array.mGrow; + + delete[] mData; + mData = new T[mAlloc]; + + for (int i = 0; i < mLength; i++) + mData[i] = Array.mData[i]; + + return *this; + } + + lcArray& operator+=(const lcArray& Array) + { + AllocGrow(Array.mLength); + + for (int i = 0; i < Array.mLength; i++) + mData[mLength + i] = Array.mData[i]; + + mLength += Array.mLength; + return *this; + } + + T& operator[](int Index) const + { + return mData[Index]; + } + + int GetSize() const + { + return mLength; + } + + void SetSize(int NewSize) + { + if (NewSize > mAlloc) + AllocGrow(NewSize - mAlloc); + + mLength = NewSize; + } + + void AllocGrow(int Grow) + { + if ((mLength + Grow) > mAlloc) + { + int NewSize = ((mLength + Grow + mGrow - 1) / mGrow) * mGrow; + T* NewData = new T[NewSize]; + + for (int i = 0; i < mLength; i++) + NewData[i] = mData[i]; + + delete[] mData; + mData = NewData; + mAlloc = NewSize; + } + } + + void Add(const T& NewItem) + { + AllocGrow(1); + mData[mLength++] = NewItem; + } + + T& Add() + { + AllocGrow(1); + return mData[mLength++]; + } + + void AddSorted(const T& Obj, lcArrayCompareFunc CompareFunc) + { + for (int i = 0; i < mLength; i++) + { + if (CompareFunc(Obj, mData[i]) < 0) + { + InsertAt(i, Obj); + return; + } + } + + Add(Obj); + } + + void InsertAt(int Index, const T& NewItem) + { + if (Index >= mLength) + AllocGrow(Index - mLength + 1); + else + AllocGrow(1); + + mLength++; + for (int i = mLength - 1; i > Index; i--) + mData[i] = mData[i - 1]; + + mData[Index] = NewItem; + } + + void RemoveIndex(int Index) + { + mLength--; + + for (int i = Index; i < mLength; i++) + mData[i] = mData[i + 1]; + } + + void Remove(const T& Item) + { + for (int i = 0; i < mLength; i++) + { + if (mData[i] == Item) + { + RemoveIndex(i); + return; + } + } + } + + void RemoveAll() + { + mLength = 0; + } + + int FindIndex(const T& Item) const + { + for (int i = 0; i < mLength; i++) + if (mData[i] == Item) + return i; + + return -1; + } + + void Sort(lcArrayCompareFunc CompareFunc) + { + if (mLength <= 1) + return; + + int i = 1; + bool Flipped; + + do + { + Flipped = false; + + for (int j = mLength - 1; j >= i; --j) + { + T& a = mData[j]; + T& b = mData[j - 1]; + + if (CompareFunc(b, a) > 0) + { + T Tmp = b; + mData[j - 1] = a; + mData[j] = Tmp; + Flipped = true; + } + } + } while ((++i < mLength) && Flipped); + } + +protected: + T* mData; + int mLength; + int mAlloc; + int mGrow; +}; + +#endif // _LC_ARRAY_H_ diff --git a/common/lc_commands.cpp b/common/lc_commands.cpp index 382184df..ce9256b1 100644 --- a/common/lc_commands.cpp +++ b/common/lc_commands.cpp @@ -984,6 +984,34 @@ lcCommand gCommands[LC_NUM_COMMANDS] = "Toggle fullscreen mode", "" }, + // LC_VIEW_PROJECTION_PERSPECTIVE + { + "View.Perspective.Point", + "&Point", + "Perspective projection", + "" + }, + // LC_VIEW_PROJECTION_ORTHO + { + "View.Perspective.Orthographic", + "&Ortho", + "Orthographic projection", + "" + }, + // LC_VIEW_PERSPECTIVE_CYCLE + { + "View.Perspective.Cycle", + "&Cycle", + "Cycle to next perspective", + "" + }, + // LC_VIEW_PERSPECTIVE_FOCUS + { + "View.Perspective.Focus", + "&Focus", + "Focus perspective on selected piece", + "" + }, // LC_PIECE_INSERT { "Piece.Insert", diff --git a/common/lc_commands.h b/common/lc_commands.h index fdb31d35..169fc7c0 100644 --- a/common/lc_commands.h +++ b/common/lc_commands.h @@ -149,6 +149,12 @@ enum LC_COMMANDS LC_VIEW_REMOVE_VIEW, LC_VIEW_RESET_VIEWS, LC_VIEW_FULLSCREEN, + LC_VIEW_PROJECTION_FIRST, + LC_VIEW_PROJECTION_PERSPECTIVE = LC_VIEW_PROJECTION_FIRST, + LC_VIEW_PROJECTION_ORTHO, + LC_VIEW_PROJECTION_LAST = LC_VIEW_PROJECTION_ORTHO, + LC_VIEW_PROJECTION_CYCLE, + LC_VIEW_PROJECTION_FOCUS, LC_PIECE_INSERT, LC_PIECE_DELETE, LC_PIECE_MOVE_PLUSX, diff --git a/common/lc_mainwindow.h b/common/lc_mainwindow.h index 71dca515..162f4e99 100644 --- a/common/lc_mainwindow.h +++ b/common/lc_mainwindow.h @@ -41,6 +41,7 @@ class lcMainWindow : public lcBaseWindow void UpdateUndoRedo(const char* UndoText, const char* RedoText); void UpdateTransformType(int NewType); void UpdateCurrentCamera(int CameraIndex); + void UpdatePerspective(View* view); void UpdateCameraMenu(const lcArray& Cameras, Camera* CurrentCamera); void UpdateCategories(); void UpdateTitle(const char* Title, bool Modified); diff --git a/common/lc_math.h b/common/lc_math.h index e31dea27..b624a87a 100644 --- a/common/lc_math.h +++ b/common/lc_math.h @@ -347,6 +347,14 @@ inline lcVector3 lcNormalize(const lcVector3& a) return Ret; } +inline void lcAlign(lcVector3& t, const lcVector3& a, const lcVector3& b) +{ + lcVector3 Vector(b - a); + Vector.Normalize(); + Vector *= (t - a).Length(); + t = a + Vector; +} + inline float lcDot(const lcVector3& a, const lcVector3& b) { return a.x * b.x + a.y * b.y + a.z * b.z; diff --git a/common/project.cpp b/common/project.cpp index de4bba6b..42d74faf 100644 --- a/common/project.cpp +++ b/common/project.cpp @@ -93,6 +93,8 @@ void Project::UpdateInterface() gMainWindow->UpdateLockSnap(m_nSnap); gMainWindow->UpdateSnap(); gMainWindow->UpdateCameraMenu(mCameras, m_ActiveView ? m_ActiveView->mCamera : NULL); + gMainWindow->UpdatePerspective(m_ActiveView); + UpdateSelection(); if (m_bAnimation) gMainWindow->UpdateTime(m_bAnimation, m_nCurFrame, m_nTotalFrames); @@ -1476,7 +1478,10 @@ void Project::AddView (View* pView) RenderInitialize (); if (!m_ActiveView) + { m_ActiveView = pView; + gMainWindow->UpdatePerspective(m_ActiveView); + } } void Project::RemoveView (View* pView) @@ -1497,6 +1502,7 @@ void Project::UpdateAllViews() bool Project::SetActiveView(View* view) { m_ActiveView = view; + gMainWindow->UpdatePerspective(m_ActiveView); return false; /* if (view == m_ActiveView) @@ -1533,8 +1539,7 @@ void Project::Render(View* view, bool ToMemory) RenderBackground(view); // Setup the projection and camera matrices. - float ratio = (float)view->mWidth / (float)view->mHeight; - view->mCamera->LoadProjection(ratio); + view->UpdateProjection(); if (ToMemory) RenderScenePieces(view); @@ -1677,8 +1682,9 @@ int lcOpaqueRenderCompare(Piece* const& a, Piece* const& b) void Project::RenderScenePieces(View* view) { + view->UpdateProjection(); + float AspectRatio = (float)view->mWidth / (float)view->mHeight; - view->mCamera->LoadProjection(AspectRatio); if (m_nDetail & LC_DET_LIGHTING) { @@ -3062,7 +3068,9 @@ void Project::RenderViewports(View* view) glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glEnable(GL_BLEND); - m_pScreenFont->PrintText(3.0f, (float)view->mHeight - 1.0f - 6.0f, 0.0f, view->mCamera->GetName()); + String str(view->mCamera->GetName()); + if (str.GetLength() > 0) + m_pScreenFont->PrintText(3.0f, (float)view->mHeight - 1.0f - 6.0f, 0.0f, str); glDisable(GL_BLEND); glDisable(GL_TEXTURE_2D); @@ -5766,6 +5774,33 @@ void Project::HandleCommand(LC_COMMANDS id) gMainWindow->ToggleFullScreen(); break; + case LC_VIEW_PROJECTION_PERSPECTIVE: + m_ActiveView->SetProjectionType(lcProjection::Projection); + m_ActiveView->Redraw(); + gMainWindow->UpdatePerspective(m_ActiveView); + break; + + case LC_VIEW_PROJECTION_ORTHO: + m_ActiveView->SetProjectionType(lcProjection::Ortho); + m_ActiveView->Redraw(); + gMainWindow->UpdatePerspective(m_ActiveView); + break; + + case LC_VIEW_PROJECTION_CYCLE: + m_ActiveView->SetProjectionType(lcProjection::Cycle); + m_ActiveView->Redraw(); + gMainWindow->UpdatePerspective(m_ActiveView); + break; + + case LC_VIEW_PROJECTION_FOCUS: + { + lcVector3 FocusVector; + GetSelectionCenter(FocusVector); + m_ActiveView->mCamera->SetFocalPoint(FocusVector, m_bAnimation ? m_nCurFrame : m_nCurStep, m_bAnimation, m_bAddKeys); + UpdateAllViews(); + break; + } + case LC_PIECE_INSERT: { if (m_pCurPiece == NULL) @@ -5875,16 +5910,10 @@ void Project::HandleCommand(LC_COMMANDS id) if ((m_nSnap & LC_DRAW_MOVEAXIS) == 0) { // TODO: rewrite this - - int Viewport[4] = { 0, 0, m_ActiveView->mWidth, m_ActiveView->mHeight }; - float Aspect = (float)Viewport[2]/(float)Viewport[3]; - Camera* Cam = m_ActiveView->mCamera; - - const lcMatrix44& ModelView = Cam->mWorldView; - lcMatrix44 Projection = lcMatrix44Perspective(Cam->m_fovy, Aspect, Cam->m_zNear, Cam->m_zFar); - + + const lcProjection& projection = m_ActiveView->UpdateProjection(); lcVector3 Pts[3] = { lcVector3(5.0f, 5.0f, 0.1f), lcVector3(10.0f, 5.0f, 0.1f), lcVector3(5.0f, 10.0f, 0.1f) }; - lcUnprojectPoints(Pts, 3, ModelView, Projection, Viewport); + projection.UnprojectPoints(m_ActiveView->mCamera->mWorldView, Pts, 3); float ax, ay; lcVector3 vx((Pts[1][0] - Pts[0][0]), (Pts[1][1] - Pts[0][1]), 0);//Pts[1][2] - Pts[0][2] }; @@ -6727,42 +6756,49 @@ void Project::HandleCommand(LC_COMMANDS id) { m_ActiveView->mCamera->SetViewpoint(LC_VIEWPOINT_FRONT, m_bAnimation ? m_nCurFrame : m_nCurStep, m_bAnimation, m_bAddKeys); HandleCommand(LC_VIEW_ZOOM_EXTENTS); + m_ActiveView->UpdateProjection(); } break; case LC_VIEW_VIEWPOINT_BACK: { m_ActiveView->mCamera->SetViewpoint(LC_VIEWPOINT_BACK, m_bAnimation ? m_nCurFrame : m_nCurStep, m_bAnimation, m_bAddKeys); HandleCommand(LC_VIEW_ZOOM_EXTENTS); + m_ActiveView->UpdateProjection(); } break; case LC_VIEW_VIEWPOINT_TOP: { m_ActiveView->mCamera->SetViewpoint(LC_VIEWPOINT_TOP, m_bAnimation ? m_nCurFrame : m_nCurStep, m_bAnimation, m_bAddKeys); HandleCommand(LC_VIEW_ZOOM_EXTENTS); + m_ActiveView->UpdateProjection(); } break; case LC_VIEW_VIEWPOINT_BOTTOM: { m_ActiveView->mCamera->SetViewpoint(LC_VIEWPOINT_BOTTOM, m_bAnimation ? m_nCurFrame : m_nCurStep, m_bAnimation, m_bAddKeys); HandleCommand(LC_VIEW_ZOOM_EXTENTS); + m_ActiveView->UpdateProjection(); } break; case LC_VIEW_VIEWPOINT_LEFT: { m_ActiveView->mCamera->SetViewpoint(LC_VIEWPOINT_LEFT, m_bAnimation ? m_nCurFrame : m_nCurStep, m_bAnimation, m_bAddKeys); HandleCommand(LC_VIEW_ZOOM_EXTENTS); + m_ActiveView->UpdateProjection(); } break; case LC_VIEW_VIEWPOINT_RIGHT: { m_ActiveView->mCamera->SetViewpoint(LC_VIEWPOINT_RIGHT, m_bAnimation ? m_nCurFrame : m_nCurStep, m_bAnimation, m_bAddKeys); HandleCommand(LC_VIEW_ZOOM_EXTENTS); + m_ActiveView->UpdateProjection(); } break; case LC_VIEW_VIEWPOINT_HOME: { m_ActiveView->mCamera->SetViewpoint(LC_VIEWPOINT_HOME, m_bAnimation ? m_nCurFrame : m_nCurStep, m_bAnimation, m_bAddKeys); HandleCommand(LC_VIEW_ZOOM_EXTENTS); + m_ActiveView->UpdateProjection(); } break; case LC_VIEW_CAMERA_NONE: @@ -7464,16 +7500,10 @@ void Project::GetPieceInsertPosition(View* view, int MouseX, int MouseY, lcVecto } // Try to hit the base grid. - int Viewport[4] = { 0, 0, view->mWidth, view->mHeight }; - - float Aspect = (float)Viewport[2]/(float)Viewport[3]; - Camera* Cam = view->mCamera; - - const lcMatrix44& ModelView = Cam->mWorldView; - lcMatrix44 Projection = lcMatrix44Perspective(Cam->m_fovy, Aspect, Cam->m_zNear, Cam->m_zFar); + const lcProjection& projection = view->UpdateProjection(); lcVector3 ClickPoints[2] = { lcVector3((float)m_nDownX, (float)m_nDownY, 0.0f), lcVector3((float)m_nDownX, (float)m_nDownY, 1.0f) }; - lcUnprojectPoints(ClickPoints, 2, ModelView, Projection, Viewport); + projection.UnprojectPoints(view->mCamera->mWorldView, ClickPoints, 2); lcVector3 Intersection; if (lcLinePlaneIntersection(&Intersection, ClickPoints[0], ClickPoints[1], lcVector4(0, 0, 1, m_pCurPiece->m_fDimensions[5]))) @@ -7485,21 +7515,16 @@ void Project::GetPieceInsertPosition(View* view, int MouseX, int MouseY, lcVecto } // Couldn't find a good position, so just place the piece somewhere near the camera. - Position = lcUnprojectPoint(lcVector3((float)m_nDownX, (float)m_nDownY, 0.9f), ModelView, Projection, Viewport); + Position = projection.UnprojectPoint(view->mCamera->mWorldView, lcVector3((float)m_nDownX, (float)m_nDownY, 0.9f)); Rotation = lcVector4(0, 0, 1, 0); } Object* Project::FindObjectFromPoint(View* view, int x, int y, bool PiecesOnly) { - int Viewport[4] = { 0, 0, view->mWidth, view->mHeight }; - float Aspect = (float)Viewport[2]/(float)Viewport[3]; - Camera* Cam = view->mCamera; + const lcProjection& projection = view->UpdateProjection(); - const lcMatrix44& ModelView = Cam->mWorldView; - lcMatrix44 Projection = lcMatrix44Perspective(Cam->m_fovy, Aspect, Cam->m_zNear, Cam->m_zFar); - - lcVector3 Start = lcUnprojectPoint(lcVector3((float)x, (float)y, 0.0f), ModelView, Projection, Viewport); - lcVector3 End = lcUnprojectPoint(lcVector3((float)x, (float)y, 1.0f), ModelView, Projection, Viewport); + lcVector3 Start = projection.UnprojectPoint(view->mCamera->mWorldView, lcVector3((float)x, (float)y, 0.0f)); + lcVector3 End = projection.UnprojectPoint(view->mCamera->mWorldView, lcVector3((float)x, (float)y, 1.0f)); lcClickLine ClickLine; @@ -7532,12 +7557,8 @@ Object* Project::FindObjectFromPoint(View* view, int x, int y, bool PiecesOnly) void Project::FindObjectsInBox(float x1, float y1, float x2, float y2, lcArray& Objects) { - int Viewport[4] = { 0, 0, m_ActiveView->mWidth, m_ActiveView->mHeight }; - float Aspect = (float)Viewport[2]/(float)Viewport[3]; Camera* Cam = m_ActiveView->mCamera; - - const lcMatrix44& ModelView = Cam->mWorldView; - lcMatrix44 Projection = lcMatrix44Perspective(Cam->m_fovy, Aspect, Cam->m_zNear, Cam->m_zFar); + const lcProjection& projection = m_ActiveView->UpdateProjection(); // Find out the top-left and bottom-right corners in screen coordinates. float Left, Top, Bottom, Right; @@ -7571,7 +7592,7 @@ void Project::FindObjectsInBox(float x1, float y1, float x2, float y2, lcArraymCamera->mWorldView, Corners, 6); // Build the box planes. lcVector3 PlaneNormals[6]; @@ -8623,7 +8644,7 @@ void Project::ModifyObject(Object* Object, lcObjectProperty Property, void* Valu } if (CheckPointString) - { + { SetModifiedFlag(true); CheckPoint(CheckPointString); gMainWindow->UpdateFocusObject(GetFocusObject()); @@ -8633,28 +8654,28 @@ void Project::ModifyObject(Object* Object, lcObjectProperty Property, void* Valu } void Project::ZoomActiveView(int Amount) - { +{ m_ActiveView->mCamera->DoZoom(Amount, m_nMouse, m_bAnimation ? m_nCurFrame : m_nCurStep, m_bAnimation, m_bAddKeys); gMainWindow->UpdateFocusObject(GetFocusObject()); UpdateOverlayScale(); UpdateAllViews(); - } +} void Project::BeginPieceDrop(PieceInfo* Info) - { +{ StartTracking(LC_TRACK_LEFT); mDropPiece = Info; mDropPiece->AddRef(); - } +} void Project::OnPieceDropMove(int x, int y) - { +{ if (!mDropPiece) return; if (m_nDownX != x || m_nDownY != y) - { + { m_nDownX = x; m_nDownY = y; @@ -8697,14 +8718,9 @@ void Project::OnLeftButtonDown(View* view) m_MouseTotalDelta = lcVector3(0, 0, 0); m_MouseSnapLeftover = lcVector3(0, 0, 0); - int Viewport[4] = { 0, 0, view->mWidth, view->mHeight }; - float Aspect = (float)Viewport[2]/(float)Viewport[3]; - Camera* Cam = view->mCamera; + const lcProjection& projection = view->UpdateProjection(); + lcVector3 point = projection.UnprojectPoint(view->mCamera->mWorldView, lcVector3((float)x, (float)y, 0.9f)); - const lcMatrix44& ModelView = Cam->mWorldView; - lcMatrix44 Projection = lcMatrix44Perspective(Cam->m_fovy, Aspect, Cam->m_zNear, Cam->m_zFar); - - lcVector3 point = lcUnprojectPoint(lcVector3((float)x, (float)y, 0.9f), ModelView, Projection, Viewport); m_fTrack[0] = point[0]; m_fTrack[1] = point[1]; m_fTrack[2] = point[2]; if (Alt) @@ -8892,34 +8908,34 @@ void Project::OnLeftButtonDown(View* view) CheckPoint("Inserting"); } break; - case LC_ACTION_SPOTLIGHT: - { - GLint max; - int count = 0; - Light *pLight; + case LC_ACTION_SPOTLIGHT: + { + GLint max; + int count = 0; + Light *pLight; - glGetIntegerv (GL_MAX_LIGHTS, &max); - for (pLight = m_pLights; pLight; pLight = pLight->m_pNext) - count++; + glGetIntegerv (GL_MAX_LIGHTS, &max); + for (pLight = m_pLights; pLight; pLight = pLight->m_pNext) + count++; - if (count == max) - break; + if (count == max) + break; - lcVector3 tmp = lcUnprojectPoint(lcVector3(x+1.0f, y-1.0f, 0.9f), ModelView, Projection, Viewport); - SelectAndFocusNone(false); - StartTracking(LC_TRACK_START_LEFT); - pLight = new Light (m_fTrack[0], m_fTrack[1], m_fTrack[2], tmp[0], tmp[1], tmp[2]); - pLight->GetTarget ()->Select (true, true, false); - pLight->m_pNext = m_pLights; - m_pLights = pLight; - UpdateSelection(); - UpdateAllViews(); - gMainWindow->UpdateFocusObject(pLight); - } break; + lcVector3 tmp = projection.UnprojectPoint(view->mCamera->mWorldView, lcVector3(x+1.0f, y-1.0f, 0.9f)); + SelectAndFocusNone(false); + StartTracking(LC_TRACK_START_LEFT); + pLight = new Light (m_fTrack[0], m_fTrack[1], m_fTrack[2], tmp[0], tmp[1], tmp[2]); + pLight->GetTarget ()->Select (true, true, false); + pLight->m_pNext = m_pLights; + m_pLights = pLight; + UpdateSelection(); + UpdateAllViews(); + gMainWindow->UpdateFocusObject(pLight); + } break; case LC_ACTION_CAMERA: { - lcVector3 tmp = lcUnprojectPoint(lcVector3(x+1.0f, y-1.0f, 0.9f), ModelView, Projection, Viewport); + lcVector3 tmp = projection.UnprojectPoint(view->mCamera->mWorldView, lcVector3(x+1.0f, y-1.0f, 0.9f)); SelectAndFocusNone(false); StartTracking(LC_TRACK_START_LEFT); @@ -9011,14 +9027,9 @@ void Project::OnLeftButtonDoubleClick(View* view) int y = view->mInputState.y; bool Control = view->mInputState.Control; - int Viewport[4] = { 0, 0, view->mWidth, view->mHeight }; - float Aspect = (float)Viewport[2]/(float)Viewport[3]; - Camera* Cam = view->mCamera; + const lcProjection& projection = view->UpdateProjection(); + lcVector3 point = projection.UnprojectPoint(view->mCamera->mWorldView, lcVector3((float)x, (float)y, 0.9f)); - const lcMatrix44& ModelView = Cam->mWorldView; - lcMatrix44 Projection = lcMatrix44Perspective(Cam->m_fovy, Aspect, Cam->m_zNear, Cam->m_zFar); - - lcVector3 point = lcUnprojectPoint(lcVector3((float)x, (float)y, 0.9f), ModelView, Projection, Viewport); m_fTrack[0] = point[0]; m_fTrack[1] = point[1]; m_fTrack[2] = point[2]; Object* Closest = FindObjectFromPoint(view, x, y); @@ -9078,14 +9089,9 @@ void Project::OnMiddleButtonDown(View* view) m_nDownY = y; m_bTrackCancel = false; - int Viewport[4] = { 0, 0, view->mWidth, view->mHeight }; - float Aspect = (float)Viewport[2]/(float)Viewport[3]; - Camera* Cam = view->mCamera; + const lcProjection& projection = view->UpdateProjection(); + lcVector3 point = projection.UnprojectPoint(view->mCamera->mWorldView, lcVector3((float)x, (float)y, 0.9f)); - const lcMatrix44& ModelView = Cam->mWorldView; - lcMatrix44 Projection = lcMatrix44Perspective(Cam->m_fovy, Aspect, Cam->m_zNear, Cam->m_zFar); - - lcVector3 point = lcUnprojectPoint(lcVector3((float)x, (float)y, 0.9f), ModelView, Projection, Viewport); m_fTrack[0] = point[0]; m_fTrack[1] = point[1]; m_fTrack[2] = point[2]; if (Alt) @@ -9097,6 +9103,13 @@ void Project::OnMiddleButtonDown(View* view) { StartTracking(LC_TRACK_START_RIGHT); } break; + + default: + { + view->SetProjectionType(lcProjection::Cycle); + gMainWindow->UpdatePerspective(view); + UpdateAllViews(); + } } } @@ -9121,14 +9134,9 @@ void Project::OnRightButtonDown(View* view) m_nDownY = y; m_bTrackCancel = false; - int Viewport[4] = { 0, 0, view->mWidth, view->mHeight }; - float Aspect = (float)Viewport[2]/(float)Viewport[3]; - Camera* Cam = view->mCamera; + const lcProjection& projection = view->UpdateProjection(); + lcVector3 point = projection.UnprojectPoint(view->mCamera->mWorldView, lcVector3((float)x, (float)y, 0.9f)); - const lcMatrix44& ModelView = Cam->mWorldView; - lcMatrix44 Projection = lcMatrix44Perspective(Cam->m_fovy, Aspect, Cam->m_zNear, Cam->m_zFar); - - lcVector3 point = lcUnprojectPoint(lcVector3((float)x, (float)y, 0.9f), ModelView, Projection, Viewport); m_fTrack[0] = point[0]; m_fTrack[1] = point[1]; m_fTrack[2] = point[2]; if (Alt) @@ -9215,34 +9223,17 @@ void Project::OnMouseMove(View* view) float ptx, pty, ptz; - int Viewport[4] = { 0, 0, view->mWidth, view->mHeight }; - float Aspect = (float)Viewport[2]/(float)Viewport[3]; - Camera* Cam = view->mCamera; + const lcProjection& projection = view->UpdateProjection(); + lcVector3 tmp = projection.UnprojectPoint(view->mCamera->mWorldView, lcVector3((float)x, (float)y, 0.9f)); - const lcMatrix44& ModelView = Cam->mWorldView; - lcMatrix44 Projection = lcMatrix44Perspective(Cam->m_fovy, Aspect, Cam->m_zNear, Cam->m_zFar); - - lcVector3 tmp = lcUnprojectPoint(lcVector3((float)x, (float)y, 0.9f), ModelView, Projection, Viewport); ptx = tmp[0]; pty = tmp[1]; ptz = tmp[2]; switch (GetAction()) { case LC_ACTION_SELECT: { - int ClampX = x, ClampY = y; - - if (ClampX >= Viewport[0] + Viewport[2]) - ClampX = Viewport[0] + Viewport[2] - 1; - else if (ClampX <= Viewport[0]) - ClampX = Viewport[0] + 1; - - if (ClampY >= Viewport[1] + Viewport[3]) - ClampY = Viewport[1] + Viewport[3] - 1; - else if (ClampY <= Viewport[1]) - ClampY = Viewport[1] + 1; - - m_fTrack[0] = (float)ClampX; - m_fTrack[1] = (float)ClampY; + m_fTrack[0] = (float)projection.ConstrainX(x); + m_fTrack[1] = (float)projection.ConstrainY(y); if (m_nTracking != LC_TRACK_NONE) { @@ -9776,12 +9767,7 @@ void Project::MouseUpdateOverlays(View* view, int x, int y) const float OverlayRotateArrowStart = 1.0f * OverlayScale; const float OverlayRotateArrowEnd = 1.5f * OverlayScale; - int Viewport[4] = { 0, 0, view->mWidth, view->mHeight }; - float Aspect = (float)Viewport[2]/(float)Viewport[3]; - Camera* Cam = view->mCamera; - - const lcMatrix44& ModelView = Cam->mWorldView; - lcMatrix44 Projection = lcMatrix44Perspective(Cam->m_fovy, Aspect, Cam->m_zNear, Cam->m_zFar); + const lcProjection& projection = view->UpdateProjection(); // Intersect the mouse with the 3 planes. lcVector3 PlaneNormals[3] = @@ -9806,8 +9792,8 @@ void Project::MouseUpdateOverlays(View* view, int x, int y) } int Mode = (m_nCurAction == LC_ACTION_MOVE) ? LC_OVERLAY_MOVE_XYZ : LC_OVERLAY_NONE; - lcVector3 Start = lcUnprojectPoint(lcVector3((float)x, (float)y, 0.0f), ModelView, Projection, Viewport); - lcVector3 End = lcUnprojectPoint(lcVector3((float)x, (float)y, 1.0f), ModelView, Projection, Viewport); + lcVector3 Start = projection.UnprojectPoint(view->mCamera->mWorldView, lcVector3((float)x, (float)y, 0.0f)); + lcVector3 End = projection.UnprojectPoint(view->mCamera->mWorldView, lcVector3((float)x, (float)y, 1.0f)); float ClosestIntersectionDistance = FLT_MAX; for (int AxisIndex = 0; AxisIndex < 3; AxisIndex++) @@ -9874,18 +9860,13 @@ void Project::MouseUpdateOverlays(View* view, int x, int y) else if (m_nCurAction == LC_ACTION_ROTATE) { const float OverlayRotateRadius = 2.0f; + Camera* Cam = m_ActiveView->mCamera; - // Calculate the distance from the mouse pointer to the center of the sphere. - int Viewport[4] = { 0, 0, view->mWidth, view->mHeight }; - float Aspect = (float)Viewport[2]/(float)Viewport[3]; - Camera* Cam = view->mCamera; - - const lcMatrix44& ModelView = Cam->mWorldView; - lcMatrix44 Projection = lcMatrix44Perspective(Cam->m_fovy, Aspect, Cam->m_zNear, Cam->m_zFar); + const lcProjection& projection = view->UpdateProjection(); // Unproject the mouse point against both the front and the back clipping planes. - lcVector3 SegStart = lcUnprojectPoint(lcVector3((float)x, (float)y, 0.0f), ModelView, Projection, Viewport); - lcVector3 SegEnd = lcUnprojectPoint(lcVector3((float)x, (float)y, 1.0f), ModelView, Projection, Viewport); + lcVector3 SegStart = projection.UnprojectPoint(view->mCamera->mWorldView, lcVector3((float)x, (float)y, 0.0f)); + lcVector3 SegEnd = projection.UnprojectPoint(view->mCamera->mWorldView, lcVector3((float)x, (float)y, 1.0f)); lcVector3 Center(m_OverlayCenter); @@ -10105,16 +10086,10 @@ void Project::UpdateOverlayScale() { // Calculate the scaling factor by projecting the center to the front plane then // projecting a point close to it back. - int Viewport[4] = { 0, 0, m_ActiveView->mWidth, m_ActiveView->mHeight }; - float Aspect = (float)Viewport[2]/(float)Viewport[3]; - Camera* Cam = m_ActiveView->mCamera; - - const lcMatrix44& ModelView = Cam->mWorldView; - lcMatrix44 Projection = lcMatrix44Perspective(Cam->m_fovy, Aspect, Cam->m_zNear, Cam->m_zFar); - - lcVector3 ScreenPos = lcProjectPoint(m_OverlayCenter, ModelView, Projection, Viewport); - ScreenPos[0] += 10.0f; - lcVector3 Point = lcUnprojectPoint(ScreenPos, ModelView, Projection, Viewport); + const lcProjection& projection = m_ActiveView->UpdateProjection(); + lcVector3 Screen = projection.ProjectPoint(m_ActiveView->mCamera->mWorldView, m_OverlayCenter); + Screen[0] += 10.0f; + lcVector3 Point = projection.UnprojectPoint(m_ActiveView->mCamera->mWorldView, Screen); lcVector3 Dist(Point - m_OverlayCenter); m_ActiveView->m_OverlayScale = Dist.Length() * 5.0f; diff --git a/common/view.cpp b/common/view.cpp index 7a1bf07b..67762deb 100644 --- a/common/view.cpp +++ b/common/view.cpp @@ -120,6 +120,25 @@ LC_CURSOR_TYPE View::GetCursor() const } } +// Call this once before using a view during a callback in order +// to pick up any changes to the view or its camera. +const lcProjection& View::UpdateProjection() +{ + mProjection.SetView(mCamera, mWidth, mHeight); + mCamera->LoadProjection(mProjection); + return mProjection; +} + +void View::SetProjectionType(lcProjection::Type type) +{ + mProjection.SetType(type); +} + +lcProjection::Type View::GetProjectionType() const +{ + return mProjection.GetType(); +} + void View::OnDraw() { m_Project->Render(this, false); diff --git a/common/view.h b/common/view.h index 1984cc7a..403ac944 100644 --- a/common/view.h +++ b/common/view.h @@ -2,6 +2,7 @@ #define _VIEW_H_ #include "lc_glwidget.h" +#include "lc_projection.h" class Camera; class Project; @@ -27,12 +28,18 @@ public: void SetCamera(Camera* camera, bool ForceCopy); void SetDefaultCamera(); + const lcProjection& UpdateProjection(); + void SetProjectionType(lcProjection::Type type); + lcProjection::Type GetProjectionType() const; LC_CURSOR_TYPE GetCursor() const; Project* m_Project; Camera* mCamera; float m_OverlayScale; + +private: + lcProjection mProjection; }; #endif // _VIEW_H_ diff --git a/leocad.pro b/leocad.pro index 9deac6d7..f359b7f4 100644 --- a/leocad.pro +++ b/leocad.pro @@ -16,6 +16,7 @@ win32 { QMAKE_LFLAGS += /INCREMENTAL PRECOMPILED_SOURCE = common/lc_global.cpp RC_FILE = qt/leocad.rc + LIBS += -ladvapi32 -lshell32 } else { LIBS += -lz QMAKE_CXXFLAGS_WARN_ON += -Wno-unused-parameter @@ -106,6 +107,7 @@ SOURCES += common/view.cpp \ common/camera.cpp \ common/lc_profile.cpp \ common/lc_category.cpp \ + common/lc_projection.cpp \ qt/lc_qmainwindow.cpp \ qt/system.cpp \ qt/qtmain.cpp \ @@ -166,6 +168,7 @@ HEADERS += \ common/camera.h \ common/lc_profile.h \ common/lc_category.h \ + common/lc_projection.h \ qt/lc_qmainwindow.h \ qt/lc_config.h \ qt/lc_qpovraydialog.h \ diff --git a/qt/lc_qmainwindow.cpp b/qt/lc_qmainwindow.cpp index 79015087..3f6c8d63 100644 --- a/qt/lc_qmainwindow.cpp +++ b/qt/lc_qmainwindow.cpp @@ -195,6 +195,13 @@ void lcQMainWindow::createActions() actionCameraGroup->addAction(actions[actionIdx]); } + QActionGroup *actionPerspectiveGroup = new QActionGroup(this); + for (int actionIdx = LC_VIEW_PROJECTION_FIRST; actionIdx <= LC_VIEW_PROJECTION_LAST; actionIdx++) + { + actions[actionIdx]->setCheckable(true); + actionPerspectiveGroup->addAction(actions[actionIdx]); + } + updateShortcuts(); } @@ -307,6 +314,9 @@ void lcQMainWindow::createMenus() menuViewpoints->addAction(actions[LC_VIEW_VIEWPOINT_BOTTOM]); menuViewpoints->addAction(actions[LC_VIEW_VIEWPOINT_HOME]); menuView->addMenu(menuCamera); + QMenu* menuPerspective = menuView->addMenu(tr("Projection")); + menuPerspective->addAction(actions[LC_VIEW_PROJECTION_PERSPECTIVE]); + menuPerspective->addAction(actions[LC_VIEW_PROJECTION_ORTHO]); QMenu* menuStep = menuView->addMenu(tr("Ste&p")); menuStep->addAction(actions[LC_VIEW_TIME_FIRST]); menuStep->addAction(actions[LC_VIEW_TIME_PREVIOUS]); @@ -1248,6 +1258,16 @@ void lcQMainWindow::updateCurrentCamera(int cameraIndex) actions[actionIndex]->setChecked(true); } +void lcQMainWindow::updatePerspective(View* view) +{ + lcProjection::Type type = view->GetProjectionType(); + + if (lcProjection::Projection == type) + actions[LC_VIEW_PROJECTION_PERSPECTIVE]->setChecked(true); + else + actions[LC_VIEW_PROJECTION_ORTHO]->setChecked(true); +} + void lcQMainWindow::updateCategories() { partsTree->updateCategories(); diff --git a/qt/lc_qmainwindow.h b/qt/lc_qmainwindow.h index 7521df05..499bb1f0 100644 --- a/qt/lc_qmainwindow.h +++ b/qt/lc_qmainwindow.h @@ -13,6 +13,7 @@ class lcQColorList; class lcQPropertiesTree; class Object; class Camera; +class View; class lcQMainWindow : public QMainWindow { @@ -43,6 +44,7 @@ public: void updateTransformType(int newType); void updateCameraMenu(const lcArray& cameras, Camera* currentCamera); void updateCurrentCamera(int cameraIndex); + void updatePerspective(View* view); void updateCategories(); void updateTitle(const char* title, bool modified); void updateModified(bool modified); diff --git a/qt/qtmain.cpp b/qt/qtmain.cpp index 05cb59a1..3aac7f03 100644 --- a/qt/qtmain.cpp +++ b/qt/qtmain.cpp @@ -559,6 +559,14 @@ void lcMainWindow::UpdateCurrentCamera(int CameraIndex) window->updateCurrentCamera(CameraIndex); } +void lcMainWindow::UpdatePerspective(View* view) +{ + lcQMainWindow* window = (lcQMainWindow*)mHandle; + + if (window) + window->updatePerspective(view); +} + void lcMainWindow::UpdateCategories() { lcQMainWindow* window = (lcQMainWindow*)mHandle;