TAPs 0.7.7.3
TAPsOpenGLTrackball.cpp
Go to the documentation of this file.
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
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines