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

SourceForge.net Logo

©2005-2010 Laurent Ribon