Changed the naming and calling convention of the new Drawable::AttributeFunctor

and have updated GeoSet to use mutable values for the _numverts etc, allowing
osg::GeoSet::computeNumVerts() to be a const operation. osg::GeoSet::getNumVerts
is now a const once more, so avoiding compilation problems.  Also chaned the new
osgconv orientation code to use a Drawable::AttributeFunctor so it can work on
other Drawables other than just GeoSets.
This commit is contained in:
Robert Osfield
2001-10-13 11:16:10 +00:00
parent a57ab6d121
commit 1e4a0cadf5
7 changed files with 265 additions and 38 deletions

View File

@@ -4,6 +4,46 @@
using namespace osg;
class TransformFunctor : public osg::Drawable::AttributeFunctor
{
public:
osg::Matrix _m;
TransformFunctor(const osg::Matrix& m):
AttributeFunctor(osg::Drawable::COORDS|osg::Drawable::NORMALS),
_m(m) {}
virtual ~TransformFunctor() {}
virtual bool apply(osg::Drawable::AttributeBitMask abm,osg::Vec3* begin,osg::Vec3* end)
{
if (abm == osg::Drawable::COORDS)
{
for (osg::Vec3* itr=begin;itr<end;++itr)
{
(*itr) = (*itr)*_m;
}
return true;
}
else if (abm == osg::Drawable::NORMALS)
{
for (osg::Vec3* itr=begin;itr<end;++itr)
{
// note post mult rather than pre mult of value.
(*itr) = osg::Matrix::transform3x3(_m,(*itr));
(*itr).normalize();
}
return true;
}
return false;
}
};
OrientationConverter::OrientationConverter( void )
{
}
@@ -29,15 +69,19 @@ void OrientationConverter::convert( Node &node )
void OrientationConverter::ConvertVisitor::apply( Geode &geode )
{
int numdrawables = geode.getNumDrawables();
TransformFunctor tf(_mat);
// We assume all Drawables are GeoSets ?!!?
for( int i = 0; i < numdrawables; i++ )
{
geode.getDrawable(i)->applyAttributeOperation(tf);
/*
GeoSet *gset = dynamic_cast<GeoSet *>(geode.getDrawable(i));
if( gset == NULL )
continue;
int numcoords = gset->getNumCoords();
Vec3 *vertex = gset->getCoords();
@@ -54,5 +98,6 @@ void OrientationConverter::ConvertVisitor::apply( Geode &geode )
Vec3 vv = normals[i];
normals[i] = vv * _mat;
}
*/
}
}

View File

@@ -14,7 +14,7 @@ TARGET_BIN_FILES = sgv
#note, standard library list.
LIBS = -losgGLUT -losgUtil -losgDB -losg $(GLUTLIB) -lGLU -lGL -lm -lXmu -lX11 -lXi
C++FLAGS += -I../../../include
C++FLAGS += -I../../../include -g
LDFLAGS += -L../../../lib
include ../../../Make/makerules

View File

