From Geoff Michel, added tesselate pass to Optimizer and added handling of per
primitve color to osgUtil::Tesselator.
This commit is contained in:
@@ -27,6 +27,7 @@
|
||||
|
||||
#include <osgUtil/TransformAttributeFunctor>
|
||||
#include <osgUtil/TriStripVisitor>
|
||||
#include <osgUtil/Tesselator>
|
||||
|
||||
#include <typeinfo>
|
||||
#include <algorithm>
|
||||
@@ -91,6 +92,9 @@ void Optimizer::optimize(osg::Node* node)
|
||||
if(str.find("~COPY_SHARED_NODES")!=std::string::npos) options ^= COPY_SHARED_NODES;
|
||||
else if(str.find("COPY_SHARED_NODES")!=std::string::npos) options |= COPY_SHARED_NODES;
|
||||
|
||||
if(str.find("~TESSELATE_GEOMETRY")!=std::string::npos) options ^= TESSELATE_GEOMETRY;
|
||||
else if(str.find("TESSELATE_GEOMETRY")!=std::string::npos) options |= TESSELATE_GEOMETRY;
|
||||
|
||||
if(str.find("~TRISTRIP_GEOMETRY")!=std::string::npos) options ^= TRISTRIP_GEOMETRY;
|
||||
else if(str.find("TRISTRIP_GEOMETRY")!=std::string::npos) options |= TRISTRIP_GEOMETRY;
|
||||
|
||||
@@ -106,6 +110,14 @@ void Optimizer::optimize(osg::Node* node)
|
||||
void Optimizer::optimize(osg::Node* node, unsigned int options)
|
||||
{
|
||||
|
||||
if (options & TESSELATE_GEOMETRY)
|
||||
{
|
||||
osg::notify(osg::INFO)<<"Optimizer::optimize() doing TESSELATE_GEOMETRY"<<std::endl;
|
||||
|
||||
TesselateVisitor tsv;
|
||||
node->accept(tsv);
|
||||
}
|
||||
|
||||
if (options & COMBINE_ADJACENT_LODS)
|
||||
{
|
||||
osg::notify(osg::INFO)<<"Optimizer::optimize() doing COMBINE_ADJACENT_LODS"<<std::endl;
|
||||
@@ -207,6 +219,23 @@ void Optimizer::optimize(osg::Node* node, unsigned int options)
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Tesselate geometry - eg break complex POLYGONS into triangles, strips, fans..
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
void Optimizer::TesselateVisitor::apply(osg::Geode& geode)
|
||||
{
|
||||
for(unsigned int i=0;i<geode.getNumDrawables();++i)
|
||||
{
|
||||
osg::Geometry* geom = dynamic_cast<osg::Geometry*>(geode.getDrawable(i));
|
||||
if (geom) {
|
||||
osgUtil::Tesselator tesselator;
|
||||
tesselator.retesselatePolygons(*geom);
|
||||
}
|
||||
}
|
||||
traverse(geode);
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Optimize State Visitor
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -320,7 +320,7 @@ void Tesselator::retesselatePolygons(osg::Geometry& geom)
|
||||
}
|
||||
|
||||
|
||||
// we don't properly handle per primitive and per primitive bindings yet
|
||||
// we don't properly handle per primitive and per primitive_set bindings yet
|
||||
// will need to address this soon. Robert Oct 2002.
|
||||
{
|
||||
osg::Vec3Array* normals = NULL; // GWM Sep 2002 - add normals for extra facets
|
||||
@@ -330,6 +330,28 @@ void Tesselator::retesselatePolygons(osg::Geometry& geom)
|
||||
{
|
||||
normals = geom.getNormalArray(); // GWM Sep 2002
|
||||
}
|
||||
// GWM Dec 2003 - nneded to add colours for extra facets
|
||||
osg::Vec4Array* cols4 = NULL; // GWM Dec 2003 colours are vec4
|
||||
osg::Vec3Array* cols3 = NULL; // GWM Dec 2003 colours are vec3
|
||||
if (geom.getColorBinding()==osg::Geometry::BIND_PER_PRIMITIVE/* ||
|
||||
geom.getColorBinding()==osg::Geometry::BIND_PER_PRIMITIVE_SET*/)
|
||||
{
|
||||
Array* colours = geom.getColorArray(); // GWM Dec 2003 - need to duplicate face colours
|
||||
switch (colours->getType()) {
|
||||
case osg::Array::Vec4ArrayType:
|
||||
cols4=dynamic_cast<osg::Vec4Array *> (colours);
|
||||
break;
|
||||
case osg::Array::Vec3ArrayType:
|
||||
cols3=dynamic_cast<osg::Vec3Array *> (colours);
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
// GWM Dec 2003 - these holders need to go outside the loop to
|
||||
// retain the flat shaded colour &/or normal for each tesselated polygon
|
||||
osg::Vec3 norm(0.0f,0.0f,0.0f);
|
||||
osg::Vec4 primCol4(0.0f,0.0f,0.0f,1.0f);
|
||||
osg::Vec3 primCol3(0.0f,0.0f,0.0f);
|
||||
for(PrimList::iterator primItr=_primList.begin();
|
||||
primItr!=_primList.end();
|
||||
++primItr)
|
||||
@@ -346,18 +368,33 @@ void Tesselator::retesselatePolygons(osg::Geometry& geom)
|
||||
}
|
||||
|
||||
if (primItr==_primList.begin())
|
||||
{
|
||||
// first new primitive so overwrite the previous polygon.
|
||||
{ // first new primitive so overwrite the previous polygon & collect primitive normal & colour.
|
||||
geom.getPrimitiveSetList()[primNo] = elements;
|
||||
if (normals) {
|
||||
norm=(*normals)[iprim]; // GWM Sep 2002 the flat shaded normal
|
||||
}
|
||||
if (cols4) {
|
||||
primCol4=(*cols4)[iprim]; // GWM Dec 2003 the flat shaded rgba colour
|
||||
}
|
||||
if (cols3) {
|
||||
primCol3=(*cols3)[iprim]; // GWM Dec 2003 flat shaded rgb colour
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// subsequence primitives add to the back of the primitive list.
|
||||
// subsequent primitives add to the back of the primitive list, and may have same colour as hte original facet.
|
||||
geom.addPrimitiveSet(elements);
|
||||
if (normals) normals->push_back(norm); // GWM Sep 2002 add flat shaded normal for new facet
|
||||
if (cols4) cols4->push_back(primCol4); // GWM Dec 2003 add flat shaded colour for new facet
|
||||
if (cols3) cols3->push_back(primCol3); // GWM Dec 2003 add flat shaded colour for new facet
|
||||
if (prim->_mode==GL_TRIANGLES) { // also need one per triangle?
|
||||
int ntris=elements->getNumIndices()/3;
|
||||
for (int ii=1; ii<ntris; ii++) {
|
||||
if (normals) normals->push_back(norm); // GWM Sep 2002 add flat shaded normal for new facet
|
||||
if (cols4) cols4->push_back(primCol4);
|
||||
}
|
||||
}
|
||||
// osg::notify(osg::WARN)<<"Add: "<< iprim << std::endl;
|
||||
}
|
||||
iprim++; // GWM Sep 2002 count which normal we should use
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user