/* * QGLExaminerViewer.cpp * $Id: QGLExaminerViewer.cpp,v 1.12 2001/11/20 16:23:49 guenth Exp $ * * Copyright (C) 1999, 2000 Markus Janich * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * As a special exception to the GPL, the QGLViewer authors (Markus * Janich, Michael Meissner, Richard Guenther, Alexander Buck and Thomas * Woerner) give permission to link this program with Qt (non-)commercial * edition, and distribute the resulting executable, without including * the source code for the Qt (non-)commercial edition in the source * distribution. * */ // Description : Class QGLExaminerViewer // Purpose : Provides funcionality of a OpenGL viewer // Qt /////// #include #include #include #include #include #include #include // needed for qApp->quit() #include // needed for help messagebox #include // needed for what? ---- Right, for tooltips. #include #include #include // System /////////// #include // needed for 'getenv()' // Own /////////// #include "QGLExaminerViewer.h" #include "QToggleButton.h" #include "CCamera.h" #include "QCameraDrag.h" #include "QCameraDropSite.h" #ifndef M_PI #define M_PI 3.14159265358979323846 #endif // Function : QGLExaminerViewer // Parameters: bool viewertype // Purpose : Initializes all stuff that is unique to all constructors. // Comments : See docu for details. void QGLExaminerViewer::init(bool viewertype) /*********************************************************************/ { // initialize some members to default values m_nLastRotAngle = 0; m_fLeftButtonPressed = false; m_fMiddleButtonPressed = false; m_fToolTips = false; m_fOldBehave = false; // create submenu 'Functions' QPopupMenu *pSubFunctions = new QPopupMenu(getMainMenu()); Q_CHECK_PTR( pSubFunctions ); pSubFunctions->insertItem( tr("Home"), this, SLOT(sltGoHome()) ); pSubFunctions->insertItem( tr("Set Home"), this, SLOT(sltSetHome()) ); pSubFunctions->insertItem( tr("View All"), this, SLOT(sltViewAll()) ); insertItem( tr("Functions"), pSubFunctions ); // create submenu 'Preferences' QPopupMenu *pPreferences = new QPopupMenu(getMainMenu()); Q_CHECK_PTR(pPreferences); pPreferences->insertItem( tr("Refresh Rate"), this, SLOT(sltSetRefreshRate()) ); insertItem( tr("Preferences"), pPreferences ); m_nSelectionID = insertItem( tr("Selection on"), this, SLOT(sltMenuToggleRenderMode()) ); setItemChecked( m_nSelectionID, false ); m_nDecoID = insertItem( tr("Decoration on"), this, SLOT(sltToggleDeco()) ); m_nTTipsID = insertItem( tr("Tooltips on"), this, SLOT(sltToggleToolTips()) ); m_nSpinOnOffID = insertItem( tr("Spinning on"), this, SLOT(sltToggleSpinning()) ); setItemChecked( m_nSpinOnOffID, true); m_nSwitchBehaveID = insertItem( tr("Fix rotation around z-axis"), this, SLOT(sltSwitchBehave()) ); setItemChecked( m_nSwitchBehaveID, false); m_nStereoID = insertItem( tr("Stereo"), this, SLOT(sltToggleStereo()) ); setItemChecked( m_nStereoID, false); if(viewertype) { setItemChecked( m_nDecoID, true ); } if(!viewertype) { makeSimpleViewer(); } else { makeFullViewer(); } m_pqTimer = new QTimer(this); Q_CHECK_PTR( m_pqTimer ); connect( m_pqTimer, SIGNAL(timeout()), this, SLOT(sltCamRotStep()) ); m_pqTimeOut = new QTimer(this); Q_CHECK_PTR( m_pqTimeOut ); connect( m_pqTimeOut, SIGNAL(timeout()), this, SLOT(sltTimeOut()) ); } // Function : keyPressEvents // Parameters: QKeyEvent *event // Purpose : Implements a handler for keyPressEvents. // Comments : See docu for details. void QGLExaminerViewer::keyPressEvent(QKeyEvent *event) /*********************************************************************/ { CBoundingBox3D cBBox; CCamera *pCamera = getCameraPtr(); CP3D cEyePos = pCamera->getEyePos(); cBBox = pCamera->getBoundingBox(); m_cUp = pCamera->getViewUp(); m_cRight = pCamera->getViewRight(); m_cDir = pCamera->getViewDir(); switch(event->state()) { case NoButton: switch(event->key()) { case Key_I: QMessageBox::information( this, tr("Help. Here are the built in key definitions:"), tr("i : opens this box\n" "CURSOR_UP : rotate \"back\" around x-axis\n" "CURSOR_DOWN : rotate \"to the front\" around x-axis\n" "CURSOR_LEFT : rotate left around y-axis\n" "CURSOR_RIGHT : rotate right around y-axis\n" "a : view all\n" "s : set homecamera to current camera\n" "h : set current camera to homecamera\n" "p : toggle projectionmode\n" "+ : zoom in\n" "- : zoom out\n" "ESC or q : exit application\n" "CTRL+CURSOR_LEFT : translate to the left\n" "CTRL+CURSOR_RIGHT : translate to the right\n" "CTRL+CURSOR_UP : translate up\n" "CTRL+CURSOR_DOWN : translate down\n" "SHIFT+CURSOR_UP : move forward\n" "SHIFT+CURSOR_DOWN : move back\n" "SHIFT+Left Mouse Button: move left -> look to the left," " move up -> look upwards, ..."), tr("&Ok") ); break; case Key_Left: // rotate left around y-axis pCamera->rotate(-5.0, m_cUp, true ); sltUpdateView(); break; case Key_Right: // rotate right around y-axis pCamera->rotate(5.0, m_cUp, true ); sltUpdateView(); break; case Key_Up: // rotate "back" around x-axis pCamera->rotate(-5.0, m_cRight, true ); sltUpdateView(); break; case Key_Down: // rotate "to the front" around x-axis pCamera->rotate(5.0, m_cRight, true ); sltUpdateView(); break; case Key_A: // view all sltViewAll(); break; case Key_S: // set homecamera to current camera sltSetHome(); break; case Key_H: sltGoHome(); // set current camera to homecamera break; case Key_P: sltToggleProjectionMode(); // toggle projectionmode break; case Key_Plus: // zoom in m_pqZoom->subtractStep(); break; case Key_Minus: // zoom out m_pqZoom->addStep(); break; case Key_Escape: // exit viewer case Key_Q: qApp->quit(); break; default: break; } break; case ControlButton: switch(event->key()) { case Key_Left: // translate to the left (<=> put camera to the right) pCamera->translate( m_cRight * 0.1 ); sltUpdateView(); break; case Key_Right: // translate to the right (<=> put camera to the left) pCamera->translate( m_cRight * -0.1 ); sltUpdateView(); break; case Key_Up: // translate up (<=> put camera down) pCamera->translate( m_cUp * -0.1 ); sltUpdateView(); break; case Key_Down: // translate down (<=> put camera up) pCamera->translate( m_cUp * 0.1); sltUpdateView(); break; default: break; } break; case ShiftButton: switch(event->key()) { case Key_Up: // move forward cEyePos += m_cDir * ((1.0+cBBox.getSize(2)) * 0.1); pCamera->setEyePos( cEyePos ); sltUpdateView(); break; case Key_Down: // move back cEyePos += m_cDir * ((1.0+cBBox.getSize(2)) * -0.1); pCamera->setEyePos( cEyePos ); sltUpdateView(); break; case Key_Plus: // zoom in (double for english keyboerds) m_pqZoom->subtractStep(); break; default: break; } break; default: break; } } // Function : closeEvents // Parameters: QCloseEvent *pqEvent // Purpose : Implements a handler for closeEvents. // Comments : See docu for details. void QGLExaminerViewer::closeEvent(QCloseEvent *pqEvent) /*********************************************************************/ { emit( sigViewerClosed() ); QWidget::closeEvent(pqEvent); } // Function : setCamera // Parameters: const CCamera &Camera, CameraType which // Purpose : Reimplements inherited function for interaction // with zoom-slider and other things. // Comments : See docu for details. void QGLExaminerViewer::setCamera(const CCamera &cCamera, CameraType eWhich) /*********************************************************************/ { double rdFovy; // adjust zoom slider rdFovy = cCamera.getFovy(); if (isFullViewer()) { sltSetZoomSlider(int(rdFovy*ZOOMSCALING)); sltSetZoomText(int(rdFovy*ZOOMSCALING)); // adjust projection togglebutton if (cCamera.getCameraType() == CCamera::perspective) { if (((QPushButton *)m_apqWidgets[2])->isOn()) { ((QPushButton *)m_apqWidgets[2])->setOn(false); } } else { if (!(((QPushButton *)m_apqWidgets[2])->isOn())) { ((QPushButton *)m_apqWidgets[2])->setOn(true); } } } QGLViewer::setCamera( cCamera, eWhich ); } // Function : makeSimpleViewer // Parameters: // Purpose : // Comments : See docu for details. void QGLExaminerViewer::makeSimpleViewer() /*********************************************************************/ { //cout << "Widget size: " << size().width() << " x " << size().height() << endl; //cout << "Frame size: " << frameSize().width() << " x " << frameSize().height() << endl; // Create top-level layout manager m_pqTopLayout = new QVBoxLayout( this, 0, 0, "m_pqTopLayout"); Q_CHECK_PTR(m_pqTopLayout); // Set parameters for GL-output and add drawarea to layout QGLSignalWidget *drawArea = getDrawArea(); if ( !drawArea->isValid() ) { // Try without double-buffering QGLFormat fmt( false ); drawArea->setFormat( fmt ); if ( !drawArea->isValid() ) { fatal("Failed to create OpenGL rendering context on this display"); } } drawArea->setMinimumSize( 50, 50 ); m_pqTopLayout->addWidget( getQFrame(), 200 ); // Start the geometry management m_pqTopLayout->activate(); } // include images used for buttons #include "pictures/go_home.xpm" #include "pictures/look_at.xpm" #include "pictures/movecursor.xpm" #include "pictures/movemode.xpm" #include "pictures/para_proj.xpm" #include "pictures/persp_proj.xpm" #include "pictures/selectcursor.xpm" #include "pictures/selectmode.xpm" #include "pictures/set_home.xpm" // Function : makeFullViewer // Parameters: // Purpose : // Comments : See docu for details. void QGLExaminerViewer::makeFullViewer() /*********************************************************************/ { //cout << "Widget size: " << size().width() << " x " << size().height() << endl; //cout << "Frame size: " << frameSize().width() << " x " << frameSize().height() << endl; // Initialize m_vUp and m_vRight with current values m_cUp = getCameraPtr()->getViewUp(); m_cRight = getCameraPtr()->getViewRight(); // Initialize pixmaps for buttons QPixmap goHomePix((const char **)go_home_xpm); QPixmap setHomePix((const char **)set_home_xpm); QPixmap paraProjPix((const char **)para_proj_xpm); QPixmap perspProjPix((const char **)persp_proj_xpm); QPixmap lookAtPix((const char **)look_at_xpm); QPixmap moveModePix((const char **)movemode_xpm); QPixmap selectModePix((const char **)selectmode_xpm); // Create top-level layout manager m_pqTopLayout = new QVBoxLayout( this, 10, 10, "m_pqTopLayout"); Q_CHECK_PTR(m_pqTopLayout); // Create 1st horizontal layout for the following vert. layouts QHBoxLayout *hlayout0 = new QHBoxLayout( 5, "hlayout0"); Q_CHECK_PTR(hlayout0); m_pqTopLayout->addLayout( hlayout0, 100 ); // Create a layout manager for the xRot-slider QVBoxLayout *vlayout0 = new QVBoxLayout( 5, "vlayout0"); Q_CHECK_PTR(vlayout0); hlayout0->addLayout( vlayout0 ); // Create a layout for the OpenGL widget and yRot-slider QVBoxLayout *vlayout1 = new QVBoxLayout( 5, "vlayout1"); Q_CHECK_PTR(vlayout1); hlayout0->addLayout( vlayout1, 10 ); // Create a layout manager for the buttons QVBoxLayout *vlayout2 = new QVBoxLayout( 5, "vlayout2"); Q_CHECK_PTR(vlayout2); hlayout0->addLayout( vlayout2 ); // Set parameters for GL-output and add drawarea to layout QGLSignalWidget *drawArea = getDrawArea(); if ( !drawArea->isValid() ) { // Try without double-buffering QGLFormat fmt(false); drawArea->setFormat( fmt ); if ( !drawArea->isValid() ) { fatal("Failed to create OpenGL rendering context on this display"); } } drawArea->setMinimumSize( 50, 50 ); drawArea->installEventFilter(this); vlayout1->addWidget( getQFrame(), 200 ); // Create a layout for yRot_lab and yRot-slider QHBoxLayout *hlayout2 = new QHBoxLayout( 5, "hlayout2"); Q_CHECK_PTR(hlayout2); m_pqTopLayout->addLayout( hlayout2, 1 ); // Create labels for the sliders QLabel *xRot_lab = new QLabel("RotX", this, "RotX"); Q_CHECK_PTR(xRot_lab); xRot_lab->setMinimumSize( xRot_lab->sizeHint() ); xRot_lab->setFocusPolicy(NoFocus); vlayout0->addWidget( xRot_lab, 1 ); QLabel *yRot_lab = new QLabel("RotY", this, "RotY"); Q_CHECK_PTR(yRot_lab); yRot_lab->setMinimumSize( yRot_lab->sizeHint() ); yRot_lab->setFocusPolicy(NoFocus); hlayout2->addWidget( yRot_lab, 1 ); QLabel *zoom_lab = new QLabel("Zoom", this, "Zoom"); Q_CHECK_PTR(zoom_lab); zoom_lab->setMinimumSize( zoom_lab->sizeHint() ); zoom_lab->setFocusPolicy(NoFocus); // Create the two sliders; one for each rotation axis m_pqXRot = new QSlider ( -180, 180, 60, 0, QSlider::Vertical, this, "m_pqXRot" ); Q_CHECK_PTR(m_pqXRot); m_pqXRot->setTickInterval( 10 ); m_pqXRot->setTickmarks( QSlider::Both ); m_pqXRot->setMinimumSize( m_pqXRot->sizeHint() ); m_pqXRot->setFocusPolicy(NoFocus); m_pqXRot->installEventFilter(this); vlayout0->addWidget( m_pqXRot, 100); connect( m_pqXRot, SIGNAL(valueChanged(int)), this, SLOT(sltCamXRotate(int)) ); connect( m_pqXRot, SIGNAL(sliderReleased()), this, SLOT(sltResetXSlider()) ); connect( m_pqXRot, SIGNAL(sliderPressed()), this, SLOT(sltSaveVectors()) ); m_pqYRot = new QSlider ( -180, 180, 60, 0, QSlider::Horizontal, this, "m_pqYRot" ); Q_CHECK_PTR(m_pqYRot); m_pqYRot->setTickInterval( 10 ); m_pqYRot->setTickmarks( QSlider::Both ); m_pqYRot->setMinimumSize( m_pqYRot->sizeHint() ); m_pqYRot->setFocusPolicy(NoFocus); m_pqYRot->installEventFilter(this); hlayout2->addWidget( m_pqYRot, 100 ); connect( m_pqYRot, SIGNAL(valueChanged(int)), this, SLOT(sltCamYRotate(int)) ); connect( m_pqYRot, SIGNAL(sliderReleased()), this, SLOT(sltResetYSlider()) ); connect( m_pqYRot, SIGNAL(sliderPressed()), this, SLOT(sltSaveVectors()) ); QToggleButton *rendermode = new QToggleButton("Render", "Select", this, "Render_Mode"); Q_CHECK_PTR(rendermode); if( !(moveModePix.isNull() || selectModePix.isNull()) ) rendermode->setPixmap(moveModePix, selectModePix); if (isItemChecked(m_nSelectionID)) rendermode->toggle(); rendermode->setFocusPolicy(NoFocus); vlayout2->addWidget(rendermode, 1); connect( rendermode, SIGNAL(clicked()), this, SLOT(sltToggleRenderMode()) ); QPushButton *goHome = new QPushButton("Go Home", this, "Go_Home"); Q_CHECK_PTR(goHome); if( !(goHomePix.isNull()) ) goHome->setPixmap(goHomePix); goHome->setMinimumSize( goHome->sizeHint() ); goHome->setFocusPolicy(NoFocus); goHome->installEventFilter(this); vlayout2->addWidget(goHome, 1); connect( goHome, SIGNAL(clicked()), this, SLOT(sltGoHome()) ); QPushButton *setHome = new QPushButton("Set Home", this, "Set_Home"); Q_CHECK_PTR(setHome); if( !(setHomePix.isNull()) ) setHome->setPixmap(setHomePix); setHome->setMinimumSize( setHome->sizeHint() ); setHome->setFocusPolicy(NoFocus); setHome->installEventFilter(this); vlayout2->addWidget(setHome, 1); connect( setHome, SIGNAL(clicked()), this, SLOT(sltSetHome()) ); QToggleButton *setProj = new QToggleButton("Perspective", "Orthographic", this, "Proj_Type"); Q_CHECK_PTR(setProj); if( !(paraProjPix.isNull() || perspProjPix.isNull()) ) setProj->setPixmap(perspProjPix, paraProjPix); setProj->setMinimumSize( setProj->sizeHint() ); setProj->setFocusPolicy(NoFocus); setProj->installEventFilter(this); if( getProjectionMode() == QGLViewer::parallel) { setProj->toggle(); } vlayout2->addWidget(setProj, 1); connect( setProj, SIGNAL(clicked()), this, SLOT(sltToggleProjectionMode()) ); QPushButton *centerObj = new QPushButton("Center Object", this, "Center_Obj"); Q_CHECK_PTR(centerObj); if( !(lookAtPix.isNull()) ) centerObj->setPixmap( lookAtPix ); centerObj->setMinimumSize( centerObj->sizeHint() ); vlayout2->addWidget(centerObj, 1); centerObj->setFocusPolicy(NoFocus); centerObj->installEventFilter(this); connect( centerObj, SIGNAL(clicked()), this, SLOT(sltViewAll()) ); // create drag'n drop site and add it to the layout QCameraDropSite *pqDropSite = new QCameraDropSite(this); Q_CHECK_PTR(pqDropSite); pqDropSite->setFocusPolicy( NoFocus ); pqDropSite->setMinimumSize(pqDropSite->sizeHint()); pqDropSite->setCamera(getCameraPtr()); pqDropSite->setFocusPolicy(NoFocus); pqDropSite->installEventFilter(this); vlayout2->addWidget(pqDropSite, 1); connect(pqDropSite, SIGNAL(sigCameraDropped(const CCamera &)), this, SLOT(sltSetCamera(const CCamera &))); vlayout2->addSpacing(50); vlayout2->addWidget(zoom_lab, 1); m_pqZoomText = new QLineEdit(this); Q_CHECK_PTR(m_pqZoomText); m_pqZoomText->setMaxLength(6); QSize qSize = this->fontMetrics().size(0, "0000.00"); m_pqZoomText->setMaximumSize(qSize); m_pqZoomText->setFocusPolicy(NoFocus); m_pqZoomText->installEventFilter(this); vlayout2->addWidget(m_pqZoomText, 1); m_pqZoom = new QSlider( 1, 18000, 1800, 0, QSlider::Vertical, this, "m_pqZoom" ); Q_CHECK_PTR(m_pqZoom); m_pqZoom->setTickInterval( 1000 ); m_pqZoom->setTickmarks( QSlider::Both ); m_pqZoom->setMinimumSize( m_pqZoom->sizeHint() ); m_pqZoom->setFocusPolicy(NoFocus); m_pqZoom->installEventFilter(this); vlayout2->addWidget( m_pqZoom, 10); connect( m_pqZoom, SIGNAL(valueChanged(int)), this, SLOT(sltSetZoom(int)) ); connect(m_pqZoom, SIGNAL(valueChanged(int)), this, SLOT(sltSetZoomText(int))); connect(m_pqZoomText, SIGNAL(textChanged(const QString &)), this, SLOT(sltSetZoomSlider(const QString &))); double rdFovy = getCameraPtr()->getFovy(); m_pqZoom->setValue(int(rdFovy*ZOOMSCALING)); // connect the signal 'sigFovyChanged()' of the viewer to // the appropriate slot. connect(this, SIGNAL(sigFovyChanged(double)), SLOT(sltSetZoomSlider(double))); hlayout2->addSpacing( setProj->sizeHint().width() + 5 ); // save the pointers to the widgets in the array m_apqWidgets[0] = m_pqZoom; m_apqWidgets[1] = centerObj; m_apqWidgets[2] = setProj; m_apqWidgets[3] = setHome; m_apqWidgets[4] = goHome; m_apqWidgets[5] = rendermode; m_apqWidgets[6] = m_pqYRot; m_apqWidgets[7] = m_pqXRot; m_apqWidgets[8] = zoom_lab; m_apqWidgets[9] = yRot_lab; m_apqWidgets[10] = xRot_lab; m_apqWidgets[11] = pqDropSite; m_apqWidgets[12] = m_pqZoomText; // Start the geometry management m_pqTopLayout->activate(); } // Function : sltResetXSlider // Parameters: // Purpose : resets the slider to zero. // Comments : See docu for details. void QGLExaminerViewer::sltResetXSlider() /*********************************************************************/ { m_nLastRotAngle = 0; m_pqXRot->setValue(0); } // Function : sltResetYSlider // Parameters: // Purpose : resets the slider to zero. // Comments : See docu for details. void QGLExaminerViewer::sltResetYSlider() /*********************************************************************/ { m_nLastRotAngle = 0; m_pqYRot->setValue(0); } // Function : sltSetZoomSlider // Parameters: int nScaling // Purpose : // Comments : See docu for details. void QGLExaminerViewer::sltSetZoomSlider(int nScaling) /*********************************************************************/ { if (isFullViewer()) { m_pqZoom->setValue(nScaling); } } // Function : sltSetZoomSlider // Parameters: const QString &qText // Purpose : // Comments : See docu for details. void QGLExaminerViewer::sltSetZoomSlider(const QString &qText) /*********************************************************************/ { float rfAngle; if (isFullViewer()) { rfAngle = qText.toFloat(); m_pqZoom->setValue(rfAngle * ZOOMSCALING); } } // Function : sltSetZoomSlider // Parameters: double rdFovy // Purpose : // Comments : See docu for details. void QGLExaminerViewer::sltSetZoomSlider(double rdFovy) /*********************************************************************/ { if (isFullViewer()) { disconnect( m_pqZoom, SIGNAL(valueChanged(int)), this, SLOT(sltSetZoom(int)) ); m_pqZoom->setValue(int(rdFovy*ZOOMSCALING)); connect( m_pqZoom, SIGNAL(valueChanged(int)), SLOT(sltSetZoom(int)) ); } } // Function : sltSetZoomText // Parameters: int n // Purpose : // Comments : See docu for details. void QGLExaminerViewer::sltSetZoomText(int n) /*********************************************************************/ { QString qString; qString.setNum(float(n) / ZOOMSCALING); m_pqZoomText->setText(qString); } // Function : sltSetZoom // Parameters: int nZoomFactor // Purpose : Adjusts the camera while zooming. // Comments : See docu for details. void QGLExaminerViewer::sltSetZoom(int nZoomFactor) /*********************************************************************/ { CCamera *camera = getCameraPtr(); camera->setFovy(double(nZoomFactor) / ZOOMSCALING); sltUpdateView(); } // Function : sltCamXRotate // Parameters: int nAngle // Purpose : Rotate camera around the x-axis with an angle of 'nAngle' // degrees. // Comments : See docu for details. void QGLExaminerViewer::sltCamXRotate(int nAngle) /*********************************************************************/ { getCameraPtr()->rotate((double)nAngle-m_nLastRotAngle, m_cRight); m_nLastRotAngle = nAngle; sltUpdateView(); } // Function : sltCamYRotate // Parameters: int nAngle // Purpose : Rotate camera around the y-axis with an angle of 'nAngle' // degrees. // Comments : See docu for details. void QGLExaminerViewer::sltCamYRotate(int nAngle) /*********************************************************************/ { getCameraPtr()->rotate((double)nAngle-m_nLastRotAngle, m_cUp); m_nLastRotAngle = nAngle; sltUpdateView(); } // Function : sltSaveVectors // Parameters: // Purpose : Saves the ViewUp direction in 'm_vUp' and the ViewRight // direction in 'm_vRight'. // Comments : See docu for details. void QGLExaminerViewer::sltSaveVectors() /*********************************************************************/ { m_cUp = getCameraPtr()->getViewUp(); m_cRight = getCameraPtr()->getViewRight(); m_cDir = getCameraPtr()->getViewDir(); } // Function : ManageMousePress // Parameters: QMouseEvent *pqEvent // Purpose : Implements the method from the derived class QGLViewer. // Comments : See docu for details. void QGLExaminerViewer::ManageMousePress(QMouseEvent *pqEvent) /*********************************************************************/ { m_nMousePosX = pqEvent->x(); m_nMousePosY = pqEvent->y(); m_nXDiff = m_nYDiff = 0; if( m_pqTimer->isActive() ) { m_pqTimer->stop(); } if ( pqEvent->button() == LeftButton ) { sltSaveVectors(); m_fLeftButtonPressed = true; } if ( pqEvent->button() == MidButton ) { sltSaveVectors(); m_fMiddleButtonPressed = true; } } // Function : ManageMouseMove // Parameters: QMouseEvent *pqEvent // Purpose : Implements the method from the derived class QGLViewer. // Comments : See docu for details. void QGLExaminerViewer::ManageMouseMove(QMouseEvent *pqEvent) /*********************************************************************/ { double rdDistance; CCamera *pCamera = getCameraPtr(); CP3D cEyePos; CBoundingBox3D cBBox; cBBox = pCamera->getBoundingBox(); m_nYDiff = pqEvent->y() - m_nMousePosY; m_nXDiff = m_nMousePosX - pqEvent->x(); m_fShiftPressed = (pqEvent->state() & ShiftButton) == ShiftButton; m_nMousePosX = pqEvent->x(); m_nMousePosY = pqEvent->y(); if(m_fLeftButtonPressed && !m_fMiddleButtonPressed) { if (!m_fShiftPressed) { // save the quadrant where the event happened. if (pqEvent->x() > getDrawArea()->width()/2) { if (pqEvent->y() > getDrawArea()->height()/2) { m_nQuadrant = 2; } else { m_nQuadrant = 1; } } else { if (pqEvent->y() > getDrawArea()->height()/2) { m_nQuadrant = 3; } else { m_nQuadrant = 0; } } // calculate the relative amount of rotation around the axis of the view direction if (!m_fOldBehave) { if (pqEvent->x() >= 0 && pqEvent->x() <= getDrawArea()->width()) { m_rfXAlpha = fabs(1 - (float(pqEvent->x()) / getDrawArea()->width()) * 2); } else { m_rfXAlpha = 1; } if (pqEvent->y() >= 0 && pqEvent->y() <= getDrawArea()->height()) { m_rfYAlpha = fabs(1 - (double(pqEvent->y()) / getDrawArea()->height()) * 2); } else { m_rfYAlpha = 1; } } else { m_rfXAlpha = m_rfYAlpha = 0; } } sltCamRotStep(); // start timeout for animation only if spinning // is switched on if (isItemChecked(m_nSpinOnOffID)) { m_fAnimationOn = true; m_pqTimeOut->start(1, true); } return; } if(m_fLeftButtonPressed && m_fMiddleButtonPressed) { if(m_nYDiff != 0) { // move forward / back cEyePos = pCamera->getEyePos(); cEyePos = cEyePos + (m_cDir * (((double)m_nYDiff/(double)getDrawArea()->height()) * (1.0+cBBox.getSize(2)) * 10.0)); pCamera->setEyePos( cEyePos ); sltUpdateView(); return; } } if(!m_fLeftButtonPressed && m_fMiddleButtonPressed) { rdDistance = (pCamera->getRefPoint() - pCamera->getEyePos()).getNorm(); if(m_nYDiff != 0) { // translate box in y-direction pCamera->translate( m_cUp * ((double)m_nYDiff/(double)getDrawArea()->height()) * (1.0+rdDistance) ); } if(m_nXDiff != 0) { // translate box in x-direction pCamera->translate( m_cRight * ((double)m_nXDiff/(double)getDrawArea()->width()) * (1.0+rdDistance) ); } sltUpdateView(); return; } } // Function : ManageMouseRelease // Parameters: QMouseEvent *pqEvent // Purpose : Implements the method from the derived class QGLViewer. // Comments : See docu for details. void QGLExaminerViewer::ManageMouseRelease(QMouseEvent *pqEvent) /*********************************************************************/ { if( (m_fLeftButtonPressed && !m_fMiddleButtonPressed) && m_fAnimationOn) { /* start timer only if rotation was the last action */ m_pqTimer->start( 20 ); } if ( pqEvent->button() == LeftButton ) { m_fLeftButtonPressed = false; } if ( pqEvent->button() == MidButton ) { m_fMiddleButtonPressed = false; } } // Function : eventFilter // Parameters: QObject *pqObject, QEvent *pqEvent // Purpose : Implements inherited method // Comments : See docu for details. bool QGLExaminerViewer::eventFilter(QObject *pqObject, QEvent *pqEvent) /*********************************************************************/ { if ( pqEvent->type() == QEvent::KeyPress ) { // key press keyPressEvent((QKeyEvent*)pqEvent); return true; } return QGLViewer::eventFilter(pqObject, pqEvent); // standard event processing } // Function : sltGoHome // Parameters: // Purpose : Reimplements inherited function for interaction // with zoom-slider and other GUI things. // Comments : See docu for details. void QGLExaminerViewer::sltGoHome() /*********************************************************************/ { double rdFovy; QGLViewer::sltGoHome(); rdFovy = getCameraPtr()->getFovy(); if( isFullViewer() ) { m_pqZoom->setValue(int(rdFovy*ZOOMSCALING)); } } // Function : sltCamRotStep // Parameters: // Purpose : Rotates the camera around the x-, y-axis and z-axis depending on // the values saved in 'm_nXDiff', 'm_nYDiff', 'm_rfXAlpha' and // 'm_rfYAlpha'. // Comments : See docu for details. void QGLExaminerViewer::sltCamRotStep() /*********************************************************************/ { int nSign; CCamera *pCamera = getCameraPtr(); if(m_nYDiff != 0) { // partitional rotation around the x-axis nSign = (m_nQuadrant % 3) == 0 ? -1 : 1; if (m_fShiftPressed) pCamera->rotate( (double)m_nYDiff/(double)getDrawArea()->height() * 90.0, m_cRight, false ); else { pCamera->rotate((1 - m_rfXAlpha) * (double)m_nYDiff/(double)getDrawArea()->height() * 180.0, m_cRight, true ); if (!m_fOldBehave) { // partitional rotation around the z-axis pCamera->rotate(m_rfXAlpha * (180.0 * (double)m_nYDiff/(double)getDrawArea()->height() * nSign), pCamera->getViewDir(), true ); } } m_cUp = pCamera->getViewUp(); } if(m_nXDiff != 0) { // partitional rotation around the y-axis nSign = m_nQuadrant > 1 ? -1 : 1; if (m_fShiftPressed) pCamera->rotate( -(double)m_nXDiff/(double)getDrawArea()->width() * 90.0, m_cUp, false ); else { pCamera->rotate((1 - m_rfYAlpha) * -(double)m_nXDiff/(double)getDrawArea()->width() * 180.0, m_cUp, true); if (!m_fOldBehave) { // partitional rotation around the z-axis pCamera->rotate(m_rfYAlpha * (180.0 * (double)-m_nXDiff/(double)getDrawArea()->width() * nSign), pCamera->getViewDir(), true ); } } m_cRight = pCamera->getViewRight(); } sltUpdateView(); } // Function : sltToggleDeco // Parameters: // Purpose : Toggles between full and simple viewer. // Comments : See docu for details. void QGLExaminerViewer::sltToggleDeco() /*********************************************************************/ { if( isFullViewer() ) { setItemChecked( m_nDecoID, false ); setFullViewer( false ); } else { setItemChecked( m_nDecoID, true ); setFullViewer( true ); } } // Function : sltToggleToolTips // Parameters: // Purpose : Toggles between the tooltip on and off. // Initially the tooltip are on. // Comments : See docu for details. void QGLExaminerViewer::sltToggleToolTips() /*********************************************************************/ { int i; switch(m_fToolTips) { case false: m_fToolTips = true; setItemChecked( m_nTTipsID, true ); QToolTip::add( m_apqWidgets[0], tr("Slider is for changing\nthe opening angle of camera.") ); QToolTip::add( m_apqWidgets[1], tr("Push here to fit your\nscene to the drawarea.") ); QToolTip::add( m_apqWidgets[2], tr("Push here to toggle between\northographic and perspective projection.") ); QToolTip::add( m_apqWidgets[3], tr("Push here to save your current\nposition as homeposition.") ); QToolTip::add( m_apqWidgets[4], tr("Push here to get\nyour saved homeposition.") ); QToolTip::add( m_apqWidgets[5], tr("Push here to toggle between\nrender and selectionmode.") ); QToolTip::add( m_apqWidgets[6], tr("Slider is for rotating\nthe scene around the x-axis.") ); QToolTip::add( m_apqWidgets[7], tr("Slider is for rotating\nthe scene around the y-axis.") ); QToolTip::add( m_apqWidgets[11], tr("Push here to get the current camera\nand drag it to any other viewer.") ); break; case true: m_fToolTips = false; setItemChecked( m_nTTipsID, false ); for(i=0; itoggle(); } sltToggleRenderMode(); } // Function : sltSetRefreshRate // Parameters: // Purpose : Shows an dialog to enter a new refresh rate. // Comments : See docu for details. void QGLExaminerViewer::sltSetRefreshRate() /*********************************************************************/ { bool fOk = false; int nFps = QInputDialog::getInteger(tr("Change refresh rate"), tr("New refresh rate in fps"), getRefreshRate(), 1, 1000, 5, &fOk, this ); if (fOk) setRefreshRate(nFps); } // Function : sltToggleRenderMode // Parameters: // Purpose : Reimplementation of the inherited slot. // Comments : See docu for details. void QGLExaminerViewer::sltToggleRenderMode() /*********************************************************************/ { QGLViewer::sltToggleRenderMode(); if( getRenderMode()==GL_RENDER ) { setItemChecked( m_nSelectionID, false ); } else { setItemChecked( m_nSelectionID, true ); } } // Function : sltToggleStereo // Parameters: // Purpose : Reimplementation of the inherited slot. // Comments : See docu for details. void QGLExaminerViewer::sltToggleStereo() /*********************************************************************/ { setItemChecked( m_nStereoID, isItemChecked(m_nStereoID) ? false : true); QGLViewer::sltToggleStereo(); } // Function : setFullViewer // Parameters: bool fState // Purpose : Reimplements inherited function to switch between // the two possible GUIs. // Comments : See docu for details. void QGLExaminerViewer::setFullViewer(bool fState) /*********************************************************************/ { int i; bool fShown = false; //QRect qGeometry; if( isVisible() ) { fShown = true; hide(); } if(isFullViewer() && !fState) { // call inherited function QGLViewer::setFullViewer(fState); disconnect(this, SIGNAL(sigFovyChanged(double)), this, SLOT(sltSetZoomSlider(double))); // go to simple viewer for(i=0; i