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