Fixes to the LWO to better handle 3 and 4 vertex polygons.

Added an extra pass into the Optimizer's merging of geometry primitives so
it convertex 3 and 4 vertex polygons into triangles and quads respectively.
This commit is contained in:
Robert Osfield 2002-09-03 20:12:29 +00:00
parent 2842346b5a
commit 1ad924d0ca
5 changed files with 111 additions and 38 deletions

View File

@ -126,6 +126,8 @@ class Primitive : public Object
virtual void accept(Drawable::PrimitiveFunctor&) {}
virtual void offsetIndices(int offset) = 0;
virtual unsigned int getNumIndices() = 0;
protected:
@ -178,6 +180,8 @@ class SG_EXPORT DrawArrays : public Primitive
virtual void offsetIndices(int offset) { _first += offset; }
virtual unsigned int getNumIndices() { return _count; }
protected:
GLint _first;
@ -229,6 +233,8 @@ class SG_EXPORT DrawArrayLengths : public Primitive, public VectorSizei
virtual void offsetIndices(int offset) { _first += offset; }
virtual unsigned int getNumIndices();
protected:
GLint _first;
@ -269,6 +275,8 @@ class SG_EXPORT DrawElementsUByte : public Primitive, public VectorUByte
virtual void accept(Drawable::PrimitiveFunctor& functor);
virtual void offsetIndices(int offset);
virtual unsigned int getNumIndices() { return size(); }
};
@ -307,6 +315,8 @@ class SG_EXPORT DrawElementsUShort : public Primitive, public VectorUShort
virtual void accept(Drawable::PrimitiveFunctor& functor);
virtual void offsetIndices(int offset);
virtual unsigned int getNumIndices() { return size(); }
};
class SG_EXPORT DrawElementsUInt : public Primitive, public VectorUInt
@ -344,6 +354,8 @@ class SG_EXPORT DrawElementsUInt : public Primitive, public VectorUInt
virtual void accept(Drawable::PrimitiveFunctor& functor);
virtual void offsetIndices(int offset);
virtual unsigned int getNumIndices() { return size(); }
};
// backwards compatibility with first incarnation of DrawElements nameing convention.

View File

@ -36,6 +36,17 @@ void DrawArrayLengths::accept(Drawable::PrimitiveFunctor& functor)
}
}
unsigned int DrawArrayLengths::getNumIndices()
{
unsigned int count = 0;
for(VectorSizei::iterator itr=begin();
itr!=end();
++itr)
{
count += *itr;
}
return count;
}
void DrawElementsUByte::draw() const

View File

