2005-03-13 09:47:46 +08:00
# include <stdio.h>
# include <osg/ArgumentParser>
# include <osg/ApplicationUsage>
# include <osg/Group>
# include <osg/Notify>
# include <osg/Vec3>
2008-04-11 18:16:38 +08:00
# include <osg/ProxyNode>
2005-03-13 09:47:46 +08:00
# include <osg/Geometry>
# include <osg/Texture2D>
# include <osg/Texture3D>
# include <osg/BlendFunc>
2007-05-23 18:57:46 +08:00
# include <osg/Timer>
2005-03-13 09:47:46 +08:00
# include <osgDB/Registry>
# include <osgDB/ReadFile>
# include <osgDB/WriteFile>
# include <osgDB/FileNameUtils>
# include <osgDB/ReaderWriter>
2008-07-25 18:18:36 +08:00
# include <osgDB/PluginQuery>
2005-03-13 09:47:46 +08:00
# include <osgUtil/Optimizer>
2008-04-11 18:16:38 +08:00
# include <osgUtil/Simplifier>
2005-03-16 22:14:12 +08:00
# include <osgUtil/SmoothingVisitor>
2005-03-13 09:47:46 +08:00
2007-08-26 18:19:12 +08:00
# include <osgViewer/GraphicsWindow>
2007-12-11 00:14:21 +08:00
# include <osgViewer/Version>
2007-08-26 18:19:12 +08:00
2005-03-13 09:47:46 +08:00
# include <iostream>
# include "OrientationConverter.h"
typedef std : : vector < std : : string > FileNameList ;
2007-01-10 22:56:22 +08:00
class MyGraphicsContext {
2005-03-13 09:47:46 +08:00
public :
2007-01-10 22:56:22 +08:00
MyGraphicsContext ( )
2005-03-13 09:47:46 +08:00
{
2007-01-10 22:56:22 +08:00
osg : : ref_ptr < osg : : GraphicsContext : : Traits > traits = new osg : : GraphicsContext : : Traits ;
traits - > x = 0 ;
traits - > y = 0 ;
traits - > width = 1 ;
traits - > height = 1 ;
traits - > windowDecoration = false ;
traits - > doubleBuffer = false ;
traits - > sharedContext = 0 ;
traits - > pbuffer = true ;
2018-09-09 00:18:33 +08:00
traits - > readDISPLAY ( ) ;
traits - > setUndefinedScreenDetailsToDefaultScreen ( ) ;
2005-03-13 09:47:46 +08:00
2007-01-10 22:56:22 +08:00
_gc = osg : : GraphicsContext : : createGraphicsContext ( traits . get ( ) ) ;
if ( ! _gc )
{
osg : : notify ( osg : : NOTICE ) < < " Failed to create pbuffer, failing back to normal graphics window. " < < std : : endl ;
2013-06-27 17:54:45 +08:00
2007-01-10 22:56:22 +08:00
traits - > pbuffer = false ;
_gc = osg : : GraphicsContext : : createGraphicsContext ( traits . get ( ) ) ;
}
2013-06-27 17:54:45 +08:00
if ( _gc . valid ( ) )
2007-01-10 22:56:22 +08:00
{
_gc - > realize ( ) ;
_gc - > makeCurrent ( ) ;
2007-08-26 18:19:12 +08:00
if ( dynamic_cast < osgViewer : : GraphicsWindow * > ( _gc . get ( ) ) )
{
std : : cout < < " Realized graphics window for OpenGL operations. " < < std : : endl ;
}
else
{
std : : cout < < " Realized pbuffer for OpenGL operations. " < < std : : endl ;
}
2007-01-10 22:56:22 +08:00
}
2005-03-13 09:47:46 +08:00
}
2013-06-27 17:54:45 +08:00
2007-01-10 22:56:22 +08:00
bool valid ( ) const { return _gc . valid ( ) & & _gc - > isRealized ( ) ; }
2013-06-27 17:54:45 +08:00
2005-03-13 09:47:46 +08:00
private :
2007-01-10 22:56:22 +08:00
osg : : ref_ptr < osg : : GraphicsContext > _gc ;
2005-03-13 09:47:46 +08:00
} ;
2008-04-11 18:16:38 +08:00
class DefaultNormalsGeometryVisitor
: public osg : : NodeVisitor
{
public :
DefaultNormalsGeometryVisitor ( )
: osg : : NodeVisitor ( osg : : NodeVisitor : : TRAVERSE_ALL_CHILDREN ) {
}
virtual void apply ( osg : : Geode & geode )
{
for ( unsigned int ii = 0 ; ii < geode . getNumDrawables ( ) ; + + ii )
{
osg : : ref_ptr < osg : : Geometry > geometry = dynamic_cast < osg : : Geometry * > ( geode . getDrawable ( ii ) ) ;
if ( geometry . valid ( ) )
{
osg : : ref_ptr < osg : : Vec3Array > newnormals = new osg : : Vec3Array ;
newnormals - > push_back ( osg : : Z_AXIS ) ;
2013-06-27 17:54:45 +08:00
geometry - > setNormalArray ( newnormals . get ( ) , osg : : Array : : BIND_OVERALL ) ;
2008-04-11 18:16:38 +08:00
}
}
}
virtual void apply ( osg : : Node & node )
{
traverse ( node ) ;
}
} ;
2005-03-13 09:47:46 +08:00
class CompressTexturesVisitor : public osg : : NodeVisitor
{
public :
CompressTexturesVisitor ( osg : : Texture : : InternalFormatMode internalFormatMode ) :
osg : : NodeVisitor ( osg : : NodeVisitor : : TRAVERSE_ALL_CHILDREN ) ,
_internalFormatMode ( internalFormatMode ) { }
virtual void apply ( osg : : Node & node )
{
if ( node . getStateSet ( ) ) apply ( * node . getStateSet ( ) ) ;
traverse ( node ) ;
}
2013-06-27 17:54:45 +08:00
2005-03-13 09:47:46 +08:00
virtual void apply ( osg : : Geode & node )
{
if ( node . getStateSet ( ) ) apply ( * node . getStateSet ( ) ) ;
2013-06-27 17:54:45 +08:00
2005-03-13 09:47:46 +08:00
for ( unsigned int i = 0 ; i < node . getNumDrawables ( ) ; + + i )
{
osg : : Drawable * drawable = node . getDrawable ( i ) ;
if ( drawable & & drawable - > getStateSet ( ) ) apply ( * drawable - > getStateSet ( ) ) ;
}
2013-06-27 17:54:45 +08:00
2005-03-13 09:47:46 +08:00
traverse ( node ) ;
}
2013-06-27 17:54:45 +08:00
2005-03-13 09:47:46 +08:00
virtual void apply ( osg : : StateSet & stateset )
{
2007-12-11 01:30:18 +08:00
// search for the existence of any texture object attributes
2005-03-13 09:47:46 +08:00
for ( unsigned int i = 0 ; i < stateset . getTextureAttributeList ( ) . size ( ) ; + + i )
{
osg : : Texture * texture = dynamic_cast < osg : : Texture * > ( stateset . getTextureAttribute ( i , osg : : StateAttribute : : TEXTURE ) ) ;
if ( texture )
{
_textureSet . insert ( texture ) ;
}
}
}
2013-06-27 17:54:45 +08:00
2005-03-13 09:47:46 +08:00
void compress ( )
{
2007-01-10 22:56:22 +08:00
MyGraphicsContext context ;
if ( ! context . valid ( ) )
{
2007-12-11 00:14:21 +08:00
osg : : notify ( osg : : NOTICE ) < < " Error: Unable to create graphis context, problem with running osgViewer- " < < osgViewerGetVersion ( ) < < " , cannot run compression. " < < std : : endl ;
2007-01-10 22:56:22 +08:00
return ;
}
2005-03-13 09:47:46 +08:00
osg : : ref_ptr < osg : : State > state = new osg : : State ;
2015-09-04 22:50:39 +08:00
state - > initializeExtensionProcs ( ) ;
2005-03-13 09:47:46 +08:00
for ( TextureSet : : iterator itr = _textureSet . begin ( ) ;
itr ! = _textureSet . end ( ) ;
+ + itr )
{
osg : : Texture * texture = const_cast < osg : : Texture * > ( itr - > get ( ) ) ;
2013-06-27 17:54:45 +08:00
2005-03-13 09:47:46 +08:00
osg : : Texture2D * texture2D = dynamic_cast < osg : : Texture2D * > ( texture ) ;
osg : : Texture3D * texture3D = dynamic_cast < osg : : Texture3D * > ( texture ) ;
2013-06-27 17:54:45 +08:00
2006-06-26 23:18:14 +08:00
osg : : ref_ptr < osg : : Image > image = texture2D ? texture2D - > getImage ( ) : ( texture3D ? texture3D - > getImage ( ) : 0 ) ;
2013-06-27 17:54:45 +08:00
if ( image . valid ( ) & &
2005-03-13 09:47:46 +08:00
( image - > getPixelFormat ( ) = = GL_RGB | | image - > getPixelFormat ( ) = = GL_RGBA ) & &
( image - > s ( ) > = 32 & & image - > t ( ) > = 32 ) )
{
texture - > setInternalFormatMode ( _internalFormatMode ) ;
2013-06-27 17:54:45 +08:00
2015-04-13 18:43:56 +08:00
// need to disable the unref after apply, otherwise the image could go out of scope.
2006-06-26 23:18:14 +08:00
bool unrefImageDataAfterApply = texture - > getUnRefImageDataAfterApply ( ) ;
texture - > setUnRefImageDataAfterApply ( false ) ;
2013-06-27 17:54:45 +08:00
2005-03-13 09:47:46 +08:00
// get OpenGL driver to create texture from image.
texture - > apply ( * state ) ;
2006-06-26 23:18:14 +08:00
// restore the original setting
texture - > setUnRefImageDataAfterApply ( unrefImageDataAfterApply ) ;
2005-03-13 09:47:46 +08:00
image - > readImageFromCurrentTexture ( 0 , true ) ;
texture - > setInternalFormatMode ( osg : : Texture : : USE_IMAGE_DATA_FORMAT ) ;
}
}
}
2009-02-20 23:47:28 +08:00
void write ( const std : : string & dir )
{
for ( TextureSet : : iterator itr = _textureSet . begin ( ) ;
itr ! = _textureSet . end ( ) ;
+ + itr )
{
osg : : Texture * texture = const_cast < osg : : Texture * > ( itr - > get ( ) ) ;
2013-06-27 17:54:45 +08:00
2009-02-20 23:47:28 +08:00
osg : : Texture2D * texture2D = dynamic_cast < osg : : Texture2D * > ( texture ) ;
osg : : Texture3D * texture3D = dynamic_cast < osg : : Texture3D * > ( texture ) ;
2013-06-27 17:54:45 +08:00
2009-02-20 23:47:28 +08:00
osg : : ref_ptr < osg : : Image > image = texture2D ? texture2D - > getImage ( ) : ( texture3D ? texture3D - > getImage ( ) : 0 ) ;
if ( image . valid ( ) )
{
std : : string name = osgDB : : getStrippedName ( image - > getFileName ( ) ) ;
name + = " .dds " ;
image - > setFileName ( name ) ;
std : : string path = dir . empty ( ) ? name : osgDB : : concatPaths ( dir , name ) ;
osgDB : : writeImageFile ( * image , path ) ;
osg : : notify ( osg : : NOTICE ) < < " Image written to ' " < < path < < " '. " < < std : : endl ;
}
}
}
2013-06-27 17:54:45 +08:00
2005-03-13 09:47:46 +08:00
typedef std : : set < osg : : ref_ptr < osg : : Texture > > TextureSet ;
TextureSet _textureSet ;
osg : : Texture : : InternalFormatMode _internalFormatMode ;
2013-06-27 17:54:45 +08:00
2005-03-13 09:47:46 +08:00
} ;
class FixTransparencyVisitor : public osg : : NodeVisitor
{
public :
enum FixTransparencyMode
{
NO_TRANSPARANCY_FIXING ,
MAKE_OPAQUE_TEXTURE_STATESET_OPAQUE ,
2007-04-06 23:36:13 +08:00
MAKE_ALL_STATESET_OPAQUE
2005-03-13 09:47:46 +08:00
} ;
FixTransparencyVisitor ( FixTransparencyMode mode = MAKE_OPAQUE_TEXTURE_STATESET_OPAQUE ) :
osg : : NodeVisitor ( osg : : NodeVisitor : : TRAVERSE_ALL_CHILDREN ) ,
_numTransparent ( 0 ) ,
_numOpaque ( 0 ) ,
_numTransparentMadeOpaque ( 0 ) ,
_mode ( mode )
{
std : : cout < < " Running FixTransparencyVisitor... " < < std : : endl ;
}
2013-06-27 17:54:45 +08:00
2005-03-13 09:47:46 +08:00
~ FixTransparencyVisitor ( )
{
std : : cout < < " Number of Transparent StateSet " < < _numTransparent < < std : : endl ;
std : : cout < < " Number of Opaque StateSet " < < _numOpaque < < std : : endl ;
std : : cout < < " Number of Transparent State made Opaque " < < _numTransparentMadeOpaque < < std : : endl ;
}
virtual void apply ( osg : : Node & node )
{
if ( node . getStateSet ( ) ) isTransparent ( * node . getStateSet ( ) ) ;
traverse ( node ) ;
}
2013-06-27 17:54:45 +08:00
2005-03-13 09:47:46 +08:00
virtual void apply ( osg : : Geode & node )
{
if ( node . getStateSet ( ) ) isTransparent ( * node . getStateSet ( ) ) ;
2013-06-27 17:54:45 +08:00
2005-03-13 09:47:46 +08:00
for ( unsigned int i = 0 ; i < node . getNumDrawables ( ) ; + + i )
{
osg : : Drawable * drawable = node . getDrawable ( i ) ;
if ( drawable & & drawable - > getStateSet ( ) ) isTransparent ( * drawable - > getStateSet ( ) ) ;
}
2013-06-27 17:54:45 +08:00
2005-03-13 09:47:46 +08:00
traverse ( node ) ;
}
2013-06-27 17:54:45 +08:00
2005-03-13 09:47:46 +08:00
virtual bool isTransparent ( osg : : StateSet & stateset )
{
bool hasTranslucentTexture = false ;
bool hasBlendFunc = dynamic_cast < osg : : BlendFunc * > ( stateset . getAttribute ( osg : : StateAttribute : : BLENDFUNC ) ) ! = 0 ;
bool hasTransparentRenderingHint = stateset . getRenderingHint ( ) = = osg : : StateSet : : TRANSPARENT_BIN ;
bool hasDepthSortBin = ( stateset . getRenderBinMode ( ) = = osg : : StateSet : : USE_RENDERBIN_DETAILS ) ? ( stateset . getBinName ( ) = = " DepthSortedBin " ) : false ;
bool hasTexture = false ;
2007-12-11 01:30:18 +08:00
// search for the existence of any texture object attributes
2005-03-13 09:47:46 +08:00
for ( unsigned int i = 0 ; i < stateset . getTextureAttributeList ( ) . size ( ) ; + + i )
{
osg : : Texture * texture = dynamic_cast < osg : : Texture * > ( stateset . getTextureAttribute ( i , osg : : StateAttribute : : TEXTURE ) ) ;
if ( texture )
{
hasTexture = true ;
for ( unsigned int im = 0 ; im < texture - > getNumImages ( ) ; + + im )
{
osg : : Image * image = texture - > getImage ( im ) ;
2013-06-27 17:54:45 +08:00
if ( image & & image - > isImageTranslucent ( ) ) hasTranslucentTexture = true ;
2005-03-13 09:47:46 +08:00
}
}
}
2013-06-27 17:54:45 +08:00
2005-03-13 09:47:46 +08:00
if ( hasTranslucentTexture | | hasBlendFunc | | hasTransparentRenderingHint | | hasDepthSortBin )
{
+ + _numTransparent ;
2013-06-27 17:54:45 +08:00
2005-03-13 09:47:46 +08:00
bool makeNonTransparent = false ;
switch ( _mode )
{
case ( MAKE_OPAQUE_TEXTURE_STATESET_OPAQUE ) :
if ( hasTexture & & ! hasTranslucentTexture )
{
makeNonTransparent = true ;
}
break ;
case ( MAKE_ALL_STATESET_OPAQUE ) :
makeNonTransparent = true ;
break ;
default :
makeNonTransparent = false ;
break ;
}
2013-06-27 17:54:45 +08:00
2005-03-13 09:47:46 +08:00
if ( makeNonTransparent )
{
stateset . removeAttribute ( osg : : StateAttribute : : BLENDFUNC ) ;
stateset . removeMode ( GL_BLEND ) ;
stateset . setRenderingHint ( osg : : StateSet : : DEFAULT_BIN ) ;
+ + _numTransparentMadeOpaque ;
}
return true ;
}
else
{
+ + _numOpaque ;
return false ;
}
}
unsigned int _numTransparent ;
2013-06-27 17:54:45 +08:00
unsigned int _numOpaque ;
2005-03-13 09:47:46 +08:00
unsigned int _numTransparentMadeOpaque ;
FixTransparencyMode _mode ;
} ;
class PruneStateSetVisitor : public osg : : NodeVisitor
{
public :
PruneStateSetVisitor ( ) :
osg : : NodeVisitor ( osg : : NodeVisitor : : TRAVERSE_ALL_CHILDREN ) ,
_numStateSetRemoved ( 0 )
{
std : : cout < < " Running PruneStateSet... " < < std : : endl ;
}
2013-06-27 17:54:45 +08:00
2005-03-13 09:47:46 +08:00
~ PruneStateSetVisitor ( )
{
std : : cout < < " Number of StateState removed " < < _numStateSetRemoved < < std : : endl ;
}
virtual void apply ( osg : : Node & node )
{
if ( node . getStateSet ( ) )
{
node . setStateSet ( 0 ) ;
+ + _numStateSetRemoved ;
}
traverse ( node ) ;
}
2013-06-27 17:54:45 +08:00
2005-03-13 09:47:46 +08:00
virtual void apply ( osg : : Geode & node )
{
if ( node . getStateSet ( ) )
{
node . setStateSet ( 0 ) ;
+ + _numStateSetRemoved ;
}
2013-06-27 17:54:45 +08:00
2005-03-13 09:47:46 +08:00
traverse ( node ) ;
}
2013-06-27 17:54:45 +08:00
2005-03-13 09:47:46 +08:00
unsigned int _numStateSetRemoved ;
} ;
2005-03-17 04:44:10 +08:00
/** Add missing colours to osg::Geometry.*/
class AddMissingColoursToGeometryVisitor : public osg : : NodeVisitor
{
public :
AddMissingColoursToGeometryVisitor ( ) : osg : : NodeVisitor ( osg : : NodeVisitor : : TRAVERSE_ALL_CHILDREN ) { }
virtual void apply ( osg : : Geode & geode )
{
for ( unsigned int i = 0 ; i < geode . getNumDrawables ( ) ; + + i )
{
osg : : Geometry * geometry = dynamic_cast < osg : : Geometry * > ( geode . getDrawable ( i ) ) ;
if ( geometry )
{
if ( geometry - > getColorArray ( ) = = 0 | | geometry - > getColorArray ( ) - > getNumElements ( ) = = 0 )
{
osg : : Vec4Array * colours = new osg : : Vec4Array ( 1 ) ;
( * colours ) [ 0 ] . set ( 1.0f , 1.0f , 1.0f , 1.0f ) ;
2013-06-27 17:54:45 +08:00
geometry - > setColorArray ( colours , osg : : Array : : BIND_OVERALL ) ;
2005-03-17 04:44:10 +08:00
}
}
}
}
virtual void apply ( osg : : Node & node ) { traverse ( node ) ; }
} ;
2005-03-13 09:47:46 +08:00
static void usage ( const char * prog , const char * msg )
{
if ( msg )
{
osg : : notify ( osg : : NOTICE ) < < std : : endl ;
osg : : notify ( osg : : NOTICE ) < < msg < < std : : endl ;
}
2008-04-11 18:16:38 +08:00
// basic usage
2005-03-13 09:47:46 +08:00
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 ;
2008-04-11 18:16:38 +08:00
// print env options - especially since optimizer is always _on_
osg : : notify ( osg : : NOTICE ) < < " environment: " < < std : : endl ;
osg : : ApplicationUsage : : UsageMap um = osg : : ApplicationUsage : : instance ( ) - > getEnvironmentalVariables ( ) ;
std : : string envstring ;
osg : : ApplicationUsage : : instance ( ) - > getFormattedString ( envstring , um ) ;
osg : : notify ( osg : : NOTICE ) < < envstring < < std : : endl ;
// print tool options
2005-03-13 09:47:46 +08:00
osg : : notify ( osg : : NOTICE ) < < " options: " < < std : : endl ;
osg : : notify ( osg : : NOTICE ) < < " -O option - ReaderWriter option " < < std : : endl ;
osg : : notify ( osg : : NOTICE ) < < std : : endl ;
osg : : notify ( osg : : NOTICE ) < < " --compressed - Enable the usage of compressed textures, " < < std : : endl ;
osg : : notify ( osg : : NOTICE ) < < " defaults to OpenGL ARB compressed textures. " < < std : : endl ;
osg : : notify ( osg : : NOTICE ) < < " --compressed-arb - Enable the usage of OpenGL ARB compressed textures " < < std : : endl ;
osg : : notify ( osg : : NOTICE ) < < " --compressed-dxt1 - Enable the usage of S3TC DXT1 compressed textures " < < std : : endl ;
osg : : notify ( osg : : NOTICE ) < < " --compressed-dxt3 - Enable the usage of S3TC DXT3 compressed textures " < < std : : endl ;
osg : : notify ( osg : : NOTICE ) < < " --compressed-dxt5 - Enable the usage of S3TC DXT5 compressed textures " < < std : : endl ;
osg : : notify ( osg : : NOTICE ) < < std : : endl ;
2011-04-14 23:45:14 +08:00
osg : : notify ( osg : : NOTICE ) < < " --fix-transparency - fix statesets which are currently " < < std : : endl ;
osg : : notify ( osg : : NOTICE ) < < " declared as transparent, but should be opaque. " < < std : : endl ;
osg : : notify ( osg : : NOTICE ) < < " Defaults to using the fixTranspancyMode " < < std : : endl ;
osg : : notify ( osg : : NOTICE ) < < " MAKE_OPAQUE_TEXTURE_STATESET_OPAQUE. " < < std : : endl ;
osg : : notify ( osg : : NOTICE ) < < " --fix-transparency-mode <mode_string> - fix statesets which are currently " < < std : : endl ;
osg : : notify ( osg : : NOTICE ) < < " declared as transparent but should be opaque. " < < std : : endl ;
osg : : notify ( osg : : NOTICE ) < < " The mode_string determines which algorithm is used " < < std : : endl ;
osg : : notify ( osg : : NOTICE ) < < " to fix the transparency, options are: " < < std : : endl ;
2005-03-13 09:47:46 +08:00
osg : : notify ( osg : : NOTICE ) < < " MAKE_OPAQUE_TEXTURE_STATESET_OPAQUE, " < < std : : endl ;
osg : : notify ( osg : : NOTICE ) < < " MAKE_ALL_STATESET_OPAQUE. " < < std : : endl ;
osg : : notify ( osg : : NOTICE ) < < 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 "
2011-04-14 23:45:14 +08:00
" output file, or degrees is the rotation angle in \n "
" degrees around axis (A0,A1,A2). For example, to \n "
" convert a model built in a Y-Up coordinate system to a \n "
" model with a Z-up coordinate system, the argument may \n "
" look like \n "
2005-03-13 09:47:46 +08:00
" \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 ;
2011-05-27 19:22:43 +08:00
osg : : notify ( osg : : NOTICE ) < < " --use-world-frame - Perform transformations in the world frame, rather \n "
" than relative to the center of the bounding sphere. \n "
< < std : : endl ;
2011-04-14 23:45:14 +08:00
osg : : notify ( osg : : NOTICE ) < < " --simplify n - Run simplifier prior to output. Argument must be a " < < std : : endl
< < " normalized value for the resultant percentage " < < std : : endl
< < " reduction. " < < std : : endl
< < " Example: --simplify .5 " < < std : : endl
< < " will produce a 50% reduced model. " < < std : : endl
2008-04-11 18:16:38 +08:00
< < std : : endl ;
2005-03-13 09:47:46 +08:00
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 "
2011-04-14 23:45:14 +08:00
" Caution: Scaling is done in destination orientation \n "
2005-03-13 09:47:46 +08:00
< < std : : endl ;
2005-03-16 22:14:12 +08:00
osg : : notify ( osg : : NOTICE ) < < " --smooth - Smooth the surface by regenerating surface normals on \n "
2011-04-14 23:45:14 +08:00
" all geometry nodes " < < std : : endl ;
osg : : notify ( osg : : NOTICE ) < < " --addMissingColors - Add a white color value to all geometry nodes \n "
" that don't have their own color values \n "
" (--addMissingColours also accepted). " < < std : : endl ;
2008-04-11 18:16:38 +08:00
osg : : notify ( osg : : NOTICE ) < < " --overallNormal - Replace normals with a single overall normal. " < < std : : endl ;
2009-06-09 00:50:50 +08:00
osg : : notify ( osg : : NOTICE ) < < " --enable-object-cache - Enable caching of objects, images, etc. " < < std : : endl ;
2005-03-17 04:44:10 +08:00
2008-12-22 16:26:16 +08:00
osg : : notify ( osg : : NOTICE ) < < std : : endl ;
osg : : notify ( osg : : NOTICE ) < <
2011-04-14 23:45:14 +08:00
" --formats - List all supported formats and their supported options. " < < std : : endl ;
2008-12-22 16:26:16 +08:00
osg : : notify ( osg : : NOTICE ) < <
2011-04-14 23:45:14 +08:00
" --format <format> - Display information about the specified <format>, \n "
" where <format> is the file extension, such as \" flt \" . " < < std : : endl ;
2008-12-22 16:26:16 +08:00
osg : : notify ( osg : : NOTICE ) < <
2011-04-14 23:45:14 +08:00
" --plugins - List all supported plugin files. " < < std : : endl ;
2008-12-22 16:26:16 +08:00
osg : : notify ( osg : : NOTICE ) < <
2011-04-14 23:45:14 +08:00
" --plugin <plugin> - Display information about the specified <plugin>, \n "
" where <plugin> is the plugin's full path and file name. " < < std : : endl ;
2005-03-13 09:47:46 +08:00
}
int main ( int argc , char * * argv )
{
// use an ArgumentParser object to manage the program arguments.
osg : : ArgumentParser arguments ( & argc , argv ) ;
2013-06-27 17:54:45 +08:00
2005-03-13 09:47:46 +08:00
// set up the usage document, in case we need to print out how to use this program.
arguments . getApplicationUsage ( ) - > setApplicationName ( arguments . getApplicationName ( ) ) ;
2005-11-16 06:07:54 +08:00
arguments . getApplicationUsage ( ) - > setDescription ( arguments . getApplicationName ( ) + " is a utility for converting between various input and output databases formats. " ) ;
2005-03-13 09:47:46 +08:00
arguments . getApplicationUsage ( ) - > setCommandLineUsage ( arguments . getApplicationName ( ) + " [options] filename ... " ) ;
2007-12-11 01:30:18 +08:00
arguments . getApplicationUsage ( ) - > addCommandLineOption ( " -h or --help " , " Display command line parameters " ) ;
2005-11-03 18:57:10 +08:00
arguments . getApplicationUsage ( ) - > addCommandLineOption ( " --help-env " , " Display environmental variables available " ) ;
2008-12-22 16:26:16 +08:00
//arguments.getApplicationUsage()->addCommandLineOption("--formats","List supported file formats");
//arguments.getApplicationUsage()->addCommandLineOption("--plugins","List database olugins");
2005-03-13 09:47:46 +08:00
// if user request help write it out to cout.
if ( arguments . read ( " -h " ) | | arguments . read ( " --help " ) )
2013-06-27 17:54:45 +08:00
{
2014-06-25 19:07:59 +08:00
osg : : setNotifyLevel ( osg : : NOTICE ) ;
2005-03-13 09:47:46 +08:00
usage ( arguments . getApplicationName ( ) . c_str ( ) , 0 ) ;
//arguments.getApplicationUsage()->write(std::cout);
return 1 ;
}
2013-06-27 17:54:45 +08:00
2005-11-03 18:57:10 +08:00
if ( arguments . read ( " --help-env " ) )
2013-06-27 17:54:45 +08:00
{
2005-11-03 18:57:10 +08:00
arguments . getApplicationUsage ( ) - > write ( std : : cout , osg : : ApplicationUsage : : ENVIRONMENTAL_VARIABLE ) ;
return 1 ;
}
2013-06-27 17:54:45 +08:00
2008-07-15 04:22:38 +08:00
if ( arguments . read ( " --plugins " ) )
2008-07-14 16:48:49 +08:00
{
osgDB : : FileNameList plugins = osgDB : : listAllAvailablePlugins ( ) ;
for ( osgDB : : FileNameList : : iterator itr = plugins . begin ( ) ;
itr ! = plugins . end ( ) ;
+ + itr )
{
std : : cout < < " Plugin " < < * itr < < std : : endl ;
}
2008-07-15 04:22:38 +08:00
return 0 ;
2013-06-27 17:54:45 +08:00
}
2008-07-24 20:01:23 +08:00
std : : string plugin ;
if ( arguments . read ( " --plugin " , plugin ) )
{
osgDB : : outputPluginDetails ( std : : cout , plugin ) ;
return 0 ;
2013-06-27 17:54:45 +08:00
}
2008-07-24 20:01:23 +08:00
std : : string ext ;
if ( arguments . read ( " --format " , ext ) )
{
plugin = osgDB : : Registry : : instance ( ) - > createLibraryNameForExtension ( ext ) ;
osgDB : : outputPluginDetails ( std : : cout , plugin ) ;
return 0 ;
2013-06-27 17:54:45 +08:00
}
2008-07-15 04:22:38 +08:00
if ( arguments . read ( " --formats " ) )
{
osgDB : : FileNameList plugins = osgDB : : listAllAvailablePlugins ( ) ;
for ( osgDB : : FileNameList : : iterator itr = plugins . begin ( ) ;
itr ! = plugins . end ( ) ;
+ + itr )
{
2008-07-24 20:01:23 +08:00
osgDB : : outputPluginDetails ( std : : cout , * itr ) ;
2008-07-15 04:22:38 +08:00
}
return 0 ;
2013-06-27 17:54:45 +08:00
}
2005-03-13 09:47:46 +08:00
if ( arguments . argc ( ) < = 1 )
{
arguments . getApplicationUsage ( ) - > write ( std : : cout , osg : : ApplicationUsage : : COMMAND_LINE_OPTION ) ;
return 1 ;
}
FileNameList fileNames ;
OrientationConverter oc ;
bool do_convert = false ;
2011-05-27 19:22:43 +08:00
if ( arguments . read ( " --use-world-frame " ) )
{
oc . useWorldFrame ( true ) ;
}
2005-03-13 09:47:46 +08:00
std : : string str ;
while ( arguments . read ( " -O " , str ) )
{
osgDB : : ReaderWriter : : Options * options = new osgDB : : ReaderWriter : : Options ;
options - > setOptionString ( str ) ;
osgDB : : Registry : : instance ( ) - > setOptions ( options ) ;
}
while ( arguments . read ( " -e " , ext ) )
{
std : : string libName = osgDB : : Registry : : instance ( ) - > createLibraryNameForExtension ( ext ) ;
2016-06-23 23:32:30 +08:00
if ( osgDB : : Registry : : instance ( ) - > loadLibrary ( libName ) = = osgDB : : Registry : : NOT_LOADED )
{
OSG_NOTICE < < " Unable to load library : " < < libName < < std : : endl ;
}
2005-03-13 09:47:46 +08:00
}
2013-06-27 17:54:45 +08:00
2005-03-13 09:47:46 +08:00
std : : string libName ;
while ( arguments . read ( " -l " , libName ) )
{
2016-06-23 17:06:12 +08:00
if ( osgDB : : Registry : : instance ( ) - > loadLibrary ( libName ) = = osgDB : : Registry : : NOT_LOADED )
{
OSG_NOTICE < < " Unable to load library : " < < libName < < std : : endl ;
}
2005-03-13 09:47:46 +08:00
}
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 " ,
& degrees , & 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 ;
}
2013-06-27 17:54:45 +08:00
}
2005-03-13 09:47:46 +08:00
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 ;
}
2008-04-11 18:16:38 +08:00
float simplifyPercent = 1.0 ;
bool do_simplify = false ;
while ( arguments . read ( " --simplify " , str ) )
{
float nsimp = 1.0 ;
if ( sscanf ( str . c_str ( ) , " %f " ,
& nsimp ) ! = 1 )
{
usage ( argv [ 0 ] , " Scale argument format incorrect. " ) ;
return 1 ;
}
std : : cout < < str < < " " < < nsimp < < std : : endl ;
simplifyPercent = nsimp ;
osg : : notify ( osg : : INFO ) < < " Simplifying with percentage: " < < simplifyPercent < < std : : endl ;
do_simplify = true ;
}
2005-03-13 09:47:46 +08:00
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 ;
}
2013-06-27 17:54:45 +08:00
2005-03-13 09:47:46 +08:00
FixTransparencyVisitor : : FixTransparencyMode fixTransparencyMode = FixTransparencyVisitor : : NO_TRANSPARANCY_FIXING ;
std : : string fixString ;
while ( arguments . read ( " --fix-transparency " ) ) fixTransparencyMode = FixTransparencyVisitor : : MAKE_OPAQUE_TEXTURE_STATESET_OPAQUE ;
while ( arguments . read ( " --fix-transparency-mode " , fixString ) )
{
if ( fixString = = " MAKE_OPAQUE_TEXTURE_STATESET_OPAQUE " ) fixTransparencyMode = FixTransparencyVisitor : : MAKE_OPAQUE_TEXTURE_STATESET_OPAQUE ;
if ( fixString = = " MAKE_ALL_STATESET_OPAQUE " ) fixTransparencyMode = FixTransparencyVisitor : : MAKE_ALL_STATESET_OPAQUE ;
} ;
2013-06-27 17:54:45 +08:00
2005-03-13 09:47:46 +08:00
bool pruneStateSet = false ;
while ( arguments . read ( " --prune-StateSet " ) ) pruneStateSet = true ;
osg : : Texture : : InternalFormatMode internalFormatMode = osg : : Texture : : USE_IMAGE_DATA_FORMAT ;
while ( arguments . read ( " --compressed " ) | | arguments . read ( " --compressed-arb " ) ) { internalFormatMode = osg : : Texture : : USE_ARB_COMPRESSION ; }
while ( arguments . read ( " --compressed-dxt1 " ) ) { internalFormatMode = osg : : Texture : : USE_S3TC_DXT1_COMPRESSION ; }
while ( arguments . read ( " --compressed-dxt3 " ) ) { internalFormatMode = osg : : Texture : : USE_S3TC_DXT3_COMPRESSION ; }
while ( arguments . read ( " --compressed-dxt5 " ) ) { internalFormatMode = osg : : Texture : : USE_S3TC_DXT5_COMPRESSION ; }
2005-03-16 22:14:12 +08:00
bool smooth = false ;
while ( arguments . read ( " --smooth " ) ) { smooth = true ; }
2013-06-27 17:54:45 +08:00
2005-03-17 04:44:10 +08:00
bool addMissingColours = false ;
while ( arguments . read ( " --addMissingColours " ) | | arguments . read ( " --addMissingColors " ) ) { addMissingColours = true ; }
2005-03-16 22:14:12 +08:00
2008-04-11 18:16:38 +08:00
bool do_overallNormal = false ;
2017-12-03 00:49:47 +08:00
while ( arguments . read ( " --overallNormal " ) ) { do_overallNormal = true ; }
2008-04-11 18:16:38 +08:00
2009-06-09 00:50:50 +08:00
bool enableObjectCache = false ;
while ( arguments . read ( " --enable-object-cache " ) ) { enableObjectCache = true ; }
2005-03-13 09:47:46 +08:00
// any option left unread are converted into errors to write out later.
arguments . reportRemainingOptionsAsUnrecognized ( ) ;
2007-12-11 01:30:18 +08:00
// report any errors if they have occurred when parsing the program arguments.
2005-03-13 09:47:46 +08:00
if ( arguments . errors ( ) )
{
arguments . writeErrorMessages ( std : : cout ) ;
return 1 ;
}
for ( int pos = 1 ; pos < arguments . argc ( ) ; + + pos )
{
if ( ! arguments . isOption ( pos ) )
{
fileNames . push_back ( arguments [ pos ] ) ;
}
}
2009-06-09 00:50:50 +08:00
if ( enableObjectCache )
{
if ( osgDB : : Registry : : instance ( ) - > getOptions ( ) = = 0 ) osgDB : : Registry : : instance ( ) - > setOptions ( new osgDB : : Options ( ) ) ;
osgDB : : Registry : : instance ( ) - > getOptions ( ) - > setObjectCacheHint ( osgDB : : Options : : CACHE_ALL ) ;
}
2005-03-13 09:47:46 +08:00
2018-11-20 22:19:37 +08:00
std : : string fileNameOut ( " converted.osgt " ) ;
2005-03-13 09:47:46 +08:00
if ( fileNames . size ( ) > 1 )
{
fileNameOut = fileNames . back ( ) ;
fileNames . pop_back ( ) ;
}
2007-05-23 18:57:46 +08:00
osg : : Timer_t startTick = osg : : Timer : : instance ( ) - > tick ( ) ;
2018-11-20 22:19:37 +08:00
typedef std : : vector < osg : : ref_ptr < osg : : Image > > Images ;
typedef std : : vector < osg : : ref_ptr < osg : : Node > > Nodes ;
typedef std : : vector < osg : : ref_ptr < osg : : Object > > Objects ;
2005-03-13 09:47:46 +08:00
2018-11-20 22:19:37 +08:00
Images images ;
Nodes nodes ;
Objects objects ;
for ( FileNameList : : iterator itr = fileNames . begin ( ) ;
itr ! = fileNames . end ( ) ;
+ + itr )
2007-05-23 18:57:46 +08:00
{
2018-11-20 22:19:37 +08:00
osg : : ref_ptr < osg : : Object > object = osgDB : : readObjectFile ( * itr ) ;
if ( object . valid ( ) )
{
if ( object - > asNode ( ) ) nodes . push_back ( object - > asNode ( ) ) ;
else if ( object - > asImage ( ) ) images . push_back ( object - > asImage ( ) ) ;
else objects . push_back ( object ) ;
}
2007-05-23 18:57:46 +08:00
}
2018-11-20 22:19:37 +08:00
if ( images . empty ( ) & & nodes . empty ( ) & & objects . empty ( ) )
2005-03-13 09:47:46 +08:00
{
2018-11-20 22:19:37 +08:00
osg : : notify ( osg : : NOTICE ) < < " Warning: failed to load any files " < < std : : endl ;
return 1 ;
2005-03-13 09:47:46 +08:00
}
2018-11-20 22:19:37 +08:00
osg : : Timer_t endTick = osg : : Timer : : instance ( ) - > tick ( ) ;
osg : : notify ( osg : : INFO ) < < " Time to load files " < < osg : : Timer : : instance ( ) - > delta_m ( startTick , endTick ) < < " ms " < < std : : endl ;
osg : : ref_ptr < osg : : Node > root ;
if ( nodes . size ( ) = = 1 ) root = nodes . front ( ) ;
else if ( nodes . size ( ) > 1 )
2005-03-13 09:47:46 +08:00
{
2018-11-20 22:19:37 +08:00
osg : : ref_ptr < osg : : Group > group = new osg : : Group ;
for ( Nodes : : iterator itr = nodes . begin ( ) ;
itr ! = nodes . end ( ) ;
+ + itr )
{
group - > addChild ( itr - > get ( ) ) ;
}
root = group ;
2005-03-13 09:47:46 +08:00
}
if ( root . valid ( ) )
{
2018-11-20 22:19:37 +08:00
if ( pruneStateSet )
{
PruneStateSetVisitor pssv ;
root - > accept ( pssv ) ;
}
if ( fixTransparencyMode ! = FixTransparencyVisitor : : NO_TRANSPARANCY_FIXING )
{
FixTransparencyVisitor atv ( fixTransparencyMode ) ;
root - > accept ( atv ) ;
}
2013-06-27 17:54:45 +08:00
2005-03-16 22:14:12 +08:00
if ( smooth )
{
osgUtil : : SmoothingVisitor sv ;
root - > accept ( sv ) ;
2013-06-27 17:54:45 +08:00
}
2005-03-17 04:44:10 +08:00
if ( addMissingColours )
{
AddMissingColoursToGeometryVisitor av ;
root - > accept ( av ) ;
}
2015-04-13 18:43:56 +08:00
// optimize the scene graph, remove redundant nodes and state etc.
2005-03-13 09:47:46 +08:00
osgUtil : : Optimizer optimizer ;
optimizer . optimize ( root . get ( ) ) ;
2013-06-27 17:54:45 +08:00
2005-03-13 09:47:46 +08:00
if ( do_convert )
root = oc . convert ( root . get ( ) ) ;
2013-06-27 17:54:45 +08:00
2005-03-13 09:47:46 +08:00
if ( internalFormatMode ! = osg : : Texture : : USE_IMAGE_DATA_FORMAT )
{
2016-05-20 20:38:34 +08:00
ext = osgDB : : getFileExtension ( fileNameOut ) ;
2009-02-20 23:47:28 +08:00
CompressTexturesVisitor ctv ( internalFormatMode ) ;
root - > accept ( ctv ) ;
ctv . compress ( ) ;
osgDB : : ReaderWriter : : Options * options = osgDB : : Registry : : instance ( ) - > getOptions ( ) ;
if ( ext ! = " ive " | | ( options & & options - > getOptionString ( ) . find ( " noTexturesInIVEFile " ) ! = std : : string : : npos ) )
2005-03-13 09:47:46 +08:00
{
2009-02-20 23:47:28 +08:00
ctv . write ( osgDB : : getFilePath ( fileNameOut ) ) ;
2005-03-13 09:47:46 +08:00
}
}
2008-04-11 18:16:38 +08:00
// scrub normals
if ( do_overallNormal )
{
DefaultNormalsGeometryVisitor dngv ;
root - > accept ( dngv ) ;
}
// apply any user-specified simplification
if ( do_simplify )
{
osgUtil : : Simplifier simple ;
simple . setSmoothing ( smooth ) ;
osg : : notify ( osg : : ALWAYS ) < < " smoothing: " < < smooth < < std : : endl ;
simple . setSampleRatio ( simplifyPercent ) ;
root - > accept ( simple ) ;
}
2007-10-01 03:53:02 +08:00
osgDB : : ReaderWriter : : WriteResult result = osgDB : : Registry : : instance ( ) - > writeNode ( * root , fileNameOut , osgDB : : Registry : : instance ( ) - > getOptions ( ) ) ;
2006-11-08 01:00:56 +08:00
if ( result . success ( ) )
2005-03-13 09:47:46 +08:00
{
osg : : notify ( osg : : NOTICE ) < < " Data written to ' " < < fileNameOut < < " '. " < < std : : endl ;
}
2006-11-08 01:00:56 +08:00
else if ( result . message ( ) . empty ( ) )
{
2011-05-05 18:28:34 +08:00
osg : : notify ( osg : : NOTICE ) < < " Warning: file write to ' " < < fileNameOut < < " ' not supported. " < < std : : endl ;
2006-11-08 01:00:56 +08:00
}
else
{
osg : : notify ( osg : : NOTICE ) < < result . message ( ) < < std : : endl ;
}
2005-03-13 09:47:46 +08:00
}
2018-11-20 22:19:37 +08:00
else if ( ! images . empty ( ) )
{
if ( images . size ( ) > 1 )
{
OSG_NOTICE < < " Warning: osgconv does not support writing multiple to a single file. " < < std : : endl ;
return 1 ;
}
osgDB : : writeImageFile ( * images . front ( ) , fileNameOut ) ;
}
else if ( ! objects . empty ( ) )
{
osgDB : : writeObjectFile ( * images . front ( ) , fileNameOut ) ;
}
2005-03-13 09:47:46 +08:00
else
{
osg : : notify ( osg : : NOTICE ) < < " Error no data loaded. " < < std : : endl ;
return 1 ;
}
return 0 ;
}