#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "OrientationConverter.h" #include "GeoSet.h" typedef std::vector FileNameList; //////////////////////////////////////////////////////////////////////////// // Convert GeoSet To Geometry Visitor. //////////////////////////////////////////////////////////////////////////// /** ConvertGeoSetsToGeometryVisitor all the old GeoSet Drawables to the new Geometry Drawables.*/ class ConvertGeoSetsToGeometryVisitor : public osg::NodeVisitor { public: ConvertGeoSetsToGeometryVisitor():osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN) {} virtual void apply(osg::Geode& geode) { for(unsigned int i=0;i(geode.getDrawable(i)); if (geoset) { osg::Geometry* geom = geoset->convertToGeometry(); if (geom) { osg::notify(osg::NOTICE)<<"Successfully converted GeoSet to Geometry"<setWindowRectangle(0,0,1,1); rs->useBorder(false); rs->useConfigEventThread(false); rs->realize(); std::cout<<"Realized window"< rs; }; class CompressTexturesVisitor : public osg::NodeVisitor { public: CompressTexturesVisitor():osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN) {} virtual void apply(osg::Node& node) { if (node.getStateSet()) apply(*node.getStateSet()); traverse(node); } virtual void apply(osg::Geode& node) { if (node.getStateSet()) apply(*node.getStateSet()); for(unsigned int i=0;igetStateSet()) apply(*drawable->getStateSet()); } traverse(node); } virtual void apply(osg::StateSet& stateset) { // search for the existance of any texture object attributes for(unsigned int i=0;i(stateset.getTextureAttribute(i,osg::StateAttribute::TEXTURE)); if (texture) { _textureSet.insert(texture); } } } void compress() { GraphicsContext context; osg::ref_ptr state = new osg::State; for(TextureSet::iterator itr=_textureSet.begin(); itr!=_textureSet.end(); ++itr) { osg::Texture2D* texture = const_cast(itr->get()); osg::Image* image = texture->getImage(); if (image && (image->getPixelFormat()==GL_RGB || image->getPixelFormat()==GL_RGBA) && (image->s()>=32 && image->t()>=32)) { texture->setInternalFormatMode(osg::Texture::USE_S3TC_DXT3_COMPRESSION); // get OpenGL driver to create texture from image. texture->apply(*state); image->readImageFromCurrentTexture(0,true); texture->setInternalFormatMode(osg::Texture::USE_IMAGE_DATA_FORMAT); } } } typedef std::set< osg::ref_ptr > TextureSet; TextureSet _textureSet; }; static void usage( const char *prog, const char *msg ) { if (msg) { osg::notify(osg::NOTICE)<< std::endl; osg::notify(osg::NOTICE) << msg << std::endl; } osg::notify(osg::NOTICE)<< std::endl; osg::notify(osg::NOTICE)<<"usage:"<< std::endl; osg::notify(osg::NOTICE)<<" " << prog << " [options] infile1 [infile2 ...] outfile"<< std::endl; osg::notify(osg::NOTICE)<< std::endl; osg::notify(osg::NOTICE)<<"options:"<< std::endl; osg::notify(osg::NOTICE)<<" -O option - ReaderWriter option"<< std::endl; osg::notify(osg::NOTICE)<<" --compressed - Compress textures."<< std::endl; osg::notify(osg::NOTICE)<<" -l libraryName - load plugin of name libraryName"<< std::endl; osg::notify(osg::NOTICE)<<" i.e. -l osgdb_pfb"<< std::endl; osg::notify(osg::NOTICE)<<" Useful for loading reader/writers which can load"<< std::endl; osg::notify(osg::NOTICE)<<" other file formats in addition to its extension."<< std::endl; osg::notify(osg::NOTICE)<<" -e extensionName - load reader/wrter plugin for file extension"<< std::endl; osg::notify(osg::NOTICE)<<" i.e. -e pfb"<< std::endl; osg::notify(osg::NOTICE)<<" Useful short hand for specifying full library name as"<< std::endl; osg::notify(osg::NOTICE)<<" done with -l above, as it automatically expands to the"<< std::endl; osg::notify(osg::NOTICE)<<" full library name appropriate for each platform."<< std::endl; osg::notify(osg::NOTICE)<<" -o orientation - Convert geometry from input files to output files."<< std::endl; osg::notify(osg::NOTICE)<< " Format of orientation argument must be the following:\n" "\n" " X1,Y1,Z1-X2,Y2,Z2\n" " or\n" " degrees-A0,A1,A2\n" "\n" " where X1,Y1,Z1 represent the UP vector in the input\n" " files and X2,Y2,Z2 represent the UP vector of the\n" " output file, or degrees is the rotation angle in degrees\n" " around axis (A0,A1,A2). For example, to convert a model\n" " built in a Y-Up coordinate system to a model with a Z-up\n" " coordinate system, the argument may look like\n" "\n" " 0,1,0-0,0,1" "\n" " or\n" " -90-1,0,0\n" "\n" << std::endl; osg::notify(osg::NOTICE)<<" -t translation - Convert spatial position of output files. Format of\n" " translation argument must be the following :\n" "\n" " X,Y,Z\n" "\n" " where X, Y, and Z represent the coordinates of the\n" " absolute position in world space\n" << std::endl; osg::notify(osg::NOTICE)<<" -s scale - Scale size of model. Scale argument must be the \n" " following :\n" "\n" " SX,SY,SZ\n" "\n" " where SX, SY, and SZ represent the scale factors\n" " Caution: Scaling will be done in destination orientation\n" << std::endl; } int main( int argc, char **argv ) { // use an ArgumentParser object to manage the program arguments. osg::ArgumentParser arguments(&argc,argv); // set up the usage document, in case we need to print out how to use this program. arguments.getApplicationUsage()->setApplicationName(arguments.getApplicationName()); arguments.getApplicationUsage()->setDescription(arguments.getApplicationName()+" is the standard OpenSceneGraph example which loads and visualises 3d models."); arguments.getApplicationUsage()->setCommandLineUsage(arguments.getApplicationName()+" [options] filename ..."); // if user request help write it out to cout. if (arguments.read("-h") || arguments.read("--help")) { usage( arguments.getApplicationName().c_str(), 0 ); //arguments.getApplicationUsage()->write(std::cout); return 1; } if (arguments.argc()<=1) { arguments.getApplicationUsage()->write(std::cout,osg::ApplicationUsage::COMMAND_LINE_OPTION); return 1; } FileNameList fileNames; OrientationConverter oc; bool do_convert = false; bool compressTextures = false; std::string str; while (arguments.read("-O",str)) { osgDB::ReaderWriter::Options* options = new osgDB::ReaderWriter::Options; options->setOptionString(str); osgDB::Registry::instance()->setOptions(options); } std::string ext; while (arguments.read("-e",ext)) { std::string libName = osgDB::Registry::instance()->createLibraryNameForExtension(ext); osgDB::Registry::instance()->loadLibrary(libName); } std::string libName; while (arguments.read("-l",libName)) { osgDB::Registry::instance()->loadLibrary(libName); } #if 0 if( nexti < argc ) { osg::Vec3 scale(0,0,0); if( sscanf( argv[nexti++], "%f,%f,%f", &scale[0], &scale[1], &scale[2] ) != 3 ) { usage( argv[0], "Scale argument format incorrect." ); return false; } oc.setScale( scale ); do_convert = true; } else { usage( argv[0], "Scale conversion option requires an argument." ); return false; } break; #endif while (arguments.read("-o",str)) { osg::Vec3 from, to; if( sscanf( str.c_str(), "%f,%f,%f-%f,%f,%f", &from[0], &from[1], &from[2], &to[0], &to[1], &to[2] ) != 6 ) { float degrees; osg::Vec3 axis; // Try deg-axis format if( sscanf( str.c_str(), "%f-%f,%f,%f", °rees, &axis[0], &axis[1], &axis[2] ) != 4 ) { usage( argv[0], "Orientation argument format incorrect." ); return 1; } else { oc.setRotation( degrees, axis ); do_convert = true; } } else { oc.setRotation( from, to ); do_convert = true; } } while (arguments.read("-s",str)) { osg::Vec3 scale(0,0,0); if( sscanf( str.c_str(), "%f,%f,%f", &scale[0], &scale[1], &scale[2] ) != 3 ) { usage( argv[0], "Scale argument format incorrect." ); return 1; } oc.setScale( scale ); do_convert = true; } while (arguments.read("-t",str)) { osg::Vec3 trans(0,0,0); if( sscanf( str.c_str(), "%f,%f,%f", &trans[0], &trans[1], &trans[2] ) != 3 ) { usage( argv[0], "Translation argument format incorrect." ); return 1; } oc.setTranslation( trans ); do_convert = true; } while (arguments.read("--compressed")) { compressTextures = true; } // any option left unread are converted into errors to write out later. arguments.reportRemainingOptionsAsUnrecognized(); // report any errors if they have occured when parsing the program aguments. if (arguments.errors()) { arguments.writeErrorMessages(std::cout); return 1; } for(int pos=1;pos1) { fileNameOut = fileNames.back(); fileNames.pop_back(); } osg::ref_ptr root = osgDB::readNodeFiles(fileNames); if ( root.valid() ) { // convert the old style GeoSet to Geometry ConvertGeoSetsToGeometryVisitor cgtg; if( root.valid() ) root->accept(cgtg); // optimize the scene graph, remove rendundent nodes and state etc. osgUtil::Optimizer optimizer; optimizer.optimize(root.get()); if( do_convert ) root = oc.convert( root.get() ); if (compressTextures) { std::string ext = osgDB::getFileExtension(fileNameOut); if (ext=="ive") { CompressTexturesVisitor ctv; root->accept(ctv); ctv.compress(); } else { std::cout<<"Warning: compressing texture only supported when outputing to .ive"<