Added support for transforming LOD and Billboard centers to the

OrientationConverter and the flattenTransformVisitor in sgv.
This commit is contained in:
Robert Osfield
2001-10-16 10:04:26 +00:00
parent 659f7ad1ab
commit a9564008f3
3 changed files with 183 additions and 84 deletions

View File

@@ -1,52 +1,14 @@
#include <stdio.h>
#include <osg/GeoSet>
#include <osg/Geode>
#include <osg/Billboard>
#include <osg/LOD>
#include "OrientationConverter.h"
using namespace osg;
class TransformFunctor : public osg::Drawable::AttributeFunctor
{
public:
osg::Matrix _m;
osg::Matrix _im;
TransformFunctor(const osg::Matrix& m):
osg::Drawable::AttributeFunctor(osg::Drawable::COORDS|osg::Drawable::NORMALS)
{
_m = m;
_im.invert(_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 by inverse for normals.
(*itr) = osg::Matrix::transform3x3(_im,(*itr));
(*itr).normalize();
}
return true;
}
return false;
}
};
OrientationConverter::OrientationConverter( void )
{
}
@@ -69,37 +31,28 @@ void OrientationConverter::convert( Node &node )
}
void OrientationConverter::ConvertVisitor::apply( Geode &geode )
void OrientationConverter::ConvertVisitor::apply(osg::Geode& geode)
{
int numdrawables = geode.getNumDrawables();
TransformFunctor tf(_mat);
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();
for( int i = 0; i < numcoords; i++ )
{
Vec3 vv = vertex[i];
vertex[i] = vv * _mat;
}
int numnormals = gset->getNumNormals();
Vec3 *normals = gset->getNormals();
for( int i = 0; i < numnormals; i++ )
{
Vec3 vv = normals[i];
normals[i] = vv * _mat;
}
*/
}
for(int i=0;i<geode.getNumDrawables();++i)
{
geode.getDrawable(i)->applyAttributeOperation(_tf);
}
}
void OrientationConverter::ConvertVisitor::apply(osg::Billboard& billboard)
{
osg::Vec3 axis = osg::Matrix::transform3x3(_tf._im,billboard.getAxis());
billboard.setAxis(axis);
for(int i=0;i<billboard.getNumDrawables();++i)
{
billboard.setPos(i,billboard.getPos(i)*_tf._m);
billboard.getDrawable(i)->applyAttributeOperation(_tf);
}
}
void OrientationConverter::ConvertVisitor::apply(osg::LOD& lod)
{
lod.setCenter(lod.getCenter()*_tf._m);
traverse(lod);
}

View File

@@ -16,23 +16,65 @@ class OrientationConverter {
OrientationConverter( const OrientationConverter& ) {}
OrientationConverter& operator = (const OrientationConverter& ) { return *this; }
class TransformFunctor : public osg::Drawable::AttributeFunctor
{
public:
osg::Matrix _m;
osg::Matrix _im;
TransformFunctor():
osg::Drawable::AttributeFunctor(osg::Drawable::COORDS|osg::Drawable::NORMALS)
{
}
void set(const osg::Matrix& m)
{
_m = m;
_im.invert(_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 by inverse for normals.
(*itr) = osg::Matrix::transform3x3(_im,(*itr));
(*itr).normalize();
}
return true;
}
return false;
}
};
class ConvertVisitor : public osg::NodeVisitor
{
public :
ConvertVisitor() : osg::NodeVisitor(TRAVERSE_ALL_CHILDREN)
{
_mat.makeIdent();
}
ConvertVisitor() : osg::NodeVisitor(TRAVERSE_ALL_CHILDREN) {}
void setMatrix( osg::Matrix mat ) { _mat = mat; }
void setMatrix( const osg::Matrix& mat ) { _tf.set(mat); }
virtual void apply( osg::Node &node ) { traverse( node ); }
virtual void apply( osg::Geode &geode );
virtual void apply( osg::Billboard& billboard );
virtual void apply( osg::LOD& lod );
private :
osg::Matrix _mat;
TransformFunctor _tf;
};
ConvertVisitor _cv;

