![]() |
TAPs 0.7.7.3
|
00001 /****************************************************************************** 00002 TAPsOpenGLTrackball.cpp 00003 00004 An object using OpenGL for Trackball Rotation. 00005 00006 SUKITTI PUNAK (10/06/2004) 00007 UPDATE (10/06/2004) 00008 -------------------------------------------------------------------------------- 00009 Example of Usage: See TAPsOpenGLTrackball.hpp 00010 ----------------- 00011 ******************************************************************************/ 00012 #include "TAPsOpenGLTrackball.hpp" 00013 // Using Inclusion Model (i.e. definitions are included in declarations) 00014 // (this name.cpp is included in name.hpp) 00015 // Each friend is defined directly inside its declaration. 00016 00017 BEGIN_NAMESPACE_TAPs 00018 //============================================================================= 00019 //----------------------------------------------------------------------------- 00020 OpenGLTrackball::OpenGLTrackball() 00021 { 00022 #ifdef TAPs_ENABLE_DEBUG 00023 std::cout << "Delete A OpenGLTrackball" << std::endl; 00024 #endif//TAPs_DEBUG_MODE 00025 00026 int i; 00027 // initialize matrices 00028 for ( i = 1; i < 15; i++ ) M[i] = Om[i] = m[i] = 0; 00029 for ( i = 0; i < 16; i += 5 ) M[i] = Om[i] = m[i] = 1; 00030 // initialize data members 00031 for ( i = 0; i < 3; i++ ) lastPos[i] = 0; 00032 } 00033 //----------------------------------------------------------------------------- 00034 OpenGLTrackball::~OpenGLTrackball() 00035 { 00036 #ifdef TAPs_ENABLE_DEBUG 00037 std::cout << "Delete A OpenGLTrackball" << std::endl; 00038 #endif//TAPs_DEBUG_MODE 00039 } 00040 //----------------------------------------------------------------------------- 00041 void OpenGLTrackball::MoveObject(int x, int y, int w_pix, int h_pix) 00042 { 00043 int i, j, k; 00044 double curPos[3], dx, dy, dz; 00045 00046 Trackball_ptov(x, y, w_pix, h_pix, curPos); 00047 dx = curPos[0] - lastPos[0]; 00048 dy = curPos[1] - lastPos[1]; 00049 dz = curPos[2] - lastPos[2]; 00050 00051 if (dx || dy || dz) { 00052 rotationAngle = 90.0 * asin(sqrt(dx*dx + dy*dy + dz*dz)); 00053 // for small motions by angle theta 00054 // (and we measure often so motions are small) 00055 // sin (theta) is approximately equal to theta 00056 00057 // axis = Pold x P 00058 rotationAxis[0] = lastPos[1]*curPos[2] - lastPos[2]*curPos[1]; 00059 rotationAxis[1] = lastPos[2]*curPos[0] - lastPos[0]*curPos[2]; 00060 rotationAxis[2] = lastPos[0]*curPos[1] - lastPos[1]*curPos[0]; 00061 00062 lastPos[0] = curPos[0]; 00063 lastPos[1] = curPos[1]; 00064 lastPos[2] = curPos[2]; 00065 00066 // find matrix 00067 glPushMatrix(); 00068 glLoadIdentity(); 00069 glRotated(rotationAngle, rotationAxis[0], rotationAxis[1], rotationAxis[2]); 00070 glGetDoublev(GL_MODELVIEW_MATRIX, m); 00071 glPopMatrix(); 00072 00073 // calculate the new matrix 00074 for ( i = 0; i < 4; i++ ) { 00075 for ( j = 0; j < 4; j++ ) { 00076 M[i+j*4] = 0; 00077 for ( k = 0; k < 4; k++ ) { 00078 M[i+j*4] += m[i+k*4]*Om[k+j*4]; 00079 } 00080 } 00081 } 00082 00083 for ( i = 0; i < 16; i++ ) { 00084 m[i] = M[i]; 00085 Om[i] = M[i]; 00086 } 00087 } 00088 } 00089 //----------------------------------------------------------------------------- 00090 void OpenGLTrackball::StartMotion(int x, int y, int w_pix, int h_pix) 00091 { 00092 startX = x; startY = y; 00093 curx = x; cury = y; 00094 Trackball_ptov(x, y, w_pix, h_pix, lastPos); 00095 } 00096 //----------------------------------------------------------------------------- 00097 void OpenGLTrackball::Trackball_ptov(int x, int y, int w_pix, int h_pix, double v[3]) 00098 { 00099 double d, a, dx, dy; 00100 00101 dx = x; 00102 dy = y; 00103 00104 // project x,y onto a hemi-sphere centered within width and height 00105 v[0] = (1.0*dx - w_pix) / w_pix; 00106 v[1] = -(1.0*dy - h_pix) / h_pix; 00107 00108 00109 d = v[0]*v[0] + v[1]*v[1]; 00110 d = (d < 1.0) ? d : 1.0; // keep below or equal to 1 00111 v[2] = sqrt(1-d); 00112 a = sqrt(d + v[2]*v[2]); 00113 v[0] /= a; 00114 v[1] /= a; 00115 v[2] /= a; 00116 } 00117 //----------------------------------------------------------------------------- 00118 void OpenGLTrackball::Reset() 00119 { 00120 int i; 00121 for ( i = 0; i < 16; i++ ) { 00122 if ( i%5 ) { 00123 m[i] = Om[i] = 0; 00124 } 00125 else { 00126 m[i] = Om[i] = 1; 00127 } 00128 } 00129 } 00130 //============================================================================= 00131 END_NAMESPACE_TAPs 00132 //345678901234567890123456789012345678901234567890123456789012345678901234567890 00133 //--+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8