Main Page   Modules   Class Hierarchy   Compound List   File List   Compound Members   File Members   Related Pages   Examples  

glutm/winexam.cpp

Go to the documentation of this file.
00001 #include "winexam.h"
00002 
00007 #include <glutm/glut.h>
00008 
00009 #include <glt/matrix.h>
00010 
00011 #include <cstddef>
00012 #include <cmath>
00013 #include <iostream>
00014 using namespace std;
00015 
00016 GlutWindowExaminer::GlutWindowExaminer(const std::string &title,int width,int height,int x,int y,unsigned int displayMode)
00017 : GlutWindow(title,width,height,x,y,displayMode), 
00018   _mouseZoom(true), 
00019   _mousePan(true), 
00020   _mouseRotate(true),
00021   _mouseMode(MODE_MOUSE_ONLY),
00022   _mouseLeft(false), 
00023   _mouseMiddle(false), 
00024   _mouseRight(false), 
00025   _mouseX(0), 
00026   _mouseY(0),
00027   _oldCursor(0)
00028 {
00029     glMatrixMode(GL_MODELVIEW);     
00030     glLoadIdentity();
00031 }
00032 
00033 GlutWindowExaminer::~GlutWindowExaminer()
00034 {
00035 }
00036 
00037 bool   &GlutWindowExaminer::mouseZoom()      { return _mouseZoom;      }
00038 bool   &GlutWindowExaminer::mousePan()       { return _mousePan;       }
00039 bool   &GlutWindowExaminer::mouseRotate()    { return _mouseRotate;    }
00040 
00041 GlutWindowExaminer::MouseMode &GlutWindowExaminer::mouseMode() { return _mouseMode; }
00042 
00043 Vector &GlutWindowExaminer::referencePoint() { return _referencePoint; }
00044 
00045 bool 
00046 GlutWindowExaminer::mousePressed() const
00047 {
00048     return _mouseLeft || _mouseMiddle || _mouseRight;
00049 }
00050 
00051 Vector GlutWindowExaminer::xAxisOfRotation() const
00052 {
00053     return _viewMatrixInverse*VectorX - _viewMatrixInverse*Vector0;
00054 }
00055 
00056 Vector GlutWindowExaminer::yAxisOfRotation() const
00057 {
00058     return _viewMatrixInverse*VectorY - _viewMatrixInverse*Vector0;
00059 }
00060 
00061 Vector GlutWindowExaminer::axisOfRotation(const Vector &v) const
00062 {
00063     return _viewMatrixInverse*v - _viewMatrixInverse*Vector0;
00064 }
00065 
00066 void GlutWindowExaminer::OnPreDisplay()
00067 {
00068     glMatrixMode(GL_MODELVIEW);     
00069     glLoadIdentity();
00070     _viewMatrix.glMultMatrix();
00071 }
00072 
00073 void GlutWindowExaminer::OnOpen()
00074 {
00075     GlutWindow::OnOpen();
00076     OnOrient(_viewMatrix,_viewMatrixInverse);
00077 }
00078 
00079 void GlutWindowExaminer::OnClose()
00080 {
00081     GlutWindow::OnClose();
00082 }
00083 
00084 void GlutWindowExaminer::OnReshape(int w, int h)                        
00085 {
00086     GlutWindow::OnReshape(w,h);
00087     _ortho.set(w,h);
00088     OnOrient(_viewMatrix,_viewMatrixInverse);
00089 }
00090 
00091 void GlutWindowExaminer::OnKeyboard(unsigned char key, int x, int y)
00092 {
00093     bool draw = true;
00094 
00095     switch (key)
00096     {
00097     case 'i':  if (_mouseZoom) _viewMatrix = matrixScale(1.2)          * _viewMatrix; break;
00098     case 'o':  if (_mouseZoom) _viewMatrix = matrixScale(1.0/1.2)      * _viewMatrix; break;
00099 
00100     case 'g':  if (_mousePan) _viewMatrix = _viewMatrix * matrixTranslate(VectorY* 0.1); break;
00101     case 'b':  if (_mousePan) _viewMatrix = _viewMatrix * matrixTranslate(VectorY*-0.1); break;
00102     case 'n':  if (_mousePan) _viewMatrix = _viewMatrix * matrixTranslate(VectorX*-0.1); break;
00103     case 'm':  if (_mousePan) _viewMatrix = _viewMatrix * matrixTranslate(VectorX* 0.1); break;
00104     case 'f':  if (_mousePan) _viewMatrix = _viewMatrix * matrixTranslate(VectorZ* 0.1); break;
00105     case 'v':  if (_mousePan) _viewMatrix = _viewMatrix * matrixTranslate(VectorZ*-0.1); break;
00106 
00107     case 'a':  if (_mouseRotate) _viewMatrix = matrixRotate(xAxisOfRotation(),10.0)  * _viewMatrix; break;
00108     case 'z':  if (_mouseRotate) _viewMatrix = matrixRotate(xAxisOfRotation(),-10.0) * _viewMatrix; break;
00109     case 'x':  if (_mouseRotate) _viewMatrix = matrixRotate(yAxisOfRotation(),10.0)  * _viewMatrix; break;
00110     case 'c':  if (_mouseRotate) _viewMatrix = matrixRotate(yAxisOfRotation(),-10.0) * _viewMatrix; break;
00111 
00112     case 'q':
00113     case 27:  close(); return;
00114 
00115     default:
00116         GlutWindow::OnKeyboard(key,x,y);
00117         draw = false;
00118     }
00119 
00120     if (draw)
00121     {       
00122         _viewMatrixInverse = _viewMatrix.inverse();
00123         postRedisplay();
00124         OnOrient(_viewMatrix,_viewMatrixInverse);
00125     }
00126 }
00127 
00128 void 
00129 GlutWindowExaminer::OnSpecial(int key, int x, int y)  
00130 {
00131     GlutWindow::OnSpecial(key,x,y);
00132 
00133     bool draw = true;
00134 
00135     switch (key)
00136     {
00137     case GLUT_KEY_HOME: _viewMatrix = Matrix(); break;
00138     default:
00139         draw = false;
00140     }
00141 
00142     if (draw)
00143     {       
00144         _viewMatrixInverse = _viewMatrix.inverse();
00145         postRedisplay();
00146         OnOrient(_viewMatrix,_viewMatrixInverse);
00147     }
00148 }
00149 
00150 void GlutWindowExaminer::OnMenu(int value)
00151 {
00152     GlutWindow::OnMenu(value);
00153 }
00154 
00155 void GlutWindowExaminer::OnMouse(int button, int state, int x, int y)
00156 {
00157     // Keep mouse position for later
00158 
00159     _mouseX = x;
00160     _mouseY = y;
00161 
00162     // Suspend idle, if necessary
00163 
00164     if (!mousePressed())
00165     {
00166         // TODO: Is this really necessary??
00167         // Idle is a bad way to drive redraw anyway!
00168         _wasIdle = getIdle();
00169         setIdle(false);
00170         _oldCursor = getCursor();
00171     }
00172 
00173     // Update mouse button state
00174 
00175     if (state==GLUT_UP)
00176         switch (button)
00177         {
00178         case GLUT_LEFT_BUTTON:   _mouseLeft   = false; break;
00179         case GLUT_MIDDLE_BUTTON: _mouseMiddle = false; break;
00180         case GLUT_RIGHT_BUTTON:  _mouseRight  = false; break;
00181         }
00182     else
00183     {
00184         _referencePoint = getReferencePoint(x,y,dragPos(x,y),_viewMatrix,_viewMatrixInverse);
00185 
00186         switch (button)
00187         {
00188         case GLUT_LEFT_BUTTON:      _mouseLeft   = true; break;
00189         case GLUT_MIDDLE_BUTTON:    _mouseMiddle = true; break;
00190         case GLUT_RIGHT_BUTTON:     _mouseRight  = true; break;
00191         }
00192     }
00193 
00194     // Restart idle, if necessary
00195 
00196     if (!mousePressed())
00197     {
00198         setIdle(_wasIdle);
00199         setCursor(_oldCursor);
00200     }
00201 
00202     // Keep track of world-space drag position
00203 
00204     _dragPosPrev = dragPos(x,y);
00205 }
00206 
00207 void GlutWindowExaminer::OnMotion(int x, int y)
00208 {
00209     bool changed = false;
00210 
00211     const int dx = x - _mouseX;
00212     const int dy = y - _mouseY;
00213 
00214     if (dx==0 && dy==0)
00215         return;
00216 
00217     bool zoom   = false;
00218     bool pan    = false;
00219     bool rotate = false;
00220 
00221     switch (_mouseMode)
00222     {
00223         //
00224         // Left rotate, middle zoom, right pan
00225         //
00226 
00227         default:
00228         case MODE_MOUSE_ONLY:
00229             zoom   = _mouseZoom   && (_mouseMiddle || (_mouseLeft && _mouseRight));
00230             pan    = _mousePan    && _mouseRight && !zoom;
00231             rotate = _mouseRotate && _mouseLeft  && !zoom;
00232             break;
00233 
00234         //
00235         // Right mouse button, shift to pan, control to zoom
00236         //
00237 
00238         case MODE_MOUSE_RIGHT:
00239             zoom   = _mouseZoom   && _mouseRight && getCtrlModifier();
00240             pan    = _mousePan    && _mouseRight && getShiftModifier() && !zoom;
00241             rotate = _mouseRotate && _mouseRight && !zoom && !pan;  
00242             break;
00243     }
00244 
00245     if (zoom)
00246     {
00247         // ZOOM
00248 
00249         _viewMatrix = 
00250             matrixTranslate(-_referencePoint) *
00251             matrixScale(exp(double(dy)*0.01)) *
00252             matrixTranslate(_referencePoint) *
00253             _viewMatrix;
00254 
00255         setCursor(GLUT_CURSOR_UP_DOWN);
00256         
00257         changed = true;
00258     }
00259     else
00260     if (rotate)
00261     {
00262         // ROTATE
00263 
00264         Vector axis;
00265         real angle = 0.0;
00266 
00267         if (getAltModifier())
00268         {
00269             // Axis is perpendicular to viewing plane
00270             // Angle is proportional to mouse y velocity
00271 
00272             axis  = VectorZ;
00273             angle = -dy/(_viewport.height()+1.0)*720.0;
00274         }
00275         else
00276         {
00277             // Axis is perpendicular to delta
00278             // (The "-dy" is because mouse has top left origin)
00279             // Angle is proportional to the distance moved
00280 
00281             axis  = xProduct(Vector(real(dx),real(-dy),0.0),VectorZ);
00282             angle = axis.length()/(_viewport.width()+1.0)*180.0;
00283         }
00284 
00285         _viewMatrix = 
00286             matrixTranslate(-_referencePoint) *
00287             matrixRotate(axisOfRotation(axis),angle) *
00288             matrixTranslate(_referencePoint) *
00289             _viewMatrix;
00290 
00291         setCursor(GLUT_CURSOR_CYCLE);
00292 
00293         changed = true;
00294     }
00295     else
00296     if (pan)
00297     {
00298         // PAN
00299 
00300         const Vector pos = dragPos(x,y);
00301 
00302         if (getAltModifier())
00303             _viewMatrix = _viewMatrix * matrixTranslate(VectorZ*dy/_viewport.height()*(_ortho.zFar()-_ortho.zNear()));      
00304         else
00305             _viewMatrix = _viewMatrix * matrixTranslate(pos-_dragPosPrev);
00306 
00307         _dragPosPrev = pos;
00308 
00309         setCursor(GLUT_CURSOR_CROSSHAIR);
00310 
00311         changed = true;
00312     }
00313 
00314     // Save the current mouse position for later
00315 
00316     _mouseX = x;
00317     _mouseY = y;
00318 
00319     if (changed)
00320     {
00321         _viewMatrixInverse = _viewMatrix.inverse();
00322         postRedisplay();
00323         OnOrient(_viewMatrix,_viewMatrixInverse);
00324     }   
00325 }
00326 
00327 Vector 
00328 GlutWindowExaminer::dragPos(const int x,const int y) const
00329 {
00330     // Use the ortho projection and viewport information
00331     // to map from mouse co-ordinates back into world 
00332     // co-ordinates
00333 
00334     real wx = real(x-_viewport.x())/real(_viewport.width());
00335     real wy = real(y-_viewport.y())/real(_viewport.height());
00336 
00337     wx = _ortho.left() + wx*(_ortho.right() -_ortho.left());
00338     wy = _ortho.top()  + wy*(_ortho.bottom()-_ortho.top());
00339 
00340     return Vector(wx,wy,_ortho.zNear());
00341 }
00342 
00343 Vector 
00344 GlutWindowExaminer::getReferencePoint(int x,int y,const Vector &pos,const Matrix &modelView,const Matrix &modelViewInverse) const
00345 {
00346     return Vector0; 
00347 }
00348 
00349 void 
00350 GlutWindowExaminer::OnPassiveMotion(int x, int y)
00351 {
00352 }
00353 
00354 void 
00355 GlutWindowExaminer::OnOrient(const Matrix &viewing,const Matrix &inverse)
00356 {
00357 }

Generated on Tue Nov 5 11:11:04 2002 for GLT by doxygen1.2.18