![]() |
TAPs 0.7.7.3
|
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