Terrain: use the main camera's viewpoint for intersection tests

Fixes lag spikes caused by intersection tests loading/unloading terrain pages.
0.6.1
scrawl 8 years ago
parent a629d48df6
commit ac78d01b2b

@ -222,6 +222,7 @@ namespace MWRender
mTerrain.reset(new Terrain::QuadTreeWorld(sceneRoot, mRootNode, mResourceSystem, mTerrainStorage, Mask_Terrain, Mask_PreCompile));
else
mTerrain.reset(new Terrain::TerrainGrid(sceneRoot, mRootNode, mResourceSystem, mTerrainStorage, Mask_Terrain, Mask_PreCompile));
mTerrain->setDefaultViewer(mViewer->getCamera());
mCamera.reset(new Camera(mViewer->getCamera()));

@ -99,8 +99,10 @@ void QuadTreeNode::traverse(osg::NodeVisitor &nv)
if (!hasValidBounds())
return;
if ((mLodCallback && mLodCallback->isSufficientDetail(this, nv.getEyePoint())) || !getNumChildren())
getView(nv)->add(this, true);
ViewData* vd = getView(nv);
if ((mLodCallback && mLodCallback->isSufficientDetail(this, vd->getEyePoint())) || !getNumChildren())
vd->add(this, true);
else
osg::Group::traverse(nv);
}
@ -130,11 +132,20 @@ ViewData* QuadTreeNode::getView(osg::NodeVisitor &nv)
if (nv.getVisitorType() == osg::NodeVisitor::CULL_VISITOR)
{
osgUtil::CullVisitor* cv = static_cast<osgUtil::CullVisitor*>(&nv);
return mViewDataMap->getViewData(cv->getCurrentCamera(), true);
ViewData* vd = mViewDataMap->getViewData(cv->getCurrentCamera(), true);
vd->setEyePoint(nv.getEyePoint());
return vd;
}
else // INTERSECTION_VISITOR
{
return mViewDataMap->getViewData(&nv, (nv.referenceCount() > 0)); // if no referenceCount, the visitor was allocated on the stack
static osg::ref_ptr<osg::Object> dummyObj = new osg::DummyObject;
ViewData* vd = mViewDataMap->getViewData(dummyObj.get(), true);
ViewData* defaultView = mViewDataMap->getDefaultView();
if (defaultView->hasEyePoint())
vd->setEyePoint(defaultView->getEyePoint());
else
vd->setEyePoint(nv.getEyePoint());
return vd;
}
}

@ -456,5 +456,10 @@ void QuadTreeWorld::reportStats(unsigned int frameNumber, osg::Stats *stats)
stats->setAttribute(frameNumber, "Composite", mCompositeMapRenderer->getCompileSetSize());
}
void QuadTreeWorld::setDefaultViewer(osg::Object *obj)
{
mViewDataMap->setDefaultViewer(obj);
}
}

@ -33,6 +33,8 @@ namespace Terrain
void reportStats(unsigned int frameNumber, osg::Stats* stats);
virtual void setDefaultViewer(osg::Object* obj);
private:
void ensureQuadTreeBuilt();

@ -7,6 +7,7 @@ ViewData::ViewData()
: mNumEntries(0)
, mFrameLastUsed(0)
, mChanged(false)
, mHasEyePoint(false)
{
}
@ -43,6 +44,22 @@ bool ViewData::hasChanged() const
return mChanged;
}
bool ViewData::hasEyePoint() const
{
return mHasEyePoint;
}
void ViewData::setEyePoint(const osg::Vec3f &eye)
{
mEyePoint = eye;
mHasEyePoint = true;
}
const osg::Vec3f& ViewData::getEyePoint() const
{
return mEyePoint;
}
void ViewData::reset(unsigned int frame)
{
// clear any unused entries
@ -150,5 +167,15 @@ void ViewDataMap::clear()
mViewVector.clear();
}
void ViewDataMap::setDefaultViewer(osg::Object *viewer)
{
mDefaultViewer = viewer;
}
ViewData* ViewDataMap::getDefaultView()
{
return getViewData(mDefaultViewer, true);
}
}

@ -52,12 +52,19 @@ namespace Terrain
/// @return Have any nodes changed since the last frame
bool hasChanged() const;
bool hasEyePoint() const;
void setEyePoint(const osg::Vec3f& eye);
const osg::Vec3f& getEyePoint() const;
private:
std::vector<Entry> mEntries;
unsigned int mNumEntries;
unsigned int mFrameLastUsed;
bool mChanged;
osg::ref_ptr<osg::Object> mViewer;
osg::Vec3f mEyePoint;
bool mHasEyePoint;
};
class ViewDataMap : public osg::Referenced
@ -71,6 +78,10 @@ namespace Terrain
void clear();
void setDefaultViewer(osg::Object* viewer);
ViewData* getDefaultView();
private:
std::list<ViewData> mViewVector;
@ -78,6 +89,8 @@ namespace Terrain
Map mViews;
std::deque<ViewData*> mUnusedViews;
osg::ref_ptr<osg::Object> mDefaultViewer;
};
}

@ -14,6 +14,7 @@ namespace osg
class Group;
class Stats;
class Node;
class Object;
}
namespace Resource
@ -87,6 +88,9 @@ namespace Terrain
virtual void reportStats(unsigned int frameNumber, osg::Stats* stats) {}
/// Set the default viewer (usually a Camera), used as viewpoint for any viewers that don't use their own viewpoint.
virtual void setDefaultViewer(osg::Object* obj) {}
Storage* getStorage() { return mStorage; }
protected:

Loading…
Cancel
Save