Move traverse methods to the QuadTreeNode

pull/2325/head
bzzt 6 years ago committed by Andrei Kortunov
parent a02f730a77
commit ce4e8be9ac

@ -109,6 +109,51 @@ void QuadTreeNode::initNeighbours()
getChild(i)->initNeighbours();
}
void QuadTreeNode::traverse(ViewData* vd, osg::NodeVisitor* nv, const osg::Vec3f& viewPoint, bool visible, float maxDist)
{
if (!hasValidBounds())
return;
if (nv && nv->getVisitorType() == osg::NodeVisitor::CULL_VISITOR)
visible = visible && !static_cast<osgUtil::CullVisitor*>(nv)->isCulled(mBoundingBox);
float dist = distance(viewPoint);
if (dist > maxDist)
return;
bool stopTraversal = (mLodCallback->isSufficientDetail(this, dist)) || !getNumChildren();
if (stopTraversal)
vd->add(this, visible);
else
{
for (unsigned int i=0; i<getNumChildren(); ++i)
getChild(i)->traverse(vd, nv, viewPoint, visible, maxDist);
}
}
void QuadTreeNode::traverseTo(ViewData* vd, float size, const osg::Vec2f& center)
{
if (!hasValidBounds())
return;
if (getCenter().x() + getSize()/2.f <= center.x() - size/2.f
|| getCenter().x() - getSize()/2.f >= center.x() + size/2.f
|| getCenter().y() + getSize()/2.f <= center.y() - size/2.f
|| getCenter().y() - getSize()/2.f >= center.y() + size/2.f)
return;
bool stopTraversal = (getSize() == size);
if (stopTraversal)
vd->add(this, true);
else
{
for (unsigned int i=0; i<getNumChildren(); ++i)
getChild(i)->traverseTo(vd, size, center);
}
}
void QuadTreeNode::traverse(osg::NodeVisitor &nv)
{
if (!hasValidBounds())

@ -72,8 +72,16 @@ namespace Terrain
/// center in cell coordinates
const osg::Vec2f& getCenter() const;
/// Traverse the child tree and populate the ViewData
virtual void traverse(osg::NodeVisitor& nv);
/// Optimized version of traverse() that doesn't incur the overhead of NodeVisitor double-dispatch or fetching the various variables.
/// Note this doesn't do any culling for non-cull visitors (e.g. intersections) so it shouldn't be used for those.
void traverse(ViewData* vd, osg::NodeVisitor* nv, const osg::Vec3f& viewPoint, bool visible, float maxDist);
/// Traverse to a specific node and add only that node.
void traverseTo(ViewData* vd, float size, const osg::Vec2f& center);
/// Set the Lod callback to use for determining when to stop traversing further down the quad tree.
void setLodCallback(LodCallback* lodCallback);

@ -246,52 +246,6 @@ QuadTreeWorld::~QuadTreeWorld()
mViewDataMap->clear();
}
void traverse(QuadTreeNode* node, ViewData* vd, osg::NodeVisitor* nv, LodCallback* lodCallback, const osg::Vec3f& viewPoint, bool visible, float maxDist)
{
if (!node->hasValidBounds())
return;
if (nv && nv->getVisitorType() == osg::NodeVisitor::CULL_VISITOR)
visible = visible && !static_cast<osgUtil::CullVisitor*>(nv)->isCulled(node->getBoundingBox());
float dist = node->distance(viewPoint);
if (dist > maxDist)
return;
bool stopTraversal = (lodCallback && lodCallback->isSufficientDetail(node, dist)) || !node->getNumChildren();
if (stopTraversal)
vd->add(node, visible);
else
{
for (unsigned int i=0; i<node->getNumChildren(); ++i)
traverse(node->getChild(i), vd, nv, lodCallback, viewPoint, visible, maxDist);
}
}
void traverseToCell(QuadTreeNode* node, ViewData* vd, int cellX, int cellY)
{
if (!node->hasValidBounds())
return;
if (node->getCenter().x() + node->getSize()/2.f <= cellX
|| node->getCenter().x() - node->getSize()/2.f >= cellX+1
|| node->getCenter().y() + node->getSize()/2.f <= cellY
|| node->getCenter().y() - node->getSize()/2.f >= cellY+1)
return;
bool stopTraversal = !node->getNumChildren();
if (stopTraversal)
vd->add(node, true);
else
{
for (unsigned int i=0; i<node->getNumChildren(); ++i)
traverseToCell(node->getChild(i), vd, cellX, cellY);
}
}
/// get the level of vertex detail to render this node at, expressed relative to the native resolution of the data set.
unsigned int getVertexLod(QuadTreeNode* node, int vertexLodMod)
{
@ -400,10 +354,10 @@ void QuadTreeWorld::accept(osg::NodeVisitor &nv)
int x,y;
stream >> x;
stream >> y;
traverseToCell(mRootNode.get(), vd, x,y);
mRootNode->traverseTo(vd, 1, osg::Vec2f(x+0.5,y+0.5));
}
else
traverse(mRootNode.get(), vd, cv, mRootNode->getLodCallback(), cv->getViewPoint(), true, mViewDistance);
mRootNode->traverse(vd, &nv, cv->getViewPoint(), true, mViewDistance);
}
else
mRootNode->traverse(nv);
@ -483,7 +437,7 @@ void QuadTreeWorld::cacheCell(View *view, int x, int y)
{
ensureQuadTreeBuilt();
ViewData* vd = static_cast<ViewData*>(view);
traverseToCell(mRootNode.get(), vd, x, y);
mRootNode->traverseTo(vd, 1, osg::Vec2f(x+0.5f,y+0.5f));
for (unsigned int i=0; i<vd->getNumEntries(); ++i)
{
@ -503,7 +457,7 @@ void QuadTreeWorld::preload(View *view, const osg::Vec3f &viewPoint, std::atomic
ViewData* vd = static_cast<ViewData*>(view);
vd->setViewPoint(viewPoint);
traverse(mRootNode.get(), vd, nullptr, mRootNode->getLodCallback(), viewPoint, false, mViewDistance);
mRootNode->traverse(vd, nullptr, viewPoint, false, mViewDistance);
for (unsigned int i=0; i<vd->getNumEntries() && !abort; ++i)
{

Loading…
Cancel
Save