Updated the osgconv support for orientation conversion so that it used

inserted a static transform to do the work of rotating the scene, then
applied a standard osgUtil::Optimizer::FlattenStaticTransformsVisitor
traversal to flatten the transfrom down on to the geometry nodes.
This commit is contained in:
Robert Osfield
2002-02-13 22:53:58 +00:00
parent 0c1264f547
commit 5d1289144c
4 changed files with 42 additions and 148 deletions

View File

@@ -1,4 +1,4 @@
#!smake
#!gmake
include $(OSGHOME)/Make/makedefs
C++FILES = \
@@ -14,10 +14,10 @@ TARGET_BIN_FILES = osgconv
#LIBS = ${PFLIBS} -losgDB -losg -lGLU -lGL -lm -lXmu -lX11 -lXi
#note, standard library list.
LIBS = -losgDB -losg $(GL_LIBS) $(X_LIBS)
LIBS = -losgUtil -losgDB -losg $(GL_LIBS) $(X_LIBS)
#under Darwin we have to use the framework stuff to get GLUT OpenGL etc.
MACOSXLIBS = -losgGLUT -losgUtil -losgDB -losg -lm -ldl -lstdc++ -lobjc
MACOSXLIBS = -losgUtil -losgDB -losg -lm -ldl -lstdc++ -lobjc
C++FLAGS += -I$(OSGHOME)/include
LDFLAGS += -L$(OSGHOME)/lib

View File

@@ -1,9 +1,7 @@
#include <stdio.h>
#include <osg/GeoSet>
#include <osg/Geode>
#include <osg/Billboard>
#include <osg/LOD>
#include <osg/Transform>
#include <osgUtil/Optimizer>
#include "OrientationConverter.h"
@@ -34,7 +32,7 @@ void OrientationConverter::setScale( const Vec3 &scale )
}
void OrientationConverter::convert( Node &node )
Node* OrientationConverter::convert( Node *node )
{
// Order of operations here is :
// 1. Translate to world origin (0,0,0)
@@ -44,38 +42,23 @@ void OrientationConverter::convert( Node &node )
// - translate to absolute translation in world coordinates
// else
// - translate back to model's original origin.
BoundingSphere bs = node.getBound();
Matrix C = Matrix::translate( Vec3(0,0,0) - bs.center() );
BoundingSphere bs = node->getBound();
Matrix C = Matrix::translate( -bs.center() );
if( _trans_set == false )
T = Matrix::translate( bs.center() );
_cv.setMatrix( C * R * S * T );
node.accept(_cv);
}
void OrientationConverter::ConvertVisitor::apply(osg::Geode& geode)
{
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);
osg::Group* root = new osg::Group;
osg::Transform* transform = new osg::Transform;
transform->setType(osg::Transform::STATIC);
transform->setMatrix( C * R * S * T );
root->addChild(transform);
transform->addChild(node);
osgUtil::Optimizer::FlattenStaticTransformsVisitor fstv;
node->accept(fstv);
fstv.removeTransforms();
return root->getChild(0);
}

View File

@@ -13,74 +13,15 @@ class OrientationConverter {
const osg::Vec3 &to );
void setTranslation( const osg::Vec3 &trans);
void setScale( const osg::Vec3 &trans);
void convert( osg::Node &node );
/** return the root of the updated subgraph as the subgraph
* the node passed in my flatten during optimization.*/
osg::Node* convert( osg::Node* node );
private :
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) {}
void setMatrix( const osg::Matrix& mat ) { _tf.set(mat); }
virtual void apply( osg::Geode &geode );
virtual void apply( osg::Billboard& billboard );
virtual void apply( osg::LOD& lod );
private :
TransformFunctor _tf;
};
ConvertVisitor _cv;
osg::Matrix R, T, S;
bool _trans_set;

View File

@@ -198,58 +198,28 @@ int main( int argc, char **argv )
if( parse_args( argc, argv, fileNames, oc ) == false )
return -1;
if (fileNames.size()==1)
std::string fileNameOut("converted.osg");
if (fileNames.size()>1)
{
osg::Node* root = osgDB::readNodeFile(fileNames.front());
fileNameOut = fileNames.back();
fileNames.pop_back();
}
if( do_convert )
oc.convert( *root );
osg::Node* root = osgDB::readNodeFiles(fileNames);
if( do_convert )
root = oc.convert( root );
if (root)
{
osgDB::writeNodeFile(*root,"converted.osg");
osg::notify(osg::NOTICE)<<"Data written to 'converted.osg'."<< std::endl;
}
else
{
osg::notify(osg::NOTICE)<<"Error no data loaded."<< std::endl;
return 1;
}
if (root)
{
osgDB::writeNodeFile(*root,fileNameOut);
osg::notify(osg::NOTICE)<<"Data written to '"<<fileNameOut<<"'."<< std::endl;
}
else
{
std::string fileNameOut = fileNames.back();
fileNames.pop_back();
osg::Group* group = new osg::Group();
for(FileNameList::iterator itr=fileNames.begin();
itr<fileNames.end();
++itr)
{
osg::Node* child = osgDB::readNodeFile(*itr);
if (child)
{
group->addChild(child);
}
}
if( do_convert )
oc.convert(*group);
if (group->getNumChildren()==0)
{
osg::notify(osg::NOTICE)<<"Error no data loaded."<< std::endl;
return 1;
}
else if (group->getNumChildren()==1)
{
osgDB::writeNodeFile(*(group->getChild(0)),fileNameOut);
}
else
{
osgDB::writeNodeFile(*group,fileNameOut);
}
osg::notify(osg::NOTICE)<<"Error no data loaded."<< std::endl;
return 1;
}
return 0;