Add special handling for CullVisitor to QuadTreeWorld.

- Cull only against bounding box, not bounding sphere, as this appears to perform better.
- Also traverse into non visible nodes to compute their LOD, this is to avoid nodes having to be loaded in when the player turns the view around, and will avoid unnecessary refs/unrefs of rendering data in the View. This should probably be turned off at some point for static cameras, such as the local maps.
0.6.1
scrawl 8 years ago
parent f19a88be9d
commit 8c151364df

@ -104,7 +104,7 @@ void QuadTreeNode::traverse(osg::NodeVisitor &nv)
}
if ((mLodCallback && mLodCallback->isSufficientDetail(this, nv)) || !getNumChildren())
getView(nv)->add(this);
getView(nv)->add(this, true);
else
osg::Group::traverse(nv);
}
@ -114,6 +114,11 @@ void QuadTreeNode::setLodCallback(LodCallback *lodCallback)
mLodCallback = lodCallback;
}
LodCallback *QuadTreeNode::getLodCallback()
{
return mLodCallback;
}
void QuadTreeNode::setViewDataMap(ViewDataMap *map)
{
mViewDataMap = map;

@ -66,6 +66,8 @@ namespace Terrain
/// Set the Lod callback to use for determining when to stop traversing further down the quad tree.
void setLodCallback(LodCallback* lodCallback);
LodCallback* getLodCallback();
/// Set the view data map that the finally used nodes for a given camera/intersection are pushed onto.
void setViewDataMap(ViewDataMap* map);

@ -1,5 +1,7 @@
#include "quadtreeworld.hpp"
#include <osgUtil/CullVisitor>
#include <components/sceneutil/workqueue.hpp>
#include "quadtreenode.hpp"
@ -235,15 +237,39 @@ QuadTreeWorld::~QuadTreeWorld()
}
}
void traverse(QuadTreeNode* node, ViewData* vd, osgUtil::CullVisitor* cv, bool visible)
{
if (!node->hasValidBounds())
return;
visible = visible && !cv->isCulled(node->getBoundingBox());
bool stopTraversal = (node->getLodCallback() && node->getLodCallback()->isSufficientDetail(node, *cv)) || !node->getNumChildren();
if (stopTraversal)
vd->add(node, visible);
else
{
for (unsigned int i=0; i<node->getNumChildren(); ++i)
traverse(node->getChild(i), vd, cv, visible);
}
}
void QuadTreeWorld::accept(osg::NodeVisitor &nv)
{
if (nv.getVisitorType() != osg::NodeVisitor::CULL_VISITOR)// && nv.getVisitorType() != osg::NodeVisitor::INTERSECTION_VISITOR)
return;
mRootNode->traverse(nv);
ViewData* vd = mRootNode->getView(nv);
if (nv.getVisitorType() == osg::NodeVisitor::CULL_VISITOR)
{
osgUtil::CullVisitor* cv = static_cast<osgUtil::CullVisitor*>(&nv);
traverse(mRootNode.get(), vd, cv, true);
}
else
mRootNode->traverse(nv);
for (unsigned int i=0; i<vd->getNumEntries(); ++i)
{
ViewData::Entry& entry = vd->getEntry(i);
@ -253,7 +279,8 @@ void QuadTreeWorld::accept(osg::NodeVisitor &nv)
entry.mRenderingNode = mChunkManager->getChunk(entry.mNode->getSize(), entry.mNode->getCenter(), lod);
}
entry.mRenderingNode->accept(nv);
if (entry.mVisible)
entry.mRenderingNode->accept(nv);
}
vd->reset(nv.getTraversalNumber());

@ -12,14 +12,14 @@ ViewData::ViewData()
}
void ViewData::add(QuadTreeNode *node)
void ViewData::add(QuadTreeNode *node, bool visible)
{
int index = mNumEntries++;
mEntries.resize(index+1);
Entry& entry = mEntries[index];
if (entry.set(node))
if (entry.set(node, visible))
mChanged = true;
}
@ -37,7 +37,7 @@ void ViewData::reset(unsigned int frame)
{
// clear any unused entries
for (unsigned int i=mNumEntries; i<mEntries.size(); ++i)
mEntries[i].set(NULL);
mEntries[i].set(NULL, false);
// reset index for next frame
mNumEntries = 0;
@ -48,19 +48,21 @@ void ViewData::reset(unsigned int frame)
void ViewData::clear()
{
for (unsigned int i=0; i<mEntries.size(); ++i)
mEntries[i].set(NULL);
mEntries[i].set(NULL, false);
mNumEntries = 0;
mFrameLastUsed = 0;
}
ViewData::Entry::Entry()
: mNode(NULL)
, mVisible(true)
{
}
bool ViewData::Entry::set(QuadTreeNode *node)
bool ViewData::Entry::set(QuadTreeNode *node, bool visible)
{
mVisible = visible;
if (node == mNode)
return false;
else

@ -16,7 +16,7 @@ namespace Terrain
public:
ViewData();
void add(QuadTreeNode* node);
void add(QuadTreeNode* node, bool visible);
void reset(unsigned int frame);
@ -26,9 +26,10 @@ namespace Terrain
{
Entry();
bool set(QuadTreeNode* node);
bool set(QuadTreeNode* node, bool visible);
QuadTreeNode* mNode;
bool mVisible;
osg::ref_ptr<osg::Node> mRenderingNode;
};

Loading…
Cancel
Save