diff --git a/include/osgTerrain/Layer b/include/osgTerrain/Layer index 68467ad1c..027ebb4af 100644 --- a/include/osgTerrain/Layer +++ b/include/osgTerrain/Layer @@ -418,6 +418,51 @@ class OSGTERRAIN_EXPORT ProxyLayer : public Layer }; + + +class OSGTERRAIN_EXPORT SwitchLayer : public Layer +{ + public: + + SwitchLayer(); + + /** Copy constructor using CopyOp to manage deep vs shallow copy.*/ + SwitchLayer(const SwitchLayer& switchLayer,const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY); + + META_Object(osgTerrain, SwitchLayer); + + void clear(); + + void setActiveLayer(unsigned int i) { _activeLayer = i; } + unsigned int getActiveLayer() const { return _activeLayer; } + + void setFileName(unsigned int i, const std::string& filename) { _layers[i].first = filename; if (_layers[i].second.valid()) _layers[i].second->setFileName(filename); } + const std::string& getFileName(unsigned int i) const { return _layers[i].second.valid() ? _layers[i].second->getFileName() : _layers[i].first; } + + void setLayer(unsigned int i, Layer* layer) { _layers[i].second = layer; } + Layer* getLayer(unsigned int i) { return _layers[i].second.get(); } + const Layer* getLayer(unsigned int i) const { return _layers[i].second.get(); } + + void addLayer(const std::string& filename) { _layers.push_back(FileNameLayerPair(filename,0)); } + + void addLayer(Layer* layer) { _layers.push_back(FileNameLayerPair(layer->getFileName(),layer)); } + + void removeLayer(unsigned int i) { _layers.erase(_layers.begin()+i); } + + unsigned int getNumLayers() const { return _layers.size(); } + + protected: + + virtual ~SwitchLayer() {} + + typedef std::pair< std::string, osg::ref_ptr > FileNameLayerPair; + + typedef std::vector< FileNameLayerPair > Layers; + + unsigned int _activeLayer; + Layers _layers; +}; + } #endif diff --git a/src/osgPlugins/ive/CMakeLists.txt b/src/osgPlugins/ive/CMakeLists.txt index 063211542..6f959e3b4 100644 --- a/src/osgPlugins/ive/CMakeLists.txt +++ b/src/osgPlugins/ive/CMakeLists.txt @@ -20,6 +20,7 @@ SET(TARGET_SRC ClusterCullingCallback.cpp ColorMask.cpp CompositeLayer.cpp + SwitchLayer.cpp ConeSector.cpp ConvexPlanarOccluder.cpp ConvexPlanarPolygon.cpp @@ -133,6 +134,7 @@ SET(TARGET_H ClusterCullingCallback.h ColorMask.h CompositeLayer.h + SwitchLayer.h ConeSector.h ConvexPlanarOccluder.h ConvexPlanarPolygon.h diff --git a/src/osgPlugins/ive/DataInputStream.cpp b/src/osgPlugins/ive/DataInputStream.cpp index 9f1b58848..a9ae0f18f 100644 --- a/src/osgPlugins/ive/DataInputStream.cpp +++ b/src/osgPlugins/ive/DataInputStream.cpp @@ -105,6 +105,7 @@ #include "ImageLayer.h" #include "HeightFieldLayer.h" #include "CompositeLayer.h" +#include "SwitchLayer.h" #include "FadeText.h" #include "Text3D.h" @@ -1585,6 +1586,11 @@ osgTerrain::Layer* DataInputStream::readLayer() layer = new osgTerrain::ImageLayer; ((ive::ImageLayer*)(layer))->read(this); } + else if (layerid==IVESWITCHLAYER) + { + layer = new osgTerrain::SwitchLayer; + ((ive::SwitchLayer*)(layer))->read(this); + } else if (layerid==IVECOMPOSITELAYER) { layer = new osgTerrain::CompositeLayer; diff --git a/src/osgPlugins/ive/DataOutputStream.cpp b/src/osgPlugins/ive/DataOutputStream.cpp index 9facf704b..cd97deca7 100644 --- a/src/osgPlugins/ive/DataOutputStream.cpp +++ b/src/osgPlugins/ive/DataOutputStream.cpp @@ -106,6 +106,7 @@ #include "ImageLayer.h" #include "HeightFieldLayer.h" #include "CompositeLayer.h" +#include "SwitchLayer.h" #include #include @@ -1289,6 +1290,10 @@ void DataOutputStream::writeLayer(const osgTerrain::Layer* layer) { ((ive::ImageLayer*)(layer))->write(this); } + else if (dynamic_cast(layer)) + { + ((ive::SwitchLayer*)(layer))->write(this); + } else if (dynamic_cast(layer)) { ((ive::CompositeLayer*)(layer))->write(this); diff --git a/src/osgPlugins/ive/Layer.cpp b/src/osgPlugins/ive/Layer.cpp index 73aa79b8c..c5467a92b 100644 --- a/src/osgPlugins/ive/Layer.cpp +++ b/src/osgPlugins/ive/Layer.cpp @@ -19,6 +19,7 @@ #include "ImageLayer.h" #include "HeightFieldLayer.h" #include "CompositeLayer.h" +#include "SwitchLayer.h" #include @@ -108,6 +109,10 @@ void LayerHelper::writeLayer(DataOutputStream* out, osgTerrain::Layer* layer) { ((ive::ImageLayer*)(layer))->write(out); } + else if (dynamic_cast(layer)) + { + ((ive::SwitchLayer*)(layer))->write(out); + } else if (dynamic_cast(layer)) { ((ive::CompositeLayer*)(layer))->write(out); @@ -150,6 +155,12 @@ osgTerrain::Layer* LayerHelper::readLayer(DataInputStream* in) ((ive::ImageLayer*)(layer))->read(in); return layer; } + else if (id==IVESWITCHLAYER) + { + osgTerrain::SwitchLayer* layer = new osgTerrain::SwitchLayer; + ((ive::SwitchLayer*)(layer))->read(in); + return layer; + } else if (id==IVECOMPOSITELAYER) { osgTerrain::CompositeLayer* layer = new osgTerrain::CompositeLayer; diff --git a/src/osgPlugins/ive/ReadWrite.h b/src/osgPlugins/ive/ReadWrite.h index d8cb86d41..773f6299a 100644 --- a/src/osgPlugins/ive/ReadWrite.h +++ b/src/osgPlugins/ive/ReadWrite.h @@ -135,8 +135,9 @@ namespace ive { #define IVETERRAINTECHNIQUE 0x00200008 #define IVEGEOMETRYTECHNIQUE 0x00200009 #define IVEVALIDDATAOPERATOR 0x0020000A -#define IVEVALIDRANGE 0x0020000B -#define IVENODATAVALUE 0x0020000C +#define IVEVALIDRANGE 0x0020000B +#define IVENODATAVALUE 0x0020000C +#define IVESWITCHLAYER 0x0020000D //#define IVETERRAIN 0x0020000A // osgFX classes diff --git a/src/osgPlugins/ive/SwitchLayer.cpp b/src/osgPlugins/ive/SwitchLayer.cpp new file mode 100644 index 000000000..3c7da9f6c --- /dev/null +++ b/src/osgPlugins/ive/SwitchLayer.cpp @@ -0,0 +1,88 @@ +/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2008 Robert Osfield + * + * This library is open source and may be redistributed and/or modified under + * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or + * (at your option) any later version. The full license is in LICENSE file + * included with this distribution, and on the openscenegraph.org website. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * OpenSceneGraph Public License for more details. +*/ + +#include "Exception.h" +#include "SwitchLayer.h" +#include "Layer.h" + +using namespace ive; + +void SwitchLayer::write(DataOutputStream* out) +{ + // Write Layer's identification. + out->writeInt(IVESWITCHLAYER); + + // If the osg class is inherited by any other class we should also write this to file. + osgTerrain::Layer* layer = dynamic_cast(this); + if (layer) + ((ive::Layer*)(layer))->write(out); + else + throw Exception("SwitchLayer::write(): Could not cast this osgLayer::SwitchLayer to an osgTerrain::Layer."); + + + out->writeUInt(getActiveLayer()); + + LayerHelper helper; + + out->writeUInt(getNumLayers()); + for(unsigned int i=0; iwriteBool(true); + helper.writeLayer(out, getLayer(i)); + } + else + { + out->writeBool(false); + out->writeString(getFileName(i)); + } + } +} + +void SwitchLayer::read(DataInputStream* in) +{ + // Peek on Layer's identification. + int id = in->peekInt(); + if (id != IVESWITCHLAYER) + throw Exception("SwitchLayer::read(): Expected SwitchLayer identification."); + + // Read Layer's identification. + id = in->readInt(); + + // If the osg class is inherited by any other class we should also read this from file. + osgTerrain::Layer* layer = dynamic_cast(this); + if (layer) + ((ive::Layer*)(layer))->read(in); + else + throw Exception("SwitchLayer::read(): Could not cast this osgLayer::Layer to an osg::Group."); + + + setActiveLayer(in->readUInt()); + + LayerHelper helper; + + unsigned int numLayers = in->readUInt(); + for(unsigned int i=0; ireadBool(); + if (readInlineLayer) + { + addLayer(helper.readLayer(in)); + } + else + { + addLayer(in->readString()); + } + } +} diff --git a/src/osgPlugins/ive/SwitchLayer.h b/src/osgPlugins/ive/SwitchLayer.h new file mode 100644 index 000000000..05f4dcacc --- /dev/null +++ b/src/osgPlugins/ive/SwitchLayer.h @@ -0,0 +1,19 @@ +#ifndef IVE_SWITCHLAYER +#define IVE_SWITCHLAYER 1 + +#include +#include "ReadWrite.h" + +namespace ive +{ + +class SwitchLayer : public osgTerrain::SwitchLayer, public ReadWrite +{ +public: + void write(DataOutputStream* out); + void read(DataInputStream* in); +}; + +} + +#endif diff --git a/src/osgPlugins/osgTerrain/CMakeLists.txt b/src/osgPlugins/osgTerrain/CMakeLists.txt index 3c55676d6..f5c3bd3da 100644 --- a/src/osgPlugins/osgTerrain/CMakeLists.txt +++ b/src/osgPlugins/osgTerrain/CMakeLists.txt @@ -6,6 +6,7 @@ SET(TARGET_SRC ImageLayer.cpp HeightFieldLayer.cpp CompositeLayer.cpp + SwitchLayer.cpp Layer.cpp TerrainTile.cpp GeometryTechnique.cpp diff --git a/src/osgPlugins/osgTerrain/SwitchLayer.cpp b/src/osgPlugins/osgTerrain/SwitchLayer.cpp new file mode 100644 index 000000000..e22e96bf0 --- /dev/null +++ b/src/osgPlugins/osgTerrain/SwitchLayer.cpp @@ -0,0 +1,170 @@ +/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2008 Robert Osfield + * + * This library is open source and may be redistributed and/or modified under + * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or + * (at your option) any later version. The full license is in LICENSE file + * included with this distribution, and on the openscenegraph.org website. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * OpenSceneGraph Public License for more details. +*/ + +#include + +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include + +bool SwitchLayer_readLocalData(osg::Object &obj, osgDB::Input &fr); +bool SwitchLayer_writeLocalData(const osg::Object &obj, osgDB::Output &fw); + +osgDB::RegisterDotOsgWrapperProxy SwitchLayer_Proxy +( + new osgTerrain::SwitchLayer, + "SwitchLayer", + "Object SwitchLayer Layer", + SwitchLayer_readLocalData, + SwitchLayer_writeLocalData +); + +bool SwitchLayer_readLocalData(osg::Object& obj, osgDB::Input &fr) +{ + osgTerrain::SwitchLayer& layer = static_cast(obj); + + bool itrAdvanced = false; + + osg::ref_ptr locator = 0; + + unsigned int i; + if (fr.read("ActiveLayer",i)) layer.setActiveLayer(i); + + do + { + itrAdvanced = false; + + osg::ref_ptr readObject = fr.readObjectOfType(osgDB::type_wrapper()); + locator = dynamic_cast(readObject.get()); + if (readObject.valid()) itrAdvanced = true; + + unsigned int minLevel=0; + if (fr.read("MinLevel",minLevel)) + { + itrAdvanced = true; + } + + unsigned int maxLevel = MAXIMUM_NUMBER_OF_LEVELS; + if (fr.read("MaxLevel",maxLevel)) + { + itrAdvanced = true; + } + + if (fr.matchSequence("file %s") || fr.matchSequence("file %w") ) + { + layer.addLayer(fr[1].getStr()); + fr += 2; + + itrAdvanced = true; + } + else if (fr.matchSequence("ProxyLayer %s") || fr.matchSequence("ProxyLayer %w")) + { + osgTerrain::ProxyLayer* proxyLayer = new osgTerrain::ProxyLayer; + proxyLayer->setFileName(fr[1].getStr()); + + if (locator.valid()) proxyLayer->setLocator(locator.get()); + if (minLevel!=0) proxyLayer->setMinLevel(minLevel); + if (maxLevel!=MAXIMUM_NUMBER_OF_LEVELS) proxyLayer->setMaxLevel(maxLevel); + + layer.addLayer(proxyLayer); + + fr += 2; + + itrAdvanced = true; + } + else + { + osg::ref_ptr readObject = fr.readObjectOfType(osgDB::type_wrapper()); + osgTerrain::Layer* readLayer = dynamic_cast(readObject.get()); + if (readLayer) + { + if (locator.valid()) + { + readLayer->setLocator(locator.get()); + locator = 0; + } + + if (minLevel!=0) readLayer->setMinLevel(minLevel); + if (maxLevel!=MAXIMUM_NUMBER_OF_LEVELS) readLayer->setMaxLevel(maxLevel); + + layer.addLayer(readLayer); + } + + if (readObject.valid()) itrAdvanced = true; + } + + } while (itrAdvanced); + + if (locator.valid()) layer.setLocator(locator.get()); + + return itrAdvanced; +} + +bool SwitchLayer_writeLocalData(const osg::Object& obj, osgDB::Output& fw) +{ + const osgTerrain::SwitchLayer& layer = static_cast(obj); + + fw.indent()<<"ActiveLayer "<(layer.getLayer(i)); + if (proxyLayer) + { + if (!proxyLayer->getFileName().empty()) + { + const osgTerrain::Locator* locator = proxyLayer->getLocator(); + if (locator && !locator->getDefinedInFile()) + { + fw.writeObject(*locator); + } + + if (proxyLayer->getMinLevel()!=0) + { + fw.indent()<<"MinLevel "<getMinLevel()<getMaxLevel()!=MAXIMUM_NUMBER_OF_LEVELS) + { + fw.indent()<<"MaxLevel "<getMaxLevel()<getFileName()<