Fixed to TXP plugin from Nick.
This commit is contained in:
@@ -544,6 +544,7 @@ bool TXPArchive::getTileInfo(int x, int y, int lod, TileInfo& info)
|
||||
|
||||
header.GetLodRange(lod,info.maxRange);
|
||||
header.GetLodRange(lod+1,info.minRange);
|
||||
header.GetLodRange(0,info.lod0Range);
|
||||
|
||||
trpg2dPoint sw,ne;
|
||||
header.GetExtents(sw,ne);
|
||||
@@ -551,6 +552,10 @@ bool TXPArchive::getTileInfo(int x, int y, int lod, TileInfo& info)
|
||||
trpg2dPoint size;
|
||||
header.GetTileSize(lod,size);
|
||||
|
||||
info.size.x() = size.x;
|
||||
info.size.y() = size.y;
|
||||
info.size.z() = 0.f;
|
||||
|
||||
trpgwAppAddress addr;
|
||||
float minz = 0.f;
|
||||
float maxz = 0.f;
|
||||
@@ -582,7 +587,8 @@ osg::Group* TXPArchive::getTileContent(
|
||||
int x, int y, int lod,
|
||||
double realMinRange,
|
||||
double realMaxRange,
|
||||
double usedMaxRange)
|
||||
double usedMaxRange,
|
||||
osg::Vec3& tileCenter)
|
||||
{
|
||||
if (_parser.get() == 0)
|
||||
{
|
||||
@@ -597,6 +603,7 @@ osg::Group* TXPArchive::getTileContent(
|
||||
}
|
||||
|
||||
osg::Group *tileGroup = _parser->parseScene(buf,_gstates,_models,realMinRange,realMaxRange,usedMaxRange);
|
||||
tileCenter = _parser->getTileCenter();
|
||||
return tileGroup;
|
||||
}
|
||||
|
||||
|
||||
@@ -91,10 +91,12 @@ public:
|
||||
// Gets some informations for a given tile
|
||||
struct TileInfo
|
||||
{
|
||||
osg::Vec3 center;
|
||||
osg::Vec3 center;
|
||||
double minRange;
|
||||
double maxRange;
|
||||
double lod0Range;
|
||||
float radius;
|
||||
osg::Vec3 size;
|
||||
osg::BoundingBox bbox;
|
||||
};
|
||||
bool getTileInfo(int x, int y, int lod, TileInfo& info);
|
||||
@@ -141,7 +143,8 @@ public:
|
||||
int lod,
|
||||
double realMinRange,
|
||||
double realMaxRange,
|
||||
double usedMaxRange);
|
||||
double usedMaxRange,
|
||||
osg::Vec3& tileCenter);
|
||||
|
||||
// Get the number of tiles for given LOD
|
||||
bool getLODSize(int lod, int& x, int& y);
|
||||
|
||||
@@ -63,13 +63,15 @@ namespace txp
|
||||
_neighbours.push_back(n);
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual ~TXPPagedLOD();
|
||||
|
||||
int _tileX;
|
||||
int _tileY;
|
||||
int _tileLOD;
|
||||
|
||||
protected:
|
||||
virtual ~TXPPagedLOD();
|
||||
|
||||
|
||||
|
||||
struct Neighbour
|
||||
{
|
||||
int _x, _y;
|
||||
|
||||
@@ -39,6 +39,7 @@ _realMinRange(0.0),
|
||||
_realMaxRange(0.0),
|
||||
_usedMaxRange(0.0)
|
||||
{
|
||||
AddCallback(TRPG_ATTACH,new attachRead(this));
|
||||
AddCallback(TRPG_GEOMETRY,new geomRead(this));
|
||||
AddCallback(TRPG_GROUP,new groupRead(this));
|
||||
AddCallback(TRPG_LOD,new lodRead(this));
|
||||
@@ -83,6 +84,8 @@ osg::Group *TXPParser::parseScene(
|
||||
_realMaxRange = realMaxRange;
|
||||
_usedMaxRange = usedMaxRange;
|
||||
|
||||
_tileCenter = osg::Vec3(0.f,0.f,0.f);
|
||||
|
||||
if (!Parse(buf))
|
||||
{
|
||||
osg::notify(osg::NOTICE) << "txp::TXPParser::parseScene(): failed to parse the given tile" << std::endl;
|
||||
@@ -111,6 +114,8 @@ void TXPParser::replaceTileLod(osg::Group* group)
|
||||
if (!g) return;
|
||||
if (g->getNumChildren()) return;
|
||||
|
||||
_tileCenter = loLOD->getCenter();
|
||||
|
||||
group->addChild(loLOD->getChild(0));
|
||||
group->removeChild(loLOD);
|
||||
group->removeChild(hiLOD);
|
||||
@@ -120,27 +125,31 @@ void TXPParser::replaceTileLod(osg::Group* group)
|
||||
|
||||
bool TXPParser::StartChildren(void *in)
|
||||
{
|
||||
|
||||
bool pushParent = true;
|
||||
if (_underBillboardSubgraph )
|
||||
{
|
||||
if (_numBillboardLevels > 0) pushParent = false;
|
||||
_numBillboardLevels++;
|
||||
}
|
||||
else
|
||||
if (_underLayerSubgraph)
|
||||
{
|
||||
if (_numLayerLevels > 0) pushParent = false;
|
||||
_numLayerLevels++;
|
||||
}
|
||||
else
|
||||
if (in && (in != (void*)1))
|
||||
if (pushParent)
|
||||
{
|
||||
osg::Group *parent = (osg::Group*)in;
|
||||
_parents.push(parent);
|
||||
_currentTop = parent;
|
||||
_parents.push(_currentTop);
|
||||
_currentTop = _currentNode->asGroup();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TXPParser::EndChildren(void *)
|
||||
{
|
||||
bool popParent = true;
|
||||
if (_underLayerSubgraph)
|
||||
{
|
||||
_numLayerLevels--;
|
||||
@@ -148,6 +157,8 @@ bool TXPParser::EndChildren(void *)
|
||||
{
|
||||
_underLayerSubgraph = false;
|
||||
}
|
||||
else
|
||||
popParent = false;
|
||||
}
|
||||
else
|
||||
if (_underBillboardSubgraph)
|
||||
@@ -157,18 +168,18 @@ bool TXPParser::EndChildren(void *)
|
||||
{
|
||||
_underBillboardSubgraph = false;
|
||||
}
|
||||
else
|
||||
popParent = false;
|
||||
}
|
||||
else
|
||||
if (popParent)
|
||||
{
|
||||
_currentTop = 0;
|
||||
if (_parents.size())
|
||||
{
|
||||
_currentTop = _parents.top();
|
||||
_parents.pop();
|
||||
if (_parents.size())
|
||||
{
|
||||
_currentTop = _parents.top();
|
||||
}
|
||||
}
|
||||
else
|
||||
_currentTop = _root.get();
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -475,36 +486,33 @@ void* lodRead::Parse(trpgToken /*tok*/,trpgReadBuffer &buf)
|
||||
|
||||
// Create a new osg LOD
|
||||
osg::ref_ptr<osg::LOD> osgLod = new osg::LOD();
|
||||
osg::ref_ptr<GeodeGroup> osgLodG = new GeodeGroup;
|
||||
|
||||
osgLod->addChild(osgLodG.get());
|
||||
|
||||
osg::Vec3 osgCenter;
|
||||
osgCenter[0] = center.x;
|
||||
osgCenter[1] = center.y;
|
||||
osgCenter[2] = center.z;
|
||||
osgLod->setCenter(osgCenter);
|
||||
//osgLod->setRange(0,minRange, maxRange );
|
||||
#if 1
|
||||
osgLod->setRange(0,minRange, maxRange );
|
||||
#else
|
||||
osgLod->setRange(
|
||||
0,
|
||||
_parse->checkAndGetMinRange(minRange),
|
||||
_parse->checkAndGetMaxRange(maxRange)
|
||||
);
|
||||
#endif
|
||||
|
||||
// Our LODs are binary so we need to add a group under this LOD and attach stuff
|
||||
// to that instead of the LOD
|
||||
osg::ref_ptr<GeodeGroup> osgLodG = new GeodeGroup();
|
||||
osgLod->addChild(osgLodG.get());
|
||||
|
||||
// to that instead of the LOD
|
||||
// Add it into the scene graph
|
||||
osg::Group *top = _parse->getCurrTop();
|
||||
if (top)
|
||||
{
|
||||
top->addChild(osgLod.get());
|
||||
_parse->setPotentionalTileGroup(top);
|
||||
return (void *) osgLodG.get();
|
||||
}
|
||||
else
|
||||
{
|
||||
return (void*) 1;
|
||||
}
|
||||
_parse->setCurrentNode(osgLodG.get());
|
||||
_parse->getCurrTop()->addChild(osgLod.get());
|
||||
_parse->setPotentionalTileGroup(_parse->getCurrTop());
|
||||
|
||||
return (void*)1;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
@@ -562,12 +570,10 @@ void *modelRefRead::Parse(trpgToken /*tok*/,trpgReadBuffer &buf)
|
||||
osg::MatrixTransform *scs = new osg::MatrixTransform();
|
||||
scs->setMatrix(osg_Mat);
|
||||
scs->addChild(osg_Model);
|
||||
|
||||
// Add the SCS to the hierarchy
|
||||
osg::Group *top = _parse->getCurrTop();
|
||||
if (top)
|
||||
{
|
||||
top->addChild(scs);
|
||||
}
|
||||
_parse->setCurrentNode(scs);
|
||||
_parse->getCurrTop()->addChild(scs);
|
||||
}
|
||||
}
|
||||
return (void *) 1;
|
||||
@@ -591,6 +597,10 @@ void* billboardRead::Parse(trpgToken /*tok*/,trpgReadBuffer &buf)
|
||||
}
|
||||
else
|
||||
{
|
||||
GeodeGroup* grp = new GeodeGroup;
|
||||
_parse->setCurrentNode(grp);
|
||||
_parse->getCurrTop()->addChild(grp);
|
||||
|
||||
TXPParser::TXPBillboardInfo info;
|
||||
if (bill.GetType(info.type) && bill.GetMode(info.mode) && bill.GetCenter(info.center) && bill.GetAxis(info.axis))
|
||||
{
|
||||
@@ -599,7 +609,6 @@ void* billboardRead::Parse(trpgToken /*tok*/,trpgReadBuffer &buf)
|
||||
_parse->setUnderBillboardSubgraph(true);
|
||||
}
|
||||
}
|
||||
|
||||
return (void *)1;
|
||||
}
|
||||
|
||||
@@ -613,21 +622,29 @@ void* groupRead::Parse(trpgToken /*tok*/,trpgReadBuffer &buf)
|
||||
trpgGroup group;
|
||||
if (!group.Read(buf)) return NULL;
|
||||
|
||||
// Create a new group
|
||||
osg::ref_ptr<GeodeGroup> osgGroup = new GeodeGroup();
|
||||
if (_parse->underLayerSubgraph()) return (void*)1;
|
||||
|
||||
// Add it into the scene graph
|
||||
osg::Group *top = _parse->getCurrTop();
|
||||
if (top)
|
||||
{
|
||||
top->addChild(osgGroup.get());
|
||||
_parse->setPotentionalTileGroup(top);
|
||||
return (void *) osgGroup.get();
|
||||
}
|
||||
else
|
||||
{
|
||||
return (void*) 1;
|
||||
}
|
||||
osg::ref_ptr<GeodeGroup> osgGroup = new GeodeGroup();
|
||||
_parse->setCurrentNode(osgGroup.get());
|
||||
_parse->getCurrTop()->addChild(osgGroup.get());
|
||||
return (void*)1;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
// Attach Reader Class
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
void* attachRead::Parse(trpgToken /*tok*/,trpgReadBuffer &buf)
|
||||
{
|
||||
trpgAttach group;
|
||||
if (!group.Read(buf)) return NULL;
|
||||
|
||||
// Create a new group
|
||||
osg::ref_ptr<osg::Group> osgGroup = new osg::Group();
|
||||
_parse->setCurrentNode(osgGroup.get());
|
||||
_parse->getCurrTop()->addChild(osgGroup.get());
|
||||
return (void*)1;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
@@ -649,8 +666,6 @@ void* lightRead::Parse(trpgToken /*tok*/,trpgReadBuffer &buf)
|
||||
uint32 nvert;
|
||||
light.GetNumVertices(nvert);
|
||||
|
||||
osg::Group *top = _parse->getCurrTop();
|
||||
|
||||
if( node->getLightPoint(0)._sector.valid() ) // osgSim::LigthPoint is a must
|
||||
{
|
||||
for(unsigned int i = 0; i < nvert; i++)
|
||||
@@ -665,10 +680,9 @@ void* lightRead::Parse(trpgToken /*tok*/,trpgReadBuffer &buf)
|
||||
osg::ref_ptr<osg::MatrixTransform> trans = new osg::MatrixTransform();
|
||||
trans->setMatrix(matrix);
|
||||
trans->addChild(node);
|
||||
if (top)
|
||||
{
|
||||
top->addChild(trans.get());
|
||||
}
|
||||
|
||||
_parse->setCurrentNode(trans.get());
|
||||
_parse->getCurrTop()->addChild(trans.get());
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -693,13 +707,10 @@ void* lightRead::Parse(trpgToken /*tok*/,trpgReadBuffer &buf)
|
||||
geom->setUseDisplayList(false);
|
||||
geom->setStateSet(dla.fallback.get());
|
||||
|
||||
if (top)
|
||||
{
|
||||
osg::Geode* g = new osg::Geode;
|
||||
g->addDrawable(geom.get());
|
||||
top->addChild(g);
|
||||
|
||||
}
|
||||
osg::Geode* g = new osg::Geode;
|
||||
g->addDrawable(geom.get());
|
||||
_parse->setCurrentNode(g);
|
||||
_parse->getCurrTop()->addChild(g);
|
||||
}
|
||||
|
||||
return (void *) 1;
|
||||
@@ -715,18 +726,25 @@ void* layerRead::Parse(trpgToken /*tok*/,trpgReadBuffer &buf)
|
||||
trpgLayer group;
|
||||
if (!group.Read(buf)) return NULL;
|
||||
|
||||
#if 0
|
||||
osg::Group* osgGroup = new osg::Group;
|
||||
_parse->setCurrentNode(osgGroup);
|
||||
_parse->getCurrTop()->addChild(osgGroup);
|
||||
_parse->addLayer(osgGroup);
|
||||
return (void*)1;
|
||||
|
||||
#else
|
||||
if (_parse->underLayerSubgraph()) return (void*)1;
|
||||
|
||||
osg::ref_ptr<GeodeGroup> layer = new GeodeGroup;
|
||||
osg::Group* top = _parse->getCurrTop();
|
||||
if (top)
|
||||
{
|
||||
_parse->setLayerGeode(layer->getGeode());
|
||||
_parse->setUnderLayerSubgraph(true);
|
||||
top->addChild(layer.get());
|
||||
}
|
||||
|
||||
return (void *) 1;
|
||||
_parse->setLayerGeode(layer->getGeode());
|
||||
_parse->setUnderLayerSubgraph(true);
|
||||
_parse->setCurrentNode(layer.get());
|
||||
_parse->getCurrTop()->addChild(layer.get());
|
||||
|
||||
return (void *)1;
|
||||
#endif
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
@@ -785,7 +803,7 @@ void* geomRead::Parse(trpgToken /*tok*/,trpgReadBuffer &buf)
|
||||
{
|
||||
trpgGeometry geom;
|
||||
if (!geom.Read(buf)) return NULL;
|
||||
|
||||
|
||||
// Get the necessary info out of the geom
|
||||
trpgGeometry::PrimType primType;
|
||||
int numPrims;
|
||||
@@ -1050,12 +1068,15 @@ void* geomRead::Parse(trpgToken /*tok*/,trpgReadBuffer &buf)
|
||||
if (geodeTop)
|
||||
{
|
||||
geodeTop->getGeode()->addDrawable(geometry);
|
||||
_parse->setCurrentNode(geodeTop->getGeode());
|
||||
}
|
||||
else
|
||||
{
|
||||
osg::Geode* geode = new osg::Geode;
|
||||
geode->addDrawable(geometry);
|
||||
top->addChild(geode);
|
||||
|
||||
_parse->setCurrentNode(geode);
|
||||
_parse->getCurrTop()->addChild(geode);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -250,7 +250,12 @@ public:
|
||||
else
|
||||
return range;
|
||||
}
|
||||
|
||||
|
||||
// gets tile center, from the top lod node
|
||||
inline const osg::Vec3 getTileCenter() const { return _tileCenter; }
|
||||
|
||||
inline void setCurrentNode(osg::Node* node) { _currentNode = node; }
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
@@ -270,6 +275,9 @@ protected:
|
||||
|
||||
// Current parent
|
||||
osg::Group* _currentTop;
|
||||
|
||||
// Current node
|
||||
osg::Node* _currentNode;
|
||||
|
||||
// The root of the tile
|
||||
osg::ref_ptr<osg::Group> _root;
|
||||
@@ -291,7 +299,7 @@ protected:
|
||||
|
||||
// Model list
|
||||
std::vector<osg::ref_ptr<osg::Node> >* _models;
|
||||
|
||||
|
||||
// Tile header
|
||||
trpgTileHeader _tileHeader;
|
||||
|
||||
@@ -320,7 +328,10 @@ protected:
|
||||
double _realMinRange;
|
||||
double _realMaxRange;
|
||||
double _usedMaxRange;
|
||||
|
||||
|
||||
// tile center
|
||||
osg::Vec3 _tileCenter;
|
||||
|
||||
// TEMP
|
||||
osg::Geode* createBoundingBox(int x,int y, int lod);
|
||||
|
||||
@@ -352,6 +363,17 @@ protected:
|
||||
TXPParser *_parse;
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
class attachRead : public trpgr_Callback
|
||||
{
|
||||
public:
|
||||
attachRead(TXPParser *in_parse) : _parse(in_parse)
|
||||
{};
|
||||
void *Parse(trpgToken tok,trpgReadBuffer &buf);
|
||||
protected:
|
||||
TXPParser *_parse;
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
class lodRead : public trpgr_Callback
|
||||
{
|
||||
|
||||
@@ -14,6 +14,8 @@ TXPSeamLOD::TXPSeamLOD() :
|
||||
_tileRef = 0;
|
||||
_txpNode = 0;
|
||||
_archive = 0;
|
||||
_hiResPresent = false;
|
||||
_nonSeamChildrenIndex = -1;
|
||||
}
|
||||
|
||||
TXPSeamLOD::TXPSeamLOD(int x, int y, int lod, const osg::Vec3& center, float dmin, float dmid, float dmax) :
|
||||
@@ -29,6 +31,8 @@ TXPSeamLOD::TXPSeamLOD(int x, int y, int lod, const osg::Vec3& center, float dmi
|
||||
_txpNode = 0;
|
||||
_tileRef = 0;
|
||||
_archive = 0;
|
||||
_hiResPresent = false;
|
||||
_nonSeamChildrenIndex = -1;
|
||||
}
|
||||
|
||||
TXPSeamLOD::TXPSeamLOD(const TXPSeamLOD& ttg,const osg::CopyOp& copyop) :
|
||||
@@ -39,6 +43,8 @@ TXPSeamLOD::TXPSeamLOD(const TXPSeamLOD& ttg,const osg::CopyOp& copyop) :
|
||||
_neighbourTileLOD = ttg._neighbourTileLOD;
|
||||
_tileRef = ttg._tileRef;
|
||||
_archive = ttg._archive;
|
||||
_hiResPresent = ttg._hiResPresent;
|
||||
_nonSeamChildrenIndex = ttg._nonSeamChildrenIndex;
|
||||
}
|
||||
|
||||
void TXPSeamLOD::traverse(osg::NodeVisitor& nv)
|
||||
@@ -46,12 +52,12 @@ void TXPSeamLOD::traverse(osg::NodeVisitor& nv)
|
||||
if (nv.getVisitorType()==osg::NodeVisitor::CULL_VISITOR && _children.size()==2)
|
||||
{
|
||||
|
||||
#if 1
|
||||
osg::PagedLOD* pagedLOD = TileMapper::instance()->getPagedLOD(_neighbourTileX,_neighbourTileY, _neighbourTileLOD);
|
||||
#if 1
|
||||
bool acceptLoRes = true;
|
||||
if (pagedLOD)
|
||||
{
|
||||
|
||||
|
||||
float distance = nv.getDistanceToEyePoint(_center,true);
|
||||
distance = nv.getDistanceToEyePoint(pagedLOD->getCenter(),true);
|
||||
|
||||
@@ -73,6 +79,12 @@ void TXPSeamLOD::traverse(osg::NodeVisitor& nv)
|
||||
{
|
||||
getChild(0)->accept(nv); // pick low res
|
||||
}
|
||||
|
||||
if (_nonSeamChildrenIndex > -1)
|
||||
{
|
||||
for (int i = _nonSeamChildrenIndex; i < (int)getNumChildren(); i++ )
|
||||
getChild(i)->accept(nv);
|
||||
}
|
||||
#else
|
||||
float distance = nv.getDistanceToEyePoint(_center,true);
|
||||
if (distance<=_mid)
|
||||
|
||||
@@ -80,8 +80,15 @@ public:
|
||||
_archive = ar;
|
||||
}
|
||||
|
||||
inline void setHiResPresent(bool p) { _hiResPresent = p; }
|
||||
inline void setNonSeamChildrenIndex(int ix) { _nonSeamChildrenIndex = ix; }
|
||||
|
||||
protected:
|
||||
|
||||
bool _hiResPresent;
|
||||
|
||||
int _nonSeamChildrenIndex;
|
||||
|
||||
int _neighbourTileX;
|
||||
int _neighbourTileY;
|
||||
int _neighbourTileLOD;
|
||||
|
||||
@@ -46,10 +46,15 @@ class PrintVisitor : public osg::NodeVisitor
|
||||
{
|
||||
moveIn();
|
||||
writeIndent(); std::cout << lod.className() <<std::endl;
|
||||
writeIndent(); std::cout << "center="<<lod.getCenter()<<std::endl;
|
||||
if (lod.className()=="TXPPagedLOD")
|
||||
{
|
||||
TXPPagedLOD *plod = (TXPPagedLOD*)&lod;
|
||||
writeIndent(); std::cout << "X="<<plod->_tileX<<" Y="<<plod->_tileY<<" LOD="<<plod->_tileLOD<< std::endl;
|
||||
}
|
||||
//writeIndent(); std::cout << "center="<<lod.getCenter()<<std::endl;
|
||||
for(unsigned int i=0;i<lod.getNumChildren();++i)
|
||||
{
|
||||
writeIndent(); std::cout << "child min="<<lod.getMinRange(i)<<" max="<<lod.getMaxRange(i)<<std::endl;
|
||||
//writeIndent(); std::cout << "child min="<<lod.getMinRange(i)<<" max="<<lod.getMaxRange(i)<<std::endl;
|
||||
lod.getChild(i)->accept(*this);
|
||||
}
|
||||
moveOut();
|
||||
@@ -83,80 +88,139 @@ void TXPTileNode::setArchive(TXPArchive* archive)
|
||||
_archive = archive;
|
||||
}
|
||||
|
||||
|
||||
osg::Node* TXPTileNode::seamReplacement(osg::Node* child,int x, int y, int level, TXPArchive::TileInfo& info)
|
||||
class SeamFinder: public osg::NodeVisitor
|
||||
{
|
||||
osg::Group* group = child->asGroup();
|
||||
if (group)
|
||||
{
|
||||
if (group->getNumChildren()==2)
|
||||
{
|
||||
osg::LOD* lod1 = dynamic_cast<osg::LOD*>(group->getChild(0));
|
||||
osg::LOD* lod2 = dynamic_cast<osg::LOD*>(group->getChild(1));
|
||||
if (lod1 && lod1->getNumChildren()==1 &&
|
||||
lod2 && lod2->getNumChildren()==1)
|
||||
{
|
||||
|
||||
osg::Vec3 delta = lod1->getCenter()-info.center;
|
||||
if (fabs(delta.x())>fabs(delta.y()))
|
||||
{
|
||||
if (delta.x()<0.0)
|
||||
{
|
||||
// west tile
|
||||
--x;
|
||||
}
|
||||
else
|
||||
{
|
||||
// east tile
|
||||
x++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (delta.y()<0.0)
|
||||
{
|
||||
// south tile
|
||||
--y;
|
||||
}
|
||||
else
|
||||
{
|
||||
// north tile
|
||||
++y;
|
||||
}
|
||||
}
|
||||
|
||||
// std::cout<<"seamReplacement lod1 min="<<lod1->getMinRange(0)<<" max="<<lod1->getMaxRange(0)<<std::endl;
|
||||
// std::cout<<" lod2 min="<<lod2->getMinRange(0)<<" max="<<lod2->getMaxRange(0)<<std::endl;
|
||||
public:
|
||||
SeamFinder(int x, int y, int lod, TXPArchive::TileInfo& info, TXPArchive *archive ):
|
||||
NodeVisitor(NodeVisitor::TRAVERSE_ALL_CHILDREN),
|
||||
_x(x), _y(y), _lod(lod), _info(info), _archive(archive)
|
||||
{};
|
||||
|
||||
#if 0
|
||||
|
||||
if (lod1->getMaxRange(0)<lod2->getMaxRange(0))
|
||||
{
|
||||
// std::cout<<" lod1 is high res, lod2 is low res."<<std::endl;
|
||||
}
|
||||
else if (lod1->getMaxRange(0)==lod2->getMaxRange(0))
|
||||
{
|
||||
// std::cout<<" lod1 and lod2 range equal. ****************"<<std::endl;
|
||||
// don't replace with seam LOD node, leave as a standard LOD.
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
// std::cout<<" lod1 is low res, lod2 is high res. --------------"<<std::endl;
|
||||
// don't replace with seam LOD node, leave as a standard LOD
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
TXPSeamLOD* seam = new TXPSeamLOD(x,y,level,lod1->getCenter(),lod1->getMinRange(0),lod1->getMaxRange(0),lod2->getMaxRange(0));
|
||||
seam->setArchive(_archive);
|
||||
seam->addChild(lod1->getChild(0)); // low res
|
||||
seam->addChild(lod2->getChild(0)); // high res
|
||||
return seam;
|
||||
virtual void apply(osg::Group& group)
|
||||
{
|
||||
for (unsigned int i = 0; i < group.getNumChildren(); i++)
|
||||
{
|
||||
osg::Node* child = group.getChild(i);
|
||||
osg::Node* seam = seamReplacement(child);
|
||||
if (child != seam)
|
||||
{
|
||||
group.replaceChild(child,seam);
|
||||
}
|
||||
else
|
||||
{
|
||||
child->accept(*this);
|
||||
}
|
||||
}
|
||||
}
|
||||
return child;
|
||||
|
||||
protected:
|
||||
osg::Node* seamReplacement(osg::Node* node);
|
||||
|
||||
int _x, _y, _lod;
|
||||
TXPArchive::TileInfo& _info;
|
||||
TXPArchive *_archive;
|
||||
};
|
||||
|
||||
osg::Node* SeamFinder::seamReplacement(osg::Node* node)
|
||||
{
|
||||
osg::Group* group = node->asGroup();
|
||||
if (group == 0) return node;
|
||||
|
||||
std::vector<osg::Node*> nonSeamChildren;
|
||||
osg::LOD* hiRes = 0;
|
||||
osg::LOD* loRes = 0;
|
||||
|
||||
for (unsigned int i = 0; i < group->getNumChildren(); i++)
|
||||
{
|
||||
osg::LOD* lod = dynamic_cast<osg::LOD*>(group->getChild(i));
|
||||
if (lod == 0)
|
||||
{
|
||||
nonSeamChildren.push_back(group->getChild(i));
|
||||
continue;
|
||||
}
|
||||
|
||||
bool nonSeamChild = true;
|
||||
|
||||
// seam center is outside the bounding box of the tile
|
||||
if (!_info.bbox.contains(lod->getCenter()))
|
||||
{
|
||||
// seams have center as the neighbour tile
|
||||
osg::Vec3 d = _info.center - lod->getCenter();
|
||||
if (((fabs(d.x())-_info.size.x()) > 0.0001) && ((fabs(d.y())-_info.size.y()) > 0.0001))
|
||||
{
|
||||
nonSeamChildren.push_back(lod);
|
||||
continue;
|
||||
}
|
||||
|
||||
// low res seam has min/max ranges of lod+1 range/lod 0 range
|
||||
if ((fabs(_info.minRange-lod->getMinRange(0))<0.001)&&(fabs(_info.lod0Range-lod->getMaxRange(0))<0.001))
|
||||
{
|
||||
|
||||
if (loRes==0)
|
||||
{
|
||||
loRes = lod;
|
||||
nonSeamChild = false;
|
||||
}
|
||||
}
|
||||
|
||||
// hi res seam has min/max ranges of 0 range/lod+1 range
|
||||
if ((lod->getMinRange(0)==0.0f)&&(fabs(_info.minRange-lod->getMaxRange(0))<0.001))
|
||||
{
|
||||
if (hiRes==0)
|
||||
{
|
||||
hiRes = lod;
|
||||
nonSeamChild = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (nonSeamChild)
|
||||
{
|
||||
nonSeamChildren.push_back(lod);
|
||||
}
|
||||
}
|
||||
|
||||
if (loRes)
|
||||
{
|
||||
int x = _x;
|
||||
int y = _y;
|
||||
int lod = _lod;
|
||||
osg::Vec3 delta = loRes->getCenter()-_info.center;
|
||||
if (fabs(delta.x())>fabs(delta.y()))
|
||||
{
|
||||
if (delta.x()<0.0) --x; // west
|
||||
else x++; // east
|
||||
}
|
||||
else
|
||||
{
|
||||
if (delta.y()<0.0) --y; // south
|
||||
else ++y; // north
|
||||
}
|
||||
TXPSeamLOD* seam = new TXPSeamLOD(
|
||||
x,
|
||||
y,
|
||||
lod,
|
||||
loRes->getCenter(),
|
||||
0.f,
|
||||
_info.minRange,
|
||||
_info.maxRange
|
||||
);
|
||||
seam->setArchive(_archive);
|
||||
seam->addChild(loRes->getChild(0)); // low res
|
||||
if (hiRes)
|
||||
{
|
||||
seam->addChild(hiRes->getChild(0)); // high res
|
||||
seam->setHiResPresent(true);
|
||||
}
|
||||
if (nonSeamChildren.size())
|
||||
{
|
||||
seam->setNonSeamChildrenIndex(seam->getNumChildren());
|
||||
for (unsigned int i = 0; i < nonSeamChildren.size(); i++)
|
||||
seam->addChild(nonSeamChildren[i]);
|
||||
}
|
||||
return seam;
|
||||
}
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
bool TXPTileNode::loadTile(int x, int y, int lod)
|
||||
@@ -173,38 +237,24 @@ bool TXPTileNode::loadTile(int x, int y, int lod)
|
||||
double realMinRange = info.minRange;
|
||||
double realMaxRange = info.maxRange;
|
||||
double usedMaxRange = osg::maximum(info.maxRange,1e7);
|
||||
osg::Group* tileGroup = _archive->getTileContent(x,y,lod,realMinRange,realMaxRange,usedMaxRange);
|
||||
osg::Vec3 tileCenter;
|
||||
osg::Group* tileGroup = _archive->getTileContent(x,y,lod,realMinRange,realMaxRange,usedMaxRange,tileCenter);
|
||||
|
||||
|
||||
// if group has only one child, then simply use its child.
|
||||
// if group has only one child, then simply use its child.
|
||||
#if 1
|
||||
while (tileGroup->getNumChildren()==1 && tileGroup->getChild(0)->asGroup())
|
||||
{
|
||||
tileGroup = tileGroup->getChild(0)->asGroup();
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
if (tileGroup->getNumChildren()==5)
|
||||
// Handle seams
|
||||
if (lod < (numLods-1))
|
||||
{
|
||||
// candidate for being a Tile with seams.
|
||||
// std::cout<<"------- Seams candidate ------ "<<std::endl;
|
||||
// std::cout<<" info.center = "<<info.center<<std::endl;
|
||||
// PrintVisitor pv;
|
||||
// tileGroup->accept(pv);
|
||||
|
||||
for(unsigned int i=1;i<tileGroup->getNumChildren();++i)
|
||||
{
|
||||
osg::Node* child = tileGroup->getChild(i);
|
||||
osg::Node* replacement = seamReplacement(child,x,y,lod,info);
|
||||
if (child!=replacement)
|
||||
{
|
||||
tileGroup->replaceChild(child,replacement);
|
||||
}
|
||||
}
|
||||
|
||||
SeamFinder sfv(x,y,lod,info,_archive);
|
||||
tileGroup->accept(sfv);
|
||||
}
|
||||
|
||||
|
||||
if (lod < (numLods-1))
|
||||
{
|
||||
char pagedLODfile[1024];
|
||||
@@ -222,6 +272,7 @@ bool TXPTileNode::loadTile(int x, int y, int lod)
|
||||
pagedLOD->setFileName(1,pagedLODfile);
|
||||
pagedLOD->setRange(1,0,info.minRange);
|
||||
pagedLOD->setCenter(info.center);
|
||||
//pagedLOD->setCenter(tileCenter);
|
||||
pagedLOD->setRadius(info.radius);
|
||||
pagedLOD->setPriorityOffset(0,numLods-lod);
|
||||
pagedLOD->setPriorityScale(0,1.0f);
|
||||
@@ -240,6 +291,9 @@ bool TXPTileNode::loadTile(int x, int y, int lod)
|
||||
TileMapper::instance()->insertPagedLOD(x,y,lod,pagedLOD.get());
|
||||
|
||||
addChild(pagedLOD.get());
|
||||
|
||||
//PrintVisitor pv;
|
||||
//accept(pv);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -54,9 +54,6 @@ public:
|
||||
void setArchive(TXPArchive* archive);
|
||||
bool loadTile(int x, int y, int lod);
|
||||
|
||||
osg::Node* seamReplacement(osg::Node* child, int x, int y, int level,
|
||||
TXPArchive::TileInfo& info);
|
||||
|
||||
protected:
|
||||
|
||||
virtual ~TXPTileNode();
|
||||
|
||||
Reference in New Issue
Block a user