Added support for transforming LOD and Billboard centers to the
OrientationConverter and the flattenTransformVisitor in sgv.
This commit is contained in:
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 );
|
||||
|
||||
Reference in New Issue
Block a user