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