View File

@@ -3,6 +3,7 @@
#endif
#include <osg/Transform>
#include <osg/Billboard>
#include <osg/Geode>
#include <osg/Group>
#include <osg/Notify>
@@ -88,6 +89,32 @@ class FlattenStaticTransformsVisitor : public osg::NodeVisitor
}
}
virtual void apply(osg::Billboard& billboard)
{
if (!_matrixStack.empty())
{
osg::Matrix& matrix = _matrixStack.back();
TransformFunctor tf(matrix);
osg::Vec3 axis = osg::Matrix::transform3x3(tf._im,billboard.getAxis());
billboard.setAxis(axis);
for(int i=0;i<billboard.getNumDrawables();++i)
{
billboard.setPos(i,billboard.getPos(i)*matrix);
billboard.getDrawable(i)->applyAttributeOperation(tf);
}
}
}
virtual void apply(osg::LOD& lod)
{
if (!_matrixStack.empty())
{
lod.setCenter(lod.getCenter()*_matrixStack.back());
}
traverse(lod);
}
virtual void apply(osg::Transform& transform)
{
@@ -187,6 +214,80 @@ class RemoveRedundentNodesVisitor : public osg::NodeVisitor
};
class CombineLODsVisitor : public osg::NodeVisitor
{
public:
typedef std::set<osg::Group*> GroupList;
GroupList _groupList;
CombineLODsVisitor():osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN) {}
virtual void apply(osg::LOD& lod)
{
for(int i=0;i<lod.getNumParents();++i)
{
_groupList.insert(lod.getParent(i));
}
traverse(lod);
}
void combineLODs()
{
for(GroupList::iterator itr=_groupList.begin();
itr!=_groupList.end();
++itr)
{
osg::Group* group = *itr;
typedef std::multimap<float,osg::LOD*> RangeLODMap;
typedef std::set<osg::LOD*> LODSet;
typedef std::multimap<osg::Vec3,osg::LOD*> CenterLODMap;
typedef std::set<osg::Node*> NodeSet;
CenterLODMap centerLODMap;
NodeSet otherChildren;
for(int i=0;i<group->getNumChildren();++i)
{
osg::Node* child = group->getChild(i);
osg::LOD* lod = dynamic_cast<osg::LOD*>(child);
if (lod)
{
centerLODMap.insert(std::pair<osg::Vec3,osg::LOD*>(lod->getCenter(),lod));
}
else
{
otherChildren.insert(child);
}
}
cout << "Group "<<group<<endl;
for(CenterLODMap::iterator clod_itr=centerLODMap.begin();
clod_itr!=centerLODMap.end();
++clod_itr)
{
cout << " center ("<<clod_itr->first<<")";
osg::LOD* lod = clod_itr->second;
for(int i=0;i<lod->getNumRanges();++i)
{
cout << ", "<< lod->getRange(i);
}
cout <<endl;
}
for(NodeSet::iterator oc_itr=otherChildren.begin();
oc_itr!=otherChildren.end();
++oc_itr)
{
cout << " other child "<<*oc_itr<<endl;
}
}
_groupList.clear();
}
};
@@ -318,7 +419,6 @@ int main( int argc, char **argv )
rootnode->accept(osv);
osv.optimize();
#endif
/*
FlattenStaticTransformsVisitor fstv;
rootnode->accept(fstv);
@@ -327,7 +427,11 @@ int main( int argc, char **argv )
RemoveRedundentNodesVisitor rrnv;
rootnode->accept(rrnv);
rrnv.removeRedundentNodes();
*/
CombineLODsVisitor clv;
rootnode->accept(clv);
clv.combineLODs();
*/
// initialize the viewer.
osgGLUT::Viewer viewer;
viewer.addViewport( rootnode );