/* SWWViewer An OpenSceneGraph viewer for pyVolution SWW files. copyright (C) 2004-2005 Geoscience Australia */ #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("-lightpos ,,","x,y,z of bedslope directional light (default is overhead)"); 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,300,400,300); 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 tmpfloat, tps, vscale; if( !arguments.read("-tps", tps) || tps <= 0.0 ) tps = DEF_TPS; if( !arguments.read("-scale", vscale) ) vscale = 1.0; 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 ); std::string bedslopetexture; if( arguments.read("-texture",bedslopetexture) ) sww->setBedslopeTexture( bedslopetexture ); // 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 DirectionalLight* light = new DirectionalLight(rootStateSet); light->setPosition( osg::Vec3(0,0,2) ); // z is up std::string lightposstr; while (arguments.read("-lightpos",lightposstr)) { float x, y, z; int count = sscanf( lightposstr.c_str(), "%f,%f,%f", &x, &y, &z ); if( count == 3 ) light->setPosition( osg::Vec3(x,y,z) ); // z is up else osg::notify(osg::WARN) << "Invalid bedslope light position \"" << lightposstr << "\"" << std::endl; } // scenegraph hierarchy rootnode->setStateSet(rootStateSet); rootnode->addChild( hud->get() ); rootnode->addChild( light->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 CustomTerrainManipulator* terrainmanipulator = viewer.getTerrainManipulator(); terrainmanipulator->setNode( model ); terrainmanipulator->setAutoComputeHomePosition( false ); terrainmanipulator->setHomePosition( osg::Vec3d(0,-3,3), // camera location osg::Vec3d(0,0,0), // camera target osg::Vec3d(0,1,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) ); } // events if( event_handler->toggleWireframe() ) water->toggleWireframe(); // 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; }