diff --git a/include/osgUtil/Simplifier b/include/osgUtil/Simplifier index dde718d10..6494a1dde 100644 --- a/include/osgUtil/Simplifier +++ b/include/osgUtil/Simplifier @@ -81,9 +81,13 @@ class OSGUTIL_EXPORT Simplifier : public osg::NodeVisitor } } - /** simply the geometry to defined ratio of original size.*/ + /** simply the geometry.*/ void simplify(osg::Geometry& geometry); + + typedef std::vector IndexList; /// a list of point indices + /** simply the geometry, whilst protecting key points from being modified.*/ + void simplify(osg::Geometry& geometry, const IndexList& protectedPoints); protected: diff --git a/src/osgTerrain/DataSet.cpp b/src/osgTerrain/DataSet.cpp index bdbd10d86..a6dbc16ee 100644 --- a/src/osgTerrain/DataSet.cpp +++ b/src/osgTerrain/DataSet.cpp @@ -1924,7 +1924,7 @@ osg::Node* DataSet::DestinationTile::createPolygonal() return 0; } - bool createSkirt = false; + bool createSkirt = true; // compute sizes. unsigned int numColumns = grid->getNumColumns(); @@ -2108,6 +2108,8 @@ osg::Node* DataSet::DestinationTile::createPolygonal() if (n.valid() && n->size()!=numVertices) n->resize(numVertices); #endif + osgUtil::Simplifier::IndexList pointsToProtectDuringSimplification; + if (numVerticesInSkirt>0) { osg::DrawElementsUShort& skirtDrawElements = *(new osg::DrawElementsUShort(GL_QUAD_STRIP,2*numVerticesInSkirt+2)); @@ -2118,8 +2120,15 @@ osg::Node* DataSet::DestinationTile::createPolygonal() r=0; for(c=0;c0;--c) { + // assign indices to primitive set skirtDrawElements[ei++] = (r)*numColumns+c; skirtDrawElements[ei++] = vi; + + // mark these points as protected to prevent them from being removed during simplification + pointsToProtectDuringSimplification.push_back((r)*numColumns+c); + pointsToProtectDuringSimplification.push_back(vi); + + // add in the new point on the bottom of the skirt v[vi] = v[(r)*numColumns+c]+skirtVector; if (n.valid()) (*n)[vi] = (*n)[(r)*numColumns+c]; t[vi++] = t[(r)*numColumns+c]; @@ -2148,8 +2171,15 @@ osg::Node* DataSet::DestinationTile::createPolygonal() c=0; for(r=numRows-1;r>0;--r) { + // assign indices to primitive set skirtDrawElements[ei++] = (r)*numColumns+c; skirtDrawElements[ei++] = vi; + + // mark these points as protected to prevent them from being removed during simplification + pointsToProtectDuringSimplification.push_back((r)*numColumns+c); + pointsToProtectDuringSimplification.push_back(vi); + + // add in the new point on the bottom of the skirt v[vi] = v[(r)*numColumns+c]+skirtVector; if (n.valid()) (*n)[vi] = (*n)[(r)*numColumns+c]; t[vi++] = t[(r)*numColumns+c]; @@ -2179,18 +2209,12 @@ osg::Node* DataSet::DestinationTile::createPolygonal() geometry->setColorBinding(osg::Geometry::BIND_OVERALL); } -#if 1 osgUtil::Simplifier simplifier(0.5f,geometry->getBound().radius()/2000.0f); -// osgUtil::Simplifier simplifier(1.0f,1.0f); - simplifier.simplify(*geometry); // this will replace the normal vector with a new one -#endif + simplifier.simplify(*geometry, pointsToProtectDuringSimplification); // this will replace the normal vector with a new one -#if 1 osgUtil::TriStripVisitor tsv; tsv.stripify(*geometry); -#endif - osg::Geode* geode = new osg::Geode; geode->addDrawable(geometry); diff --git a/src/osgUtil/Simplifier.cpp b/src/osgUtil/Simplifier.cpp index 5375ad532..c3339a45e 100644 --- a/src/osgUtil/Simplifier.cpp +++ b/src/osgUtil/Simplifier.cpp @@ -56,7 +56,7 @@ public: ~EdgeCollapse(); - void setGeometry(osg::Geometry* geometry); + void setGeometry(osg::Geometry* geometry, const Simplifier::IndexList& protectedPoints); osg::Geometry* getGeometry() { return _geometry; } unsigned int getNumOfTriangles() { return _triangleSet.size(); } @@ -199,8 +199,10 @@ public: struct Point : public osg::Referenced { - Point():_index(0) {} + Point(): _protected(false), _index(0) {} + bool _protected; + unsigned int _index; osg::Vec3 _vertex; @@ -223,6 +225,8 @@ public: bool isBoundaryPoint() const { + if (_protected) return true; + for(TriangleSet::const_iterator itr=_triangles.begin(); itr!=_triangles.end(); ++itr) @@ -1180,7 +1184,7 @@ class CopyVertexArrayToPointsVisitor : public osg::ArrayVisitor EdgeCollapse::PointList& _pointList; }; -void EdgeCollapse::setGeometry(osg::Geometry* geometry) +void EdgeCollapse::setGeometry(osg::Geometry* geometry, const Simplifier::IndexList& protectedPoints) { _geometry = geometry; @@ -1227,10 +1231,20 @@ void EdgeCollapse::setGeometry(osg::Geometry* geometry) geometry->getVertexAttribArray(vi)->accept(copyArrayToPoints); } + // now set the protected points up. + for(Simplifier::IndexList::const_iterator pitr=protectedPoints.begin(); + pitr!=protectedPoints.end(); + ++pitr) + { + _originalPointList[*pitr]->_protected = true; + } + + CollectTriangleIndexFunctor collectTriangles; collectTriangles.setEdgeCollapse(this); _geometry->accept(collectTriangles); + } @@ -1466,11 +1480,20 @@ Simplifier::Simplifier(float sampleRatio, float maximumError): } void Simplifier::simplify(osg::Geometry& geometry) +{ + // pass an empty list of indices to simply(Geometry,IndexList) + // so that this one method handle both cases of non protected indices + // and specified indices. + IndexList emptyList; + simplify(geometry,emptyList); +} + +void Simplifier::simplify(osg::Geometry& geometry, const IndexList& protectedPoints) { osg::notify(osg::WARN)<<"++++++++++++++simplifier************"<