Orthographic projection option.

This commit is contained in:
leo 2013-12-17 02:43:16 +00:00
parent 4dbc82a8ab
commit 418481f8c8
14 changed files with 492 additions and 365 deletions

View file

@ -101,6 +101,7 @@ Camera::Camera(bool Simple)
{ {
mPosition = lcVector3(-10.0f, -10.0f, 5.0f); mPosition = lcVector3(-10.0f, -10.0f, 5.0f);
mTargetPosition = lcVector3(0.0f, 0.0f, 0.0f); mTargetPosition = lcVector3(0.0f, 0.0f, 0.0f);
mOrthoTarget = mTargetPosition;
mUpVector = lcVector3(-0.2357f, -0.2357f, 0.94281f); mUpVector = lcVector3(-0.2357f, -0.2357f, 0.94281f);
ChangeKey(1, false, true, mPosition, LC_CK_EYE); 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()) if (IsEyeSelected())
{ {
mPosition += MoveVec; mPosition += MoveVec;
lcAlign(mOrthoTarget, mPosition, mTargetPosition);
if (!IsSimple()) if (!IsSimple())
ChangeKey(nTime, bAnimation, bAddKey, mPosition, LC_CK_EYE); ChangeKey(nTime, bAnimation, bAddKey, mPosition, LC_CK_EYE);
@ -468,6 +470,7 @@ void Camera::CopyPosition(const Camera* camera)
mWorldView = camera->mWorldView; mWorldView = camera->mWorldView;
mPosition = camera->mPosition; mPosition = camera->mPosition;
mTargetPosition = camera->mTargetPosition; mTargetPosition = camera->mTargetPosition;
mOrthoTarget = camera->mOrthoTarget;
mUpVector = camera->mUpVector; mUpVector = camera->mUpVector;
} }
@ -521,9 +524,38 @@ void Camera::Render(float fLineWidth)
glPopMatrix(); 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. // Draw target.
glPushMatrix(); glPushMatrix();
lcMatrix44 TargetMat = ViewWorld;
TargetMat.SetTranslation(mTargetPosition); TargetMat.SetTranslation(mTargetPosition);
glMultMatrixf(TargetMat); glMultMatrixf(TargetMat);
@ -542,21 +574,6 @@ void Camera::Render(float fLineWidth)
} }
glEnableClientState(GL_VERTEX_ARRAY); 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); glVertexPointer(3, GL_FLOAT, 0, box);
glDrawArrays(GL_LINES, 0, 24); glDrawArrays(GL_LINES, 0, 24);
glPopMatrix(); glPopMatrix();
@ -639,23 +656,15 @@ bool Camera::IntersectsVolume(const lcVector4 Planes[6]) const
return lcBoundingBoxIntersectsVolume(Min, Max, LocalPlanes); return lcBoundingBoxIntersectsVolume(Min, Max, LocalPlanes);
} }
void Camera::LoadProjection(float fAspect) void Camera::LoadProjection(const lcProjection& projection)
{ {
if (m_pTR != NULL) if (m_pTR != NULL)
m_pTR->BeginTile(); m_pTR->BeginTile();
else else
{ {
glMatrixMode(GL_PROJECTION); glMatrixMode(GL_PROJECTION);
glLoadMatrixf(lcMatrix44Perspective(m_fovy, fAspect, m_zNear, m_zFar)); mProjection = projection;
/* glLoadMatrixf((lcMatrix44&)mProjection);
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);
*/
} }
glMatrixMode(GL_MODELVIEW); 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); mPosition = lcZoomExtents(Position, mWorldView, Projection, Points, NumPoints);
mTargetPosition = Center; mTargetPosition = Center;
mOrthoTarget = mTargetPosition;
if (!IsSimple()) if (!IsSimple())
{ {
@ -734,7 +744,13 @@ void Camera::DoZoom(int dy, int mouse, unsigned short nTime, bool bAnimation, bo
FrontVector.Normalize(); FrontVector.Normalize();
FrontVector *= -2.0f * dy / (21 - mouse); 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; mPosition += FrontVector;
mTargetPosition += 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))); lcVector3 MoveVec = (SideVector * (2.0f * dx / (21 - mouse))) + (mUpVector * (-2.0f * dy / (21 - mouse)));
mPosition += MoveVec; mPosition += MoveVec;
mTargetPosition += MoveVec; mTargetPosition += MoveVec;
mOrthoTarget += MoveVec;
if (!IsSimple()) 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; mPosition = lcMul31(mPosition - CenterPosition, transform) + CenterPosition;
mTargetPosition = lcMul31(mTargetPosition - CenterPosition, transform) + CenterPosition; mTargetPosition = lcMul31(mTargetPosition - CenterPosition, transform) + CenterPosition;
lcAlign(mOrthoTarget, mPosition, mTargetPosition);
mUpVector = lcMul31(mUpVector, transform); mUpVector = lcMul31(mUpVector, transform);
if (!IsSimple()) if (!IsSimple())
@ -836,6 +855,7 @@ void Camera::SetViewpoint(LC_VIEWPOINT Viewpoint, unsigned short nTime, bool bAn
mPosition = Positions[Viewpoint]; mPosition = Positions[Viewpoint];
mTargetPosition = lcVector3(0, 0, 0); mTargetPosition = lcVector3(0, 0, 0);
mOrthoTarget = mTargetPosition;
mUpVector = Ups[Viewpoint]; mUpVector = Ups[Viewpoint];
if (!IsSimple()) if (!IsSimple())
@ -880,3 +900,29 @@ bool Camera::EndTile()
return false; 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);
}

View file

