diff --git a/include/osgUtil/TriStripVisitor b/include/osgUtil/TriStripVisitor index c3048477f..e336f97ab 100644 --- a/include/osgUtil/TriStripVisitor +++ b/include/osgUtil/TriStripVisitor @@ -36,7 +36,8 @@ class OSGUTIL_EXPORT TriStripVisitor : public BaseOptimizerVisitor BaseOptimizerVisitor( optimizer, Optimizer::TRISTRIP_GEOMETRY), _cacheSize( 16 ), _minStripSize( 2 ), - _generateFourPointPrimitivesQuads ( false) + _generateFourPointPrimitivesQuads ( false ), + _mergeTriangleStrips( false ) {} /** Convert mesh primitives in Geometry into Tri Strips. @@ -45,6 +46,8 @@ class OSGUTIL_EXPORT TriStripVisitor : public BaseOptimizerVisitor */ void stripify(osg::Geometry& drawable); + void mergeTriangleStrips(osg::Geometry::PrimitiveSetList& primitives); + /** Stripify (make into strips of tria or quads) the accumulated list of Geometry drawables.*/ void stripify(); @@ -75,6 +78,8 @@ class OSGUTIL_EXPORT TriStripVisitor : public BaseOptimizerVisitor void setGenerateFourPointPrimitivesQuads(bool flag) { _generateFourPointPrimitivesQuads = flag; } bool getGenerateFourPointPrimitivesQuads() const { return _generateFourPointPrimitivesQuads; } + void setMergeTriangleStrips(bool flag) { _mergeTriangleStrips = flag; } + bool getMergeTriangleStrips() const { return _mergeTriangleStrips; } private: @@ -84,6 +89,7 @@ class OSGUTIL_EXPORT TriStripVisitor : public BaseOptimizerVisitor unsigned int _minStripSize; GeometryList _geometryList; bool _generateFourPointPrimitivesQuads; + bool _mergeTriangleStrips; }; } diff --git a/src/osgUtil/TriStripVisitor.cpp b/src/osgUtil/TriStripVisitor.cpp index 25f0ef13d..dd005de8e 100644 --- a/src/osgUtil/TriStripVisitor.cpp +++ b/src/osgUtil/TriStripVisitor.cpp @@ -504,6 +504,10 @@ void TriStripVisitor::stripify(Geometry& geom) } } + if(_mergeTriangleStrips) { + mergeTriangleStrips(new_primitives); + } + geom.setPrimitiveSetList(new_primitives); #if 0 @@ -527,6 +531,73 @@ void TriStripVisitor::stripify(Geometry& geom) } + +void TriStripVisitor::mergeTriangleStrips(osg::Geometry::PrimitiveSetList& primitives) +{ + int nbtristrip = 0; + int nbtristripVertexes = 0; + + for (unsigned int i = 0; i < primitives.size(); ++ i) + { + osg::PrimitiveSet* ps = primitives[i].get(); + osg::DrawElements* de = ps->getDrawElements(); + if (de && de->getMode() == osg::PrimitiveSet::TRIANGLE_STRIP) + { + ++ nbtristrip; + nbtristripVertexes += de->getNumIndices(); + } + } + + if (nbtristrip > 0) { + osg::notify(osg::NOTICE) << "found " << nbtristrip << " tristrip, " + << "total indices " << nbtristripVertexes + << " should result to " << nbtristripVertexes + nbtristrip * 2 + << " after connection" << std::endl; + + osg::DrawElementsUInt* ndw = new osg::DrawElementsUInt(osg::PrimitiveSet::TRIANGLE_STRIP); + for (unsigned int i = 0; i < primitives.size(); ++ i) + { + osg::PrimitiveSet* ps = primitives[i].get(); + if (ps && ps->getMode() == osg::PrimitiveSet::TRIANGLE_STRIP) + { + osg::DrawElements* de = ps->getDrawElements(); + if (de) + { + // if connection needed insert degenerate triangles + if (ndw->getNumIndices() != 0 && ndw->back() != de->getElement(0)) + { + // duplicate last vertex + ndw->addElement(ndw->back()); + // insert first vertex of next strip + ndw->addElement(de->getElement(0)); + } + + if (ndw->getNumIndices() % 2 != 0 ) { + // add a dummy vertex to reverse the strip + ndw->addElement(de->getElement(0)); + } + + for (unsigned int j = 0; j < de->getNumIndices(); j++) { + ndw->addElement(de->getElement(j)); + } + } + } + } + + for (int i = primitives.size() - 1 ; i >= 0 ; -- i) + { + osg::PrimitiveSet* ps = primitives[i].get(); + // remove null primitive sets and all primitives that have been merged + // (i.e. all TRIANGLE_STRIP DrawElements) + if (!ps || (ps && ps->getMode() == osg::PrimitiveSet::TRIANGLE_STRIP)) + { + primitives.erase(primitives.begin() + i); + } + } + primitives.insert(primitives.begin(), ndw); + } +} + void TriStripVisitor::stripify() { for(GeometryList::iterator itr=_geometryList.begin();