QtBaseViewerPicking.cc

00001 /*===========================================================================*\
00002  *                                                                           *
00003  *                              OpenFlipper                                  *
00004  *      Copyright (C) 2001-2009 by Computer Graphics Group, RWTH Aachen      *
00005  *                           www.openflipper.org                             *
00006  *                                                                           *
00007  *---------------------------------------------------------------------------*
00008  *  This file is part of OpenFlipper.                                        *
00009  *                                                                           *
00010  *  OpenFlipper is free software: you can redistribute it and/or modify      *
00011  *  it under the terms of the GNU Lesser General Public License as           *
00012  *  published by the Free Software Foundation, either version 3 of           *
00013  *  the License, or (at your option) any later version with the              *
00014  *  following exceptions:                                                    *
00015  *                                                                           *
00016  *  If other files instantiate templates or use macros                       *
00017  *  or inline functions from this file, or you compile this file and         *
00018  *  link it with other files to produce an executable, this file does        *
00019  *  not by itself cause the resulting executable to be covered by the        *
00020  *  GNU Lesser General Public License. This exception does not however       *
00021  *  invalidate any other reasons why the executable file might be            *
00022  *  covered by the GNU Lesser General Public License.                        *
00023  *                                                                           *
00024  *  OpenFlipper is distributed in the hope that it will be useful,           *
00025  *  but WITHOUT ANY WARRANTY; without even the implied warranty of           *
00026  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the            *
00027  *  GNU Lesser General Public License for more details.                      *
00028  *                                                                           *
00029  *  You should have received a copy of the GNU LesserGeneral Public          *
00030  *  License along with OpenFlipper. If not,                                  *
00031  *  see <http://www.gnu.org/licenses/>.                                      *
00032  *                                                                           *
00033 \*===========================================================================*/
00034 
00035 /*===========================================================================*\
00036  *                                                                           *
00037  *   $Revision: 7363 $                                                         *
00038  *   $Author: dekkers $                                                      *
00039  *   $Date: 2009-10-12 19:18:30 +0200 (Mo, 12. Okt 2009) $                   *
00040  *                                                                           *
00041 \*===========================================================================*/
00042 
00043 
00044 
00045 
00046 //=============================================================================
00047 //
00048 //  CLASS glViewer - IMPLEMENTATION
00049 //
00050 //=============================================================================
00051 
00052 
00053 //== INCLUDES =================================================================
00054 
00055 #include "QtBaseViewer.hh"
00056 #include "QtGLGraphicsScene.hh"
00057 #include "QtGLGraphicsView.hh"
00058 
00059 #include <QGLFramebufferObject>
00060 
00061 //== NAMESPACES ===============================================================
00062 
00063 //== IMPLEMENTATION ==========================================================
00064 
00065 static const unsigned int  SELECTION_BUFFER_SIZE = 10000;
00066 static const unsigned int  NAME_STACK_SIZE       = 2;
00067 
00068 //== IMPLEMENTATION ==========================================================
00069 
00070 
00071 bool glViewer::pick( ACG::SceneGraph::PickTarget _pickTarget,
00072                      const QPoint&               _mousePos,
00073                      unsigned int&               _nodeIdx,
00074                      unsigned int&               _targetIdx,
00075                      ACG::Vec3d*                 _hitPointPtr )
00076 {
00077   if (sceneGraphRoot_)
00078   {
00079     // unsigned int node, target;
00080     // QTime time;
00081     // time.start ();
00082     int rv = pickFromCache (_pickTarget, _mousePos, _nodeIdx, _targetIdx, _hitPointPtr);
00083 
00084     // cache will return -1 if a update is needed or caching is not supported
00085     if (rv < 0)
00086       rv = pickColor (_pickTarget, _mousePos, _nodeIdx, _targetIdx, _hitPointPtr);
00087 
00088     // printf ("ColorPicking took %d msec\n",time.restart ());
00089     // rv = -1;
00090     // node = _nodeIdx;
00091     // target = _targetIdx;
00092     if (rv < 0)
00093       rv = pickGL (_pickTarget, _mousePos, _nodeIdx, _targetIdx, _hitPointPtr);
00094     // printf ("GLPicking took %d msec\n",time.restart ());
00095 
00096     // if (rv > 0 && (node != _nodeIdx || target != _targetIdx))
00097     //   printf ("***** Picking difference Color %d/%d GL %d/%d\n",node, target, _nodeIdx, _targetIdx);
00098     if (rv > 0)
00099       return rv;
00100   }
00101   return false;
00102 }
00103 
00104 
00105 //-----------------------------------------------------------------------------
00106 
00107 int glViewer::pickColor( ACG::SceneGraph::PickTarget _pickTarget,
00108                          const QPoint&               _mousePos,
00109                          unsigned int&               _nodeIdx,
00110                          unsigned int&               _targetIdx,
00111                          ACG::Vec3d*                 _hitPointPtr )
00112 {
00113   GLint         w = glWidth(),
00114                 h = glHeight(),
00115                 l = scenePos().x(),
00116                 b = scene()->height () - scenePos().y() - h,
00117                 x = _mousePos.x(),
00118                 y = scene()->height () - _mousePos.y(),
00119                 pW = 1,
00120                 pH = 1;
00121   GLubyte       pixels[9][4];
00122   GLfloat       depths[9];
00123   int           hit = -1;
00124 
00125   // traversing order (center, top, bottom, ...)
00126   unsigned char order[9] = { 4, 7, 1, 3, 5, 0, 2, 6, 8 };
00127 
00128   if (pickCacheSupported_)
00129   {
00130     // delete pick cache if the size changed
00131     if (pickCache_ && pickCache_->size () != QSize (glWidth (), glHeight ()))
00132     {
00133       delete pickCache_;
00134       pickCache_ = NULL;
00135     }
00136     // create a new pick cache frambuffer object
00137     if (!pickCache_)
00138     {
00139       pickCache_ = new QGLFramebufferObject (glWidth (), glHeight (), QGLFramebufferObject::Depth);
00140       if (!pickCache_->isValid ())
00141       {
00142         pickCacheSupported_ = false;
00143         delete pickCache_;
00144         pickCache_ = NULL;
00145       }
00146     }
00147     if (pickCache_)
00148     {
00149       // the viewport for the framebuffer object
00150       l = 0;
00151       b = 0;
00152       x = _mousePos.x() - scenePos().x();
00153       y = glHeight() - (_mousePos.y() - scenePos().y());
00154 
00155       // we can only pick inside of our window
00156       if (x < 0 || y < 0 || x >= (int)glWidth() || y >= (int)glHeight())
00157         return 0;
00158 
00159       pickCache_->bind ();
00160     }
00161   }
00162 
00163   const ACG::GLMatrixd&  modelview  = properties_.glState().modelview();
00164   const ACG::GLMatrixd&  projection = properties_.glState().projection();
00165 
00166   ACG::Vec4f clear_color = properties_.glState().clear_color();
00167   properties_.glState().set_clear_color (ACG::Vec4f (0.0, 0.0, 0.0, 0.0));
00168 
00169   // prepare GL state
00170   makeCurrent();
00171 
00172   glViewport (l, b, w, h);
00173   glMatrixMode(GL_PROJECTION);
00174   glLoadIdentity();
00175 
00176   glMultMatrixd(projection.get_raw_data());
00177   glMatrixMode(GL_MODELVIEW);
00178   glLoadMatrixd(modelview.get_raw_data());
00179   glDisable(GL_LIGHTING);
00180   glDisable(GL_BLEND);
00181   glEnable(GL_DEPTH_TEST);
00182   glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
00183   properties_.glState().pick_init (true);
00184 
00185   // do the picking
00186   ACG::SceneGraph::PickAction action(properties_.glState(), _pickTarget, properties_.drawMode());
00187   ACG::SceneGraph::traverse(sceneGraphRoot_, action);
00188 
00189   // restore GL state
00190   glMatrixMode( GL_PROJECTION );
00191   glLoadMatrixd(projection.get_raw_data());
00192   glMatrixMode( GL_MODELVIEW );
00193   glLoadMatrixd(modelview.get_raw_data());
00194   glEnable(GL_LIGHTING);
00195 
00196   properties_.glState().set_clear_color (clear_color);
00197 
00198   if (properties_.glState().pick_error ())
00199   {
00200     if (pickCache_ && pickCache_->isBound ())
00201       pickCache_->release ();
00202     return -1;
00203   }
00204 
00205   glPixelStorei(GL_PACK_ALIGNMENT, 1);
00206   glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
00207 
00208   // we can only read inside our viewport
00209   if (x + 1 < w)
00210     pW++;
00211 
00212   if (y + 1 < h)
00213     pH++;
00214 
00215   if (x > 0)
00216   {
00217     x--;
00218     pW++;
00219   }
00220   if (y > 0)
00221   {
00222     y--;
00223     pH++;
00224   }
00225 
00226   if (pH != 3 || pW != 3)
00227   {
00228     // initialize unused values with 0
00229     for (int i = 0; i < 9; i++)
00230     {
00231       pixels[i][0] = 0;
00232       pixels[i][1] = 0;
00233       pixels[i][2] = 0;
00234       pixels[i][3] = 0;
00235       depths[i] = 0.0;
00236     }
00237   }
00238 
00239   // read from framebuffer
00240   glReadPixels (x, y, pW, pH, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
00241   glReadPixels (x, y, pW, pH, GL_DEPTH_COMPONENT, GL_FLOAT, depths);
00242 
00243   // unbind pick cache
00244   if (pickCache_ && pickCache_->isBound ())
00245   {
00246     pickCache_->release ();
00247     updatePickCache_ = false;
00248     pickCacheTarget_ = _pickTarget;
00249   }
00250 
00251   // get first found pixel
00252   for (int i = 0; i < 9; i++)
00253   {
00254     if (hit < 0 && (pixels[order[i]][2] != 0 || pixels[order[i]][1] != 0 || pixels[order[i]][0] != 0 || pixels[order[i]][3] != 0))
00255     {
00256       hit = order[i];
00257       break;
00258     }
00259   }
00260 
00261   if (hit < 0)
00262     return 0;
00263 
00264 
00265   ACG::Vec4uc rgba;
00266   rgba[0] = pixels[hit][0];
00267   rgba[1] = pixels[hit][1];
00268   rgba[2] = pixels[hit][2];
00269   rgba[3] = pixels[hit][3];
00270 
00271   std::vector<unsigned int> rv = properties_.glState().pick_color_to_stack (rgba);
00272 
00273   // something wrong with the color stack ?
00274   if (rv.size () < 2)
00275     return -1;
00276 
00277   _nodeIdx   = rv[1];
00278   _targetIdx = rv[0];
00279 
00280 //   // Debug Code to visualize picking cache ( DO NOT REMOVE!!!! Jan )
00281 //   QImage murks(glWidth (),glHeight (),QImage::Format_ARGB32);
00282 //   murks = pickCache_->toImage();
00283 //   for ( int i = 0 ; i < glWidth() ; ++i ) 
00284 //     for ( int j = 0 ; j < glHeight() ; ++j )  {
00285 //       QColor bla (murks.pixel(i,j));
00286 //       bla.setAlpha(255);
00287 //       murks.setPixel(i,j,bla.rgba());
00288 //     }
00289 //   murks.save("murks.png");
00290 
00291   if (_hitPointPtr)
00292   {
00293     *_hitPointPtr = properties_.glState().unproject (
00294       ACG::Vec3d(_mousePos.x(), scene()->height () - _mousePos.y(),depths[hit]));
00295   }
00296 
00297   return 1;
00298 }
00299 
00300 //-----------------------------------------------------------------------------
00301 
00302 int glViewer::pickFromCache( ACG::SceneGraph::PickTarget _pickTarget,
00303                              const QPoint&               _mousePos,
00304                              unsigned int&               _nodeIdx,
00305                              unsigned int&               _targetIdx,
00306                              ACG::Vec3d*                 _hitPointPtr )
00307 {
00308   // do we need an update?
00309   if (!pickCacheSupported_ || updatePickCache_ || !pickCache_ ||
00310       pickCacheTarget_ != _pickTarget)
00311     return -1;
00312 
00313   GLint         x = _mousePos.x() - scenePos().x(),
00314                 y = glHeight() - (_mousePos.y() - scenePos().y()),
00315                 pW = 1,
00316                 pH = 1;
00317   GLubyte       pixels[9][4];
00318   GLfloat       depths[9];
00319   int           hit = -1;
00320 
00321   // traversing order (center, top, bottom, ...)
00322   unsigned char order[9] = { 4, 7, 1, 3, 5, 0, 2, 6, 8 };
00323 
00324   // can't pick outside
00325   if (x < 0 || y < 0 || x >= (int)glWidth() || y >= (int)glHeight())
00326     return 0;
00327 
00328   // bind cache framebuffer object
00329   pickCache_->bind ();
00330 
00331   glPixelStorei(GL_PACK_ALIGNMENT, 1);
00332   glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
00333 
00334   // we can only read inside our viewport
00335   if (x + 1 < (int)glWidth ())
00336     pW++;
00337 
00338   if (y + 1 < (int)glHeight ())
00339     pH++;
00340 
00341   if (x > 0)
00342   {
00343     x--;
00344     pW++;
00345   }
00346   if (y > 0)
00347   {
00348     y--;
00349     pH++;
00350   }
00351 
00352   if (pH != 3 || pW != 3)
00353   {
00354     // initialize unused values with 0
00355     for (int i = 0; i < 9; i++)
00356     {
00357       pixels[i][0] = 0;
00358       pixels[i][1] = 0;
00359       pixels[i][2] = 0;
00360       pixels[i][3] = 0;
00361       depths[i] = 0.0;
00362     }
00363   }
00364 
00365   // read from framebuffer
00366   glReadPixels (x, y, pW, pH, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
00367   glReadPixels (x, y, pW, pH, GL_DEPTH_COMPONENT, GL_FLOAT, depths);
00368 
00369   // unbind
00370   pickCache_->release ();
00371 
00372   // get first found pixel
00373   for (int i = 0; i < 9; i++)
00374   {
00375     if (hit < 0 && (pixels[order[i]][2] != 0 || pixels[order[i]][1] != 0 || pixels[order[i]][0] != 0 || pixels[order[i]][3] != 0))
00376     {
00377       hit = order[i];
00378       break;
00379     }
00380   }
00381 
00382   if (hit < 0)
00383     return 0;
00384 
00385 
00386   ACG::Vec4uc rgba;
00387   rgba[0] = pixels[hit][0];
00388   rgba[1] = pixels[hit][1];
00389   rgba[2] = pixels[hit][2];
00390   rgba[3] = pixels[hit][3];
00391 
00392   std::vector<unsigned int> rv = properties_.glState().pick_color_to_stack (rgba);
00393 
00394   // something wrong with the color stack ?
00395   if (rv.size () < 2)
00396     return -1;
00397 
00398   _nodeIdx   = rv[1];
00399   _targetIdx = rv[0];
00400 
00401   if (_hitPointPtr)
00402   {
00403     *_hitPointPtr = properties_.glState().unproject(
00404       ACG::Vec3d(_mousePos.x(), scene()->height () - _mousePos.y(),depths[hit]));
00405   }
00406 
00407   return 1;
00408 }
00409 
00410 //-----------------------------------------------------------------------------
00411 
00412 bool glViewer::pickGL( ACG::SceneGraph::PickTarget _pickTarget,
00413                        const QPoint&               _mousePos,
00414                        unsigned int&               _nodeIdx,
00415                        unsigned int&               _targetIdx,
00416                        ACG::Vec3d*                 _hitPointPtr )
00417 {
00418   GLint         w = glWidth(),
00419                 h = glHeight(),
00420                 l = scenePos().x(),
00421                 b = scene()->height () - scenePos().y() - h,
00422                 x = _mousePos.x(),
00423                 y = scene()->height () - _mousePos.y();
00424   GLint         viewport[4] = {l,b,w,h};
00425   GLuint        selectionBuffer[ SELECTION_BUFFER_SIZE ],
00426                 nameBuffer[ NAME_STACK_SIZE ];
00427 
00428   const ACG::GLMatrixd&  modelview  = properties_.glState().modelview();
00429   const ACG::GLMatrixd&  projection = properties_.glState().projection();
00430 
00431   // prepare GL state
00432   makeCurrent();
00433 
00434   glSelectBuffer( SELECTION_BUFFER_SIZE, selectionBuffer );
00435   glRenderMode(GL_SELECT);
00436   glMatrixMode(GL_PROJECTION);
00437   glLoadIdentity();
00438   gluPickMatrix((GLdouble) x, (GLdouble) y, 3, 3, viewport);
00439   glMultMatrixd(projection.get_raw_data());
00440   glMatrixMode(GL_MODELVIEW);
00441   glLoadMatrixd(modelview.get_raw_data());
00442   glDisable(GL_LIGHTING);
00443   glDisable(GL_BLEND);
00444   glClear(GL_DEPTH_BUFFER_BIT);
00445   properties_.glState().pick_init (false);
00446 
00447   // do the picking
00448   ACG::SceneGraph::PickAction action(properties_.glState(), _pickTarget, properties_.drawMode());
00449   ACG::SceneGraph::traverse(sceneGraphRoot_, action);
00450   int hits = glRenderMode(GL_RENDER);
00451 
00452   // restore GL state
00453   glMatrixMode( GL_PROJECTION );
00454   glLoadMatrixd(projection.get_raw_data());
00455   glMatrixMode( GL_MODELVIEW );
00456   glLoadMatrixd(modelview.get_raw_data());
00457   glEnable(GL_LIGHTING);
00458   glEnable(GL_BLEND);
00459 
00460   // process hit record
00461   if ( hits > 0 )
00462   {
00463     GLuint *ptr = selectionBuffer,
00464     num_names,
00465     z,
00466     min_z=~(0u),
00467     max_z=0;
00468 
00469     for (int i=0; i<hits; ++i)
00470     {
00471       num_names = *ptr++;
00472       if ( num_names != NAME_STACK_SIZE )
00473       {
00474         std::cerr << "glViewer::pick() : namestack error\n\n";
00475         return false;
00476       }
00477 
00478       if ( (z = *ptr++) < min_z )
00479       {
00480         min_z = z;
00481         max_z = *ptr++;
00482         for (unsigned int j=0; j<num_names; ++j)
00483           nameBuffer[j] = *ptr++;
00484       }
00485       else ptr += 1+num_names;
00486     }
00487 
00488     _nodeIdx   = nameBuffer[0];
00489     _targetIdx = nameBuffer[1];
00490 
00491     if (_hitPointPtr)
00492     {
00493       GLuint zscale=~(0u);
00494       GLdouble min_zz = ((GLdouble)min_z) / ((GLdouble)zscale);
00495       GLdouble max_zz = ((GLdouble)max_z) / ((GLdouble)zscale);
00496       GLdouble zz     = 0.5F * (min_zz + max_zz);
00497       *_hitPointPtr = properties_.glState().unproject(ACG::Vec3d(x,y,zz));
00498     }
00499 
00500     return true;
00501   }
00502   else if (hits < 0)
00503     std::cerr << "glViewer::pick() : selection buffer overflow\n\n";
00504 
00505   return false;
00506 }
00507 
00508 //-----------------------------------------------------------------------------
00509 
00510 bool glViewer::pick_region( ACG::SceneGraph::PickTarget                _pickTarget,
00511                             const QRegion&                             _region,
00512                             QList<QPair<unsigned int, unsigned int> >& _list)
00513 {
00514   QRect    rect = _region.boundingRect();
00515   GLint    w = glWidth(),
00516            h = glHeight(),
00517            l = scenePos().x(),
00518            b = scene()->height () - scenePos().y() - h,
00519            x = rect.x(),
00520            y = scene()->height () - rect.bottom();
00521   GLubyte* buffer;
00522 
00523   if (pickCacheSupported_)
00524   {
00525     // delete pick cache if the size changed
00526     if (pickCache_ && pickCache_->size () != QSize (glWidth (), glHeight ()))
00527     {
00528       delete pickCache_;
00529       pickCache_ = NULL;
00530     }
00531     // create a new pick cache frambuffer object
00532     if (!pickCache_)
00533     {
00534       pickCache_ = new QGLFramebufferObject (glWidth (), glHeight (), QGLFramebufferObject::Depth);
00535       if (!pickCache_->isValid ())
00536       {
00537         pickCacheSupported_ = false;
00538         delete pickCache_;
00539         pickCache_ = NULL;
00540       }
00541     }
00542     if (pickCache_)
00543     {
00544       // the viewport for the framebuffer object
00545       l = 0;
00546       b = 0;
00547       x = rect.x() - scenePos().x();
00548       y = glHeight() - (rect.bottom() - scenePos().y());
00549 
00550       // we can only pick inside of our window
00551       if (x < 0 || y < 0 || x >= (int)glWidth() || y >= (int)glHeight())
00552         return 0;
00553 
00554       pickCache_->bind ();
00555     }
00556   }
00557 
00558   const ACG::GLMatrixd&  modelview  = properties_.glState().modelview();
00559   const ACG::GLMatrixd&  projection = properties_.glState().projection();
00560 
00561   ACG::Vec4f clear_color = properties_.glState().clear_color();
00562   properties_.glState().set_clear_color (ACG::Vec4f (0.0, 0.0, 0.0, 0.0));
00563 
00564   // prepare GL state
00565   makeCurrent();
00566 
00567   glViewport (l, b, w, h);
00568   glMatrixMode(GL_PROJECTION);
00569   glLoadIdentity();
00570 
00571   glMultMatrixd(projection.get_raw_data());
00572   glMatrixMode(GL_MODELVIEW);
00573   glLoadMatrixd(modelview.get_raw_data());
00574   glDisable(GL_LIGHTING);
00575   glDisable(GL_BLEND);
00576   glEnable(GL_DEPTH_TEST);
00577   glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
00578   properties_.glState().pick_init (true);
00579 
00580   // do the picking
00581   ACG::SceneGraph::PickAction action(properties_.glState(), _pickTarget, properties_.drawMode());
00582   ACG::SceneGraph::traverse(sceneGraphRoot_, action);
00583 
00584   // restore GL state
00585   glMatrixMode( GL_PROJECTION );
00586   glLoadMatrixd(projection.get_raw_data());
00587   glMatrixMode( GL_MODELVIEW );
00588   glLoadMatrixd(modelview.get_raw_data());
00589   glEnable(GL_LIGHTING);
00590   glEnable(GL_BLEND);
00591 
00592   properties_.glState().set_clear_color (clear_color);
00593 
00594   if (properties_.glState().pick_error ())
00595   {
00596     if (pickCache_ && pickCache_->isBound ())
00597       pickCache_->release ();
00598     return -1;
00599   }
00600 
00601   buffer = new GLubyte[4 * rect.width() * rect.height()];
00602 
00603   glPixelStorei(GL_PACK_ALIGNMENT, 1);
00604   glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
00605 
00606   glReadPixels (x, y, rect.width(),
00607                 rect.height(), GL_RGBA, GL_UNSIGNED_BYTE, buffer);
00608 
00609   QSet<QPair<unsigned int, unsigned int> > found;
00610 
00611   for (int y = 0; y < rect.height (); y++)
00612     for (int x = 0; x < rect.width (); x++)
00613     {
00614       if (_region.contains (QPoint (rect.x() + x, rect.y() + y)))
00615       {
00616         int bPos = (((rect.height () - (y + 1)) * rect.width ()) + x) * 4;
00617         if (buffer[bPos + 2] != 0 || buffer[bPos + 1] != 0 || buffer[bPos] != 0 || buffer[bPos + 3] != 0)
00618         {
00619           ACG::Vec4uc rgba;
00620           rgba[0] = buffer[bPos];
00621           rgba[1] = buffer[bPos + 1];
00622           rgba[2] = buffer[bPos + 2];
00623           rgba[3] = buffer[bPos + 3];
00624 
00625           std::vector<unsigned int> rv = properties_.glState().pick_color_to_stack (rgba);
00626           if (rv.size () < 2)
00627             continue;
00628 
00629           found << QPair<unsigned int, unsigned int>(rv[1], rv[0]);
00630         }
00631       }
00632     }
00633 
00634   delete buffer;
00635   _list = found.toList();
00636 
00637   // unbind pick cache
00638   if (pickCache_ && pickCache_->isBound ())
00639   {
00640     pickCache_->release ();
00641     updatePickCache_ = false;
00642     pickCacheTarget_ = _pickTarget;
00643   }
00644 
00645   return true;
00646 }
00647 
00648 //-----------------------------------------------------------------------------
00649 
00650 bool
00651 glViewer::
00652 fast_pick( const QPoint&  _mousePos,
00653            ACG::Vec3d&    _hitPoint )
00654 {
00655   // get x,y,z values of pixel
00656   GLint     x(_mousePos.x()), y(glHeight() - _mousePos.y());
00657   GLfloat   z;
00658 
00659 
00660   makeCurrent();
00661   glPixelStorei(GL_PACK_ALIGNMENT, 1);
00662   glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
00663   glReadPixels(x, y, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &z);
00664 
00665 
00666   if (z < 0.99999)
00667   {
00668     _hitPoint = properties_.glState().unproject( ACG::Vec3d(x, y, z) );
00669     return true;
00670   }
00671   else return false;
00672 }
00673 
00674 
00675 //=============================================================================
00676 
00677 //=============================================================================

acg pic Project OpenFlipper, ©  Computer Graphics Group, RWTH Aachen. Documentation generated using doxygen .