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_colorId()
00054 , m_DefaultLOD(m_GlobalDefaultLOD)
00055 , m_ViewableFlag(GLC_3DViewInstance::FullViewable)
00056 , m_ViewableGeomFlag()
00057 {
00058
00059 glc::encodeRgbId(m_Uid, m_colorId);
00060
00061
00062
00063 }
00064
00065
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
00080 glc::encodeRgbId(m_Uid, m_colorId);
00081
00082 setName(m_3DRep.name());
00083
00084
00085
00086 }
00087
00088
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
00103 glc::encodeRgbId(m_Uid, m_colorId);
00104
00105 setName(m_3DRep.name());
00106
00107
00108
00109 }
00110
00111
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
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
00136 GLC_3DViewInstance& GLC_3DViewInstance::operator=(const GLC_3DViewInstance& inputNode)
00137 {
00138 if (this != &inputNode)
00139 {
00140
00141 clear();
00142 GLC_Object::operator=(inputNode);
00143
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
00160
00161 }
00162
00163 return *this;
00164 }
00165
00166
00167 GLC_3DViewInstance::~GLC_3DViewInstance()
00168 {
00169 clear();
00170 }
00171
00173
00175
00176
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
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
00224 GLC_3DViewInstance GLC_3DViewInstance::instanciate()
00225 {
00226 GLC_3DViewInstance instance(*this);
00227 instance.m_Uid= glc::GLC_GenID();
00228
00229 glc::encodeRgbId(m_Uid, m_colorId);
00230
00231 return instance;
00232 }
00233
00235
00237
00238
00239
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
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
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
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
00281 GLC_3DViewInstance& GLC_3DViewInstance::resetMatrix(void)
00282 {
00283 m_AbsoluteMatrix.setToIdentity();
00284 m_IsBoundingBoxValid= false;
00285
00286 return *this;
00287 }
00288
00290
00292
00293
00294 void GLC_3DViewInstance::render(glc::RenderFlag renderFlag, bool useLod, GLC_Viewport* pView)
00295 {
00296
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
00308 glPushMatrix();
00309 OpenglVisProperties();
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);
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
00353 glPopMatrix();
00354 }
00355
00356
00357 void GLC_3DViewInstance::renderForBodySelection()
00358 {
00359 Q_ASSERT(GLC_State::isInSelectionMode());
00360 if (m_3DRep.isEmpty()) return;
00361
00362
00363 glc::RenderMode previousRenderMode= m_RenderProperties.renderingMode();
00364 m_RenderProperties.setRenderingMode(glc::BodySelection);
00365
00366
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
00383 m_RenderProperties.setRenderingMode(previousRenderMode);
00384
00385 glPopMatrix();
00386 }
00387
00388
00389 int GLC_3DViewInstance::renderForPrimitiveSelection(GLC_uint bodyId)
00390 {
00391 Q_ASSERT(GLC_State::isInSelectionMode());
00392 if (m_3DRep.isEmpty()) return -1;
00393
00394 glc::RenderMode previousRenderMode= m_RenderProperties.renderingMode();
00395 m_RenderProperties.setRenderingMode(glc::PrimitiveSelection);
00396
00397
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
00419 glPopMatrix();
00420
00421 return i;
00422 }
00423
00424
00425
00427
00429
00430
00431
00432
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
00453 void GLC_3DViewInstance::clear()
00454 {
00455
00456 delete m_pBoundingBox;
00457 m_pBoundingBox= NULL;
00458
00459
00460 m_IsBoundingBoxValid= false;
00461
00462 }
00463
00464
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
00480
00481 return static_cast<int>(ratio);
00482 }
00483
00484