mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-02-06 13:15:33 +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));
|
mTerrain.reset(new Terrain::QuadTreeWorld(sceneRoot, mRootNode, mResourceSystem, mTerrainStorage, Mask_Terrain, Mask_PreCompile));
|
||||||
else
|
else
|
||||||
mTerrain.reset(new Terrain::TerrainGrid(sceneRoot, mRootNode, mResourceSystem, mTerrainStorage, Mask_Terrain, Mask_PreCompile));
|
mTerrain.reset(new Terrain::TerrainGrid(sceneRoot, mRootNode, mResourceSystem, mTerrainStorage, Mask_Terrain, Mask_PreCompile));
|
||||||
|
mTerrain->setDefaultViewer(mViewer->getCamera());
|
||||||
|
|
||||||
mCamera.reset(new Camera(mViewer->getCamera()));
|
mCamera.reset(new Camera(mViewer->getCamera()));
|
||||||
|
|
||||||
|
|
|
@ -99,8 +99,10 @@ void QuadTreeNode::traverse(osg::NodeVisitor &nv)
|
||||||
if (!hasValidBounds())
|
if (!hasValidBounds())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if ((mLodCallback && mLodCallback->isSufficientDetail(this, nv.getEyePoint())) || !getNumChildren())
|
ViewData* vd = getView(nv);
|
||||||
getView(nv)->add(this, true);
|
|
||||||
|
if ((mLodCallback && mLodCallback->isSufficientDetail(this, vd->getEyePoint())) || !getNumChildren())
|
||||||
|
vd->add(this, true);
|
||||||
else
|
else
|
||||||
osg::Group::traverse(nv);
|
osg::Group::traverse(nv);
|
||||||
}
|
}
|
||||||
|
@ -130,11 +132,20 @@ ViewData* QuadTreeNode::getView(osg::NodeVisitor &nv)
|
||||||
if (nv.getVisitorType() == osg::NodeVisitor::CULL_VISITOR)
|
if (nv.getVisitorType() == osg::NodeVisitor::CULL_VISITOR)
|
||||||
{
|
{
|
||||||
osgUtil::CullVisitor* cv = static_cast<osgUtil::CullVisitor*>(&nv);
|
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
|
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());
|
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);
|
void reportStats(unsigned int frameNumber, osg::Stats* stats);
|
||||||
|
|
||||||
|
virtual void setDefaultViewer(osg::Object* obj);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void ensureQuadTreeBuilt();
|
void ensureQuadTreeBuilt();
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,7 @@ ViewData::ViewData()
|
||||||
: mNumEntries(0)
|
: mNumEntries(0)
|
||||||
, mFrameLastUsed(0)
|
, mFrameLastUsed(0)
|
||||||
, mChanged(false)
|
, mChanged(false)
|
||||||
|
, mHasEyePoint(false)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -43,6 +44,22 @@ bool ViewData::hasChanged() const
|
||||||
return mChanged;
|
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)
|
void ViewData::reset(unsigned int frame)
|
||||||
{
|
{
|
||||||
// clear any unused entries
|
// clear any unused entries
|
||||||
|
@ -150,5 +167,15 @@ void ViewDataMap::clear()
|
||||||
mViewVector.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
|
/// @return Have any nodes changed since the last frame
|
||||||
bool hasChanged() const;
|
bool hasChanged() const;
|
||||||
|
|
||||||
|
bool hasEyePoint() const;
|
||||||
|
|
||||||
|
void setEyePoint(const osg::Vec3f& eye);
|
||||||
|
const osg::Vec3f& getEyePoint() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<Entry> mEntries;
|
std::vector<Entry> mEntries;
|
||||||
unsigned int mNumEntries;
|
unsigned int mNumEntries;
|
||||||
unsigned int mFrameLastUsed;
|
unsigned int mFrameLastUsed;
|
||||||
bool mChanged;
|
bool mChanged;
|
||||||
osg::ref_ptr<osg::Object> mViewer;
|
osg::ref_ptr<osg::Object> mViewer;
|
||||||
|
osg::Vec3f mEyePoint;
|
||||||
|
bool mHasEyePoint;
|
||||||
};
|
};
|
||||||
|
|
||||||
class ViewDataMap : public osg::Referenced
|
class ViewDataMap : public osg::Referenced
|
||||||
|
@ -71,6 +78,10 @@ namespace Terrain
|
||||||
|
|
||||||
void clear();
|
void clear();
|
||||||
|
|
||||||
|
void setDefaultViewer(osg::Object* viewer);
|
||||||
|
|
||||||
|
ViewData* getDefaultView();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::list<ViewData> mViewVector;
|
std::list<ViewData> mViewVector;
|
||||||
|
|
||||||
|
@ -78,6 +89,8 @@ namespace Terrain
|
||||||
Map mViews;
|
Map mViews;
|
||||||
|
|
||||||
std::deque<ViewData*> mUnusedViews;
|
std::deque<ViewData*> mUnusedViews;
|
||||||
|
|
||||||
|
osg::ref_ptr<osg::Object> mDefaultViewer;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,6 +14,7 @@ namespace osg
|
||||||
class Group;
|
class Group;
|
||||||
class Stats;
|
class Stats;
|
||||||
class Node;
|
class Node;
|
||||||
|
class Object;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace Resource
|
namespace Resource
|
||||||
|
@ -87,6 +88,9 @@ namespace Terrain
|
||||||
|
|
||||||
virtual void reportStats(unsigned int frameNumber, osg::Stats* stats) {}
|
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; }
|
Storage* getStorage() { return mStorage; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
Loading…
Reference in a new issue