diff --git a/VisualStudio/osgPlugins/txp/txp.dsp b/VisualStudio/osgPlugins/txp/txp.dsp index efda79c21..66ad23a8c 100644 --- a/VisualStudio/osgPlugins/txp/txp.dsp +++ b/VisualStudio/osgPlugins/txp/txp.dsp @@ -98,6 +98,14 @@ SOURCE=..\..\..\src\osgPlugins\txp\ReaderWriterTXP.cpp # End Source File # Begin Source File +SOURCE=..\..\..\src\osgPlugins\txp\TerrapageNode.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\osgPlugins\txp\IO_TerrapageNode.cpp +# End Source File +# Begin Source File + SOURCE=..\..\..\src\osgPlugins\txp\trpage_basic.cpp # End Source File # Begin Source File @@ -198,6 +206,10 @@ SOURCE=..\..\..\src\osgPlugins\txp\ReaderWriterTXP.h # End Source File # Begin Source File +SOURCE=..\..\..\src\osgPlugins\txp\TerrapageNode.h +# End Source File +# Begin Source File + SOURCE=..\..\..\src\osgPlugins\txp\trdll.h # End Source File # Begin Source File diff --git a/include/osg/NodeVisitor b/include/osg/NodeVisitor index 96dc5ec07..ad37e7fde 100644 --- a/include/osg/NodeVisitor +++ b/include/osg/NodeVisitor @@ -189,6 +189,10 @@ class SG_EXPORT NodeVisitor : public Referenced /** Get the World To Local Matrix from the NodePath for specified Transform::Mode.*/ virtual bool getWorldToLocalMatrix(Matrix& matrix, Node* node); + /** Get the eye point in local coordinates. + * Note, not all NodeVisitor implement this method, it is mainly cull visitors which will implement.*/ + virtual osg::Vec3 getEyePoint() const { return Vec3(0.0f,0.0f,0.0f); } + /** Get the distance from a point to the eye point, distance value in local coordinate system. * Note, not all NodeVisitor implement this method, it is mainly cull visitors which will implement. * If the getDistianceFromEyePoint(pos) is not implmented than a default value of 0.0 is returned.*/ diff --git a/include/osgTXP/TrPageParser.h b/include/osgTXP/TrPageParser.h index 0a32eb771..ddc3e562e 100644 --- a/include/osgTXP/TrPageParser.h +++ b/include/osgTXP/TrPageParser.h @@ -166,5 +166,5 @@ namespace txp TrPageParser*parse; }; -}; // namespace txp +} // namespace txp #endif diff --git a/include/osgTXP/trPagePageManager.h b/include/osgTXP/trPagePageManager.h index 3e0d1e530..1ff9f4a0a 100644 --- a/include/osgTXP/trPagePageManager.h +++ b/include/osgTXP/trPagePageManager.h @@ -34,6 +34,7 @@ #include #include #include +#include namespace txp { diff --git a/include/osgUtil/CullVisitor b/include/osgUtil/CullVisitor index e5d02cb5b..f4ceb7d01 100644 --- a/include/osgUtil/CullVisitor +++ b/include/osgUtil/CullVisitor @@ -48,6 +48,7 @@ class OSGUTIL_EXPORT CullVisitor : public osg::NodeVisitor, public osg::CullStac virtual void reset(); + virtual osg::Vec3 getEyePoint() const { return getEyeLocal(); } virtual float getDistanceToEyePoint(const osg::Vec3& pos, bool withLODScale) const; virtual float getDistanceFromEyePoint(const osg::Vec3& pos, bool withLODScale) const; diff --git a/src/Demos/osgtxp/TrPageViewer.h b/src/Demos/osgtxp/TrPageViewer.h index e770637b9..cb0b6cbbb 100644 --- a/src/Demos/osgtxp/TrPageViewer.h +++ b/src/Demos/osgtxp/TrPageViewer.h @@ -31,8 +31,6 @@ #include -#include - #include namespace txp diff --git a/src/osg/Group.cpp b/src/osg/Group.cpp index ba408ab49..8a4423c44 100644 --- a/src/osg/Group.cpp +++ b/src/osg/Group.cpp @@ -261,10 +261,13 @@ bool Group::setChild( unsigned int i, Node* newNode ) bool Group::computeBound() const { - _bsphere_computed = true; _bsphere.init(); - if (_children.empty()) return false; + if (_children.empty()) + { + _bsphere_computed = true; + return false; + } // note, special handling of the case when a child is an Transform, // such that only Transforms which are relative to their parents coordinates frame (i.e this group) @@ -284,7 +287,11 @@ bool Group::computeBound() const } } - if (!bb.valid()) return false; + if (!bb.valid()) + { + _bsphere_computed = true; + return false; + } _bsphere._center = bb.center(); _bsphere._radius = 0.0f; @@ -299,5 +306,6 @@ bool Group::computeBound() const } } + _bsphere_computed = true; return true; } diff --git a/src/osgDB/Registry.cpp b/src/osgDB/Registry.cpp index faa767a0d..cc16ee924 100644 --- a/src/osgDB/Registry.cpp +++ b/src/osgDB/Registry.cpp @@ -244,6 +244,25 @@ void Registry::readCommandLine(std::vector& commandLine) found = true; } + // read any option strings that exist. + itr = commandLine.begin(); + for(;itr!=commandLine.end();++itr) + { + if (*itr=="-O") break; + } + + if (itr!=commandLine.end()) + { + std::vector::iterator start = itr; + ++itr; + if (itr!=commandLine.end()) + { + osgDB::Registry::instance()->setOptions(new osgDB::ReaderWriter::Options(*itr)); + ++itr; + } + commandLine.erase(start,itr); + found = true; + } } } diff --git a/src/osgPlugins/txp/IO_TerrapageNode.cpp b/src/osgPlugins/txp/IO_TerrapageNode.cpp new file mode 100644 index 000000000..8dd4a1be4 --- /dev/null +++ b/src/osgPlugins/txp/IO_TerrapageNode.cpp @@ -0,0 +1,56 @@ +#include "TerrapageNode.h" + +#include +#include +#include + +#include + +bool TerrapageNode_readLocalData(osg::Object &obj, osgDB::Input &fr); +bool TerrapageNode_writeLocalData(const osg::Object &obj, osgDB::Output &fw); + +osgDB::RegisterDotOsgWrapperProxy TerrapageNode_Proxy +( + new txp::TerrapageNode, + "TerrapageNode", + "Object Node TerrapageNode", + TerrapageNode_readLocalData, + TerrapageNode_writeLocalData +); + +bool TerrapageNode_readLocalData(osg::Object &obj, osgDB::Input &fr) +{ + txp::TerrapageNode &pager = static_cast(obj); + bool itrAdvanced = false; + + if (fr.matchSequence("databaseOptions %s")) + { + pager.setDatabaseOptions(fr[1].getStr()); + fr += 2; + itrAdvanced = true; + } + + if (fr.matchSequence("databaseName %s")) + { + pager.setDatabaseName(fr[1].getStr()); + pager.loadDatabase(); + + fr += 2; + itrAdvanced = true; + } + + + return itrAdvanced; +} + +bool TerrapageNode_writeLocalData(const osg::Object &obj, osgDB::Output &fw) +{ + const txp::TerrapageNode &pager = static_cast(obj); + + if (!pager.getDatabaseOptions().empty()) fw.indent() << "databaseOptions \"" << pager.getDatabaseOptions() << "\""< +#include "TerrapageNode.h" + using namespace txp; using namespace osg; -//---------------------------------------------------------------------------- -// private class for txp file -class TXPFile -{ -public: - TrPageArchive archive; - TXPFile() - { - }; - ~TXPFile() - { - }; - - Node* readNode(const std::string &filename) - { - Group* ret = 0; - // search the SGL data path - std::string foundname = osgDB::findDataFile(filename); - if( !foundname.empty()) - { - if (archive.OpenFile(foundname.c_str())) - { - notify(INFO) << "TXPFile::loadFile(): loading archive: " - << foundname << std::endl; - archive.LoadMaterials(); - archive.LoadModels(); - - notify(INFO) << "TXPFile::loadFile(): loading geometry" - << std::endl; - - ret = archive.LoadAllTiles(); - - notify(INFO) << "TXPFile::loadFile(): loaded archive: " - << foundname << std::endl; - //sgluOutputTree(sceneGraph, cout, 3); - } - else - { - notify(WARN) << "Failed to load archive: " << foundname << std::endl; - } - } - else - { - notify(WARN) <<"sglTrPageGroup::loadFile() failed to find archive: " - << foundname << std::endl; - } - return ret; - }; - - Object* readObject(const std::string &filename) - { - return readNode(filename); - }; -}; - -osgDB::ReaderWriter::ReadResult ReaderWriterTXP::readObject(const std::string& fileName, const osgDB::ReaderWriter::Options*) +osgDB::ReaderWriter::ReadResult ReaderWriterTXP::readNode(const std::string& fileName, const osgDB::ReaderWriter::Options* options) { if( !acceptsExtension(osgDB::getFileExtension(fileName) )) return ReadResult::FILE_NOT_HANDLED; - TXPFile read; - - Object* obj = read.readObject(fileName); - if (obj) return obj; - else return ReadResult::FILE_NOT_HANDLED; -} - - -osgDB::ReaderWriter::ReadResult ReaderWriterTXP::readNode(const std::string& fileName, const osgDB::ReaderWriter::Options*) -{ - if( !acceptsExtension(osgDB::getFileExtension(fileName) )) - return ReadResult::FILE_NOT_HANDLED; - - TXPFile read; - Node* node = read.readNode(fileName); - if (node) return node; - else return ReadResult::FILE_NOT_HANDLED; + ref_ptr pager = new TerrapageNode; + + pager->setDatabaseName(fileName); + + if (options) + { + pager->setDatabaseOptions(options->getOptionString()); + } + + if (pager->loadDatabase()) + { + return pager.get(); + } + else + return ReadResult::ERROR_IN_READING_FILE; + } osgDB::RegisterReaderWriterProxy g_txpReaderWriterProxy; diff --git a/src/osgPlugins/txp/ReaderWriterTXP.h b/src/osgPlugins/txp/ReaderWriterTXP.h index 4eb0ff3eb..a740f8975 100644 --- a/src/osgPlugins/txp/ReaderWriterTXP.h +++ b/src/osgPlugins/txp/ReaderWriterTXP.h @@ -35,16 +35,19 @@ namespace txp { + class ReaderWriterTXP : public osgDB::ReaderWriter { -public: - virtual const char* className() { return "TXP Reader/Writer"; } - virtual bool acceptsExtension(const std::string& extension) - { - return osgDB::equalCaseInsensitive(extension,"txp"); - } - virtual ReadResult readObject(const std::string& fileName, const osgDB::ReaderWriter::Options*); - virtual ReadResult readNode(const std::string& fileName, const osgDB::ReaderWriter::Options*); + public: + virtual const char* className() { return "TXP Reader/Writer"; } + + virtual bool acceptsExtension(const std::string& extension) + { + return osgDB::equalCaseInsensitive(extension,"txp"); + } + + virtual ReadResult readNode(const std::string& fileName, const osgDB::ReaderWriter::Options*); }; -}; // namespace + +} // namespace #endif diff --git a/src/osgPlugins/txp/TerrapageNode.cpp b/src/osgPlugins/txp/TerrapageNode.cpp new file mode 100644 index 000000000..830afa293 --- /dev/null +++ b/src/osgPlugins/txp/TerrapageNode.cpp @@ -0,0 +1,179 @@ +#include "TerrapageNode.h" + +#include + +namespace txp +{ + +TerrapageNode::TerrapageNode(): + _pageManager(0) +{ + setNumChildrenRequiringAppTraversal(1); +} + +TerrapageNode::TerrapageNode(const TerrapageNode& pager,const osg::CopyOp&): + osg::Group(), + _databaseDimensions(pager._databaseDimensions), + _databaseName(pager._databaseName), + _databaseOptions(pager._databaseOptions), + _pageManager(0), + _lastRecordEyePoint(pager._lastRecordEyePoint) +{ + setNumChildrenRequiringAppTraversal(getNumChildrenRequiringAppTraversal()+1); +} + +TerrapageNode::~TerrapageNode() +{ + // will the page manger delete the archive? + delete _pageManager; +} + +void TerrapageNode::traverse(osg::NodeVisitor& nv) +{ + if (_pageManager) + { + if (nv.getVisitorType()==osg::NodeVisitor::APP_VISITOR) + { + updateSceneGraph(); + } + else if (nv.getVisitorType()==osg::NodeVisitor::CULL_VISITOR) + { + updateEyePoint(nv.getEyePoint()); + } + } + + Group::traverse(nv); +} + + +bool TerrapageNode::loadDatabase() +{ + // Open the TXP database + TrPageArchive *txpArchive = new TrPageArchive(); + if (!txpArchive->OpenFile(_databaseName.c_str())) + { + osg::notify(osg::WARN)<<"Couldn't load TerraPage archive "<<_databaseName<LoadMaterials(); + + // get the exents of the archive + const trpgHeader *head = txpArchive->GetHeader(); + trpg2dPoint sw,ne; + head->GetExtents(sw,ne); + + _databaseDimensions.set(sw.x,sw.y,0.0f, + ne.x,ne.y,0.0f); + + + // set up the options. + bool loadAll=false; + OSGPageManager::ThreadMode threadMode = OSGPageManager::ThreadFree; + + if (!_databaseOptions.empty()) + { + if (_databaseOptions.find("LoadAll")!=std::string::npos) + { + loadAll = true; + std::cout<<"LoadAll selected"<LoadAllTiles(); + if (!node) { + osg::notify(osg::WARN)<<"Couldn't load whole TerraPage archive "<<_databaseName<StartThread(threadMode,newThread); + } + + } + + return true; +} + + +void TerrapageNode::updateSceneGraph() +{ + if (_pageManager) + { _bsphere_computed = true; + + if (_pageManager->GetThreadMode() == OSGPageManager::ThreadNone) + { + // we're in non-thread mode, load in the given number of tiles (maximum). + int numTile = 1; + _pageManager->UpdateNoThread(this,_lastRecordEyePoint.x(),_lastRecordEyePoint.y(),numTile); + } + else + { + // we're in ThreadFree mode, merge in whatever may be ready. + _pageManager->MergeUpdateThread(this); + } + } +} + + +void TerrapageNode::updateEyePoint(const osg::Vec3& eyepoint) const +{ + if (_pageManager && (_pageManager->GetThreadMode() != OSGPageManager::ThreadNone)) + { + _pageManager->UpdatePositionThread(eyepoint.x(),eyepoint.y()); + } + + _lastRecordEyePoint = eyepoint; +} + +bool TerrapageNode::computeBound() const +{ + if (_databaseDimensions.valid()) + { + _bsphere.init(); + _bsphere.expandBy(_databaseDimensions); + _bsphere_computed = true; + return true; + } + else + { + return osg::Group::computeBound(); + } +} + + +} // namespace txp diff --git a/src/osgPlugins/txp/TerrapageNode.h b/src/osgPlugins/txp/TerrapageNode.h new file mode 100644 index 000000000..0f513ab14 --- /dev/null +++ b/src/osgPlugins/txp/TerrapageNode.h @@ -0,0 +1,60 @@ +//C++ header. + +#ifndef TERRAPAGENODE_H +#define TERRAPAGENODE_H + +#include +#include + +#include + +namespace txp +{ + +class TerrapageNode : public osg::Group +{ + public: + + TerrapageNode(); + + /** Copy constructor using CopyOp to manage deep vs shallow copy.*/ + TerrapageNode(const TerrapageNode&,const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY); + + META_Node(txp, TerrapageNode); + + virtual void traverse(osg::NodeVisitor& nv); + + + bool loadDatabase(); + + void setDatabaseName(const std::string& name) { _databaseName = name; } + const std::string& getDatabaseName() const { return _databaseName; } + + void setDatabaseOptions(const std::string& name) { _databaseOptions = name; } + const std::string& getDatabaseOptions() const { return _databaseOptions; } + + void setDatabaseDimensions(const osg::BoundingBox& box) { _databaseDimensions = box; } + const osg::BoundingBox& getDatabaseDimensions() const { return _databaseDimensions; } + + + virtual void updateSceneGraph(); + + virtual void updateEyePoint(const osg::Vec3& eyepoint) const; + + + protected: + + virtual ~TerrapageNode(); + + virtual bool computeBound() const; + + osg::BoundingBox _databaseDimensions; + std::string _databaseName; + std::string _databaseOptions; + OSGPageManager* _pageManager; + mutable osg::Vec3 _lastRecordEyePoint; +}; + + +} // namespace txp +#endif