00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
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
00041
00042
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
00056 glc::encodeRgbId(m_Uid, m_colorId);
00057
00058
00059
00060 }
00061
00062
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
00076 glc::encodeRgbId(m_Uid, m_colorId);
00077
00078 setName(m_3DRep.name());
00079
00080
00081
00082 }
00083
00084
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
00098 glc::encodeRgbId(m_Uid, m_colorId);
00099
00100 setName(m_3DRep.name());
00101
00102
00103
00104 }
00105
00106
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
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
00130 GLC_3DViewInstance& GLC_3DViewInstance::operator=(const GLC_3DViewInstance& inputNode)
00131 {
00132 if (this != &inputNode)
00133 {
00134
00135 clear();
00136 GLC_Object::operator=(inputNode);
00137
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
00154
00155 }
00156
00157 return *this;
00158 }
00159
00160
00161 GLC_3DViewInstance::~GLC_3DViewInstance()
00162 {
00163 clear();
00164 }
00165
00167
00169
00170
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
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
00218 GLC_3DViewInstance GLC_3DViewInstance::instanciate()
00219 {
00220 GLC_3DViewInstance instance(*this);
00221 instance.m_Uid= glc::GLC_GenID();
00222
00223 glc::encodeRgbId(m_Uid, m_colorId);
00224
00225 return instance;
00226 }
00227
00229
00231
00232
00233
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
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
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
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
00275 GLC_3DViewInstance& GLC_3DViewInstance::resetMatrix(void)
00276 {
00277 m_AbsoluteMatrix.setToIdentity();
00278 m_IsBoundingBoxValid= false;
00279
00280 return *this;
00281 }
00282
00284
00286
00287
00288 void GLC_3DViewInstance::render(glc::RenderFlag renderFlag, bool useLod, GLC_Viewport* pView)
00289 {
00290
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
00302 glPushMatrix();
00303 OpenglVisProperties();
00304
00305
00306 if (m_AbsoluteMatrix.type() == GLC_Matrix4x4::Indirect)
00307 {
00308 glFrontFace(GL_CW);
00309 }
00310 if(GLC_State::isInSelectionMode())
00311 {
00312 glColor3ubv(m_colorId);
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
00353 glPopMatrix();
00354
00355
00356 if (m_AbsoluteMatrix.type() == GLC_Matrix4x4::Indirect)
00357 {
00358 glFrontFace(GL_CCW);
00359 }
00360
00361 }
00362
00363
00364 void GLC_3DViewInstance::renderForBodySelection()
00365 {
00366 Q_ASSERT(GLC_State::isInSelectionMode());
00367 if (m_3DRep.isEmpty()) return;
00368
00369
00370 glc::RenderMode previousRenderMode= m_RenderProperties.renderingMode();
00371 m_RenderProperties.setRenderingMode(glc::BodySelection);
00372
00373
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
00390 m_RenderProperties.setRenderingMode(previousRenderMode);
00391
00392 glPopMatrix();
00393 }
00394
00395
00396 int GLC_3DViewInstance::renderForPrimitiveSelection(GLC_uint bodyId)
00397 {
00398 Q_ASSERT(GLC_State::isInSelectionMode());
00399 if (m_3DRep.isEmpty()) return -1;
00400
00401 glc::RenderMode previousRenderMode= m_RenderProperties.renderingMode();
00402 m_RenderProperties.setRenderingMode(glc::PrimitiveSelection);
00403
00404
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
00426 glPopMatrix();
00427
00428 return i;
00429 }
00430
00431
00432
00434
00436
00437
00438
00439
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
00460 void GLC_3DViewInstance::clear()
00461 {
00462
00463 delete m_pBoundingBox;
00464 m_pBoundingBox= NULL;
00465
00466
00467 m_IsBoundingBoxValid= false;
00468
00469 }
00470
00471
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