diff --git a/components/terrain/quadtreenode.cpp b/components/terrain/quadtreenode.cpp index 5eb59a6a2..d556bb4fe 100644 --- a/components/terrain/quadtreenode.cpp +++ b/components/terrain/quadtreenode.cpp @@ -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; diff --git a/components/terrain/quadtreenode.hpp b/components/terrain/quadtreenode.hpp index 1d996487e..c7a6a09d9 100644 --- a/components/terrain/quadtreenode.hpp +++ b/components/terrain/quadtreenode.hpp @@ -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); diff --git a/components/terrain/quadtreeworld.cpp b/components/terrain/quadtreeworld.cpp index 24f24ff37..9c27fa1ad 100644 --- a/components/terrain/quadtreeworld.cpp +++ b/components/terrain/quadtreeworld.cpp @@ -1,5 +1,7 @@ #include "quadtreeworld.hpp" +#include + #include #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; igetNumChildren(); ++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(&nv); + traverse(mRootNode.get(), vd, cv, true); + } + else + mRootNode->traverse(nv); + for (unsigned int i=0; igetNumEntries(); ++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()); diff --git a/components/terrain/viewdata.cpp b/components/terrain/viewdata.cpp index aff20cd54..ce89150c1 100644 --- a/components/terrain/viewdata.cpp +++ b/components/terrain/viewdata.cpp @@ -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 mRenderingNode; };