2003-10-28 00:07:21 +08:00
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2003 Robert Osfield
*
* This application is open source and may be redistributed and / or modified
* freely and without restriction , both in commericial and non commericial applications ,
* as long as this copyright notice is maintained .
*
* This application is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE .
*/
# include <osg/Texture2D>
# include <osg/Geometry>
# include <osg/State>
# include <osg/ShapeDrawable>
# include <osgDB/ReadFile>
# include <osgDB/WriteFile>
# include <osgDB/ImageOptions>
# include <osgDB/FileNameUtils>
# include <osgUtil/Optimizer>
# include <osgUtil/TriStripVisitor>
# include <osgUtil/SmoothingVisitor>
# include <osgUtil/TangentSpaceGenerator>
# include <osgFX/BumpMapping>
# include <osgProducer/Viewer>
2004-01-29 23:47:06 +08:00
# include <osg/Switch>
2003-10-28 00:07:21 +08:00
2004-03-12 00:14:25 +08:00
# include <osgTerrain/DataSet>
2003-10-28 00:07:21 +08:00
2004-01-29 23:47:06 +08:00
# include <ogr_spatialref.h>
2004-03-29 18:45:58 +08:00
class GraphicsContext {
public :
GraphicsContext ( )
{
rs = new Producer : : RenderSurface ;
rs - > setWindowRectangle ( 0 , 0 , 1 , 1 ) ;
rs - > useBorder ( false ) ;
rs - > useConfigEventThread ( false ) ;
rs - > realize ( ) ;
std : : cout < < " Realized window " < < std : : endl ;
}
virtual ~ GraphicsContext ( )
{
}
private :
Producer : : ref_ptr < Producer : : RenderSurface > rs ;
} ;
2004-03-20 06:03:32 +08:00
2004-03-12 00:14:25 +08:00
char * SanitizeSRS ( const char * pszUserInput )
{
OGRSpatialReferenceH hSRS ;
char * pszResult = NULL ;
CPLErrorReset ( ) ;
hSRS = OSRNewSpatialReference ( NULL ) ;
if ( OSRSetFromUserInput ( hSRS , pszUserInput ) = = OGRERR_NONE )
OSRExportToWkt ( hSRS , & pszResult ) ;
else
{
CPLError ( CE_Failure , CPLE_AppDefined ,
" Translating source or target SRS failed: \n %s " ,
pszUserInput ) ;
exit ( 1 ) ;
}
OSRDestroySpatialReference ( hSRS ) ;
return pszResult ;
}
2003-10-28 00:07:21 +08:00
2004-03-31 23:50:30 +08:00
void ellipsodeTransformTest ( double latitude , double longitude , double height )
{
osgTerrain : : EllipsodeTransform transform ;
double X , Y , Z ;
double newLat , newLong , newHeight ;
transform . convertLatLongHeightToXYZ ( latitude , longitude , height ,
X , Y , Z ) ;
transform . convertXYZToLatLongHeight ( X , Y , Z ,
newLat , newLong , newHeight ) ;
std : : cout < < " lat = " < < osg : : RadiansToDegrees ( latitude ) < < " \t long= " < < osg : : RadiansToDegrees ( longitude ) < < " \t " < < height < < std : : endl ;
std : : cout < < " X = " < < X < < " \t Y= " < < Y < < " \t Z= " < < Z < < std : : endl ;
std : : cout < < " lat = " < < osg : : RadiansToDegrees ( newLat ) < < " \t long= " < < osg : : RadiansToDegrees ( newLong ) < < " \t " < < newHeight < < std : : endl ;
}
2003-11-25 19:40:10 +08:00
int main ( int argc , char * * argv )
2003-10-28 00:07:21 +08:00
{
2004-03-20 06:03:32 +08:00
2003-11-25 19:40:10 +08:00
// use an ArgumentParser object to manage the program arguments.
osg : : ArgumentParser arguments ( & argc , argv ) ;
2003-10-28 00:07:21 +08:00
2003-11-25 19:40:10 +08:00
// 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 ... " ) ;
arguments . getApplicationUsage ( ) - > addCommandLineOption ( " -d <filename> " , " Specify the digital elevation map input file to process " ) ;
arguments . getApplicationUsage ( ) - > addCommandLineOption ( " -t <filename> " , " Specify the texture map input file to process " ) ;
arguments . getApplicationUsage ( ) - > addCommandLineOption ( " -m <filename> " , " Specify the 3D database model input file to process " ) ;
arguments . getApplicationUsage ( ) - > addCommandLineOption ( " -o <outputfile> " , " Specify the output master file to generate " ) ;
arguments . getApplicationUsage ( ) - > addCommandLineOption ( " -l <numOfLevels> " , " Specify the number of PagedLOD levels to generate " ) ;
arguments . getApplicationUsage ( ) - > addCommandLineOption ( " -e <x> <y> <w> <h> " , " Extents of the model to generate " ) ;
arguments . getApplicationUsage ( ) - > addCommandLineOption ( " -h or --help " , " Display this information " ) ;
2004-03-12 06:04:41 +08:00
arguments . getApplicationUsage ( ) - > addCommandLineOption ( " --o_cs <coordinates system string> " , " Set the output coordinates system. The string may be any of the usual GDAL/OGR forms, complete WKT, PROJ.4, EPS " ) ;
2003-11-25 19:40:10 +08:00
if ( arguments . argc ( ) < = 1 )
2003-10-28 00:07:21 +08:00
{
2003-11-25 19:40:10 +08:00
arguments . getApplicationUsage ( ) - > write ( std : : cout , osg : : ApplicationUsage : : COMMAND_LINE_OPTION ) ;
return 1 ;
2003-10-28 00:07:21 +08:00
}
2003-11-25 19:40:10 +08:00
// create DataSet.
2004-03-12 00:14:25 +08:00
osg : : ref_ptr < osgTerrain : : DataSet > dataset = new osgTerrain : : DataSet ;
2003-10-28 00:07:21 +08:00
2003-11-25 19:40:10 +08:00
float x , y , w , h ;
while ( arguments . read ( " -e " , x , y , w , h ) )
2003-10-28 00:07:21 +08:00
{
2003-11-25 19:40:10 +08:00
dataset - > setDestinationExtents ( osg : : BoundingBox ( x , y , 0.0f , x + w , y + h , 0.0f ) ) ;
2003-10-28 00:07:21 +08:00
}
2004-01-29 23:47:06 +08:00
2004-03-29 18:45:58 +08:00
while ( arguments . read ( " --HEIGHT_FIELD " ) )
{
dataset - > setGeometryType ( osgTerrain : : DataSet : : HEIGHT_FIELD ) ;
}
while ( arguments . read ( " --POLYGONAL " ) )
{
dataset - > setGeometryType ( osgTerrain : : DataSet : : POLYGONAL ) ;
}
2004-03-15 23:47:22 +08:00
while ( arguments . read ( " --LOD " ) )
{
dataset - > setDatabaseType ( osgTerrain : : DataSet : : LOD_DATABASE ) ;
}
2004-01-29 23:47:06 +08:00
2004-03-15 23:47:22 +08:00
while ( arguments . read ( " --PagedLOD " ) )
{
dataset - > setDatabaseType ( osgTerrain : : DataSet : : PagedLOD_DATABASE ) ;
}
2003-10-28 00:07:21 +08:00
2003-11-25 19:40:10 +08:00
dataset - > setDestinationTileBaseName ( " output " ) ;
dataset - > setDestinationTileExtension ( " .ive " ) ;
2003-10-28 00:07:21 +08:00
2004-01-16 05:07:34 +08:00
float numLevels = 6.0f ;
2003-10-28 00:07:21 +08:00
while ( arguments . read ( " -l " , numLevels ) ) { }
2003-11-25 19:40:10 +08:00
float verticalScale ;
2004-03-12 00:14:25 +08:00
while ( arguments . read ( " -v " , verticalScale ) )
{
dataset - > setVerticalScale ( verticalScale ) ;
}
2003-10-28 00:07:21 +08:00
2003-10-29 19:11:17 +08:00
2003-10-28 00:07:21 +08:00
// if user request help write it out to cout.
if ( arguments . read ( " -h " ) | | arguments . read ( " --help " ) )
{
arguments . getApplicationUsage ( ) - > write ( std : : cout ) ;
return 1 ;
}
2004-03-20 06:03:32 +08:00
// read the input data
std : : string filename ;
std : : string currentCS ;
osg : : Matrixd geoTransform ;
bool geoTransformSet = false ;
2004-03-12 00:14:25 +08:00
2004-03-20 06:03:32 +08:00
int pos = 1 ;
while ( pos < arguments . argc ( ) )
2004-01-29 23:47:06 +08:00
{
2004-03-20 06:03:32 +08:00
std : : string def ;
2004-03-21 02:32:49 +08:00
osgTerrain : : DataSet : : Source * source = 0 ;
2004-03-20 06:03:32 +08:00
if ( arguments . read ( pos , " --cs " , def ) )
{
currentCS = ! def . empty ( ) ? SanitizeSRS ( def . c_str ( ) ) : " " ;
std : : cout < < " --cs " < < currentCS < < std : : endl ;
2004-03-20 06:20:35 +08:00
}
2004-04-01 19:03:39 +08:00
else if ( arguments . read ( pos , " --wkt " , def ) )
2004-03-30 06:26:51 +08:00
{
currentCS = def ;
2004-04-01 19:03:39 +08:00
std : : cout < < " --wkt " < < currentCS < < std : : endl ;
}
else if ( arguments . read ( pos , " --geocentric " ) )
{
dataset - > setConvertFromGeographicToGeocentric ( true ) ;
std : : cout < < " --geocentric " < < currentCS < < std : : endl ;
2004-03-30 06:26:51 +08:00
}
2004-03-21 02:32:49 +08:00
else if ( arguments . read ( pos , " --identity " ) )
2004-03-20 06:20:35 +08:00
{
geoTransformSet = false ;
geoTransform . makeIdentity ( ) ;
2004-03-20 06:03:32 +08:00
}
2004-03-21 20:17:44 +08:00
// x vector
2004-03-21 02:32:49 +08:00
else if ( arguments . read ( pos , " --xx " , geoTransform ( 0 , 0 ) ) )
2004-03-20 06:20:35 +08:00
{
geoTransformSet = true ;
2004-03-21 20:17:44 +08:00
std : : cout < < " --xx " < < geoTransform ( 0 , 0 ) < < std : : endl ;
}
else if ( arguments . read ( pos , " --xy " , geoTransform ( 1 , 0 ) ) )
{
geoTransformSet = true ;
std : : cout < < " --xy " < < geoTransform ( 1 , 0 ) < < std : : endl ;
}
else if ( arguments . read ( pos , " --xz " , geoTransform ( 2 , 0 ) ) )
{
geoTransformSet = true ;
std : : cout < < " --xz " < < geoTransform ( 2 , 0 ) < < std : : endl ;
2004-03-20 06:20:35 +08:00
}
2004-03-21 02:32:49 +08:00
else if ( arguments . read ( pos , " --xt " , geoTransform ( 3 , 0 ) ) )
2004-03-20 06:20:35 +08:00
{
geoTransformSet = true ;
std : : cout < < " --xo " < < geoTransform ( 3 , 0 ) < < std : : endl ;
}
2004-03-21 20:17:44 +08:00
// y vector
else if ( arguments . read ( pos , " --yx " , geoTransform ( 0 , 1 ) ) )
{
geoTransformSet = true ;
std : : cout < < " --yx " < < geoTransform ( 0 , 1 ) < < std : : endl ;
}
2004-03-21 02:32:49 +08:00
else if ( arguments . read ( pos , " --yy " , geoTransform ( 1 , 1 ) ) )
2004-03-20 06:20:35 +08:00
{
geoTransformSet = true ;
std : : cout < < " --yy " < < geoTransform ( 1 , 1 ) < < std : : endl ;
}
2004-03-21 20:17:44 +08:00
else if ( arguments . read ( pos , " --yz " , geoTransform ( 2 , 1 ) ) )
{
geoTransformSet = true ;
std : : cout < < " --yz " < < geoTransform ( 2 , 1 ) < < std : : endl ;
}
2004-03-21 02:32:49 +08:00
else if ( arguments . read ( pos , " --yt " , geoTransform ( 3 , 1 ) ) )
2004-03-20 06:20:35 +08:00
{
geoTransformSet = true ;
std : : cout < < " --yt " < < geoTransform ( 3 , 1 ) < < std : : endl ;
}
2004-03-21 20:17:44 +08:00
// z vector
else if ( arguments . read ( pos , " --zx " , geoTransform ( 0 , 2 ) ) )
{
geoTransformSet = true ;
std : : cout < < " --zx " < < geoTransform ( 0 , 2 ) < < std : : endl ;
}
else if ( arguments . read ( pos , " --zy " , geoTransform ( 1 , 2 ) ) )
{
geoTransformSet = true ;
std : : cout < < " --zy " < < geoTransform ( 1 , 2 ) < < std : : endl ;
}
2004-03-21 02:32:49 +08:00
else if ( arguments . read ( pos , " --zz " , geoTransform ( 2 , 2 ) ) )
2004-03-20 06:20:35 +08:00
{
geoTransformSet = true ;
std : : cout < < " --zz " < < geoTransform ( 2 , 2 ) < < std : : endl ;
}
2004-03-21 02:32:49 +08:00
else if ( arguments . read ( pos , " --zt " , geoTransform ( 3 , 2 ) ) )
2004-03-20 06:20:35 +08:00
{
geoTransformSet = true ;
std : : cout < < " --zt " < < geoTransform ( 3 , 2 ) < < std : : endl ;
}
2004-03-21 20:17:44 +08:00
2004-03-21 02:32:49 +08:00
else if ( arguments . read ( pos , " -d " , filename ) )
2004-03-20 06:03:32 +08:00
{
if ( ! filename . empty ( ) )
{
std : : cout < < " -d " < < filename < < std : : endl ;
source = new osgTerrain : : DataSet : : Source ( osgTerrain : : DataSet : : Source : : HEIGHT_FIELD , filename ) ;
}
}
2004-03-21 02:32:49 +08:00
else if ( arguments . read ( pos , " -t " , filename ) )
2004-03-20 06:03:32 +08:00
{
if ( ! filename . empty ( ) )
{
std : : cout < < " -t " < < filename < < std : : endl ;
source = new osgTerrain : : DataSet : : Source ( osgTerrain : : DataSet : : Source : : IMAGE , filename ) ;
}
}
2004-03-21 02:32:49 +08:00
else if ( arguments . read ( pos , " -m " , filename ) )
2004-03-20 06:03:32 +08:00
{
if ( ! filename . empty ( ) )
{
std : : cout < < " -m " < < filename < < std : : endl ;
source = new osgTerrain : : DataSet : : Source ( osgTerrain : : DataSet : : Source : : MODEL , filename ) ;
}
}
2004-03-21 02:32:49 +08:00
else if ( arguments . read ( pos , " -o " , filename ) )
{
std : : cout < < " -o " < < filename < < std : : endl ;
std : : string path = osgDB : : getFilePath ( filename ) ;
std : : string base = path . empty ( ) ? osgDB : : getStrippedName ( filename ) :
path + ' / ' + osgDB : : getStrippedName ( filename ) ;
std : : string extension = ' . ' + osgDB : : getLowerCaseFileExtension ( filename ) ;
dataset - > setDestinationTileBaseName ( base ) ;
dataset - > setDestinationTileExtension ( extension ) ;
if ( ! currentCS . empty ( ) ) dataset - > setDestinationCoordinateSystem ( currentCS ) ;
}
else
{
// if no argument read advance to next argument.
+ + pos ;
}
2004-03-20 06:03:32 +08:00
if ( source )
{
if ( ! currentCS . empty ( ) )
{
std : : cout < < " source->setCoordySystem " < < currentCS < < std : : endl ;
source - > setCoordinateSystemPolicy ( osgTerrain : : DataSet : : Source : : PREFER_CONFIG_SETTINGS ) ;
source - > setCoordinateSystem ( currentCS ) ;
}
if ( geoTransformSet )
{
std : : cout < < " source->setGeoTransform " < < geoTransform < < std : : endl ;
source - > setGeoTransformPolicy ( osgTerrain : : DataSet : : Source : : PREFER_CONFIG_SETTINGS ) ;
source - > setGeoTransform ( geoTransform ) ;
}
dataset - > addSource ( source ) ;
}
2004-01-29 23:47:06 +08:00
2004-03-20 06:03:32 +08:00
}
2004-01-29 23:47:06 +08:00
2003-10-28 00:07:21 +08:00
// 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 ;
}
2004-03-29 18:45:58 +08:00
// generate the database
{
GraphicsContext context ;
2003-10-28 00:07:21 +08:00
2004-03-29 18:45:58 +08:00
dataset - > loadSources ( ) ;
dataset - > createDestination ( ( unsigned int ) numLevels ) ;
dataset - > writeDestination ( ) ;
}
2003-10-28 00:07:21 +08:00
return 0 ;
}