Introduced osgTerrain::WhiteListTileLoadedCallback for the management of options terrain layers

This commit is contained in:
Robert Osfield 2008-09-11 13:21:58 +00:00
parent a214a677f8
commit ff299eb104
4 changed files with 305 additions and 192 deletions

View File

@ -233,192 +233,6 @@ protected:
osg::ref_ptr<osgTerrain::Terrain> _terrain;
};
struct WhiteListTileLoadedCallback : public osgTerrain::TerrainTile::TileLoadedCallback
{
WhiteListTileLoadedCallback()
{
}
void allow(const std::string& setname) { _setWhiteList.insert(setname); }
typedef std::set<std::string> SetWhiteList;
SetWhiteList _setWhiteList;
bool layerAcceptable(const std::string& setname) const
{
if (setname.empty()) return true;
return _setWhiteList.count(setname)!=0;
}
bool readImageLayer(osgTerrain::ImageLayer* imageLayer, const osgDB::ReaderWriter::Options* options) const
{
if (!imageLayer->getImage() &&
!imageLayer->getFileName().empty())
{
if (layerAcceptable(imageLayer->getSetName()))
{
osg::ref_ptr<osg::Image> image = osgDB::readImageFile(imageLayer->getFileName(), options);
std::cout<<"ok readingImageLayer("<<imageLayer->getSetName()<<","<<imageLayer->getFileName()<<" success="<<image->valid()<<std::endl;
imageLayer->setImage(image.get());
}
else
{
std::cout<<"disallowed readingImageLayer("<<imageLayer->getSetName()<<","<<imageLayer->getFileName()<<std::endl;
}
}
return imageLayer->getImage()!=0;
}
virtual bool deferExternalLayerLoading() const
{
return true;
}
virtual void loaded(osgTerrain::TerrainTile* tile, const osgDB::ReaderWriter::Options* options) const
{
// read any external layers
for(unsigned int i=0; i<tile->getNumColorLayers(); ++i)
{
osgTerrain::Layer* layer = tile->getColorLayer(i);
osgTerrain::ImageLayer* imageLayer = dynamic_cast<osgTerrain::ImageLayer*>(layer);
if (imageLayer)
{
readImageLayer(imageLayer, options);
continue;
}
osgTerrain::SwitchLayer* switchLayer = dynamic_cast<osgTerrain::SwitchLayer*>(layer);
if (switchLayer)
{
for(unsigned int si=0; si<switchLayer->getNumLayers(); ++si)
{
osgTerrain::ImageLayer* imageLayer = dynamic_cast<osgTerrain::ImageLayer*>(switchLayer->getLayer(si));
if (imageLayer)
{
if (readImageLayer(imageLayer, options))
{
// replace SwitchLayer by
tile->setColorLayer(i, imageLayer);
continue;
}
}
}
continue;
}
osgTerrain::CompositeLayer* compositeLayer = dynamic_cast<osgTerrain::CompositeLayer*>(layer);
if (compositeLayer)
{
for(unsigned int ci=0; ci<compositeLayer->getNumLayers(); ++ci)
{
osgTerrain::ImageLayer* imageLayer = dynamic_cast<osgTerrain::ImageLayer*>(compositeLayer->getLayer(ci));
if (imageLayer)
{
readImageLayer(imageLayer, options);
}
}
continue;
}
}
// assign colour layers over missing layers
osgTerrain::Layer* validLayer = 0;
for(unsigned int i=0; i<tile->getNumColorLayers(); ++i)
{
osgTerrain::Layer* layer = tile->getColorLayer(i);
osgTerrain::ImageLayer* imageLayer = dynamic_cast<osgTerrain::ImageLayer*>(layer);
if (imageLayer)
{
if (imageLayer->getImage()!=0)
{
validLayer = imageLayer;
}
continue;
}
osgTerrain::SwitchLayer* switchLayer = dynamic_cast<osgTerrain::SwitchLayer*>(layer);
if (switchLayer)
{
for(unsigned int si=0; si<switchLayer->getNumLayers(); ++si)
{
osgTerrain::ImageLayer* imageLayer = dynamic_cast<osgTerrain::ImageLayer*>(switchLayer->getLayer(si));
if (imageLayer && imageLayer->getImage()!=0)
{
validLayer = imageLayer;
}
}
continue;
}
osgTerrain::CompositeLayer* compositeLayer = dynamic_cast<osgTerrain::CompositeLayer*>(layer);
if (compositeLayer)
{
for(unsigned int ci=0; ci<compositeLayer->getNumLayers(); ++ci)
{
osgTerrain::ImageLayer* imageLayer = dynamic_cast<osgTerrain::ImageLayer*>(switchLayer->getLayer(ci));
if (imageLayer && imageLayer->getImage()!=0)
{
validLayer = imageLayer;
}
}
continue;
}
}
if (validLayer)
{
// fill in any missing layers
for(unsigned int i=0; i<tile->getNumColorLayers(); ++i)
{
osgTerrain::Layer* layer = tile->getColorLayer(i);
osgTerrain::ImageLayer* imageLayer = dynamic_cast<osgTerrain::ImageLayer*>(layer);
if (imageLayer)
{
if (imageLayer->getImage()==0)
{
tile->setColorLayer(i, validLayer);
break;
}
continue;
}
osgTerrain::SwitchLayer* switchLayer = dynamic_cast<osgTerrain::SwitchLayer*>(layer);
if (switchLayer)
{
for(unsigned int si=0; si<switchLayer->getNumLayers(); ++si)
{
osgTerrain::ImageLayer* imageLayer = dynamic_cast<osgTerrain::ImageLayer*>(switchLayer->getLayer(si));
if (imageLayer && imageLayer->getImage()==0)
{
tile->setColorLayer(i, validLayer);
break;
}
}
continue;
}
osgTerrain::CompositeLayer* compositeLayer = dynamic_cast<osgTerrain::CompositeLayer*>(layer);
if (compositeLayer)
{
for(unsigned int ci=0; ci<compositeLayer->getNumLayers(); ++ci)
{
osgTerrain::ImageLayer* imageLayer = dynamic_cast<osgTerrain::ImageLayer*>(switchLayer->getLayer(ci));
if (imageLayer && imageLayer->getImage()==0)
{
tile->setColorLayer(i, validLayer);
break;
}
}
continue;
}
}
}
}
};
int main( int argc, char **argv )
{
// use an ArgumentParser object to manage the program arguments.
@ -427,25 +241,34 @@ int main( int argc, char **argv )
arguments.getApplicationUsage()->addCommandLineOption("-r","Set the terrain sample ratio.");
arguments.getApplicationUsage()->addCommandLineOption("--login <url> <username> <password>","Provide authentication information for http file access.");
// construct the viewer.
osgViewer::Viewer viewer(arguments);
// set the tile loaded callback to load the optional imagery
osg::ref_ptr<WhiteListTileLoadedCallback> whiteList = new WhiteListTileLoadedCallback;
osg::ref_ptr<osgTerrain::WhiteListTileLoadedCallback> whiteList = new osgTerrain::WhiteListTileLoadedCallback;
std::string setname;
while(arguments.read("--allow",setname))
{
whiteList->allow(setname);
}
while(arguments.read("--allow-all"))
{
whiteList->setAllowAll(true);
}
osgTerrain::TerrainTile::setTileLoadedCallback(whiteList.get());
// construct the viewer.
osgViewer::Viewer viewer(arguments);
// obtain the vertical scale
float verticalScale = 1.0f;
while(arguments.read("-v",verticalScale)) {}
// obtain the sample ratio
float sampleRatio = 1.0f;
while(arguments.read("-r",sampleRatio)) {}
// set up any authentication.
std::string url, username, password;
while(arguments.read("--login",url, username, password))
{
@ -545,6 +368,13 @@ int main( int argc, char **argv )
if (mtc)
{
numLayers = mtc->getNumTextureWeights();
// switch on just the first texture layer.
mtc->setTextureWeight(0,1.0f);
for(unsigned int i=1; i<numLayers; ++i)
{
mtc->setTextureWeight(i,0.0f);
}
}
if (numLayers<2)

View File

@ -354,6 +354,18 @@ class OSGTERRAIN_EXPORT ProxyLayer : public Layer
META_Object(osgTerrain, ProxyLayer);
/** Return image associated with layer if supported. */
virtual osg::Image* getImage()
{
return _implementation.valid() ? _implementation->getImage() : 0;
}
/** Return const image associated with layer if supported. */
virtual const osg::Image* getImage() const
{
return _implementation.valid() ? _implementation->getImage() : 0;
}
/** Set the implementation layer that does the actual work.*/
void setImplementation(Layer* layer) { _implementation = layer; }
@ -485,6 +497,22 @@ class OSGTERRAIN_EXPORT SwitchLayer : public CompositeLayer
void setActiveLayer(int i) { _activeLayer = i; }
int getActiveLayer() const { return _activeLayer; }
/** Return image associated with layer if supported. */
virtual osg::Image* getImage()
{
if (_activeLayer < 0) return 0;
if (_activeLayer >= static_cast<int>(getNumLayers())) return 0;
return _layers[_activeLayer].layer->getImage();
}
/** Return const image associated with layer if supported. */
virtual const osg::Image* getImage() const
{
if (_activeLayer < 0) return 0;
if (_activeLayer >= static_cast<int>(getNumLayers())) return 0;
return _layers[_activeLayer].layer->getImage();
}
protected:
virtual ~SwitchLayer() {}

View File

@ -208,6 +208,45 @@ class OSGTERRAIN_EXPORT TerrainTile : public osg::Group
bool _treatBoundariesToValidDataAsDefaultValue;
};
/** Helper callback for managing optional sets of layers, that loading of is deffered to this callback,
* with this callback working out which layers to load, and how to create fallback versions of the layers.
*/
class OSGTERRAIN_EXPORT WhiteListTileLoadedCallback : public TerrainTile::TileLoadedCallback
{
public:
WhiteListTileLoadedCallback();
void allow(const std::string& setname) { _setWhiteList.insert(setname); }
void setMinimumNumOfLayers(unsigned int numLayers) { _minumumNumberOfLayers = numLayers; }
unsigned int getMinimumNumOfLayers() const { return _minumumNumberOfLayers; }
void setReplaceSwitchLayer(bool replaceSwitchLayer) { _replaceSwitchLayer = replaceSwitchLayer; }
bool getReplaceSwitchLayer() const { return _replaceSwitchLayer; }
void setAllowAll(bool allowAll) { _allowAll = allowAll; }
bool getAllowAll() const { return _allowAll; }
bool layerAcceptable(const std::string& setname) const;
bool readImageLayer(osgTerrain::ImageLayer* imageLayer, const osgDB::ReaderWriter::Options* options) const;
virtual bool deferExternalLayerLoading() const;
virtual void loaded(osgTerrain::TerrainTile* tile, const osgDB::ReaderWriter::Options* options) const;
protected:
virtual ~WhiteListTileLoadedCallback();
typedef std::set<std::string> SetWhiteList;
SetWhiteList _setWhiteList;
unsigned int _minumumNumberOfLayers;
bool _replaceSwitchLayer;
bool _allowAll;
};
}
#endif

