glc_viewport.cpp

Go to the documentation of this file.
00001 /****************************************************************************
00002 
00003  This file is part of the GLC-lib library.
00004  Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net)
00005  http://glc-lib.sourceforge.net
00006 
00007  GLC-lib is free software; you can redistribute it and/or modify
00008  it under the terms of the GNU Lesser General Public License as published by
00009  the Free Software Foundation; either version 3 of the License, or
00010  (at your option) any later version.
00011 
00012  GLC-lib is distributed in the hope that it will be useful,
00013  but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  GNU Lesser General Public License for more details.
00016 
00017  You should have received a copy of the GNU Lesser General Public License
00018  along with GLC-lib; if not, write to the Free Software
00019  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
00020 
00021 *****************************************************************************/
00022 
00024 
00025 #include <QtOpenGL>
00026 
00027 #include "../glu/glc_glu.h"
00028 #include "glc_viewport.h"
00029 #include "../glc_openglexception.h"
00030 #include "../glc_ext.h"
00031 #include "../shading/glc_selectionmaterial.h"
00032 #include "../glc_state.h"
00033 #include "../sceneGraph/glc_3dviewinstance.h"
00034 
00035 #include <QtDebug>
00036 
00037 using namespace glc;
00039 // Constructor Destructor
00041 
00042 GLC_Viewport::GLC_Viewport(QGLWidget *GLWidget)
00043 // Camera definition
00044 : m_pViewCam(new GLC_Camera())                          // Camera
00045 , m_DistanceMax(500.0)                  // Camera Maximum distance
00046 , m_dDistanceMini(0.01)                 // Camera Minimum distance
00047 , m_ViewAngle(35)                                       // Camera angle of view
00048 , m_ViewTangent(tan(glc::toRadian(m_ViewAngle)))
00049 , m_pImagePlane(NULL)                   // Background image
00050 // OpenGL Window size
00051 , m_WindowHSize(0)                              // Horizontal OpenGL viewport size
00052 , m_WindowVSize(0)                              // Vertical OpenGL viewport size
00053 , m_AspectRatio(1.0)
00054 , m_pQGLWidget(GLWidget)                // Attached QGLWidget
00055 // the default backgroundColor
00056 , m_BackgroundColor(Qt::black)
00057 , m_SelectionSquareSize(4)
00058 , m_ProjectionMatrix()
00059 , m_Frustum()
00060 , m_ClipPlanesHash()
00061 , m_UseClipPlane(false)
00062 , m_3DWidgetCollection()
00063 , m_UseParallelProjection(false)
00064 , m_MinimumStaticPixelSize(10)
00065 , m_MinimumStaticRatioSize(0.0)
00066 , m_MinimumDynamicRatioSize(0.0)
00067 {
00068         updateMinimumRatioSize();
00069 }
00070 
00071 GLC_Viewport::~GLC_Viewport()
00072 {
00073         delete m_pViewCam;
00074 
00075         // delete background image
00076         deleteBackGroundImage();
00077 
00078         // Delete clip planes
00079         QHash<GLenum, GLC_Plane*>::iterator iClip= m_ClipPlanesHash.begin();
00080         while (m_ClipPlanesHash.constEnd() != iClip)
00081         {
00082                 delete iClip.value();
00083                 ++iClip;
00084         }
00085 }
00086 
00088 // Get Functions
00090 GLC_Point2d  GLC_Viewport::normalyseMousePosition(int x, int y)
00091 {
00092         double nX= 0.0;
00093         double nY= 0.0;
00094         if (m_WindowHSize != 0)
00095         {
00096                 nX= static_cast<double>(x) / static_cast<double>(m_WindowHSize);
00097         }
00098 
00099         if (m_WindowVSize != 0)
00100         {
00101                 nY= static_cast<double>(y) / static_cast<double>(m_WindowVSize);
00102         }
00103 
00104         return GLC_Point2d(nX, nY);
00105 }
00106 
00107 GLC_Point2d GLC_Viewport::mapToOpenGLScreen(int x, int y)
00108 {
00109         GLC_Point2d nPos= normalyseMousePosition(x, y);
00110 
00111         return mapNormalyzeToOpenGLScreen(nPos.getX(), nPos.getY());
00112 }
00113 
00114 GLC_Point2d GLC_Viewport::mapNormalyzeToOpenGLScreen(double x, double y)
00115 {
00116         GLC_Point2d pos(x, y);
00117         pos= pos * 2.0;
00118         pos.setY(pos.getY() * -1.0);
00119         pos= pos + GLC_Point2d(-1.0, 1.0);
00120         return pos;
00121 }
00122 
00123 GLC_Vector3d GLC_Viewport::mapPosMouse( GLdouble Posx, GLdouble Posy) const
00124 {
00125         // Change the window origin (Up Left -> centred)
00126         Posx= Posx - static_cast<double>(m_WindowHSize)  / 2.0;
00127         Posy= static_cast<double>(m_WindowVSize) / 2.0 - Posy;
00128 
00129         GLC_Vector3d VectMouse(Posx, Posy,0);
00130 
00131         // Compute the length of camera's field of view
00132         const double ChampsVision = m_pViewCam->distEyeTarget() *  m_ViewTangent;
00133 
00134         // the side of camera's square is mapped on Vertical length of window
00135         // Ratio OpenGL/Pixel = dimend GL / dimens Pixel
00136         const double Ratio= ChampsVision / static_cast<double>(m_WindowVSize);
00137 
00138         VectMouse= VectMouse * Ratio;
00139 
00140         return VectMouse;
00141 }
00142 
00143 GLC_Vector3d GLC_Viewport::mapNormalyzePosMouse(double Posx, double Posy) const
00144 {
00145         double screenX= Posx * static_cast<double>(m_WindowHSize);
00146         double screenY= Posy * static_cast<double>(m_WindowVSize);
00147         return mapPosMouse(screenX, screenY);
00148 }
00149 
00151 // Public OpenGL Functions
00153 
00154 void GLC_Viewport::initGl()
00155 {
00156         m_pQGLWidget->qglClearColor(m_BackgroundColor);       // Background
00157         glClearDepth(1.0f);                                   // Depth Buffer Setup
00158         glShadeModel(GL_SMOOTH);                              // Enable Smooth Shading
00159         glEnable(GL_DEPTH_TEST);                              // Enables Depth Testing
00160         glDepthFunc(GL_LEQUAL);                               // The Type Of Depth Testing To Do
00161         glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);    // Really Nice Perspective Calculation
00162         glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
00163         glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
00164         glPolygonOffset (1.0f, 1.0f);
00165 }
00166 
00167 void GLC_Viewport::glExecuteCam(void)
00168 {
00169         renderImagePlane();
00170         m_pViewCam->glExecute();
00171 }
00172 
00173 void GLC_Viewport::updateProjectionMat(void)
00174 {
00175         GLC_Context::current()->glcMatrixMode(GL_PROJECTION);                                           // select The Projection Matrix
00176         GLC_Context::current()->glcLoadIdentity();                                                                      // Reset The Projection Matrix
00177 
00178         if (m_UseParallelProjection)
00179         {
00180                 const double ChampsVision = m_pViewCam->distEyeTarget() * m_ViewTangent;
00181                 const double height= ChampsVision;
00182                 const double with= ChampsVision * m_AspectRatio;
00183                 const double left= -with * 0.5;
00184                 const double right=  -left;
00185                 const double bottom= - height * 0.5;
00186                 const double top= -bottom;
00187                 GLC_Context::current()->glcOrtho(left, right, bottom, top, m_dDistanceMini, m_DistanceMax);
00188         }
00189         else
00190         {
00191             const double yMax= m_dDistanceMini * tan(m_ViewAngle * glc::PI / 360.0);
00192             const double yMin= -yMax;
00193             const double xMax= yMax * m_AspectRatio;
00194             const double xMin= -xMax;
00195             GLC_Context::current()->glcFrustum(xMin, xMax, yMin, yMax, m_dDistanceMini, m_DistanceMax);
00196         }
00197 
00198         // Save the projection matrix
00199         m_ProjectionMatrix= GLC_Context::current()->projectionMatrix();
00200 
00201         GLC_Context::current()->glcMatrixMode(GL_MODELVIEW);                                                    // select The Modelview Matrix
00202 }
00203 
00204 void GLC_Viewport::forceAspectRatio(double ratio)
00205 {
00206         m_AspectRatio= ratio;
00207         updateProjectionMat();
00208 }
00209 
00210 void GLC_Viewport::updateAspectRatio()
00211 {
00212         // Update The Aspect Ratio Of The Window
00213         m_AspectRatio= static_cast<double>(m_WindowHSize)/static_cast<double>(m_WindowVSize);
00214 }
00215 GLC_Frustum GLC_Viewport::selectionFrustum(int x, int y) const
00216 {
00217         const int halfSize= m_SelectionSquareSize / 2;
00218         // Calculate the 4 points of the selection
00219         //p1->p2
00220         //
00221         //p0  p3
00222         QList<int> coordinates;
00223         // Point 0
00224         coordinates << (x - halfSize) << (y + halfSize);
00225         // Point 1
00226         coordinates << (x - halfSize) << (y - halfSize);
00227         // Point 2
00228         coordinates << (x + halfSize) << (y - halfSize);
00229         // Point 3
00230         coordinates << (x + halfSize) << (y + halfSize);
00231 
00232         // Unproject the 4 point
00233         QList<GLC_Point3d> listOfPoint= unproject(coordinates);
00234 
00235         Q_ASSERT(4 == listOfPoint.size());
00236         // Create the four frustum planes
00237         GLC_Point3d eye= m_pViewCam->eye();
00238         const GLC_Plane leftPlane(listOfPoint.at(0), listOfPoint.at(1), eye);
00239         const GLC_Plane rightPlane(listOfPoint.at(3), eye , listOfPoint.at(2));
00240         const GLC_Plane upPlane(listOfPoint.at(2), eye, listOfPoint.at(1));
00241         const GLC_Plane bottomPlane(listOfPoint.at(0), eye, listOfPoint.at(3));
00242 
00243         GLC_Frustum selectionFrustum(m_Frustum);
00244         selectionFrustum.setLeftClippingPlane(leftPlane);
00245         selectionFrustum.setRightClippingPlane(rightPlane);
00246         selectionFrustum.setTopClippingPlane(upPlane);
00247         selectionFrustum.setBottomClippingPlane(bottomPlane);
00248 
00249         return selectionFrustum;
00250 }
00251 
00252 GLC_Point3d GLC_Viewport::unProject(int x, int y) const
00253 {
00254         // Z Buffer component of the given coordinate is between 0 and 1
00255         GLfloat Depth;
00256         // read selected point
00257         glReadPixels(x, m_WindowVSize - y , 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &Depth);
00258 
00259         // The current viewport opengl definition
00260         GLint Viewport[4];
00261         glGetIntegerv(GL_VIEWPORT, Viewport);
00262 
00263         // OpenGL ccordinate of selected point
00264         GLdouble pX, pY, pZ;
00265         glc::gluUnProject((GLdouble) x, (GLdouble) (m_WindowVSize - y) , Depth
00266                 , m_pViewCam->modelViewMatrix().getData(), m_ProjectionMatrix.getData(), Viewport, &pX, &pY, &pZ);
00267 
00268         return GLC_Point3d(pX, pY, pZ);
00269 }
00270 
00271 QList<GLC_Point3d> GLC_Viewport::unproject(const QList<int>& list)const
00272 {
00273         const int size= list.size();
00274         Q_ASSERT((size % 2) == 0);
00275 
00276         // The current viewport opengl definition
00277         GLint Viewport[4];
00278         glGetIntegerv(GL_VIEWPORT, Viewport);
00279 
00280         // Z Buffer component of the given coordinate is between 0 and 1
00281         GLfloat Depth;
00282 
00283         // Coordinate of readed points
00284         GLdouble pX, pY, pZ;
00285         QList<GLC_Point3d> unprojectedPoints;
00286         for (int i= 0; i < size; i+= 2)
00287         {
00288                 const int x= list.at(i);
00289                 const int y= m_WindowVSize - list.at(i + 1);
00290                 glReadPixels(x, y , 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &Depth);
00291 
00292                 glc::gluUnProject(static_cast<GLdouble>(x), static_cast<GLdouble>(y) , Depth , m_pViewCam->modelViewMatrix().getData()
00293                                 , m_ProjectionMatrix.getData(), Viewport, &pX, &pY, &pZ);
00294                 unprojectedPoints.append(GLC_Point3d(pX, pY, pZ));
00295         }
00296 
00297         return unprojectedPoints;
00298 }
00299 
00301 // Private OpenGL Functions
00303 
00304 void GLC_Viewport::renderImagePlane()
00305 {
00306 
00307         if(!GLC_State::isInSelectionMode())
00308         {
00309                 if (m_pImagePlane != NULL)
00310                 {
00311                         m_pImagePlane->render();
00312                 }
00313         }
00314 }
00315 
00316 void GLC_Viewport::render3DWidget()
00317 {
00318         m_3DWidgetCollection.render(0, glc::WireRenderFlag);
00319         m_3DWidgetCollection.render(0, glc::TransparentRenderFlag);
00320 }
00322 // Set Functions
00324 
00325 void GLC_Viewport::setWinGLSize(int HSize, int VSize)
00326 {
00327         m_WindowHSize= HSize;
00328         m_WindowVSize= VSize;
00329 
00330         // from NeHe's Tutorial 3
00331         if (m_WindowVSize == 0)                                                         // Prevent A Divide By Zero By
00332         {
00333                 m_WindowVSize= 1;                                                                       // Making Height Equal One
00334         }
00335 
00336         glViewport(0,0,m_WindowHSize,m_WindowVSize);                    // Reset The Current Viewport
00337 
00338         updateAspectRatio();
00339 
00340         updateProjectionMat();
00341 
00342         updateMinimumRatioSize();
00343 }
00344 
00345 GLC_uint GLC_Viewport::renderAndSelect(int x, int y)
00346 {
00347 
00348         m_pQGLWidget->qglClearColor(Qt::black);
00349         GLC_State::setSelectionMode(true);
00350         // Draw the scene
00351         m_pQGLWidget->updateGL();
00352         GLC_State::setSelectionMode(false);
00353 
00354         return selectOnPreviousRender(x, y);
00355 }
00356 
00357 GLC_uint GLC_Viewport::selectOnPreviousRender(int x, int y)
00358 {
00359         GLsizei width= m_SelectionSquareSize;
00360         GLsizei height= width;
00361         GLint newX= x - width / 2;
00362         GLint newY= (m_pQGLWidget->size().height() - y) - height / 2;
00363         if (newX < 0) newX= 0;
00364         if (newY < 0) newY= 0;
00365 
00366         return meaningfulIdInsideSquare(newX, newY, width, height);
00367 }
00368 GLC_uint GLC_Viewport::selectBody(GLC_3DViewInstance* pInstance, int x, int y)
00369 {
00370         m_pQGLWidget->qglClearColor(Qt::black);
00371         GLC_State::setSelectionMode(true);
00372         glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
00373         GLC_Context::current()->glcLoadIdentity();
00374 
00375         glExecuteCam();
00376 
00377         // Draw the scene
00378         glDisable(GL_BLEND);
00379         GLC_Context::current()->glcEnableLighting(false);
00380         glDisable(GL_TEXTURE_2D);
00381 
00382         pInstance->renderForBodySelection();
00383         GLC_State::setSelectionMode(false);
00384 
00385         GLsizei width= 6;
00386         GLsizei height= width;
00387         GLint newX= x - width / 2;
00388         GLint newY= (m_pQGLWidget->size().height() - y) - height / 2;
00389         if (newX < 0) newX= 0;
00390         if (newY < 0) newY= 0;
00391 
00392         return meaningfulIdInsideSquare(newX, newY, width, height);
00393 }
00394 
00395 QPair<int, GLC_uint> GLC_Viewport::selectPrimitive(GLC_3DViewInstance* pInstance, int x, int y)
00396 {
00397         QPair<int, GLC_uint> result;
00398 
00399         m_pQGLWidget->qglClearColor(Qt::black);
00400         GLC_State::setSelectionMode(true);
00401         glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
00402         GLC_Context::current()->glcLoadIdentity();
00403 
00404         glExecuteCam();
00405 
00406         // Draw the scene
00407         glDisable(GL_BLEND);
00408         GLC_Context::current()->glcEnableLighting(false);
00409         glDisable(GL_TEXTURE_2D);
00410 
00411         pInstance->renderForBodySelection();
00412 
00413 
00414         GLsizei width= 6;
00415         GLsizei height= width;
00416         GLint newX= x - width / 2;
00417         GLint newY= (m_pQGLWidget->size().height() - y) - height / 2;
00418         if (newX < 0) newX= 0;
00419         if (newY < 0) newY= 0;
00420 
00421         GLC_uint bodyId= meaningfulIdInsideSquare(newX, newY, width, height);
00422         if (bodyId == 0)
00423         {
00424                 result.first= -1;
00425                 result.second= 0;
00426         }
00427         else
00428         {
00429                 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
00430 
00431                 result.first= pInstance->renderForPrimitiveSelection(bodyId);
00432                 result.second= meaningfulIdInsideSquare(newX, newY, width, height);
00433         }
00434         GLC_State::setSelectionMode(false);
00435         return result;
00436 }
00437 
00438 QSet<GLC_uint> GLC_Viewport::selectInsideSquare(int x1, int y1, int x2, int y2)
00439 {
00440         if (x1 > x2)
00441         {
00442                 int xTemp= x1;
00443                 x1= x2;
00444                 x2= xTemp;
00445         }
00446         if (y2 > y1)
00447         {
00448                 int yTemp= y1;
00449                 y1= y2;
00450                 y2= yTemp;
00451         }
00452         m_pQGLWidget->qglClearColor(Qt::black);
00453         GLC_State::setSelectionMode(true);
00454         // Draw the scene
00455         m_pQGLWidget->updateGL();
00456         GLC_State::setSelectionMode(false);
00457 
00458         GLsizei width= x2 - x1;
00459         GLsizei height= y1 - y2;
00460         GLint newX= x1;
00461         GLint newY= (m_pQGLWidget->size().height() - y1);
00462         if (newX < 0) newX= 0;
00463         if (newY < 0) newY= 0;
00464 
00465         return listOfIdInsideSquare(newX, newY, width, height);
00466 }
00467 
00468 GLC_uint GLC_Viewport::meaningfulIdInsideSquare(GLint x, GLint y, GLsizei width, GLsizei height)
00469 {
00470         const int squareSize= width * height;
00471         const GLsizei arraySize= squareSize * 4; // 4 -> R G B A
00472         QVector<GLubyte> colorId(arraySize);
00473 
00474         // Get the array of pixels
00475         glReadPixels(x, y, width, height, GL_RGBA, GL_UNSIGNED_BYTE, colorId.data());
00476 
00477         // Restore Background color
00478         m_pQGLWidget->qglClearColor(m_BackgroundColor);
00479 
00480         QHash<GLC_uint, int> idHash;
00481         QList<int> idWeight;
00482 
00483         // Find the most meaningful color
00484         GLC_uint returnId= 0;
00485         // There is nothing at the center
00486         int maxWeight= 0;
00487         int currentIndex= 0;
00488         for (int i= 0; i < squareSize; ++i)
00489         {
00490                 GLC_uint id= glc::decodeRgbId(&colorId[i * 4]);
00491                 if (idHash.contains(id))
00492                 {
00493                         const int currentWeight= ++(idWeight[idHash.value(id)]);
00494                         if (maxWeight < currentWeight)
00495                         {
00496                                 returnId= id;
00497                                 maxWeight= currentWeight;
00498                         }
00499                 }
00500                 else if (id != 0)
00501                 {
00502                         idHash.insert(id, currentIndex++);
00503                         idWeight.append(1);
00504                         if (maxWeight < 1)
00505                         {
00506                                 returnId= id;
00507                                 maxWeight= 1;
00508                         }
00509                 }
00510         }
00511 
00512         return returnId;
00513 }
00514 
00515 QSet<GLC_uint> GLC_Viewport::listOfIdInsideSquare(GLint x, GLint y, GLsizei width, GLsizei height)
00516 {
00517         const int squareSize= width * height;
00518         const GLsizei arraySize= squareSize * 4; // 4 -> R G B A
00519         QVector<GLubyte> colorId(arraySize);
00520 
00521         // Get the array of pixels
00522         glReadPixels(x, y, width, height, GL_RGBA, GL_UNSIGNED_BYTE, colorId.data());
00523 
00524         // Restore Background color
00525         m_pQGLWidget->qglClearColor(m_BackgroundColor);
00526 
00527         QSet<GLC_uint> idSet;
00528 
00529         // get the color inside square
00530         for (int i= 0; i < squareSize; ++i)
00531         {
00532                 GLC_uint id= glc::decodeRgbId(&colorId[i * 4]);
00533                 idSet << id;
00534         }
00535 
00536         return idSet;
00537 }
00538 
00539 void GLC_Viewport::updateMinimumRatioSize()
00540 {
00541         int size= qMax(m_WindowHSize, m_WindowVSize);
00542         m_MinimumStaticRatioSize=  static_cast<double>(m_MinimumStaticPixelSize) / static_cast<double>(size) * 100.0;
00543         m_MinimumDynamicRatioSize= m_MinimumStaticRatioSize * 2.0;
00544         //qDebug() << "GLC_Viewport::updateMinimumRatioSize() m_MinimumRatioSize " << m_MinimumStaticRatioSize;
00545 }
00546 
00547 void GLC_Viewport::loadBackGroundImage(const QString& ImageFile)
00548 {
00549         delete m_pImagePlane;
00550         m_pImagePlane= new GLC_ImagePlane(ImageFile);
00551 }
00552 
00553 void GLC_Viewport::loadBackGroundImage(const QImage& image)
00554 {
00555         delete m_pImagePlane;
00556         m_pImagePlane= new GLC_ImagePlane(image);
00557 }
00558 
00559 void GLC_Viewport::deleteBackGroundImage()
00560 {
00561         delete m_pImagePlane;
00562         m_pImagePlane= NULL;
00563 }
00564 
00565 void GLC_Viewport::setToOrtho(bool useOrtho)
00566 {
00567         if (m_UseParallelProjection != useOrtho)
00568         {
00569                 m_UseParallelProjection= useOrtho;
00570                 updateProjectionMat();
00571         }
00572 
00573 }
00574 
00575 void GLC_Viewport::reframe(const GLC_BoundingBox& box)
00576 {
00577         Q_ASSERT(!box.isEmpty());
00578 
00579         // Center view on the BoundingBox
00580         const GLC_Vector3d deltaVector(box.center() - m_pViewCam->target());
00581         m_pViewCam->translate(deltaVector);
00582 
00583         double cameraCover= box.boundingSphereRadius() * 2.0;
00584 
00585         // Compute Camera distance
00586         const double distance = cameraCover / m_ViewTangent;
00587 
00588         // Update Camera position
00589         m_pViewCam->setDistEyeTarget(distance);
00590 }
00591 
00592 bool GLC_Viewport::setDistMin(double DistMin)
00593 {
00594         DistMin= fabs(DistMin);
00595         if (DistMin < m_DistanceMax)
00596         {
00597                 m_dDistanceMini= DistMin;
00598 
00599                 updateProjectionMat();  // Update OpenGL projection matrix
00600 
00601                 return true;
00602         }
00603         else
00604         {
00605                 qDebug("GLC_Viewport::SetDistMin : KO");
00606                 return false;
00607         }
00608 
00609 }
00610 
00611 bool GLC_Viewport::setDistMax(double DistMax)
00612 {
00613         DistMax= fabs(DistMax);
00614         if (DistMax > m_dDistanceMini)
00615         {
00616                 m_DistanceMax= DistMax;
00617 
00618                 // Update OpenGL projection matrix
00619                 updateProjectionMat();
00620 
00621                 return true;
00622         }
00623         else
00624         {
00625                 qDebug("GLC_Viewport::SetDistMax : KO");
00626                 return false;
00627         }
00628 }
00629 
00630 void GLC_Viewport::setDistMinAndMax(const GLC_BoundingBox& bBox)
00631 {
00632         if(!bBox.isEmpty())
00633         {
00634                 // The scene is not empty
00635                 GLC_Matrix4x4 matComp(m_pViewCam->modelViewMatrix());
00636 
00637                 // The bounding Box in Camera coordinate
00638                 GLC_BoundingBox boundingBox(bBox);
00639                 boundingBox.transform(matComp);
00640 
00641                 // Increase size of the bounding box
00642                 const double increaseFactor= 1.1;
00643                 // Convert box distance in sphere distance
00644                 const double center= fabs(boundingBox.center().z());
00645                 const double radius= boundingBox.boundingSphereRadius();
00646                 const double min= center - radius * increaseFactor;
00647                 const double max= center + radius * increaseFactor;
00648 
00649                 GLC_Point3d camEye(m_pViewCam->eye());
00650                 camEye= matComp * camEye;
00651 
00652                 if (min > 0.0)
00653                 {
00654                         // Outside bounding Sphere
00655                         m_dDistanceMini= min;
00656                         m_DistanceMax= max;
00657                         //qDebug() << "distmin" << m_dCamDistMin;
00658                         //qDebug() << "distmax" << m_dCamDistMax;
00659                 }
00660                 else
00661                 {
00662                         // Inside bounding Sphere
00663                         m_dDistanceMini= qMin(0.01 * radius, m_pViewCam->distEyeTarget() / 4.0);
00664                         m_DistanceMax= max;
00665                         //qDebug() << "inside distmin" << m_dCamDistMin;
00666                         //qDebug() << "inside distmax" << m_dCamDistMax;
00667                 }
00668         }
00669         else
00670         {
00671                 // The scene is empty
00672                 m_dDistanceMini= m_pViewCam->distEyeTarget() / 2.0;
00673                 m_DistanceMax= m_pViewCam->distEyeTarget();
00674         }
00675 
00676         // Update OpenGL projection matrix
00677         updateProjectionMat();
00678 }
00679 
00680 void GLC_Viewport::setBackgroundColor(QColor setColor)
00681 {
00682         m_BackgroundColor= setColor;
00683         m_pQGLWidget->qglClearColor(m_BackgroundColor);
00684 }
00685 
00686 void GLC_Viewport::addClipPlane(GLenum planeGlEnum,GLC_Plane* pPlane)
00687 {
00688         if (m_ClipPlanesHash.contains(planeGlEnum))
00689         {
00690                 delete m_ClipPlanesHash.value(planeGlEnum);
00691                 m_ClipPlanesHash.remove(planeGlEnum);
00692         }
00693         m_ClipPlanesHash.insert(planeGlEnum, pPlane);
00694 }
00695 
00696 void GLC_Viewport::removeClipPlane(GLenum planeGlEnum)
00697 {
00698         if (m_ClipPlanesHash.contains(planeGlEnum))
00699         {
00700                 delete m_ClipPlanesHash.value(planeGlEnum);
00701                 m_ClipPlanesHash.remove(planeGlEnum);
00702         }
00703         else
00704         {
00705                 qDebug() << "GLC_Viewport::removeClipPlane Clipp plane " << planeGlEnum << " Not found";
00706         }
00707 }
00708 
00709 void GLC_Viewport::removeAllClipPlane()
00710 {
00711         // Delete clip planes
00712         QHash<GLenum, GLC_Plane*>::iterator iClip= m_ClipPlanesHash.begin();
00713         while (m_ClipPlanesHash.constEnd() != iClip)
00714         {
00715                 delete iClip.value();
00716                 ++iClip;
00717         }
00718 }
00719 
00720 void GLC_Viewport::useClipPlane(bool flag)
00721 {
00722         m_UseClipPlane= flag;
00723         if (m_UseClipPlane)
00724         {
00725                 QHash<GLenum, GLC_Plane*>::iterator iClip= m_ClipPlanesHash.begin();
00726                 while (m_ClipPlanesHash.constEnd() != iClip)
00727                 {
00728                         GLenum planeKey= iClip.key();
00729                         GLC_Plane* pPlane= iClip.value();
00730 
00731                         glClipPlane (planeKey, pPlane->data());
00732                         glEnable (planeKey);
00733                         ++iClip;
00734                 }
00735         }
00736         else
00737         {
00738                 QHash<GLenum, GLC_Plane*>::iterator iClip= m_ClipPlanesHash.begin();
00739                 while (m_ClipPlanesHash.constEnd() != iClip)
00740                 {
00741                         glDisable(iClip.key());
00742                         ++iClip;
00743                 }
00744         }
00745 
00746 }

SourceForge.net Logo

©2005-2011 Laurent Ribon