@ -4,6 +4,7 @@
#include "object.h" #include "object.h"
#include "lc_math.h" #include "lc_math.h"
#include "lc_array.h" #include "lc_array.h"
#include "lc_projection.h"
#define LC_CAMERA_HIDDEN 0x01 #define LC_CAMERA_HIDDEN 0x01
#define LC_CAMERA_SELECTED 0x02 #define LC_CAMERA_SELECTED 0x02
@ -143,7 +144,7 @@ public:
void UpdatePosition(unsigned short nTime, bool bAnimation); void UpdatePosition(unsigned short nTime, bool bAnimation);
void CopyPosition(const Camera* camera); void CopyPosition(const Camera* camera);
void Render(float fLineWidth); 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 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); 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 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 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 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 StartTiledRendering(int tw, int th, int iw, int ih, float fAspect);
void GetTileInfo(int* row, int* col, int* width, int* height); void GetTileInfo(int* row, int* col, int* width, int* height);
@ -168,6 +170,8 @@ public:
lcVector3 mPosition; lcVector3 mPosition;
lcVector3 mTargetPosition; lcVector3 mTargetPosition;
lcVector3 mUpVector; lcVector3 mUpVector;
lcVector3 mOrthoTarget;
lcProjection mProjection;
protected: protected:
void Initialize(); void Initialize();

View file

@ -1,195 +1,195 @@
#ifndef _LC_ARRAY_H_ #ifndef _LC_ARRAY_H_
#define _LC_ARRAY_H_ #define _LC_ARRAY_H_
template <class T> template <class T>
class lcArray class lcArray
{ {
public: public:
typedef int (*lcArrayCompareFunc)(const T& a, const T& b); typedef int (*lcArrayCompareFunc)(const T& a, const T& b);
lcArray(int Size = 0, int Grow = 16) lcArray(int Size = 0, int Grow = 16)
{ {
mData = NULL; mData = NULL;
mLength = 0; mLength = 0;
mAlloc = 0; mAlloc = 0;
mGrow = Grow; mGrow = Grow;
if (Size != 0) if (Size != 0)
AllocGrow(Size); AllocGrow(Size);
} }
~lcArray() ~lcArray()
{ {
delete[] mData; delete[] mData;
} }
lcArray<T>& operator=(const lcArray<T>& Array) lcArray<T>& operator=(const lcArray<T>& Array)
{ {
mLength = Array.mLength; mLength = Array.mLength;
mAlloc = Array.mAlloc; mAlloc = Array.mAlloc;
mGrow = Array.mGrow; mGrow = Array.mGrow;
delete[] mData; delete[] mData;
mData = new T[mAlloc]; mData = new T[mAlloc];
for (int i = 0; i < mLength; i++) for (int i = 0; i < mLength; i++)
mData[i] = Array.mData[i]; mData[i] = Array.mData[i];
return *this; return *this;
} }
lcArray<T>& operator+=(const lcArray<T>& Array) lcArray<T>& operator+=(const lcArray<T>& Array)
{ {
AllocGrow(Array.mLength); AllocGrow(Array.mLength);
for (int i = 0; i < Array.mLength; i++) for (int i = 0; i < Array.mLength; i++)
mData[mLength + i] = Array.mData[i]; mData[mLength + i] = Array.mData[i];
mLength += Array.mLength; mLength += Array.mLength;
return *this; return *this;
} }
T& operator[](int Index) const T& operator[](int Index) const
{ {
return mData[Index]; return mData[Index];
} }
int GetSize() const int GetSize() const
{ {
return mLength; return mLength;
} }
void SetSize(int NewSize) void SetSize(int NewSize)
{ {
if (NewSize > mAlloc) if (NewSize > mAlloc)
AllocGrow(NewSize - mAlloc); AllocGrow(NewSize - mAlloc);
mLength = NewSize; mLength = NewSize;
} }
void AllocGrow(int Grow) void AllocGrow(int Grow)
{ {
if ((mLength + Grow) > mAlloc) if ((mLength + Grow) > mAlloc)
{ {
int NewSize = ((mLength + Grow + mGrow - 1) / mGrow) * mGrow; int NewSize = ((mLength + Grow + mGrow - 1) / mGrow) * mGrow;
T* NewData = new T[NewSize]; T* NewData = new T[NewSize];
for (int i = 0; i < mLength; i++) for (int i = 0; i < mLength; i++)
NewData[i] = mData[i]; NewData[i] = mData[i];
delete[] mData; delete[] mData;
mData = NewData; mData = NewData;
mAlloc = NewSize; mAlloc = NewSize;
} }
} }
void Add(const T& NewItem) void Add(const T& NewItem)
{ {
AllocGrow(1); AllocGrow(1);
mData[mLength++] = NewItem; mData[mLength++] = NewItem;
} }
T& Add() T& Add()
{ {
AllocGrow(1); AllocGrow(1);
return mData[mLength++]; return mData[mLength++];
} }
void AddSorted(const T& Obj, lcArrayCompareFunc CompareFunc) void AddSorted(const T& Obj, lcArrayCompareFunc CompareFunc)
{ {
for (int i = 0; i < mLength; i++) for (int i = 0; i < mLength; i++)
{ {
if (CompareFunc(Obj, mData[i]) < 0) if (CompareFunc(Obj, mData[i]) < 0)
{ {
InsertAt(i, Obj); InsertAt(i, Obj);
return; return;
} }
} }
Add(Obj); Add(Obj);
} }
void InsertAt(int Index, const T& NewItem) void InsertAt(int Index, const T& NewItem)
{ {
if (Index >= mLength) if (Index >= mLength)
AllocGrow(Index - mLength + 1); AllocGrow(Index - mLength + 1);
else else
AllocGrow(1); AllocGrow(1);
mLength++; mLength++;
for (int i = mLength - 1; i > Index; i--) for (int i = mLength - 1; i > Index; i--)
mData[i] = mData[i - 1]; mData[i] = mData[i - 1];
mData[Index] = NewItem; mData[Index] = NewItem;
} }
void RemoveIndex(int Index) void RemoveIndex(int Index)
{ {
mLength--; mLength--;
for (int i = Index; i < mLength; i++) for (int i = Index; i < mLength; i++)
mData[i] = mData[i + 1]; mData[i] = mData[i + 1];
} }
void Remove(const T& Item) void Remove(const T& Item)
{ {
for (int i = 0; i < mLength; i++) for (int i = 0; i < mLength; i++)
{ {
if (mData[i] == Item) if (mData[i] == Item)
{ {
RemoveIndex(i); RemoveIndex(i);
return; return;
} }
} }
} }
void RemoveAll() void RemoveAll()
{ {
mLength = 0; mLength = 0;
} }
int FindIndex(const T& Item) const int FindIndex(const T& Item) const
{ {
for (int i = 0; i < mLength; i++) for (int i = 0; i < mLength; i++)
if (mData[i] == Item) if (mData[i] == Item)
return i; return i;
return -1; return -1;
} }
void Sort(lcArrayCompareFunc CompareFunc) void Sort(lcArrayCompareFunc CompareFunc)
{ {
if (mLength <= 1) if (mLength <= 1)
return; return;
int i = 1; int i = 1;
bool Flipped; bool Flipped;
do do
{ {
Flipped = false; Flipped = false;
for (int j = mLength - 1; j >= i; --j) for (int j = mLength - 1; j >= i; --j)
{ {
T& a = mData[j]; T& a = mData[j];
T& b = mData[j - 1]; T& b = mData[j - 1];
if (CompareFunc(b, a) > 0) if (CompareFunc(b, a) > 0)
{ {
T Tmp = b; T Tmp = b;
mData[j - 1] = a; mData[j - 1] = a;
mData[j] = Tmp; mData[j] = Tmp;
Flipped = true; Flipped = true;
} }
} }
} while ((++i < mLength) && Flipped); } while ((++i < mLength) && Flipped);
} }
protected: protected:
T* mData; T* mData;
int mLength; int mLength;
int mAlloc; int mAlloc;
int mGrow; int mGrow;
}; };
#endif // _LC_ARRAY_H_ #endif // _LC_ARRAY_H_

