diff --git a/examples/osgmultitexturecontrol/osgmultitexturecontrol.cpp b/examples/osgmultitexturecontrol/osgmultitexturecontrol.cpp index bdd15d128..f671b8f96 100644 --- a/examples/osgmultitexturecontrol/osgmultitexturecontrol.cpp +++ b/examples/osgmultitexturecontrol/osgmultitexturecontrol.cpp @@ -233,192 +233,6 @@ protected: osg::ref_ptr _terrain; }; - -struct WhiteListTileLoadedCallback : public osgTerrain::TerrainTile::TileLoadedCallback -{ - WhiteListTileLoadedCallback() - { - } - - void allow(const std::string& setname) { _setWhiteList.insert(setname); } - - typedef std::set 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 image = osgDB::readImageFile(imageLayer->getFileName(), options); - std::cout<<"ok readingImageLayer("<getSetName()<<","<getFileName()<<" success="<valid()<setImage(image.get()); - } - else - { - std::cout<<"disallowed readingImageLayer("<getSetName()<<","<getFileName()<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; igetNumColorLayers(); ++i) - { - osgTerrain::Layer* layer = tile->getColorLayer(i); - osgTerrain::ImageLayer* imageLayer = dynamic_cast(layer); - if (imageLayer) - { - readImageLayer(imageLayer, options); - continue; - } - - osgTerrain::SwitchLayer* switchLayer = dynamic_cast(layer); - if (switchLayer) - { - for(unsigned int si=0; sigetNumLayers(); ++si) - { - osgTerrain::ImageLayer* imageLayer = dynamic_cast(switchLayer->getLayer(si)); - if (imageLayer) - { - if (readImageLayer(imageLayer, options)) - { - // replace SwitchLayer by - tile->setColorLayer(i, imageLayer); - continue; - } - } - } - continue; - } - - osgTerrain::CompositeLayer* compositeLayer = dynamic_cast(layer); - if (compositeLayer) - { - for(unsigned int ci=0; cigetNumLayers(); ++ci) - { - osgTerrain::ImageLayer* imageLayer = dynamic_cast(compositeLayer->getLayer(ci)); - if (imageLayer) - { - readImageLayer(imageLayer, options); - } - } - continue; - } - } - - // assign colour layers over missing layers - osgTerrain::Layer* validLayer = 0; - for(unsigned int i=0; igetNumColorLayers(); ++i) - { - osgTerrain::Layer* layer = tile->getColorLayer(i); - osgTerrain::ImageLayer* imageLayer = dynamic_cast(layer); - if (imageLayer) - { - if (imageLayer->getImage()!=0) - { - validLayer = imageLayer; - } - continue; - } - - osgTerrain::SwitchLayer* switchLayer = dynamic_cast(layer); - if (switchLayer) - { - for(unsigned int si=0; sigetNumLayers(); ++si) - { - osgTerrain::ImageLayer* imageLayer = dynamic_cast(switchLayer->getLayer(si)); - if (imageLayer && imageLayer->getImage()!=0) - { - validLayer = imageLayer; - } - } - continue; - } - - osgTerrain::CompositeLayer* compositeLayer = dynamic_cast(layer); - if (compositeLayer) - { - for(unsigned int ci=0; cigetNumLayers(); ++ci) - { - osgTerrain::ImageLayer* imageLayer = dynamic_cast(switchLayer->getLayer(ci)); - if (imageLayer && imageLayer->getImage()!=0) - { - validLayer = imageLayer; - } - } - continue; - } - } - - if (validLayer) - { - // fill in any missing layers - for(unsigned int i=0; igetNumColorLayers(); ++i) - { - osgTerrain::Layer* layer = tile->getColorLayer(i); - osgTerrain::ImageLayer* imageLayer = dynamic_cast(layer); - if (imageLayer) - { - if (imageLayer->getImage()==0) - { - tile->setColorLayer(i, validLayer); - break; - } - continue; - } - - osgTerrain::SwitchLayer* switchLayer = dynamic_cast(layer); - if (switchLayer) - { - for(unsigned int si=0; sigetNumLayers(); ++si) - { - osgTerrain::ImageLayer* imageLayer = dynamic_cast(switchLayer->getLayer(si)); - if (imageLayer && imageLayer->getImage()==0) - { - tile->setColorLayer(i, validLayer); - break; - } - } - continue; - } - - osgTerrain::CompositeLayer* compositeLayer = dynamic_cast(layer); - if (compositeLayer) - { - for(unsigned int ci=0; cigetNumLayers(); ++ci) - { - osgTerrain::ImageLayer* imageLayer = dynamic_cast(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 ","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 whiteList = new WhiteListTileLoadedCallback; + osg::ref_ptr 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; isetTextureWeight(i,0.0f); + } } if (numLayers<2) diff --git a/include/osgTerrain/Layer b/include/osgTerrain/Layer index 4caf0d217..92ea84b66 100644 --- a/include/osgTerrain/Layer +++ b/include/osgTerrain/Layer @@ -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(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(getNumLayers())) return 0; + return _layers[_activeLayer].layer->getImage(); + } + protected: virtual ~SwitchLayer() {} diff --git a/include/osgTerrain/TerrainTile b/include/osgTerrain/TerrainTile index 726e58bf0..a91d80c98 100644 --- a/include/osgTerrain/TerrainTile +++ b/include/osgTerrain/TerrainTile @@ -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 SetWhiteList; + SetWhiteList _setWhiteList; + unsigned int _minumumNumberOfLayers; + bool _replaceSwitchLayer; + bool _allowAll; + +}; + } #endif diff --git a/src/osgTerrain/TerrainTile.cpp b/src/osgTerrain/TerrainTile.cpp index c43ac8c4d..bf273d78c 100644 --- a/src/osgTerrain/TerrainTile.cpp +++ b/src/osgTerrain/TerrainTile.cpp @@ -16,9 +16,16 @@ #include +#include + + 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 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; igetNumColorLayers(); ++i) + { + osgTerrain::Layer* layer = tile->getColorLayer(i); + osgTerrain::ImageLayer* imageLayer = dynamic_cast(layer); + if (imageLayer) + { + readImageLayer(imageLayer, options); + continue; + } + + osgTerrain::SwitchLayer* switchLayer = dynamic_cast(layer); + if (switchLayer) + { + for(unsigned int si=0; sigetNumLayers(); ++si) + { + osgTerrain::ImageLayer* imageLayer = dynamic_cast(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(layer); + if (compositeLayer) + { + for(unsigned int ci=0; cigetNumLayers(); ++ci) + { + osgTerrain::ImageLayer* imageLayer = dynamic_cast(compositeLayer->getLayer(ci)); + if (imageLayer) + { + readImageLayer(imageLayer, options); + } + } + continue; + } + } + + // assign colour layers over missing layers + osgTerrain::Layer* validLayer = 0; + for(unsigned int i=0; igetNumColorLayers(); ++i) + { + osgTerrain::Layer* layer = tile->getColorLayer(i); + osgTerrain::ImageLayer* imageLayer = dynamic_cast(layer); + if (imageLayer) + { + if (imageLayer->getImage()!=0) + { + validLayer = imageLayer; + } + continue; + } + + osgTerrain::SwitchLayer* switchLayer = dynamic_cast(layer); + if (switchLayer) + { + for(unsigned int si=0; sigetNumLayers(); ++si) + { + osgTerrain::ImageLayer* imageLayer = dynamic_cast(switchLayer->getLayer(si)); + if (imageLayer && imageLayer->getImage()!=0) + { + validLayer = imageLayer; + } + } + continue; + } + + osgTerrain::CompositeLayer* compositeLayer = dynamic_cast(layer); + if (compositeLayer) + { + for(unsigned int ci=0; cigetNumLayers(); ++ci) + { + osgTerrain::ImageLayer* imageLayer = dynamic_cast(switchLayer->getLayer(ci)); + if (imageLayer && imageLayer->getImage()!=0) + { + validLayer = imageLayer; + } + } + continue; + } + } + + if (validLayer) + { + // fill in any missing layers + for(unsigned int i=0; igetNumColorLayers(); ++i) + { + osgTerrain::Layer* layer = tile->getColorLayer(i); + osgTerrain::ImageLayer* imageLayer = dynamic_cast(layer); + if (imageLayer) + { + if (imageLayer->getImage()==0) + { + tile->setColorLayer(i, validLayer); + break; + } + continue; + } + + osgTerrain::SwitchLayer* switchLayer = dynamic_cast(layer); + if (switchLayer) + { + for(unsigned int si=0; sigetNumLayers(); ++si) + { + osgTerrain::ImageLayer* imageLayer = dynamic_cast(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(layer); + if (compositeLayer) + { + for(unsigned int ci=0; cigetNumLayers(); ++ci) + { + osgTerrain::ImageLayer* imageLayer = dynamic_cast(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); + } + } + + } +}