mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-02-21 17:39:40 +00:00
Move traverse methods to the QuadTreeNode
This commit is contained in:
parent
a02f730a77
commit
ce4e8be9ac
3 changed files with 57 additions and 50 deletions
|
@ -109,6 +109,51 @@ void QuadTreeNode::initNeighbours()
|
||||||
getChild(i)->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)
|
void QuadTreeNode::traverse(osg::NodeVisitor &nv)
|
||||||
{
|
{
|
||||||
if (!hasValidBounds())
|
if (!hasValidBounds())
|
||||||
|
|
|
@ -72,8 +72,16 @@ namespace Terrain
|
||||||
/// center in cell coordinates
|
/// center in cell coordinates
|
||||||
const osg::Vec2f& getCenter() const;
|
const osg::Vec2f& getCenter() const;
|
||||||
|
|
||||||
|
/// Traverse the child tree and populate the ViewData
|
||||||
virtual void traverse(osg::NodeVisitor& nv);
|
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.
|
/// Set the Lod callback to use for determining when to stop traversing further down the quad tree.
|
||||||
void setLodCallback(LodCallback* lodCallback);
|
void setLodCallback(LodCallback* lodCallback);
|
||||||
|
|
||||||
|
|
|
@ -246,52 +246,6 @@ QuadTreeWorld::~QuadTreeWorld()
|
||||||
mViewDataMap->clear();
|
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.
|
/// 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)
|
unsigned int getVertexLod(QuadTreeNode* node, int vertexLodMod)
|
||||||
{
|
{
|
||||||
|
@ -400,10 +354,10 @@ void QuadTreeWorld::accept(osg::NodeVisitor &nv)
|
||||||
int x,y;
|
int x,y;
|
||||||
stream >> x;
|
stream >> x;
|
||||||
stream >> y;
|
stream >> y;
|
||||||
traverseToCell(mRootNode.get(), vd, x,y);
|
mRootNode->traverseTo(vd, 1, osg::Vec2f(x+0.5,y+0.5));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
traverse(mRootNode.get(), vd, cv, mRootNode->getLodCallback(), cv->getViewPoint(), true, mViewDistance);
|
mRootNode->traverse(vd, &nv, cv->getViewPoint(), true, mViewDistance);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
mRootNode->traverse(nv);
|
mRootNode->traverse(nv);
|
||||||
|
@ -483,7 +437,7 @@ void QuadTreeWorld::cacheCell(View *view, int x, int y)
|
||||||
{
|
{
|
||||||
ensureQuadTreeBuilt();
|
ensureQuadTreeBuilt();
|
||||||
ViewData* vd = static_cast<ViewData*>(view);
|
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)
|
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);
|
ViewData* vd = static_cast<ViewData*>(view);
|
||||||
vd->setViewPoint(viewPoint);
|
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)
|
for (unsigned int i=0; i<vd->getNumEntries() && !abort; ++i)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue