1
0
Fork 0
mirror of https://github.com/OpenMW/openmw.git synced 2025-01-16 18:59:57 +00:00
openmw/components/terrain/viewdata.cpp
scrawl 8c151364df 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.
2017-03-14 19:27:56 +01:00

134 lines
2.5 KiB
C++

#include "viewdata.hpp"
namespace Terrain
{
ViewData::ViewData()
: mNumEntries(0)
, mFrameLastUsed(0)
, mChanged(false)
, mPersistent(false)
{
}
void ViewData::add(QuadTreeNode *node, bool visible)
{
int index = mNumEntries++;
mEntries.resize(index+1);
Entry& entry = mEntries[index];
if (entry.set(node, visible))
mChanged = true;
}
unsigned int ViewData::getNumEntries() const
{
return mNumEntries;
}
ViewData::Entry &ViewData::getEntry(unsigned int i)
{
return mEntries[i];
}
void ViewData::reset(unsigned int frame)
{
// clear any unused entries
for (unsigned int i=mNumEntries; i<mEntries.size(); ++i)
mEntries[i].set(NULL, false);
// reset index for next frame
mNumEntries = 0;
mFrameLastUsed = frame;
}
void ViewData::clear()
{
for (unsigned int i=0; i<mEntries.size(); ++i)
mEntries[i].set(NULL, false);
mNumEntries = 0;
mFrameLastUsed = 0;
}
ViewData::Entry::Entry()
: mNode(NULL)
, mVisible(true)
{
}
bool ViewData::Entry::set(QuadTreeNode *node, bool visible)
{
mVisible = visible;
if (node == mNode)
return false;
else
{
mNode = node;
// clear cached data
mRenderingNode = NULL;
return true;
}
}
ViewData *ViewDataMap::getViewData(osg::Object *viewer, bool ref)
{
Map::const_iterator found = mViews.find(viewer);
if (found == mViews.end())
{
ViewData* vd = createOrReuseView();
if (ref)
vd->setViewer(viewer);
mViews[viewer] = vd;
return vd;
}
else
return found->second;
}
ViewData *ViewDataMap::createOrReuseView()
{
if (mUnusedViews.size())
{
ViewData* vd = mUnusedViews.front();
mUnusedViews.pop_front();
return vd;
}
else
{
mViewVector.push_back(ViewData());
return &mViewVector.back();
}
}
void ViewDataMap::clearUnusedViews(unsigned int frame)
{
for (Map::iterator it = mViews.begin(); it != mViews.end(); )
{
ViewData* vd = it->second;
if (!vd->getPersistent() &&
(!vd->getViewer() // if no ref was held, always need to clear to avoid holding a dangling ref.
|| vd->getFrameLastUsed() + 2 < frame))
{
vd->setViewer(NULL);
vd->clear();
mUnusedViews.push_back(vd);
mViews.erase(it++);
}
else
++it;
}
}
void ViewDataMap::clear()
{
mViews.clear();
mUnusedViews.clear();
mViewVector.clear();
}
}