arbeit
Main Page | Namespace List | Class Hierarchy | Alphabetical List | Compound List | File List | Namespace Members | Compound Members | File Members

RenderableQGL.cpp

Go to the documentation of this file.
00001 //------------------------------------------------------------------------
00002 //
00003 //   Joe Kniss
00004 //     8-29-02
00005 //                   ________    ____   ___ 
00006 //                  |        \  /    | /  /
00007 //                  +---+     \/     |/  /
00008 //                  +--+|  |\    /|     < 
00009 //                  |  ||  | \  / |  |\  \ 
00010 //                  |      |  \/  |  | \  \ 
00011 //                   \_____|      |__|  \__\
00012 //                       Copyright  2001 
00013 //                      Joe Michael Kniss
00014 //                   <<< jmk@cs.utah.edu >>>
00015 //               "All Your Base are Belong to Us"
00016 //-------------------------------------------------------------------------
00017 
00018 ///////////////////////////////////////////////////////////////////////////
00019 /// A BasicQGL that knows about renderables.
00020 
00021 
00022 
00023 #include <iostream>
00024 #include <vector>
00025 #include <limits>
00026 #include <algorithm>
00027 #include <qwidget.h>
00028 #include <GL/Pick.h>
00029 #include "QtGutzEvent.h"
00030 #include "RenderableQGL.h"
00031 
00032 
00033 using namespace std;
00034 using namespace gutz;
00035 
00036 RenderableQGL::RenderableQGL(QWidget *parent, const char *name)
00037 : BasicQGL(parent, name), 
00038   _picking(false),
00039   _picked(0)
00040 {
00041 
00042    _cam = new Camera();
00043    _manip = new Manip(_cam);
00044 
00045    initManipulators();
00046 
00047    cerr << " event map = " << endl;
00048    _cam->serialEventMap(cerr, std::string("  "));
00049    cerr << endl;
00050 
00051    _time.silent();
00052 }
00053 
00054 RenderableQGL::~RenderableQGL() 
00055 {
00056 
00057 }
00058 
00059 ///////////////////////////////////////////////////////////////////////////
00060 ///////////////////////////////////////////////////////////////////////////
00061 /// draw;
00062 ///////////////////////////////////////////////////////////////////////////
00063 ///////////////////////////////////////////////////////////////////////////
00064 
00065 void RenderableQGL::draw()
00066 {
00067    cerr << " drawing " << endl;
00068    static int ave = 0;
00069 
00070    if(_timeOn && !(ave%10)){
00071       _time.start();
00072    }
00073    ++ave;
00074 
00075    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
00076 
00077    /// if picking, the projection matrix can't be messed with.
00078    /// We reset it every pass, so the pick uses the last 
00079    /// projection matrix we set.
00080    if(!_picking) 
00081    {
00082       glMatrixMode(GL_PROJECTION);
00083       glLoadMatrixf(_cam->getProjectMatrix().m);
00084    }
00085    glMatrixMode(GL_MODELVIEW);
00086    glLoadMatrixf(_cam->getViewMatrix().m);
00087 
00088    glPushMatrix();
00089    {
00090       glColor4f(1,1,1,1);
00091       drawRenderables();
00092    }
00093    glPopMatrix();
00094 
00095    if(_timeOn && !(ave%10))
00096    {
00097       glFinish();
00098       double t = _time.et();
00099       cout << " time = " << t/10.0 << endl;
00100    }
00101 
00102    ///TODO: remove QT signals for simian events use gutz::signal
00103    drawFinished();
00104    drawDone();
00105    cerr << " draw done " << endl;
00106 }
00107 
00108 
00109 /////////////////////////////////////////////////////////
00110 /// call this one to simply cycle through the renderables
00111 void RenderableQGL::drawRenderables()
00112 {
00113    RenderableVecIter rli = _rens.begin();
00114    gutz::RenderEvent re(_cam,_manip,_picking);
00115 
00116    while(rli != _rens.end())
00117    {
00118       (*rli)->draw(re);
00119       ++rli;
00120    } 
00121 }
00122 
00123 ///////////////////////////////////////////////////////////////////////////
00124 /// Mousing
00125 ///////////////////////////////////////////////////////////////////////////
00126 
00127 
00128 ///////////////////////////////////////////////////////////////////////////
00129 /// Mouse move
00130 ///////////////////////////////////////////////////////////////////////////
00131 /// TODO: nuke debug statements, or make them part of a proper base class
00132 void RenderableQGL::mouseMoveEvent( QMouseEvent * e)
00133 {
00134   
00135    if(_picked)
00136    {
00137       /// some error checking, so we might have a chance of working :)
00138       ///  TODO: nuke this, at some point decide that you are doing the right thing.
00139       if(!_curMove)
00140       {
00141          cerr << "RenderableQGL::mouseMoveEvent(), no move defined " << endl;
00142          if(!_curMouse)
00143          {
00144             cerr << "RenderableQGL::mouseMoveEvent(), no mouse defined " << endl;
00145             _curMouse = qt2GutzMouse(e,_cam,_manip);
00146          }
00147          _curMove = new MouseMoveEvent(*_curMouse, vec3f(e->x(), e->y(),_curMouse->z()));
00148       }
00149 
00150       /// update the current move event's  position
00151       _curMove->setPos(vec3f(e->x(), e->y(), _curMouse->z()));
00152 
00153       /// see if the pick wanted the move
00154       if(_picked->move(*_curMove))
00155       {
00156          update();
00157          return; /// did, so return
00158       }
00159       else
00160       {
00161          _picked = 0; /// didn't so un pick it 
00162       }
00163    }
00164 
00165    /// if we made it his far, the pick didn't exist or didn't want
00166    ///  the event, so just do the standard move.
00167    BasicQGL::mouseMoveEvent(e);
00168 }
00169 
00170 ///////////////////////////////////////////////////////////////////////////
00171 /// Mouse down
00172 ///////////////////////////////////////////////////////////////////////////
00173 void RenderableQGL::mousePressEvent( QMouseEvent * e)
00174 {
00175    _curMouse = qt2GutzMouse(e,_cam,_manip);
00176    /// see if we picked something
00177    if( pickGL(_curMouse) ) /// something got picked
00178    {
00179       if(_picked) /// make sure picked actually got set
00180       {
00181          _curMove = new MouseMoveEvent(*_curMouse, vec3f(e->x(), e->y(), _curMouse->z()));
00182          /// see if the pick wants the event
00183          if(_picked->mouse(*_curMouse)) 
00184          {
00185             update();
00186             return; /// did want the event, so it was forwarded
00187          }
00188          else
00189          {
00190             _picked = 0; /// didn't want the event, so.. unpick
00191          }
00192       }
00193    }
00194 
00195    /// revert to standard mouse events if nothing was picked, or 
00196    ///  the pick didn't want the event.
00197    BasicQGL::mousePressEvent(e);
00198 }
00199 
00200 ///////////////////////////////////////////////////////////////////////////
00201 /// Mouse up
00202 ///////////////////////////////////////////////////////////////////////////
00203 void RenderableQGL::mouseReleaseEvent ( QMouseEvent * e )
00204 {
00205    if(_picked)
00206    {
00207       _curMouse = qt2GutzMouse(e,_cam,_manip);
00208       _curMouse->setButtonDown(false);
00209       _picked->mouse(*_curMouse);
00210    }   
00211    _curMouse->setButton(GUTZ_BUTTON_NONE);
00212    /// make sure everyone knows that the mouse is up
00213    BasicQGL::mouseReleaseEvent(e);
00214 }
00215 
00216 ///////////////////////////////////////////////////////////////////////////
00217 /// Mouse double down
00218 ///////////////////////////////////////////////////////////////////////////
00219 void RenderableQGL::mouseDoubleClickEvent ( QMouseEvent * e )
00220 {
00221    BasicQGL::mouseDoubleClickEvent(e);
00222 }
00223 
00224 ///////////////////////////////////////////////////////////////////////////
00225 /// Picking
00226 ///////////////////////////////////////////////////////////////////////////
00227 
00228 //////////////////////////////////////////////////////
00229 /// pick (GL style) a renderable or widget
00230 ///   returns true if something was picked, false otherwize
00231 ///   also sets the picked object...
00232 ///   TODO: unify renderables and widgets...
00233 bool RenderableQGL::pickGL(MouseEventSP me)
00234 {
00235    Pick p;
00236 
00237    p.startPickGL(me->x(),height()-me->y()-1,4);
00238    {
00239       /// draw!!!
00240       _picking = true;
00241       {
00242          draw();
00243       }
00244       _picking = false;
00245    }
00246    PickInfoVec pinfo = p.endPickGL();
00247 
00248    /// check if we picked something, and if we might 
00249    /// have the signature for a "Renderable" pick,
00250    ///  (ie. at least 2 names on the stack),
00251    /// TODO: should check each pick and accept the first one that
00252    ///  is a "Renderable" pick, ie skip over other geometry,
00253    ///  such as the volume, that is over the widget (for instance)
00254    if( (pinfo.size() > 0) && (pinfo[0].dataSize >= 2) && pinfo[0].data )
00255    {
00256       /// get the guy who wants to be picked
00257       if(!castPick(pinfo[0].data[0],pinfo[0].data[1]))
00258          return false;
00259       /// set the pick data, but strip off the 
00260       ///  id and pointer
00261       me->setPickData(&(pinfo[0].data[2]), pinfo[0].dataSize-2);
00262       /// set the "z" position of pick
00263       me->setZ(pinfo[0].z1);
00264       return true;;
00265    }
00266    else
00267    {
00268       _picked = 0;
00269       cerr << " picked nothing " << endl;
00270    }
00271 
00272    return false;
00273 }
00274 
00275 bool RenderableQGL::castPick(unsigned int name, unsigned int ptr)
00276 {
00277    if(name == RENDERABLE_NAME)
00278    {
00279       //cerr << " got a renderable " << ptr << endl;
00280       _picked = (Renderable *)ptr;
00281       //cerr << "  --- " << typeid(*_picked).name() << endl;
00282       //cerr << " done with cast " << endl;
00283       return true;
00284    }
00285    else
00286    {
00287       cerr << "RenderableQGL::castPick(), didn't match name " << endl;
00288       _picked = 0;
00289       return false;
00290    }
00291    return false;
00292 }
00293 
00294 ///////////////////////////////////////////////////////////////////////////
00295 ///////////////////////////////////////////////////////////////////////////
00296 /// renderable management
00297 ///////////////////////////////////////////////////////////////////////////
00298 ///////////////////////////////////////////////////////////////////////////
00299 
00300 
00301 void RenderableQGL::addRenderable(Renderable *r) 
00302 {
00303    _rens.push_back(r); 
00304    //update();
00305 }
00306 
00307 Renderable *RenderableQGL::getRenderable(unsigned int i)
00308 {
00309    if(i < (_rens.size()-1)) 
00310       return _rens[i]; 
00311    else 
00312       return 0;
00313 }
00314 
00315 void RenderableQGL::delRenderable(unsigned int idx)
00316 {
00317 
00318    RenderableVecIter rvi = _rens.begin();
00319 
00320    for(unsigned int i=0; i<idx; ++i)
00321    {
00322       ++rvi;
00323    }
00324 
00325    if(rvi != _rens.end())
00326    {
00327       _rens.erase(rvi);
00328    }
00329 }
00330 
00331 void RenderableQGL::delRenderable(Renderable *r)
00332 {
00333    RenderableVecIter ri = std::find(_rens.begin(), _rens.end(), RenderableSP(r));
00334    if(ri != _rens.end())
00335    {
00336       _rens.erase(ri);
00337    }
00338 }
00339 
00340 RenderableVec RenderableQGL::getRenderables() const
00341 {
00342    return _rens;
00343 }
00344 
00345 void RenderableQGL::setRenderables(RenderableVec &v)
00346 {
00347    _rens = v;
00348 }
00349 

Send questions, comments, and bug reports to:
jmk