Changeset 106


Ignore:
Timestamp:
Jun 14, 2005, 1:28:07 PM (20 years ago)
Author:
darran
Message:
  • bugfix relating to relative path name in bedslope texture
  • added fixes for envmap and sky
Location:
Swollen
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • Swollen/include/swwreader.h

    r105 r106  
    103103    virtual triangle_list getConnectivity(unsigned int index) {return _connectivity.at(index);}
    104104
     105    const std::string getSwollenDir() {return *_swollendir;}
     106    virtual void setSwollenDir(const std::string path) {_swollendir = new std::string(path);}
     107
    105108
    106109protected:
     
    109112
    110113    std::string* _filename;
     114    std::string* _swollendir;
    111115   
    112116    // constructor determines SWW validity (netcdf + proper structure)
  • Swollen/swollen/createSky.cpp

    r65 r106  
    4444
    4545
    46 osg::Transform* createSky(float radius, char* filename)
     46osg::Transform* createSky(float radius, const std::string filename)
    4747{
    4848    osg::Geode* geode = new osg::Geode;
     
    5353    texture->setDataVariance(osg::Object::DYNAMIC);  // protect from being optimized away as static state.
    5454    texture->setWrap(osg::Texture::WRAP_S, osg::Texture::REPEAT);
    55     texture->setImage(osgDB::readImageFile(filename));
     55    texture->setImage(osgDB::readImageFile(filename.c_str()));
    5656   
    5757    osg::StateSet* stateset = new osg::StateSet;
  • Swollen/swollen/main.cpp

    r105 r106  
    11/*
    2     SWWViewer
    3 
    4     An OpenSceneGraph viewer for pyVolution SWW files.
    5     copyright (C) 2004-2005 Geoscience Australia
     2  SWWViewer
     3
     4  An OpenSceneGraph viewer for pyVolution SWW files.
     5  copyright (C) 2004-2005 Geoscience Australia
    66*/
    77
     
    1212#include <osg/PositionAttitudeTransform>
    1313#include <osg/StateAttribute>
     14#include <osgDB/FileNameUtils>
    1415
    1516#include <project.h>
     
    2425
    2526// prototypes
    26 osg::Transform* createSky(float radius, char* filename);
     27osg::Transform* createSky(float radius, const std::string filename);
    2728extern const char* version();
    2829
     
    3132{
    3233
    33     // use an ArgumentParser object to manage the program arguments
    34     osg::ArgumentParser arguments(&argc,argv);
    35 
    36     // set up the usage document
    37     std::string appname = arguments.getApplicationName();
    38     arguments.getApplicationUsage()->setDescription( appname );
    39     arguments.getApplicationUsage()->setCommandLineUsage("swollen [options] swwfile ...");
    40     arguments.getApplicationUsage()->addCommandLineOption("-help","Display this information");
    41     arguments.getApplicationUsage()->addCommandLineOption("-scale <float>","Vertical scale factor");
    42     arguments.getApplicationUsage()->addCommandLineOption("-tps <rate>","Timesteps per second");
    43     arguments.getApplicationUsage()->addCommandLineOption("-hmin <float>","Height below which transparency is set to zero");
    44     arguments.getApplicationUsage()->addCommandLineOption("-hmax <float>","Height above which transparency is set to alphamax");
    45     arguments.getApplicationUsage()->addCommandLineOption("-alphamin <float 0-1>","Transparency value at hmin");
    46     arguments.getApplicationUsage()->addCommandLineOption("-alphamax <float 0-1>","Maximum transparency clamp value");
    47     arguments.getApplicationUsage()->addCommandLineOption("-lightpos <float>,<float>,<float>","x,y,z of bedslope directional light (z is up, default is overhead)");
    48     arguments.getApplicationUsage()->addCommandLineOption("-nosky","Omit background sky");
    49     arguments.getApplicationUsage()->addCommandLineOption("-cullangle <float angle 0-90>","Cull triangles steeper than this value");
    50     arguments.getApplicationUsage()->addCommandLineOption("-texture <file>","Image to use for bedslope topography");
    51     arguments.getApplicationUsage()->addCommandLineOption("-version","Revision number and creation (not compile) date");
    52 
    53     // construct the viewer.
    54     CustomViewer viewer(arguments);
    55 
    56     // set up with sensible default event handlers
    57     viewer.setUpViewer( osgProducer::Viewer::STANDARD_SETTINGS );
    58     viewer.setClearColor( osg::Vec4(DEF_BACKGROUND_COLOUR) );
    59     //viewer.getCamera(0)->getRenderSurface()->setWindowRectangle(200,300,400,300);
    60     viewer.getCullSettings().setComputeNearFarMode( osg::CullSettings::COMPUTE_NEAR_FAR_USING_PRIMITIVES );
    61 
    62 
    63     // get details on keyboard and mouse bindings used by the viewer
    64     viewer.getUsage(*arguments.getApplicationUsage());
    65 
    66     // if user requested help, write it out to cout
    67     if( arguments.read("-help") )
    68     {
    69         arguments.getApplicationUsage()->write(std::cout);
    70         return 1;
    71     }
    72 
    73     // same for version info
    74     if( arguments.read("-version") )
    75     {
    76         std::cout << version() << std::endl;
    77         return 1;
    78     }
    79 
    80 
    81     // load sww file specified as final argument on command line (static bedslope
    82     // geometry only, per timestep height field geometry is done in loop below)
    83     int lastarg = arguments.argc()-1;
    84     std::string swwfile = arguments.argv()[lastarg];
    85     arguments.remove(lastarg);
    86     if( swwfile.substr(swwfile.size()-4,4).find(".sww",0) == -1 )  // ensure filename ends in .sww
    87     {
    88         std::cout << "Require last argument be an .sww file ... quitting" << std::endl;
    89         return 1;
    90     }
    91     SWWReader *sww = new SWWReader(swwfile);
    92     if (sww->isValid() == false)
    93     {
    94         std::cout << "Unable to load " << swwfile << " ... is this really an .sww file?" << std::endl;
    95         return 1;
    96     }
    97 
    98 
    99     // default arguments and command line parameters
    100     float tmpfloat, tps, vscale;
    101     if( !arguments.read("-tps", tps) || tps <= 0.0 ) tps = DEF_TPS;
    102     if( !arguments.read("-scale", vscale) ) vscale = 1.0;
    103     if( arguments.read("-hmin",tmpfloat) ) sww->setHeightMin( tmpfloat ); 
    104     if( arguments.read("-hmax",tmpfloat) ) sww->setHeightMax( tmpfloat );     
    105     if( arguments.read("-alphamin",tmpfloat) ) sww->setAlphaMin( tmpfloat );   
    106     if( arguments.read("-alphamax",tmpfloat) ) sww->setAlphaMax( tmpfloat );
    107     if( arguments.read("-cullangle",tmpfloat) ) sww->setCullAngle( tmpfloat );
    108 
    109     std::string bedslopetexture;
    110     if( arguments.read("-texture",bedslopetexture) ) sww->setBedslopeTexture( bedslopetexture );
    111 
    112     // root node
    113     osg::Group* rootnode = new osg::Group;
    114 
    115     // transform
    116     osg::PositionAttitudeTransform* model = new osg::PositionAttitudeTransform;
    117     model->setName("position_attitude_transform");
    118 
    119     // enscapsulates OpenGL state
    120     osg::StateSet* rootStateSet = new osg::StateSet;
    121 
    122     // Bedslope geometry
    123     BedSlope* bedslope = new BedSlope(sww);
    124 
    125     // Water geometry
    126     WaterSurface* water = new WaterSurface(sww);
    127 
    128     // Heads Up Display (text overlay)
    129     HeadsUpDisplay* hud = new HeadsUpDisplay();
    130     hud->setTitle("pyVolution SWW Viewer");
    131 
    132 
    133     // Lighting
    134     DirectionalLight* light = new DirectionalLight(rootStateSet);
    135     light->setPosition( osg::Vec3(1,1,1) );  // z is up
    136 
    137     std::string lightposstr;
    138     while (arguments.read("-lightpos",lightposstr))
    139     {
    140         float x, y, z;
    141         int count = sscanf( lightposstr.c_str(), "%f,%f,%f", &x, &y, &z );
    142         if( count == 3 ) light->setPosition( osg::Vec3(x,y,z) );  // z is up
    143         else osg::notify(osg::WARN) << "Invalid bedslope light position \"" << lightposstr << "\"" << std::endl;
    144     }
    145 
    146 
    147 
    148     // scenegraph hierarchy
    149     rootnode->setStateSet(rootStateSet);
    150     rootnode->addChild( hud->get() );
    151     rootnode->addChild( light->get() );
    152     rootnode->addChild(model);
    153     model->addChild( bedslope->get() );
    154     model->addChild( water->get() );
    155 
    156 
    157     // allow vertical scaling from command line parameter
    158     model->setScale( osg::Vec3(1.0, 1.0, vscale) );
    159 
    160     // surrounding sky sphere
    161     if( !arguments.read("-nosky") )
    162       rootnode->addChild( createSky(10.0, "sky_small.jpg") );
    163 
    164 
    165     // add model to viewer.
    166     viewer.setSceneData(rootnode);
     34   // use an ArgumentParser object to manage the program arguments
     35   osg::ArgumentParser arguments( &argc, argv );
     36
     37   // set up the usage document
     38   std::string appname = arguments.getApplicationName();
     39   arguments.getApplicationUsage()->setDescription( appname );
     40   arguments.getApplicationUsage()->setCommandLineUsage("swollen [options] swwfile ...");
     41   arguments.getApplicationUsage()->addCommandLineOption("-help","Display this information");
     42   arguments.getApplicationUsage()->addCommandLineOption("-scale <float>","Vertical scale factor");
     43   arguments.getApplicationUsage()->addCommandLineOption("-tps <rate>","Timesteps per second");
     44   arguments.getApplicationUsage()->addCommandLineOption("-hmin <float>","Height below which transparency is set to zero");
     45   arguments.getApplicationUsage()->addCommandLineOption("-hmax <float>","Height above which transparency is set to alphamax");
     46   arguments.getApplicationUsage()->addCommandLineOption("-alphamin <float 0-1>","Transparency value at hmin");
     47   arguments.getApplicationUsage()->addCommandLineOption("-alphamax <float 0-1>","Maximum transparency clamp value");
     48   arguments.getApplicationUsage()->addCommandLineOption("-lightpos <float>,<float>,<float>","x,y,z of bedslope directional light (z is up, default is overhead)");
     49   arguments.getApplicationUsage()->addCommandLineOption("-nosky","Omit background sky");
     50   arguments.getApplicationUsage()->addCommandLineOption("-cullangle <float angle 0-90>","Cull triangles steeper than this value");
     51   arguments.getApplicationUsage()->addCommandLineOption("-texture <file>","Image to use for bedslope topography");
     52   arguments.getApplicationUsage()->addCommandLineOption("-version","Revision number and creation (not compile) date");
     53
     54   // construct the viewer.
     55   CustomViewer viewer(arguments);
     56
     57   // set up with sensible default event handlers
     58   viewer.setUpViewer( osgProducer::Viewer::STANDARD_SETTINGS );
     59   viewer.setClearColor( osg::Vec4(DEF_BACKGROUND_COLOUR) );
     60   //viewer.getCamera(0)->getRenderSurface()->setWindowRectangle(200,300,400,300);
     61   viewer.getCullSettings().setComputeNearFarMode( osg::CullSettings::COMPUTE_NEAR_FAR_USING_PRIMITIVES );
     62
     63
     64   // get details on keyboard and mouse bindings used by the viewer
     65   viewer.getUsage(*arguments.getApplicationUsage());
     66
     67   // if user requested help, write it out to cout
     68   if( arguments.read("-help") )
     69   {
     70      arguments.getApplicationUsage()->write(std::cout);
     71      return 1;
     72   }
     73
     74   // same for version info
     75   if( arguments.read("-version") )
     76   {
     77      std::cout << version() << std::endl;
     78      return 1;
     79   }
     80
     81
     82   // load sww file specified as final argument on command line (static bedslope
     83   // geometry only, per timestep height field geometry is done in loop below)
     84   int lastarg = arguments.argc()-1;
     85   std::string swwfile = arguments.argv()[lastarg];
     86   arguments.remove(lastarg);
     87   if( swwfile.substr(swwfile.size()-4,4).find(".sww",0) == -1 )  // ensure filename ends in .sww
     88   {
     89      std::cout << "Require last argument be an .sww file ... quitting" << std::endl;
     90      return 1;
     91   }
     92   SWWReader *sww = new SWWReader(swwfile);
     93   if (sww->isValid() == false)
     94   {
     95      std::cout << "Unable to load " << swwfile << " ... is this really an .sww file?" << std::endl;
     96      return 1;
     97   }
     98
     99
     100   // relative directory to swollen binary
     101   if( osgDB::getFilePath(argv[0]) == "" )
     102      sww->setSwollenDir( std::string(".") );
     103   else
     104      sww->setSwollenDir( osgDB::getFilePath(argv[0]) );
     105
     106
     107   // default arguments and command line parameters
     108   float tmpfloat, tps, vscale;
     109   if( !arguments.read("-tps", tps) || tps <= 0.0 ) tps = DEF_TPS;
     110   if( !arguments.read("-scale", vscale) ) vscale = 1.0;
     111   if( arguments.read("-hmin",tmpfloat) ) sww->setHeightMin( tmpfloat ); 
     112   if( arguments.read("-hmax",tmpfloat) ) sww->setHeightMax( tmpfloat );     
     113   if( arguments.read("-alphamin",tmpfloat) ) sww->setAlphaMin( tmpfloat );   
     114   if( arguments.read("-alphamax",tmpfloat) ) sww->setAlphaMax( tmpfloat );
     115   if( arguments.read("-cullangle",tmpfloat) ) sww->setCullAngle( tmpfloat );
     116
     117   std::string bedslopetexture;
     118   if( arguments.read("-texture",bedslopetexture) ) sww->setBedslopeTexture( bedslopetexture );
     119
     120   // root node
     121   osg::Group* rootnode = new osg::Group;
     122
     123   // transform
     124   osg::PositionAttitudeTransform* model = new osg::PositionAttitudeTransform;
     125   model->setName("position_attitude_transform");
     126
     127   // enscapsulates OpenGL state
     128   osg::StateSet* rootStateSet = new osg::StateSet;
     129
     130   // Bedslope geometry
     131   BedSlope* bedslope = new BedSlope(sww);
     132
     133   // Water geometry
     134   WaterSurface* water = new WaterSurface(sww);
     135
     136   // Heads Up Display (text overlay)
     137   HeadsUpDisplay* hud = new HeadsUpDisplay();
     138   hud->setTitle("pyVolution SWW Viewer");
     139
     140
     141   // Lighting
     142   DirectionalLight* light = new DirectionalLight(rootStateSet);
     143   light->setPosition( osg::Vec3(1,1,1) );  // z is up
     144
     145   std::string lightposstr;
     146   while (arguments.read("-lightpos",lightposstr))
     147   {
     148      float x, y, z;
     149      int count = sscanf( lightposstr.c_str(), "%f,%f,%f", &x, &y, &z );
     150      if( count == 3 ) light->setPosition( osg::Vec3(x,y,z) );  // z is up
     151      else osg::notify(osg::WARN) << "Invalid bedslope light position \"" << lightposstr << "\"" << std::endl;
     152   }
     153
     154
     155
     156   // scenegraph hierarchy
     157   rootnode->setStateSet(rootStateSet);
     158   rootnode->addChild( hud->get() );
     159   rootnode->addChild( light->get() );
     160   rootnode->addChild(model);
     161   model->addChild( bedslope->get() );
     162   model->addChild( water->get() );
     163
     164
     165   // allow vertical scaling from command line parameter
     166   model->setScale( osg::Vec3(1.0, 1.0, vscale) );
     167
     168   // surrounding sky sphere
     169   if( !arguments.read("-nosky") )
     170      rootnode->addChild( createSky(10.0, sww->getSwollenDir() + std::string("/sky_small.jpg") ));
     171
     172
     173   // add model to viewer.
     174   viewer.setSceneData(rootnode);
    167175 
    168     // any option left unread are converted into errors to write out later.
    169     arguments.reportRemainingOptionsAsUnrecognized();
     176   // any option left unread are converted into errors to write out later.
     177   arguments.reportRemainingOptionsAsUnrecognized();
    170178 
    171     // report any errors if they have occured when parsing the program aguments.
    172     if (arguments.errors())
    173     {
    174         arguments.writeErrorMessages(std::cout);
    175         return 1;
    176     }
    177 
    178     // register additional event handler
    179     KeyboardEventHandler* event_handler = new KeyboardEventHandler(sww->getNumberOfTimesteps(), tps);
    180     viewer.getEventHandlerList().push_front(event_handler);
     179   // report any errors if they have occured when parsing the program aguments.
     180   if (arguments.errors())
     181   {
     182      arguments.writeErrorMessages(std::cout);
     183      return 1;
     184   }
     185
     186   // register additional event handler
     187   KeyboardEventHandler* event_handler = new KeyboardEventHandler(sww->getNumberOfTimesteps(), tps);
     188   viewer.getEventHandlerList().push_front(event_handler);
    181189
    182190 
    183     // create the windows and run the threads.
    184     viewer.realize();
    185 
    186 
    187     // initial camera position
    188     CustomTerrainManipulator* terrainmanipulator = viewer.getTerrainManipulator();
    189     terrainmanipulator->setNode( model );
    190     terrainmanipulator->setAutoComputeHomePosition( false );
    191     terrainmanipulator->setHomePosition(
    192         osg::Vec3d(0,-3,3),    // camera location
    193         osg::Vec3d(0,0,0),     // camera target
    194         osg::Vec3d(0,1,1) );   // camera up vector
    195     terrainmanipulator->moveToHome();
    196     terrainmanipulator->enable();
    197 
    198 
    199     unsigned int timestep = 0;
    200     while( !viewer.done() )
    201     {
     191   // create the windows and run the threads.
     192   viewer.realize();
     193
     194
     195   // initial camera position
     196   CustomTerrainManipulator* terrainmanipulator = viewer.getTerrainManipulator();
     197   terrainmanipulator->setNode( model );
     198   terrainmanipulator->setAutoComputeHomePosition( false );
     199   terrainmanipulator->setHomePosition(
     200      osg::Vec3d(0,-3,3),    // camera location
     201      osg::Vec3d(0,0,0),     // camera target
     202      osg::Vec3d(0,1,1) );   // camera up vector
     203   terrainmanipulator->moveToHome();
     204   terrainmanipulator->enable();
     205
     206
     207   unsigned int timestep = 0;
     208   while( !viewer.done() )
     209   {
    202210   
    203         // wait for all cull and draw threads to complete.
    204         viewer.sync();
    205 
    206 
    207         // current time
    208         double time = viewer.getFrameStamp()->getReferenceTime();
    209 
    210         // advance sww frame?
    211         event_handler->setTime( time );
    212         if( event_handler->timestepChanged() )
    213         {
    214             timestep = event_handler->getTimestep();
    215             water->setTimeStep(timestep);
    216             hud->setTime( sww->getTime(timestep) );
    217         }
    218 
    219         // events
    220         if( event_handler->toggleWireframe() )
    221             water->toggleWireframe();
    222 
    223         if( event_handler->toggleCulling() )
    224         {
    225             sww->toggleCulling();
    226             water->setTimeStep(timestep);  // refresh
    227         }
    228 
    229         // update the scene by traversing with the update visitor
    230         viewer.update();
     211      // wait for all cull and draw threads to complete.
     212      viewer.sync();
     213
     214
     215      // current time
     216      double time = viewer.getFrameStamp()->getReferenceTime();
     217
     218      // advance sww frame?
     219      event_handler->setTime( time );
     220      if( event_handler->timestepChanged() )
     221      {
     222         timestep = event_handler->getTimestep();
     223         water->setTimeStep(timestep);
     224         hud->setTime( sww->getTime(timestep) );
     225      }
     226
     227      // events
     228      if( event_handler->toggleWireframe() )
     229         water->toggleWireframe();
     230
     231      if( event_handler->toggleCulling() )
     232      {
     233         sww->toggleCulling();
     234         water->setTimeStep(timestep);  // refresh
     235      }
     236
     237      // update the scene by traversing with the update visitor
     238      viewer.update();
    231239         
    232         // fire off the cull and draw traversals of the scene.
    233         viewer.frame();
    234     }
     240      // fire off the cull and draw traversals of the scene.
     241      viewer.frame();
     242   }
    235243   
    236     // wait for all cull and draw threads to complete before exit.
    237     viewer.sync();
    238 
    239     return 0;
     244   // wait for all cull and draw threads to complete before exit.
     245   viewer.sync();
     246
     247   return 0;
    240248}
  • Swollen/swollen/version.cpp

    r103 r106  
    1 const char* version() { const char* s = "Revision: 102M"; return s; }
     1const char* version() { const char* s = "Revision: 105M"; return s; }
  • Swollen/swollen/watersurface.cpp

    r105 r106  
    4646    texture->setBorderColor(osg::Vec4(1.0f,1.0f,1.0f,0.5f));
    4747    texture->setWrap(osg::Texture::WRAP_S, osg::Texture::REPEAT);
    48     texture->setImage(osgDB::readImageFile("envmap.jpg"));
     48    std::string* envmap = new std::string( _sww->getSwollenDir() + std::string("/") + std::string("envmap.jpg") );
     49    texture->setImage(osgDB::readImageFile( envmap->c_str() ));
    4950    _stateset->setTextureAttributeAndModes( 1, texture, osg::StateAttribute::ON );
    5051    _stateset->setMode( GL_LIGHTING, osg::StateAttribute::ON );
  • Swollen/swwreader/swwreader.cpp

    r105 r106  
    11/*
    2     SWWReader
    3 
    4     Reader of SWW files from within OpenSceneGraph.
    5 
    6     copyright (C) 2004-2005 Geoscience Australia
     2  SWWReader
     3
     4  Reader of SWW files from within OpenSceneGraph.
     5
     6  copyright (C) 2004-2005 Geoscience Australia
    77*/
    88
     
    3636SWWReader::SWWReader(const std::string& filename)
    3737{
    38     // assume failure until end of constructor
    39     _valid = false;
    40 
    41     // netcdf filename
    42     _filename = new std::string(filename);
    43 
    44     // netcdf open
    45     _status.push_back( nc_open(_filename->c_str(), NC_NOWRITE, &_ncid) );
    46     if (this->_statusHasError()) return;
    47 
    48     // dimension ids
    49     _status.push_back( nc_inq_dimid(_ncid, "number_of_volumes", &_nvolumesid) );
    50     _status.push_back( nc_inq_dimid(_ncid, "number_of_vertices", &_nverticesid) );
    51     _status.push_back( nc_inq_dimid(_ncid, "number_of_points", &_npointsid) );
    52     _status.push_back( nc_inq_dimid(_ncid, "number_of_timesteps", &_ntimestepsid) );
    53     if (this->_statusHasError()) return;
    54 
    55     // dimension values
    56     _status.push_back( nc_inq_dimlen(_ncid, _nvolumesid, &_nvolumes) );
    57     _status.push_back( nc_inq_dimlen(_ncid, _nverticesid, &_nvertices) );
    58     _status.push_back( nc_inq_dimlen(_ncid, _npointsid, &_npoints) );
    59     _status.push_back( nc_inq_dimlen(_ncid, _ntimestepsid, &_ntimesteps) );
    60     if (this->_statusHasError()) return;
    61 
    62     // variable ids
    63     _status.push_back( nc_inq_varid (_ncid, "x", &_xid) );
    64     _status.push_back( nc_inq_varid (_ncid, "y", &_yid) );
    65     _status.push_back( nc_inq_varid (_ncid, "z", &_zid) );
    66     _status.push_back( nc_inq_varid (_ncid, "volumes", &_volumesid) );
    67     _status.push_back( nc_inq_varid (_ncid, "time", &_timeid) );
    68     _status.push_back( nc_inq_varid (_ncid, "stage", &_stageid) );
    69     if (this->_statusHasError()) return;
    70 
    71     // allocation of variable arrays, destructor responsible for cleanup
    72     _px = new float[_npoints];
    73     _py = new float[_npoints];
    74     _pz = new float[_npoints];
    75     _ptime = new float[_ntimesteps];
    76     _pvolumes = new unsigned int[_nvertices * _nvolumes];
    77     _pstage = new float[_npoints];
    78 
    79     // loading variables from netcdf file
    80     _status.push_back( nc_get_var_float (_ncid, _xid, _px) );  // x vertices
    81     _status.push_back( nc_get_var_float (_ncid, _yid, _py) );  // y vertices
    82     _status.push_back( nc_get_var_float (_ncid, _zid, _pz) );  // bedslope heights
    83     _status.push_back( nc_get_var_float (_ncid, _timeid, _ptime) );  // time array
    84     _status.push_back( nc_get_var_int (_ncid, _volumesid, (int *) _pvolumes) );  // triangle indices
    85     if (this->_statusHasError()) return;
    86 
    87 
    88     // sww file can optionally contain bedslope texture image filename
    89     size_t attlen; // length of text attribute (if it exists)
    90     if( nc_inq_attlen(_ncid, NC_GLOBAL, "texture", &attlen) != NC_ENOTATT )
    91     {
    92         char* texfilename;
    93         if( (texfilename = (char*) malloc(attlen+1)) != NULL){
    94                 int status;
    95                 status = nc_get_att_text(_ncid, NC_GLOBAL, "texture", texfilename);
    96                 if( status == NC_NOERR )
    97                 {
    98                     texfilename[attlen] = '\0';  // ensure string is terminated, not a requirement for netcdf attributes
    99                     osg::notify(osg::INFO) << "[SWWReader] embedded image filename: " << texfilename <<  std::endl;
    100                 setBedslopeTexture( osgDB::getFilePath(filename) + std::string("/") + std::string(texfilename) );
    101                 }
    102             free( texfilename );
    103         }
    104     }
    105 
    106     // sww file can optionally contain georeference offset
    107     int status1 = nc_get_att_float(_ncid, NC_GLOBAL, "xllcorner", &_xllcorner);
    108     int status2 = nc_get_att_float(_ncid, NC_GLOBAL, "yllcorner", &_yllcorner);
    109     if( status1 == NC_NOERR && status2 == NC_NOERR)
    110     {
    111        osg::notify(osg::INFO) << "[SWWReader] xllcorner: " << _xllcorner <<  std::endl;
    112        osg::notify(osg::INFO) << "[SWWReader] yllcorner: " << _yllcorner <<  std::endl;
    113     }
    114     else
    115     {
    116        _xllcorner = 0.0;  // default value
    117        _yllcorner = 0.0;
    118     }
    119 
    120 
    121     // alpha-scaling defaults, can be overridden after construction by command line parameters
    122     _alphamin = DEFAULT_ALPHAMIN;
    123     _alphamax = DEFAULT_ALPHAMAX;
    124     _heightmin = DEFAULT_HEIGHTMIN;
    125     _heightmax = DEFAULT_HEIGHTMAX;
    126 
    127     // steepness culling default, can be overridden after construction by command line parameter
    128     _cullangle = DEFAULT_CULLANGLE;
    129     _culling = DEFAULT_CULLONSTART;
    130 
    131     // loop index
    132     size_t iv;
    133 
    134     // vertex indices
    135     unsigned int v1index, v2index, v3index;
    136 
    137     // bedslope range and resultant scale factors (note, these don't take into
    138     // account any xllcorner, yllcorner offsets - used during texture coord assignment)
    139     float xmin, xmax, xrange;
    140     float ymin, ymax, yrange;
    141     float zmin, zmax, zrange;
    142     float aspect_ratio;
    143     xmin = _px[0];
    144     xmax = _px[0];
    145     ymin = _py[0];
    146     ymax = _py[0];
    147     zmin = _pz[0];
    148     zmax = _pz[0];
    149     for( iv=1; iv < _npoints; iv++ )
    150     {
    151        if( _px[iv] < xmin ) xmin = _px[iv];
    152        if( _px[iv] > xmax ) xmax = _px[iv];
    153        if( _py[iv] < ymin ) ymin = _py[iv];
    154        if( _py[iv] > ymax ) ymax = _py[iv];
    155        if( _pz[iv] < zmin ) zmin = _pz[iv];
    156        if( _pz[iv] > zmax ) zmax = _pz[iv];
    157     }
    158 
    159     xrange = xmax - xmin;
    160     yrange = ymax - ymin;
    161     zrange = zmax - zmin;
    162     aspect_ratio = xrange/yrange;
    163     _xscale = 1.0 / xrange;
    164     _yscale = 1.0 / yrange;
     38   // assume failure until end of constructor
     39   _valid = false;
     40
     41   // netcdf filename
     42   _filename = new std::string(filename);
     43
     44   // netcdf open
     45   _status.push_back( nc_open(_filename->c_str(), NC_NOWRITE, &_ncid) );
     46   if (this->_statusHasError()) return;
     47
     48   // dimension ids
     49   _status.push_back( nc_inq_dimid(_ncid, "number_of_volumes", &_nvolumesid) );
     50   _status.push_back( nc_inq_dimid(_ncid, "number_of_vertices", &_nverticesid) );
     51   _status.push_back( nc_inq_dimid(_ncid, "number_of_points", &_npointsid) );
     52   _status.push_back( nc_inq_dimid(_ncid, "number_of_timesteps", &_ntimestepsid) );
     53   if (this->_statusHasError()) return;
     54
     55   // dimension values
     56   _status.push_back( nc_inq_dimlen(_ncid, _nvolumesid, &_nvolumes) );
     57   _status.push_back( nc_inq_dimlen(_ncid, _nverticesid, &_nvertices) );
     58   _status.push_back( nc_inq_dimlen(_ncid, _npointsid, &_npoints) );
     59   _status.push_back( nc_inq_dimlen(_ncid, _ntimestepsid, &_ntimesteps) );
     60   if (this->_statusHasError()) return;
     61
     62   // variable ids
     63   _status.push_back( nc_inq_varid (_ncid, "x", &_xid) );
     64   _status.push_back( nc_inq_varid (_ncid, "y", &_yid) );
     65   _status.push_back( nc_inq_varid (_ncid, "z", &_zid) );
     66   _status.push_back( nc_inq_varid (_ncid, "volumes", &_volumesid) );
     67   _status.push_back( nc_inq_varid (_ncid, "time", &_timeid) );
     68   _status.push_back( nc_inq_varid (_ncid, "stage", &_stageid) );
     69   if (this->_statusHasError()) return;
     70
     71   // allocation of variable arrays, destructor responsible for cleanup
     72   _px = new float[_npoints];
     73   _py = new float[_npoints];
     74   _pz = new float[_npoints];
     75   _ptime = new float[_ntimesteps];
     76   _pvolumes = new unsigned int[_nvertices * _nvolumes];
     77   _pstage = new float[_npoints];
     78
     79   // loading variables from netcdf file
     80   _status.push_back( nc_get_var_float (_ncid, _xid, _px) );  // x vertices
     81   _status.push_back( nc_get_var_float (_ncid, _yid, _py) );  // y vertices
     82   _status.push_back( nc_get_var_float (_ncid, _zid, _pz) );  // bedslope heights
     83   _status.push_back( nc_get_var_float (_ncid, _timeid, _ptime) );  // time array
     84   _status.push_back( nc_get_var_int (_ncid, _volumesid, (int *) _pvolumes) );  // triangle indices
     85   if (this->_statusHasError()) return;
     86
     87
     88   // sww file can optionally contain bedslope texture image filename
     89   size_t attlen; // length of text attribute (if it exists)
     90   if( nc_inq_attlen(_ncid, NC_GLOBAL, "texture", &attlen) != NC_ENOTATT )
     91   {
     92      char* texfilename;
     93      if( (texfilename = (char*) malloc(attlen+1)) != NULL){
     94         int status;
     95         status = nc_get_att_text(_ncid, NC_GLOBAL, "texture", texfilename);
     96         if( status == NC_NOERR )
     97         {
     98            texfilename[attlen] = '\0';  // ensure string is terminated, not a requirement for netcdf attributes
     99            osg::notify(osg::INFO) << "[SWWReader] embedded image filename: " << texfilename <<  std::endl;
     100
     101            // if sww isn't in current directory, need to prepend sww path to the bedslope texture
     102            if( osgDB::getFilePath(filename) == "" )
     103               setBedslopeTexture( std::string(texfilename) );
     104            else
     105               setBedslopeTexture( osgDB::getFilePath(filename) + std::string("/") + std::string(texfilename) );
     106         }
     107         free( texfilename );
     108      }
     109   }
     110
     111   // sww file can optionally contain georeference offset
     112   int status1 = nc_get_att_float(_ncid, NC_GLOBAL, "xllcorner", &_xllcorner);
     113   int status2 = nc_get_att_float(_ncid, NC_GLOBAL, "yllcorner", &_yllcorner);
     114   if( status1 == NC_NOERR && status2 == NC_NOERR)
     115   {
     116      osg::notify(osg::INFO) << "[SWWReader] xllcorner: " << _xllcorner <<  std::endl;
     117      osg::notify(osg::INFO) << "[SWWReader] yllcorner: " << _yllcorner <<  std::endl;
     118   }
     119   else
     120   {
     121      _xllcorner = 0.0;  // default value
     122      _yllcorner = 0.0;
     123   }
     124
     125
     126   // alpha-scaling defaults, can be overridden after construction by command line parameters
     127   _alphamin = DEFAULT_ALPHAMIN;
     128   _alphamax = DEFAULT_ALPHAMAX;
     129   _heightmin = DEFAULT_HEIGHTMIN;
     130   _heightmax = DEFAULT_HEIGHTMAX;
     131
     132   // steepness culling default, can be overridden after construction by command line parameter
     133   _cullangle = DEFAULT_CULLANGLE;
     134   _culling = DEFAULT_CULLONSTART;
     135
     136   // loop index
     137   size_t iv;
     138
     139   // vertex indices
     140   unsigned int v1index, v2index, v3index;
     141
     142   // bedslope range and resultant scale factors (note, these don't take into
     143   // account any xllcorner, yllcorner offsets - used during texture coord assignment)
     144   float xmin, xmax, xrange;
     145   float ymin, ymax, yrange;
     146   float zmin, zmax, zrange;
     147   float aspect_ratio;
     148   xmin = _px[0];
     149   xmax = _px[0];
     150   ymin = _py[0];
     151   ymax = _py[0];
     152   zmin = _pz[0];
     153   zmax = _pz[0];
     154   for( iv=1; iv < _npoints; iv++ )
     155   {
     156      if( _px[iv] < xmin ) xmin = _px[iv];
     157      if( _px[iv] > xmax ) xmax = _px[iv];
     158      if( _py[iv] < ymin ) ymin = _py[iv];
     159      if( _py[iv] > ymax ) ymax = _py[iv];
     160      if( _pz[iv] < zmin ) zmin = _pz[iv];
     161      if( _pz[iv] > zmax ) zmax = _pz[iv];
     162   }
     163
     164   xrange = xmax - xmin;
     165   yrange = ymax - ymin;
     166   zrange = zmax - zmin;
     167   aspect_ratio = xrange/yrange;
     168   _xscale = 1.0 / xrange;
     169   _yscale = 1.0 / yrange;
    165170   
    166     // handle case of a flat bed that doesn't necessarily pass through z=0
    167     _zscale = (zrange == 0.0) ? 1.0 : 1.0/zrange;
    168 
    169     _xoffset = xmin;
    170     _yoffset = ymin;
    171     _zoffset = zmin;
    172     _xcenter = 0.5;
    173     _ycenter = 0.5;
    174     _zcenter = 0.0;
    175 
    176     if( aspect_ratio > 1.0 )
    177     {
    178         _scale = 1.0/xrange;
    179         _ycenter /= aspect_ratio;
    180     }
    181     else
    182     {
    183         _scale = 1.0/yrange;
    184         _xcenter /= aspect_ratio;
    185     }
    186 
    187     osg::notify(osg::INFO) << "[SWWReader] xscale: " << _xscale <<  std::endl;
    188     osg::notify(osg::INFO) << "[SWWReader] yscale: " << _yscale <<  std::endl;
    189     osg::notify(osg::INFO) << "[SWWReader] zmin: " << zmin <<  std::endl;
    190     osg::notify(osg::INFO) << "[SWWReader] zmax: " << zmax <<  std::endl;
    191     osg::notify(osg::INFO) << "[SWWReader] zscale: " << _zscale <<  std::endl;
    192 
    193 
    194     // compute triangle connectivity, a list (indexed by vertex number)
    195     // of lists (indices of triangles sharing this vertex)
    196     _connectivity = std::vector<triangle_list>(_npoints);
    197     for (iv=0; iv < _nvolumes; iv++)
    198     {
    199         v1index = _pvolumes[3*iv+0];
    200         v2index = _pvolumes[3*iv+1];
    201         v3index = _pvolumes[3*iv+2];
    202         _connectivity.at(v1index).push_back(iv);
    203         _connectivity.at(v2index).push_back(iv);
    204         _connectivity.at(v3index).push_back(iv);
    205     }
    206 
    207     // bedslope vertex array, shifting and scaling vertices to unit cube
    208     // centred about the origin
    209     _bedslopevertices = new osg::Vec3Array;
    210     for (iv=0; iv < _npoints; iv++)
    211         _bedslopevertices->push_back( osg::Vec3( (_px[iv]-_xoffset)*_scale - _xcenter,
    212                                                 (_py[iv]-_yoffset)*_scale - _ycenter,
    213                                                 (_pz[iv]-_zoffset)*_scale - _zcenter - DEFAULT_BEDSLOPEOFFSET) );
    214 
    215     // bedslope index array, pvolumes array indexes into x, y and z
    216     _bedslopeindices = new osg::DrawElementsUShort(osg::PrimitiveSet::TRIANGLES, _nvolumes*_nvertices);
    217     for (iv=0; iv < _nvolumes*_nvertices; iv++)
    218         (*_bedslopeindices)[iv] = _pvolumes[iv];
    219 
    220 
    221     // calculate bedslope primitive normal and centroid arrays
    222     _bedslopenormals = new osg::Vec3Array;
    223     _bedslopecentroids = new osg::Vec3Array;
    224     osg::Vec3 v1, v2, v3, side1, side2, nrm;
    225     for (iv=0; iv < _nvolumes; iv++)
    226     {
    227         v1index = _pvolumes[3*iv+0];
    228         v2index = _pvolumes[3*iv+1];
    229         v3index = _pvolumes[3*iv+2];
    230 
    231         v1 = _bedslopevertices->at(v1index);
    232         v2 = _bedslopevertices->at(v2index);
    233         v3 = _bedslopevertices->at(v3index);
    234 
    235         side1 = v2 - v1;
    236         side2 = v3 - v2;
    237         nrm = side1^side2;
    238         nrm.normalize();
    239 
    240         _bedslopenormals->push_back( nrm );
    241         _bedslopecentroids->push_back( (v1+v2+v3)/3.0 );
    242     }
    243 
    244     // success!
    245     _valid = true;
     171   // handle case of a flat bed that doesn't necessarily pass through z=0
     172   _zscale = (zrange == 0.0) ? 1.0 : 1.0/zrange;
     173
     174   _xoffset = xmin;
     175   _yoffset = ymin;
     176   _zoffset = zmin;
     177   _xcenter = 0.5;
     178   _ycenter = 0.5;
     179   _zcenter = 0.0;
     180
     181   if( aspect_ratio > 1.0 )
     182   {
     183      _scale = 1.0/xrange;
     184      _ycenter /= aspect_ratio;
     185   }
     186   else
     187   {
     188      _scale = 1.0/yrange;
     189      _xcenter /= aspect_ratio;
     190   }
     191
     192   osg::notify(osg::INFO) << "[SWWReader] xscale: " << _xscale <<  std::endl;
     193   osg::notify(osg::INFO) << "[SWWReader] yscale: " << _yscale <<  std::endl;
     194   osg::notify(osg::INFO) << "[SWWReader] zmin: " << zmin <<  std::endl;
     195   osg::notify(osg::INFO) << "[SWWReader] zmax: " << zmax <<  std::endl;
     196   osg::notify(osg::INFO) << "[SWWReader] zscale: " << _zscale <<  std::endl;
     197
     198
     199   // compute triangle connectivity, a list (indexed by vertex number)
     200   // of lists (indices of triangles sharing this vertex)
     201   _connectivity = std::vector<triangle_list>(_npoints);
     202   for (iv=0; iv < _nvolumes; iv++)
     203   {
     204      v1index = _pvolumes[3*iv+0];
     205      v2index = _pvolumes[3*iv+1];
     206      v3index = _pvolumes[3*iv+2];
     207      _connectivity.at(v1index).push_back(iv);
     208      _connectivity.at(v2index).push_back(iv);
     209      _connectivity.at(v3index).push_back(iv);
     210   }
     211
     212   // bedslope vertex array, shifting and scaling vertices to unit cube
     213   // centred about the origin
     214   _bedslopevertices = new osg::Vec3Array;
     215   for (iv=0; iv < _npoints; iv++)
     216      _bedslopevertices->push_back( osg::Vec3( (_px[iv]-_xoffset)*_scale - _xcenter,
     217                                              (_py[iv]-_yoffset)*_scale - _ycenter,
     218                                              (_pz[iv]-_zoffset)*_scale - _zcenter - DEFAULT_BEDSLOPEOFFSET) );
     219
     220   // bedslope index array, pvolumes array indexes into x, y and z
     221   _bedslopeindices = new osg::DrawElementsUShort(osg::PrimitiveSet::TRIANGLES, _nvolumes*_nvertices);
     222   for (iv=0; iv < _nvolumes*_nvertices; iv++)
     223      (*_bedslopeindices)[iv] = _pvolumes[iv];
     224
     225
     226   // calculate bedslope primitive normal and centroid arrays
     227   _bedslopenormals = new osg::Vec3Array;
     228   _bedslopecentroids = new osg::Vec3Array;
     229   osg::Vec3 v1, v2, v3, side1, side2, nrm;
     230   for (iv=0; iv < _nvolumes; iv++)
     231   {
     232      v1index = _pvolumes[3*iv+0];
     233      v2index = _pvolumes[3*iv+1];
     234      v3index = _pvolumes[3*iv+2];
     235
     236      v1 = _bedslopevertices->at(v1index);
     237      v2 = _bedslopevertices->at(v2index);
     238      v3 = _bedslopevertices->at(v3index);
     239
     240      side1 = v2 - v1;
     241      side2 = v3 - v2;
     242      nrm = side1^side2;
     243      nrm.normalize();
     244
     245      _bedslopenormals->push_back( nrm );
     246      _bedslopecentroids->push_back( (v1+v2+v3)/3.0 );
     247   }
     248
     249   // success!
     250   _valid = true;
    246251
    247252}
     
    251256SWWReader::~SWWReader()
    252257{
    253     _status.push_back( nc_close(_ncid) );
    254     delete[]( _px, _py, _pz, _ptime, _pvolumes, _pstage );
     258   _status.push_back( nc_close(_ncid) );
     259   delete[]( _px, _py, _pz, _ptime, _pvolumes, _pstage );
    255260}
    256261
     
    259264void SWWReader::setBedslopeTexture( std::string filename )
    260265{
    261     osg::notify(osg::INFO) << "[SWWReader::setBedslopetexture] filename: " << filename <<  std::endl;
     266   osg::notify(osg::INFO) << "[SWWReader::setBedslopetexture] filename: " << filename <<  std::endl;
    262267   _bedslopetexture = new std::string(filename);
    263268   _bedslopegeodata.hasData = false;
     
    278283      _bedslopegeodata.xresolution = pGDAL->GetRasterXSize();
    279284      _bedslopegeodata.yresolution = pGDAL->GetRasterYSize();
    280           osg::notify(osg::INFO) << "[SWWReader::setBedslopetexture] xresolution: " <<
    281           _bedslopegeodata.xresolution <<  std::endl;
    282           osg::notify(osg::INFO) << "[SWWReader::setBedslopetexture] yresolution: " <<
    283           _bedslopegeodata.yresolution <<  std::endl;
     285      osg::notify(osg::INFO) << "[SWWReader::setBedslopetexture] xresolution: " << _bedslopegeodata.xresolution <<  std::endl;
     286      osg::notify(osg::INFO) << "[SWWReader::setBedslopetexture] yresolution: " << _bedslopegeodata.yresolution <<  std::endl;
    284287
    285288      // check if image contains geodata
     
    287290      if( pGDAL->GetGeoTransform( geodata ) == CE_None )
    288291      {
    289           _bedslopegeodata.xorigin = geodata[0];
    290           _bedslopegeodata.yorigin = geodata[3];
    291           _bedslopegeodata.rotation = geodata[2];
    292           _bedslopegeodata.xpixel = geodata[1];
    293           _bedslopegeodata.ypixel = geodata[5];
    294           _bedslopegeodata.hasData = true;
    295 
    296           osg::notify(osg::INFO) << "[SWWReader::setBedslopetexture] xorigin: " << _bedslopegeodata.xorigin <<  std::endl;
    297           osg::notify(osg::INFO) << "[SWWReader::setBedslopetexture] yorigin: " << _bedslopegeodata.yorigin <<  std::endl;
    298           osg::notify(osg::INFO) << "[SWWReader::setBedslopetexture] xpixel: " << _bedslopegeodata.xpixel <<  std::endl;
    299           osg::notify(osg::INFO) << "[SWWReader::setBedslopetexture] ypixel: " << _bedslopegeodata.ypixel <<  std::endl;
    300           osg::notify(osg::INFO) << "[SWWReader::setBedslopetexture] rotation: " << _bedslopegeodata.rotation <<  std::endl;
    301       }
    302    }
    303 
     292         _bedslopegeodata.xorigin = geodata[0];
     293         _bedslopegeodata.yorigin = geodata[3];
     294         _bedslopegeodata.rotation = geodata[2];
     295         _bedslopegeodata.xpixel = geodata[1];
     296         _bedslopegeodata.ypixel = geodata[5];
     297         _bedslopegeodata.hasData = true;
     298
     299         osg::notify(osg::INFO) << "[SWWReader::setBedslopetexture] xorigin: " << _bedslopegeodata.xorigin <<  std::endl;
     300         osg::notify(osg::INFO) << "[SWWReader::setBedslopetexture] yorigin: " << _bedslopegeodata.yorigin <<  std::endl;
     301         osg::notify(osg::INFO) << "[SWWReader::setBedslopetexture] xpixel: " << _bedslopegeodata.xpixel <<  std::endl;
     302         osg::notify(osg::INFO) << "[SWWReader::setBedslopetexture] ypixel: " << _bedslopegeodata.ypixel <<  std::endl;
     303         osg::notify(osg::INFO) << "[SWWReader::setBedslopetexture] rotation: " << _bedslopegeodata.rotation <<  std::endl;
     304      }
     305   }
    304306}
    305307
     
    316318{
    317319   _bedslopetexcoords = new osg::Vec2Array;
    318     if( _bedslopegeodata.hasData )  // georeferenced bedslope texture
    319     {
    320         float xorigin = _bedslopegeodata.xorigin;
    321         float yorigin = _bedslopegeodata.yorigin;
    322         float xrange = _bedslopegeodata.xpixel * _bedslopegeodata.xresolution;
    323         float yrange = _bedslopegeodata.ypixel * _bedslopegeodata.yresolution;
    324         for( unsigned int iv=0; iv < _npoints; iv++ )
    325             _bedslopetexcoords->push_back( osg::Vec2( (_px[iv] + _xllcorner - xorigin)/xrange,
    326                                                       (_py[iv] + _yllcorner - yorigin)/yrange ) );
    327     }
    328     else
    329     {
    330         // decal'd using (x,y) locations scaled by extents into range [0,1]
    331         for( unsigned int iv=0; iv < _npoints; iv++ )
    332             _bedslopetexcoords->push_back( osg::Vec2( (_px[iv]-_xoffset)*_xscale, (_py[iv]-_yoffset)*_yscale ) );
    333     }
     320   if( _bedslopegeodata.hasData )  // georeferenced bedslope texture
     321   {
     322      float xorigin = _bedslopegeodata.xorigin;
     323      float yorigin = _bedslopegeodata.yorigin;
     324      float xrange = _bedslopegeodata.xpixel * _bedslopegeodata.xresolution;
     325      float yrange = _bedslopegeodata.ypixel * _bedslopegeodata.yresolution;
     326      for( unsigned int iv=0; iv < _npoints; iv++ )
     327         _bedslopetexcoords->push_back( osg::Vec2( (_px[iv] + _xllcorner - xorigin)/xrange,
     328                                                   (_py[iv] + _yllcorner - yorigin)/yrange ) );
     329   }
     330   else
     331   {
     332      // decal'd using (x,y) locations scaled by extents into range [0,1]
     333      for( unsigned int iv=0; iv < _npoints; iv++ )
     334         _bedslopetexcoords->push_back( osg::Vec2( (_px[iv]-_xoffset)*_xscale, (_py[iv]-_yoffset)*_yscale ) );
     335   }
    334336
    335337   return _bedslopetexcoords;
     
    340342osg::ref_ptr<osg::Vec3Array> SWWReader::getStageVertexArray(unsigned int index)
    341343{
    342     size_t start[2], count[2], iv;
    343     const ptrdiff_t stride[2] = {1,1};
    344     start[0] = index;
    345     start[1] = 0;
    346     count[0] = 1;
    347     count[1] = _npoints;
    348 
    349     // empty array for storing list of steep triangles
    350     osg::ref_ptr<osg::IntArray> steeptri = new osg::IntArray;
    351 
    352     // stage heights from netcdf file (x and y are same as bedslope)
    353     int status = nc_get_vars_float (_ncid, _stageid, start, count, stride, _pstage);
    354 
    355     // load stage vertex array, scaling and shifting vertices to lie in the unit cube
    356     _stagevertices = new osg::Vec3Array;
    357     for (iv=0; iv < _npoints; iv++)
    358         _stagevertices->push_back( osg::Vec3( (_px[iv]-_xoffset)*_scale - _xcenter,
    359                                               (_py[iv]-_yoffset)*_scale - _ycenter,
    360                                               (_pstage[iv]-_zoffset)*_scale - _zcenter) );
    361 
    362     // stage index, per primitive normal and centroid arrays
    363     _stageprimitivenormals = new osg::Vec3Array;
    364     _stagecentroids = new osg::Vec3Array;
    365     osg::Vec3 v1b, v2b, v3b;
    366     osg::Vec3 v1s, v2s, v3s;
    367     osg::Vec3 side1, side2, nrm;
    368     unsigned int v1index, v2index, v3index;
    369 
    370     // cullangle given in degrees, test is against dot product
    371     float cullthreshold = cos(osg::DegreesToRadians(_cullangle));
    372 
    373     // over all stage triangles
    374     for (iv=0; iv < _nvolumes; iv++)
    375     {
    376         v1index = _pvolumes[3*iv+0];
    377         v2index = _pvolumes[3*iv+1];
    378         v3index = _pvolumes[3*iv+2];
    379 
    380         v1s = _stagevertices->at(v1index);
    381         v2s = _stagevertices->at(v2index);
    382         v3s = _stagevertices->at(v3index);
    383         v1b = _bedslopevertices->at(v1index);
    384         v2b = _bedslopevertices->at(v2index);
    385         v3b = _bedslopevertices->at(v3index);
    386 
    387         // current triangle primitive normal
    388         side1 = v2s - v1s;
    389         side2 = v3s - v2s;
    390         nrm = side1^side2;
    391         nrm.normalize();
    392 
    393         // store centroid and primitive normal
    394         _stagecentroids->push_back( (v1s+v2s+v3s)/3.0 );
    395         _stageprimitivenormals->push_back( nrm );
    396 
    397         // identify steep triangles, store index
    398         if( fabs(nrm * osg::Vec3f(0,0,1)) < cullthreshold )
    399             steeptri->push_back( iv );
    400     }
    401 
    402     // stage height above bedslope mapped as alpha value
    403     //      alpha = min( a(h-hmin) + alphamin, alphamax),  h >= hmin
    404     //      alpha = 0,                                     h < hmin
    405     // where a = (alphamax-alphamin)/(hmax-hmin)
    406     float alpha, height, alphascale;
    407     alphascale = (_alphamax - _alphamin) / (_heightmax - _heightmin);
    408     _stagecolors = new osg::Vec4Array;
    409     for (iv=0; iv < _npoints; iv++)
    410     {
    411         // water height above corresponding bedslope
    412         height = _stagevertices->at(iv).z() - _bedslopevertices->at(iv).z();
     344   size_t start[2], count[2], iv;
     345   const ptrdiff_t stride[2] = {1,1};
     346   start[0] = index;
     347   start[1] = 0;
     348   count[0] = 1;
     349   count[1] = _npoints;
     350
     351   // empty array for storing list of steep triangles
     352   osg::ref_ptr<osg::IntArray> steeptri = new osg::IntArray;
     353
     354   // stage heights from netcdf file (x and y are same as bedslope)
     355   int status = nc_get_vars_float (_ncid, _stageid, start, count, stride, _pstage);
     356
     357   // load stage vertex array, scaling and shifting vertices to lie in the unit cube
     358   _stagevertices = new osg::Vec3Array;
     359   for (iv=0; iv < _npoints; iv++)
     360      _stagevertices->push_back( osg::Vec3( (_px[iv]-_xoffset)*_scale - _xcenter,
     361                                            (_py[iv]-_yoffset)*_scale - _ycenter,
     362                                            (_pstage[iv]-_zoffset)*_scale - _zcenter) );
     363
     364   // stage index, per primitive normal and centroid arrays
     365   _stageprimitivenormals = new osg::Vec3Array;
     366   _stagecentroids = new osg::Vec3Array;
     367   osg::Vec3 v1b, v2b, v3b;
     368   osg::Vec3 v1s, v2s, v3s;
     369   osg::Vec3 side1, side2, nrm;
     370   unsigned int v1index, v2index, v3index;
     371
     372   // cullangle given in degrees, test is against dot product
     373   float cullthreshold = cos(osg::DegreesToRadians(_cullangle));
     374
     375   // over all stage triangles
     376   for (iv=0; iv < _nvolumes; iv++)
     377   {
     378      v1index = _pvolumes[3*iv+0];
     379      v2index = _pvolumes[3*iv+1];
     380      v3index = _pvolumes[3*iv+2];
     381
     382      v1s = _stagevertices->at(v1index);
     383      v2s = _stagevertices->at(v2index);
     384      v3s = _stagevertices->at(v3index);
     385      v1b = _bedslopevertices->at(v1index);
     386      v2b = _bedslopevertices->at(v2index);
     387      v3b = _bedslopevertices->at(v3index);
     388
     389      // current triangle primitive normal
     390      side1 = v2s - v1s;
     391      side2 = v3s - v2s;
     392      nrm = side1^side2;
     393      nrm.normalize();
     394
     395      // store centroid and primitive normal
     396      _stagecentroids->push_back( (v1s+v2s+v3s)/3.0 );
     397      _stageprimitivenormals->push_back( nrm );
     398
     399      // identify steep triangles, store index
     400      if( fabs(nrm * osg::Vec3f(0,0,1)) < cullthreshold )
     401         steeptri->push_back( iv );
     402   }
     403
     404   // stage height above bedslope mapped as alpha value
     405   //      alpha = min( a(h-hmin) + alphamin, alphamax),  h >= hmin
     406   //      alpha = 0,                                     h < hmin
     407   // where a = (alphamax-alphamin)/(hmax-hmin)
     408   float alpha, height, alphascale;
     409   alphascale = (_alphamax - _alphamin) / (_heightmax - _heightmin);
     410   _stagecolors = new osg::Vec4Array;
     411   for (iv=0; iv < _npoints; iv++)
     412   {
     413      // water height above corresponding bedslope
     414      height = _stagevertices->at(iv).z() - _bedslopevertices->at(iv).z();
    413415       
    414         if (height < _heightmin)
    415             alpha = 0.0;
    416         else
    417         {
    418             alpha = alphascale * (height - _heightmin) + _alphamin;
    419                 if( alpha > _alphamax )
    420                 alpha = _alphamax;
    421         }
    422 
    423         _stagecolors->push_back( osg::Vec4( 1.0, 1.0, 1.0, alpha ) );
    424     }
    425 
    426         // steep triangle vertices should have alpha=0, overwrite such vertex colours
    427     if( _culling )
    428     {
    429         for (iv=0; iv < steeptri->size() ; iv++)
    430         {
    431             int tri = steeptri->at(iv);
    432             v1index = _pvolumes[3*tri+0];
    433             v2index = _pvolumes[3*tri+1];
    434             v3index = _pvolumes[3*tri+2];
    435 
    436             _stagecolors->at(v1index) = osg::Vec4( 1, 1, 1, 0 );
    437             _stagecolors->at(v2index) = osg::Vec4( 1, 1, 1, 0 );
    438             _stagecolors->at(v3index) = osg::Vec4( 1, 1, 1, 0 );
    439         }
    440     }
    441 
    442     // per-vertex normals calculated as average of primitive normals
    443     // from contributing triangles
    444     _stagevertexnormals = new osg::Vec3Array;
    445     int num_shared_triangles, triangle_index;
    446     for (iv=0; iv < _npoints; iv++)
    447     {
    448         nrm.set(0,0,0);
    449         num_shared_triangles = _connectivity.at(iv).size();
    450         for (int i=0; i<num_shared_triangles; i++ )
    451         {
    452             triangle_index = _connectivity.at(iv).at(i);
    453             nrm += _stageprimitivenormals->at(triangle_index);
    454         }
    455 
    456         nrm = nrm / num_shared_triangles;  // average
    457         nrm.normalize();
    458         _stagevertexnormals->push_back(nrm);
    459     }
    460 
    461     return _stagevertices;
     416      if (height < _heightmin)
     417         alpha = 0.0;
     418      else
     419      {
     420         alpha = alphascale * (height - _heightmin) + _alphamin;
     421         if( alpha > _alphamax )
     422            alpha = _alphamax;
     423      }
     424
     425      _stagecolors->push_back( osg::Vec4( 1.0, 1.0, 1.0, alpha ) );
     426   }
     427
     428   // steep triangle vertices should have alpha=0, overwrite such vertex colours
     429   if( _culling )
     430   {
     431      for (iv=0; iv < steeptri->size() ; iv++)
     432      {
     433         int tri = steeptri->at(iv);
     434         v1index = _pvolumes[3*tri+0];
     435         v2index = _pvolumes[3*tri+1];
     436         v3index = _pvolumes[3*tri+2];
     437
     438         _stagecolors->at(v1index) = osg::Vec4( 1, 1, 1, 0 );
     439         _stagecolors->at(v2index) = osg::Vec4( 1, 1, 1, 0 );
     440         _stagecolors->at(v3index) = osg::Vec4( 1, 1, 1, 0 );
     441      }
     442   }
     443
     444   // per-vertex normals calculated as average of primitive normals
     445   // from contributing triangles
     446   _stagevertexnormals = new osg::Vec3Array;
     447   int num_shared_triangles, triangle_index;
     448   for (iv=0; iv < _npoints; iv++)
     449   {
     450      nrm.set(0,0,0);
     451      num_shared_triangles = _connectivity.at(iv).size();
     452      for (int i=0; i<num_shared_triangles; i++ )
     453      {
     454         triangle_index = _connectivity.at(iv).at(i);
     455         nrm += _stageprimitivenormals->at(triangle_index);
     456      }
     457
     458      nrm = nrm / num_shared_triangles;  // average
     459      nrm.normalize();
     460      _stagevertexnormals->push_back(nrm);
     461   }
     462
     463   return _stagevertices;
    462464}
    463465
     
    467469bool SWWReader::_statusHasError()
    468470{
    469     bool haserror = false;  // assume success, trap failure
    470 
    471     std::vector<int>::iterator iter;
    472     for (iter=_status.begin(); iter != _status.end(); iter++)
    473     {
    474         if (*iter != NC_NOERR)
    475         {
    476             osg::notify(osg::WARN) << nc_strerror(*iter) <<  std::endl;
    477             haserror = true;
    478             nc_close(_ncid);
    479             break;
    480         }
    481     }
    482 
    483     // on return start gathering result values afresh
    484     _status.clear();
    485 
    486     return haserror;
    487 }
     471   bool haserror = false;  // assume success, trap failure
     472
     473   std::vector<int>::iterator iter;
     474   for (iter=_status.begin(); iter != _status.end(); iter++)
     475   {
     476      if (*iter != NC_NOERR)
     477      {
     478         osg::notify(osg::WARN) << nc_strerror(*iter) <<  std::endl;
     479         haserror = true;
     480         nc_close(_ncid);
     481         break;
     482      }
     483   }
     484
     485   // on return start gathering result values afresh
     486   _status.clear();
     487
     488   return haserror;
     489}
Note: See TracChangeset for help on using the changeset viewer.