00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054 #include "QtBaseViewer.hh"
00055 #include "QtGLGraphicsScene.hh"
00056 #include "QtGLGraphicsView.hh"
00057
00058
00059
00060 namespace ACG {
00061 namespace QtWidgets {
00062
00063
00064
00065 static const unsigned int SELECTION_BUFFER_SIZE = 10000;
00066 static const unsigned int NAME_STACK_SIZE = 2;
00067
00068
00069
00070
00071 void QtBaseViewer::renderPicking(bool _renderPicking, ACG::SceneGraph::PickTarget _mode) {
00072 renderPicking_ = _renderPicking;
00073 pickRendererMode_ = _mode;
00074 }
00075
00076
00077
00078
00079 bool QtBaseViewer::pick( SceneGraph::PickTarget _pickTarget,
00080 const QPoint& _mousePos,
00081 unsigned int& _nodeIdx,
00082 unsigned int& _targetIdx,
00083 Vec3d* _hitPointPtr )
00084 {
00085 if (sceneGraphRoot_)
00086 {
00087 GLint w = glWidth(),
00088 h = glHeight(),
00089 x = _mousePos.x(),
00090 y = h - _mousePos.y();
00091 GLint viewport[4] = {0,0,w,h};
00092 GLuint selectionBuffer[ SELECTION_BUFFER_SIZE ],
00093 nameBuffer[ NAME_STACK_SIZE ];
00094
00095 const GLMatrixd& modelview = glstate_->modelview();
00096 const GLMatrixd& projection = glstate_->projection();
00097
00098
00099
00100 makeCurrent();
00101
00102 glSelectBuffer( SELECTION_BUFFER_SIZE, selectionBuffer );
00103 glRenderMode(GL_SELECT);
00104 glMatrixMode(GL_PROJECTION);
00105 glLoadIdentity();
00106 gluPickMatrix((GLdouble) x, (GLdouble) y, 3, 3, viewport);
00107 glMultMatrixd(projection.get_raw_data());
00108 glMatrixMode(GL_MODELVIEW);
00109 glLoadMatrixd(modelview.get_raw_data());
00110 glDisable(GL_LIGHTING);
00111 glClear(GL_DEPTH_BUFFER_BIT);
00112 glstate_->pick_init (false);
00113
00114
00115 SceneGraph::PickAction action(*glstate_, _pickTarget, curDrawMode_);
00116 SceneGraph::traverse(sceneGraphRoot_, action);
00117 int hits = glRenderMode(GL_RENDER);
00118
00119
00120 glMatrixMode( GL_PROJECTION );
00121 glLoadMatrixd(projection.get_raw_data());
00122 glMatrixMode( GL_MODELVIEW );
00123 glLoadMatrixd(modelview.get_raw_data());
00124 glEnable(GL_LIGHTING);
00125
00126
00127
00128 if ( hits > 0 )
00129 {
00130 GLuint *ptr = selectionBuffer,
00131 num_names,
00132 z,
00133 min_z=~(0u),
00134 max_z=0;
00135
00136 for (int i=0; i<hits; ++i)
00137 {
00138 num_names = *ptr++;
00139 if ( num_names != NAME_STACK_SIZE )
00140 {
00141 std::cerr << "QtBaseViewer::pick() : namestack error\n\n";
00142 return false;
00143 }
00144
00145 if ( (z = *ptr++) < min_z )
00146 {
00147 min_z = z;
00148 max_z = *ptr++;
00149 for (unsigned int j=0; j<num_names; ++j)
00150 nameBuffer[j] = *ptr++;
00151 }
00152 else ptr += 1+num_names;
00153 }
00154
00155 _nodeIdx = nameBuffer[0];
00156 _targetIdx = nameBuffer[1];
00157
00158 if (_hitPointPtr)
00159 {
00160 GLuint zscale=~(0u);
00161 GLdouble min_zz = ((GLdouble)min_z) / ((GLdouble)zscale);
00162 GLdouble max_zz = ((GLdouble)max_z) / ((GLdouble)zscale);
00163 GLdouble zz = 0.5F * (min_zz + max_zz);
00164 *_hitPointPtr = glstate_->unproject(Vec3d(x,y,zz));
00165 }
00166
00167 return true;
00168 }
00169 else if (hits < 0)
00170 std::cerr << "QtBaseViewer::pick() : selection buffer overflow\n\n";
00171 }
00172
00173 return false;
00174 }
00175
00176
00177
00178
00179
00180 bool
00181 QtBaseViewer::
00182 fast_pick( const QPoint& _mousePos,
00183 Vec3d& _hitPoint )
00184 {
00185
00186 GLint x(_mousePos.x()), y(glHeight() - _mousePos.y());
00187 GLfloat z;
00188
00189
00190 makeCurrent();
00191 glPixelStorei(GL_PACK_ALIGNMENT, 1);
00192 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
00193 glReadPixels(x, y, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &z);
00194
00195
00196 if (z < 0.99999)
00197 {
00198 _hitPoint = glstate_->unproject( Vec3d(x, y, z) );
00199 return true;
00200 }
00201 else return false;
00202 }
00203
00204
00205
00206
00207 void QtBaseViewer::pickMode( int _id )
00208 {
00209 if (_id < (int) pick_modes_.size() )
00210 {
00211 pick_mode_idx_ = _id;
00212 pick_mode_name_ = pick_modes_[pick_mode_idx_].name;
00213
00214
00215 if ( actionMode_ == PickingMode )
00216 trackMouse(pick_modes_[pick_mode_idx_].tracking);
00217
00218
00219 if ( actionMode_ == PickingMode )
00220 glView_->setCursor(pick_modes_[pick_mode_idx_].cursor);
00221
00222
00223 emit(signalPickModeChanged(pick_mode_name_));
00224 }
00225 }
00226
00227
00228
00229
00230
00231 void QtBaseViewer::addPickMode(const std::string& _name,
00232 bool _tracking,
00233 int _pos,
00234 bool _visible,
00235 QCursor _cursor)
00236 {
00237 if ((unsigned int)_pos < pick_modes_.size())
00238 {
00239 std::vector<PickMode>::iterator it = pick_modes_.begin();
00240 it += _pos+1;
00241 pick_modes_.insert(it, PickMode(_name, _tracking, _visible, _cursor));
00242 }
00243 else
00244 pick_modes_.push_back(PickMode(_name, _tracking, _visible, _cursor));
00245
00246 updatePickMenu();
00247 }
00248
00249
00250
00251 void QtBaseViewer::setPickModeCursor(const std::string& _name, QCursor _cursor)
00252 {
00253 for (uint i=0; i < pick_modes_.size(); i++)
00254 if ( pick_modes_[i].name == _name ){
00255 pick_modes_[i].cursor = _cursor;
00256
00257
00258 if (pick_mode_name_ == _name && actionMode_ == PickingMode)
00259 glView_->setCursor(_cursor);
00260 break;
00261 }
00262 }
00263
00264
00265
00266 void QtBaseViewer::setPickModeMouseTracking(const std::string& _name, bool _mouseTracking)
00267 {
00268 for (uint i=0; i < pick_modes_.size(); i++)
00269 if ( pick_modes_[i].name == _name ){
00270 pick_modes_[i].tracking = _mouseTracking;
00271
00272
00273 if (pick_mode_name_ == _name && actionMode_ == PickingMode)
00274 trackMouse(_mouseTracking);
00275 break;
00276 }
00277 }
00278
00279
00280
00281
00282 void QtBaseViewer::clearPickModes()
00283 {
00284 pick_modes_.clear();
00285 pick_mode_idx_ = -1;
00286 pick_mode_name_ = "";
00287 updatePickMenu();
00288 }
00289
00290
00291
00292
00293
00294 const std::string& QtBaseViewer::pickMode() const
00295 {
00296 return pick_mode_name_;
00297 }
00298
00299
00300
00301
00302
00303 void QtBaseViewer::pickMode(const std::string& _name)
00304 {
00305 for (unsigned int i=0; i<pick_modes_.size(); ++i)
00306 {
00307 if (pick_modes_[i].name == _name)
00308 {
00309 pickMode( i );
00310 updatePickMenu();
00311 return;
00312 }
00313 }
00314 }
00315
00316
00317
00318 void QtBaseViewer::pickingMode() {
00319 actionMode(PickingMode);
00320 }
00321
00322
00323
00324 }
00325 }
00326