• Main Page
  • Related Pages
  • Namespaces
  • Classes
  • Files
  • File List
  • File Members

PolyVoxCore/include/PolyVoxCore/SurfaceMesh.inl

Go to the documentation of this file.
00001 /*******************************************************************************
00002 Copyright (c) 2005-2009 David Williams
00003 
00004 This software is provided 'as-is', without any express or implied
00005 warranty. In no event will the authors be held liable for any damages
00006 arising from the use of this software.
00007 
00008 Permission is granted to anyone to use this software for any purpose,
00009 including commercial applications, and to alter it and redistribute it
00010 freely, subject to the following restrictions:
00011 
00012     1. The origin of this software must not be misrepresented; you must not
00013     claim that you wrote the original software. If you use this software
00014     in a product, an acknowledgment in the product documentation would be
00015     appreciated but is not required.
00016 
00017     2. Altered source versions must be plainly marked as such, and must not be
00018     misrepresented as being the original software.
00019 
00020     3. This notice may not be removed or altered from any source
00021     distribution.   
00022 *******************************************************************************/
00023 
00024 namespace PolyVox
00025 {
00026     template <typename VertexType>
00027     SurfaceMesh<VertexType>::SurfaceMesh()
00028     {
00029         m_iTimeStamp = -1;
00030     }
00031 
00032     template <typename VertexType>
00033     SurfaceMesh<VertexType>::~SurfaceMesh()   
00034     {
00035     }
00036 
00037     template <typename VertexType>
00038     const std::vector<uint32_t>& SurfaceMesh<VertexType>::getIndices(void) const
00039     {
00040         return m_vecTriangleIndices;
00041     }
00042 
00043     template <typename VertexType>
00044     uint32_t SurfaceMesh<VertexType>::getNoOfIndices(void) const
00045     {
00046         return m_vecTriangleIndices.size();
00047     }   
00048 
00049     template <typename VertexType>
00050     uint32_t SurfaceMesh<VertexType>::getNoOfNonUniformTrianges(void) const
00051     {
00052         uint32_t result = 0;
00053         for(uint32_t i = 0; i < m_vecTriangleIndices.size() - 2; i += 3)
00054         {
00055             if((m_vecVertices[m_vecTriangleIndices[i]].getMaterial() == m_vecVertices[m_vecTriangleIndices[i+1]].getMaterial())
00056             && (m_vecVertices[m_vecTriangleIndices[i]].getMaterial() == m_vecVertices[m_vecTriangleIndices[i+2]].getMaterial()))
00057             {
00058             }
00059             else
00060             {
00061                 result++;
00062             }
00063         }
00064         return result;
00065     }
00066 
00067     template <typename VertexType>
00068     uint32_t SurfaceMesh<VertexType>::getNoOfUniformTrianges(void) const
00069     {
00070         uint32_t result = 0;
00071         for(uint32_t i = 0; i < m_vecTriangleIndices.size() - 2; i += 3)
00072         {
00073             if((m_vecVertices[m_vecTriangleIndices[i]].getMaterial() == m_vecVertices[m_vecTriangleIndices[i+1]].getMaterial())
00074             && (m_vecVertices[m_vecTriangleIndices[i]].getMaterial() == m_vecVertices[m_vecTriangleIndices[i+2]].getMaterial()))
00075             {
00076                 result++;
00077             }
00078         }
00079         return result;
00080     }
00081 
00082     template <typename VertexType>
00083     uint32_t SurfaceMesh<VertexType>::getNoOfVertices(void) const
00084     {
00085         return m_vecVertices.size();
00086     }
00087 
00088     template <typename VertexType>
00089     std::vector<VertexType>& SurfaceMesh<VertexType>::getRawVertexData(void)
00090     {
00091         return m_vecVertices;
00092     }
00093 
00094     template <typename VertexType>
00095     const std::vector<VertexType>& SurfaceMesh<VertexType>::getVertices(void) const
00096     {
00097         return m_vecVertices;
00098     }       
00099 
00100     template <typename VertexType>
00101     void SurfaceMesh<VertexType>::addTriangle(uint32_t index0, uint32_t index1, uint32_t index2)
00102     {
00103         m_vecTriangleIndices.push_back(index0);
00104         m_vecTriangleIndices.push_back(index1);
00105         m_vecTriangleIndices.push_back(index2);
00106 
00107         if((m_vecVertices[index0].material == m_vecVertices[index1].material) && (m_vecVertices[index0].material == m_vecVertices[index2].material))
00108         {
00109             m_mapUsedMaterials.insert(m_vecVertices[index0].material);          
00110         }
00111     }
00112 
00113     template <typename VertexType>
00114     void SurfaceMesh<VertexType>::addTriangleCubic(uint32_t index0, uint32_t index1, uint32_t index2)
00115     {
00116         m_vecTriangleIndices.push_back(index0);
00117         m_vecTriangleIndices.push_back(index1);
00118         m_vecTriangleIndices.push_back(index2);
00119     }
00120 
00121     template <typename VertexType>
00122     uint32_t SurfaceMesh<VertexType>::addVertex(const VertexType& vertex)
00123     {
00124         m_vecVertices.push_back(vertex);
00125         return m_vecVertices.size() - 1;
00126     }
00127 
00128     template <typename VertexType>
00129     void SurfaceMesh<VertexType>::clear(void)
00130     {
00131         m_vecVertices.clear();
00132         m_vecTriangleIndices.clear();
00133         m_vecLodRecords.clear();
00134         m_mapUsedMaterials.clear();
00135     }
00136 
00137     template <typename VertexType>
00138     bool SurfaceMesh<VertexType>::isEmpty(void) const
00139     {
00140         return (getNoOfVertices() == 0) || (getNoOfIndices() == 0);
00141     }
00142 
00151     /*template <typename VertexType>
00152     void SurfaceMesh<VertexType>::sumNearbyNormals(bool bNormaliseResult)
00153     {
00154         if(m_vecVertices.size() == 0) //FIXME - I don't think we should need this test, but I have seen crashes otherwise...
00155         {
00156             return;
00157         }
00158 
00159         std::vector<Vector3DFloat> summedNormals(m_vecVertices.size());
00160 
00161         //Initialise all normals to zero. Should be ok as the vector should store all elements contiguously.
00162         memset(&summedNormals[0], 0, summedNormals.size() * sizeof(Vector3DFloat));
00163 
00164         for(vector<uint32_t>::iterator iterIndex = m_vecTriangleIndices.begin(); iterIndex != m_vecTriangleIndices.end();)
00165         {
00166             PositionMaterialNormal& v0 = m_vecVertices[*iterIndex];
00167             Vector3DFloat& v0New = summedNormals[*iterIndex];
00168             iterIndex++;
00169             PositionMaterialNormal& v1 = m_vecVertices[*iterIndex];
00170             Vector3DFloat& v1New = summedNormals[*iterIndex];
00171             iterIndex++;
00172             PositionMaterialNormal& v2 = m_vecVertices[*iterIndex];
00173             Vector3DFloat& v2New = summedNormals[*iterIndex];
00174             iterIndex++;
00175 
00176             Vector3DFloat sumOfNormals = v0.getNormal() + v1.getNormal() + v2.getNormal();
00177 
00178             v0New += sumOfNormals;
00179             v1New += sumOfNormals;
00180             v2New += sumOfNormals;
00181         }
00182 
00183         for(uint32_t uIndex = 0; uIndex < summedNormals.size(); uIndex++)
00184         {
00185             if(bNormaliseResult)
00186             {
00187                 summedNormals[uIndex].normalise();
00188             }
00189             m_vecVertices[uIndex].setNormal(summedNormals[uIndex]);
00190         }
00191     }*/
00192 
00193     /*template <typename VertexType>
00194     void SurfaceMesh<VertexType>::generateAveragedFaceNormals(bool bNormalise, bool bIncludeEdgeVertices)
00195     {
00196         Vector3DFloat offset = static_cast<Vector3DFloat>(m_Region.getLowerCorner());
00197 
00198         //Initially zero the normals
00199         for(vector<PositionMaterialNormal>::iterator iterVertex = m_vecVertices.begin(); iterVertex != m_vecVertices.end(); iterVertex++)
00200         {
00201             if(m_Region.containsPoint(iterVertex->getPosition() + offset, 0.001))
00202             {
00203                 iterVertex->setNormal(Vector3DFloat(0.0f,0.0f,0.0f));
00204             }
00205         }
00206 
00207         for(vector<uint32_t>::iterator iterIndex = m_vecTriangleIndices.begin(); iterIndex != m_vecTriangleIndices.end();)
00208         {
00209             PositionMaterialNormal& v0 = m_vecVertices[*iterIndex];
00210             iterIndex++;
00211             PositionMaterialNormal& v1 = m_vecVertices[*iterIndex];
00212             iterIndex++;
00213             PositionMaterialNormal& v2 = m_vecVertices[*iterIndex];
00214             iterIndex++;
00215 
00216             Vector3DFloat triangleNormal = (v1.getPosition()-v0.getPosition()).cross(v2.getPosition()-v0.getPosition());
00217 
00218             if(m_Region.containsPoint(v0.getPosition() + offset, 0.001))
00219             {
00220                 v0.setNormal(v0.getNormal() + triangleNormal);
00221             }
00222             if(m_Region.containsPoint(v1.getPosition() + offset, 0.001))
00223             {
00224                 v1.setNormal(v1.getNormal() + triangleNormal);
00225             }
00226             if(m_Region.containsPoint(v2.getPosition() + offset, 0.001))
00227             {
00228                 v2.setNormal(v2.getNormal() + triangleNormal);
00229             }
00230         }
00231 
00232         if(bNormalise)
00233         {
00234             for(vector<PositionMaterialNormal>::iterator iterVertex = m_vecVertices.begin(); iterVertex != m_vecVertices.end(); iterVertex++)
00235             {
00236                 Vector3DFloat normal = iterVertex->getNormal();
00237                 normal.normalise();
00238                 iterVertex->setNormal(normal);
00239             }
00240         }
00241     }*/
00242 
00243     /*template <typename VertexType>
00244     polyvox_shared_ptr< SurfaceMesh<VertexType> > SurfaceMesh<VertexType>::extractSubset(std::set<uint8_t> setMaterials)
00245     {
00246         polyvox_shared_ptr< SurfaceMesh<VertexType> > result(new SurfaceMesh<VertexType>);
00247 
00248         if(m_vecVertices.size() == 0) //FIXME - I don't think we should need this test, but I have seen crashes otherwise...
00249         {
00250             return result;
00251         }
00252 
00253         assert(m_vecLodRecords.size() == 1);
00254         if(m_vecLodRecords.size() != 1)
00255         {
00256             //If we have done progressive LOD then it's too late to split into subsets.
00257             return result;
00258         }
00259 
00260         std::vector<int32_t> indexMap(m_vecVertices.size());
00261         std::fill(indexMap.begin(), indexMap.end(), -1);
00262 
00263         for(uint32_t triCt = 0; triCt < m_vecTriangleIndices.size(); triCt += 3)
00264         {
00265 
00266             PositionMaterialNormal& v0 = m_vecVertices[m_vecTriangleIndices[triCt]];
00267             PositionMaterialNormal& v1 = m_vecVertices[m_vecTriangleIndices[triCt + 1]];
00268             PositionMaterialNormal& v2 = m_vecVertices[m_vecTriangleIndices[triCt + 2]];
00269 
00270             if(
00271                 (setMaterials.find(v0.getMaterial()) != setMaterials.end()) || 
00272                 (setMaterials.find(v1.getMaterial()) != setMaterials.end()) || 
00273                 (setMaterials.find(v2.getMaterial()) != setMaterials.end()))
00274             {
00275                 uint32_t i0;
00276                 if(indexMap[m_vecTriangleIndices[triCt]] == -1)
00277                 {
00278                     indexMap[m_vecTriangleIndices[triCt]] = result->addVertex(v0);
00279                 }
00280                 i0 = indexMap[m_vecTriangleIndices[triCt]];
00281 
00282                 uint32_t i1;
00283                 if(indexMap[m_vecTriangleIndices[triCt+1]] == -1)
00284                 {
00285                     indexMap[m_vecTriangleIndices[triCt+1]] = result->addVertex(v1);
00286                 }
00287                 i1 = indexMap[m_vecTriangleIndices[triCt+1]];
00288 
00289                 uint32_t i2;
00290                 if(indexMap[m_vecTriangleIndices[triCt+2]] == -1)
00291                 {
00292                     indexMap[m_vecTriangleIndices[triCt+2]] = result->addVertex(v2);
00293                 }
00294                 i2 = indexMap[m_vecTriangleIndices[triCt+2]];
00295 
00296                 result->addTriangle(i0,i1,i2);
00297             }
00298         }
00299 
00300         result->m_vecLodRecords.clear();
00301         LodRecord lodRecord;
00302         lodRecord.beginIndex = 0;
00303         lodRecord.endIndex = result->getNoOfIndices();
00304         result->m_vecLodRecords.push_back(lodRecord);
00305 
00306         return result;
00307     }*/
00308 
00309     template <typename VertexType>
00310     int SurfaceMesh<VertexType>::noOfDegenerateTris(void)
00311     {
00312         int count = 0;
00313         for(uint32_t triCt = 0; triCt < m_vecTriangleIndices.size();)
00314         {
00315             int v0 = m_vecTriangleIndices[triCt];
00316             triCt++;
00317             int v1 = m_vecTriangleIndices[triCt];
00318             triCt++;
00319             int v2 = m_vecTriangleIndices[triCt];
00320             triCt++;
00321 
00322             if((v0 == v1) || (v1 == v2) || (v2 == v0))
00323             {
00324                 count++;
00325             }
00326         }
00327         return count;
00328     }
00329 
00330     template <typename VertexType>
00331     void SurfaceMesh<VertexType>::removeDegenerateTris(void)
00332     {
00333         int noOfNonDegenerate = 0;
00334         int targetCt = 0;
00335         for(uint32_t triCt = 0; triCt < m_vecTriangleIndices.size();)
00336         {
00337             int v0 = m_vecTriangleIndices[triCt];
00338             triCt++;
00339             int v1 = m_vecTriangleIndices[triCt];
00340             triCt++;
00341             int v2 = m_vecTriangleIndices[triCt];
00342             triCt++;
00343 
00344             if((v0 != v1) && (v1 != v2) & (v2 != v0))
00345             {
00346                 m_vecTriangleIndices[targetCt] = v0;
00347                 targetCt++;
00348                 m_vecTriangleIndices[targetCt] = v1;
00349                 targetCt++;
00350                 m_vecTriangleIndices[targetCt] = v2;
00351                 targetCt++;
00352 
00353                 noOfNonDegenerate++;
00354             }
00355         }
00356 
00357         m_vecTriangleIndices.resize(noOfNonDegenerate * 3);
00358     }
00359 
00360     template <typename VertexType>
00361     void SurfaceMesh<VertexType>::removeUnusedVertices(void)
00362     {
00363         std::vector<bool> isVertexUsed(m_vecVertices.size());
00364         fill(isVertexUsed.begin(), isVertexUsed.end(), false);
00365 
00366         for(uint32_t triCt = 0; triCt < m_vecTriangleIndices.size(); triCt++)
00367         {
00368             int v = m_vecTriangleIndices[triCt];
00369             isVertexUsed[v] = true;
00370         }
00371 
00372         int noOfUsedVertices = 0;
00373         std::vector<uint32_t> newPos(m_vecVertices.size());
00374         for(uint32_t vertCt = 0; vertCt < m_vecVertices.size(); vertCt++)
00375         {
00376             if(isVertexUsed[vertCt])
00377             {
00378                 m_vecVertices[noOfUsedVertices] = m_vecVertices[vertCt];
00379                 newPos[vertCt] = noOfUsedVertices;
00380                 noOfUsedVertices++;
00381             }
00382         }
00383 
00384         m_vecVertices.resize(noOfUsedVertices);
00385 
00386         for(uint32_t triCt = 0; triCt < m_vecTriangleIndices.size(); triCt++)
00387         {
00388             m_vecTriangleIndices[triCt] = newPos[m_vecTriangleIndices[triCt]];
00389         }
00390     }
00391 
00392     //Currently a free function - think where this needs to go.
00393     template <typename VertexType>
00394     polyvox_shared_ptr< SurfaceMesh<VertexType> > extractSubset(SurfaceMesh<VertexType>& inputMesh, std::set<uint8_t> setMaterials)
00395     {
00396         polyvox_shared_ptr< SurfaceMesh<VertexType> > result(new SurfaceMesh<VertexType>);
00397         
00398         result->m_Region = inputMesh.m_Region;
00399 
00400         if(inputMesh.m_vecVertices.size() == 0) //FIXME - I don't think we should need this test, but I have seen crashes otherwise...
00401         {
00402             return result;
00403         }
00404 
00405         assert(inputMesh.m_vecLodRecords.size() == 1);
00406         if(inputMesh.m_vecLodRecords.size() != 1)
00407         {
00408             //If we have done progressive LOD then it's too late to split into subsets.
00409             return result;
00410         }
00411 
00412         std::vector<int32_t> indexMap(inputMesh.m_vecVertices.size());
00413         std::fill(indexMap.begin(), indexMap.end(), -1);
00414 
00415         for(uint32_t triCt = 0; triCt < inputMesh.m_vecTriangleIndices.size(); triCt += 3)
00416         {
00417 
00418             VertexType& v0 = inputMesh.m_vecVertices[inputMesh.m_vecTriangleIndices[triCt]];
00419             VertexType& v1 = inputMesh.m_vecVertices[inputMesh.m_vecTriangleIndices[triCt + 1]];
00420             VertexType& v2 = inputMesh.m_vecVertices[inputMesh.m_vecTriangleIndices[triCt + 2]];
00421 
00422             if(
00423                 (setMaterials.find(v0.getMaterial()) != setMaterials.end()) || 
00424                 (setMaterials.find(v1.getMaterial()) != setMaterials.end()) || 
00425                 (setMaterials.find(v2.getMaterial()) != setMaterials.end()))
00426             {
00427                 uint32_t i0;
00428                 if(indexMap[inputMesh.m_vecTriangleIndices[triCt]] == -1)
00429                 {
00430                     indexMap[inputMesh.m_vecTriangleIndices[triCt]] = result->addVertex(v0);
00431                 }
00432                 i0 = indexMap[inputMesh.m_vecTriangleIndices[triCt]];
00433 
00434                 uint32_t i1;
00435                 if(indexMap[inputMesh.m_vecTriangleIndices[triCt+1]] == -1)
00436                 {
00437                     indexMap[inputMesh.m_vecTriangleIndices[triCt+1]] = result->addVertex(v1);
00438                 }
00439                 i1 = indexMap[inputMesh.m_vecTriangleIndices[triCt+1]];
00440 
00441                 uint32_t i2;
00442                 if(indexMap[inputMesh.m_vecTriangleIndices[triCt+2]] == -1)
00443                 {
00444                     indexMap[inputMesh.m_vecTriangleIndices[triCt+2]] = result->addVertex(v2);
00445                 }
00446                 i2 = indexMap[inputMesh.m_vecTriangleIndices[triCt+2]];
00447 
00448                 result->addTriangle(i0,i1,i2);
00449             }
00450         }
00451 
00452         result->m_vecLodRecords.clear();
00453         LodRecord lodRecord;
00454         lodRecord.beginIndex = 0;
00455         lodRecord.endIndex = result->getNoOfIndices();
00456         result->m_vecLodRecords.push_back(lodRecord);
00457 
00458         return result;
00459     }
00460 
00461     template <typename VertexType>
00462     void SurfaceMesh<VertexType>::scaleVertices(float amount)
00463     {
00464         for(uint32_t ct = 0; ct < m_vecVertices.size(); ct++)
00465         {
00466             //TODO: Should rethink accessors here to provide faster access
00467             Vector3DFloat position = m_vecVertices[ct].getPosition();
00468             position *= amount;
00469             m_vecVertices[ct].setPosition(position);
00470         }
00471     }
00472 
00473     template <typename VertexType>
00474     void SurfaceMesh<VertexType>::translateVertices(const Vector3DFloat& amount)
00475     {
00476         for(uint32_t ct = 0; ct < m_vecVertices.size(); ct++)
00477         {
00478             //TODO: Should rethink accessors here to provide faster access
00479             Vector3DFloat position = m_vecVertices[ct].getPosition();
00480             position += amount;
00481             m_vecVertices[ct].setPosition(position);
00482         }
00483     }
00484 }

Generated on Sat Nov 19 2011 00:27:31 for PolyVox by  doxygen 1.7.1