From da47f8a156e082b68771caa5d51fecf7ff5d2d12 Mon Sep 17 00:00:00 2001 From: Marc Helbling Date: Fri, 1 Jul 2016 18:12:32 +0200 Subject: [PATCH] Adds an indexMesh option to disable mesh reindexation This mainly breaks gles/osgjs when stripifying a MorphGeometry. It also usually doesn't make sense to reindex an already indexed mesh. --- include/osgUtil/TriStripVisitor | 13 +- src/osgUtil/TriStripVisitor.cpp | 284 +++++++++++++++++--------------- 2 files changed, 164 insertions(+), 133 deletions(-) diff --git a/include/osgUtil/TriStripVisitor b/include/osgUtil/TriStripVisitor index 744f7de20..b73c60bdf 100644 --- a/include/osgUtil/TriStripVisitor +++ b/include/osgUtil/TriStripVisitor @@ -37,7 +37,8 @@ class OSGUTIL_EXPORT TriStripVisitor : public BaseOptimizerVisitor _cacheSize( 16 ), _minStripSize( 2 ), _generateFourPointPrimitivesQuads ( false ), - _mergeTriangleStrips( false ) + _mergeTriangleStrips( false ), + _indexMesh( true ) {} /** Convert mesh primitives in Geometry into Tri Strips. @@ -74,6 +75,15 @@ class OSGUTIL_EXPORT TriStripVisitor : public BaseOptimizerVisitor return _minStripSize; } + inline void setIndexMesh( bool allow ) + { + _indexMesh = allow; + } + + inline bool getIndexMesh() const + { + return _indexMesh; + } void setGenerateFourPointPrimitivesQuads(bool flag) { _generateFourPointPrimitivesQuads = flag; } bool getGenerateFourPointPrimitivesQuads() const { return _generateFourPointPrimitivesQuads; } @@ -90,6 +100,7 @@ class OSGUTIL_EXPORT TriStripVisitor : public BaseOptimizerVisitor GeometryList _geometryList; bool _generateFourPointPrimitivesQuads; bool _mergeTriangleStrips; + bool _indexMesh; }; } diff --git a/src/osgUtil/TriStripVisitor.cpp b/src/osgUtil/TriStripVisitor.cpp index c16056efe..24ae1ea00 100644 --- a/src/osgUtil/TriStripVisitor.cpp +++ b/src/osgUtil/TriStripVisitor.cpp @@ -187,6 +187,146 @@ protected: RemapArray& operator = (const RemapArray&) { return *this; } }; + +void indexGeometry(osg::Geometry& geom, IndexList& mapping) { + // check for the existence of surface primitives + unsigned int numSurfacePrimitives = 0; + unsigned int numNonSurfacePrimitives = 0; + Geometry::PrimitiveSetList& primitives = geom.getPrimitiveSetList(); + for(Geometry::PrimitiveSetList::iterator itr=primitives.begin(); + itr!=primitives.end(); + ++itr) + { + switch((*itr)->getMode()) + { + case(PrimitiveSet::TRIANGLES): + case(PrimitiveSet::TRIANGLE_STRIP): + case(PrimitiveSet::TRIANGLE_FAN): + case(PrimitiveSet::QUADS): + case(PrimitiveSet::QUAD_STRIP): + case(PrimitiveSet::POLYGON): + ++numSurfacePrimitives; + break; + default: + ++numNonSurfacePrimitives; + break; + } + } + + // nothitng to tri strip leave. + if (!numSurfacePrimitives) return; + + // compute duplicate vertices + + unsigned int numVertices = geom.getVertexArray()->getNumElements(); + IndexList vindices(numVertices); + unsigned int i,j; + for(i=0;igetNumIndices(); + } + } + float ratio_of_indices_to_unique_vertices = ((float)nbPrimitiveIndices/(float)numUnique); + + if(!finalMapping.empty() && + ratio_of_indices_to_unique_vertices >= minimum_ratio_of_indices_to_unique_vertices) { + + OSG_INFO << "TriStripVisitor::stripify(Geometry&): Number of indices" << nbPrimitiveIndices + << " numUnique" << numUnique << std::endl; + OSG_INFO << "TriStripVisitor::stripify(Geometry&): ratio indices/numUnique" + << ratio_of_indices_to_unique_vertices << std::endl; + + // remap any shared vertex attributes + RemapArray ra(copyMapping); + arrayComparitor.accept(ra); + finalMapping.swap(mapping); + } +} + + struct MyTriangleOperator { @@ -227,129 +367,20 @@ void TriStripVisitor::stripify(Geometry& geom) // no point tri stripping if we don't have enough vertices. if (!geom.getVertexArray() || geom.getVertexArray()->getNumElements()<3) return; - // check for the existence of surface primitives - unsigned int numSurfacePrimitives = 0; - unsigned int numNonSurfacePrimitives = 0; - Geometry::PrimitiveSetList& primitives = geom.getPrimitiveSetList(); - for(Geometry::PrimitiveSetList::iterator itr=primitives.begin(); - itr!=primitives.end(); - ++itr) - { - switch((*itr)->getMode()) - { - case(PrimitiveSet::TRIANGLES): - case(PrimitiveSet::TRIANGLE_STRIP): - case(PrimitiveSet::TRIANGLE_FAN): - case(PrimitiveSet::QUADS): - case(PrimitiveSet::QUAD_STRIP): - case(PrimitiveSet::POLYGON): - ++numSurfacePrimitives; - break; - default: - ++numNonSurfacePrimitives; - break; - + IndexList mapping; + if(_indexMesh) { + indexGeometry(geom, mapping); + if(mapping.empty()) { + return; } } - // nothitng to tri strip leave. - if (!numSurfacePrimitives) return; - - // compute duplicate vertices - - unsigned int numVertices = geom.getVertexArray()->getNumElements(); - IndexList vindices(numVertices); - unsigned int i,j; - for(i=0;i=minimum_ratio_of_indices_to_unique_vertices) + if (!taf._in_indices.empty()) { OSG_INFO<<"TriStripVisitor::stripify(Geometry&): doing tri strip"<< std::endl; @@ -393,13 +417,9 @@ void TriStripVisitor::stripify(Geometry& geom) if (*itr>in_numVertices) in_numVertices=*itr; } // the largest indice is in_numVertices, but indices start at 0 - // so increment to give to the corrent number of verticies. + // so increment to give to the corrent number of vertices. ++in_numVertices; - // remap any shared vertex attributes - RemapArray ra(copyMapping); - arrayComparitor.accept(ra); - triangle_stripper::tri_stripper stripifier(taf._in_indices); stripifier.SetCacheSize(_cacheSize); stripifier.SetMinStripSize(_minStripSize); @@ -450,7 +470,7 @@ void TriStripVisitor::stripify(Geometry& geom) pitr = qitr->second; unsigned int min_pos = 0; - for(i=1;i<4;++i) + for(unsigned int i = 1 ; i < 4 ; ++ i) { if (pitr->Indices[min_pos]>pitr->Indices[i]) min_pos = i;