/* SWWViewer An OpenSceneGraph viewer for pyVolution SWW files. copyright (C) 2004 Geoscience Australia */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include // prototypes osg::Transform* createSky(float radius, char* filename); extern const char* version(); 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 std::string appname = arguments.getApplicationName(); arguments.getApplicationUsage()->setDescription( appname ); arguments.getApplicationUsage()->setCommandLineUsage("swollen [options] swwfile ..."); arguments.getApplicationUsage()->addCommandLineOption("-help","Display this information"); arguments.getApplicationUsage()->addCommandLineOption("-scale ","Vertical scale factor"); arguments.getApplicationUsage()->addCommandLineOption("-tps ","Timesteps per second"); arguments.getApplicationUsage()->addCommandLineOption("-hmin ","Height below which transparency is set to zero"); arguments.getApplicationUsage()->addCommandLineOption("-hmax ","Height above which transparency is set to alphamax"); arguments.getApplicationUsage()->addCommandLineOption("-alphamin ","Transparency value at hmin"); arguments.getApplicationUsage()->addCommandLineOption("-alphamax ","Maximum transparency clamp value"); arguments.getApplicationUsage()->addCommandLineOption("-nosky","Omit background sky"); arguments.getApplicationUsage()->addCommandLineOption("-texture ","Image to use for bedslope topography"); arguments.getApplicationUsage()->addCommandLineOption("-version","Revision number and creation (not compile) date"); // construct the viewer. CustomViewer viewer(arguments); // set up with sensible default event handlers viewer.setUpViewer( osgProducer::Viewer::STANDARD_SETTINGS ); viewer.setClearColor( osg::Vec4(DEF_BACKGROUND_COLOUR) ); viewer.getCamera(0)->getRenderSurface()->setWindowRectangle(200,100,800,600); viewer.getCullSettings().setComputeNearFarMode( osg::CullSettings::COMPUTE_NEAR_FAR_USING_PRIMITIVES ); // get details on keyboard and mouse bindings used by the viewer viewer.getUsage(*arguments.getApplicationUsage()); // if user requested help, write it out to cout if( arguments.read("-help") ) { arguments.getApplicationUsage()->write(std::cout); return 1; } // same for version info if( arguments.read("-version") ) { std::cout << version() << std::endl; return 1; } // load sww file specified as final argument on command line (static bedslope // geometry only, per timestep height field geometry is done in loop below) int lastarg = arguments.argc()-1; std::string swwfile = arguments.argv()[lastarg]; arguments.remove(lastarg); if( swwfile.substr(swwfile.size()-4,4).find(".sww",0) == -1 ) // ensure filename ends in .sww { std::cout << "Require last argument be an .sww file ... quitting" << std::endl; return 1; } SWWReader *sww = new SWWReader(swwfile); if (sww->isValid() == false) { std::cout << "Unable to load " << swwfile << " ... is this really an .sww file?" << std::endl; return 1; } // default arguments and command line parameters float tps; if( !arguments.read("-tps",tps) || tps <= 0.0 ) tps = DEF_TPS; float vscale; if( !arguments.read("-scale",vscale) ) vscale = 1.0; std::string bedslopetexture; if( arguments.read("-texture",bedslopetexture) ) sww->setBedslopeTexture( bedslopetexture ); float tmpfloat; if( arguments.read("-hmin",tmpfloat) ) sww->setHeightMin( tmpfloat ); if( arguments.read("-hmax",tmpfloat) ) sww->setHeightMax( tmpfloat ); if( arguments.read("-alphamin",tmpfloat) ) sww->setAlphaMin( tmpfloat ); if( arguments.read("-alphamax",tmpfloat) ) sww->setAlphaMax( tmpfloat ); // root node osg::Group* rootnode = new osg::Group; // transform osg::PositionAttitudeTransform* model = new osg::PositionAttitudeTransform; model->setName("position_attitude_transform"); // enscapsulates OpenGL state osg::StateSet* rootStateSet = new osg::StateSet; // Bedslope geometry BedSlope* bedslope = new BedSlope(sww); // Water geometry WaterSurface* water = new WaterSurface(sww); // Heads Up Display (text overlay) HeadsUpDisplay* hud = new HeadsUpDisplay(); hud->setTitle("pyVolution SWW Viewer"); // Lighting SpotLight* spotlight = new SpotLight(rootStateSet); spotlight->setPosition( osg::Vec3(0,1,0) ); // z is up spotlight->setSpotAngle( 45.0 ); // scenegraph hierarchy rootnode->setStateSet(rootStateSet); rootnode->addChild( hud->get() ); rootnode->addChild( spotlight->get() ); rootnode->addChild(model); model->addChild( bedslope->get() ); model->addChild( water->get() ); // allow vertical scaling from command line parameter model->setScale( osg::Vec3(1.0, 1.0, vscale) ); // surrounding sky sphere if( !arguments.read("-nosky") ) rootnode->addChild( createSky(10.0, "sky_small.jpg") ); // add model to viewer. viewer.setSceneData(rootnode); // 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; } // register additional event handler KeyboardEventHandler* event_handler = new KeyboardEventHandler(sww->getNumberOfTimesteps(), tps); viewer.getEventHandlerList().push_front(event_handler); // create the windows and run the threads. viewer.realize(); // initial camera position CustomTrackballManipulator* trackball = viewer.getTrackball(); trackball->setNode( model ); trackball->setAutoComputeHomePosition( false ); trackball->setHomePosition( osg::Vec3d(0,1,0), // location osg::Vec3d(0,0,0), // target osg::Vec3d(0,0,1) ); // up vector trackball->moveToHome(); trackball->disable(); CustomTerrainManipulator* terrainmanipulator = viewer.getTerrainManipulator(); terrainmanipulator->setNode( rootnode ); terrainmanipulator->setAutoComputeHomePosition( false ); terrainmanipulator->setHomePosition( osg::Vec3d(0,-3,0), // camera location osg::Vec3d(0,0,0), // camera target osg::Vec3d(0,0,1) ); // camera up vector terrainmanipulator->moveToHome(); terrainmanipulator->enable(); unsigned int timestep = 0; while( !viewer.done() ) { // wait for all cull and draw threads to complete. viewer.sync(); // current time double time = viewer.getFrameStamp()->getReferenceTime(); // advance sww frame? event_handler->setTime( time ); if( event_handler->timestepChanged() ) { timestep = event_handler->getTimestep(); water->setTimeStep(timestep); hud->setTime( sww->getTime(timestep) ); } // light position manipulator if( trackball->isEnabled() ) { //osg::Matrixd matrix = trackball->getInverseMatrix(); osg::Matrixd matrix = trackball->getMatrix(); osg::Vec3d position = matrix.getTrans(); //std::cout << "trackball position x: " << position. << std::endl; spotlight->setPosition( position ); } // events if( event_handler->toggleWireframe() ) water->toggleWireframe(); // click-mouse movement can change either camera view or scene light position if( event_handler->toggleManipulatorMode() ) { if( trackball->isEnabled() ) { trackball->disable(); terrainmanipulator->enable(); } else { trackball->enable(); terrainmanipulator->disable(); } } // update the scene by traversing with the update visitor viewer.update(); // fire off the cull and draw traversals of the scene. viewer.frame(); } // wait for all cull and draw threads to complete before exit. viewer.sync(); return 0; }