From f9fab3c3b010a7d6a8a298c638f2df025f2f59ff Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Mon, 16 Jul 2007 12:37:39 +0000 Subject: [PATCH] First steps at provide a .terrain file format to experiment with file definitions of terrain subgraphs --- examples/osgterrain/CMakeLists.txt | 2 +- examples/osgterrain/ReaderWriterTerrain.cpp | 245 ++++++++++++++++++++ examples/osgterrain/osgterrain.cpp | 28 ++- 3 files changed, 269 insertions(+), 6 deletions(-) create mode 100644 examples/osgterrain/ReaderWriterTerrain.cpp diff --git a/examples/osgterrain/CMakeLists.txt b/examples/osgterrain/CMakeLists.txt index 949b71d1a..ea1173e8e 100644 --- a/examples/osgterrain/CMakeLists.txt +++ b/examples/osgterrain/CMakeLists.txt @@ -1,7 +1,7 @@ #this file is automatically generated -SET(TARGET_SRC osgterrain.cpp ) +SET(TARGET_SRC osgterrain.cpp ReaderWriterTerrain.cpp) SET(TARGET_ADDED_LIBRARIES osgTerrain ) #### end var setup ### SETUP_EXAMPLE(osgterrain) diff --git a/examples/osgterrain/ReaderWriterTerrain.cpp b/examples/osgterrain/ReaderWriterTerrain.cpp new file mode 100644 index 000000000..a86472f83 --- /dev/null +++ b/examples/osgterrain/ReaderWriterTerrain.cpp @@ -0,0 +1,245 @@ +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +class ReaderWriterTerrain : public osgDB::ReaderWriter +{ + public: + + ReaderWriterTerrain() + { + } + + virtual const char* className() const { return "Terrain Reader"; } + + virtual bool acceptsExtension(const std::string& extension) const + { + return osgDB::equalCaseInsensitive(extension,"terrain"); + } + + virtual osgDB::ReaderWriter::ReadResult readNode(const std::string& file, const osgDB::ReaderWriter::Options* opt) const + { + std::string ext = osgDB::getLowerCaseFileExtension(file); + if (!acceptsExtension(ext)) return ReadResult::FILE_NOT_HANDLED; + + std::string fileName = osgDB::findDataFile( file, opt ); + if (fileName.empty()) return ReadResult::FILE_NOT_FOUND; + + // code for setting up the database path so that internally referenced file are searched for on relative paths. + osg::ref_ptr local_opt = opt ? static_cast(opt->clone(osg::CopyOp::SHALLOW_COPY)) : new Options; + local_opt->setDatabasePath(osgDB::getFilePath(fileName)); + + std::ifstream fin(fileName.c_str()); + if (fin) + { + return readNode(fin, local_opt.get()); + } + return 0L; + + } + + virtual osgDB::ReaderWriter::ReadResult readNode(std::istream& fin, const Options* options) const; + + osg::Node* readTerrainNode(osgDB::Input& fr) const; + osgTerrain::Layer* readLayer(osgDB::Input& fr) const; + +}; + +osgDB::ReaderWriter::ReadResult ReaderWriterTerrain::readNode(std::istream& fin, const osgDB::ReaderWriter::Options* options) const +{ + fin.imbue(std::locale::classic()); + + osgDB::Input fr; + fr.attach(&fin); + fr.setOptions(options); + + osg::notify(osg::NOTICE)<<"Reading terrain"< group = new osg::Group; + + while(!fr.eof()) + { + osg::notify(osg::NOTICE)<<"Read : "<addChild(node); + + fr += 2; + itrAdvanced = true; + } + + if (fr.matchSequence("TerrainNode {") || fr.matchSequence("Terrain {") ) + { + osg::Node* node = readTerrainNode(fr); + + itrAdvanced = true; + } + + + if (!itrAdvanced) ++fr; + } + + if (group->getNumChildren()>0) return group.release(); + else return 0; +} + +osg::Node* ReaderWriterTerrain::readTerrainNode(osgDB::Input& fr) const +{ + osg::ref_ptr terrain = new osgTerrain::TerrainNode; + + int entry = fr[0].getNoNestedBrackets(); + + fr += 2; + + while (!fr.eof() && fr[0].getNoNestedBrackets()>entry) + { + osg::notify(osg::NOTICE)<<"Terrain : "<setName(fr[1].getStr()); + + fr += 2; + itrAdvanced = true; + } + + if (fr.matchSequence("ElevationLayer {")) + { + osgTerrain::Layer* layer = readLayer(fr); + + if (layer) terrain->setElevationLayer(layer); + + itrAdvanced = true; + } + + if (fr.matchSequence("ColorLayer {") || fr.matchSequence("ColourLayer {") ) + { + osgTerrain::Layer* layer = readLayer(fr); + + if (layer) terrain->setColorLayer(0, layer); + + itrAdvanced = true; + } + + if (fr.matchSequence("ColorLayer %i {") || fr.matchSequence("ColourLayer %i {") ) + { + unsigned int layerNum; + fr[1].getUInt(layerNum); + + ++fr; + + osgTerrain::Layer* layer = readLayer(fr); + + if (layer) terrain->setColorLayer(layerNum, layer); + + itrAdvanced = true; + } + + if (!itrAdvanced) + { + ++fr; + } + } + + return terrain.release(); + +} + +osgTerrain::Layer* ReaderWriterTerrain::readLayer(osgDB::Input& fr) const +{ + osg::ref_ptr layer; + osg::ref_ptr locator; + + + + int entry = fr[0].getNoNestedBrackets(); + + fr += 2; + + while (!fr.eof() && fr[0].getNoNestedBrackets()>entry) + { + osg::notify(osg::NOTICE)<<"Layer : "< image = osgDB::readImageFile(fr[1].getStr()); + + if (image.valid()) + { + osg::ref_ptr imagelayer = new osgTerrain::ImageLayer; + imagelayer->setImage(image.get()); + + layer = imagelayer.get(); + } + + fr += 2; + itrAdvanced = true; + } + + if (fr.matchSequence("EllipsoidLocator %f %f %f %f")) + { + double x,y,w,h; + fr[1].getFloat(x); + fr[2].getFloat(y); + fr[3].getFloat(w); + fr[4].getFloat(h); + + locator = new osgTerrain::EllipsoidLocator(x,y,w,h,0); + + fr += 5; + itrAdvanced = true; + } + + if (fr.matchSequence("CartesianLocator %f %f %f %f")) + { + double x,y,w,h; + fr[1].getFloat(x); + fr[2].getFloat(y); + fr[3].getFloat(w); + fr[4].getFloat(h); + + locator = new osgTerrain::CartesianLocator(x,y,w,h,0); + + fr += 5; + itrAdvanced = true; + } + + if (!itrAdvanced) + { + ++fr; + } + } + + if (layer.valid() && locator.valid()) + { + layer->setLocator(locator.get()); + } + + return layer.release(); +} + + +// now register with Registry to instantiate the above +// reader/writer. +REGISTER_OSGPLUGIN(terrain, ReaderWriterTerrain) + diff --git a/examples/osgterrain/osgterrain.cpp b/examples/osgterrain/osgterrain.cpp index 35e32fbcf..7ff494709 100644 --- a/examples/osgterrain/osgterrain.cpp +++ b/examples/osgterrain/osgterrain.cpp @@ -48,9 +48,10 @@ #include + class FilterHandler : public osgGA::GUIEventHandler { -public: + public: FilterHandler(osgTerrain::GeometryTechnique* gt): _gt(gt) {} @@ -114,8 +115,8 @@ public: } -protected: - + protected: + osg::observer_ptr _gt; }; @@ -124,7 +125,7 @@ protected: class LayerHandler : public osgGA::GUIEventHandler { -public: + public: LayerHandler(osgTerrain::Layer* layer): _layer(layer) {} @@ -158,7 +159,7 @@ public: } -protected: + protected: osg::observer_ptr _layer; @@ -214,6 +215,23 @@ int main(int argc, char** argv) double y = 0.0; double w = 1.0; double h = 1.0; + + osg::ref_ptr test = osgDB::readNodeFile("test.terrain"); + + if (!test.valid()) return 0; + + viewer.setSceneData(test.get()); + viewer.realize(); + + while (!viewer.done()) + { + viewer.advance(); + viewer.eventTraversal(); + viewer.updateTraversal(); + viewer.frame(); + } + + return 0; osg::ref_ptr terrain = new osgTerrain::TerrainNode; osg::ref_ptr locator = new osgTerrain::EllipsoidLocator(-osg::PI, -osg::PI*0.5, 2.0*osg::PI, osg::PI, 0.0);