From fced94fab3df9f36d9aa63a0b84fa0eb330efee2 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Sun, 2 May 2004 21:50:15 +0000 Subject: [PATCH] Added support for decoration of the osgTerrain::DataSet generated databases with a CoordinateSystemNode which reflect the coordinate system of the database. Added support for reading and writing CoordianteSystemNode into the .osg and .ive formats. --- include/osg/CoordinateSystemNode | 2 +- include/osg/NodeVisitor | 3 + include/osgTerrain/DataSet | 16 ++++- src/osgDB/Field.cpp | 2 +- src/osgPlugins/ive/CoordinateSystemNode.cpp | 76 +++++++++++++++++++++ src/osgPlugins/ive/CoordinateSystemNode.h | 15 ++++ src/osgPlugins/ive/DataInputStream.cpp | 5 ++ src/osgPlugins/ive/DataOutputStream.cpp | 4 ++ src/osgPlugins/ive/EllipsoidModel.cpp | 62 +++++++++++++++++ src/osgPlugins/ive/EllipsoidModel.h | 15 ++++ src/osgPlugins/ive/GNUmakefile | 2 + src/osgPlugins/ive/ReadWrite.h | 2 + src/osgPlugins/osg/CoordinateSystemNode.cpp | 60 ++++++++++++++++ src/osgPlugins/osg/EllipsoidModel.cpp | 67 ++++++++++++++++++ src/osgPlugins/osg/GNUmakefile | 4 +- src/osgTerrain/DataSet.cpp | 34 +++++++++ 16 files changed, 363 insertions(+), 6 deletions(-) create mode 100644 src/osgPlugins/ive/CoordinateSystemNode.cpp create mode 100644 src/osgPlugins/ive/CoordinateSystemNode.h create mode 100644 src/osgPlugins/ive/EllipsoidModel.cpp create mode 100644 src/osgPlugins/ive/EllipsoidModel.h create mode 100644 src/osgPlugins/osg/CoordinateSystemNode.cpp create mode 100644 src/osgPlugins/osg/EllipsoidModel.cpp diff --git a/include/osg/CoordinateSystemNode b/include/osg/CoordinateSystemNode index f80b9bb99..a75e3850a 100644 --- a/include/osg/CoordinateSystemNode +++ b/include/osg/CoordinateSystemNode @@ -93,7 +93,7 @@ class SG_EXPORT CoordinateSystemNode : public Group /** Set the CoordinateSystem reference string, should be stored in OpenGIS Well Know Text form.*/ - void setCoordnateSystem(const std::string& WKT) { _WKT = WKT; } + void setCoordinateSystem(const std::string& WKT) { _WKT = WKT; } /** Get the CoordinateSystem reference string.*/ const std::string& getCoordinateSystem() const { return _WKT; } diff --git a/include/osg/NodeVisitor b/include/osg/NodeVisitor index 572e64af5..0de01a8c4 100644 --- a/include/osg/NodeVisitor +++ b/include/osg/NodeVisitor @@ -36,6 +36,7 @@ class Impostor; class ClearNode; class OccluderNode; class Sequence; +class CoordinateSystemNode; /** Visitor for type safe operations on osg::Node's. Based on GOF's Visitor pattern. The NodeVisitor @@ -221,6 +222,8 @@ class SG_EXPORT NodeVisitor : public virtual Referenced virtual void apply(Projection& node) { apply((Group&)node); } + virtual void apply(CoordinateSystemNode& node) { apply((Group&)node); } + virtual void apply(ClipNode& node) { apply((Group&)node); } virtual void apply(LightSource& node) { apply((Group&)node); } diff --git a/include/osgTerrain/DataSet b/include/osgTerrain/DataSet index a5477c9b6..8ce3937bc 100644 --- a/include/osgTerrain/DataSet +++ b/include/osgTerrain/DataSet @@ -91,13 +91,16 @@ class OSGTERRAIN_EXPORT DataSet : public osg::Referenced struct DestinationData : public osg::Referenced, SpatialProperties { - DestinationData(): + DestinationData(DataSet* dataSet): + _dataSet(dataSet), _minDistance(0.0), _maxDistance(FLT_MAX) {} typedef std::vector< osg::ref_ptr > ModelList; + DataSet* _dataSet; + float _minDistance; float _maxDistance; @@ -903,6 +906,9 @@ class OSGTERRAIN_EXPORT DataSet : public osg::Referenced void setUseLocalTileTransform(bool flag) { _useLocalTileTransform = flag; } bool getUseLocalTileTransform() const { return _useLocalTileTransform; } + void setDecorateGeneratedSceneGraphWithCoordinateSystemNode(bool flag) { _decorateWithCoordinateSystemNode = flag; } + bool getDecorateGeneratedSceneGraphWithCoordinateSystemNode() const { return _decorateWithCoordinateSystemNode; } + CompositeDestination* createDestinationGraph(CompositeDestination* parent, @@ -937,6 +943,8 @@ class OSGTERRAIN_EXPORT DataSet : public osg::Referenced void _equalizeRow(Row& row); void _writeRow(Row& row); + osg::CoordinateSystemNode* decorateWithCoordinateSystemNode(osg::Node* subgraph); + void init(); osg::ref_ptr _sourceGraph; @@ -949,8 +957,8 @@ class OSGTERRAIN_EXPORT DataSet : public osg::Referenced float _radiusToMaxVisibleDistanceRatio; float _verticalScale; - osg::ref_ptr _destinationCoordinateSystem; - osg::ref_ptr _intermediateCoordinateSystem; + osg::ref_ptr _destinationCoordinateSystem; + osg::ref_ptr _intermediateCoordinateSystem; bool _convertFromGeographicToGeocentric; osg::ref_ptr _ellipsoidModel; @@ -964,6 +972,8 @@ class OSGTERRAIN_EXPORT DataSet : public osg::Referenced GeometryType _geometryType; TextureType _textureType; bool _useLocalTileTransform; + + bool _decorateWithCoordinateSystemNode; osg::ref_ptr _rootNode; diff --git a/src/osgDB/Field.cpp b/src/osgDB/Field.cpp index c1e5b9b51..36dc57b34 100644 --- a/src/osgDB/Field.cpp +++ b/src/osgDB/Field.cpp @@ -365,7 +365,7 @@ bool Field::getFloat(double& f) const getFieldType(); if (_fieldType==REAL || _fieldType==INTEGER) { - f = (float)atof(_fieldCache); + f = atof(_fieldCache); return true; } else diff --git a/src/osgPlugins/ive/CoordinateSystemNode.cpp b/src/osgPlugins/ive/CoordinateSystemNode.cpp new file mode 100644 index 000000000..beeac2820 --- /dev/null +++ b/src/osgPlugins/ive/CoordinateSystemNode.cpp @@ -0,0 +1,76 @@ +/********************************************************************** + * + * FILE: CoordinateSystemNode.cpp + * + * DESCRIPTION: Read/Write osg::CoordinateSystemNode in binary format to disk. + * + * CREATED BY: Auto generated by iveGenerator + * and later modified by Rune Schmidt Jensen. + * + * HISTORY: Created 9.4.2003 + * + * Copyright 2003 VR-C + **********************************************************************/ + +#include "Exception.h" +#include "CoordinateSystemNode.h" +#include "EllipsoidModel.h" +#include "Group.h" + +using namespace ive; + +void CoordinateSystemNode::write(DataOutputStream* out) +{ + // Write CoordinateSystemNode's identification. + out->writeInt(IVECOORDINATESYSTEMNODE); + // If the osg class is inherited by any other class we should also write this to file. + osg::Group* group = dynamic_cast(this); + if(group){ + ((ive::Group*)(group))->write(out); + } + else + throw Exception("CoordinateSystemNode::write(): Could not cast this osg::CoordinateSystemNode to an osg::Group."); + // Write CoordinateSystemNode's properties. + + out->writeString(getCoordinateSystem()); + + out->writeBool(getEllipsoidModel()!=0); + if(getEllipsoidModel()) + { + ((ive::EllipsoidModel*)(getEllipsoidModel()))->write(out); + } + +} + +void CoordinateSystemNode::read(DataInputStream* in){ + // Peek on CoordinateSystemNode's identification. + int id = in->peekInt(); + if(id == IVECOORDINATESYSTEMNODE) + { + // Read CoordinateSystemNode's identification. + id = in->readInt(); + // If the osg class is inherited by any other class we should also read this from file. + osg::Group* group = dynamic_cast(this); + if(group){ + ((ive::Group*)(group))->read(in); + } + else + throw Exception("CoordinateSystemNode::read(): Could not cast this osg::CoordinateSystemNode to an osg::Group."); + // Read CoordinateSystemNode's properties + + // Read coord string + setCoordinateSystem( in->readString()); + + bool readEllopsoidModel = in->readBool(); + if (readEllopsoidModel) + { + osg::EllipsoidModel* em = new osg::EllipsoidModel(); + ((ive::EllipsoidModel*)(em))->read(in); + setEllipsoidModel(em); + } + + } + else{ + throw Exception("CoordinateSystemNode::read(): Expected CoordinateSystemNode identification."); + } +} diff --git a/src/osgPlugins/ive/CoordinateSystemNode.h b/src/osgPlugins/ive/CoordinateSystemNode.h new file mode 100644 index 000000000..d65eaf35d --- /dev/null +++ b/src/osgPlugins/ive/CoordinateSystemNode.h @@ -0,0 +1,15 @@ +#ifndef IVE_COORDINATESYSTEMNODE +#define IVE_COORDINATESYSTEMNODE 1 + +#include +#include "ReadWrite.h" + +namespace ive{ +class CoordinateSystemNode : public osg::CoordinateSystemNode, public ReadWrite { +public: + void write(DataOutputStream* out); + void read(DataInputStream* in); +}; +} + +#endif diff --git a/src/osgPlugins/ive/DataInputStream.cpp b/src/osgPlugins/ive/DataInputStream.cpp index 3ddf05af8..7cfabd5f4 100644 --- a/src/osgPlugins/ive/DataInputStream.cpp +++ b/src/osgPlugins/ive/DataInputStream.cpp @@ -47,6 +47,7 @@ #include "Switch.h" #include "OccluderNode.h" #include "Impostor.h" +#include "CoordinateSystemNode.h" #include "LightPointNode.h" #include "MultiSwitch.h" @@ -826,6 +827,10 @@ osg::Node* DataInputStream::readNode() node = new osg::PagedLOD(); ((ive::PagedLOD*)(node))->read(this); } + else if(nodeTypeID== IVECOORDINATESYSTEMNODE){ + node = new osg::CoordinateSystemNode(); + ((ive::CoordinateSystemNode*)(node))->read(this); + } else if(nodeTypeID== IVESWITCH){ node = new osg::Switch(); ((ive::Switch*)(node))->read(this); diff --git a/src/osgPlugins/ive/DataOutputStream.cpp b/src/osgPlugins/ive/DataOutputStream.cpp index b92d9cd80..7f1fbb8d3 100644 --- a/src/osgPlugins/ive/DataOutputStream.cpp +++ b/src/osgPlugins/ive/DataOutputStream.cpp @@ -49,6 +49,7 @@ #include "Switch.h" #include "OccluderNode.h" #include "Impostor.h" +#include "CoordinateSystemNode.h" #include "LightPointNode.h" #include "MultiSwitch.h" @@ -611,6 +612,9 @@ void DataOutputStream::writeNode(const osg::Node* node) else if(dynamic_cast(node)){ ((ive::Switch*)(node))->write(this); } + else if(dynamic_cast(node)){ + ((ive::CoordinateSystemNode*)(node))->write(this); + } else if(dynamic_cast(node)){ ((ive::MultiSwitch*)(node))->write(this); } diff --git a/src/osgPlugins/ive/EllipsoidModel.cpp b/src/osgPlugins/ive/EllipsoidModel.cpp new file mode 100644 index 000000000..eb6849894 --- /dev/null +++ b/src/osgPlugins/ive/EllipsoidModel.cpp @@ -0,0 +1,62 @@ +/********************************************************************** + * + * FILE: EllipsoidModel.cpp + * + * DESCRIPTION: Read/Write osg::EllipsoidModel in binary format to disk. + * + * CREATED BY: Auto generated by iveGenerator + * and later modified by Rune Schmidt Jensen. + * + * HISTORY: Created 23.4.2003 + * + * Copyright 2003 VR-C + **********************************************************************/ + +#include "Exception.h" +#include "Object.h" +#include "EllipsoidModel.h" +#include "ConvexPlanarPolygon.h" + +using namespace ive; + +void EllipsoidModel::write(DataOutputStream* out){ + // Write EllipsoidModel's identification. + out->writeInt(IVEELLIPSOIDMODEL); + // If the osg class is inherited by any other class we should also write this to file. + osg::Object* obj = dynamic_cast(this); + if(obj){ + ((ive::Object*)(obj))->write(out); + } + else + throw Exception("EllipsoidModel::write(): Could not cast this osg::EllipsoidModel to an osg::Object."); + // Write EllipsoidModel's properties. + + out->writeDouble(getRadiusEquator()); + out->writeDouble(getRadiusPolar()); + +} + +void EllipsoidModel::read(DataInputStream* in){ + // Peek on EllipsoidModel's identification. + int id = in->peekInt(); + if(id == IVEELLIPSOIDMODEL){ + // Read EllipsoidModel's identification. + id = in->readInt(); + // If the osg class is inherited by any other class we should also read this from file. + osg::Object* obj = dynamic_cast(this); + if(obj){ + ((ive::Object*)(obj))->read(in); + } + else + throw Exception("EllipsoidModel::read(): Could not cast this osg::EllipsoidModel to an osg::Object."); + // Read EllipsoidModel's properties + + setRadiusEquator(in->readDouble()); + setRadiusPolar(in->readDouble()); + + + } + else{ + throw Exception("EllipsoidModel::read(): Expected EllipsoidModel identification."); + } +} diff --git a/src/osgPlugins/ive/EllipsoidModel.h b/src/osgPlugins/ive/EllipsoidModel.h new file mode 100644 index 000000000..2162245d0 --- /dev/null +++ b/src/osgPlugins/ive/EllipsoidModel.h @@ -0,0 +1,15 @@ +#ifndef IVE_ELLIPSOIDMODEL +#define IVE_ELLIPSOIDMODEL 1 + +#include +#include "ReadWrite.h" + +namespace ive{ +class EllipsoidModel : public osg::EllipsoidModel, public ReadWrite { +public: + void write(DataOutputStream* out); + void read(DataInputStream* in); +}; +} + +#endif diff --git a/src/osgPlugins/ive/GNUmakefile b/src/osgPlugins/ive/GNUmakefile index cb6e52813..f684be3d8 100644 --- a/src/osgPlugins/ive/GNUmakefile +++ b/src/osgPlugins/ive/GNUmakefile @@ -9,6 +9,7 @@ CXXFILES =\ BlendFunc.cpp\ ConvexPlanarOccluder.cpp\ ConvexPlanarPolygon.cpp\ + CoordinateSystemNode.cpp\ ClusterCullingCallback.cpp\ CullFace.cpp\ DataInputStream.cpp\ @@ -20,6 +21,7 @@ CXXFILES =\ DrawElementsUShort.cpp\ DrawElementsUInt.cpp\ Drawable.cpp\ + EllipsoidModel.cpp\ Exception.cpp\ Geode.cpp\ Geometry.cpp\ diff --git a/src/osgPlugins/ive/ReadWrite.h b/src/osgPlugins/ive/ReadWrite.h index a0552c316..a901da172 100644 --- a/src/osgPlugins/ive/ReadWrite.h +++ b/src/osgPlugins/ive/ReadWrite.h @@ -29,6 +29,8 @@ namespace ive { #define IVECONVEXPLANARPOLYGON 0x00000020 #define IVEPAGEDLOD 0x00000021 #define IVEDOFTRANSFORM 0x00000022 +#define IVECOORDINATESYSTEMNODE 0x00000023 +#define IVEELLIPSOIDMODEL 0x00000024 // Node callbacks #define IVENODECALLBACK 0x00000050 diff --git a/src/osgPlugins/osg/CoordinateSystemNode.cpp b/src/osgPlugins/osg/CoordinateSystemNode.cpp new file mode 100644 index 000000000..3e0969cfe --- /dev/null +++ b/src/osgPlugins/osg/CoordinateSystemNode.cpp @@ -0,0 +1,60 @@ +#include "osg/CoordinateSystemNode" + +#include "osgDB/Registry" +#include "osgDB/Input" +#include "osgDB/Output" + +using namespace osg; +using namespace osgDB; + +// forward declare functions to use later. +bool CoordinateSystemNode_readLocalData(Object& obj, Input& fr); +bool CoordinateSystemNode_writeLocalData(const Object& obj, Output& fw); + +// register the read and write functions with the osgDB::Registry. +RegisterDotOsgWrapperProxy g_CoordinateSystemNodeProxy +( + new osg::CoordinateSystemNode, + "CoordinateSystemNode", + "Object Node CoordinateSystemNode Group", + &CoordinateSystemNode_readLocalData, + &CoordinateSystemNode_writeLocalData +); + +bool CoordinateSystemNode_readLocalData(Object& obj, Input& fr) +{ + bool iteratorAdvanced = false; + + CoordinateSystemNode& csn = static_cast(obj); + + if (fr.matchSequence("CoordinateSystem %s")) + { + const char* str = fr[1].getStr(); + if (str) csn.setCoordinateSystem(str); + + iteratorAdvanced = true; + fr+=2; + } + + static ref_ptr s_ellipsoidModel = new EllipsoidModel; + + EllipsoidModel* em = static_cast(fr.readObjectOfType(*s_ellipsoidModel)); + if (em) csn.setEllipsoidModel(em); + + return iteratorAdvanced; +} + + +bool CoordinateSystemNode_writeLocalData(const Object& obj, Output& fw) +{ + const CoordinateSystemNode& csn = static_cast(obj); + + fw.indent()<<"CoordinateSystem "<(obj); + + if (fr.matchSequence("RadiusEquator %f")) + { + double radius; + fr[1].getFloat(radius); + em.setRadiusEquator(radius); + fr += 2; + iteratorAdvanced = true; + } + + if (fr.matchSequence("RadiusPolar %f")) + { + double radius; + fr[1].getFloat(radius); + em.setRadiusPolar(radius); + fr += 2; + iteratorAdvanced = true; + } + + return iteratorAdvanced; +} + + +bool EllipsoidModel_writeLocalData(const Object& obj, Output& fw) +{ + const EllipsoidModel& em = static_cast(obj); + + int prec = fw.precision(); + fw.precision(15); + + fw.indent()<<"RadiusEquator "< node = cd->createPagedLODScene(); + if (_decorateWithCoordinateSystemNode) + { + node = decorateWithCoordinateSystemNode(node.get()); + } + //std::string filename = cd->_name + _tileExtension; std::string filename = _tileBasename+_tileExtension; @@ -3368,6 +3375,27 @@ void DataSet::createDestination(unsigned int numLevels) } +osg::CoordinateSystemNode* DataSet::decorateWithCoordinateSystemNode(osg::Node* subgraph) +{ + // don't decorate if no coord system is set. + if (_destinationCoordinateSystem->getCoordinateSystem().empty()) + return subgraph; + + osg::CoordinateSystemNode* csn = new osg::CoordinateSystemNode; + + // copy the destinate coordinate system string. + csn->setCoordinateSystem(_destinationCoordinateSystem->getCoordinateSystem()); + + // set the ellipsoid model if geocentric coords are used. + if (getConvertFromGeographicToGeocentric()) csn->setEllipsoidModel(getEllipsoidModel()); + + // add the a subgraph. + csn->addChild(subgraph); + + return csn; +} + + void DataSet::writeDestination() { if (_destinationGraph.valid()) @@ -3379,6 +3407,12 @@ void DataSet::writeDestination() { populateDestinationGraphFromSources(); _rootNode = _destinationGraph->createScene(); + + if (_decorateWithCoordinateSystemNode) + { + _rootNode = decorateWithCoordinateSystemNode(_rootNode.get()); + } + osgDB::writeNodeFile(*_rootNode,filename); } else // _databaseType==PagedLOD_DATABASE