00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
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
00043
00044
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
00058 glc::encodeRgbId(m_Uid, m_colorId);
00059
00060
00061
00062 }
00063
00064
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
00078 glc::encodeRgbId(m_Uid, m_colorId);
00079
00080 setName(m_3DRep.name());
00081
00082
00083
00084 }
00085
00086
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
00100 glc::encodeRgbId(m_Uid, m_colorId);
00101
00102 setName(m_3DRep.name());
00103
00104
00105
00106 }
00107
00108
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
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
00132 GLC_3DViewInstance& GLC_3DViewInstance::operator=(const GLC_3DViewInstance& inputNode)
00133 {
00134 if (this != &inputNode)
00135 {
00136
00137 clear();
00138 GLC_Object::operator=(inputNode);
00139
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
00156
00157 }
00158
00159 return *this;
00160 }
00161
00162
00163 GLC_3DViewInstance::~GLC_3DViewInstance()
00164 {
00165 clear();
00166 }
00167
00169
00171
00172
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
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
00220 GLC_3DViewInstance GLC_3DViewInstance::instanciate()
00221 {
00222 GLC_3DViewInstance instance(*this);
00223 instance.m_Uid= glc::GLC_GenID();
00224
00225 glc::encodeRgbId(m_Uid, m_colorId);
00226
00227 return instance;
00228 }
00229
00231
00233
00234
00235
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
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
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
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
00277 GLC_3DViewInstance& GLC_3DViewInstance::resetMatrix(void)
00278 {
00279 m_AbsoluteMatrix.setToIdentity();
00280 m_IsBoundingBoxValid= false;
00281
00282 return *this;
00283 }
00284
00286
00288
00289
00290 void GLC_3DViewInstance::render(glc::RenderFlag renderFlag, bool useLod, GLC_Viewport* pView)
00291 {
00292
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
00304 glPushMatrix();
00305 OpenglVisProperties();
00306 if(GLC_State::isInSelectionMode())
00307 {
00308 glColor3ubv(m_colorId);
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
00349 glPopMatrix();
00350 }
00351
00352
00353 void GLC_3DViewInstance::renderForBodySelection()
00354 {
00355 Q_ASSERT(GLC_State::isInSelectionMode());
00356 if (m_3DRep.isEmpty()) return;
00357
00358
00359 glc::RenderMode previousRenderMode= m_RenderProperties.renderingMode();
00360 m_RenderProperties.setRenderingMode(glc::BodySelection);
00361
00362
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
00379 m_RenderProperties.setRenderingMode(previousRenderMode);
00380
00381 glPopMatrix();
00382 }
00383
00384
00385 int GLC_3DViewInstance::renderForPrimitiveSelection(GLC_uint bodyId)
00386 {
00387 Q_ASSERT(GLC_State::isInSelectionMode());
00388 if (m_3DRep.isEmpty()) return -1;
00389
00390 glc::RenderMode previousRenderMode= m_RenderProperties.renderingMode();
00391 m_RenderProperties.setRenderingMode(glc::PrimitiveSelection);
00392
00393
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
00415 glPopMatrix();
00416
00417 return i;
00418 }
00419
00420
00421
00423
00425
00426
00427
00428
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
00449 void GLC_3DViewInstance::clear()
00450 {
00451
00452 delete m_pBoundingBox;
00453 m_pBoundingBox= NULL;
00454
00455
00456 m_IsBoundingBoxValid= false;
00457
00458 }
00459
00460
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