From Nick, updates to TXP plugin to handle differences in LOD levels
between adjacent tiles.
This commit is contained in:
@@ -110,6 +110,10 @@ SOURCE=..\..\..\src\osgPlugins\txp\TXPNode.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\src\osgPlugins\txp\TXPPageLOD.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\src\osgPlugins\txp\TXPPageManager.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
@@ -234,6 +238,10 @@ SOURCE=..\..\..\src\osgPlugins\txp\TXPNode.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\src\osgPlugins\txp\TXPPagedNode.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\src\osgPlugins\txp\TXPPageManager.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
@@ -10,6 +10,7 @@ CXXFILES =\
|
||||
TXPTileNode.cpp\
|
||||
TXPParser.cpp\
|
||||
TXPSeamLOD.cpp\
|
||||
TXPPagedLOD.cpp\
|
||||
TileMapper.cpp\
|
||||
trpage_basic.cpp\
|
||||
trpage_compat.cpp\
|
||||
|
||||
@@ -26,6 +26,8 @@
|
||||
#include "TXPArchive.h"
|
||||
#include "TXPParser.h"
|
||||
|
||||
#include <OpenThreads/ScopedLock>
|
||||
|
||||
using namespace txp;
|
||||
|
||||
#define TXPArchiveERROR(s) osg::notify(osg::NOTICE) << "txp::TXPArchive::" << (s) << " error: "
|
||||
@@ -538,46 +540,42 @@ bool TXPArchive::getTileInfo(int x, int y, int lod, TileInfo& info)
|
||||
info.center.set(0.f,0.f,0.f);
|
||||
info.bbox.set(0.f,0.f,0.f,0.f,0.f,0.f);
|
||||
|
||||
const trpgHeader *header = GetHeader();
|
||||
const trpgTileTable *tileTable = GetTileTable();
|
||||
if (header && tileTable)
|
||||
{
|
||||
header->GetLodRange(lod,info.maxRange);
|
||||
header->GetLodRange(lod+1,info.minRange);
|
||||
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_mutex);
|
||||
|
||||
trpg2dPoint sw,ne;
|
||||
header->GetExtents(sw,ne);
|
||||
header.GetLodRange(lod,info.maxRange);
|
||||
header.GetLodRange(lod+1,info.minRange);
|
||||
|
||||
trpg2dPoint size;
|
||||
header->GetTileSize(lod,size);
|
||||
trpg2dPoint sw,ne;
|
||||
header.GetExtents(sw,ne);
|
||||
|
||||
trpgwAppAddress addr;
|
||||
float minz = 0.f;
|
||||
float maxz = 0.f;
|
||||
tileTable->GetTile(x,y,lod,addr,minz,maxz);
|
||||
trpg2dPoint size;
|
||||
header.GetTileSize(lod,size);
|
||||
|
||||
info.center.set(
|
||||
sw.x+(x*size.x)+(size.x/2.f),
|
||||
sw.y+(y*size.y)+(size.y/2.f),
|
||||
(minz+maxz)/2.f
|
||||
);
|
||||
info.bbox.set(
|
||||
osg::Vec3(
|
||||
info.center.x()-(size.x/2.f),
|
||||
info.center.y()-(size.y/2.f),
|
||||
minz
|
||||
),
|
||||
osg::Vec3(
|
||||
info.center.x()+(size.x/2.f),
|
||||
info.center.y()+(size.y/2.f),
|
||||
maxz
|
||||
)
|
||||
);
|
||||
info.radius = osg::Vec3(size.x/2.f, size.y/2.f,0.f).length() * 1.3;
|
||||
trpgwAppAddress addr;
|
||||
float minz = 0.f;
|
||||
float maxz = 0.f;
|
||||
tileTable.GetTile(x,y,lod,addr,minz,maxz);
|
||||
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
info.center.set(
|
||||
sw.x+(x*size.x)+(size.x/2.f),
|
||||
sw.y+(y*size.y)+(size.y/2.f),
|
||||
(minz+maxz)/2.f
|
||||
);
|
||||
info.bbox.set(
|
||||
osg::Vec3(
|
||||
info.center.x()-(size.x/2.f),
|
||||
info.center.y()-(size.y/2.f),
|
||||
minz
|
||||
),
|
||||
osg::Vec3(
|
||||
info.center.x()+(size.x/2.f),
|
||||
info.center.y()+(size.y/2.f),
|
||||
maxz
|
||||
)
|
||||
);
|
||||
info.radius = osg::Vec3(size.x/2.f, size.y/2.f,0.f).length() * 1.3;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
osg::Group* TXPArchive::getTileContent(
|
||||
@@ -601,3 +599,19 @@ osg::Group* TXPArchive::getTileContent(
|
||||
osg::Group *tileGroup = _parser->parseScene(buf,_gstates,_models,realMinRange,realMaxRange,usedMaxRange);
|
||||
return tileGroup;
|
||||
}
|
||||
|
||||
bool TXPArchive::getLODSize(int lod, int& x, int& y)
|
||||
{
|
||||
x = y = 0;
|
||||
|
||||
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_mutex);
|
||||
|
||||
trpg2iPoint size;
|
||||
if (header.GetLodSize(lod,size))
|
||||
{
|
||||
x = size.x;
|
||||
y = size.y;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -45,6 +45,8 @@
|
||||
#include <osg/PagedLOD>
|
||||
#include <osgSim/LightPointNode>
|
||||
|
||||
#include <OpenThreads/Mutex>
|
||||
|
||||
namespace txp
|
||||
{
|
||||
// this one handles different placement of light direction in osg and terrapage
|
||||
@@ -140,6 +142,9 @@ public:
|
||||
double realMinRange,
|
||||
double realMaxRange,
|
||||
double usedMaxRange);
|
||||
|
||||
// Get the number of tiles for given LOD
|
||||
bool getLODSize(int lod, int& x, int& y);
|
||||
|
||||
protected:
|
||||
|
||||
@@ -170,6 +175,9 @@ protected:
|
||||
|
||||
// Light attributes vector
|
||||
std::vector<DefferedLightAttribute> _lights;
|
||||
|
||||
//
|
||||
OpenThreads::Mutex _mutex;
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
|
||||
#include "TileMapper.h"
|
||||
#include "TXPNode.h"
|
||||
#include "TXPPagedLOD.h"
|
||||
using namespace txp;
|
||||
|
||||
|
||||
@@ -187,14 +188,25 @@ osg::Node* TXPNode::addPagedLODTile(int x, int y, int lod)
|
||||
TXPArchive::TileInfo info;
|
||||
_archive->getTileInfo(x,y,lod,info);
|
||||
|
||||
osg::PagedLOD* pagedLOD = new osg::PagedLOD;
|
||||
TXPPagedLOD* pagedLOD = new TXPPagedLOD;
|
||||
pagedLOD->setFileName(0,pagedLODfile);
|
||||
pagedLOD->setPriorityOffset(0,1.0f);
|
||||
//pagedLOD->setPriorityOffset(0,1.0f);
|
||||
pagedLOD->setPriorityOffset(0,_archive->getNumLODs());
|
||||
pagedLOD->setPriorityScale(0,1.0f);
|
||||
pagedLOD->setRange(0,0.0,info.maxRange);
|
||||
pagedLOD->setCenter(info.center);
|
||||
pagedLOD->setRadius(info.radius);
|
||||
pagedLOD->setNumChildrenThatCannotBeExpired(1);
|
||||
pagedLOD->setTileId(x,y,lod);
|
||||
|
||||
int sizeX, sizeY;
|
||||
if (_archive->getLODSize(lod,sizeX,sizeY))
|
||||
{
|
||||
if ((x-1) > -1) pagedLOD->addNeighbour(x-1,y);
|
||||
if ((x+1) < sizeX) pagedLOD->addNeighbour(x+1,y);
|
||||
if ((y-1) > -1) pagedLOD->addNeighbour(x,y-1);
|
||||
if ((y+1) < sizeY) pagedLOD->addNeighbour(x,y+1);
|
||||
}
|
||||
|
||||
_nodesToAdd.push_back(pagedLOD);
|
||||
|
||||
|
||||
124
src/osgPlugins/txp/TXPPagedLOD.cpp
Normal file
124
src/osgPlugins/txp/TXPPagedLOD.cpp
Normal file
@@ -0,0 +1,124 @@
|
||||
#include "TileMapper.h"
|
||||
#include "TXPPagedLOD.h"
|
||||
using namespace txp;
|
||||
|
||||
TXPPagedLOD::TXPPagedLOD():
|
||||
PagedLOD(),
|
||||
_tileX(-1),
|
||||
_tileY(-1),
|
||||
_tileLOD(-1)
|
||||
{
|
||||
}
|
||||
|
||||
TXPPagedLOD::TXPPagedLOD(const TXPPagedLOD& plod,const osg::CopyOp& copyop):
|
||||
PagedLOD(plod,copyop),
|
||||
_tileX(plod._tileX),
|
||||
_tileY(plod._tileY),
|
||||
_tileLOD(plod._tileLOD)
|
||||
{
|
||||
}
|
||||
|
||||
TXPPagedLOD::~TXPPagedLOD()
|
||||
{
|
||||
}
|
||||
|
||||
void TXPPagedLOD::traverse(osg::NodeVisitor& nv)
|
||||
{
|
||||
|
||||
double timeStamp = nv.getFrameStamp()?nv.getFrameStamp()->getReferenceTime():0.0;
|
||||
bool updateTimeStamp = nv.getVisitorType()==osg::NodeVisitor::CULL_VISITOR;
|
||||
|
||||
switch(nv.getTraversalMode())
|
||||
{
|
||||
case(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN):
|
||||
std::for_each(_children.begin(),_children.end(),osg::NodeAcceptOp(nv));
|
||||
break;
|
||||
case(osg::NodeVisitor::TRAVERSE_ACTIVE_CHILDREN):
|
||||
{
|
||||
float distance = nv.getDistanceToEyePoint(getCenter(),true);
|
||||
|
||||
int lastChildTraversed = -1;
|
||||
bool needToLoadChild = false;
|
||||
bool rollBack = false;
|
||||
for(unsigned int i=0;i<_rangeList.size();++i)
|
||||
{
|
||||
if (_rangeList[i].first<=distance && distance<_rangeList[i].second)
|
||||
{
|
||||
if (i<_children.size())
|
||||
{
|
||||
bool acceptThisChild = true;
|
||||
|
||||
if (i)
|
||||
{
|
||||
for (unsigned int ni = 0; ni < _neighbours.size(); ni++)
|
||||
{
|
||||
Neighbour& n = _neighbours[ni];
|
||||
if (TileMapper::instance()->getPagedLOD(n._x, n._y, _tileLOD)== 0)
|
||||
{
|
||||
rollBack = true;
|
||||
acceptThisChild = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (acceptThisChild)
|
||||
{
|
||||
if (updateTimeStamp) _perRangeDataList[i]._timeStamp=timeStamp;
|
||||
_children[i]->accept(nv);
|
||||
lastChildTraversed = (int)i;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
needToLoadChild = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (rollBack)
|
||||
{
|
||||
if (updateTimeStamp) _perRangeDataList[0]._timeStamp=timeStamp;
|
||||
_children[0]->accept(nv);
|
||||
lastChildTraversed = 0;
|
||||
//std::cout << "Rolling back" << std::endl;
|
||||
}
|
||||
|
||||
if (needToLoadChild)
|
||||
{
|
||||
unsigned int numChildren = _children.size();
|
||||
|
||||
//std::cout<<"PagedLOD::traverse() - falling back "<<std::endl;
|
||||
// select the last valid child.
|
||||
if (numChildren>0 && ((int)numChildren-1)!=lastChildTraversed)
|
||||
{
|
||||
//std::cout<<" to child "<<numChildren-1<<std::endl;
|
||||
if (updateTimeStamp) _perRangeDataList[numChildren-1]._timeStamp=timeStamp;
|
||||
_children[numChildren-1]->accept(nv);
|
||||
}
|
||||
|
||||
// now request the loading of the next unload child.
|
||||
if (nv.getDatabaseRequestHandler() && numChildren<_perRangeDataList.size())
|
||||
{
|
||||
// compute priority from where abouts in the required range the distance falls.
|
||||
float priority = (_rangeList[numChildren].second-distance)/(_rangeList[numChildren].second-_rangeList[numChildren].first);
|
||||
|
||||
// modify the priority according to the child's priority offset and scale.
|
||||
priority = _perRangeDataList[numChildren]._priorityOffset + priority * _perRangeDataList[numChildren]._priorityScale;
|
||||
|
||||
//std::cout<<" requesting child "<<_fileNameList[numChildren]<<" priotity = "<<priority<<std::endl;
|
||||
nv.getDatabaseRequestHandler()->requestNodeFile(_perRangeDataList[numChildren]._filename,this,priority,nv.getFrameStamp());
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
82
src/osgPlugins/txp/TXPPagedLOD.h
Normal file
82
src/osgPlugins/txp/TXPPagedLOD.h
Normal file
@@ -0,0 +1,82 @@
|
||||
/***************************************************************************
|
||||
* December 2003
|
||||
*
|
||||
* This TerraPage loader was re-written in a fashion to use PagedLOD
|
||||
* to manage paging entirely, also includes a version of Terrex's smart mesh
|
||||
* adapted to work with PagedLOD. The essential code by Boris Bralo is still present,
|
||||
* slight modified.
|
||||
* nick at terrex dot com
|
||||
*
|
||||
* Ported to PagedLOD technology by Trajce Nikolov (Nick) & Robert Osfield
|
||||
*****************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
* OpenSceneGraph loader for Terrapage format database
|
||||
* by Boris Bralo 2002
|
||||
*
|
||||
* based on/modifed sgl (Scene Graph Library) loader by Bryan Walsh
|
||||
*
|
||||
* This loader is based on/modified from Terrain Experts Performer Loader,
|
||||
* and was ported to SGL by Bryan Walsh / bryanw at earthlink dot net
|
||||
*
|
||||
* That loader is redistributed under the terms listed on Terrain Experts
|
||||
* website (www.terrex.com/www/pages/technology/technologypage.htm)
|
||||
*
|
||||
* "TerraPage is provided as an Open Source format for use by anyone...
|
||||
* We supply the TerraPage C++ source code free of charge. Anyone
|
||||
* can use it and redistribute it as needed (including our competitors).
|
||||
* We do, however, ask that you keep the TERREX copyrights intact."
|
||||
*
|
||||
* Copyright Terrain Experts Inc. 1999.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
*****************************************************************************/
|
||||
#ifndef __TXPPAGEDLOD_H_
|
||||
#define __TXPPAGEDLOD_H_
|
||||
|
||||
#include <osg/PagedLOD>
|
||||
|
||||
namespace txp
|
||||
{
|
||||
class TXPPagedLOD : public osg::PagedLOD
|
||||
{
|
||||
public:
|
||||
TXPPagedLOD();
|
||||
|
||||
/** Copy constructor using CopyOp to manage deep vs shallow copy.*/
|
||||
TXPPagedLOD(const TXPPagedLOD&,const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY);
|
||||
|
||||
META_Node(txp, TXPPagedLOD);
|
||||
|
||||
virtual void traverse(osg::NodeVisitor& nv);
|
||||
|
||||
inline void setTileId(int x, int y, int lod)
|
||||
{
|
||||
_tileX = x; _tileY = y; _tileLOD = lod;
|
||||
}
|
||||
|
||||
inline void addNeighbour(int x,int y)
|
||||
{
|
||||
Neighbour n;
|
||||
n._x = x;
|
||||
n._y = y;
|
||||
_neighbours.push_back(n);
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual ~TXPPagedLOD();
|
||||
|
||||
int _tileX;
|
||||
int _tileY;
|
||||
int _tileLOD;
|
||||
|
||||
struct Neighbour
|
||||
{
|
||||
int _x, _y;
|
||||
};
|
||||
std::vector<Neighbour> _neighbours;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
#endif // __TXPPAGEDLOD_H_
|
||||
@@ -48,6 +48,7 @@ void TXPSeamLOD::traverse(osg::NodeVisitor& nv)
|
||||
|
||||
#if 1
|
||||
osg::PagedLOD* pagedLOD = TileMapper::instance()->getPagedLOD(_neighbourTileX,_neighbourTileY, _neighbourTileLOD);
|
||||
bool acceptLoRes = true;
|
||||
if (pagedLOD)
|
||||
{
|
||||
|
||||
@@ -63,11 +64,12 @@ void TXPSeamLOD::traverse(osg::NodeVisitor& nv)
|
||||
if (distance<=pagedLOD->getMaxRange(i))
|
||||
{
|
||||
getChild(i)->accept(nv);
|
||||
return;
|
||||
acceptLoRes = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
if (acceptLoRes)
|
||||
{
|
||||
getChild(0)->accept(nv); // pick low res
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
#include "TXPTileNode.h"
|
||||
#include "TXPArchive.h"
|
||||
#include "TXPSeamLOD.h"
|
||||
|
||||
#include "TXPPagedLOD.h"
|
||||
using namespace txp;
|
||||
|
||||
class PrintVisitor : public osg::NodeVisitor
|
||||
@@ -216,14 +216,26 @@ bool TXPTileNode::loadTile(int x, int y, int lod)
|
||||
_archive->getId()
|
||||
);
|
||||
|
||||
osg::ref_ptr<osg::PagedLOD> pagedLOD = new osg::PagedLOD;
|
||||
osg::ref_ptr<TXPPagedLOD> pagedLOD = new TXPPagedLOD;
|
||||
// not use maximum(info.maxRange,1e7) as just maxRange would result in some corner tiles from being culled out.
|
||||
pagedLOD->addChild(tileGroup,info.minRange,osg::maximum(info.maxRange,1e7));
|
||||
pagedLOD->setFileName(1,pagedLODfile);
|
||||
pagedLOD->setRange(1,0,info.minRange);
|
||||
pagedLOD->setCenter(info.center);
|
||||
pagedLOD->setRadius(info.radius);
|
||||
pagedLOD->setPriorityOffset(0,numLods-lod);
|
||||
pagedLOD->setPriorityScale(0,1.0f);
|
||||
pagedLOD->setNumChildrenThatCannotBeExpired(1);
|
||||
pagedLOD->setTileId(x,y,lod);
|
||||
|
||||
int sizeX, sizeY;
|
||||
if (_archive->getLODSize(lod,sizeX,sizeY))
|
||||
{
|
||||
if ((x-1) > -1) pagedLOD->addNeighbour(x-1,y);
|
||||
if ((x+1) < sizeX) pagedLOD->addNeighbour(x+1,y);
|
||||
if ((y-1) > -1) pagedLOD->addNeighbour(x,y-1);
|
||||
if ((y+1) < sizeY) pagedLOD->addNeighbour(x,y+1);
|
||||
}
|
||||
|
||||
TileMapper::instance()->insertPagedLOD(x,y,lod,pagedLOD.get());
|
||||
|
||||
|
||||
Reference in New Issue
Block a user