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_mesh.h"
00026 #include "../glc_renderstatistics.h"
00027
00028
00029 quint32 GLC_Mesh::m_ChunkId= 0xA701;
00030
00031 GLC_Mesh::GLC_Mesh()
00032 :GLC_Geometry("Mesh", false)
00033 , m_NextPrimitiveLocalId(1)
00034 , m_PrimitiveGroups()
00035 , m_DefaultMaterialId(0)
00036 , m_NumberOfVertice(0)
00037 , m_NumberOfNormals(0)
00038 , m_ColorPearVertex(false)
00039 , m_MeshData()
00040 , m_CurrentLod(0)
00041 {
00042
00043 }
00044
00045 GLC_Mesh::GLC_Mesh(const GLC_Mesh& mesh)
00046 :GLC_Geometry(mesh)
00047 , m_NextPrimitiveLocalId(mesh.m_NextPrimitiveLocalId)
00048 , m_PrimitiveGroups(mesh.m_PrimitiveGroups)
00049 , m_DefaultMaterialId(mesh.m_DefaultMaterialId)
00050 , m_NumberOfVertice(mesh.m_NumberOfVertice)
00051 , m_NumberOfNormals(mesh.m_NumberOfNormals)
00052 , m_ColorPearVertex(mesh.m_ColorPearVertex)
00053 , m_MeshData(mesh.m_MeshData)
00054 , m_CurrentLod(0)
00055 {
00056
00057 PrimitiveGroupsHash::const_iterator iPrimitiveGroups= mesh.m_PrimitiveGroups.constBegin();
00058 while (mesh.m_PrimitiveGroups.constEnd() != iPrimitiveGroups)
00059 {
00060 LodPrimitiveGroups* pPrimitiveGroups= new LodPrimitiveGroups();
00061 m_PrimitiveGroups.insert(iPrimitiveGroups.key(), pPrimitiveGroups);
00062
00063 LodPrimitiveGroups::const_iterator iPrimitiveGroup= iPrimitiveGroups.value()->constBegin();
00064 while (iPrimitiveGroups.value()->constEnd() != iPrimitiveGroup)
00065 {
00066 GLC_PrimitiveGroup* pPrimitiveGroup= new GLC_PrimitiveGroup(*(iPrimitiveGroup.value()), iPrimitiveGroup.key());
00067 pPrimitiveGroups->insert(iPrimitiveGroup.key(), pPrimitiveGroup);
00068
00069 ++iPrimitiveGroup;
00070 }
00071
00072 ++iPrimitiveGroups;
00073 }
00074
00075 }
00076
00077
00078 GLC_Mesh& GLC_Mesh::operator=(const GLC_Mesh& mesh)
00079 {
00080 if (this != &mesh)
00081 {
00082
00083 GLC_Geometry::operator=(mesh);
00084
00085
00086 clearMeshWireAndBoundingBox();
00087
00088
00089 m_NextPrimitiveLocalId= mesh.m_NextPrimitiveLocalId;
00090 m_PrimitiveGroups= mesh.m_PrimitiveGroups;
00091 m_DefaultMaterialId= mesh.m_DefaultMaterialId;
00092 m_NumberOfVertice= mesh.m_NumberOfVertice;
00093 m_NumberOfNormals= mesh.m_NumberOfNormals;
00094 m_ColorPearVertex= mesh.m_ColorPearVertex;
00095 m_MeshData= mesh.m_MeshData;
00096 m_CurrentLod= 0;
00097
00098
00099 PrimitiveGroupsHash::const_iterator iPrimitiveGroups= mesh.m_PrimitiveGroups.constBegin();
00100 while (mesh.m_PrimitiveGroups.constEnd() != iPrimitiveGroups)
00101 {
00102 LodPrimitiveGroups* pPrimitiveGroups= new LodPrimitiveGroups();
00103 m_PrimitiveGroups.insert(iPrimitiveGroups.key(), pPrimitiveGroups);
00104
00105 LodPrimitiveGroups::const_iterator iPrimitiveGroup= iPrimitiveGroups.value()->constBegin();
00106 while (iPrimitiveGroups.value()->constEnd() != iPrimitiveGroup)
00107 {
00108 GLC_PrimitiveGroup* pPrimitiveGroup= new GLC_PrimitiveGroup(*(iPrimitiveGroup.value()), iPrimitiveGroup.key());
00109 pPrimitiveGroups->insert(iPrimitiveGroup.key(), pPrimitiveGroup);
00110
00111 ++iPrimitiveGroup;
00112 }
00113
00114 ++iPrimitiveGroups;
00115 }
00116 }
00117
00118 return *this;
00119 }
00120
00121
00122 GLC_Mesh::~GLC_Mesh()
00123 {
00124 PrimitiveGroupsHash::iterator iGroups= m_PrimitiveGroups.begin();
00125 while (iGroups != m_PrimitiveGroups.constEnd())
00126 {
00127 LodPrimitiveGroups::iterator iGroup= iGroups.value()->begin();
00128 while (iGroup != iGroups.value()->constEnd())
00129 {
00130 delete iGroup.value();
00131
00132 ++iGroup;
00133 }
00134 delete iGroups.value();
00135 ++iGroups;
00136 }
00137 }
00138
00140
00142
00143 quint32 GLC_Mesh::chunckID()
00144 {
00145 return m_ChunkId;
00146 }
00147
00148
00149 unsigned int GLC_Mesh::faceCount(int lod) const
00150 {
00151 return m_MeshData.trianglesCount(lod);
00152 }
00153
00154
00155 unsigned int GLC_Mesh::VertexCount() const
00156 {
00157 return m_NumberOfVertice;
00158 }
00159
00160
00161 const GLC_BoundingBox& GLC_Mesh::boundingBox()
00162 {
00163 if (NULL == m_pBoundingBox)
00164 {
00165
00166 m_pBoundingBox= new GLC_BoundingBox();
00167
00168 if (m_MeshData.positionVectorHandle()->isEmpty())
00169 {
00170 qDebug() << "GLC_ExtendedMesh::getBoundingBox empty m_Positions";
00171 }
00172 else
00173 {
00174 GLfloatVector* pVertexVector= m_MeshData.positionVectorHandle();
00175 const int max= pVertexVector->size();
00176 for (int i= 0; i < max; i= i + 3)
00177 {
00178 GLC_Vector3d vector((*pVertexVector)[i], (*pVertexVector)[i + 1], (*pVertexVector)[i + 2]);
00179 m_pBoundingBox->combine(vector);
00180 }
00181 }
00182
00183 m_pBoundingBox->combine(m_WireData.boundingBox());
00184 }
00185 return *m_pBoundingBox;
00186
00187 }
00188
00189
00190 GLC_Geometry* GLC_Mesh::clone() const
00191 {
00192 return new GLC_Mesh(*this);
00193 }
00194
00195
00196 bool GLC_Mesh::containsTriangles(int lod, GLC_uint materialId) const
00197 {
00198
00199 Q_ASSERT(m_PrimitiveGroups.contains(lod));
00200 if (!m_PrimitiveGroups.value(lod)->contains(materialId)) return false;
00201 else return m_PrimitiveGroups.value(lod)->value(materialId)->containsTriangles();
00202 }
00203
00204
00205 QVector<GLuint> GLC_Mesh::getTrianglesIndex(int lod, GLC_uint materialId) const
00206 {
00207
00208 Q_ASSERT(containsTriangles(lod, materialId));
00209
00210 GLC_PrimitiveGroup* pPrimitiveGroup= m_PrimitiveGroups.value(lod)->value(materialId);
00211
00212 int offset= 0;
00213 if (GLC_State::vboUsed())
00214 {
00215 offset= static_cast<int>(reinterpret_cast<GLsizeiptr>(pPrimitiveGroup->trianglesIndexOffset()) / sizeof(GLuint));
00216 }
00217 else
00218 {
00219 offset= pPrimitiveGroup->trianglesIndexOffseti();
00220 }
00221 const int size= pPrimitiveGroup->trianglesIndexSize();
00222
00223 QVector<GLuint> resultIndex(size);
00224
00225 memcpy((void*)resultIndex.data(), &(m_MeshData.indexVector(lod).data())[offset], size * sizeof(GLuint));
00226
00227 return resultIndex;
00228 }
00229
00230
00231 int GLC_Mesh::numberOfTriangles(int lod, GLC_uint materialId) const
00232 {
00233
00234 if (!m_PrimitiveGroups.contains(lod))return 0;
00235 else if (!m_PrimitiveGroups.value(lod)->contains(materialId)) return 0;
00236 else return m_PrimitiveGroups.value(lod)->value(materialId)->trianglesIndexSize();
00237 }
00238
00239
00240 bool GLC_Mesh::containsStrips(int lod, GLC_uint materialId) const
00241 {
00242
00243 if (!m_PrimitiveGroups.contains(lod))return false;
00244 else if (!m_PrimitiveGroups.value(lod)->contains(materialId)) return false;
00245 else return m_PrimitiveGroups.value(lod)->value(materialId)->containsStrip();
00246
00247 }
00248
00249
00250 QList<QVector<GLuint> > GLC_Mesh::getStripsIndex(int lod, GLC_uint materialId) const
00251 {
00252
00253 Q_ASSERT(containsStrips(lod, materialId));
00254
00255 GLC_PrimitiveGroup* pPrimitiveGroup= m_PrimitiveGroups.value(lod)->value(materialId);
00256
00257 QList<int> offsets;
00258 QList<int> sizes;
00259 int stripsCount;
00260
00261 if (GLC_State::vboUsed())
00262 {
00263 stripsCount= pPrimitiveGroup->stripsOffset().size();
00264 for (int i= 0; i < stripsCount; ++i)
00265 {
00266 offsets.append(static_cast<int>(reinterpret_cast<GLsizeiptr>(pPrimitiveGroup->stripsOffset().at(i)) / sizeof(GLuint)));
00267 sizes.append(static_cast<int>(pPrimitiveGroup->stripsSizes().at(i)));
00268 }
00269 }
00270 else
00271 {
00272 stripsCount= pPrimitiveGroup->stripsOffseti().size();
00273 for (int i= 0; i < stripsCount; ++i)
00274 {
00275 offsets.append(static_cast<int>(pPrimitiveGroup->stripsOffseti().at(i)));
00276 sizes.append(static_cast<int>(pPrimitiveGroup->stripsSizes().at(i)));
00277 }
00278
00279 }
00280
00281 QList<QVector<GLuint> > result;
00282
00283 QVector<GLuint> SourceIndex(m_MeshData.indexVector(lod));
00284 for (int i= 0; i < stripsCount; ++i)
00285 {
00286 QVector<GLuint> currentStrip(sizes.at(i));
00287 memcpy((void*)currentStrip.data(), &(SourceIndex.data())[offsets.at(i)], sizes.at(i) * sizeof(GLuint));
00288 result.append(currentStrip);
00289 }
00290
00291 return result;
00292 }
00293
00294
00295 int GLC_Mesh::numberOfStrips(int lod, GLC_uint materialId) const
00296 {
00297
00298 if (!m_PrimitiveGroups.contains(lod))return 0;
00299 else if (!m_PrimitiveGroups.value(lod)->contains(materialId)) return 0;
00300 else return m_PrimitiveGroups.value(lod)->value(materialId)->stripsSizes().size();
00301 }
00302
00303
00304 bool GLC_Mesh::containsFans(int lod, GLC_uint materialId) const
00305 {
00306
00307 if (!m_PrimitiveGroups.contains(lod))return false;
00308 else if (!m_PrimitiveGroups.value(lod)->contains(materialId)) return false;
00309 else return m_PrimitiveGroups.value(lod)->value(materialId)->containsFan();
00310
00311 }
00312
00314 int GLC_Mesh::numberOfFans(int lod, GLC_uint materialId) const
00315 {
00316
00317 if(!m_PrimitiveGroups.contains(lod))return 0;
00318 else if (!m_PrimitiveGroups.value(lod)->contains(materialId)) return 0;
00319 else return m_PrimitiveGroups.value(lod)->value(materialId)->fansSizes().size();
00320 }
00321
00322
00323 QList<QVector<GLuint> > GLC_Mesh::getFansIndex(int lod, GLC_uint materialId) const
00324 {
00325
00326 Q_ASSERT(containsFans(lod, materialId));
00327
00328 GLC_PrimitiveGroup* pPrimitiveGroup= m_PrimitiveGroups.value(lod)->value(materialId);
00329
00330 QList<int> offsets;
00331 QList<int> sizes;
00332 int fansCount;
00333
00334 if (GLC_State::vboUsed())
00335 {
00336 fansCount= pPrimitiveGroup->fansOffset().size();
00337 for (int i= 0; i < fansCount; ++i)
00338 {
00339 offsets.append(static_cast<int>(reinterpret_cast<GLsizeiptr>(pPrimitiveGroup->fansOffset().at(i)) / sizeof(GLuint)));
00340 sizes.append(static_cast<int>(pPrimitiveGroup->fansSizes().at(i)));
00341 }
00342 }
00343 else
00344 {
00345 fansCount= pPrimitiveGroup->fansOffseti().size();
00346 for (int i= 0; i < fansCount; ++i)
00347 {
00348 offsets.append(static_cast<int>(pPrimitiveGroup->fansOffseti().at(i)));
00349 sizes.append(static_cast<int>(pPrimitiveGroup->fansSizes().at(i)));
00350 }
00351
00352 }
00353
00354 QList<QVector<GLuint> > result;
00355
00356 QVector<GLuint> SourceIndex(m_MeshData.indexVector(lod));
00357 for (int i= 0; i < fansCount; ++i)
00358 {
00359 QVector<GLuint> currentFan(sizes.at(i));
00360 memcpy((void*)currentFan.data(), &(SourceIndex.data())[offsets.at(i)], sizes.at(i) * sizeof(GLuint));
00361 result.append(currentFan);
00362 }
00363
00364 return result;
00365 }
00366
00367 GLC_Mesh* GLC_Mesh::createMeshOfGivenLod(int lodIndex)
00368 {
00369 Q_ASSERT(m_MeshData.lodCount() > lodIndex);
00370
00371 copyVboToClientSide();
00372 GLC_Mesh* pLodMesh= new GLC_Mesh;
00373 pLodMesh->setName(this->name() + "-LOD-" + QString::number(lodIndex));
00374 QHash<GLuint, GLuint> sourceToTargetIndexMap;
00375 QHash<GLuint, GLuint> tagetToSourceIndexMap;
00376 int maxIndex= -1;
00377
00378 int targetLod= 0;
00379 copyIndex(lodIndex, pLodMesh, sourceToTargetIndexMap, tagetToSourceIndexMap, maxIndex, targetLod);
00380
00381 copyBulkData(pLodMesh, tagetToSourceIndexMap, maxIndex);
00382
00383 pLodMesh->finish();
00384
00385 releaseVboClientSide(false);
00386
00387 return pLodMesh;
00388 }
00389
00390 GLC_Mesh* GLC_Mesh::createMeshFromGivenLod(int lodIndex)
00391 {
00392 const int lodCount= m_MeshData.lodCount();
00393 Q_ASSERT(lodCount > lodIndex);
00394
00395 copyVboToClientSide();
00396 GLC_Mesh* pLodMesh= new GLC_Mesh;
00397 pLodMesh->setName(this->name() + "-LOD-" + QString::number(lodIndex));
00398 QHash<GLuint, GLuint> sourceToTargetIndexMap;
00399 QHash<GLuint, GLuint> tagetToSourceIndexMap;
00400 int maxIndex= -1;
00401
00402 if ((lodCount - lodIndex) > 1)
00403 {
00404 int targetLod= 1;
00405 for (int i= lodIndex + 1; i < lodCount; ++i)
00406 {
00407 copyIndex(i, pLodMesh, sourceToTargetIndexMap, tagetToSourceIndexMap, maxIndex, targetLod);
00408 ++targetLod;
00409 }
00410 copyIndex(lodIndex, pLodMesh, sourceToTargetIndexMap, tagetToSourceIndexMap, maxIndex, 0);
00411 }
00412 else
00413 {
00414 copyIndex(lodIndex, pLodMesh, sourceToTargetIndexMap, tagetToSourceIndexMap, maxIndex, 0);
00415 }
00416
00417
00418 copyBulkData(pLodMesh, tagetToSourceIndexMap, maxIndex);
00419
00420 pLodMesh->finish();
00421
00422 releaseVboClientSide(false);
00423
00424 return pLodMesh;
00425 }
00426 GLC_Mesh& GLC_Mesh::transformVertice(const GLC_Matrix4x4& matrix)
00427 {
00428 if (matrix.type() != GLC_Matrix4x4::Identity)
00429 {
00430 delete m_pBoundingBox;
00431 m_pBoundingBox= NULL;
00432 copyVboToClientSide();
00433 const int stride= 3;
00434 GLfloatVector* pVectPos= m_MeshData.positionVectorHandle();
00435 const GLC_Matrix4x4 rotationMatrix= matrix.rotationMatrix();
00436 GLfloatVector* pVectNormal= m_MeshData.normalVectorHandle();
00437 const int verticeCount= pVectPos->size() / stride;
00438 for (int i= 0; i < verticeCount; ++i)
00439 {
00440 GLC_Vector3d newPos(pVectPos->at(stride * i), pVectPos->at(stride * i + 1), pVectPos->at(stride * i + 2));
00441 newPos= matrix * newPos;
00442 pVectPos->operator[](stride * i)= static_cast<GLfloat>(newPos.x());
00443 pVectPos->operator[](stride * i + 1)= static_cast<GLfloat>(newPos.y());
00444 pVectPos->operator[](stride * i + 2)= static_cast<GLfloat>(newPos.z());
00445
00446 GLC_Vector3d newNormal(pVectNormal->at(stride * i), pVectNormal->at(stride * i + 1), pVectNormal->at(stride * i + 2));
00447 newNormal= rotationMatrix * newNormal;
00448 pVectNormal->operator[](stride * i)= static_cast<GLfloat>(newNormal.x());
00449 pVectNormal->operator[](stride * i + 1)= static_cast<GLfloat>(newNormal.y());
00450 pVectNormal->operator[](stride * i + 2)= static_cast<GLfloat>(newNormal.z());
00451 }
00452 releaseVboClientSide(true);
00453 }
00454
00455 return *this;
00456 }
00457
00459
00461
00462
00463 void GLC_Mesh::clear()
00464 {
00465
00466 clearMeshWireAndBoundingBox();
00467
00468
00469 GLC_Geometry::clear();
00470 }
00471
00472
00473
00474 void GLC_Mesh::clearMeshWireAndBoundingBox()
00475 {
00476
00477 m_NextPrimitiveLocalId= 1;
00478
00479
00480 PrimitiveGroupsHash::iterator iGroups= m_PrimitiveGroups.begin();
00481 while (iGroups != m_PrimitiveGroups.constEnd())
00482 {
00483 LodPrimitiveGroups::iterator iGroup= iGroups.value()->begin();
00484 while (iGroup != iGroups.value()->constEnd())
00485 {
00486 delete iGroup.value();
00487
00488 ++iGroup;
00489 }
00490 delete iGroups.value();
00491 ++iGroups;
00492 }
00493 m_PrimitiveGroups.clear();
00494
00495 m_DefaultMaterialId= 0;
00496 m_NumberOfVertice= 0;
00497 m_NumberOfNormals= 0;
00498 m_IsSelected= false;
00499 m_ColorPearVertex= false;
00500
00501 m_MeshData.clear();
00502 m_CurrentLod= 0;
00503
00504 GLC_Geometry::clearWireAndBoundingBox();
00505 }
00506
00507
00508 GLC_uint GLC_Mesh::addTriangles(GLC_Material* pMaterial, const IndexList& indexList, const int lod, double accuracy)
00509 {
00510 GLC_uint groupId= setCurrentMaterial(pMaterial, lod, accuracy);
00511 Q_ASSERT(m_PrimitiveGroups.value(lod)->contains(groupId));
00512 Q_ASSERT(!indexList.isEmpty());
00513
00514 GLC_uint id= 0;
00515 if (0 == lod)
00516 {
00517 id= m_NextPrimitiveLocalId++;
00518 }
00519 m_MeshData.trianglesAdded(lod, indexList.size() / 3);
00520
00521 m_PrimitiveGroups.value(lod)->value(groupId)->addTriangles(indexList, id);
00522
00523
00524 m_GeometryIsValid = false;
00525
00526 return id;
00527 }
00528
00529
00530 GLC_uint GLC_Mesh::addTrianglesStrip(GLC_Material* pMaterial, const IndexList& indexList, const int lod, double accuracy)
00531 {
00532 GLC_uint groupId= setCurrentMaterial(pMaterial, lod, accuracy);
00533 Q_ASSERT(m_PrimitiveGroups.value(lod)->contains(groupId));
00534 Q_ASSERT(!indexList.isEmpty());
00535
00536 GLC_uint id= 0;
00537 if (0 == lod)
00538 {
00539 id= m_NextPrimitiveLocalId++;
00540 }
00541 m_MeshData.trianglesAdded(lod, indexList.size() - 2);
00542
00543 m_PrimitiveGroups.value(lod)->value(groupId)->addTrianglesStrip(indexList, id);
00544
00545
00546 m_GeometryIsValid = false;
00547
00548 return id;
00549 }
00550
00551 GLC_uint GLC_Mesh::addTrianglesFan(GLC_Material* pMaterial, const IndexList& indexList, const int lod, double accuracy)
00552 {
00553 GLC_uint groupId= setCurrentMaterial(pMaterial, lod, accuracy);
00554 Q_ASSERT(m_PrimitiveGroups.value(lod)->contains(groupId));
00555 Q_ASSERT(!indexList.isEmpty());
00556
00557 GLC_uint id= 0;
00558 if (0 == lod)
00559 {
00560 id= m_NextPrimitiveLocalId++;
00561 }
00562 m_MeshData.trianglesAdded(lod, indexList.size() - 2);
00563 m_PrimitiveGroups.value(lod)->value(groupId)->addTrianglesFan(indexList, id);
00564
00565
00566 m_GeometryIsValid = false;
00567
00568 return id;
00569 }
00570
00571
00572 void GLC_Mesh::reverseNormals()
00573 {
00574 GLfloatVector* pNormalVector= m_MeshData.normalVectorHandle();
00575 if (pNormalVector->isEmpty())
00576 {
00577 (*m_MeshData.normalVectorHandle())= m_MeshData.normalVector();
00578 }
00579 const int size= pNormalVector->size();
00580 for (int i= 0; i < size; ++i)
00581 {
00582 (*pNormalVector)[i]= - pNormalVector->at(i);
00583 }
00584
00585 m_GeometryIsValid = false;
00586 }
00587
00588
00589 void GLC_Mesh::finish()
00590 {
00591 boundingBox();
00592
00593 m_MeshData.finishLod();
00594
00595 if (GLC_State::vboUsed())
00596 {
00597 finishVbo();
00598 }
00599 else
00600 {
00601 finishNonVbo();
00602 }
00603
00604
00605 }
00606
00607
00608
00609 void GLC_Mesh::setCurrentLod(const int value)
00610 {
00611 if (value)
00612 {
00613 const int numberOfLod= m_MeshData.lodCount() - 1;
00614
00615 m_CurrentLod= qRound(static_cast<int>((static_cast<double>(value) / 100.0) * numberOfLod));
00616 }
00617 else
00618 {
00619 m_CurrentLod= 0;
00620 }
00621 }
00622
00623 void GLC_Mesh::replaceMasterMaterial(GLC_Material* pMat)
00624 {
00625 if (hasMaterial())
00626 {
00627 GLC_uint oldId= firstMaterial()->id();
00628 replaceMaterial(oldId, pMat);
00629 }
00630 else
00631 {
00632 addMaterial(pMat);
00633 }
00634 }
00635
00636
00637 void GLC_Mesh::replaceMaterial(const GLC_uint oldId, GLC_Material* pMat)
00638 {
00639 Q_ASSERT(containsMaterial(oldId));
00640 Q_ASSERT(!containsMaterial(pMat->id()) || (pMat->id() == oldId));
00641
00642 if (pMat->id() != oldId)
00643 {
00644
00645 PrimitiveGroupsHash::const_iterator iGroups= m_PrimitiveGroups.constBegin();
00646 while (m_PrimitiveGroups.constEnd() != iGroups)
00647 {
00648 LodPrimitiveGroups* pPrimitiveGroups= iGroups.value();
00649
00650 LodPrimitiveGroups::iterator iGroup= pPrimitiveGroups->begin();
00651 while (pPrimitiveGroups->constEnd() != iGroup)
00652 {
00653 if (iGroup.key() == oldId)
00654 {
00655 GLC_PrimitiveGroup* pGroup= iGroup.value();
00656
00657 pPrimitiveGroups->erase(iGroup);
00658
00659 pGroup->setId(pMat->id());
00660
00661 pPrimitiveGroups->insert(pMat->id(), pGroup);
00662 iGroup= pPrimitiveGroups->end();
00663 }
00664 else
00665 {
00666 ++iGroup;
00667 }
00668 }
00669 ++iGroups;
00670 }
00671 }
00672
00673 if (pMat != m_MaterialHash.value(oldId))
00674 {
00675
00676 removeMaterial(oldId);
00677
00678 addMaterial(pMat);
00679 }
00680
00681 }
00682
00683 void GLC_Mesh::copyVboToClientSide()
00684 {
00685 m_MeshData.copyVboToClientSide();
00686 GLC_Geometry::copyVboToClientSide();
00687 }
00688
00689 void GLC_Mesh::releaseVboClientSide(bool update)
00690 {
00691 m_MeshData.releaseVboClientSide(update);
00692 GLC_Geometry::releaseVboClientSide(update);
00693 }
00694
00695
00696 void GLC_Mesh::loadFromDataStream(QDataStream& stream, const MaterialHash& materialHash, const QHash<GLC_uint, GLC_uint>& materialIdMap)
00697 {
00698 quint32 chunckId;
00699 stream >> chunckId;
00700 Q_ASSERT(chunckId == m_ChunkId);
00701
00702
00703 QString meshName;
00704 stream >> meshName;
00705 setName(meshName);
00706
00707
00708 stream >> GLC_Geometry::m_WireData;
00709
00710
00711 GLC_uint localId;
00712 stream >> localId;
00713 setNextPrimitiveLocalId(localId);
00714
00715
00716 stream >> m_MeshData;
00717
00718
00719 QList<int> primitiveGroupLodList;
00720 stream >> primitiveGroupLodList;
00721
00722
00723 QList<QList<GLC_PrimitiveGroup> > primitiveListOfGroupList;
00724 stream >> primitiveListOfGroupList;
00725
00726
00727 const int lodCount= primitiveGroupLodList.size();
00728 for (int i= 0; i < lodCount; ++i)
00729 {
00730 GLC_Mesh::LodPrimitiveGroups* pCurrentPrimitiveGroup= new GLC_Mesh::LodPrimitiveGroups();
00731 m_PrimitiveGroups.insert(primitiveGroupLodList.at(i), pCurrentPrimitiveGroup);
00732 const int groupCount= primitiveListOfGroupList.at(i).size();
00733 for (int iGroup= 0; iGroup < groupCount; ++iGroup)
00734 {
00735 Q_ASSERT(materialIdMap.contains(primitiveListOfGroupList.at(i).at(iGroup).id()));
00736 const GLC_uint newId= materialIdMap.value(primitiveListOfGroupList.at(i).at(iGroup).id());
00737
00738 if (!containsMaterial(newId))
00739 {
00740 addMaterial(materialHash.value(newId));
00741 }
00742 GLC_PrimitiveGroup* pGroup= new GLC_PrimitiveGroup(primitiveListOfGroupList.at(i).at(iGroup), newId);
00743
00744 Q_ASSERT(! m_PrimitiveGroups.value(primitiveGroupLodList.at(i))->contains(newId));
00745 m_PrimitiveGroups.value(primitiveGroupLodList.at(i))->insert(newId, pGroup);
00746 }
00747 }
00748 stream >> m_NumberOfVertice;
00749 stream >> m_NumberOfNormals;
00750
00751 finishSerialized();
00752
00753 }
00754
00755
00756 void GLC_Mesh::saveToDataStream(QDataStream& stream) const
00757 {
00758 quint32 chunckId= m_ChunkId;
00759 stream << chunckId;
00760
00761
00762 stream << name();
00763
00764
00765 stream << m_WireData;
00766
00767
00768 stream << nextPrimitiveLocalId();
00769
00770
00771 stream << m_MeshData;
00772
00773
00774 QList<int> primitiveGroupLodList;
00775 QList<QList<GLC_PrimitiveGroup> > primitiveListOfGroupList;
00776
00777 GLC_Mesh::PrimitiveGroupsHash::const_iterator iGroupsHash= m_PrimitiveGroups.constBegin();
00778 while (m_PrimitiveGroups.constEnd() != iGroupsHash)
00779 {
00780 primitiveGroupLodList.append(iGroupsHash.key());
00781 QList<GLC_PrimitiveGroup> primitiveGroupList;
00782 GLC_Mesh::LodPrimitiveGroups::const_iterator iGroups= iGroupsHash.value()->constBegin();
00783 while (iGroupsHash.value()->constEnd() != iGroups)
00784 {
00785 primitiveGroupList.append(*(iGroups.value()));
00786 ++iGroups;
00787 }
00788 primitiveListOfGroupList.append(primitiveGroupList);
00789 ++iGroupsHash;
00790 }
00791 stream << primitiveGroupLodList;
00792 stream << primitiveListOfGroupList;
00793
00794 stream << m_NumberOfVertice;
00795 stream << m_NumberOfNormals;
00796 }
00797
00799
00801
00802
00803 void GLC_Mesh::glDraw(const GLC_RenderProperties& renderProperties)
00804 {
00805 Q_ASSERT(m_GeometryIsValid || !m_MeshData.normalVectorHandle()->isEmpty());
00806
00807 const bool vboIsUsed= GLC_State::vboUsed();
00808
00809 if (m_IsSelected && (renderProperties.renderingMode() == glc::PrimitiveSelected) && !GLC_State::isInSelectionMode()
00810 && !renderProperties.setOfSelectedPrimitiveIdIsEmpty())
00811 {
00812 m_CurrentLod= 0;
00813 }
00814
00815 if (vboIsUsed)
00816 {
00817 m_MeshData.createVBOs();
00818
00819
00820 if (!m_GeometryIsValid && !m_MeshData.positionVectorHandle()->isEmpty())
00821 {
00822 fillVbosAndIbos();
00823 }
00824 else if (!m_GeometryIsValid && !m_MeshData.normalVectorHandle()->isEmpty())
00825 {
00826
00827 m_MeshData.useVBO(true, GLC_MeshData::GLC_Normal);
00828
00829 GLfloatVector* pNormalVector= m_MeshData.normalVectorHandle();
00830 const GLsizei dataNbr= static_cast<GLsizei>(pNormalVector->size());
00831 const GLsizeiptr dataSize= dataNbr * sizeof(GLfloat);
00832 glBufferData(GL_ARRAY_BUFFER, dataSize, pNormalVector->data(), GL_STATIC_DRAW);
00833 m_MeshData.normalVectorHandle()->clear();
00834 }
00835
00836
00837 activateVboAndIbo();
00838 }
00839 else
00840 {
00841 activateVertexArray();
00842 }
00843
00844 if (GLC_State::isInSelectionMode())
00845 {
00846 if (renderProperties.renderingMode() == glc::PrimitiveSelection)
00847 {
00848 primitiveSelectionRenderLoop(vboIsUsed);
00849 }
00850 else if (renderProperties.renderingMode() == glc::BodySelection)
00851 {
00852 bodySelectionRenderLoop(vboIsUsed);
00853 }
00854 else
00855 {
00856 normalRenderLoop(renderProperties, vboIsUsed);
00857 }
00858 }
00859 else if (m_IsSelected)
00860 {
00861 if (renderProperties.renderingMode() == glc::PrimitiveSelected)
00862 {
00863 if (!renderProperties.setOfSelectedPrimitiveIdIsEmpty())
00864 {
00865 primitiveSelectedRenderLoop(renderProperties, vboIsUsed);
00866 }
00867 else
00868 {
00869 m_IsSelected= false;
00870 if ((m_CurrentLod == 0) && (renderProperties.savedRenderingMode() == glc::OverwritePrimitiveMaterial) && !renderProperties.hashOfOverwritePrimitiveMaterialsIsEmpty())
00871 primitiveRenderLoop(renderProperties, vboIsUsed);
00872 else
00873 normalRenderLoop(renderProperties, vboIsUsed);
00874 m_IsSelected= true;
00875 }
00876 }
00877 else
00878 {
00879 normalRenderLoop(renderProperties, vboIsUsed);
00880 }
00881 }
00882 else
00883 {
00884
00885 switch (renderProperties.renderingMode())
00886 {
00887 case glc::NormalRenderMode:
00888 normalRenderLoop(renderProperties, vboIsUsed);
00889 break;
00890 case glc::OverwriteMaterial:
00891 OverwriteMaterialRenderLoop(renderProperties, vboIsUsed);
00892 break;
00893 case glc::OverwriteTransparency:
00894 OverwriteTransparencyRenderLoop(renderProperties, vboIsUsed);
00895 break;
00896 case glc::OverwritePrimitiveMaterial:
00897 if ((m_CurrentLod == 0) && !renderProperties.hashOfOverwritePrimitiveMaterialsIsEmpty())
00898 primitiveRenderLoop(renderProperties, vboIsUsed);
00899 else
00900 normalRenderLoop(renderProperties, vboIsUsed);
00901 break;
00902 default:
00903 Q_ASSERT(false);
00904 break;
00905 }
00906 }
00907
00908
00909
00910 if (vboIsUsed)
00911 {
00912 m_MeshData.useIBO(false);
00913 m_MeshData.useVBO(false, GLC_MeshData::GLC_Normal);
00914 }
00915
00916 if (m_ColorPearVertex && !m_IsSelected && !GLC_State::isInSelectionMode())
00917 {
00918 glDisableClientState(GL_COLOR_ARRAY);
00919 glDisable(GL_COLOR_MATERIAL);
00920 }
00921
00922 glDisableClientState(GL_VERTEX_ARRAY);
00923 glDisableClientState(GL_NORMAL_ARRAY);
00924 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
00925
00926
00927 if ((renderProperties.renderingFlag() == glc::WireRenderFlag) && !m_WireData.isEmpty() && !GLC_Geometry::typeIsWire())
00928 {
00929 if (!GLC_State::isInSelectionMode())
00930 {
00931 glDisable(GL_LIGHTING);
00932
00933 GLfloat color[4]= {static_cast<float>(m_WireColor.redF()),
00934 static_cast<float>(m_WireColor.greenF()),
00935 static_cast<float>(m_WireColor.blueF()),
00936 static_cast<float>(m_WireColor.alphaF())};
00937
00938 glColor4fv(color);
00939 m_WireData.glDraw(renderProperties, GL_LINE_STRIP);
00940 glEnable(GL_LIGHTING);
00941 }
00942 else
00943 {
00944 m_WireData.glDraw(renderProperties, GL_LINE_STRIP);
00945 }
00946 }
00947
00948
00949 GLC_RenderStatistics::addBodies(1);
00950 GLC_RenderStatistics::addTriangles(m_MeshData.trianglesCount(m_CurrentLod));
00951 }
00952
00954
00956
00957
00958 GLC_uint GLC_Mesh::setCurrentMaterial(GLC_Material* pMaterial, int lod, double accuracy)
00959 {
00960
00961
00962 if (!m_PrimitiveGroups.contains(lod))
00963 {
00964 m_PrimitiveGroups.insert(lod, new LodPrimitiveGroups());
00965
00966 m_MeshData.appendLod(accuracy);
00967 }
00968
00969 GLC_uint returnId;
00970 if (NULL == pMaterial)
00971 {
00972 returnId= m_DefaultMaterialId;
00973
00974
00975 if (m_DefaultMaterialId == 0)
00976 {
00977 pMaterial= new GLC_Material();
00978
00979 addMaterial(pMaterial);
00980 m_DefaultMaterialId= pMaterial->id();
00981 returnId= m_DefaultMaterialId;
00982
00983 }
00984
00985 if (!m_PrimitiveGroups.value(lod)->contains(returnId))
00986 {
00987 m_PrimitiveGroups.value(lod)->insert(returnId, new GLC_PrimitiveGroup(returnId));
00988 }
00989 }
00990 else
00991 {
00992 returnId= pMaterial->id();
00993
00994 if (!containsMaterial(returnId))
00995 {
00996
00997 addMaterial(pMaterial);
00998 m_PrimitiveGroups.value(lod)->insert(returnId, new GLC_PrimitiveGroup(returnId));
00999
01000 }
01001 else if (!m_PrimitiveGroups.value(lod)->contains(returnId))
01002 {
01003
01004 m_PrimitiveGroups.value(lod)->insert(returnId, new GLC_PrimitiveGroup(returnId));
01005 }
01006 }
01007
01008 return returnId;
01009 }
01010
01011
01012 void GLC_Mesh::fillVbosAndIbos()
01013 {
01014
01015 m_MeshData.fillVbo(GLC_MeshData::GLC_Vertex);
01016
01017
01018 m_MeshData.fillVbo(GLC_MeshData::GLC_Normal);
01019
01020
01021 m_MeshData.fillVbo(GLC_MeshData::GLC_Texel);
01022
01023
01024 m_MeshData.fillVbo(GLC_MeshData::GLC_Color);
01025
01026 const int lodNumber= m_MeshData.lodCount();
01027 for (int i= 0; i < lodNumber; ++i)
01028 {
01029
01030 if (!m_MeshData.indexVectorHandle(i)->isEmpty())
01031 {
01032 QVector<GLuint>* pIndexVector= m_MeshData.indexVectorHandle(i);
01033 m_MeshData.useIBO(true, i);
01034 const GLsizei indexNbr= static_cast<GLsizei>(pIndexVector->size());
01035 const GLsizeiptr indexSize = indexNbr * sizeof(GLuint);
01036 glBufferData(GL_ELEMENT_ARRAY_BUFFER, indexSize, pIndexVector->data(), GL_STATIC_DRAW);
01037 }
01038 }
01039
01040 m_MeshData.finishVbo();
01041
01042 }
01043
01044 void GLC_Mesh::finishSerialized()
01045 {
01046 if (GLC_State::vboUsed())
01047 {
01048 PrimitiveGroupsHash::iterator iGroups= m_PrimitiveGroups.begin();
01049 while (iGroups != m_PrimitiveGroups.constEnd())
01050 {
01051 LodPrimitiveGroups::iterator iGroup= iGroups.value()->begin();
01052 while (iGroup != iGroups.value()->constEnd())
01053 {
01054 iGroup.value()->changeToVboMode();
01055 ++iGroup;
01056 }
01057 ++iGroups;
01058 }
01059 }
01060 }
01061
01062
01063 void GLC_Mesh::finishVbo()
01064 {
01065 PrimitiveGroupsHash::iterator iGroups= m_PrimitiveGroups.begin();
01066 while (iGroups != m_PrimitiveGroups.constEnd())
01067 {
01068 int currentLod= iGroups.key();
01069 LodPrimitiveGroups::iterator iGroup= iGroups.value()->begin();
01070 while (iGroup != iGroups.value()->constEnd())
01071 {
01072
01073 if (iGroup.value()->containsTriangles())
01074 {
01075 iGroup.value()->setTrianglesOffset(BUFFER_OFFSET(m_MeshData.indexVectorSize(currentLod) * sizeof(GLuint)));
01076 (*m_MeshData.indexVectorHandle(currentLod))+= iGroup.value()->trianglesIndex().toVector();
01077 }
01078
01079
01080 if (iGroup.value()->containsStrip())
01081 {
01082 iGroup.value()->setBaseTrianglesStripOffset(BUFFER_OFFSET(m_MeshData.indexVectorSize(currentLod) * sizeof(GLuint)));
01083 (*m_MeshData.indexVectorHandle(currentLod))+= iGroup.value()->stripsIndex().toVector();
01084 }
01085
01086
01087 if (iGroup.value()->containsFan())
01088 {
01089 iGroup.value()->setBaseTrianglesFanOffset(BUFFER_OFFSET(m_MeshData.indexVectorSize(currentLod) * sizeof(GLuint)));
01090 (*m_MeshData.indexVectorHandle(currentLod))+= iGroup.value()->fansIndex().toVector();
01091 }
01092
01093 iGroup.value()->finish();
01094 ++iGroup;
01095 }
01096 ++iGroups;
01097
01098 }
01099 }
01100
01101
01102 void GLC_Mesh::finishNonVbo()
01103 {
01104
01105 PrimitiveGroupsHash::iterator iGroups= m_PrimitiveGroups.begin();
01106 while (iGroups != m_PrimitiveGroups.constEnd())
01107 {
01108 int currentLod= iGroups.key();
01109 LodPrimitiveGroups::iterator iGroup= iGroups.value()->begin();
01110 while (iGroup != iGroups.value()->constEnd())
01111 {
01112
01113 if (iGroup.value()->containsTriangles())
01114 {
01115 iGroup.value()->setTrianglesOffseti(m_MeshData.indexVectorSize(currentLod));
01116 (*m_MeshData.indexVectorHandle(currentLod))+= iGroup.value()->trianglesIndex().toVector();
01117 }
01118
01119
01120 if (iGroup.value()->containsStrip())
01121 {
01122 iGroup.value()->setBaseTrianglesStripOffseti(m_MeshData.indexVectorSize(currentLod));
01123 (*m_MeshData.indexVectorHandle(currentLod))+= iGroup.value()->stripsIndex().toVector();
01124 }
01125
01126
01127 if (iGroup.value()->containsFan())
01128 {
01129 iGroup.value()->setBaseTrianglesFanOffseti(m_MeshData.indexVectorSize(currentLod));
01130 (*m_MeshData.indexVectorHandle(currentLod))+= iGroup.value()->fansIndex().toVector();
01131 }
01132
01133 iGroup.value()->finish();
01134 ++iGroup;
01135 }
01136 ++iGroups;
01137 }
01138 }
01139
01140
01141 void GLC_Mesh::normalRenderLoop(const GLC_RenderProperties& renderProperties, bool vboIsUsed)
01142 {
01143 const bool isTransparent= (renderProperties.renderingFlag() == glc::TransparentRenderFlag);
01144 if ((!m_IsSelected || !isTransparent) || GLC_State::isInSelectionMode())
01145 {
01146 LodPrimitiveGroups::iterator iGroup= m_PrimitiveGroups.value(m_CurrentLod)->begin();
01147 while (iGroup != m_PrimitiveGroups.value(m_CurrentLod)->constEnd())
01148 {
01149 GLC_PrimitiveGroup* pCurrentGroup= iGroup.value();
01150 GLC_Material* pCurrentMaterial= m_MaterialHash.value(pCurrentGroup->id());
01151
01152
01153 bool materialIsrenderable = (pCurrentMaterial->isTransparent() == isTransparent);
01154
01155
01156 if ((materialIsrenderable || m_IsSelected) && !GLC_State::isInSelectionMode())
01157 {
01158
01159 pCurrentMaterial->glExecute();
01160
01161 if (m_IsSelected) GLC_SelectionMaterial::glExecute();
01162 }
01163
01164
01165 if (m_IsSelected || GLC_State::isInSelectionMode() || materialIsrenderable)
01166 {
01167
01168 if (vboIsUsed)
01169 vboDrawPrimitivesOf(pCurrentGroup);
01170 else
01171 vertexArrayDrawPrimitivesOf(pCurrentGroup);
01172 }
01173
01174 ++iGroup;
01175 }
01176 }
01177 }
01178
01179
01180 void GLC_Mesh::OverwriteMaterialRenderLoop(const GLC_RenderProperties& renderProperties, bool vboIsUsed)
01181 {
01182
01183 GLC_Material* pOverwriteMaterial= renderProperties.overwriteMaterial();
01184 Q_ASSERT(NULL != pOverwriteMaterial);
01185 pOverwriteMaterial->glExecute();
01186 if (m_IsSelected) GLC_SelectionMaterial::glExecute();
01187
01188 LodPrimitiveGroups::iterator iGroup= m_PrimitiveGroups.value(m_CurrentLod)->begin();
01189 while (iGroup != m_PrimitiveGroups.value(m_CurrentLod)->constEnd())
01190 {
01191 GLC_PrimitiveGroup* pCurrentGroup= iGroup.value();
01192
01193
01194 bool materialIsrenderable = (pOverwriteMaterial->isTransparent() == (renderProperties.renderingFlag() == glc::TransparentRenderFlag));
01195
01196
01197 if (m_IsSelected || materialIsrenderable)
01198 {
01199
01200 if (vboIsUsed)
01201 vboDrawPrimitivesOf(pCurrentGroup);
01202 else
01203 vertexArrayDrawPrimitivesOf(pCurrentGroup);
01204 }
01205
01206 ++iGroup;
01207 }
01208 }
01209
01210 void GLC_Mesh::OverwriteTransparencyRenderLoop(const GLC_RenderProperties& renderProperties, bool vboIsUsed)
01211 {
01212
01213 const float alpha= renderProperties.overwriteTransparency();
01214 Q_ASSERT(-1.0f != alpha);
01215
01216
01217 bool materialIsrenderable = (renderProperties.renderingFlag() == glc::TransparentRenderFlag);
01218
01219 if (materialIsrenderable || m_IsSelected)
01220 {
01221 LodPrimitiveGroups::iterator iGroup= m_PrimitiveGroups.value(m_CurrentLod)->begin();
01222 while (iGroup != m_PrimitiveGroups.value(m_CurrentLod)->constEnd())
01223 {
01224 GLC_PrimitiveGroup* pCurrentGroup= iGroup.value();
01225 GLC_Material* pCurrentMaterial= m_MaterialHash.value(pCurrentGroup->id());
01226
01227
01228 pCurrentMaterial->glExecute(alpha);
01229
01230 if (m_IsSelected) GLC_SelectionMaterial::glExecute();
01231
01232
01233 if (m_IsSelected || materialIsrenderable)
01234 {
01235
01236 if (vboIsUsed)
01237 vboDrawPrimitivesOf(pCurrentGroup);
01238 else
01239 vertexArrayDrawPrimitivesOf(pCurrentGroup);
01240 }
01241 ++iGroup;
01242 }
01243 }
01244 }
01245
01246
01247 void GLC_Mesh::bodySelectionRenderLoop(bool vboIsUsed)
01248 {
01249 Q_ASSERT(GLC_State::isInSelectionMode());
01250
01251 LodPrimitiveGroups::iterator iGroup= m_PrimitiveGroups.value(m_CurrentLod)->begin();
01252 while (iGroup != m_PrimitiveGroups.value(m_CurrentLod)->constEnd())
01253 {
01254 GLC_PrimitiveGroup* pCurrentGroup= iGroup.value();
01255
01256 if (vboIsUsed)
01257 vboDrawPrimitivesOf(pCurrentGroup);
01258 else
01259 vertexArrayDrawPrimitivesOf(pCurrentGroup);
01260
01261 ++iGroup;
01262 }
01263 }
01264
01265
01266 void GLC_Mesh::primitiveSelectionRenderLoop(bool vboIsUsed)
01267 {
01268 Q_ASSERT(GLC_State::isInSelectionMode());
01269
01270 LodPrimitiveGroups::iterator iGroup= m_PrimitiveGroups.value(m_CurrentLod)->begin();
01271
01272 while (iGroup != m_PrimitiveGroups.value(m_CurrentLod)->constEnd())
01273 {
01274 GLC_PrimitiveGroup* pCurrentGroup= iGroup.value();
01275
01276 if (vboIsUsed)
01277 vboDrawInSelectionModePrimitivesOf(pCurrentGroup);
01278 else
01279 vertexArrayDrawInSelectionModePrimitivesOf(pCurrentGroup);
01280
01281 ++iGroup;
01282 }
01283 }
01284
01285
01286 void GLC_Mesh::primitiveRenderLoop(const GLC_RenderProperties& renderProperties, bool vboIsUsed)
01287 {
01288 const bool isTransparent= (renderProperties.renderingFlag() == glc::TransparentRenderFlag);
01289 LodPrimitiveGroups::iterator iGroup= m_PrimitiveGroups.value(m_CurrentLod)->begin();
01290 while (iGroup != m_PrimitiveGroups.value(m_CurrentLod)->constEnd())
01291 {
01292 GLC_PrimitiveGroup* pCurrentGroup= iGroup.value();
01293 GLC_Material* pCurrentMaterial= m_MaterialHash.value(pCurrentGroup->id());
01294
01295
01296 const bool materialIsrenderable = (pCurrentMaterial->isTransparent() == isTransparent);
01297
01298 if (materialIsrenderable)
01299 {
01300 pCurrentMaterial->glExecute();
01301 }
01302 if (vboIsUsed)
01303 vboDrawPrimitivesGroupOf(pCurrentGroup, pCurrentMaterial, materialIsrenderable, isTransparent, renderProperties.hashOfOverwritePrimitiveMaterials());
01304 else
01305 vertexArrayDrawPrimitivesGroupOf(pCurrentGroup, pCurrentMaterial, materialIsrenderable, isTransparent, renderProperties.hashOfOverwritePrimitiveMaterials());
01306
01307 ++iGroup;
01308 }
01309 }
01310
01311
01312 void GLC_Mesh::primitiveSelectedRenderLoop(const GLC_RenderProperties& renderProperties, bool vboIsUsed)
01313 {
01314 const bool isTransparent= (renderProperties.renderingFlag() == glc::TransparentRenderFlag);
01315 LodPrimitiveGroups::iterator iGroup= m_PrimitiveGroups.value(m_CurrentLod)->begin();
01316 while (iGroup != m_PrimitiveGroups.value(m_CurrentLod)->constEnd())
01317 {
01318 GLC_PrimitiveGroup* pCurrentGroup= iGroup.value();
01319 GLC_Material* pCurrentMaterial= m_MaterialHash.value(pCurrentGroup->id());
01320
01321
01322 const bool materialIsrenderable = (pCurrentMaterial->isTransparent() == isTransparent);
01323
01324 if (materialIsrenderable)
01325 {
01326 pCurrentMaterial->glExecute();
01327 }
01328
01329 if (vboIsUsed)
01330 vboDrawSelectedPrimitivesGroupOf(pCurrentGroup, pCurrentMaterial, materialIsrenderable, isTransparent, renderProperties);
01331 else
01332 vertexArrayDrawSelectedPrimitivesGroupOf(pCurrentGroup, pCurrentMaterial, materialIsrenderable, isTransparent, renderProperties);
01333
01334 ++iGroup;
01335 }
01336 }
01337
01338 void GLC_Mesh::copyIndex(int lodIndex, GLC_Mesh* pLodMesh, QHash<GLuint, GLuint>& sourceToTargetIndexMap, QHash<GLuint, GLuint>& tagetToSourceIndexMap, int& maxIndex, int targetLod)
01339 {
01341 QList<GLuint> materialId= m_PrimitiveGroups.value(lodIndex)->keys();
01342
01343 const int materialCount= materialId.size();
01344 for (int i= 0; i < materialCount; ++i)
01345 {
01346 GLuint currentMaterialId= materialId.at(i);
01347 GLC_Material* pCurrentMaterial= GLC_Geometry::material(currentMaterialId);
01348
01349
01350 if (containsTriangles(lodIndex, currentMaterialId))
01351 {
01352 QVector<GLuint> sourceTriangleIndex= getTrianglesIndex(lodIndex, currentMaterialId);
01353 QList<GLuint> targetTriangleIndex;
01354 const int triangleIndexCount= sourceTriangleIndex.size();
01355 for (int i= 0; i < triangleIndexCount; ++i)
01356 {
01357 const GLuint currentIndex= sourceTriangleIndex.at(i);
01358 if (!sourceToTargetIndexMap.contains(currentIndex))
01359 {
01360 sourceToTargetIndexMap.insert(currentIndex, ++maxIndex);
01361 tagetToSourceIndexMap.insert(maxIndex, currentIndex);
01362 targetTriangleIndex.append(maxIndex);
01363 }
01364 else
01365 {
01366 targetTriangleIndex.append(sourceToTargetIndexMap.value(currentIndex));
01367 }
01368 }
01369 pLodMesh->addTriangles(pCurrentMaterial, targetTriangleIndex, targetLod, m_MeshData.getLod(lodIndex)->accuracy());
01370 }
01371
01372
01373 if (containsStrips(lodIndex, currentMaterialId))
01374 {
01375 QList<QVector<GLuint> > sourceStripIndex= getStripsIndex(lodIndex, currentMaterialId);
01376 const int stripCount= sourceStripIndex.size();
01377 for (int stripIndex= 0; stripIndex < stripCount; ++stripIndex)
01378 {
01379
01380 QVector<GLuint> sourceTriangleStripIndex= sourceStripIndex.at(stripIndex);
01381 QList<GLuint> targetTriangleStripIndex;
01382 const int triangleStripIndexCount= sourceTriangleStripIndex.size();
01383 for (int i= 0; i < triangleStripIndexCount; ++i)
01384 {
01385 const GLuint currentIndex= sourceTriangleStripIndex.at(i);
01386 if (!sourceToTargetIndexMap.contains(currentIndex))
01387 {
01388 sourceToTargetIndexMap.insert(currentIndex, ++maxIndex);
01389 tagetToSourceIndexMap.insert(maxIndex, currentIndex);
01390 targetTriangleStripIndex.append(maxIndex);
01391 }
01392 else
01393 {
01394 targetTriangleStripIndex.append(sourceToTargetIndexMap.value(currentIndex));
01395 }
01396 }
01397 pLodMesh->addTrianglesStrip(pCurrentMaterial, targetTriangleStripIndex, targetLod, m_MeshData.getLod(lodIndex)->accuracy());
01398 }
01399 }
01400
01401 if (containsFans(lodIndex, currentMaterialId))
01402 {
01403 QList<QVector<GLuint> > sourceFanIndex= getFansIndex(lodIndex, currentMaterialId);
01404 const int fanCount= sourceFanIndex.size();
01405 for (int fanIndex= 0; fanIndex < fanCount; ++fanIndex)
01406 {
01407
01408 QVector<GLuint> sourceTriangleFanIndex= sourceFanIndex.at(fanIndex);
01409 QList<GLuint> targetTriangleFanIndex;
01410 const int triangleFanIndexCount= sourceTriangleFanIndex.size();
01411 for (int i= 0; i < triangleFanIndexCount; ++i)
01412 {
01413 const GLuint currentIndex= sourceTriangleFanIndex.at(i);
01414 if (!sourceToTargetIndexMap.contains(currentIndex))
01415 {
01416 sourceToTargetIndexMap.insert(currentIndex, ++maxIndex);
01417 tagetToSourceIndexMap.insert(maxIndex, currentIndex);
01418 targetTriangleFanIndex.append(maxIndex);
01419 }
01420 else
01421 {
01422 targetTriangleFanIndex.append(sourceToTargetIndexMap.value(currentIndex));
01423 }
01424 }
01425 pLodMesh->addTrianglesFan(pCurrentMaterial, targetTriangleFanIndex, targetLod, m_MeshData.getLod(lodIndex)->accuracy());
01426 }
01427 }
01428 }
01429 }
01430
01431 void GLC_Mesh::copyBulkData(GLC_Mesh* pLodMesh, const QHash<GLuint, GLuint>& tagetToSourceIndexMap, int maxIndex)
01432 {
01433 GLfloatVector tempFloatVector;
01434 int stride= 3;
01435
01436 Q_ASSERT(!m_MeshData.positionVectorHandle()->isEmpty());
01437 tempFloatVector.resize(stride * (maxIndex + 1));
01438 for (int i= 0; i < maxIndex + 1; ++i)
01439 {
01440 GLfloat* pTarget= &(tempFloatVector.data()[i * stride]);
01441 GLfloat* pSource= &(m_MeshData.positionVectorHandle()->data()[tagetToSourceIndexMap.value(i) * stride]);
01442
01443 memcpy(pTarget, pSource, sizeof(GLfloat) * stride);
01444 }
01445 pLodMesh->addVertice(tempFloatVector);
01446 tempFloatVector.clear();
01447
01448
01449 Q_ASSERT(!m_MeshData.normalVectorHandle()->isEmpty());
01450 tempFloatVector.resize(stride * (maxIndex + 1));
01451 for (int i= 0; i < maxIndex + 1; ++i)
01452 {
01453 GLfloat* pTarget= &(tempFloatVector.data()[i * stride]);
01454 GLfloat* pSource= &(m_MeshData.normalVectorHandle()->data()[tagetToSourceIndexMap.value(i) * stride]);
01455
01456 memcpy(pTarget, pSource, sizeof(GLfloat) * stride);
01457 }
01458 pLodMesh->addNormals(tempFloatVector);
01459 tempFloatVector.clear();
01460
01461 if (!m_MeshData.texelVectorHandle()->isEmpty())
01462 {
01463
01464 stride= 2;
01465 tempFloatVector.resize(stride * (maxIndex + 1));
01466
01467 for (int i= 0; i < maxIndex + 1; ++i)
01468 {
01469 GLfloat* pTarget= &(tempFloatVector.data()[i * stride]);
01470 GLfloat* pSource= &(m_MeshData.texelVectorHandle()->data()[tagetToSourceIndexMap.value(i) * stride]);
01471
01472 memcpy(pTarget, pSource, sizeof(GLfloat) * stride);
01473 }
01474 pLodMesh->addTexels(tempFloatVector);
01475 tempFloatVector.clear();
01476 }
01477 }