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