QtExaminerViewer.cc
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 "QtExaminerViewer.hh"
00055
00056 #include <QTimer>
00057 #include <QPushButton>
00058 #include <QClipboard>
00059 #include <QApplication>
00060 #include <QInputDialog>
00061 #include <QStatusBar>
00062
00063 #include <QMouseEvent>
00064 #include <QWheelEvent>
00065 #include <QEvent>
00066
00067 #ifdef max
00068 # undef max
00069 #endif
00070
00071
00072
00073
00074
00075 namespace ACG {
00076 namespace QtWidgets {
00077
00078
00079
00080
00081
00082 QtExaminerViewer::QtExaminerViewer( QWidget* _parent,
00083 const char* _name,
00084 QStatusBar *_statusBar,
00085 const QGLFormat* _format,
00086 const QtBaseViewer* _share,
00087 Options _options ) :
00088 QtBaseViewer(_parent, _name, _statusBar, _format, _share, _options)
00089 {
00090
00091
00092 timer_ = new QTimer( this );
00093 connect( timer_, SIGNAL(timeout()), this, SLOT( slotAnimation()) );
00094
00095 allowRotation_ = true;
00096
00097
00098 wZoomFactor_ = 1.0;
00099 wZoomFactorShift_ = 0.2;
00100 }
00101
00102
00103
00104
00105
00106 void
00107 QtExaminerViewer::viewMouseEvent(QMouseEvent* _event)
00108 {
00109 switch (_event->type())
00110 {
00111 case QEvent::MouseButtonPress:
00112 {
00113
00114 if (_event->modifiers() & Qt::ShiftModifier)
00115 {
00116 Vec3d c;
00117 if (fast_pick(_event->pos(), c))
00118 {
00119 trackball_center_ = c;
00120 trackball_radius_ = std::max(scene_radius_, (c-glState().eye()).norm()*0.9f);
00121 }
00122 }
00123
00124 lastPoint_hitSphere_ = mapToSphere( lastPoint2D_=_event->pos(),
00125 lastPoint3D_ );
00126 isRotating_ = true;
00127 timer_->stop();
00128
00129
00130 break;
00131 }
00132
00133
00134 case QEvent::MouseButtonDblClick:
00135 {
00136 if (allowRotation_)
00137 flyTo(_event->pos(), _event->button()==Qt::MidButton);
00138 break;
00139 }
00140
00141
00142 case QEvent::MouseMove:
00143 {
00144 double factor = 1.0;
00145
00146 if (_event->modifiers() == Qt::ShiftModifier)
00147 factor = wZoomFactorShift_;
00148
00149
00150 if (_event->buttons() & (Qt::LeftButton | Qt::MidButton))
00151 {
00152 QPoint newPoint2D = _event->pos();
00153
00154 if ( (newPoint2D.x()<0) || (newPoint2D.x() > (int)glWidth()) ||
00155 (newPoint2D.y()<0) || (newPoint2D.y() > (int)glHeight()) )
00156 return;
00157
00158 double value_x, value_y;
00159 Vec3d newPoint3D;
00160 bool newPoint_hitSphere = mapToSphere( newPoint2D, newPoint3D );
00161
00162 makeCurrent();
00163
00164
00165 if ( (_event->buttons() & Qt::LeftButton) &&
00166 (_event->buttons() & Qt::MidButton))
00167 {
00168 switch (projectionMode())
00169 {
00170 case PERSPECTIVE_PROJECTION:
00171 {
00172 value_y = scene_radius_ * ((newPoint2D.y() - lastPoint2D_.y())) * 3.0 / (double) glHeight();
00173 translate( Vec3d(0.0, 0.0, value_y * factor ) );
00174 updateGL();
00175 break;
00176 }
00177
00178 case ORTHOGRAPHIC_PROJECTION:
00179 {
00180 value_y = ((newPoint2D.y() - lastPoint2D_.y())) * orthoWidth_ / (double) glHeight();
00181 orthoWidth_ -= value_y * factor;
00182 updateProjectionMatrix();
00183 updateGL();
00184 break;
00185 }
00186 }
00187 }
00188
00189
00190 else if (_event->buttons() & Qt::MidButton)
00191 {
00192 value_x = scene_radius_ * ((newPoint2D.x() - lastPoint2D_.x())) * 2.0 / (double) glWidth();
00193 value_y = scene_radius_ * ((newPoint2D.y() - lastPoint2D_.y())) * 2.0 / (double) glHeight();
00194 translate( Vec3d(value_x * factor , -value_y * factor , 0.0) );
00195 }
00196
00197
00198 else if (allowRotation_ && (_event->buttons() & Qt::LeftButton) )
00199 {
00200 Vec3d axis(1.0,0.0,0.0);
00201 double angle(0.0);
00202
00203 if ( lastPoint_hitSphere_ ) {
00204
00205 if ( ( newPoint_hitSphere = mapToSphere( newPoint2D,
00206 newPoint3D ) ) ) {
00207 axis = lastPoint3D_ % newPoint3D;
00208 double cos_angle = ( lastPoint3D_ | newPoint3D );
00209 if ( fabs(cos_angle) < 1.0 ) {
00210 angle = acos( cos_angle ) * 180.0 / M_PI * factor ;
00211 angle *= 2.0;
00212 }
00213 }
00214
00215 rotate(axis, angle);
00216
00217 }
00218
00219 lastRotationAxis_ = axis;
00220 lastRotationAngle_ = angle;
00221 }
00222
00223 lastPoint2D_ = newPoint2D;
00224 lastPoint3D_ = newPoint3D;
00225 lastPoint_hitSphere_ = newPoint_hitSphere;
00226
00227 updateGL();
00228 lastMoveTime_.restart();
00229 }
00230 break;
00231 }
00232
00233
00234
00235 case QEvent::MouseButtonRelease:
00236 {
00237 lastPoint_hitSphere_ = false;
00238
00239
00240 if ( isRotating_ &&
00241 (_event->button() == Qt::LeftButton) &&
00242 (!(_event->buttons() & Qt::MidButton)) &&
00243 (lastMoveTime_.elapsed() < 10) &&
00244 animation() )
00245 timer_->start(0);
00246 break;
00247 }
00248
00249 default:
00250 break;
00251 }
00252
00253
00254
00255 emit(signalSetView(glstate_->modelview(), glstate_->inverse_modelview()));
00256 }
00257
00258
00259
00260
00261
00262 void
00263 QtExaminerViewer::lightMouseEvent(QMouseEvent* _event)
00264 {
00265 switch (_event->type())
00266 {
00267 case QEvent::MouseButtonPress:
00268 {
00269 lastPoint_hitSphere_ = mapToSphere( lastPoint2D_=_event->pos(),
00270 lastPoint3D_ );
00271 isRotating_ = true;
00272 timer_->stop();
00273 break;
00274 }
00275
00276
00277 case QEvent::MouseMove:
00278 {
00279
00280 if (_event->buttons() & Qt::LeftButton)
00281 {
00282 QPoint newPoint2D = _event->pos();
00283
00284 if ( (newPoint2D.x()<0) || (newPoint2D.x() > (int)glWidth()) ||
00285 (newPoint2D.y()<0) || (newPoint2D.y() > (int)glHeight()) )
00286 return;
00287
00288
00289 Vec3d newPoint3D;
00290 bool newPoint_hitSphere = mapToSphere( newPoint2D, newPoint3D );
00291
00292 makeCurrent();
00293
00294 Vec3d axis(1.0,0.0,0.0);
00295 double angle(0.0);
00296
00297 if ( lastPoint_hitSphere_ )
00298 {
00299 if ( ( newPoint_hitSphere = mapToSphere( newPoint2D, newPoint3D ) ) )
00300 {
00301 axis = lastPoint3D_ % newPoint3D;
00302 double cos_angle = ( lastPoint3D_ | newPoint3D );
00303 if ( fabs(cos_angle) < 1.0 ) {
00304 angle = acos( cos_angle ) * 180.0 / M_PI;
00305 angle *= 2.0;
00306 }
00307 }
00308 rotate_lights(axis, angle);
00309 }
00310
00311 lastPoint2D_ = newPoint2D;
00312 lastPoint3D_ = newPoint3D;
00313 lastPoint_hitSphere_ = newPoint_hitSphere;
00314
00315 updateGL();
00316 }
00317 break;
00318 }
00319
00320
00321 default:
00322 break;
00323 }
00324 }
00325
00326
00327
00328
00329 double QtExaminerViewer::wheelZoomFactor(){
00330 return wZoomFactor_;
00331 }
00332
00333
00334
00335 double QtExaminerViewer::wheelZoomFactorShift(){
00336 return wZoomFactorShift_;
00337 }
00338
00339
00340
00341 void QtExaminerViewer::setWheelZoomFactor(double _factor){
00342 wZoomFactor_ = _factor;
00343 }
00344
00345
00346
00347 void QtExaminerViewer::setWheelZoomFactorShift(double _factor){
00348 wZoomFactorShift_ = _factor;
00349 }
00350
00351
00352
00353 void QtExaminerViewer::viewWheelEvent( QWheelEvent* _event)
00354 {
00355 double factor = wZoomFactor_;
00356
00357 if (_event->modifiers() == Qt::ShiftModifier)
00358 factor = wZoomFactorShift_;
00359
00360 switch (projectionMode())
00361 {
00362 case PERSPECTIVE_PROJECTION:
00363 {
00364 double d = -(double)_event->delta() / 120.0 * 0.2 * factor * trackball_radius_/3;
00365 translate( Vec3d(0.0, 0.0, d) );
00366 updateGL();
00367 break;
00368 }
00369
00370 case ORTHOGRAPHIC_PROJECTION:
00371 {
00372 double d = (double)_event->delta() / 120.0 * 0.2 * factor * orthoWidth_;
00373 orthoWidth_ += d;
00374 updateProjectionMatrix();
00375 updateGL();
00376 break;
00377 }
00378 }
00379
00380
00381
00382 emit(signalSetView(glstate_->modelview(), glstate_->inverse_modelview()));
00383 }
00384
00385
00386
00387
00388
00389 bool QtExaminerViewer::mapToSphere(const QPoint& _v2D, Vec3d& _v3D) const
00390 {
00391 if ( (_v2D.x() >= 0) && (_v2D.x() < (int)glWidth()) &&
00392 (_v2D.y() >= 0) && (_v2D.y() < (int)glHeight()) )
00393 {
00394 double x = (double)(_v2D.x() - ((double)glWidth() / 2.0)) / (double)glWidth();
00395 double y = (double)(((double)glHeight() / 2.0) - _v2D.y()) / (double)glHeight();
00396 double sinx = sin(M_PI * x * 0.5);
00397 double siny = sin(M_PI * y * 0.5);
00398 double sinx2siny2 = sinx * sinx + siny * siny;
00399
00400 _v3D[0] = sinx;
00401 _v3D[1] = siny;
00402 _v3D[2] = sinx2siny2 < 1.0 ? sqrt(1.0 - sinx2siny2) : 0.0;
00403
00404 return true;
00405 }
00406 else return false;
00407 }
00408
00409
00410
00411
00412
00413 void QtExaminerViewer::slotAnimation()
00414 {
00415 static int msecs=0, count=0;
00416 QTime t;
00417 t.start();
00418 makeCurrent();
00419 rotate( lastRotationAxis_, lastRotationAngle_ );
00420 updateGL();
00421
00422 if (!isUpdateLocked()) {
00423 msecs += t.elapsed();
00424 if (count==10) {
00425 assert(statusbar_!=0);
00426 char s[100];
00427 sprintf( s, "%.3f fps", (10000.0 / (float)msecs) );
00428 statusbar_->showMessage(s,2000);
00429 count = msecs = 0;
00430 }
00431 else
00432 ++count;
00433 }
00434 }
00435
00436
00437
00438 }
00439 }
00440