TAPs 0.7.7.3
TAPsOpenGLViewManager.cpp
Go to the documentation of this file.
00001 /******************************************************************************
00002 TAPsOpenGLViewManager.cpp
00003 
00004 Inherited from class OpenGLBaseViewManager
00005 
00006 SUKITTI PUNAK   (07/20/2005)
00007 UPDATE          (07/30/2005)
00008 ******************************************************************************/
00009 #include "TAPsOpenGLViewManager.hpp"
00010 // Using Inclusion Model (i.e. definitions are included in declarations)
00011 //                       (this name.cpp is included in name.hpp)
00012 // Each friend is defined directly inside its declaration.
00013 
00014 //-----------------------------------------------------------------------------
00015 // DEBUG ENABLE
00016 #ifdef TAPs_ENABLE_DEBUG
00017     #define DEBUG_MESSAGE_TAPs_VIEW_MANAGER
00018 #endif
00019 //-----------------------------------------------------------------------------
00020 BEGIN_NAMESPACE_TAPs__OpenGL
00021 //=============================================================================
00022 //-----------------------------------------------------------------------------
00023 // Default Constructor
00024 template <typename T>
00025 OpenGLViewManager<T>::OpenGLViewManager ()
00026     : OpenGLBaseViewManager<T>(),
00027       m_tViewScale( 1 ),
00028       m_tWindowToWorldScale( 1 ),
00029       m_iLastMouseX( 0 ),
00030       m_iLastMouseY( 0 ),
00031       m_vLookAt( 0, 0, 0 ),
00032       m_eModifyViewType( INVALID_MODIFY_VIEW )
00033 {}
00034 //-----------------------------------------------------------------------------
00035 // Destructor
00036 template <typename T>
00037 OpenGLViewManager<T>::~OpenGLViewManager ()
00038 {}
00039 //-----------------------------------------------------------------------------
00040 // Setup OpenGL Rendering Properties
00041 template <typename T>
00042 void OpenGLViewManager<T>::Setup ()
00043 {
00044     // Enable depth buffering for hidden surface removal
00045     glDepthFunc( GL_LEQUAL );
00046     glEnable( GL_DEPTH_TEST );
00047     // Cull back faces
00048     glCullFace( GL_BACK );
00049     glEnable( GL_CULL_FACE );
00050     // Other misc features
00051     glEnable( GL_LIGHTING );
00052     glEnable( GL_NORMALIZE );
00053     glShadeModel( GL_SMOOTH );
00054     glLightModeli( GL_LIGHT_MODEL_LOCAL_VIEWER, GL_FALSE );
00055     glLightModeli( GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE );
00056     static const GLfloat light_model_ambient[] = { 0.3f, 0.3f, 0.3f, 1.0f };
00057     glLightModelfv( GL_LIGHT_MODEL_AMBIENT, light_model_ambient );
00058     //*
00059     TAPs::OpenGL::Fn::InitializeLight( GL_LIGHT0, 
00060             0.3f, 0.3f, 0.3f, 1.0f,     // ambient
00061             0.7f, 0.7f, 0.7f, 0.9f,     // diffuse
00062             0.9f, 0.9f, 0.9f, 0.5f,     // specular
00063             0.0f, 0.4f, 10.0f, 1.0f     // position
00064     );
00065     //*/
00066     /*
00067     TAPs::OpenGL::Fn::InitializeLight( GL_LIGHT1, 
00068             0.5f, 0.5f, 0.5f, 1.0f,     // ambient
00069             0.8f, 0.8f, 0.8f, 0.9f,     // diffuse
00070             1.0f, 1.0f, 1.0f, 1.0f,     // specular
00071             2.0f, 0.0f, 1.0f, 0.0f      // position
00072     );
00073     //*/
00074     /*
00075     TAPs::OpenGL::Fn::InitializeLight( GL_LIGHT2, 
00076             0.3f, 0.3f, 0.3f, 1.0f,     // ambient
00077             0.4f, 0.4f, 0.4f, 0.9f,     // diffuse
00078             0.5f, 0.5f, 0.5f, 0.5f,     // specular
00079             -2.0f, 0.0f, 1.0f, 0.0f     // position
00080     );
00081     //*/
00082 }
00083 //-----------------------------------------------------------------------------
00084 // Cleanup
00085 template <typename T>
00086 void OpenGLViewManager<T>::Cleanup ()
00087 {}
00088 //-----------------------------------------------------------------------------
00089 // ReshapeView
00090 template <typename T>
00091 void OpenGLViewManager<T>::ReshapeView ( int width, int height )
00092 {
00093     static const T K_FOV_Y = 40;
00094     static const T K_CANONICAL_SPHERE_RADIUS = sqrt( static_cast<T>(3.0) );
00095     static const T K_PI = 3.1415926535897932384626433832795;
00096     //-------------------------------------------------------------------
00097     glViewport( 0, 0, static_cast<GLsizei>(width), static_cast<GLsizei>(height) );
00098     //-------------------------------------------------------------------
00099     // Compute the viewing parameters based on a fixed fov and viewing
00100     // sphere enclosing a canonical box centered at the origin
00101     T nearDist = K_CANONICAL_SPHERE_RADIUS / tan( (K_FOV_Y/2.0) * K_PI / 180.0 );
00102     T farDist  = nearDist + 2.0 * K_CANONICAL_SPHERE_RADIUS;
00103     //T nearDist = 1;
00104     //T farDist  = 100;
00105     //std::cout << "nearDist: " << nearDist << " farDist: " << farDist << std::endl;
00106     T aspect   = static_cast<T>(width) / static_cast<T>(height);
00107     //-------------------------------------------------------------------
00108     glMatrixMode( GL_PROJECTION );
00109     glLoadIdentity();
00110     gluPerspective( K_FOV_Y, aspect, nearDist, farDist );
00111     //-------------------------------------------------------------------
00112     // View down the z-axis and look at the origin
00113     m_vViewPosition[0] = 0;
00114     m_vViewPosition[1] = 0;
00115     m_vViewPosition[2] = nearDist + K_CANONICAL_SPHERE_RADIUS;
00116     UpdateView();
00117 }
00118 //-----------------------------------------------------------------------------
00119 // UpdateView
00120 template <typename T> 
00121 void OpenGLViewManager<T>::UpdateView ()
00122 {
00123     glMatrixMode( GL_MODELVIEW );
00124     glLoadIdentity();
00125     gluLookAt(  m_vViewPosition[0], m_vViewPosition[1], m_vViewPosition[2],
00126                 m_vLookAt[0], m_vLookAt[1], m_vLookAt[2],
00127                 0, 1, 0 );
00128     glMultMatrixd( m_mViewRotation );
00129     glScaled( m_tViewScale, m_tViewScale, m_tViewScale );
00130     //----------------------------------------------------------------
00131     // Refresh the cache of OpenGL view state
00132     glGetDoublev( GL_MODELVIEW_MATRIX, m_mWorldToView );
00133     glGetDoublev( GL_PROJECTION_MATRIX, m_mViewToClip );
00134     glGetIntegerv( GL_VIEWPORT, m_aiViewport );
00135     UpdateWindowToWorldScale();
00136 }
00137 //-----------------------------------------------------------------------------
00138 // IsModifyingView
00139 template <typename T>
00140 bool OpenGLViewManager<T>::IsModifyingView () const
00141 {
00142     return m_eModifyViewType != INVALID_MODIFY_VIEW;
00143 }
00144 //-----------------------------------------------------------------------------
00145 // StartModifyView
00146 template <typename T>
00147 void OpenGLViewManager<T>::StartModifyView ( enum ModifyViewType type, int x, int y )
00148 {
00149     if ( type == MODIFY_VIEW_ROTATE || type == MODIFY_VIEW_SCALE ) {
00150         m_eModifyViewType = type;
00151         m_iLastMouseX = x;
00152         m_iLastMouseY = y;
00153     }
00154 }
00155 //-----------------------------------------------------------------------------
00156 // StopModifyView
00157 template <typename T>
00158 void OpenGLViewManager<T>::StopModifyView ()
00159 {
00160     m_eModifyViewType = INVALID_MODIFY_VIEW;
00161 }
00162 //-----------------------------------------------------------------------------
00163 // ModifyView
00164 template <typename T>
00165 void OpenGLViewManager<T>::ModifyView ( int x, int y )
00166 {
00167     static const T K_TRACK_BALL_RADIUS = 0.8;
00168     //----------------------------------------------------------------
00169     if ( m_eModifyViewType == MODIFY_VIEW_ROTATE ) {
00170         Vector3<T> lastPos;
00171         lastPos[0] = 2.0*m_iLastMouseX/GetWindowWidth() - 1.0;
00172         lastPos[1] = 2.0*(GetWindowHeight() - m_iLastMouseY)/GetWindowHeight() - 1.0;
00173         lastPos[2] = ProjectToTrackBall( K_TRACK_BALL_RADIUS, lastPos[0], lastPos[1] );
00174         //------------------------------------------------------
00175         Vector3<T> currPos;
00176         currPos[0] = 2.0*x/GetWindowWidth() - 1.0;
00177         currPos[1] = 2.0*(GetWindowHeight() - y)/GetWindowHeight() - 1.0;
00178         currPos[2] = ProjectToTrackBall( K_TRACK_BALL_RADIUS, currPos[0], currPos[1] );
00179         //------------------------------------------------------
00180         Vector3<T> vRotate = lastPos.Cross( currPos );
00181         T rotateAngle = asin( vRotate.Length() );
00182         if ( fabs( rotateAngle - 0.0 ) > Math<T>::EPSILON ) {
00183             Matrix4x4<T> deltaRotation = Matrix4x4<T>::CreateRotation( vRotate, rotateAngle ).GetTranspose();
00184             m_mViewRotation.MultRight( deltaRotation );
00185             UpdateView();
00186         }
00187     }
00188     //----------------------------------------------------------------
00189     else if ( m_eModifyViewType == MODIFY_VIEW_SCALE ) {
00190         T y1 = GetWindowHeight() - m_iLastMouseY;
00191         T y2 = GetWindowHeight() - y;
00192         m_tViewScale *= 1 + (y1 - y2) / GetWindowHeight();
00193         UpdateView();
00194     }
00195     m_iLastMouseX = x;
00196     m_iLastMouseY = y;
00197 }
00198 //-----------------------------------------------------------------------------
00199 // ToScreen
00200 template <typename T>
00201 bool OpenGLViewManager<T>::ToScreen ( const Vector3<T> & obj, Vector3<T> & win ) const
00202 {
00203     int iResult = gluProject(   obj[0], obj[1], obj[2],
00204                                 m_mWorldToView,     // m_mWorldToView matrix
00205                                 m_mViewToClip,      // projection matrix
00206                                 m_aiViewport,       // viewport
00207                                 &win[0], &win[1], &win[2] );
00208     return iResult == GL_TRUE;
00209 }
00210 //-----------------------------------------------------------------------------
00211 // FromScreen
00212 template <typename T>
00213 bool OpenGLViewManager<T>::FromScreen ( const Vector3<T> & win, Vector3<T> & obj ) const
00214 {
00215     int iResult = gluUnProject( win[0], win[1], win[2],
00216                                 m_mWorldToView,     // m_mWorldToView matrix
00217                                 m_mViewToClip,      // projection matrix 
00218                                 m_aiViewport,       // viewport
00219                                 &obj[0], &obj[1], &obj[2] );
00220     return iResult == GL_TRUE;
00221 }
00222 //-----------------------------------------------------------------------------
00223 // GetWindowToWorldScale
00224 template <typename T>
00225 T OpenGLViewManager<T>::GetWindowToWorldScale () const
00226 {
00227     return m_tWindowToWorldScale;
00228 }
00229 //-----------------------------------------------------------------------------
00230 // GetViewTransform
00231 template <typename T>
00232 const Matrix4x4<T> & OpenGLViewManager<T>::GetViewTransform () const
00233 {
00234     return m_mWorldToView;
00235 }
00236 //-----------------------------------------------------------------------------
00237 // GetProjTransform
00238 template <typename T>
00239 const Matrix4x4<T> & OpenGLViewManager<T>::GetProjTransform () const
00240 {
00241     return m_mViewToClip;
00242 }
00243 //-----------------------------------------------------------------------------
00244 //=============================================================================
00245 // Helper Fn
00246 //-----------------------------------------------------------------------------
00247 // ProjectToTrackBall
00248 // used by the view rotation code for simulating a virtual trackball.
00249 // This math computes the z height for a 2D projection onto the surface of a 
00250 // 2.5D sphere.  When the input point is near the center of the sphere, it 
00251 // computes the actual sphere intersection in Z.  When the input point is moved 
00252 // towards the outside of the sphere, it will solve for a hyperbolic projection, 
00253 // so that we still get a meaningful answer.
00254 template <typename T>
00255 T OpenGLViewManager<T>::ProjectToTrackBall ( T radius, T x, T y )
00256 {
00257     static const T K_UINT_SPHERE_RADIUS_2D = sqrt( 2.0 );
00258     T z;
00259     T dist = sqrt( x*x + y*y );
00260     if ( dist < radius * K_UINT_SPHERE_RADIUS_2D / 2.0 ) {
00261         // Solve for sphere case
00262         z = sqrt( radius*radius - dist*dist );
00263     }
00264     else {
00265         // Solve for hyperbolic sheet case
00266         T t = radius / K_UINT_SPHERE_RADIUS_2D;
00267         z = t*t / dist;
00268     }
00269     return z;
00270 }
00271 //-----------------------------------------------------------------------------
00272 // UpdateWindowToWorldScale
00273 // uses the viewing transforms to determine a scale factor that will allow us to 
00274 // specify the size of objects on the screen in pixel dimensions.
00275 template <typename T>
00276 void OpenGLViewManager<T>::UpdateWindowToWorldScale ()
00277 {
00278     Vector3<T> p0, p1;
00279     bool bNoError;
00280     bNoError = FromScreen( Vector3<T>(0,0,0), p0 );
00281     assert( bNoError );
00282     bNoError = FromScreen( Vector3<T>(1,1,0), p1 );
00283     assert( bNoError );
00284     m_tWindowToWorldScale = (p1-p0).Length() / sqrt(2.0);
00285 }
00286 //-----------------------------------------------------------------------------
00287 //=============================================================================
00288 END_NAMESPACE_TAPs__OpenGL
00289 //-----------------------------------------------------------------------------
00290 //345678901234567890123456789012345678901234567890123456789012345678901234567890
00291 //--+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines