From 3cf202f177cffb3b962420933ab8d9481b0d8f32 Mon Sep 17 00:00:00 2001 From: leo Date: Tue, 24 Jan 2006 04:48:40 +0000 Subject: Added the ability to zoom and rotate the Piece Preview. git-svn-id: http://svn.leocad.org/trunk@460 c7d43263-9d01-0410-8a33-9dba5d9f93d6 --- common/algebra.h | 14 +++++++ common/glwindow.h | 85 ++++++++++++++++++++------------------- common/pieceinf.cpp | 16 +++++++- common/pieceinf.h | 10 ++++- common/preview.cpp | 112 +++++++++++++++++++++++++++++++++++++++++++++++++++- common/preview.h | 17 ++++++++ 6 files changed, 210 insertions(+), 44 deletions(-) (limited to 'common') diff --git a/common/algebra.h b/common/algebra.h index 7f10e27..693b1ae 100644 --- a/common/algebra.h +++ b/common/algebra.h @@ -285,6 +285,7 @@ public: : m_Value(_x, _y, _z) { } inline operator const float*() const { return (const float*)this; } + inline operator float*() { return (float*)this; } inline const Vector4& GetValue() const { return m_Value; } inline operator const Vector4() const { return Vector4(m_Value[0], m_Value[1], m_Value[2], 1.0f); } @@ -313,6 +314,7 @@ public: : m_Value(_x, _y, _z) { } inline operator const float*() const { return (const float*)this; } + inline operator float*() { return (float*)this; } inline const Vector4& GetValue() const { return m_Value; } inline operator const Vector4() const { return Vector4(m_Value[0], m_Value[1], m_Value[2], 0.0f); } @@ -555,6 +557,9 @@ public: friend inline Vector3 operator*(const Vector3& a, const Matrix33& b) { return Vector3(b.m_Rows[0]*a[0] + b.m_Rows[1]*a[1] + b.m_Rows[2]*a[2]); } + friend inline Point3 operator*(const Point3& a, const Matrix33& b) + { return Point3(b.m_Rows[0]*a[0] + b.m_Rows[1]*a[1] + b.m_Rows[2]*a[2]); } + protected: Vector3 m_Rows[3]; @@ -572,8 +577,17 @@ public: inline Matrix44(const Vector4& Row0, const Vector4& Row1, const Vector4& Row2, const Vector4& Row3) { m_Rows[0] = Row0; m_Rows[1] = Row1; m_Rows[2] = Row2; m_Rows[3] = Row3; } + inline operator const float*() const { return (const float*)this; } inline Vector4& operator[](int i) { return m_Rows[i]; } + inline void LoadIdentity() + { + m_Rows[0] = Vector4(1.0f, 0.0f, 0.0f, 0.0f); + m_Rows[1] = Vector4(0.0f, 1.0f, 0.0f, 0.0f); + m_Rows[2] = Vector4(0.0f, 0.0f, 1.0f, 0.0f); + m_Rows[3] = Vector4(0.0f, 0.0f, 0.0f, 1.0f); + } + // Math operations. friend inline Point3 operator*(const Point3& a, const Matrix44& b) { return Point3(b.m_Rows[0]*a[0] + b.m_Rows[1]*a[1] + b.m_Rows[2]*a[2] + b.m_Rows[3]); } diff --git a/common/glwindow.h b/common/glwindow.h index caba367..6fc3432 100644 --- a/common/glwindow.h +++ b/common/glwindow.h @@ -3,47 +3,50 @@ class GLWindow { - public: - GLWindow (GLWindow *share); - virtual ~GLWindow (); - - void IncRef () - { m_nRef++; } - void DecRef () - { m_nRef--; if (m_nRef == 0) delete this; } - - bool Create (void* data); - void DestroyContext (); - - bool MakeCurrent (); - void SwapBuffers (); - void Redraw (); - int GetWidth () const - { return m_nWidth; } - int GetHeight () const - { return m_nHeight; } - void* GetData () const - { return m_pData; } - - virtual void OnDraw () { }; - virtual void OnSize (int cx, int cy) - { m_nWidth = cx; m_nHeight = cy; }; - virtual void OnInitialUpdate (); - virtual void OnLeftButtonDown (int x, int y, bool bControl, bool bShift) { }; - virtual void OnLeftButtonUp (int x, int y, bool bControl, bool bShift) { }; - virtual void OnLeftButtonDoubleClick (int x, int y, bool bControl, bool bShift) { }; - virtual void OnRightButtonDown (int x, int y, bool bControl, bool bShift) { }; - virtual void OnRightButtonUp (int x, int y, bool bControl, bool bShift) { }; - virtual void OnMouseMove (int x, int y, bool bControl, bool bShift) { }; - - protected: - int m_nWidth; - int m_nHeight; - - private: - void *m_pData; - GLWindow *m_pShare; - int m_nRef; +public: + GLWindow(GLWindow *share); + virtual ~GLWindow(); + + void IncRef() + { m_nRef++; } + void DecRef() + { m_nRef--; if (m_nRef == 0) delete this; } + + bool Create(void* data); + void DestroyContext(); + + bool MakeCurrent(); + void SwapBuffers(); + void Redraw(); + void CaptureMouse(); + void ReleaseMouse(); + + int GetWidth() const + { return m_nWidth; } + int GetHeight() const + { return m_nHeight; } + void* GetData() const + { return m_pData; } + + virtual void OnDraw() { }; + virtual void OnSize(int cx, int cy) + { m_nWidth = cx; m_nHeight = cy; }; + virtual void OnInitialUpdate(); + virtual void OnLeftButtonDown(int x, int y, bool bControl, bool bShift) { }; + virtual void OnLeftButtonUp(int x, int y, bool bControl, bool bShift) { }; + virtual void OnLeftButtonDoubleClick(int x, int y, bool bControl, bool bShift) { }; + virtual void OnRightButtonDown(int x, int y, bool bControl, bool bShift) { }; + virtual void OnRightButtonUp(int x, int y, bool bControl, bool bShift) { }; + virtual void OnMouseMove(int x, int y, bool bControl, bool bShift) { }; + +protected: + int m_nWidth; + int m_nHeight; + +private: + void *m_pData; + GLWindow *m_pShare; + int m_nRef; }; #endif // _GLWINDOW_H_ diff --git a/common/pieceinf.cpp b/common/pieceinf.cpp index 4df330e..56cf7c3 100644 --- a/common/pieceinf.cpp +++ b/common/pieceinf.cpp @@ -1540,10 +1540,17 @@ void PieceInfo::FreeInformation() } // Zoom extents for the preview window and print catalog -void PieceInfo::ZoomExtents(float Fov, float Aspect) +void PieceInfo::ZoomExtents(float Fov, float Aspect, float* EyePos) const { float Eye[3] = { -100.0f, -100.0f, 50.0f }; + if (EyePos) + { + Eye[0] = EyePos[0]; + Eye[1] = EyePos[1]; + Eye[2] = EyePos[2]; + } + // Get perspective information. float Alpha = Fov / 2.0f; float HalfFovY = Fov / 2.0f; @@ -1645,6 +1652,13 @@ void PieceInfo::ZoomExtents(float Fov, float Aspect) NewEye[1] = Eye[1] + Front[1] * SmallestU; NewEye[2] = Eye[2] + Front[2] * SmallestU; + if (EyePos) + { + EyePos[0] = NewEye[0]; + EyePos[1] = NewEye[1]; + EyePos[2] = NewEye[2]; + } + Vector FrontVec, RightVec, UpVec; // Calculate view matrix. diff --git a/common/pieceinf.h b/common/pieceinf.h index a4ea314..9dd3d94 100644 --- a/common/pieceinf.h +++ b/common/pieceinf.h @@ -9,6 +9,7 @@ #ifndef GLuint #include "opengl.h" #endif +#include "algebra.h" #define LC_PIECE_COUNT 0x01 // Count this piece in the totals ? #define LC_PIECE_LONGDATA 0x02 // unsigned long/short index @@ -72,8 +73,15 @@ class PieceInfo return (m_strDescription[0] == '~'); } + Point3 GetCenter() const + { + return Point3((m_fDimensions[0] + m_fDimensions[3]) * 0.5f, + (m_fDimensions[1] + m_fDimensions[4]) * 0.5f, + (m_fDimensions[2] + m_fDimensions[5]) * 0.5f); + } + // Operations - void ZoomExtents(float Fov, float Aspect); + void ZoomExtents(float Fov, float Aspect, float* EyePos = NULL) const; void RenderOnce(int nColor); void RenderPiece(int nColor); void WriteWavefront(FILE* file, unsigned char color, unsigned long* start); diff --git a/common/preview.cpp b/common/preview.cpp index 12a7986..d792849 100644 --- a/common/preview.cpp +++ b/common/preview.cpp @@ -6,11 +6,17 @@ #include "globals.h" #include "project.h" #include "pieceinf.h" +#include "system.h" PiecePreview::PiecePreview(GLWindow *share) : GLWindow(share) { m_PieceInfo = NULL; + m_RotateX = 45.0f; + m_RotateZ = 45.0f; + m_Distance = 10.0f; + m_AutoZoom = true; + m_Tracking = LC_TRACK_NONE; } PiecePreview::~PiecePreview() @@ -44,7 +50,31 @@ void PiecePreview::OnDraw() gluPerspective(30.0f, aspect, 1.0f, 100.0f); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); - m_PieceInfo->ZoomExtents(30.0f, aspect); + + Point3 Eye(0, 0, 1.0f); + Matrix33 Rot; + + Rot.CreateFromAxisAngle(Vector3(1, 0, 0), -m_RotateX * LC_DTOR); + Eye = Eye * Rot; + + Rot.CreateFromAxisAngle(Vector3(0, 0, 1), -m_RotateZ * LC_DTOR); + Eye = Eye * Rot; + + if (m_AutoZoom) + { + Eye = Eye * 100.0f; + m_PieceInfo->ZoomExtents(30.0f, aspect, Eye); + + // Update the new camera distance. + Vector3 d = Eye - m_PieceInfo->GetCenter(); + m_Distance = d.Length(); + } + else + { + Matrix44 WorldToView; + WorldToView.CreateLookAt(Eye * m_Distance, m_PieceInfo->GetCenter(), Vector3(0, 0, 1)); + glLoadMatrixf(WorldToView); + } float pos[4] = { 0, 0, 10, 0 }, *bg = project->GetBackgroundColor (); glLightfv(GL_LIGHT0, GL_POSITION, pos); @@ -72,3 +102,83 @@ void PiecePreview::SetCurrentPiece(PieceInfo *pInfo) Redraw(); } } + +void PiecePreview::OnLeftButtonDown(int x, int y, bool Control, bool Shift) +{ + if (m_Tracking == LC_TRACK_NONE) + { + m_DownX = x; + m_DownY = y; + m_Tracking = LC_TRACK_LEFT; + CaptureMouse(); + } +} + +void PiecePreview::OnLeftButtonUp(int x, int y, bool Control, bool Shift) +{ + if (m_Tracking == LC_TRACK_LEFT) + { + m_Tracking = LC_TRACK_NONE; + ReleaseMouse(); + } +} + +void PiecePreview::OnLeftButtonDoubleClick(int x, int y, bool Control, bool Shift) +{ + m_AutoZoom = true; + Redraw(); +} + +void PiecePreview::OnRightButtonDown(int x, int y, bool Control, bool Shift) +{ + if (m_Tracking == LC_TRACK_NONE) + { + m_DownX = x; + m_DownY = y; + m_Tracking = LC_TRACK_RIGHT; + CaptureMouse(); + } +} + +void PiecePreview::OnRightButtonUp(int x, int y, bool Control, bool Shift) +{ + if (m_Tracking == LC_TRACK_RIGHT) + { + m_Tracking = LC_TRACK_NONE; + ReleaseMouse(); + } +} + +void PiecePreview::OnMouseMove(int x, int y, bool Control, bool Shift) +{ + if (m_Tracking == LC_TRACK_LEFT) + { + // Rotate. + m_RotateZ += x - m_DownX; + m_RotateX += y - m_DownY; + + if (m_RotateX > 179.5f) + m_RotateX = 179.5f; + else if (m_RotateX < 0.5f) + m_RotateX = 0.5f; + + m_DownX = x; + m_DownY = y; + + Redraw(); + } + else if (m_Tracking == LC_TRACK_RIGHT) + { + // Zoom. + m_Distance += (float)(y - m_DownY) * 0.2f; + m_AutoZoom = false; + + if (m_Distance < 0.5f) + m_Distance = 0.5f; + + m_DownX = x; + m_DownY = y; + + Redraw(); + } +} diff --git a/common/preview.h b/common/preview.h index 13d6f27..e60a2be 100644 --- a/common/preview.h +++ b/common/preview.h @@ -12,6 +12,12 @@ public: virtual ~PiecePreview(); void OnDraw(); + void OnLeftButtonDown(int x, int y, bool Control, bool Shift); + void OnLeftButtonUp(int x, int y, bool Control, bool Shift); + void OnLeftButtonDoubleClick(int x, int y, bool Control, bool Shift); + void OnRightButtonDown(int x, int y, bool Control, bool Shift); + void OnRightButtonUp(int x, int y, bool Control, bool Shift); + void OnMouseMove(int x, int y, bool Control, bool Shift); PieceInfo* GetCurrentPiece() const { return m_PieceInfo; } @@ -19,6 +25,17 @@ public: protected: PieceInfo* m_PieceInfo; + + // Mouse tracking. + int m_Tracking; + int m_DownX; + int m_DownY; + + // Current camera settings. + float m_Distance; + float m_RotateX; + float m_RotateZ; + bool m_AutoZoom; }; #endif // _PREVIEW_H_ -- cgit v1.2.3