source: Swollen/swollen/main.cpp @ 115

Last change on this file since 115 was 115, checked in by darran, 20 years ago
File size: 10.7 KB
RevLine 
[6]1/*
[106]2  SWWViewer
[6]3
[106]4  An OpenSceneGraph viewer for pyVolution SWW files.
5  copyright (C) 2004-2005 Geoscience Australia
[6]6*/
7
8#include <osg/Group>
9#include <osg/Material>
10#include <osg/MatrixTransform>
11#include <osg/Notify>
12#include <osg/PositionAttitudeTransform>
13#include <osg/StateAttribute>
[106]14#include <osgDB/FileNameUtils>
[6]15
16#include <project.h>
17#include <SWWReader.h>
18#include <bedslope.h>
19#include <hud.h>
20#include <keyboardeventhandler.h>
[72]21#include <directionallight.h>
[113]22#include <state.h>
[6]23#include <watersurface.h>
[92]24#include <customviewer.h>
[6]25
26
27// prototypes
[106]28osg::Transform* createSky(float radius, const std::string filename);
[67]29extern const char* version();
[6]30
31
32int main( int argc, char **argv )
33{
[37]34
[106]35   // use an ArgumentParser object to manage the program arguments
36   osg::ArgumentParser arguments( &argc, argv );
[6]37
[106]38   // set up the usage document
39   std::string appname = arguments.getApplicationName();
40   arguments.getApplicationUsage()->setDescription( appname );
41   arguments.getApplicationUsage()->setCommandLineUsage("swollen [options] swwfile ...");
42   arguments.getApplicationUsage()->addCommandLineOption("-help","Display this information");
43   arguments.getApplicationUsage()->addCommandLineOption("-scale <float>","Vertical scale factor");
44   arguments.getApplicationUsage()->addCommandLineOption("-tps <rate>","Timesteps per second");
45   arguments.getApplicationUsage()->addCommandLineOption("-hmin <float>","Height below which transparency is set to zero");
46   arguments.getApplicationUsage()->addCommandLineOption("-hmax <float>","Height above which transparency is set to alphamax");
47   arguments.getApplicationUsage()->addCommandLineOption("-alphamin <float 0-1>","Transparency value at hmin");
48   arguments.getApplicationUsage()->addCommandLineOption("-alphamax <float 0-1>","Maximum transparency clamp value");
49   arguments.getApplicationUsage()->addCommandLineOption("-lightpos <float>,<float>,<float>","x,y,z of bedslope directional light (z is up, default is overhead)");
50   arguments.getApplicationUsage()->addCommandLineOption("-nosky","Omit background sky");
51   arguments.getApplicationUsage()->addCommandLineOption("-cullangle <float angle 0-90>","Cull triangles steeper than this value");
52   arguments.getApplicationUsage()->addCommandLineOption("-texture <file>","Image to use for bedslope topography");
53   arguments.getApplicationUsage()->addCommandLineOption("-version","Revision number and creation (not compile) date");
[38]54
[106]55   // construct the viewer.
56   CustomViewer viewer(arguments);
[6]57
[106]58   // set up with sensible default event handlers
59   viewer.setUpViewer( osgProducer::Viewer::STANDARD_SETTINGS );
60   viewer.setClearColor( osg::Vec4(DEF_BACKGROUND_COLOUR) );
61   //viewer.getCamera(0)->getRenderSurface()->setWindowRectangle(200,300,400,300);
62   viewer.getCullSettings().setComputeNearFarMode( osg::CullSettings::COMPUTE_NEAR_FAR_USING_PRIMITIVES );
[6]63
64
[106]65   // get details on keyboard and mouse bindings used by the viewer
66   viewer.getUsage(*arguments.getApplicationUsage());
[6]67
[106]68   // if user requested help, write it out to cout
69   if( arguments.read("-help") )
70   {
71      arguments.getApplicationUsage()->write(std::cout);
72      return 1;
73   }
[6]74
[106]75   // same for version info
76   if( arguments.read("-version") )
77   {
78      std::cout << version() << std::endl;
79      return 1;
80   }
[6]81
[66]82
[106]83   // load sww file specified as final argument on command line (static bedslope
84   // geometry only, per timestep height field geometry is done in loop below)
85   int lastarg = arguments.argc()-1;
86   std::string swwfile = arguments.argv()[lastarg];
87   arguments.remove(lastarg);
88   if( swwfile.substr(swwfile.size()-4,4).find(".sww",0) == -1 )  // ensure filename ends in .sww
89   {
90      std::cout << "Require last argument be an .sww file ... quitting" << std::endl;
91      return 1; 
92   }
93   SWWReader *sww = new SWWReader(swwfile);
94   if (sww->isValid() == false)
95   {
96      std::cout << "Unable to load " << swwfile << " ... is this really an .sww file?" << std::endl;
97      return 1;
98   }
[6]99
100
[106]101   // relative directory to swollen binary
102   if( osgDB::getFilePath(argv[0]) == "" )
103      sww->setSwollenDir( std::string(".") );
104   else
105      sww->setSwollenDir( osgDB::getFilePath(argv[0]) );
[6]106
[74]107
[106]108   // default arguments and command line parameters
109   float tmpfloat, tps, vscale;
110   if( !arguments.read("-tps", tps) || tps <= 0.0 ) tps = DEF_TPS;
111   if( !arguments.read("-scale", vscale) ) vscale = 1.0;
112   if( arguments.read("-hmin",tmpfloat) ) sww->setHeightMin( tmpfloat ); 
113   if( arguments.read("-hmax",tmpfloat) ) sww->setHeightMax( tmpfloat );     
114   if( arguments.read("-alphamin",tmpfloat) ) sww->setAlphaMin( tmpfloat );   
115   if( arguments.read("-alphamax",tmpfloat) ) sww->setAlphaMax( tmpfloat );
116   if( arguments.read("-cullangle",tmpfloat) ) sww->setCullAngle( tmpfloat );
[6]117
[106]118   std::string bedslopetexture;
119   if( arguments.read("-texture",bedslopetexture) ) sww->setBedslopeTexture( bedslopetexture );
[6]120
[106]121   // root node
122   osg::Group* rootnode = new osg::Group;
[6]123
[106]124   // transform
125   osg::PositionAttitudeTransform* model = new osg::PositionAttitudeTransform;
126   model->setName("position_attitude_transform");
[6]127
[106]128   // enscapsulates OpenGL state
129   osg::StateSet* rootStateSet = new osg::StateSet;
[6]130
[106]131   // Bedslope geometry
132   BedSlope* bedslope = new BedSlope(sww);
[6]133
[106]134   // Water geometry
135   WaterSurface* water = new WaterSurface(sww);
[45]136
[106]137   // Heads Up Display (text overlay)
138   HeadsUpDisplay* hud = new HeadsUpDisplay();
139   hud->setTitle("pyVolution SWW Viewer");
[6]140
[45]141
[106]142   // Lighting
143   DirectionalLight* light = new DirectionalLight(rootStateSet);
144   light->setPosition( osg::Vec3(1,1,1) );  // z is up
[100]145
[106]146   std::string lightposstr;
147   while (arguments.read("-lightpos",lightposstr))
148   {
149      float x, y, z;
150      int count = sscanf( lightposstr.c_str(), "%f,%f,%f", &x, &y, &z );
151      if( count == 3 ) light->setPosition( osg::Vec3(x,y,z) );  // z is up
152      else osg::notify(osg::WARN) << "Invalid bedslope light position \"" << lightposstr << "\"" << std::endl;
153   }
[100]154
[6]155
[11]156
[106]157   // scenegraph hierarchy
158   rootnode->setStateSet(rootStateSet);
159   rootnode->addChild( hud->get() );
160   rootnode->addChild( light->get() );
161   rootnode->addChild(model);
162   model->addChild( bedslope->get() );
163   model->addChild( water->get() );
[11]164
[6]165
[106]166   // allow vertical scaling from command line parameter
167   model->setScale( osg::Vec3(1.0, 1.0, vscale) );
[6]168
[106]169   // surrounding sky sphere
170   if( !arguments.read("-nosky") )
171      rootnode->addChild( createSky(10.0, sww->getSwollenDir() + std::string("/sky_small.jpg") ));
172
173
174   // add model to viewer.
175   viewer.setSceneData(rootnode);
[6]176 
[106]177   // any option left unread are converted into errors to write out later.
178   arguments.reportRemainingOptionsAsUnrecognized();
[6]179 
[106]180   // report any errors if they have occured when parsing the program aguments.
181   if (arguments.errors())
182   {
183      arguments.writeErrorMessages(std::cout);
184      return 1;
185   }
[6]186
[111]187
[106]188   // register additional event handler
189   KeyboardEventHandler* event_handler = new KeyboardEventHandler(sww->getNumberOfTimesteps(), tps);
190   viewer.getEventHandlerList().push_front(event_handler);
[45]191
[6]192 
[106]193   // create the windows and run the threads.
194   viewer.realize();
[6]195
196
[106]197   // initial camera position
198   CustomTerrainManipulator* terrainmanipulator = viewer.getTerrainManipulator();
199   terrainmanipulator->setNode( model );
200   terrainmanipulator->setAutoComputeHomePosition( false );
201   terrainmanipulator->setHomePosition(
202      osg::Vec3d(0,-3,3),    // camera location
203      osg::Vec3d(0,0,0),     // camera target
204      osg::Vec3d(0,1,1) );   // camera up vector
205   terrainmanipulator->moveToHome();
206   terrainmanipulator->enable();
[66]207
208
[115]209   // animation
210   State s = State();
211   std::vector<State> statelist;
[111]212   bool recordingmode = false;
[115]213   bool playbackmode = false;
214   unsigned int playback_index = 0;
[111]215
216
[114]217 
[106]218   unsigned int timestep = 0;
219   while( !viewer.done() )
220   {
[71]221   
[106]222      // wait for all cull and draw threads to complete.
223      viewer.sync();
[6]224
[105]225
[115]226      if( !playbackmode )
227      {
[6]228
[115]229         // current time
230         double time = viewer.getFrameStamp()->getReferenceTime();
231
232
233         event_handler->setTime( time );
[106]234         timestep = event_handler->getTimestep();
235         water->setTimeStep(timestep);
236         hud->setTime( sww->getTime(timestep) );
[66]237
[13]238
[115]239         // events
240         if( event_handler->toggleWireframe() )
241            water->toggleWireframe();
[104]242
[115]243         if( event_handler->toggleCulling() )
244         {
245            sww->toggleCulling();
246            water->setTimeStep(timestep);  // refresh
247         }
[111]248
249
[115]250         // '1' key starts/stops recording of view/position/setting info
251         if( event_handler->toggleRecording() )
252         {
253            switch( recordingmode )
254            {
255               case false : 
256                  recordingmode = true; 
257                  hud->setRecordingMode("recording");
258                  break;
259               case true : 
260                  recordingmode = false; 
261                  hud->setRecordingMode("");
262                  break;
263            }
264         }
[111]265
266
[115]267         // '2' key starts playback of recorded frames
268         if( event_handler->togglePlayback() )
269         {
270            recordingmode = false;
271            switch( playbackmode )
272            {
273               case false : 
274                  playbackmode = true; 
275                  hud->setRecordingMode("playback");
276                  event_handler->setPaused( true );
277                  playback_index = 0;
278                  // store current state
279                  break;
280               case true : 
281                  playbackmode = false; 
282                  hud->setRecordingMode("");
283                  event_handler->setPaused( false );
284                  // pop saved state
285                  break;
286            }
287         }
[111]288
289
[115]290         if( recordingmode )
[111]291         {
[115]292            s.setTimestep( event_handler->getTimestep() );
293            s.setTime( sww->getTime(timestep) );
294            s.setCulling( sww->getCulling() );
295            s.setWireframe( water->getWireframe() );
296            s.setPosition( viewer.getPosition() );
297            s.setOrientation( viewer.getOrientation() );
298            statelist.push_back( s );
299            std::cout << "len(statelist): " << statelist.size() << std::endl;
[111]300         }
301      }
302
[115]303      else
304
[114]305      {
[115]306         // in playback mode
307         s = statelist.at( playback_index );
308         water->setTimeStep( s.getTimestep() );
309         hud->setTime( s.getTime() );
310
311         std::cout << "playing back: " << playback_index << std::endl;
312
313         // loop playback
314         playback_index ++;
315         if( playback_index == statelist.size() )
316            playback_index = 0;
[114]317      }
[111]318
[113]319
[114]320
[106]321      // update the scene by traversing with the update visitor
322      viewer.update();
[115]323
[106]324      // fire off the cull and draw traversals of the scene.
325      viewer.frame();
326   }
[6]327   
[106]328   // wait for all cull and draw threads to complete before exit.
329   viewer.sync();
[6]330
[106]331   return 0;
[6]332}
Note: See TracBrowser for help on using the repository browser.