Added txp::TerrapageNode to the txp plugin, and implemented the node so that it
automatically assign handles the updates of eye points and database merges.
This commit is contained in:
parent
64341828b8
commit
ee3348afc9
@ -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
|
||||
|
@ -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.*/
|
||||
|
@ -166,5 +166,5 @@ namespace txp
|
||||
TrPageParser*parse;
|
||||
};
|
||||
|
||||
}; // namespace txp
|
||||
} // namespace txp
|
||||
#endif
|
||||
|
@ -34,6 +34,7 @@
|
||||
#include <osgTXP/trpage_scene.h>
|
||||
#include <osgTXP/trpage_managers.h>
|
||||
#include <osgTXP/WaitBlock.h>
|
||||
#include <osgTXP/TrPageArchive.h>
|
||||
|
||||
namespace txp
|
||||
{
|
||||
|
@ -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;
|
||||
|
||||
|
@ -31,8 +31,6 @@
|
||||
|
||||
#include <string>
|
||||
|
||||
#include <osgTXP/Export.h>
|
||||
|
||||
#include <osgTXP/trPagePageManager.h>
|
||||
|
||||
namespace txp
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -244,6 +244,25 @@ void Registry::readCommandLine(std::vector<std::string>& 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<std::string>::iterator start = itr;
|
||||
++itr;
|
||||
if (itr!=commandLine.end())
|
||||
{
|
||||
osgDB::Registry::instance()->setOptions(new osgDB::ReaderWriter::Options(*itr));
|
||||
++itr;
|
||||
}
|
||||
commandLine.erase(start,itr);
|
||||
found = true;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
56
src/osgPlugins/txp/IO_TerrapageNode.cpp
Normal file
56
src/osgPlugins/txp/IO_TerrapageNode.cpp
Normal file
@ -0,0 +1,56 @@
|
||||
#include "TerrapageNode.h"
|
||||
|
||||
#include <osgDB/Registry>
|
||||
#include <osgDB/Input>
|
||||
#include <osgDB/Output>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
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<txp::TerrapageNode &>(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<const txp::TerrapageNode &>(obj);
|
||||
|
||||
if (!pager.getDatabaseOptions().empty()) fw.indent() << "databaseOptions \"" << pager.getDatabaseOptions() << "\""<<std::endl;
|
||||
if (!pager.getDatabaseName().empty()) fw.indent() << "databaseName \"" << pager.getDatabaseName() << "\"" << std::endl;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -3,6 +3,8 @@ include $(TOPDIR)/Make/makedefs
|
||||
|
||||
CXXFILES =\
|
||||
ReaderWriterTXP.cpp\
|
||||
TerrapageNode.cpp\
|
||||
IO_TerrapageNode.cpp\
|
||||
TrPageArchive.cpp\
|
||||
TrPageParser.cpp\
|
||||
trpage_basic.cpp\
|
||||
|
@ -11,87 +11,33 @@
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#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<TerrapageNode> 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<ReaderWriterTXP> g_txpReaderWriterProxy;
|
||||
|
@ -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
|
||||
|
179
src/osgPlugins/txp/TerrapageNode.cpp
Normal file
179
src/osgPlugins/txp/TerrapageNode.cpp
Normal file
@ -0,0 +1,179 @@
|
||||
#include "TerrapageNode.h"
|
||||
|
||||
#include <osg/Notify>
|
||||
|
||||
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<<std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Note: Should be checking the return values
|
||||
txpArchive->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"<<std::endl;
|
||||
}
|
||||
|
||||
if (_databaseOptions.find("ThreadNone")!=std::string::npos)
|
||||
{
|
||||
threadMode = OSGPageManager::ThreadNone;
|
||||
std::cout<<"ThreadNone selected"<<std::endl;
|
||||
}
|
||||
|
||||
if (_databaseOptions.find("ThreadFree")!=std::string::npos)
|
||||
{
|
||||
threadMode = OSGPageManager::ThreadFree;
|
||||
std::cout<<"ThreadFree selected"<<std::endl;
|
||||
}
|
||||
|
||||
if (_databaseOptions.find("ThreadSync")!=std::string::npos)
|
||||
{
|
||||
threadMode = OSGPageManager::ThreadSync;
|
||||
std::cout<<"ThreadSync selected"<<std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
if (loadAll)
|
||||
{
|
||||
// Load the whole scenegraph
|
||||
osg::Node* node = txpArchive->LoadAllTiles();
|
||||
if (!node) {
|
||||
osg::notify(osg::WARN)<<"Couldn't load whole TerraPage archive "<<_databaseName<<std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
// need to think about ref counting these..
|
||||
delete txpArchive;
|
||||
|
||||
// add the loaded database into the scenegraph.
|
||||
addChild(node);
|
||||
|
||||
} else {
|
||||
|
||||
_pageManager = new OSGPageManager(txpArchive);
|
||||
|
||||
if (threadMode!=OSGPageManager::ThreadNone)
|
||||
{
|
||||
ThreadID newThread;
|
||||
_pageManager->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
|
60
src/osgPlugins/txp/TerrapageNode.h
Normal file
60
src/osgPlugins/txp/TerrapageNode.h
Normal file
@ -0,0 +1,60 @@
|
||||
//C++ header.
|
||||
|
||||
#ifndef TERRAPAGENODE_H
|
||||
#define TERRAPAGENODE_H
|
||||
|
||||
#include <osg/Node>
|
||||
#include <osg/BoundingBox>
|
||||
|
||||
#include <osgTXP/trPagePageManager.h>
|
||||
|
||||
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
|
Loading…
Reference in New Issue
Block a user