glc_3dviewcollection.cpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00024
00025
00026 #include "glc_3dviewcollection.h"
00027 #include "../shading/glc_material.h"
00028 #include "../glc_openglexception.h"
00029 #include "../shading/glc_selectionmaterial.h"
00030 #include "../glc_state.h"
00031 #include "../shading/glc_shader.h"
00032 #include "../viewport/glc_viewport.h"
00033 #include "glc_spacepartitioning.h"
00034
00035 #include <QtDebug>
00036
00038
00040
00041 GLC_3DViewCollection::GLC_3DViewCollection()
00042 : m_3DViewInstanceHash()
00043 , m_SelectedInstances()
00044 , m_ShadedPointerViewInstanceHash()
00045 , m_ShaderGroup()
00046 , m_MainInstances()
00047 , m_IsInShowSate(true)
00048 , m_UseLod(false)
00049 , m_pViewport(NULL)
00050 , m_pSpacePartitioning(NULL)
00051 , m_UseSpacePartitioning(false)
00052 {
00053 }
00054
00055 GLC_3DViewCollection::~GLC_3DViewCollection()
00056 {
00057
00058 clear();
00059 }
00061
00063
00064 bool GLC_3DViewCollection::bindShader(GLuint shaderId)
00065 {
00066 if (m_ShadedPointerViewInstanceHash.contains(shaderId))
00067 {
00068 return false;
00069 }
00070 else
00071 {
00072 PointerViewInstanceHash* pNodeHash= new PointerViewInstanceHash;
00073 m_ShadedPointerViewInstanceHash.insert(shaderId, pNodeHash);
00074 return true;
00075 }
00076 }
00077
00078 bool GLC_3DViewCollection::unBindShader(GLuint shaderId)
00079 {
00080 bool result= false;
00081 if (m_ShadedPointerViewInstanceHash.contains(shaderId))
00082 {
00083
00084 QList<GLC_uint> nodeId(m_ShaderGroup.keys(shaderId));
00085
00086
00087 PointerViewInstanceHash* pShaderNodeHash= m_ShadedPointerViewInstanceHash.take(shaderId);
00088 for (int i= 0; i < nodeId.size(); ++i)
00089 {
00090 const GLC_uint id= nodeId[i];
00091 GLC_3DViewInstance* pInstance= pShaderNodeHash->value(id);
00092
00093 if (!pInstance->isSelected())
00094 {
00095 m_MainInstances.insert(id, pInstance);
00096 }
00097 else
00098 {
00099 m_SelectedInstances.insert(id, pInstance);
00100 }
00101 m_ShaderGroup.remove(id);
00102 }
00103 pShaderNodeHash->clear();
00104 delete pShaderNodeHash;
00105 result= true;
00106 }
00107 Q_ASSERT(!m_ShadedPointerViewInstanceHash.contains(shaderId));
00108 return result;
00109 }
00110
00111 bool GLC_3DViewCollection::unBindAllShader()
00112 {
00113 bool result= true;
00114 HashList::iterator iEntry= m_ShadedPointerViewInstanceHash.begin();
00115 QList<GLuint> shaderList;
00116 while (iEntry != m_ShadedPointerViewInstanceHash.constEnd())
00117 {
00118 shaderList.append(iEntry.key());
00119 ++iEntry;
00120 }
00121 const int size= shaderList.size();
00122 for (int i=0; i < size; ++i)
00123 {
00124 result= result && unBindShader(shaderList[i]);
00125 }
00126 return result;
00127 }
00128
00129 bool GLC_3DViewCollection::add(const GLC_3DViewInstance& node, GLuint shaderID)
00130 {
00131 bool result= false;
00132 const GLC_uint key= node.id();
00133 if (m_3DViewInstanceHash.contains(key))
00134 {
00135 return false;
00136 }
00137
00138 m_3DViewInstanceHash.insert(key, node);
00139
00140 ViewInstancesHash::iterator iNode= m_3DViewInstanceHash.find(key);
00141 GLC_3DViewInstance* pInstance= &(iNode.value());
00142
00143 if(0 != shaderID)
00144 {
00145
00146 if (m_ShadedPointerViewInstanceHash.contains(shaderID))
00147 {
00148 m_ShaderGroup.insert(key, shaderID);
00149
00150 if(pInstance->isSelected())
00151 {
00152 m_SelectedInstances.insert(key, pInstance);
00153 }
00154 else
00155 {
00156 m_ShadedPointerViewInstanceHash.value(shaderID)->insert(key, pInstance);
00157 }
00158 result=true;
00159 }
00160 }
00161 else if (!pInstance->isSelected())
00162 {
00163 m_MainInstances.insert(key, pInstance);
00164 result=true;
00165 }
00166 else
00167 {
00168 m_SelectedInstances.insert(key, pInstance);
00169 result=true;
00170 }
00171
00172 return result;
00173 }
00174
00175 void GLC_3DViewCollection::changeShadingGroup(GLC_uint instanceId, GLuint shaderId)
00176 {
00177
00178 Q_ASSERT(m_3DViewInstanceHash.contains(instanceId));
00179
00180 const GLuint instanceShadingGroup= shadingGroup(instanceId);
00181
00182 GLC_3DViewInstance* pInstance= NULL;
00183 if (0 == instanceShadingGroup)
00184 {
00185
00186 if (m_MainInstances.contains(instanceId))
00187 {
00188 pInstance= m_MainInstances.take(instanceId);
00189 }
00190 else if (m_SelectedInstances.contains(instanceId))
00191 {
00192
00193 pInstance= m_SelectedInstances.value(instanceId);
00194 }
00195 else
00196 {
00197 Q_ASSERT(false);
00198 }
00199 }
00200 else
00201 {
00202 m_ShaderGroup.remove(instanceId);
00203
00204 if (m_SelectedInstances.contains(instanceId))
00205 {
00206
00207 pInstance= m_SelectedInstances.value(instanceId);
00208 }
00209 else
00210 {
00211 pInstance= m_ShadedPointerViewInstanceHash.value(instanceShadingGroup)->take(instanceId);
00212 }
00213
00214 }
00215
00216 if (0 != shaderId)
00217 {
00218 m_ShaderGroup.insert(instanceId, shaderId);
00219 if (!pInstance->isSelected())
00220 {
00221 m_ShadedPointerViewInstanceHash.value(shaderId)->insert(instanceId, pInstance);
00222 }
00223 }
00224 else if (!pInstance->isSelected())
00225 {
00226 m_MainInstances.insert(instanceId, pInstance);
00227 }
00228 }
00229
00230 bool GLC_3DViewCollection::remove(GLC_uint Key)
00231 {
00232 ViewInstancesHash::iterator iNode= m_3DViewInstanceHash.find(Key);
00233
00234 if (iNode != m_3DViewInstanceHash.end())
00235 {
00236
00237 if (selectionSize() > 0)
00238 {
00239
00240 unselect(Key);
00241 }
00242
00243 m_MainInstances.remove(Key);
00244
00245 m_3DViewInstanceHash.remove(Key);
00246
00247
00248 return true;
00249
00250 }
00251 else
00252 {
00253 return false;
00254 }
00255
00256 }
00257
00258 void GLC_3DViewCollection::clear(void)
00259 {
00260
00261 m_SelectedInstances.clear();
00262
00263 m_MainInstances.clear();
00264
00265 HashList::iterator iEntry= m_ShadedPointerViewInstanceHash.begin();
00266 while (iEntry != m_ShadedPointerViewInstanceHash.constEnd())
00267 {
00268 iEntry.value()->clear();
00269 delete iEntry.value();
00270 iEntry= m_ShadedPointerViewInstanceHash.erase(iEntry);
00271 }
00272
00273 m_ShadedPointerViewInstanceHash.clear();
00274 m_ShaderGroup.clear();
00275
00276
00277 m_3DViewInstanceHash.clear();
00278
00279
00280 delete m_pSpacePartitioning;
00281 }
00282
00283 bool GLC_3DViewCollection::select(GLC_uint key, bool primitive)
00284 {
00285 if (!m_3DViewInstanceHash.contains(key)) return false;
00286
00287
00288 GLC_3DViewInstance* pSelectedInstance;
00289 ViewInstancesHash::iterator iNode= m_3DViewInstanceHash.find(key);
00290 PointerViewInstanceHash::iterator iSelectedNode= m_SelectedInstances.find(key);
00291
00292 if ((iNode != m_3DViewInstanceHash.end()) && (iSelectedNode == m_SelectedInstances.end()))
00293 {
00294 pSelectedInstance= &(iNode.value());
00295 m_SelectedInstances.insert(pSelectedInstance->id(), pSelectedInstance);
00296
00297
00298 if (isInAShadingGroup(key))
00299 {
00300 m_ShadedPointerViewInstanceHash.value(shadingGroup(key))->remove(key);
00301
00302 }
00303 else
00304 {
00305 m_MainInstances.remove(key);
00306 }
00307 pSelectedInstance->select(primitive);
00308
00309
00310 return true;
00311 }
00312 else
00313 {
00314 return false;
00315 }
00316 }
00317
00318 void GLC_3DViewCollection::selectAll(bool allShowState)
00319 {
00320 unselectAll();
00321 ViewInstancesHash::iterator iNode= m_3DViewInstanceHash.begin();
00322 while (iNode != m_3DViewInstanceHash.end())
00323 {
00324 GLC_3DViewInstance *pCurrentInstance= &(iNode.value());
00325 const GLC_uint instanceId= pCurrentInstance->id();
00326
00327 if (allShowState || (pCurrentInstance->isVisible() == m_IsInShowSate))
00328 {
00329 pCurrentInstance->select(false);
00330 m_SelectedInstances.insert(instanceId, pCurrentInstance);
00331 m_MainInstances.remove(instanceId);
00332 if(isInAShadingGroup(instanceId))
00333 {
00334 m_ShadedPointerViewInstanceHash.value(shadingGroup(instanceId))->remove(instanceId);
00335 }
00336 }
00337 iNode++;
00338 }
00339 }
00340
00341 bool GLC_3DViewCollection::unselect(GLC_uint key)
00342 {
00343 GLC_3DViewInstance* pSelectedNode;
00344
00345 PointerViewInstanceHash::iterator iSelectedNode= m_SelectedInstances.find(key);
00346
00347 if (iSelectedNode != m_SelectedInstances.end())
00348 {
00349 iSelectedNode.value()->unselect();
00350
00351 pSelectedNode= iSelectedNode.value();
00352 m_SelectedInstances.remove(key);
00353
00354
00355 if (isInAShadingGroup(key))
00356 {
00357 m_ShadedPointerViewInstanceHash.value(shadingGroup(key))->insert(key, pSelectedNode);
00358 }
00359 else
00360 {
00361 m_MainInstances.insert(key, pSelectedNode);
00362 }
00363
00364
00365 return true;
00366
00367 }
00368 else
00369 {
00370
00371 return false;
00372 }
00373 }
00374
00375 void GLC_3DViewCollection::unselectAll()
00376 {
00377 PointerViewInstanceHash::iterator iSelectedNode= m_SelectedInstances.begin();
00378
00379 while (iSelectedNode != m_SelectedInstances.end())
00380 {
00381 GLC_3DViewInstance* pInstance= iSelectedNode.value();
00382 pInstance->unselect();
00383 if (isInAShadingGroup(pInstance->id()))
00384 {
00385 m_ShadedPointerViewInstanceHash.value(shadingGroup(pInstance->id()))->insert(pInstance->id(), pInstance);
00386 }
00387 else
00388 {
00389 m_MainInstances.insert(pInstance->id(), pInstance);
00390 }
00391
00392 ++iSelectedNode;
00393 }
00394
00395 m_SelectedInstances.clear();
00396 }
00397
00398 void GLC_3DViewCollection::setPolygonModeForAll(GLenum face, GLenum mode)
00399 {
00400 ViewInstancesHash::iterator iEntry= m_3DViewInstanceHash.begin();
00401
00402 while (iEntry != m_3DViewInstanceHash.constEnd())
00403 {
00404
00405 iEntry.value().setPolygonMode(face, mode);
00406 iEntry++;
00407 }
00408
00409 }
00410
00411 void GLC_3DViewCollection::setVisibility(const GLC_uint key, const bool visibility)
00412 {
00413 ViewInstancesHash::iterator iNode= m_3DViewInstanceHash.find(key);
00414 if (iNode != m_3DViewInstanceHash.end())
00415 {
00416 iNode.value().setVisibility(visibility);
00417 }
00418 }
00419
00420 void GLC_3DViewCollection::showAll()
00421 {
00422 ViewInstancesHash::iterator iEntry= m_3DViewInstanceHash.begin();
00423
00424 while (iEntry != m_3DViewInstanceHash.constEnd())
00425 {
00426
00427 iEntry.value().setVisibility(true);
00428 iEntry++;
00429 }
00430 }
00431
00432 void GLC_3DViewCollection::hideAll()
00433 {
00434 ViewInstancesHash::iterator iEntry= m_3DViewInstanceHash.begin();
00435
00436 while (iEntry != m_3DViewInstanceHash.constEnd())
00437 {
00438
00439 iEntry.value().setVisibility(false);
00440 iEntry++;
00441 }
00442
00443 }
00444
00445 void GLC_3DViewCollection::bindSpacePartitioning(GLC_SpacePartitioning* pSpacePartitioning)
00446 {
00447 Q_ASSERT(NULL != pSpacePartitioning);
00448 Q_ASSERT(pSpacePartitioning->collectionHandle() == this);
00449
00450 delete m_pSpacePartitioning;
00451 m_pSpacePartitioning= pSpacePartitioning;
00452 }
00453
00454 void GLC_3DViewCollection::unbindSpacePartitioning()
00455 {
00456 delete m_pSpacePartitioning;
00457 m_pSpacePartitioning= NULL;
00458 m_UseSpacePartitioning= false;
00459
00460 ViewInstancesHash::iterator iEntry= m_3DViewInstanceHash.begin();
00461 while (iEntry != m_3DViewInstanceHash.constEnd())
00462 {
00463
00464 iEntry.value().setViewable(GLC_3DViewInstance::FullViewable);
00465 iEntry++;
00466 }
00467
00468 }
00469
00470 void GLC_3DViewCollection::updateInstanceViewableState(GLC_Matrix4x4* pMatrix)
00471 {
00472 if ((NULL != m_pViewport) && m_UseSpacePartitioning && (NULL != m_pSpacePartitioning))
00473 {
00474 if (m_pViewport->updateFrustum(pMatrix))
00475 m_pSpacePartitioning->updateViewableInstances(m_pViewport->frustum());
00476 }
00477 }
00478
00479 void GLC_3DViewCollection::updateInstanceViewableState(const GLC_Frustum& frustum)
00480 {
00481 m_pSpacePartitioning->updateViewableInstances(frustum);
00482 }
00483
00484 QList<GLC_3DViewInstance*> GLC_3DViewCollection::instancesHandle()
00485 {
00486 QList<GLC_3DViewInstance*> instancesList;
00487
00488 ViewInstancesHash::iterator iEntry= m_3DViewInstanceHash.begin();
00489
00490 while (iEntry != m_3DViewInstanceHash.constEnd())
00491 {
00492 instancesList.append(&(iEntry.value()));
00493 iEntry++;
00494 }
00495 return instancesList;
00496 }
00497
00498 QList<GLC_3DViewInstance*> GLC_3DViewCollection::visibleInstancesHandle()
00499 {
00500 QList<GLC_3DViewInstance*> instancesList;
00501
00502 ViewInstancesHash::iterator iEntry= m_3DViewInstanceHash.begin();
00503
00504 while (iEntry != m_3DViewInstanceHash.constEnd())
00505 {
00506 if (iEntry.value().isVisible())
00507 {
00508 instancesList.append(&(iEntry.value()));
00509 }
00510 iEntry++;
00511 }
00512 return instancesList;
00513
00514 }
00515
00516 QList<GLC_3DViewInstance*> GLC_3DViewCollection::viewableInstancesHandle()
00517 {
00518 QList<GLC_3DViewInstance*> instancesList;
00519
00520 ViewInstancesHash::iterator iEntry= m_3DViewInstanceHash.begin();
00521
00522 while (iEntry != m_3DViewInstanceHash.constEnd())
00523 {
00524 if (iEntry.value().isVisible() == m_IsInShowSate)
00525 {
00526 instancesList.append(&(iEntry.value()));
00527 }
00528 iEntry++;
00529 }
00530 return instancesList;
00531 }
00532
00533 GLC_3DViewInstance* GLC_3DViewCollection::instanceHandle(GLC_uint Key)
00534 {
00535 Q_ASSERT(m_3DViewInstanceHash.contains(Key));
00536 return &(m_3DViewInstanceHash[Key]);
00537 }
00538
00539 GLC_BoundingBox GLC_3DViewCollection::boundingBox(bool allObject)
00540 {
00541 GLC_BoundingBox boundingBox;
00542
00543 if (!m_3DViewInstanceHash.isEmpty())
00544 {
00545 ViewInstancesHash::iterator iEntry= m_3DViewInstanceHash.begin();
00546 while (iEntry != m_3DViewInstanceHash.constEnd())
00547 {
00548 if(allObject || iEntry.value().isVisible() == m_IsInShowSate)
00549 {
00550
00551 boundingBox.combine(iEntry.value().boundingBox());
00552 }
00553 ++iEntry;
00554 }
00555 }
00556 return boundingBox;
00557 }
00558
00559 int GLC_3DViewCollection::drawableObjectsSize() const
00560 {
00561
00562 int numberOffDrawnHit= 0;
00563
00564
00565 ViewInstancesHash::const_iterator i= m_3DViewInstanceHash.begin();
00566 while (i != m_3DViewInstanceHash.constEnd())
00567 {
00568
00569 if (i.value().isVisible() == m_IsInShowSate)
00570 {
00571 ++numberOffDrawnHit;
00572 }
00573 ++i;
00574 }
00575 return numberOffDrawnHit;
00576 }
00577
00578 QList<QString> GLC_3DViewCollection::instanceNamesFromShadingGroup(GLuint shaderId) const
00579 {
00580 QList<QString> listOfInstanceName;
00581 QList<GLC_uint> listOfInstanceNameId= m_ShaderGroup.keys(shaderId);
00582 if (!listOfInstanceNameId.isEmpty())
00583 {
00584 const int size= listOfInstanceNameId.size();
00585 for (int i= 0; i < size; ++i)
00586 {
00587 listOfInstanceName << m_3DViewInstanceHash.value(listOfInstanceNameId[i]).name();
00588 }
00589 }
00590 return listOfInstanceName;
00591 }
00592
00593 int GLC_3DViewCollection::numberOfUsedShadingGroup() const
00594 {
00595 return m_ShaderGroup.values().toSet().size();
00596 }
00597
00599
00601
00602 void GLC_3DViewCollection::render(GLuint groupId, glc::RenderFlag renderFlag)
00603 {
00604 if (!isEmpty())
00605 {
00606 if (renderFlag == glc::WireRenderFlag)
00607 {
00608 glEnable(GL_POLYGON_OFFSET_FILL);
00609 glPolygonOffset (1.0, 1.0);
00610 }
00611 if (GLC_State::isInSelectionMode())
00612 {
00613 glDisable(GL_BLEND);
00614 glDisable(GL_LIGHTING);
00615 glDisable(GL_TEXTURE_2D);
00616 }
00617 else
00618 {
00619 glEnable(GL_LIGHTING);
00620 }
00621 glDraw(groupId, renderFlag);
00622
00623 if (renderFlag == glc::WireRenderFlag)
00624 {
00625 glDisable(GL_POLYGON_OFFSET_FILL);
00626 }
00627 }
00628 }
00629 void GLC_3DViewCollection::renderShaderGroup(glc::RenderFlag renderFlag)
00630 {
00631 if (!isEmpty())
00632 {
00633 if (GLC_State::isInSelectionMode())
00634 {
00635 glDisable(GL_BLEND);
00636 glDisable(GL_LIGHTING);
00637 glDisable(GL_TEXTURE_2D);
00638 }
00639
00640 HashList::iterator iEntry= m_ShadedPointerViewInstanceHash.begin();
00641 while (iEntry != m_ShadedPointerViewInstanceHash.constEnd())
00642 {
00643 glDraw(iEntry.key(), renderFlag);
00644 ++iEntry;
00645 }
00646 }
00647 }
00648
00649 void GLC_3DViewCollection::glDraw(GLuint groupId, glc::RenderFlag renderFlag)
00650 {
00651
00652 if (!GLC_State::isInSelectionMode() && (groupId == 0))
00653 {
00654 if (renderFlag == glc::TransparentRenderFlag)
00655 {
00656 glEnable(GL_BLEND);
00657 glDepthMask(GL_FALSE);
00658 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
00659
00660 }
00661 else
00662 {
00663 glDisable(GL_BLEND);
00664 glDepthMask(GL_TRUE);
00665 glEnable(GL_DEPTH_TEST);
00666 }
00667 }
00668
00669
00670 if ((groupId == 0) && !m_MainInstances.isEmpty())
00671 {
00672 glDrawInstancesOf(&m_MainInstances, renderFlag);
00673
00674 }
00675
00676 else if ((groupId == 1) && !m_SelectedInstances.isEmpty())
00677 {
00678 if (GLC_State::selectionShaderUsed()) GLC_SelectionMaterial::useShader();
00679
00680 glDrawInstancesOf(&m_SelectedInstances, renderFlag);
00681
00682 if (GLC_State::selectionShaderUsed()) GLC_SelectionMaterial::unUseShader();
00683 }
00684
00685 else if (!m_ShadedPointerViewInstanceHash.isEmpty())
00686 {
00687 if(m_ShadedPointerViewInstanceHash.contains(groupId) && !m_ShadedPointerViewInstanceHash.value(groupId)->isEmpty())
00688 {
00689 PointerViewInstanceHash* pNodeHash= m_ShadedPointerViewInstanceHash.value(groupId);
00690
00691 GLC_Shader::use(groupId);
00692 glDrawInstancesOf(pNodeHash, renderFlag);
00693 GLC_Shader::unuse();
00694 }
00695 }
00696
00697
00698 if (renderFlag && !GLC_State::isInSelectionMode() && (groupId == 0))
00699 {
00700 glDisable(GL_BLEND);
00701 glDepthMask(GL_TRUE);
00702 glEnable(GL_DEPTH_TEST);
00703 }
00704 }