glc_mesh.cpp

Go to the documentation of this file.
00001 /****************************************************************************
00002 
00003  This file is part of the GLC-lib library.
00004  Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net)
00005  Version 2.0.0 Beta 1, packaged on April 2010.
00006 
00007  http://glc-lib.sourceforge.net
00008 
00009  GLC-lib is free software; you can redistribute it and/or modify
00010  it under the terms of the GNU General Public License as published by
00011  the Free Software Foundation; either version 2 of the License, or
00012  (at your option) any later version.
00013 
00014  GLC-lib is distributed in the hope that it will be useful,
00015  but WITHOUT ANY WARRANTY; without even the implied warranty of
00016  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017  GNU General Public License for more details.
00018 
00019  You should have received a copy of the GNU General Public License
00020  along with GLC-lib; if not, write to the Free Software
00021  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
00022 
00023 *****************************************************************************/
00024 
00026 
00027 #include "glc_mesh.h"
00028 
00029 // Class chunk id
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         // Make a copy of m_PrimitiveGroups with new material id
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 // Overload "=" operator
00081 GLC_Mesh& GLC_Mesh::operator=(const GLC_Mesh& mesh)
00082 {
00083         if (this != &mesh)
00084         {
00085                 // Call the operator of the super class
00086                 GLC_Geometry::operator=(mesh);
00087 
00088                 // Clear the mesh
00089                 clearMeshWireAndBoundingBox();
00090 
00091                 // Copy members
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                 // Make a copy of m_PrimitiveGroups with new material id
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 // Destructor
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 // Get Functions
00146 // Return the class Chunk ID
00147 quint32 GLC_Mesh::chunckID()
00148 {
00149         return m_ChunkId;
00150 }
00151 
00152 // Get number of faces
00153 unsigned int GLC_Mesh::faceCount() const
00154 {
00155         return m_NumberOfFaces;
00156 }
00157 
00158 // Get number of vertex
00159 unsigned int GLC_Mesh::VertexCount() const
00160 {
00161         return m_NumberOfVertice;
00162 }
00163 
00164 // return the mesh bounding box
00165 const GLC_BoundingBox& GLC_Mesh::boundingBox()
00166 {
00167         if (NULL == m_pBoundingBox)
00168         {
00169                 //qDebug() << "GLC_Mesh2::boundingBox create boundingBox";
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                 // Combine with the wiredata bounding box
00187                 m_pBoundingBox->combine(m_WireData.boundingBox());
00188         }
00189         return *m_pBoundingBox;
00190 
00191 }
00192 
00193 // Return a copy of the Mesh as GLC_Geometry pointer
00194 GLC_Geometry* GLC_Mesh::clone() const
00195 {
00196         return new GLC_Mesh(*this);
00197 }
00198 
00199 // Return true if the mesh contains triangles
00200 bool GLC_Mesh::containsTriangles(int lod, GLC_uint materialId) const
00201 {
00202         // Check if the lod exist and material exists
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 // Return the specified index
00209 QVector<GLuint> GLC_Mesh::getTrianglesIndex(int lod, GLC_uint materialId) const
00210 {
00211         // Check if the mesh contains triangles
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 // Return the number of triangles
00235 int GLC_Mesh::numberOfTriangles(int lod, GLC_uint materialId) const
00236 {
00237         // Check if the lod exist and material exists
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 // Return true if the mesh contains trips
00244 bool GLC_Mesh::containsStrips(int lod, GLC_uint materialId) const
00245 {
00246         // Check if the lod exist and material exists
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 // Return the strips index
00254 QList<QVector<GLuint> > GLC_Mesh::getStripsIndex(int lod, GLC_uint materialId) const
00255 {
00256         // Check if the mesh contains trips
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         // The result list of vector
00285         QList<QVector<GLuint> > result;
00286         // The copy of the mesh Data LOD index vector
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 // Return the number of strips
00299 int GLC_Mesh::numberOfStrips(int lod, GLC_uint materialId) const
00300 {
00301         // Check if the lod exist and material exists
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 // Return true if the mesh contains fans
00308 bool GLC_Mesh::containsFans(int lod, GLC_uint materialId) const
00309 {
00310         // Check if the lod exist and material exists
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         // Check if the lod exist and material exists
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 // Return the strips index
00327 QList<QVector<GLuint> > GLC_Mesh::getFansIndex(int lod, GLC_uint materialId) const
00328 {
00329         // Check if the mesh contains trips
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         // The result list of vector
00358         QList<QVector<GLuint> > result;
00359         // The copy of the mesh Data LOD index vector
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 // Set Functions
00374 
00375 // Clear the content of the mesh and super class GLC_Geometry
00376 void GLC_Mesh::clear()
00377 {
00378         // Clear the mesh content
00379         clearMeshWireAndBoundingBox();
00380 
00381         // Clear the super class GLC_Geometry
00382         GLC_Geometry::clear();
00383 }
00384 
00385 
00386 // Clear the content off the mesh and makes it empty
00387 void GLC_Mesh::clearMeshWireAndBoundingBox()
00388 {
00389         // Reset primitive local id
00390         m_NextPrimitiveLocalId= 1;
00391 
00392         // Remove all primitive groups
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         // Clear data of the mesh
00415         m_MeshData.clear();
00416         m_CurrentLod= 0;
00417 
00418         GLC_Geometry::clearWireAndBoundingBox();
00419 }
00420 
00421 // Add triangles
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         // Invalid the geometry
00438         m_GeometryIsValid = false;
00439 
00440         return id;
00441 }
00442 
00443 // Add triangles Strip ans return his id
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         // Invalid the geometry
00459         m_GeometryIsValid = false;
00460 
00461         return id;
00462 }
00463 // Add triangles Fan
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         // Invalid the geometry
00479         m_GeometryIsValid = false;
00480 
00481         return id;
00482 }
00483 
00484 // Reverse mesh normal
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         // Invalid the geometry
00498         m_GeometryIsValid = false;
00499 }
00500 
00501 // Copy index list in a vector for Vertex Array Use
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         //qDebug() << "Mesh mem size= " << memmorySize();
00518 }
00519 
00520 
00521 // Set the lod Index
00522 void GLC_Mesh::setCurrentLod(const int value)
00523 {
00524         if (value)
00525         {
00526                 const int numberOfLod= m_MeshData.lodCount() - 1;
00527                 // Clamp value to number of load
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 // Replace the Master material
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 // Replace the material specified by id with another one
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                 // Iterate over Level of detail
00558                 PrimitiveGroupsHash::const_iterator iGroups= m_PrimitiveGroups.constBegin();
00559                 while (m_PrimitiveGroups.constEnd() != iGroups)
00560                 {
00561                         LodPrimitiveGroups* pPrimitiveGroups= iGroups.value();
00562                         // Iterate over material group
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                                         // Erase old group pointer
00570                                         pPrimitiveGroups->erase(iGroup);
00571                                         // Change the group ID
00572                                         pGroup->setId(pMat->id());
00573                                         // Add the group with  new ID
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                 // Remove old material
00589                 removeMaterial(oldId);
00590 
00591                 addMaterial(pMat);
00592         }
00593 
00594 }
00595 
00596 // Load the mesh from binary data stream
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         // The mesh name
00604         QString meshName;
00605         stream >> meshName;
00606         setName(meshName);
00607 
00608         // The wire data
00609         stream >> GLC_Geometry::m_WireData;
00610 
00611         // The mesh next primitive local id
00612         GLC_uint localId;
00613         stream >> localId;
00614         setNextPrimitiveLocalId(localId);
00615 
00616         // Retrieve geom mesh data
00617         stream >> m_MeshData;
00618 
00619         // Retrieve primitiveGroupLodList
00620         QList<int> primitiveGroupLodList;
00621         stream >> primitiveGroupLodList;
00622 
00623         // Retrieve primitiveGroup list
00624         QList<QList<GLC_PrimitiveGroup> > primitiveListOfGroupList;
00625         stream >> primitiveListOfGroupList;
00626 
00627         // Construct mesh primitiveGroupHash
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                         // Test if the mesh contains the material
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         //qDebug() << "Mesh mem size= " << memmorySize();
00656 }
00657 
00658 // Save the mesh to binary data stream
00659 void GLC_Mesh::saveToDataStream(QDataStream& stream) const
00660 {
00661         quint32 chunckId= m_ChunkId;
00662         stream << chunckId;
00663 
00664         // The mesh name
00665         stream << name();
00666 
00667         // The wire data
00668         stream << m_WireData;
00669 
00670         // The mesh next primitive local id
00671         stream << nextPrimitiveLocalId();
00672 
00673         // Mesh data serialisation
00674         stream << m_MeshData;
00675 
00676         // Primitive groups serialisation
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 // OpenGL Functions
00705 
00706 // Virtual interface for OpenGL Geometry set up.
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                 // Create VBO and IBO
00724                 if (!m_GeometryIsValid && !m_MeshData.positionVectorHandle()->isEmpty())
00725                 {
00726                         fillVbosAndIbos();
00727                 }
00728                 else if (!m_GeometryIsValid && !m_MeshData.normalVectorHandle()->isEmpty())
00729                 {
00730                         // Normals has been inversed update normal vbo
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                 // Activate mesh VBOs and IBO of the current LOD
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                 // Choose the accurate render loop
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         // Restore client state
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         // Draw mesh's wire if necessary
00831         if ((renderProperties.renderingFlag() == glc::WireRenderFlag) && !m_WireData.isEmpty() && !GLC_Geometry::typeIsWire())
00832         {
00833                 if (!GLC_State::isInSelectionMode())
00834                 {
00835                         glDisable(GL_LIGHTING);
00836                         // Set polyline colors
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 // Private services Functions
00856 
00857 // Set the current material
00858 GLC_uint GLC_Mesh::setCurrentMaterial(GLC_Material* pMaterial, int lod, double accuracy)
00859 {
00860 
00861         // Test if a primitive group hash exists for the specified lod
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; // Default material id
00873 
00874                 // Test if the material has been already load
00875                 if (m_DefaultMaterialId == 0)
00876                 {
00877                         pMaterial= new GLC_Material();
00878                         // Add the material to the mesh
00879                         addMaterial(pMaterial);
00880                         m_DefaultMaterialId= pMaterial->id();
00881                         returnId= m_DefaultMaterialId;
00882 
00883                 }
00884                 // Test if a primitive group for this material exist
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                 // Test if the material has been already load
00894                 if (!containsMaterial(returnId))
00895                 {
00896                         // Add the material to the mesh
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                         // Add the material to the group
00904                         m_PrimitiveGroups.value(lod)->insert(returnId, new GLC_PrimitiveGroup(returnId));
00905                 }
00906         }
00907 
00908         return returnId;
00909 }
00910 
00911 // Fill VBOs and IBOs
00912 void GLC_Mesh::fillVbosAndIbos()
00913 {
00914         // Create VBO of vertices
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         // Create VBO of normals
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         // Create VBO of texel if needed
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         // Create VBO of color if needed
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                 //Create LOD IBO
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         // Remove client side data
00966         m_MeshData.finishVbo();
00967 
00968 }
00969 // set primitive group offset
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 // Move Indexs from the primitive groups to the mesh Data LOD and Set IBOs offsets
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                         // Add group triangles index to mesh Data LOD triangles index vector
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                         // Add group strip index to mesh Data LOD strip index vector
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                         // Add group fan index to mesh Data LOD fan index vector
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 // Move Indexs from the primitive groups to the mesh Data LOD and Set Index offsets
01028 void GLC_Mesh::finishNonVbo()
01029 {
01030         //qDebug() << "GLC_Mesh::finishNonVbo()";
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                         // Add group triangles index to mesh Data LOD triangles index vector
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                         // Add group strip index to mesh Data LOD strip index vector
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                         // Add group fan index to mesh Data LOD fan index vector
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 // The normal display loop
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                         // Test if the current material is renderable
01079                         bool materialIsrenderable = (pCurrentMaterial->isTransparent() == isTransparent);
01080 
01081                         // Choose the material to render
01082                         if ((materialIsrenderable || m_IsSelected) && !GLC_State::isInSelectionMode())
01083                 {
01084                                 // Execute current material
01085                                 pCurrentMaterial->glExecute();
01086 
01087                                 if (m_IsSelected) GLC_SelectionMaterial::glExecute();
01088                         }
01089 
01090                         // Choose the primitives to render
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 //  The overwrite material render loop
01106 void GLC_Mesh::OverwriteMaterialRenderLoop(const GLC_RenderProperties& renderProperties, bool vboIsUsed)
01107 {
01108         // Get the overwrite material
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                 // Test if the current material is renderable
01120                 bool materialIsrenderable = (pOverwriteMaterial->isTransparent() == (renderProperties.renderingFlag() == glc::TransparentRenderFlag));
01121 
01122                 // Choose the primitives to render
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 // The overwrite transparency render loop
01136 void GLC_Mesh::OverwriteTransparencyRenderLoop(const GLC_RenderProperties& renderProperties, bool vboIsUsed)
01137 {
01138         // Get transparency value
01139         const float alpha= renderProperties.overwriteTransparency();
01140         Q_ASSERT(-1.0f != alpha);
01141 
01142         // Test if the current material is renderable
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                         // Execute current material
01154                         pCurrentMaterial->glExecute(alpha);
01155 
01156                         if (m_IsSelected) GLC_SelectionMaterial::glExecute();
01157 
01158                         // Choose the primitives to render
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 // The body selection render loop
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 // The primitive selection render loop
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 // The primitive rendeder loop
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                 // Test if the current material is renderable
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 // The primitive Selected render loop
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                 // Test if the current material is renderable
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 

SourceForge.net Logo

©2005 Laurent Ribon