View File

@ -16,9 +16,16 @@
#include <osg/ClusterCullingCallback>
#include <osgDB/ReadFile>
using namespace osg;
using namespace osgTerrain;
/////////////////////////////////////////////////////////////////////////////////
//
// TerrainTile
//
void TerrainTile::setTileLoadedCallback(TerrainTile::TileLoadedCallback* lc)
{
getTileLoadedCallback() = lc;
@ -212,3 +219,212 @@ osg::BoundingSphere TerrainTile::computeBound() const
return bs;
}
/////////////////////////////////////////////////////////////////////////////////
//
// WhiteListTileLoadedCallback
//
WhiteListTileLoadedCallback::WhiteListTileLoadedCallback()
{
_minumumNumberOfLayers = 0;
_replaceSwitchLayer = true;
_allowAll = false;
}
WhiteListTileLoadedCallback::~WhiteListTileLoadedCallback()
{
}
bool WhiteListTileLoadedCallback::layerAcceptable(const std::string& setname) const
{
if (_allowAll) return true;
if (setname.empty()) return true;
return _setWhiteList.count(setname)!=0;
}
bool WhiteListTileLoadedCallback::readImageLayer(osgTerrain::ImageLayer* imageLayer, const osgDB::ReaderWriter::Options* options) const
{
if (!imageLayer->getImage() &&
!imageLayer->getFileName().empty())
{
if (layerAcceptable(imageLayer->getSetName()))
{
osg::ref_ptr<osg::Image> image = osgDB::readImageFile(imageLayer->getFileName(), options);
imageLayer->setImage(image.get());
}
}
return imageLayer->getImage()!=0;
}
bool WhiteListTileLoadedCallback::deferExternalLayerLoading() const
{
return true;
}
void WhiteListTileLoadedCallback::loaded(osgTerrain::TerrainTile* tile, const osgDB::ReaderWriter::Options* options) const
{
// read any external layers
for(unsigned int i=0; i<tile->getNumColorLayers(); ++i)
{
osgTerrain::Layer* layer = tile->getColorLayer(i);
osgTerrain::ImageLayer* imageLayer = dynamic_cast<osgTerrain::ImageLayer*>(layer);
if (imageLayer)
{
readImageLayer(imageLayer, options);
continue;
}
osgTerrain::SwitchLayer* switchLayer = dynamic_cast<osgTerrain::SwitchLayer*>(layer);
if (switchLayer)
{
for(unsigned int si=0; si<switchLayer->getNumLayers(); ++si)
{
osgTerrain::ImageLayer* imageLayer = dynamic_cast<osgTerrain::ImageLayer*>(switchLayer->getLayer(si));
if (imageLayer)
{
if (readImageLayer(imageLayer, options))
{
// replace SwitchLayer by
if (_replaceSwitchLayer) tile->setColorLayer(i, imageLayer);
else if (switchLayer->getActiveLayer()<0) switchLayer->setActiveLayer(si);
continue;
}
}
}
continue;
}
osgTerrain::CompositeLayer* compositeLayer = dynamic_cast<osgTerrain::CompositeLayer*>(layer);
if (compositeLayer)
{
for(unsigned int ci=0; ci<compositeLayer->getNumLayers(); ++ci)
{
osgTerrain::ImageLayer* imageLayer = dynamic_cast<osgTerrain::ImageLayer*>(compositeLayer->getLayer(ci));
if (imageLayer)
{
readImageLayer(imageLayer, options);
}
}
continue;
}
}
// assign colour layers over missing layers
osgTerrain::Layer* validLayer = 0;
for(unsigned int i=0; i<tile->getNumColorLayers(); ++i)
{
osgTerrain::Layer* layer = tile->getColorLayer(i);
osgTerrain::ImageLayer* imageLayer = dynamic_cast<osgTerrain::ImageLayer*>(layer);
if (imageLayer)
{
if (imageLayer->getImage()!=0)
{
validLayer = imageLayer;
}
continue;
}
osgTerrain::SwitchLayer* switchLayer = dynamic_cast<osgTerrain::SwitchLayer*>(layer);
if (switchLayer)
{
for(unsigned int si=0; si<switchLayer->getNumLayers(); ++si)
{
osgTerrain::ImageLayer* imageLayer = dynamic_cast<osgTerrain::ImageLayer*>(switchLayer->getLayer(si));
if (imageLayer && imageLayer->getImage()!=0)
{
validLayer = imageLayer;
}
}
continue;
}
osgTerrain::CompositeLayer* compositeLayer = dynamic_cast<osgTerrain::CompositeLayer*>(layer);
if (compositeLayer)
{
for(unsigned int ci=0; ci<compositeLayer->getNumLayers(); ++ci)
{
osgTerrain::ImageLayer* imageLayer = dynamic_cast<osgTerrain::ImageLayer*>(switchLayer->getLayer(ci));
if (imageLayer && imageLayer->getImage()!=0)
{
validLayer = imageLayer;
}
}
continue;
}
}
if (validLayer)
{
// fill in any missing layers
for(unsigned int i=0; i<tile->getNumColorLayers(); ++i)
{
osgTerrain::Layer* layer = tile->getColorLayer(i);
osgTerrain::ImageLayer* imageLayer = dynamic_cast<osgTerrain::ImageLayer*>(layer);
if (imageLayer)
{
if (imageLayer->getImage()==0)
{
tile->setColorLayer(i, validLayer);
break;
}
continue;
}
osgTerrain::SwitchLayer* switchLayer = dynamic_cast<osgTerrain::SwitchLayer*>(layer);
if (switchLayer)
{
for(unsigned int si=0; si<switchLayer->getNumLayers(); ++si)
{
osgTerrain::ImageLayer* imageLayer = dynamic_cast<osgTerrain::ImageLayer*>(switchLayer->getLayer(si));
if (imageLayer && imageLayer->getImage()==0)
{
if (_replaceSwitchLayer) tile->setColorLayer(i, imageLayer);
else
{
switchLayer->setLayer(si, validLayer);
if (switchLayer->getActiveLayer()<0) switchLayer->setActiveLayer(si);
}
break;
}
}
if (switchLayer->getNumLayers()==0)
{
if (_replaceSwitchLayer) tile->setColorLayer(i, validLayer);
else
{
switchLayer->setLayer(0, validLayer);
switchLayer->setActiveLayer(0);
}
}
}
osgTerrain::CompositeLayer* compositeLayer = dynamic_cast<osgTerrain::CompositeLayer*>(layer);
if (compositeLayer)
{
for(unsigned int ci=0; ci<compositeLayer->getNumLayers(); ++ci)
{
osgTerrain::ImageLayer* imageLayer = dynamic_cast<osgTerrain::ImageLayer*>(switchLayer->getLayer(ci));
if (imageLayer && imageLayer->getImage()==0)
{
tile->setColorLayer(i, validLayer);
break;
}
}
continue;
}
}
if (_minumumNumberOfLayers>tile->getNumColorLayers())
{
for(unsigned int i=tile->getNumColorLayers(); i<_minumumNumberOfLayers; ++i)
{
tile->setColorLayer(i, validLayer);
}
}
}
}