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:
parent
2842346b5a
commit
1ad924d0ca
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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):
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user