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 Beta 1, packaged on April 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 General Public License as published by
00011  the Free Software Foundation; either version 2 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 General Public License for more details.
00018 
00019  You should have received a copy of the GNU 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_colorId()
00054 , m_DefaultLOD(m_GlobalDefaultLOD)
00055 , m_ViewableFlag(GLC_3DViewInstance::FullViewable)
00056 , m_ViewableGeomFlag()
00057 {
00058         // Encode Color Id
00059         glc::encodeRgbId(m_Uid, m_colorId);
00060 
00061         //qDebug() << "GLC_3DViewInstance::GLC_3DViewInstance null instance ID = " << m_Uid;
00062         //qDebug() << "Number of instance" << (*m_pNumberOfInstance);
00063 }
00064 
00065 // Contruct instance with a geometry
00066 GLC_3DViewInstance::GLC_3DViewInstance(GLC_Geometry* pGeom)
00067 : GLC_Object()
00068 , m_3DRep(pGeom)
00069 , m_pBoundingBox(NULL)
00070 , m_AbsoluteMatrix()
00071 , m_IsBoundingBoxValid(false)
00072 , m_RenderProperties()
00073 , m_IsVisible(true)
00074 , m_colorId()
00075 , m_DefaultLOD(m_GlobalDefaultLOD)
00076 , m_ViewableFlag(GLC_3DViewInstance::FullViewable)
00077 , m_ViewableGeomFlag()
00078 {
00079         // Encode Color Id
00080         glc::encodeRgbId(m_Uid, m_colorId);
00081 
00082         setName(m_3DRep.name());
00083 
00084         //qDebug() << "GLC_3DViewInstance::GLC_3DViewInstance ID = " << m_Uid;
00085         //qDebug() << "Number of instance" << (*m_pNumberOfInstance);
00086 }
00087 
00088 // Contruct instance with a 3DRep
00089 GLC_3DViewInstance::GLC_3DViewInstance(const GLC_3DRep& rep)
00090 : GLC_Object()
00091 , m_3DRep(rep)
00092 , m_pBoundingBox(NULL)
00093 , m_AbsoluteMatrix()
00094 , m_IsBoundingBoxValid(false)
00095 , m_RenderProperties()
00096 , m_IsVisible(true)
00097 , m_colorId()
00098 , m_DefaultLOD(m_GlobalDefaultLOD)
00099 , m_ViewableFlag(GLC_3DViewInstance::FullViewable)
00100 , m_ViewableGeomFlag()
00101 {
00102         // Encode Color Id
00103         glc::encodeRgbId(m_Uid, m_colorId);
00104 
00105         setName(m_3DRep.name());
00106 
00107         //qDebug() << "GLC_3DViewInstance::GLC_3DViewInstance ID = " << m_Uid;
00108         //qDebug() << "Number of instance" << (*m_pNumberOfInstance);
00109 }
00110 
00111 // Copy constructor
00112 GLC_3DViewInstance::GLC_3DViewInstance(const GLC_3DViewInstance& inputNode)
00113 : GLC_Object(inputNode)
00114 , m_3DRep(inputNode.m_3DRep)
00115 , m_pBoundingBox(NULL)
00116 , m_AbsoluteMatrix(inputNode.m_AbsoluteMatrix)
00117 , m_IsBoundingBoxValid(inputNode.m_IsBoundingBoxValid)
00118 , m_RenderProperties(inputNode.m_RenderProperties)
00119 , m_IsVisible(inputNode.m_IsVisible)
00120 , m_colorId()
00121 , m_DefaultLOD(inputNode.m_DefaultLOD)
00122 , m_ViewableFlag(inputNode.m_ViewableFlag)
00123 , m_ViewableGeomFlag(inputNode.m_ViewableGeomFlag)
00124 {
00125         // Encode Color Id
00126         glc::encodeRgbId(m_Uid, m_colorId);
00127 
00128         if (NULL != inputNode.m_pBoundingBox)
00129         {
00130                 m_pBoundingBox= new GLC_BoundingBox(*inputNode.m_pBoundingBox);
00131         }
00132 }
00133 
00134 
00135 // Assignement operator
00136 GLC_3DViewInstance& GLC_3DViewInstance::operator=(const GLC_3DViewInstance& inputNode)
00137 {
00138         if (this != &inputNode)
00139         {
00140                 // Clear this instance
00141                 clear();
00142                 GLC_Object::operator=(inputNode);
00143                 // Encode Color Id
00144                 glc::encodeRgbId(m_Uid, m_colorId);
00145 
00146                 m_3DRep= inputNode.m_3DRep;
00147                 if (NULL != inputNode.m_pBoundingBox)
00148                 {
00149                         m_pBoundingBox= new GLC_BoundingBox(*inputNode.m_pBoundingBox);
00150                 }
00151                 m_AbsoluteMatrix= inputNode.m_AbsoluteMatrix;
00152                 m_IsBoundingBoxValid= inputNode.m_IsBoundingBoxValid;
00153                 m_RenderProperties= inputNode.m_RenderProperties;
00154                 m_IsVisible= inputNode.m_IsVisible;
00155                 m_DefaultLOD= inputNode.m_DefaultLOD;
00156                 m_ViewableFlag= inputNode.m_ViewableFlag;
00157                 m_ViewableGeomFlag= inputNode.m_ViewableGeomFlag;
00158 
00159                 //qDebug() << "GLC_3DViewInstance::operator= :ID = " << m_Uid;
00160                 //qDebug() << "Number of instance" << (*m_pNumberOfInstance);
00161         }
00162 
00163         return *this;
00164 }
00165 
00166 // Destructor
00167 GLC_3DViewInstance::~GLC_3DViewInstance()
00168 {
00169         clear();
00170 }
00171 
00173 // Get Functions
00175 
00176 // Get the bounding box
00177 GLC_BoundingBox GLC_3DViewInstance::boundingBox(void)
00178 {
00179         GLC_BoundingBox resultBox;
00180         if (boundingBoxValidity())
00181         {
00182                 resultBox= *m_pBoundingBox;
00183         }
00184         else if (!m_3DRep.isEmpty())
00185         {
00186                 computeBoundingBox();
00187                 m_IsBoundingBoxValid= true;
00188                 resultBox= *m_pBoundingBox;
00189         }
00190 
00191         return resultBox;
00192 }
00193 
00195 void GLC_3DViewInstance::setGlobalDefaultLod(int lod)
00196 {
00197         QMutexLocker locker(&m_Mutex);
00198         m_GlobalDefaultLOD= lod;
00199 }
00200 
00201 // Clone the instance
00202 GLC_3DViewInstance GLC_3DViewInstance::deepCopy() const
00203 {
00204 
00205         GLC_3DRep* pRep= dynamic_cast<GLC_3DRep*>(m_3DRep.deepCopy());
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::setGeometry(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         glPushMatrix();
00309         OpenglVisProperties();
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);
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);
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 
00356 // Display the instance in Body selection mode
00357 void GLC_3DViewInstance::renderForBodySelection()
00358 {
00359         Q_ASSERT(GLC_State::isInSelectionMode());
00360         if (m_3DRep.isEmpty()) return;
00361 
00362         // Save previous rendering mode and set the rendering mode to BodySelection
00363         glc::RenderMode previousRenderMode= m_RenderProperties.renderingMode();
00364         m_RenderProperties.setRenderingMode(glc::BodySelection);
00365 
00366         // Save current OpenGL Matrix
00367         glPushMatrix();
00368         OpenglVisProperties();
00369 
00370         GLubyte colorId[4];
00371         const int size= m_3DRep.numberOfBody();
00372         for (int i= 0; i < size; ++i)
00373         {
00374                 GLC_Geometry* pGeom= m_3DRep.geomAt(i);
00375                 glc::encodeRgbId(pGeom->id(), colorId);
00376                 glColor3ubv(colorId);
00377                 pGeom->setCurrentLod(m_DefaultLOD);
00378                 m_RenderProperties.setCurrentBodyIndex(i);
00379                 pGeom->render(m_RenderProperties);
00380         }
00381 
00382         // Restore rendering mode
00383         m_RenderProperties.setRenderingMode(previousRenderMode);
00384         // Restore OpenGL Matrix
00385         glPopMatrix();
00386 }
00387 
00388 // Display the instance in Primitive selection mode and return the body index
00389 int GLC_3DViewInstance::renderForPrimitiveSelection(GLC_uint bodyId)
00390 {
00391         Q_ASSERT(GLC_State::isInSelectionMode());
00392         if (m_3DRep.isEmpty()) return -1;
00393         // Save previous rendering mode and set the rendering mode to BodySelection
00394         glc::RenderMode previousRenderMode= m_RenderProperties.renderingMode();
00395         m_RenderProperties.setRenderingMode(glc::PrimitiveSelection);
00396 
00397         // Save current OpenGL Matrix
00398         glPushMatrix();
00399         OpenglVisProperties();
00400 
00401         const int size= m_3DRep.numberOfBody();
00402         int i= 0;
00403         bool continu= true;
00404         while ((i < size) && continu)
00405         {
00406                 GLC_Geometry* pGeom= m_3DRep.geomAt(i);
00407                 if (pGeom->id() == bodyId)
00408                 {
00409                         pGeom->setCurrentLod(0);
00410                         pGeom->render(m_RenderProperties);
00411                         continu= false;
00412                 }
00413                 else ++i;
00414         }
00415 
00416         m_RenderProperties.setRenderingMode(previousRenderMode);
00417 
00418         // Restore OpenGL Matrix
00419         glPopMatrix();
00420 
00421         return i;
00422 }
00423 
00424 
00425 
00427 // private services functions
00429 
00430 
00431 // compute the instance bounding box
00432 // m_pGeomList should be not null
00433 void GLC_3DViewInstance::computeBoundingBox(void)
00434 {
00435         if (m_3DRep.isEmpty()) return;
00436 
00437         if (m_pBoundingBox != NULL)
00438         {
00439                 delete m_pBoundingBox;
00440                 m_pBoundingBox= NULL;
00441         }
00442         m_pBoundingBox= new GLC_BoundingBox();
00443         const int size= m_3DRep.numberOfBody();
00444         for (int i= 0; i < size; ++i)
00445         {
00446                 m_pBoundingBox->combine(m_3DRep.geomAt(i)->boundingBox());
00447         }
00448 
00449         m_pBoundingBox->transform(m_AbsoluteMatrix);
00450 }
00451 
00452 // Clear current instance
00453 void GLC_3DViewInstance::clear()
00454 {
00455 
00456         delete m_pBoundingBox;
00457         m_pBoundingBox= NULL;
00458 
00459         // invalidate the bounding box
00460         m_IsBoundingBoxValid= false;
00461 
00462 }
00463 
00464 // Compute LOD
00465 int GLC_3DViewInstance::choseLod(const GLC_BoundingBox& boundingBox, GLC_Viewport* pView)
00466 {
00467         if (NULL == pView) return 0;
00468         const double diameter= boundingBox.boundingSphereRadius() * 2.0 * m_AbsoluteMatrix.scalingX();
00469         GLC_Vector3d center(m_AbsoluteMatrix * boundingBox.center());
00470 
00471         const double dist= (center - pView->cameraHandle()->eye()).length();
00472         const double cameraCover= dist * pView->viewTangent();
00473         double ratio= diameter / cameraCover * 150.0;
00474 
00475         if (ratio > 100.0) ratio= 100.0;
00476         ratio= 100.0 - ratio;
00477         if ((ratio > 98.0) && GLC_State::isPixelCullingActivated()) ratio= 110.0;
00478         if (ratio < static_cast<double>(m_DefaultLOD)) ratio= static_cast<double>(m_DefaultLOD);
00479         //qDebug() << "RATIO = " << static_cast<int>(ratio);
00480 
00481         return static_cast<int>(ratio);
00482 }
00483 
00484 

SourceForge.net Logo

©2005 Laurent Ribon