@@ -2,6 +2,8 @@
#include <mcheck.h>
#endif
#include <osg/Transform>
#include <osg/Geode>
#include <osg/Group>
#include <osg/Notify>
@@ -18,6 +20,173 @@
#include <osgUtil/OptimizeStateVisitor>
class TransformFunctor : public osg::Drawable::AttributeFunctor
{
public:
osg::Matrix _m;
TransformFunctor(const osg::Matrix& m):
AttributeFunctor(osg::Drawable::COORDS|osg::Drawable::NORMALS),
_m(m) {}
virtual ~TransformFunctor() {}
virtual bool apply(osg::Drawable::AttributeBitMask abm,osg::Vec3* begin,osg::Vec3* end)
{
if (abm == osg::Drawable::COORDS)
{
for (osg::Vec3* itr=begin;itr<end;++itr)
{
(*itr) = (*itr)*_m;
}
return true;
}
else if (abm == osg::Drawable::NORMALS)
{
for (osg::Vec3* itr=begin;itr<end;++itr)
{
// note post mult rather than pre mult of value.
(*itr) = osg::Matrix::transform3x3(_m,(*itr));
(*itr).normalize();
}
return true;
}
return false;
}
};
class FlattenStaticTransformsVisitor : public osg::NodeVisitor
{
public:
typedef std::vector<osg::Matrix> MatrixStack;
MatrixStack _matrixStack;
typedef std::set<osg::Transform*> TransformList;
TransformList _transformList;
FlattenStaticTransformsVisitor():NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN) {}
virtual void apply(osg::Geode& geode)
{
if (!_matrixStack.empty())
{
TransformFunctor tf(_matrixStack.back());
for(int i=0;i<geode.getNumDrawables();++i)
{
geode.getDrawable(i)->applyAttributeOperation(tf);
}
}
}
virtual void apply(osg::Transform& transform)
{
if (_matrixStack.empty())
{
_matrixStack.push_back(transform.getMatrix());
}
else
{
_matrixStack.push_back(transform.getMatrix()*_matrixStack.back());
}
traverse(transform);
_transformList.insert(&transform);
// reset the matrix to identity.
transform.getMatrix().makeIdent();
_matrixStack.pop_back();
}
void removeTransforms()
{
for(TransformList::iterator itr=_transformList.begin();
itr!=_transformList.end();
++itr)
{
osg::ref_ptr<osg::Transform> transform = *itr;
osg::ref_ptr<osg::Group> group = new osg::Group;
int i;
for(i=0;i<transform->getNumChildren();++i)
{
for(int j=0;j<transform->getNumParents();++j)
{
group->addChild(transform->getChild(i));
}
}
for(i=transform->getNumParents()-1;i>=0;--i)
{
transform->getParent(i)->replaceChild(transform.get(),group.get());
}
}
_transformList.clear();
}
};
class RemoveRedundentNodesVisitor : public osg::NodeVisitor
{
public:
typedef std::set<osg::Node*> NodeList;
NodeList _redundentNodeList;
RemoveRedundentNodesVisitor():NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN) {}
virtual void apply(osg::Group& group)
{
if (typeid(group)==typeid(osg::Group))
{
if (group.getNumParents()>0 && group.getNumChildren()<=1)
{
_redundentNodeList.insert(&group);
}
}
traverse(group);
}
void removeRedundentNodes()
{
for(NodeList::iterator itr=_redundentNodeList.begin();
itr!=_redundentNodeList.end();
++itr)
{
osg::ref_ptr<osg::Group> group = dynamic_cast<osg::Group*>(*itr);
if (group.valid())
{
for(int j=group->getNumParents()-1;j>=0;--j)
{
for(int i=0;i<group->getNumChildren();++i)
{
group->getParent(j)->addChild(group->getChild(i));
}
group->getParent(j)->removeChild(group.get());
}
}
}
_redundentNodeList.clear();
}
};
/*
* Function to read several files (typically one) as specified on the command
* line, and return them in an osg::Node
@@ -141,8 +310,15 @@ int main( int argc, char **argv )
osv.optimize();
#endif
/*
FlattenStaticTransformsVisitor fstv;
rootnode->accept(fstv);
fstv.removeTransforms();
RemoveRedundentNodesVisitor rrnv;
rootnode->accept(rrnv);
rrnv.removeRedundentNodes();
*/
// initialize the viewer.
osgGLUT::Viewer viewer;
viewer.addViewport( rootnode );

View File

@@ -129,7 +129,7 @@ void GeoSet::drawImmediateMode(State&)
draw_alternate_path();
}
void GeoSet::computeNumVerts()
void GeoSet::computeNumVerts() const
{
int i;
int numverts=0;
@@ -294,9 +294,7 @@ const bool GeoSet::computeBound() const
if( _numcoords == 0 )
{
// a dirty hack to cast away constness of this..
GeoSet* gset = const_cast<GeoSet*>(this);
gset->computeNumVerts();
computeNumVerts();
}
if( _numcoords == 0 )
@@ -645,16 +643,17 @@ void GeoSet::setInterleavedArray( const InterleaveArrayType format, float *ia, I
set_fast_path();
}
Drawable::AttributeBitMask GeoSet::suppportsAttributeUpdate() const
Drawable::AttributeBitMask GeoSet::suppportsAttributeOperation() const
{
// we do support coords,normals,texcoords and colors so return true.
return COORDS | NORMALS | COLORS | TEXTURE_COORDS;
}
Drawable::AttributeBitMask GeoSet::applyAttributeUpdate(AttributeBitMask amb,AttributeUpdateFunctor& auf)
Drawable::AttributeBitMask GeoSet::applyAttributeOperation(AttributeFunctor& auf)
{
computeNumVerts();
if (_numcoords == 0) computeNumVerts();
AttributeBitMask amb = auf.getAttributeBitMask();
AttributeBitMask ramb = 0;
if ((amb & COORDS) && _coords && _numcoords)
@@ -671,12 +670,12 @@ Drawable::AttributeBitMask GeoSet::applyAttributeUpdate(AttributeBitMask amb,Att
if (auf.apply(NORMALS,_normals,_normals+_numnormals)) ramb = NORMALS;
}
if ((amb & COLORS) && _colors)
if ((amb & COLORS) && _colors && _numcolors)
{
if (auf.apply(COLORS,_colors,_colors+_numcolors)) ramb = COLORS;
}
if ((amb & TEXTURE_COORDS) && _tcoords)
if ((amb & TEXTURE_COORDS) && _tcoords && _numtcoords)
{
if (auf.apply(TEXTURE_COORDS,_tcoords,_tcoords+_numtcoords)) ramb = TEXTURE_COORDS;
}