mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-01-29 17:15:32 +00:00
Terrain: use the main camera's viewpoint for intersection tests
Fixes lag spikes caused by intersection tests loading/unloading terrain pages.
This commit is contained in:
parent
a629d48df6
commit
ac78d01b2b
7 changed files with 67 additions and 4 deletions
|
@ -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…
Reference in a new issue