glviewer.cpp
Go to the documentation of this file.
00001 /*
00002  * Software License Agreement (BSD License)
00003  *
00004  *  Copyright (c) 2013, Intelligent Robotics Lab, DLUT.
00005  *  Author: Qinghua Li, Yan Zhuang, Fei Yan
00006  *
00007  *  All rights reserved.
00008  *
00009  *  Redistribution and use in source and binary forms, with or without
00010  *  modification, are permitted provided that the following conditions
00011  *  are met:
00012  *
00013  *   * Redistributions of source code must retain the above copyright
00014  *     notice, this list of conditions and the following disclaimer.
00015  *   * Redistributions in binary form must reproduce the above
00016  *     copyright notice, this list of conditions and the following
00017  *     disclaimer in the documentation and/or other materials provided
00018  *     with the distribution.
00019  *   * Neither the name of Intelligent Robotics Lab, DLUT. nor the names
00020  *     of its contributors may be used to endorse or promote products
00021  *     derived from this software without specific prior written permission.
00022  *
00023  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00024  *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00025  *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00026  *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
00027  *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00028  *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00029  *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00030  *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00031  *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00032  *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
00033  *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00034  *  POSSIBILITY OF SUCH DAMAGE.
00035  */
00036 
00037 #include <QtGui>
00038 #include <QtOpenGL>
00039 #include <QKeyEvent>
00040 #include <GL/glu.h>
00041 #include "dlut_place_recognition/glviewer.h"
00042 
00043 #ifndef GL_MULTISAMPLE
00044 #define GL_MULTISAMPLE 0x809D
00045 #endif
00046 
00047 GLViewer::GLViewer (std::vector < std::vector < pcl::PointXYZ > >&points, int flag, QWidget *parent)
00048   : QGLWidget(QGLFormat(QGL::SampleBuffers|QGL::StereoBuffers), parent),
00049     xRot(0),
00050     yRot(0),
00051     zRot(0),
00052     xTra(-1),
00053     yTra(-2),
00054     zTra(-10),
00055     width_(0),
00056     height_(0),
00057     fov_(45.0),
00058     show_axis_(true),
00059     point_cloud(points),
00060     rotation_step_(1.0),
00061     translation_step_(0.2)
00062 {
00063   label = flag;
00064   bg_color[0] = bg_color[1] = bg_color[2] = bg_color[3] = 0.0; // Black background
00065   setSizePolicy (QSizePolicy::Expanding, QSizePolicy::Expanding); // Can make good use of more space
00066   setFocusPolicy (Qt::StrongFocus);
00067 }
00068 
00069 GLViewer::~GLViewer ()
00070 {
00071 }
00072 
00073 
00074 QSize GLViewer::minimumSizeHint () const
00075 {
00076   return QSize (400, 400);
00077 }
00078 
00079 QSize GLViewer::sizeHint () const
00080 {
00081   return QSize (640, 480);
00082 }
00083 
00084 static void qNormalizeAngle (int &angle)
00085 {
00086   while (angle < 0)
00087     angle += 360 * 16;
00088   while (angle > 360 * 16)
00089     angle -= 360 * 16;
00090 }
00091 
00092 void GLViewer::setXRotation (int angle)
00093 {
00094   qNormalizeAngle (angle);
00095   if (angle != xRot)
00096   {
00097     xRot = angle;
00098     updateGL ();
00099   }
00100 }
00101 
00102 void GLViewer::setYRotation (int angle)
00103 {
00104   qNormalizeAngle (angle);
00105   if (angle != yRot)
00106   {
00107     yRot = angle;
00108     updateGL ();
00109   }
00110 }
00111 
00112 void GLViewer::setZRotation (int angle)
00113 {
00114   qNormalizeAngle (angle);
00115   if (angle != zRot)
00116   {
00117     zRot = angle;
00118     updateGL ();
00119   }
00120 }
00121 
00122 void GLViewer::initializeGL ()
00123 {
00124   glShadeModel (GL_SMOOTH);
00125   glClearColor (bg_color[0], bg_color[1], bg_color[2], bg_color[3]);
00126 
00127   glClearDepth (1.0);
00128   glEnable (GL_DEPTH_TEST);
00129   glDepthFunc (GL_LEQUAL);
00130   glHint (GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
00131 }
00132 
00133 void GLViewer::paintGL ()
00134 {
00135   if (!this->isVisible ())
00136     return;
00137 
00138   glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
00139   glLoadIdentity ();
00140 
00141   drawPointCloud ();
00142 }
00143 
00144 void GLViewer::resizeGL (int width, int height)
00145 {
00146   if (height == 0)
00147   {
00148     height = 1;
00149   }
00150 
00151   width_ = width;
00152   height_ = height;
00153 
00154   glViewport (0, 0, width, height);
00155   glMatrixMode (GL_PROJECTION);
00156   glLoadIdentity ();
00157 
00158   float ratio = (float) width / (float) height;
00159   gluPerspective (fov_, ratio, 0.01, 1e3);
00160   glMatrixMode (GL_MODELVIEW);
00161   glLoadIdentity ();
00162 }
00163 
00164 void GLViewer::drawAxis (float scale)
00165 {
00166   glBegin (GL_LINES);
00167   glLineWidth (4);
00168   glColor4f (0.9, 0, 0, 1.0);
00169   glVertex3f (0, 0, 0);
00170   glColor4f (0.9, 0, 0, 0.0);
00171   glVertex3f (scale, 0, 0);
00172   glColor4f (0, 0.9, 0, 1.0);
00173   glVertex3f (0, 0, 0);
00174   glColor4f (0, 0.9, 0, 0.0);
00175   glVertex3f (0, scale, 0);
00176   glColor4f (0, 0, 0.9, 1.0);
00177   glVertex3f (0, 0, 0);
00178   glColor4f (0, 0, 0.9, 0.0);
00179   glVertex3f (0, 0, scale);
00180   glEnd ();
00181 }
00182 
00183 void GLViewer::drawPointCloud ()
00184 {
00185   if (point_cloud.size () > 0)
00186   {
00187     glColor4f (1 - bg_color[0], 1 - bg_color[1], 1 - bg_color[2], 1.0); /* Inverse of bg color */
00188 
00189     if (label == 1)
00190     {
00191       this->renderText (10, 25, tr ("Query Scene"), QFont ("Times", 16, QFont::Normal, true));
00192     }
00193     if (label == 2)
00194     {
00195       this->renderText (10, 25, tr ("Corresponding Scene in Database"), QFont ("Times", 16, QFont::Normal, true));
00196     }
00197 
00198     glTranslatef (xTra, yTra, zTra);
00199     int x_steps = (xRot / 16.0) / rotation_step_;
00200     int y_steps = (yRot / 16.0) / rotation_step_;
00201     int z_steps = (zRot / 16.0) / rotation_step_;
00202     glRotatef (x_steps * rotation_step_, 1.0, 0.0, 0.0);
00203     glRotatef (y_steps * rotation_step_, 0.0, 1.0, 0.0);
00204     glRotatef (z_steps * rotation_step_, 0.0, 0.0, 1.0);
00205 
00206     if (show_axis_)
00207     {
00208       drawAxis (0.5);
00209     }
00210 
00211     glColor3f (0.0, 1.0, 0.0);
00212     glPointSize (1.0);
00213     glBegin (GL_POINTS);
00214     for (int i = 0; i < (int) point_cloud.size (); ++i)
00215     {
00216       for (int j = 0; j < (int) point_cloud[i].size (); ++j)
00217       {
00218         glVertex3f (-point_cloud[i][j].y, point_cloud[i][j].z, -point_cloud[i][j].x);
00219       }
00220     }
00221     glEnd ();
00222   }
00223   else
00224   {
00225     glColor4f (1 - bg_color[0], 1 - bg_color[1], 1 - bg_color[2], 1.0); /* Inverse of bg color */
00226     this->renderText (width_ / 5, height_ / 2, tr ("Waiting for point cloud to display..."),
00227                       QFont ("Times", 16, QFont::Normal, true));
00228   }
00229 }
00230 
00231 // Reset the initial view of scene
00232 void GLViewer::reset ()
00233 {
00234   xRot = 0;
00235   yRot = 0;
00236   zRot = 0;
00237   xTra = -1;
00238   yTra = -2;
00239   zTra = -10;
00240   updateGL ();
00241 }
00242 
00243 void GLViewer::wheelEvent (QWheelEvent *event)
00244 {
00245   zTra += ((float) event->delta ()) / 25.0;
00246   updateGL ();
00247 }
00248 
00249 void GLViewer::mousePressEvent (QMouseEvent *event)
00250 {
00251   lastPos = event->pos ();
00252 }
00253 
00254 void GLViewer::mouseMoveEvent (QMouseEvent *event)
00255 {
00256   /* Consolidate setRotation methods */
00257   int dx = event->x () - lastPos.x ();
00258   int dy = event->y () - lastPos.y ();
00259 
00260   if (event->buttons () & Qt::LeftButton)
00261   {
00262     setXRotation (xRot - 8 * dy);
00263     setYRotation (yRot + 8 * dx);
00264   }
00265   else if (event->buttons () & Qt::RightButton)
00266   {
00267     setXRotation (xRot - 8 * dy);
00268     setZRotation (zRot + 8 * dx);
00269   }
00270   else if (event->buttons () & Qt::MidButton)
00271   {
00272     xTra += dx / 200.0;
00273     yTra -= dy / 200.0;
00274     updateGL ();
00275   }
00276   lastPos = event->pos ();
00277 }
00278 
00279 void GLViewer::keyPressEvent (QKeyEvent *e)
00280 {
00281   switch (e->key ())
00282   {
00283     // Reset
00284     case Qt::Key_R:
00285       reset ();
00286       break;
00287 
00288     // Front
00289     case Qt::Key_W:
00290       zTra += translation_step_;
00291       updateGL ();
00292       break;
00293 
00294     // Back
00295     case Qt::Key_S:
00296       zTra -= translation_step_;
00297       updateGL ();
00298       break;
00299 
00300     // Left
00301     case Qt::Key_A:
00302       xTra -= translation_step_;
00303       updateGL ();
00304       break;
00305 
00306     // Right
00307     case Qt::Key_D:
00308       xTra += translation_step_;
00309       updateGL ();
00310       break;
00311 
00312     // Up
00313     case Qt::Key_Q:
00314       yTra += translation_step_;
00315       updateGL ();
00316       break;
00317 
00318     // Down
00319     case Qt::Key_E:
00320       yTra -= translation_step_;
00321       updateGL ();
00322       break;
00323 
00324     // Switch drawing the coordinate axis
00325     case Qt::Key_X:
00326       show_axis_ = !show_axis_;
00327       updateGL ();
00328       break;
00329 
00330     // Close the widget
00331     case Qt::Key_Escape:
00332       close ();
00333   }
00334 }


dlut_place_recognition
Author(s): Qinghua Li, Yan Zhuang, Fei Yan
autogenerated on Sun Oct 5 2014 23:29:57