View file

@ -984,6 +984,34 @@ lcCommand gCommands[LC_NUM_COMMANDS] =
"Toggle fullscreen mode", "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 // LC_PIECE_INSERT
{ {
"Piece.Insert", "Piece.Insert",

View file

@ -149,6 +149,12 @@ enum LC_COMMANDS
LC_VIEW_REMOVE_VIEW, LC_VIEW_REMOVE_VIEW,
LC_VIEW_RESET_VIEWS, LC_VIEW_RESET_VIEWS,
LC_VIEW_FULLSCREEN, 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_INSERT,
LC_PIECE_DELETE, LC_PIECE_DELETE,
LC_PIECE_MOVE_PLUSX, LC_PIECE_MOVE_PLUSX,

View file

@ -41,6 +41,7 @@ class lcMainWindow : public lcBaseWindow
void UpdateUndoRedo(const char* UndoText, const char* RedoText); void UpdateUndoRedo(const char* UndoText, const char* RedoText);
void UpdateTransformType(int NewType); void UpdateTransformType(int NewType);
void UpdateCurrentCamera(int CameraIndex); void UpdateCurrentCamera(int CameraIndex);
void UpdatePerspective(View* view);
void UpdateCameraMenu(const lcArray<Camera*>& Cameras, Camera* CurrentCamera); void UpdateCameraMenu(const lcArray<Camera*>& Cameras, Camera* CurrentCamera);
void UpdateCategories(); void UpdateCategories();
void UpdateTitle(const char* Title, bool Modified); void UpdateTitle(const char* Title, bool Modified);

View file

@ -347,6 +347,14 @@ inline lcVector3 lcNormalize(const lcVector3& a)
return Ret; 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) inline float lcDot(const lcVector3& a, const lcVector3& b)
{ {
return a.x * b.x + a.y * b.y + a.z * b.z; return a.x * b.x + a.y * b.y + a.z * b.z;

View file

@ -93,6 +93,8 @@ void Project::UpdateInterface()
gMainWindow->UpdateLockSnap(m_nSnap); gMainWindow->UpdateLockSnap(m_nSnap);
gMainWindow->UpdateSnap(); gMainWindow->UpdateSnap();
gMainWindow->UpdateCameraMenu(mCameras, m_ActiveView ? m_ActiveView->mCamera : NULL); gMainWindow->UpdateCameraMenu(mCameras, m_ActiveView ? m_ActiveView->mCamera : NULL);
gMainWindow->UpdatePerspective(m_ActiveView);
UpdateSelection(); UpdateSelection();
if (m_bAnimation) if (m_bAnimation)
gMainWindow->UpdateTime(m_bAnimation, m_nCurFrame, m_nTotalFrames); gMainWindow->UpdateTime(m_bAnimation, m_nCurFrame, m_nTotalFrames);
@ -1476,7 +1478,10 @@ void Project::AddView (View* pView)
RenderInitialize (); RenderInitialize ();
if (!m_ActiveView) if (!m_ActiveView)
{
m_ActiveView = pView; m_ActiveView = pView;
gMainWindow->UpdatePerspective(m_ActiveView);
}
} }
void Project::RemoveView (View* pView) void Project::RemoveView (View* pView)
@ -1497,6 +1502,7 @@ void Project::UpdateAllViews()
bool Project::SetActiveView(View* view) bool Project::SetActiveView(View* view)
{ {
m_ActiveView = view; m_ActiveView = view;
gMainWindow->UpdatePerspective(m_ActiveView);
return false; return false;
/* /*
if (view == m_ActiveView) if (view == m_ActiveView)
@ -1533,8 +1539,7 @@ void Project::Render(View* view, bool ToMemory)
RenderBackground(view); RenderBackground(view);
// Setup the projection and camera matrices. // Setup the projection and camera matrices.
float ratio = (float)view->mWidth / (float)view->mHeight; view->UpdateProjection();
view->mCamera->LoadProjection(ratio);
if (ToMemory) if (ToMemory)
RenderScenePieces(view); RenderScenePieces(view);
@ -1677,8 +1682,9 @@ int lcOpaqueRenderCompare(Piece* const& a, Piece* const& b)
void Project::RenderScenePieces(View* view) void Project::RenderScenePieces(View* view)
{ {
view->UpdateProjection();
float AspectRatio = (float)view->mWidth / (float)view->mHeight; float AspectRatio = (float)view->mWidth / (float)view->mHeight;
view->mCamera->LoadProjection(AspectRatio);
if (m_nDetail & LC_DET_LIGHTING) if (m_nDetail & LC_DET_LIGHTING)
{ {
@ -3062,7 +3068,9 @@ void Project::RenderViewports(View* view)
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_BLEND); 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_BLEND);
glDisable(GL_TEXTURE_2D); glDisable(GL_TEXTURE_2D);
@ -5766,6 +5774,33 @@ void Project::HandleCommand(LC_COMMANDS id)
gMainWindow->ToggleFullScreen(); gMainWindow->ToggleFullScreen();
break; 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: case LC_PIECE_INSERT:
{ {
if (m_pCurPiece == NULL) if (m_pCurPiece == NULL)
@ -5875,16 +5910,10 @@ void Project::HandleCommand(LC_COMMANDS id)
if ((m_nSnap & LC_DRAW_MOVEAXIS) == 0) if ((m_nSnap & LC_DRAW_MOVEAXIS) == 0)
{ {
// TODO: rewrite this // TODO: rewrite this
int Viewport[4] = { 0, 0, m_ActiveView->mWidth, m_ActiveView->mHeight }; const lcProjection& projection = m_ActiveView->UpdateProjection();
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 Pts[3] = { lcVector3(5.0f, 5.0f, 0.1f), lcVector3(10.0f, 5.0f, 0.1f), lcVector3(5.0f, 10.0f, 0.1f) }; 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; float ax, ay;
lcVector3 vx((Pts[1][0] - Pts[0][0]), (Pts[1][1] - Pts[0][1]), 0);//Pts[1][2] - Pts[0][2] }; 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); m_ActiveView->mCamera->SetViewpoint(LC_VIEWPOINT_FRONT, m_bAnimation ? m_nCurFrame : m_nCurStep, m_bAnimation, m_bAddKeys);
HandleCommand(LC_VIEW_ZOOM_EXTENTS); HandleCommand(LC_VIEW_ZOOM_EXTENTS);
m_ActiveView->UpdateProjection();
} break; } break;
case LC_VIEW_VIEWPOINT_BACK: case LC_VIEW_VIEWPOINT_BACK:
{ {
m_ActiveView->mCamera->SetViewpoint(LC_VIEWPOINT_BACK, m_bAnimation ? m_nCurFrame : m_nCurStep, m_bAnimation, m_bAddKeys); m_ActiveView->mCamera->SetViewpoint(LC_VIEWPOINT_BACK, m_bAnimation ? m_nCurFrame : m_nCurStep, m_bAnimation, m_bAddKeys);
HandleCommand(LC_VIEW_ZOOM_EXTENTS); HandleCommand(LC_VIEW_ZOOM_EXTENTS);
m_ActiveView->UpdateProjection();
} break; } break;
case LC_VIEW_VIEWPOINT_TOP: case LC_VIEW_VIEWPOINT_TOP:
{ {
m_ActiveView->mCamera->SetViewpoint(LC_VIEWPOINT_TOP, m_bAnimation ? m_nCurFrame : m_nCurStep, m_bAnimation, m_bAddKeys); m_ActiveView->mCamera->SetViewpoint(LC_VIEWPOINT_TOP, m_bAnimation ? m_nCurFrame : m_nCurStep, m_bAnimation, m_bAddKeys);
HandleCommand(LC_VIEW_ZOOM_EXTENTS); HandleCommand(LC_VIEW_ZOOM_EXTENTS);
m_ActiveView->UpdateProjection();
} break; } break;
case LC_VIEW_VIEWPOINT_BOTTOM: case LC_VIEW_VIEWPOINT_BOTTOM:
{ {
m_ActiveView->mCamera->SetViewpoint(LC_VIEWPOINT_BOTTOM, m_bAnimation ? m_nCurFrame : m_nCurStep, m_bAnimation, m_bAddKeys); m_ActiveView->mCamera->SetViewpoint(LC_VIEWPOINT_BOTTOM, m_bAnimation ? m_nCurFrame : m_nCurStep, m_bAnimation, m_bAddKeys);
HandleCommand(LC_VIEW_ZOOM_EXTENTS); HandleCommand(LC_VIEW_ZOOM_EXTENTS);
m_ActiveView->UpdateProjection();
} break; } break;
case LC_VIEW_VIEWPOINT_LEFT: case LC_VIEW_VIEWPOINT_LEFT:
{ {
m_ActiveView->mCamera->SetViewpoint(LC_VIEWPOINT_LEFT, m_bAnimation ? m_nCurFrame : m_nCurStep, m_bAnimation, m_bAddKeys); m_ActiveView->mCamera->SetViewpoint(LC_VIEWPOINT_LEFT, m_bAnimation ? m_nCurFrame : m_nCurStep, m_bAnimation, m_bAddKeys);
HandleCommand(LC_VIEW_ZOOM_EXTENTS); HandleCommand(LC_VIEW_ZOOM_EXTENTS);
m_ActiveView->UpdateProjection();
} break; } break;
case LC_VIEW_VIEWPOINT_RIGHT: case LC_VIEW_VIEWPOINT_RIGHT:
{ {
m_ActiveView->mCamera->SetViewpoint(LC_VIEWPOINT_RIGHT, m_bAnimation ? m_nCurFrame : m_nCurStep, m_bAnimation, m_bAddKeys); m_ActiveView->mCamera->SetViewpoint(LC_VIEWPOINT_RIGHT, m_bAnimation ? m_nCurFrame : m_nCurStep, m_bAnimation, m_bAddKeys);
HandleCommand(LC_VIEW_ZOOM_EXTENTS); HandleCommand(LC_VIEW_ZOOM_EXTENTS);
m_ActiveView->UpdateProjection();
} break; } break;
case LC_VIEW_VIEWPOINT_HOME: case LC_VIEW_VIEWPOINT_HOME:
{ {
m_ActiveView->mCamera->SetViewpoint(LC_VIEWPOINT_HOME, m_bAnimation ? m_nCurFrame : m_nCurStep, m_bAnimation, m_bAddKeys); m_ActiveView->mCamera->SetViewpoint(LC_VIEWPOINT_HOME, m_bAnimation ? m_nCurFrame : m_nCurStep, m_bAnimation, m_bAddKeys);
HandleCommand(LC_VIEW_ZOOM_EXTENTS); HandleCommand(LC_VIEW_ZOOM_EXTENTS);
m_ActiveView->UpdateProjection();
} break; } break;
case LC_VIEW_CAMERA_NONE: 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. // Try to hit the base grid.
int Viewport[4] = { 0, 0, view->mWidth, view->mHeight }; const lcProjection& projection = view->UpdateProjection();
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);
lcVector3 ClickPoints[2] = { lcVector3((float)m_nDownX, (float)m_nDownY, 0.0f), lcVector3((float)m_nDownX, (float)m_nDownY, 1.0f) }; 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; lcVector3 Intersection;
if (lcLinePlaneIntersection(&Intersection, ClickPoints[0], ClickPoints[1], lcVector4(0, 0, 1, m_pCurPiece->m_fDimensions[5]))) 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. // 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); Rotation = lcVector4(0, 0, 1, 0);
} }
Object* Project::FindObjectFromPoint(View* view, int x, int y, bool PiecesOnly) Object* Project::FindObjectFromPoint(View* view, int x, int y, bool PiecesOnly)
{ {
int Viewport[4] = { 0, 0, view->mWidth, view->mHeight }; const lcProjection& projection = view->UpdateProjection();
float Aspect = (float)Viewport[2]/(float)Viewport[3];
Camera* Cam = view->mCamera;
const lcMatrix44& ModelView = Cam->mWorldView; lcVector3 Start = projection.UnprojectPoint(view->mCamera->mWorldView, lcVector3((float)x, (float)y, 0.0f));
lcMatrix44 Projection = lcMatrix44Perspective(Cam->m_fovy, Aspect, Cam->m_zNear, Cam->m_zFar); lcVector3 End = projection.UnprojectPoint(view->mCamera->mWorldView, lcVector3((float)x, (float)y, 1.0f));
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);
lcClickLine ClickLine; 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<Object*>& Objects) void Project::FindObjectsInBox(float x1, float y1, float x2, float y2, lcArray<Object*>& 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; Camera* Cam = m_ActiveView->mCamera;
const lcProjection& projection = m_ActiveView->UpdateProjection();
const lcMatrix44& ModelView = Cam->mWorldView;
lcMatrix44 Projection = lcMatrix44Perspective(Cam->m_fovy, Aspect, Cam->m_zNear, Cam->m_zFar);
// Find out the top-left and bottom-right corners in screen coordinates. // Find out the top-left and bottom-right corners in screen coordinates.
float Left, Top, Bottom, Right; float Left, Top, Bottom, Right;
@ -7571,7 +7592,7 @@ void Project::FindObjectsInBox(float x1, float y1, float x2, float y2, lcArray<O
lcVector3(Right, Top, 0), lcVector3(Left, Top, 1), lcVector3(Right, Bottom, 1) lcVector3(Right, Top, 0), lcVector3(Left, Top, 1), lcVector3(Right, Bottom, 1)
}; };
lcUnprojectPoints(Corners, 6, ModelView, Projection, Viewport); projection.UnprojectPoints(m_ActiveView->mCamera->mWorldView, Corners, 6);
// Build the box planes. // Build the box planes.
lcVector3 PlaneNormals[6]; lcVector3 PlaneNormals[6];
@ -8623,7 +8644,7 @@ void Project::ModifyObject(Object* Object, lcObjectProperty Property, void* Valu
} }
if (CheckPointString) if (CheckPointString)
{ {
SetModifiedFlag(true); SetModifiedFlag(true);
CheckPoint(CheckPointString); CheckPoint(CheckPointString);
gMainWindow->UpdateFocusObject(GetFocusObject()); gMainWindow->UpdateFocusObject(GetFocusObject());
@ -8633,28 +8654,28 @@ void Project::ModifyObject(Object* Object, lcObjectProperty Property, void* Valu
} }
void Project::ZoomActiveView(int Amount) void Project::ZoomActiveView(int Amount)
{ {
m_ActiveView->mCamera->DoZoom(Amount, m_nMouse, m_bAnimation ? m_nCurFrame : m_nCurStep, m_bAnimation, m_bAddKeys); m_ActiveView->mCamera->DoZoom(Amount, m_nMouse, m_bAnimation ? m_nCurFrame : m_nCurStep, m_bAnimation, m_bAddKeys);
gMainWindow->UpdateFocusObject(GetFocusObject()); gMainWindow->UpdateFocusObject(GetFocusObject());
UpdateOverlayScale(); UpdateOverlayScale();
UpdateAllViews(); UpdateAllViews();
} }
void Project::BeginPieceDrop(PieceInfo* Info) void Project::BeginPieceDrop(PieceInfo* Info)
{ {
StartTracking(LC_TRACK_LEFT); StartTracking(LC_TRACK_LEFT);
mDropPiece = Info; mDropPiece = Info;
mDropPiece->AddRef(); mDropPiece->AddRef();
} }
void Project::OnPieceDropMove(int x, int y) void Project::OnPieceDropMove(int x, int y)
{ {
if (!mDropPiece) if (!mDropPiece)
return; return;
if (m_nDownX != x || m_nDownY != y) if (m_nDownX != x || m_nDownY != y)
{ {
m_nDownX = x; m_nDownX = x;
m_nDownY = y; m_nDownY = y;
@ -8697,14 +8718,9 @@ void Project::OnLeftButtonDown(View* view)
m_MouseTotalDelta = lcVector3(0, 0, 0); m_MouseTotalDelta = lcVector3(0, 0, 0);
m_MouseSnapLeftover = lcVector3(0, 0, 0); m_MouseSnapLeftover = lcVector3(0, 0, 0);
int Viewport[4] = { 0, 0, view->mWidth, view->mHeight }; const lcProjection& projection = view->UpdateProjection();
float Aspect = (float)Viewport[2]/(float)Viewport[3]; lcVector3 point = projection.UnprojectPoint(view->mCamera->mWorldView, lcVector3((float)x, (float)y, 0.9f));
Camera* Cam = view->mCamera;
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]; m_fTrack[0] = point[0]; m_fTrack[1] = point[1]; m_fTrack[2] = point[2];
if (Alt) if (Alt)
@ -8892,34 +8908,34 @@ void Project::OnLeftButtonDown(View* view)
CheckPoint("Inserting"); CheckPoint("Inserting");
} break; } break;
case LC_ACTION_SPOTLIGHT: case LC_ACTION_SPOTLIGHT:
{ {
GLint max; GLint max;
int count = 0; int count = 0;
Light *pLight; Light *pLight;
glGetIntegerv (GL_MAX_LIGHTS, &max); glGetIntegerv (GL_MAX_LIGHTS, &max);
for (pLight = m_pLights; pLight; pLight = pLight->m_pNext) for (pLight = m_pLights; pLight; pLight = pLight->m_pNext)
count++; count++;
if (count == max) if (count == max)
break; break;
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); SelectAndFocusNone(false);
StartTracking(LC_TRACK_START_LEFT); StartTracking(LC_TRACK_START_LEFT);
pLight = new Light (m_fTrack[0], m_fTrack[1], m_fTrack[2], tmp[0], tmp[1], tmp[2]); 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->GetTarget ()->Select (true, true, false);
pLight->m_pNext = m_pLights; pLight->m_pNext = m_pLights;
m_pLights = pLight; m_pLights = pLight;
UpdateSelection(); UpdateSelection();
UpdateAllViews(); UpdateAllViews();
gMainWindow->UpdateFocusObject(pLight); gMainWindow->UpdateFocusObject(pLight);
} break; } break;
case LC_ACTION_CAMERA: 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); SelectAndFocusNone(false);
StartTracking(LC_TRACK_START_LEFT); StartTracking(LC_TRACK_START_LEFT);
@ -9011,14 +9027,9 @@ void Project::OnLeftButtonDoubleClick(View* view)
int y = view->mInputState.y; int y = view->mInputState.y;
bool Control = view->mInputState.Control; bool Control = view->mInputState.Control;
int Viewport[4] = { 0, 0, view->mWidth, view->mHeight }; const lcProjection& projection = view->UpdateProjection();
float Aspect = (float)Viewport[2]/(float)Viewport[3]; lcVector3 point = projection.UnprojectPoint(view->mCamera->mWorldView, lcVector3((float)x, (float)y, 0.9f));
Camera* Cam = view->mCamera;
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]; m_fTrack[0] = point[0]; m_fTrack[1] = point[1]; m_fTrack[2] = point[2];
Object* Closest = FindObjectFromPoint(view, x, y); Object* Closest = FindObjectFromPoint(view, x, y);
@ -9078,14 +9089,9 @@ void Project::OnMiddleButtonDown(View* view)
m_nDownY = y; m_nDownY = y;
m_bTrackCancel = false; m_bTrackCancel = false;
int Viewport[4] = { 0, 0, view->mWidth, view->mHeight }; const lcProjection& projection = view->UpdateProjection();
float Aspect = (float)Viewport[2]/(float)Viewport[3]; lcVector3 point = projection.UnprojectPoint(view->mCamera->mWorldView, lcVector3((float)x, (float)y, 0.9f));
Camera* Cam = view->mCamera;
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]; m_fTrack[0] = point[0]; m_fTrack[1] = point[1]; m_fTrack[2] = point[2];
if (Alt) if (Alt)
@ -9097,6 +9103,13 @@ void Project::OnMiddleButtonDown(View* view)
{ {
StartTracking(LC_TRACK_START_RIGHT); StartTracking(LC_TRACK_START_RIGHT);
} break; } break;
default:
{
view->SetProjectionType(lcProjection::Cycle);
gMainWindow->UpdatePerspective(view);
UpdateAllViews();
}
} }
} }
@ -9121,14 +9134,9 @@ void Project::OnRightButtonDown(View* view)
m_nDownY = y; m_nDownY = y;
m_bTrackCancel = false; m_bTrackCancel = false;
int Viewport[4] = { 0, 0, view->mWidth, view->mHeight }; const lcProjection& projection = view->UpdateProjection();
float Aspect = (float)Viewport[2]/(float)Viewport[3]; lcVector3 point = projection.UnprojectPoint(view->mCamera->mWorldView, lcVector3((float)x, (float)y, 0.9f));
Camera* Cam = view->mCamera;
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]; m_fTrack[0] = point[0]; m_fTrack[1] = point[1]; m_fTrack[2] = point[2];
if (Alt) if (Alt)
@ -9215,34 +9223,17 @@ void Project::OnMouseMove(View* view)
float ptx, pty, ptz; float ptx, pty, ptz;
int Viewport[4] = { 0, 0, view->mWidth, view->mHeight }; const lcProjection& projection = view->UpdateProjection();
float Aspect = (float)Viewport[2]/(float)Viewport[3]; lcVector3 tmp = projection.UnprojectPoint(view->mCamera->mWorldView, lcVector3((float)x, (float)y, 0.9f));
Camera* Cam = view->mCamera;
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]; ptx = tmp[0]; pty = tmp[1]; ptz = tmp[2];
switch (GetAction()) switch (GetAction())
{ {
case LC_ACTION_SELECT: case LC_ACTION_SELECT:
{ {
int ClampX = x, ClampY = y; m_fTrack[0] = (float)projection.ConstrainX(x);
m_fTrack[1] = (float)projection.ConstrainY(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;
if (m_nTracking != LC_TRACK_NONE) 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 OverlayRotateArrowStart = 1.0f * OverlayScale;
const float OverlayRotateArrowEnd = 1.5f * OverlayScale; const float OverlayRotateArrowEnd = 1.5f * OverlayScale;
int Viewport[4] = { 0, 0, view->mWidth, view->mHeight }; const lcProjection& projection = view->UpdateProjection();
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);
// Intersect the mouse with the 3 planes. // Intersect the mouse with the 3 planes.
lcVector3 PlaneNormals[3] = 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; 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 Start = projection.UnprojectPoint(view->mCamera->mWorldView, lcVector3((float)x, (float)y, 0.0f));
lcVector3 End = lcUnprojectPoint(lcVector3((float)x, (float)y, 1.0f), ModelView, Projection, Viewport); lcVector3 End = projection.UnprojectPoint(view->mCamera->mWorldView, lcVector3((float)x, (float)y, 1.0f));
float ClosestIntersectionDistance = FLT_MAX; float ClosestIntersectionDistance = FLT_MAX;
for (int AxisIndex = 0; AxisIndex < 3; AxisIndex++) 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) else if (m_nCurAction == LC_ACTION_ROTATE)
{ {
const float OverlayRotateRadius = 2.0f; const float OverlayRotateRadius = 2.0f;
Camera* Cam = m_ActiveView->mCamera;
// Calculate the distance from the mouse pointer to the center of the sphere. const lcProjection& projection = view->UpdateProjection();
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);
// Unproject the mouse point against both the front and the back clipping planes. // 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 SegStart = projection.UnprojectPoint(view->mCamera->mWorldView, lcVector3((float)x, (float)y, 0.0f));
lcVector3 SegEnd = lcUnprojectPoint(lcVector3((float)x, (float)y, 1.0f), ModelView, Projection, Viewport); lcVector3 SegEnd = projection.UnprojectPoint(view->mCamera->mWorldView, lcVector3((float)x, (float)y, 1.0f));
lcVector3 Center(m_OverlayCenter); lcVector3 Center(m_OverlayCenter);
@ -10105,16 +10086,10 @@ void Project::UpdateOverlayScale()
{ {
// Calculate the scaling factor by projecting the center to the front plane then // Calculate the scaling factor by projecting the center to the front plane then
// projecting a point close to it back. // projecting a point close to it back.
int Viewport[4] = { 0, 0, m_ActiveView->mWidth, m_ActiveView->mHeight }; const lcProjection& projection = m_ActiveView->UpdateProjection();
float Aspect = (float)Viewport[2]/(float)Viewport[3]; lcVector3 Screen = projection.ProjectPoint(m_ActiveView->mCamera->mWorldView, m_OverlayCenter);
Camera* Cam = m_ActiveView->mCamera; Screen[0] += 10.0f;
lcVector3 Point = projection.UnprojectPoint(m_ActiveView->mCamera->mWorldView, Screen);
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);
lcVector3 Dist(Point - m_OverlayCenter); lcVector3 Dist(Point - m_OverlayCenter);
m_ActiveView->m_OverlayScale = Dist.Length() * 5.0f; m_ActiveView->m_OverlayScale = Dist.Length() * 5.0f;

View file

@ -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() void View::OnDraw()
{ {
m_Project->Render(this, false); m_Project->Render(this, false);

View file

@ -2,6 +2,7 @@
#define _VIEW_H_ #define _VIEW_H_
#include "lc_glwidget.h" #include "lc_glwidget.h"
#include "lc_projection.h"
class Camera; class Camera;
class Project; class Project;
@ -27,12 +28,18 @@ public:
void SetCamera(Camera* camera, bool ForceCopy); void SetCamera(Camera* camera, bool ForceCopy);
void SetDefaultCamera(); void SetDefaultCamera();
const lcProjection& UpdateProjection();
void SetProjectionType(lcProjection::Type type);
lcProjection::Type GetProjectionType() const;
LC_CURSOR_TYPE GetCursor() const; LC_CURSOR_TYPE GetCursor() const;
Project* m_Project; Project* m_Project;
Camera* mCamera; Camera* mCamera;
float m_OverlayScale; float m_OverlayScale;
private:
lcProjection mProjection;
}; };
#endif // _VIEW_H_ #endif // _VIEW_H_

View file

@ -16,6 +16,7 @@ win32 {
QMAKE_LFLAGS += /INCREMENTAL QMAKE_LFLAGS += /INCREMENTAL
PRECOMPILED_SOURCE = common/lc_global.cpp PRECOMPILED_SOURCE = common/lc_global.cpp
RC_FILE = qt/leocad.rc RC_FILE = qt/leocad.rc
LIBS += -ladvapi32 -lshell32
} else { } else {
LIBS += -lz LIBS += -lz
QMAKE_CXXFLAGS_WARN_ON += -Wno-unused-parameter QMAKE_CXXFLAGS_WARN_ON += -Wno-unused-parameter
@ -106,6 +107,7 @@ SOURCES += common/view.cpp \
common/camera.cpp \ common/camera.cpp \
common/lc_profile.cpp \ common/lc_profile.cpp \
common/lc_category.cpp \ common/lc_category.cpp \
common/lc_projection.cpp \
qt/lc_qmainwindow.cpp \ qt/lc_qmainwindow.cpp \
qt/system.cpp \ qt/system.cpp \
qt/qtmain.cpp \ qt/qtmain.cpp \
@ -166,6 +168,7 @@ HEADERS += \
common/camera.h \ common/camera.h \
common/lc_profile.h \ common/lc_profile.h \
common/lc_category.h \ common/lc_category.h \
common/lc_projection.h \
qt/lc_qmainwindow.h \ qt/lc_qmainwindow.h \
qt/lc_config.h \ qt/lc_config.h \
qt/lc_qpovraydialog.h \ qt/lc_qpovraydialog.h \

View file

@ -195,6 +195,13 @@ void lcQMainWindow::createActions()
actionCameraGroup->addAction(actions[actionIdx]); 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(); updateShortcuts();
} }
@ -307,6 +314,9 @@ void lcQMainWindow::createMenus()
menuViewpoints->addAction(actions[LC_VIEW_VIEWPOINT_BOTTOM]); menuViewpoints->addAction(actions[LC_VIEW_VIEWPOINT_BOTTOM]);
menuViewpoints->addAction(actions[LC_VIEW_VIEWPOINT_HOME]); menuViewpoints->addAction(actions[LC_VIEW_VIEWPOINT_HOME]);
menuView->addMenu(menuCamera); 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")); QMenu* menuStep = menuView->addMenu(tr("Ste&p"));
menuStep->addAction(actions[LC_VIEW_TIME_FIRST]); menuStep->addAction(actions[LC_VIEW_TIME_FIRST]);
menuStep->addAction(actions[LC_VIEW_TIME_PREVIOUS]); menuStep->addAction(actions[LC_VIEW_TIME_PREVIOUS]);
@ -1248,6 +1258,16 @@ void lcQMainWindow::updateCurrentCamera(int cameraIndex)
actions[actionIndex]->setChecked(true); 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() void lcQMainWindow::updateCategories()
{ {
partsTree->updateCategories(); partsTree->updateCategories();

View file

@ -13,6 +13,7 @@ class lcQColorList;
class lcQPropertiesTree; class lcQPropertiesTree;
class Object; class Object;
class Camera; class Camera;
class View;
class lcQMainWindow : public QMainWindow class lcQMainWindow : public QMainWindow
{ {
@ -43,6 +44,7 @@ public:
void updateTransformType(int newType); void updateTransformType(int newType);
void updateCameraMenu(const lcArray<Camera*>& cameras, Camera* currentCamera); void updateCameraMenu(const lcArray<Camera*>& cameras, Camera* currentCamera);
void updateCurrentCamera(int cameraIndex); void updateCurrentCamera(int cameraIndex);
void updatePerspective(View* view);
void updateCategories(); void updateCategories();
void updateTitle(const char* title, bool modified); void updateTitle(const char* title, bool modified);
void updateModified(bool modified); void updateModified(bool modified);

View file

@ -559,6 +559,14 @@ void lcMainWindow::UpdateCurrentCamera(int CameraIndex)
window->updateCurrentCamera(CameraIndex); window->updateCurrentCamera(CameraIndex);
} }
void lcMainWindow::UpdatePerspective(View* view)
{
lcQMainWindow* window = (lcQMainWindow*)mHandle;
if (window)
window->updatePerspective(view);
}
void lcMainWindow::UpdateCategories() void lcMainWindow::UpdateCategories()
{ {
lcQMainWindow* window = (lcQMainWindow*)mHandle; lcQMainWindow* window = (lcQMainWindow*)mHandle;