@ -198,7 +198,30 @@ osgDB::ReaderWriter::ReadResult ReaderWriterLWO::readNode_LWO1(const std::string
{
GeometryCollection& gc = mtgcm[face.material];
gc._geom->addPrimitive(osgNew osg::DrawArrays(osg::Primitive::POLYGON,gc._coordCount,face.index_cnt));
osg::Primitive::Mode mode;
switch(face.index_cnt)
{
case(0):
mode = osg::Primitive::POINTS;
break;
case(1):
mode = osg::Primitive::POINTS;
break;
case(2):
mode = osg::Primitive::LINES;
break;
case(3):
mode = osg::Primitive::TRIANGLES;
break;
case(4):
mode = osg::Primitive::QUADS;
break;
default:
mode = osg::Primitive::POLYGON;
break;
}
gc._geom->addPrimitive(osgNew osg::DrawArrays(mode,gc._coordCount,face.index_cnt));
gc._coordCount += face.index_cnt;
// From the spec_low.lxt :
@ -239,7 +262,7 @@ osgDB::ReaderWriter::ReadResult ReaderWriterLWO::readNode_LWO1(const std::string
if (gc._geom)
{
//tesselator.retesselatePolygons(*gc._geom);
tesselator.retesselatePolygons(*gc._geom);
smoother.smooth(*gc._geom);

View File

@ -64,20 +64,12 @@ void Optimizer::optimize(osg::Node* node, unsigned int options)
if (options & SHARE_DUPLICATE_STATE)
{
// #if (defined(_MSC_VER) && _MSC_VER<1300 && !defined(_STLPORT_VERSION))
// osg::notify(osg::NOTICE)<<"Warning: this application was built with VisualStudio 6.0's native STL,"<<std::endl;
// osg::notify(osg::NOTICE)<<" and due to bugs in VS's STL we are unable to run state optimizer."<<std::endl;
// osg::notify(osg::NOTICE)<<" This may impare performance significantly for larger models."<<std::endl;
// osg::notify(osg::NOTICE)<<" It is recommend that one compiles against STLport or use "<<std::endl;
// osg::notify(osg::NOTICE)<<" Visual Studio .NET compiler which also fix these VS 6.0 STL bugs "<<std::endl;
// #else
StateVisitor osv;
node->accept(osv);
osv.optimize();
MergeGeometryVisitor mgv;
node->accept(mgv);
// #endif
}
@ -1139,49 +1131,80 @@ struct LessGeometryPrimitiveType
bool Optimizer::MergeGeometryVisitor::mergeGeode(osg::Geode& geode)
{
if (geode.getNumDrawables()<2) return false;
if (geode.getNumDrawables()>=2)
{
typedef std::vector<osg::Geometry*> DuplicateList;
typedef std::map<osg::Geometry*,DuplicateList,LessGeometry> GeometryDuplicateMap;
typedef std::vector<osg::Geometry*> DuplicateList;
typedef std::map<osg::Geometry*,DuplicateList,LessGeometry> GeometryDuplicateMap;
GeometryDuplicateMap geometryDuplicateMap;
GeometryDuplicateMap geometryDuplicateMap;
unsigned int i;
for(i=0;i<geode.getNumDrawables();++i)
{
osg::Geometry* geom = dynamic_cast<osg::Geometry*>(geode.getDrawable(i));
if (geom)
{
geom->computeCorrectBindingsAndArraySizes();
geometryDuplicateMap[geom].push_back(geom);
}
}
for(GeometryDuplicateMap::iterator itr=geometryDuplicateMap.begin();
itr!=geometryDuplicateMap.end();
++itr)
{
if (itr->second.size()>1)
{
std::sort(itr->second.begin(),itr->second.end(),LessGeometryPrimitiveType());
osg::Geometry* lhs = itr->second[0];
for(DuplicateList::iterator dupItr=itr->second.begin()+1;
dupItr!=itr->second.end();
++dupItr)
{
osg::Geometry* rhs = *dupItr;
if (mergeGeometry(*lhs,*rhs))
{
geode.removeDrawable(rhs);
static int co = 0;
osg::notify(osg::INFO)<<"merged and removed Geometry "<<++co<<std::endl;
}
}
}
}
}
// convert all polygon primitives which has 3 indices into TRIANGLES, 4 indices into QUADS.
unsigned int i;
for(i=0;i<geode.getNumDrawables();++i)
{
osg::Geometry* geom = dynamic_cast<osg::Geometry*>(geode.getDrawable(i));
if (geom)
{
geom->computeCorrectBindingsAndArraySizes();
geometryDuplicateMap[geom].push_back(geom);
}
}
for(GeometryDuplicateMap::iterator itr=geometryDuplicateMap.begin();
itr!=geometryDuplicateMap.end();
++itr)
{
if (itr->second.size()>1)
{
std::sort(itr->second.begin(),itr->second.end(),LessGeometryPrimitiveType());
osg::Geometry* lhs = itr->second[0];
for(DuplicateList::iterator dupItr=itr->second.begin()+1;
dupItr!=itr->second.end();
++dupItr)
osg::Geometry::PrimitiveList& primitives = geom->getPrimitiveList();
for(osg::Geometry::PrimitiveList::iterator itr=primitives.begin();
itr!=primitives.end();
++itr)
{
osg::Geometry* rhs = *dupItr;
if (mergeGeometry(*lhs,*rhs))
osg::Primitive* prim = itr->get();
if (prim->getMode()==osg::Primitive::POLYGON)
{
geode.removeDrawable(rhs);
static int co = 0;
osg::notify(osg::INFO)<<"merged and removed Geometry "<<++co<<std::endl;
if (prim->getNumIndices()==3)
{
prim->setMode(osg::Primitive::TRIANGLES);
}
else if (prim->getNumIndices()==4)
{
prim->setMode(osg::Primitive::QUADS);
}
}
}
}
}
// now merge any compatible primtives.
for(i=0;i<geode.getNumDrawables();++i)
{
@ -1217,6 +1240,7 @@ bool Optimizer::MergeGeometryVisitor::mergeGeode(osg::Geode& geode)
if (combine)
{
switch(lhs->getType())
{
case(osg::Primitive::DrawArraysPrimitiveType):

View File

@ -38,6 +38,7 @@ void Tesselator::beginContour()
if (_tobj)
{
gluTessBeginContour(_tobj);
// cout<<"begin"<<endl;
}
}
@ -51,6 +52,7 @@ void Tesselator::addVertex(osg::Vec3* vertex)
(*data)._v[1]=(*vertex)[1];
(*data)._v[2]=(*vertex)[2];
gluTessVertex(_tobj,data->_v,vertex);
// cout<<"\t"<<*vertex<<endl;
}
}
@ -59,6 +61,7 @@ void Tesselator::endContour()
if (_tobj)
{
gluTessEndContour(_tobj);
// cout<<"end"<<endl;
}
}