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
Line 
1/*
2  SWWViewer
3
4  An OpenSceneGraph viewer for pyVolution SWW files.
5  copyright (C) 2004-2005 Geoscience Australia
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>
14#include <osgDB/FileNameUtils>
15
16#include <project.h>
17#include <SWWReader.h>
18#include <bedslope.h>
19#include <hud.h>
20#include <keyboardeventhandler.h>
21#include <directionallight.h>
22#include <state.h>
23#include <watersurface.h>
24#include <customviewer.h>
25
26
27// prototypes
28osg::Transform* createSky(float radius, const std::string filename);
29extern const char* version();
30
31
32int main( int argc, char **argv )
33{
34
35   // use an ArgumentParser object to manage the program arguments
36   osg::ArgumentParser arguments( &argc, argv );
37
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");
54
55   // construct the viewer.
56   CustomViewer viewer(arguments);
57
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 );
63
64
65   // get details on keyboard and mouse bindings used by the viewer
66   viewer.getUsage(*arguments.getApplicationUsage());
67
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   }
74
75   // same for version info
76   if( arguments.read("-version") )
77   {
78      std::cout << version() << std::endl;
79      return 1;
80   }
81
82
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   }
99
100
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]) );
106
107
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 );
117
118   std::string bedslopetexture;
119   if( arguments.read("-texture",bedslopetexture) ) sww->setBedslopeTexture( bedslopetexture );
120
121   // root node
122   osg::Group* rootnode = new osg::Group;
123
124   // transform
125   osg::PositionAttitudeTransform* model = new osg::PositionAttitudeTransform;
126   model->setName("position_attitude_transform");
127
128   // enscapsulates OpenGL state
129   osg::StateSet* rootStateSet = new osg::StateSet;
130
131   // Bedslope geometry
132   BedSlope* bedslope = new BedSlope(sww);
133
134   // Water geometry
135   WaterSurface* water = new WaterSurface(sww);
136
137   // Heads Up Display (text overlay)
138   HeadsUpDisplay* hud = new HeadsUpDisplay();
139   hud->setTitle("pyVolution SWW Viewer");
140
141
142   // Lighting
143   DirectionalLight* light = new DirectionalLight(rootStateSet);
144   light->setPosition( osg::Vec3(1,1,1) );  // z is up
145
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   }
154
155
156
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() );
164
165
166   // allow vertical scaling from command line parameter
167   model->setScale( osg::Vec3(1.0, 1.0, vscale) );
168
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);
176 
177   // any option left unread are converted into errors to write out later.
178   arguments.reportRemainingOptionsAsUnrecognized();
179 
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   }
186
187
188   // register additional event handler
189   KeyboardEventHandler* event_handler = new KeyboardEventHandler(sww->getNumberOfTimesteps(), tps);
190   viewer.getEventHandlerList().push_front(event_handler);
191
192 
193   // create the windows and run the threads.
194   viewer.realize();
195
196
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();
207
208
209   // animation
210   State s = State();
211   std::vector<State> statelist;
212   bool recordingmode = false;
213   bool playbackmode = false;
214   unsigned int playback_index = 0;
215
216
217 
218   unsigned int timestep = 0;
219   while( !viewer.done() )
220   {
221   
222      // wait for all cull and draw threads to complete.
223      viewer.sync();
224
225
226      if( !playbackmode )
227      {
228
229         // current time
230         double time = viewer.getFrameStamp()->getReferenceTime();
231
232
233         event_handler->setTime( time );
234         timestep = event_handler->getTimestep();
235         water->setTimeStep(timestep);
236         hud->setTime( sww->getTime(timestep) );
237
238
239         // events
240         if( event_handler->toggleWireframe() )
241            water->toggleWireframe();
242
243         if( event_handler->toggleCulling() )
244         {
245            sww->toggleCulling();
246            water->setTimeStep(timestep);  // refresh
247         }
248
249
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         }
265
266
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         }
288
289
290         if( recordingmode )
291         {
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;
300         }
301      }
302
303      else
304
305      {
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;
317      }
318
319
320
321      // update the scene by traversing with the update visitor
322      viewer.update();
323
324      // fire off the cull and draw traversals of the scene.
325      viewer.frame();
326   }
327   
328   // wait for all cull and draw threads to complete before exit.
329   viewer.sync();
330
331   return 0;
332}
Note: See TracBrowser for help on using the repository browser.