From Nick, updates to TXP plugin to handle differences in LOD levels

between adjacent tiles.
This commit is contained in:
Robert Osfield
2004-01-07 14:10:47 +00:00
parent 9c15baf92f
commit dd460006a4
9 changed files with 304 additions and 41 deletions

View File

@@ -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

View File

@@ -10,6 +10,7 @@ CXXFILES =\
TXPTileNode.cpp\
TXPParser.cpp\
TXPSeamLOD.cpp\
TXPPagedLOD.cpp\
TileMapper.cpp\
trpage_basic.cpp\
trpage_compat.cpp\

View File

@@ -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;
}

View File

@@ -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;
};

View File

@@ -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);

View 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;
}
}

View 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_

View File

@@ -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
}

View File

@@ -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());