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 // Clone the instance
00196 GLC_3DViewInstance GLC_3DViewInstance::deepCopy() const
00197 {
00198 
00199         GLC_3DRep* pRep= dynamic_cast<GLC_3DRep*>(m_3DRep.deepCopy());
00200         GLC_3DRep newRep(*pRep);
00201         delete pRep;
00202         GLC_3DViewInstance cloneInstance(newRep);
00203 
00204         if (NULL != m_pBoundingBox)
00205         {
00206                 cloneInstance.m_pBoundingBox= new GLC_BoundingBox(*m_pBoundingBox);
00207         }
00208 
00209         cloneInstance.m_AbsoluteMatrix= m_AbsoluteMatrix;
00210         cloneInstance.m_IsBoundingBoxValid= m_IsBoundingBoxValid;
00211         cloneInstance.m_RenderProperties= m_RenderProperties;
00212         cloneInstance.m_IsVisible= m_IsVisible;
00213         cloneInstance.m_ViewableFlag= m_ViewableFlag;
00214         return cloneInstance;
00215 }
00216 
00217 // Instanciate the instance
00218 GLC_3DViewInstance GLC_3DViewInstance::instanciate()
00219 {
00220         GLC_3DViewInstance instance(*this);
00221         instance.m_Uid= glc::GLC_GenID();
00222         // Encode Color Id
00223         glc::encodeRgbId(m_Uid, m_colorId);
00224 
00225         return instance;
00226 }
00227 
00229 // Set Functions
00231 
00232 
00233 // Set the instance Geometry
00234 bool GLC_3DViewInstance::setGeometry(GLC_Geometry* pGeom)
00235 {
00236         if (m_3DRep.contains(pGeom))
00237         {
00238                 return false;
00239         }
00240         else
00241         {
00242                 m_3DRep.addGeom(pGeom);
00243                 return true;
00244         }
00245 }
00246 
00247 // Instance translation
00248 GLC_3DViewInstance& GLC_3DViewInstance::translate(double Tx, double Ty, double Tz)
00249 {
00250         multMatrix(GLC_Matrix4x4(Tx, Ty, Tz));
00251 
00252         return *this;
00253 }
00254 
00255 
00256 // Move instance with a 4x4Matrix
00257 GLC_3DViewInstance& GLC_3DViewInstance::multMatrix(const GLC_Matrix4x4 &MultMat)
00258 {
00259         m_AbsoluteMatrix= MultMat * m_AbsoluteMatrix;
00260         m_IsBoundingBoxValid= false;
00261 
00262         return *this;
00263 }
00264 
00265 // Replace the instance Matrix
00266 GLC_3DViewInstance& GLC_3DViewInstance::setMatrix(const GLC_Matrix4x4 &SetMat)
00267 {
00268         m_AbsoluteMatrix= SetMat;
00269         m_IsBoundingBoxValid= false;
00270 
00271         return *this;
00272 }
00273 
00274 // Reset the instance Matrix
00275 GLC_3DViewInstance& GLC_3DViewInstance::resetMatrix(void)
00276 {
00277         m_AbsoluteMatrix.setToIdentity();
00278         m_IsBoundingBoxValid= false;
00279 
00280         return *this;
00281 }
00282 
00284 // OpenGL Functions
00286 
00287 // Display the instance
00288 void GLC_3DViewInstance::render(glc::RenderFlag renderFlag, bool useLod, GLC_Viewport* pView)
00289 {
00290         //qDebug() << "GLC_3DViewInstance::render render properties= " << m_RenderProperties.renderingMode();
00291         if (m_3DRep.isEmpty()) return;
00292         const int bodyCount= m_3DRep.numberOfBody();
00293 
00294         if (bodyCount != m_ViewableGeomFlag.size())
00295         {
00296                 m_ViewableGeomFlag.fill(true, bodyCount);
00297         }
00298 
00299         m_RenderProperties.setRenderingFlag(renderFlag);
00300 
00301         // Save current OpenGL Matrix
00302         glPushMatrix();
00303         OpenglVisProperties();
00304 
00305         // Change front face orientation if this instance absolute matrix is indirect
00306         if (m_AbsoluteMatrix.type() == GLC_Matrix4x4::Indirect)
00307         {
00308                 glFrontFace(GL_CW);
00309         }
00310         if(GLC_State::isInSelectionMode())
00311         {
00312                 glColor3ubv(m_colorId); // D'ont use Alpha component
00313         }
00314 
00315         if (useLod && (NULL != pView))
00316         {
00317                 for (int i= 0; i < bodyCount; ++i)
00318                 {
00319                         if (m_ViewableGeomFlag.at(i))
00320                         {
00321                                 const int lodValue= choseLod(m_3DRep.geomAt(i)->boundingBox(), pView, useLod);
00322                                 if (lodValue <= 100)
00323                                 {
00324                                         m_3DRep.geomAt(i)->setCurrentLod(lodValue);
00325                                         m_RenderProperties.setCurrentBodyIndex(i);
00326                                         m_3DRep.geomAt(i)->render(m_RenderProperties);
00327                                 }
00328                         }
00329                 }
00330         }
00331         else
00332         {
00333                 for (int i= 0; i < bodyCount; ++i)
00334                 {
00335                         if (m_ViewableGeomFlag.at(i))
00336                         {
00337                                 int lodValue= 0;
00338                                 if (GLC_State::isPixelCullingActivated() && (NULL != pView))
00339                                 {
00340                                         lodValue= choseLod(m_3DRep.geomAt(i)->boundingBox(), pView, useLod);
00341                                 }
00342 
00343                                 if (lodValue <= 100)
00344                                 {
00345                                         m_3DRep.geomAt(i)->setCurrentLod(m_DefaultLOD);
00346                                         m_RenderProperties.setCurrentBodyIndex(i);
00347                                         m_3DRep.geomAt(i)->render(m_RenderProperties);
00348                                 }
00349                         }
00350                 }
00351         }
00352         // Restore OpenGL Matrix
00353         glPopMatrix();
00354 
00355         // Restore front face orientation if this instance absolute matrix is indirect
00356         if (m_AbsoluteMatrix.type() == GLC_Matrix4x4::Indirect)
00357         {
00358                 glFrontFace(GL_CCW);
00359         }
00360 
00361 }
00362 
00363 // Display the instance in Body selection mode
00364 void GLC_3DViewInstance::renderForBodySelection()
00365 {
00366         Q_ASSERT(GLC_State::isInSelectionMode());
00367         if (m_3DRep.isEmpty()) return;
00368 
00369         // Save previous rendering mode and set the rendering mode to BodySelection
00370         glc::RenderMode previousRenderMode= m_RenderProperties.renderingMode();
00371         m_RenderProperties.setRenderingMode(glc::BodySelection);
00372 
00373         // Save current OpenGL Matrix
00374         glPushMatrix();
00375         OpenglVisProperties();
00376 
00377         GLubyte colorId[4];
00378         const int size= m_3DRep.numberOfBody();
00379         for (int i= 0; i < size; ++i)
00380         {
00381                 GLC_Geometry* pGeom= m_3DRep.geomAt(i);
00382                 glc::encodeRgbId(pGeom->id(), colorId);
00383                 glColor3ubv(colorId);
00384                 pGeom->setCurrentLod(m_DefaultLOD);
00385                 m_RenderProperties.setCurrentBodyIndex(i);
00386                 pGeom->render(m_RenderProperties);
00387         }
00388 
00389         // Restore rendering mode
00390         m_RenderProperties.setRenderingMode(previousRenderMode);
00391         // Restore OpenGL Matrix
00392         glPopMatrix();
00393 }
00394 
00395 // Display the instance in Primitive selection mode and return the body index
00396 int GLC_3DViewInstance::renderForPrimitiveSelection(GLC_uint bodyId)
00397 {
00398         Q_ASSERT(GLC_State::isInSelectionMode());
00399         if (m_3DRep.isEmpty()) return -1;
00400         // Save previous rendering mode and set the rendering mode to BodySelection
00401         glc::RenderMode previousRenderMode= m_RenderProperties.renderingMode();
00402         m_RenderProperties.setRenderingMode(glc::PrimitiveSelection);
00403 
00404         // Save current OpenGL Matrix
00405         glPushMatrix();
00406         OpenglVisProperties();
00407 
00408         const int size= m_3DRep.numberOfBody();
00409         int i= 0;
00410         bool continu= true;
00411         while ((i < size) && continu)
00412         {
00413                 GLC_Geometry* pGeom= m_3DRep.geomAt(i);
00414                 if (pGeom->id() == bodyId)
00415                 {
00416                         pGeom->setCurrentLod(0);
00417                         pGeom->render(m_RenderProperties);
00418                         continu= false;
00419                 }
00420                 else ++i;
00421         }
00422 
00423         m_RenderProperties.setRenderingMode(previousRenderMode);
00424 
00425         // Restore OpenGL Matrix
00426         glPopMatrix();
00427 
00428         return i;
00429 }
00430 
00431 
00432 
00434 // private services functions
00436 
00437 
00438 // compute the instance bounding box
00439 // m_pGeomList should be not null
00440 void GLC_3DViewInstance::computeBoundingBox(void)
00441 {
00442         if (m_3DRep.isEmpty()) return;
00443 
00444         if (m_pBoundingBox != NULL)
00445         {
00446                 delete m_pBoundingBox;
00447                 m_pBoundingBox= NULL;
00448         }
00449         m_pBoundingBox= new GLC_BoundingBox();
00450         const int size= m_3DRep.numberOfBody();
00451         for (int i= 0; i < size; ++i)
00452         {
00453                 m_pBoundingBox->combine(m_3DRep.geomAt(i)->boundingBox());
00454         }
00455 
00456         m_pBoundingBox->transform(m_AbsoluteMatrix);
00457 }
00458 
00459 // Clear current instance
00460 void GLC_3DViewInstance::clear()
00461 {
00462 
00463         delete m_pBoundingBox;
00464         m_pBoundingBox= NULL;
00465 
00466         // invalidate the bounding box
00467         m_IsBoundingBoxValid= false;
00468 
00469 }
00470 
00471 // Compute LOD
00472 int GLC_3DViewInstance::choseLod(const GLC_BoundingBox& boundingBox, GLC_Viewport* pView, bool useLod)
00473 {
00474         if (NULL == pView) return 0;
00475         double pixelCullingRatio= 0.0;
00476         if (useLod)
00477         {
00478                 pixelCullingRatio= pView->minimumDynamicPixelCullingRatio();
00479         }
00480         else
00481         {
00482                 pixelCullingRatio= pView->minimumStaticPixelCullingRatio();
00483         }
00484 
00485         const double diameter= boundingBox.boundingSphereRadius() * 2.0 * m_AbsoluteMatrix.scalingX();
00486         GLC_Vector3d center(m_AbsoluteMatrix * boundingBox.center());
00487 
00488         const double dist= (center - pView->cameraHandle()->eye()).length();
00489         const double cameraCover= dist * pView->viewTangent();
00490 
00491         double ratio= diameter / cameraCover * 100.0;
00492         if (ratio > 100.0) ratio= 100.0;
00493         ratio= 100.0 - ratio;
00494 
00495         if ((ratio > (100.0 - pixelCullingRatio)) && GLC_State::isPixelCullingActivated()) ratio= 110.0;
00496         else if(useLod && (ratio > 50.0))
00497         {
00498                 ratio= (ratio - 50.0) / 50.0 * 100.0;
00499                 if (ratio < static_cast<double>(m_DefaultLOD)) ratio= static_cast<double>(m_DefaultLOD);
00500         }
00501         else
00502         {
00503                 ratio= static_cast<double>(m_DefaultLOD);
00504         }
00505 
00506         return static_cast<int>(ratio);
00507 }
00508 
00509 

SourceForge.net Logo

©2005-2011 Laurent Ribon