glc_3dviewinstance.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 "glc_3dviewinstance.h"
00026 #include "../shading/glc_selectionmaterial.h"
00027 #include "../viewport/glc_viewport.h"
00028 #include <QMutexLocker>
00029 #include "../glc_state.h"
00030 
00032 QMutex GLC_3DViewInstance::m_Mutex;
00033 
00035 int GLC_3DViewInstance::m_GlobalDefaultLOD= 10;
00036 
00037 
00039 // Construction/Destruction
00041 
00042 // Default constructor
00043 GLC_3DViewInstance::GLC_3DViewInstance()
00044 : GLC_Object()
00045 , m_3DRep()
00046 , m_pBoundingBox(NULL)
00047 , m_AbsoluteMatrix()
00048 , m_IsBoundingBoxValid(false)
00049 , m_RenderProperties()
00050 , m_IsVisible(true)
00051 , m_DefaultLOD(m_GlobalDefaultLOD)
00052 , m_ViewableFlag(GLC_3DViewInstance::FullViewable)
00053 , m_ViewableGeomFlag()
00054 {
00055         // Encode Color Id
00056         glc::encodeRgbId(m_Uid, m_colorId);
00057 
00058         //qDebug() << "GLC_3DViewInstance::GLC_3DViewInstance null instance ID = " << m_Uid;
00059         //qDebug() << "Number of instance" << (*m_pNumberOfInstance);
00060 }
00061 
00062 // Contruct instance with a geometry
00063 GLC_3DViewInstance::GLC_3DViewInstance(GLC_Geometry* pGeom)
00064 : GLC_Object()
00065 , m_3DRep(pGeom)
00066 , m_pBoundingBox(NULL)
00067 , m_AbsoluteMatrix()
00068 , m_IsBoundingBoxValid(false)
00069 , m_RenderProperties()
00070 , m_IsVisible(true)
00071 , m_DefaultLOD(m_GlobalDefaultLOD)
00072 , m_ViewableFlag(GLC_3DViewInstance::FullViewable)
00073 , m_ViewableGeomFlag()
00074 {
00075         // Encode Color Id
00076         glc::encodeRgbId(m_Uid, m_colorId);
00077 
00078         setName(m_3DRep.name());
00079 
00080         //qDebug() << "GLC_3DViewInstance::GLC_3DViewInstance ID = " << m_Uid;
00081         //qDebug() << "Number of instance" << (*m_pNumberOfInstance);
00082 }
00083 
00084 // Contruct instance with a 3DRep
00085 GLC_3DViewInstance::GLC_3DViewInstance(const GLC_3DRep& rep)
00086 : GLC_Object()
00087 , m_3DRep(rep)
00088 , m_pBoundingBox(NULL)
00089 , m_AbsoluteMatrix()
00090 , m_IsBoundingBoxValid(false)
00091 , m_RenderProperties()
00092 , m_IsVisible(true)
00093 , m_DefaultLOD(m_GlobalDefaultLOD)
00094 , m_ViewableFlag(GLC_3DViewInstance::FullViewable)
00095 , m_ViewableGeomFlag()
00096 {
00097         // Encode Color Id
00098         glc::encodeRgbId(m_Uid, m_colorId);
00099 
00100         setName(m_3DRep.name());
00101 
00102         //qDebug() << "GLC_3DViewInstance::GLC_3DViewInstance ID = " << m_Uid;
00103         //qDebug() << "Number of instance" << (*m_pNumberOfInstance);
00104 }
00105 
00106 // Copy constructor
00107 GLC_3DViewInstance::GLC_3DViewInstance(const GLC_3DViewInstance& inputNode)
00108 : GLC_Object(inputNode)
00109 , m_3DRep(inputNode.m_3DRep)
00110 , m_pBoundingBox(NULL)
00111 , m_AbsoluteMatrix(inputNode.m_AbsoluteMatrix)
00112 , m_IsBoundingBoxValid(inputNode.m_IsBoundingBoxValid)
00113 , m_RenderProperties(inputNode.m_RenderProperties)
00114 , m_IsVisible(inputNode.m_IsVisible)
00115 , m_DefaultLOD(inputNode.m_DefaultLOD)
00116 , m_ViewableFlag(inputNode.m_ViewableFlag)
00117 , m_ViewableGeomFlag(inputNode.m_ViewableGeomFlag)
00118 {
00119         // Encode Color Id
00120         glc::encodeRgbId(m_Uid, m_colorId);
00121 
00122         if (NULL != inputNode.m_pBoundingBox)
00123         {
00124                 m_pBoundingBox= new GLC_BoundingBox(*inputNode.m_pBoundingBox);
00125         }
00126 }
00127 
00128 
00129 // Assignement operator
00130 GLC_3DViewInstance& GLC_3DViewInstance::operator=(const GLC_3DViewInstance& inputNode)
00131 {
00132         if (this != &inputNode)
00133         {
00134                 // Clear this instance
00135                 clear();
00136                 GLC_Object::operator=(inputNode);
00137                 // Encode Color Id
00138                 glc::encodeRgbId(m_Uid, m_colorId);
00139 
00140                 m_3DRep= inputNode.m_3DRep;
00141                 if (NULL != inputNode.m_pBoundingBox)
00142                 {
00143                         m_pBoundingBox= new GLC_BoundingBox(*inputNode.m_pBoundingBox);
00144                 }
00145                 m_AbsoluteMatrix= inputNode.m_AbsoluteMatrix;
00146                 m_IsBoundingBoxValid= inputNode.m_IsBoundingBoxValid;
00147                 m_RenderProperties= inputNode.m_RenderProperties;
00148                 m_IsVisible= inputNode.m_IsVisible;
00149                 m_DefaultLOD= inputNode.m_DefaultLOD;
00150                 m_ViewableFlag= inputNode.m_ViewableFlag;
00151                 m_ViewableGeomFlag= inputNode.m_ViewableGeomFlag;
00152 
00153                 //qDebug() << "GLC_3DViewInstance::operator= :ID = " << m_Uid;
00154                 //qDebug() << "Number of instance" << (*m_pNumberOfInstance);
00155         }
00156 
00157         return *this;
00158 }
00159 
00160 // Destructor
00161 GLC_3DViewInstance::~GLC_3DViewInstance()
00162 {
00163         clear();
00164 }
00165 
00167 // Get Functions
00169 
00170 // Get the bounding box
00171 GLC_BoundingBox GLC_3DViewInstance::boundingBox(void)
00172 {
00173         GLC_BoundingBox resultBox;
00174         if (boundingBoxValidity())
00175         {
00176                 resultBox= *m_pBoundingBox;
00177         }
00178         else if (!m_3DRep.isEmpty())
00179         {
00180                 computeBoundingBox();
00181                 m_IsBoundingBoxValid= true;
00182                 resultBox= *m_pBoundingBox;
00183         }
00184 
00185         return resultBox;
00186 }
00187 
00189 void GLC_3DViewInstance::setGlobalDefaultLod(int lod)
00190 {
00191         QMutexLocker locker(&m_Mutex);
00192         m_GlobalDefaultLOD= lod;
00193 }
00194 
00195 void GLC_3DViewInstance::setVboUsage(bool usage)
00196 {
00197         m_3DRep.setVboUsage(usage);
00198 }
00199 
00200 // Clone the instance
00201 GLC_3DViewInstance GLC_3DViewInstance::deepCopy() const
00202 {
00203 
00204         GLC_3DRep* pRep= dynamic_cast<GLC_3DRep*>(m_3DRep.deepCopy());
00205         Q_ASSERT(NULL != pRep);
00206         GLC_3DRep newRep(*pRep);
00207         delete pRep;
00208         GLC_3DViewInstance cloneInstance(newRep);
00209 
00210         if (NULL != m_pBoundingBox)
00211         {
00212                 cloneInstance.m_pBoundingBox= new GLC_BoundingBox(*m_pBoundingBox);
00213         }
00214 
00215         cloneInstance.m_AbsoluteMatrix= m_AbsoluteMatrix;
00216         cloneInstance.m_IsBoundingBoxValid= m_IsBoundingBoxValid;
00217         cloneInstance.m_RenderProperties= m_RenderProperties;
00218         cloneInstance.m_IsVisible= m_IsVisible;
00219         cloneInstance.m_ViewableFlag= m_ViewableFlag;
00220         return cloneInstance;
00221 }
00222 
00223 // Instanciate the instance
00224 GLC_3DViewInstance GLC_3DViewInstance::instanciate()
00225 {
00226         GLC_3DViewInstance instance(*this);
00227         instance.m_Uid= glc::GLC_GenID();
00228         // Encode Color Id
00229         glc::encodeRgbId(m_Uid, m_colorId);
00230 
00231         return instance;
00232 }
00233 
00235 // Set Functions
00237 
00238 
00239 // Set the instance Geometry
00240 bool GLC_3DViewInstance::addGeometry(GLC_Geometry* pGeom)
00241 {
00242         if (m_3DRep.contains(pGeom))
00243         {
00244                 return false;
00245         }
00246         else
00247         {
00248                 m_3DRep.addGeom(pGeom);
00249                 return true;
00250         }
00251 }
00252 
00253 // Instance translation
00254 GLC_3DViewInstance& GLC_3DViewInstance::translate(double Tx, double Ty, double Tz)
00255 {
00256         multMatrix(GLC_Matrix4x4(Tx, Ty, Tz));
00257 
00258         return *this;
00259 }
00260 
00261 
00262 // Move instance with a 4x4Matrix
00263 GLC_3DViewInstance& GLC_3DViewInstance::multMatrix(const GLC_Matrix4x4 &MultMat)
00264 {
00265         m_AbsoluteMatrix= MultMat * m_AbsoluteMatrix;
00266         m_IsBoundingBoxValid= false;
00267 
00268         return *this;
00269 }
00270 
00271 // Replace the instance Matrix
00272 GLC_3DViewInstance& GLC_3DViewInstance::setMatrix(const GLC_Matrix4x4 &SetMat)
00273 {
00274         m_AbsoluteMatrix= SetMat;
00275         m_IsBoundingBoxValid= false;
00276 
00277         return *this;
00278 }
00279 
00280 // Reset the instance Matrix
00281 GLC_3DViewInstance& GLC_3DViewInstance::resetMatrix(void)
00282 {
00283         m_AbsoluteMatrix.setToIdentity();
00284         m_IsBoundingBoxValid= false;
00285 
00286         return *this;
00287 }
00288 
00290 // OpenGL Functions
00292 
00293 // Display the instance
00294 void GLC_3DViewInstance::render(glc::RenderFlag renderFlag, bool useLod, GLC_Viewport* pView)
00295 {
00296         //qDebug() << "GLC_3DViewInstance::render render properties= " << m_RenderProperties.renderingMode();
00297         if (m_3DRep.isEmpty()) return;
00298         const int bodyCount= m_3DRep.numberOfBody();
00299 
00300         if (bodyCount != m_ViewableGeomFlag.size())
00301         {
00302                 m_ViewableGeomFlag.fill(true, bodyCount);
00303         }
00304 
00305         m_RenderProperties.setRenderingFlag(renderFlag);
00306 
00307         // Save current OpenGL Matrix
00308         GLC_Context::current()->glcPushMatrix();
00309         OpenglVisProperties();
00310 
00311         // Change front face orientation if this instance absolute matrix is indirect
00312         if (m_AbsoluteMatrix.type() == GLC_Matrix4x4::Indirect)
00313         {
00314                 glFrontFace(GL_CW);
00315         }
00316         if(GLC_State::isInSelectionMode())
00317         {
00318                 glColor3ubv(m_colorId); // D'ont use Alpha component
00319         }
00320 
00321         if (useLod && (NULL != pView))
00322         {
00323                 for (int i= 0; i < bodyCount; ++i)
00324                 {
00325                         if (m_ViewableGeomFlag.at(i))
00326                         {
00327                                 const int lodValue= choseLod(m_3DRep.geomAt(i)->boundingBox(), pView, useLod);
00328                                 if (lodValue <= 100)
00329                                 {
00330                                         m_3DRep.geomAt(i)->setCurrentLod(lodValue);
00331                                         m_RenderProperties.setCurrentBodyIndex(i);
00332                                         m_3DRep.geomAt(i)->render(m_RenderProperties);
00333                                 }
00334                         }
00335                 }
00336         }
00337         else
00338         {
00339                 for (int i= 0; i < bodyCount; ++i)
00340                 {
00341                         if (m_ViewableGeomFlag.at(i))
00342                         {
00343                                 int lodValue= 0;
00344                                 if (GLC_State::isPixelCullingActivated() && (NULL != pView))
00345                                 {
00346                                         lodValue= choseLod(m_3DRep.geomAt(i)->boundingBox(), pView, useLod);
00347                                 }
00348 
00349                                 if (lodValue <= 100)
00350                                 {
00351                                         m_3DRep.geomAt(i)->setCurrentLod(m_DefaultLOD);
00352                                         m_RenderProperties.setCurrentBodyIndex(i);
00353                                         m_3DRep.geomAt(i)->render(m_RenderProperties);
00354                                 }
00355                         }
00356                 }
00357         }
00358         // Restore OpenGL Matrix
00359         GLC_Context::current()->glcPopMatrix();
00360 
00361         // Restore front face orientation if this instance absolute matrix is indirect
00362         if (m_AbsoluteMatrix.type() == GLC_Matrix4x4::Indirect)
00363         {
00364                 glFrontFace(GL_CCW);
00365         }
00366 
00367 }
00368 
00369 // Display the instance in Body selection mode
00370 void GLC_3DViewInstance::renderForBodySelection()
00371 {
00372         Q_ASSERT(GLC_State::isInSelectionMode());
00373         if (m_3DRep.isEmpty()) return;
00374 
00375         // Save previous rendering mode and set the rendering mode to BodySelection
00376         glc::RenderMode previousRenderMode= m_RenderProperties.renderingMode();
00377         m_RenderProperties.setRenderingMode(glc::BodySelection);
00378 
00379         // Save current OpenGL Matrix
00380         GLC_Context::current()->glcPushMatrix();
00381         OpenglVisProperties();
00382 
00383         GLubyte colorId[4];
00384         const int size= m_3DRep.numberOfBody();
00385         for (int i= 0; i < size; ++i)
00386         {
00387                 GLC_Geometry* pGeom= m_3DRep.geomAt(i);
00388                 glc::encodeRgbId(pGeom->id(), colorId);
00389                 glColor3ubv(colorId);
00390                 pGeom->setCurrentLod(m_DefaultLOD);
00391                 m_RenderProperties.setCurrentBodyIndex(i);
00392                 pGeom->render(m_RenderProperties);
00393         }
00394 
00395         // Restore rendering mode
00396         m_RenderProperties.setRenderingMode(previousRenderMode);
00397         // Restore OpenGL Matrix
00398         GLC_Context::current()->glcPopMatrix();
00399 }
00400 
00401 // Display the instance in Primitive selection mode and return the body index
00402 int GLC_3DViewInstance::renderForPrimitiveSelection(GLC_uint bodyId)
00403 {
00404         Q_ASSERT(GLC_State::isInSelectionMode());
00405         if (m_3DRep.isEmpty()) return -1;
00406         // Save previous rendering mode and set the rendering mode to BodySelection
00407         glc::RenderMode previousRenderMode= m_RenderProperties.renderingMode();
00408         m_RenderProperties.setRenderingMode(glc::PrimitiveSelection);
00409 
00410         // Save current OpenGL Matrix
00411         GLC_Context::current()->glcPushMatrix();
00412         OpenglVisProperties();
00413 
00414         const int size= m_3DRep.numberOfBody();
00415         int i= 0;
00416         bool continu= true;
00417         while ((i < size) && continu)
00418         {
00419                 GLC_Geometry* pGeom= m_3DRep.geomAt(i);
00420                 if (pGeom->id() == bodyId)
00421                 {
00422                         pGeom->setCurrentLod(0);
00423                         pGeom->render(m_RenderProperties);
00424                         continu= false;
00425                 }
00426                 else ++i;
00427         }
00428 
00429         m_RenderProperties.setRenderingMode(previousRenderMode);
00430 
00431         // Restore OpenGL Matrix
00432         GLC_Context::current()->glcPopMatrix();
00433 
00434         return i;
00435 }
00436 
00437 
00438 
00440 // private services functions
00442 
00443 
00444 // compute the instance bounding box
00445 // m_pGeomList should be not null
00446 void GLC_3DViewInstance::computeBoundingBox(void)
00447 {
00448         if (m_3DRep.isEmpty()) return;
00449 
00450         if (m_pBoundingBox != NULL)
00451         {
00452                 delete m_pBoundingBox;
00453                 m_pBoundingBox= NULL;
00454         }
00455         m_pBoundingBox= new GLC_BoundingBox();
00456         const int size= m_3DRep.numberOfBody();
00457         for (int i= 0; i < size; ++i)
00458         {
00459                 m_pBoundingBox->combine(m_3DRep.geomAt(i)->boundingBox());
00460         }
00461 
00462         m_pBoundingBox->transform(m_AbsoluteMatrix);
00463 }
00464 
00465 // Clear current instance
00466 void GLC_3DViewInstance::clear()
00467 {
00468 
00469         delete m_pBoundingBox;
00470         m_pBoundingBox= NULL;
00471 
00472         // invalidate the bounding box
00473         m_IsBoundingBoxValid= false;
00474 
00475 }
00476 
00477 // Compute LOD
00478 int GLC_3DViewInstance::choseLod(const GLC_BoundingBox& boundingBox, GLC_Viewport* pView, bool useLod)
00479 {
00480         if (NULL == pView) return 0;
00481         double pixelCullingRatio= 0.0;
00482         if (useLod)
00483         {
00484                 pixelCullingRatio= pView->minimumDynamicPixelCullingRatio();
00485         }
00486         else
00487         {
00488                 pixelCullingRatio= pView->minimumStaticPixelCullingRatio();
00489         }
00490 
00491         const double diameter= boundingBox.boundingSphereRadius() * 2.0 * m_AbsoluteMatrix.scalingX();
00492         GLC_Vector3d center(m_AbsoluteMatrix * boundingBox.center());
00493 
00494         const double dist= (center - pView->cameraHandle()->eye()).length();
00495         const double cameraCover= dist * pView->viewTangent();
00496 
00497         double ratio= diameter / cameraCover * 100.0;
00498         if (ratio > 100.0) ratio= 100.0;
00499         ratio= 100.0 - ratio;
00500 
00501         if ((ratio > (100.0 - pixelCullingRatio)) && GLC_State::isPixelCullingActivated()) ratio= 110.0;
00502         else if(useLod && (ratio > 50.0))
00503         {
00504                 ratio= (ratio - 50.0) / 50.0 * 100.0;
00505                 if (ratio < static_cast<double>(m_DefaultLOD)) ratio= static_cast<double>(m_DefaultLOD);
00506         }
00507         else
00508         {
00509                 ratio= static_cast<double>(m_DefaultLOD);
00510         }
00511 
00512         return static_cast<int>(ratio);
00513 }
00514 
00515 

SourceForge.net Logo

©2005-2011 Laurent Ribon