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:
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user