minsize based on mergedecision solves partial culling

Signed-off-by: Bret Curtis <psi29a@gmail.com>
pull/578/head
bzzt lost a hitlab login 5 years ago committed by Bret Curtis
parent 0b4226f3e2
commit 8a624e5a71

@ -285,6 +285,8 @@ namespace MWRender
{ {
mMergeFactor = Settings::Manager::getFloat("object paging merge factor", "Terrain"); mMergeFactor = Settings::Manager::getFloat("object paging merge factor", "Terrain");
mMinSize = Settings::Manager::getFloat("object paging min size", "Terrain"); mMinSize = Settings::Manager::getFloat("object paging min size", "Terrain");
mMinSizeMergeFactor = Settings::Manager::getFloat("object paging min size merge factor", "Terrain");
mMinSizeCostMultiplier = Settings::Manager::getFloat("object paging min size cost multiplier", "Terrain");
} }
osg::ref_ptr<osg::Node> ObjectPaging::createChunk(float size, const osg::Vec2f& center, const osg::Vec3f& viewPoint, bool compile) osg::ref_ptr<osg::Node> ObjectPaging::createChunk(float size, const osg::Vec2f& center, const osg::Vec3f& viewPoint, bool compile)
@ -358,7 +360,9 @@ namespace MWRender
typedef std::map<osg::ref_ptr<const osg::Node>, InstanceList> NodeMap; typedef std::map<osg::ref_ptr<const osg::Node>, InstanceList> NodeMap;
NodeMap nodes; NodeMap nodes;
AnalyzeVisitor analyzeVisitor; AnalyzeVisitor analyzeVisitor;
float minSize = mMinSize;
if (mMinSizeMergeFactor)
minSize *= mMinSizeMergeFactor;
for (const auto& pair : refs) for (const auto& pair : refs)
{ {
const ESM::CellRef& ref = pair.second; const ESM::CellRef& ref = pair.second;
@ -381,7 +385,7 @@ namespace MWRender
SizeCache::iterator found = mSizeCache.find(pair.first); SizeCache::iterator found = mSizeCache.find(pair.first);
if (found != mSizeCache.end()) if (found != mSizeCache.end())
{ {
if (found->second < d*mMinSize) if (found->second < d*minSize)
continue; continue;
} }
} }
@ -402,7 +406,7 @@ namespace MWRender
osg::ref_ptr<const osg::Node> cnode = mSceneManager->getTemplate(model, false); osg::ref_ptr<const osg::Node> cnode = mSceneManager->getTemplate(model, false);
float radius = cnode->getBound().radius() * ref.mScale; float radius = cnode->getBound().radius() * ref.mScale;
if (radius < d*mMinSize) if (radius < d*minSize)
{ {
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(mSizeCacheMutex); OpenThreads::ScopedLock<OpenThreads::Mutex> lock(mSizeCacheMutex);
{ {
@ -435,23 +439,26 @@ namespace MWRender
float mergeBenefit = analyzeVisitor.getMergeBenefit(analyzeResult) * mMergeFactor; float mergeBenefit = analyzeVisitor.getMergeBenefit(analyzeResult) * mMergeFactor;
bool merge = mergeBenefit > mergeCost; bool merge = mergeBenefit > mergeCost;
// add a ref to the original template, to hint to the cache that it's still being used and should be kept in cache float minSizeMerged = mMinSize;
templateRefs->mObjects.push_back(cnode); float factor2 = mergeBenefit > 0 ? std::min(1.f, mergeCost * mMinSizeCostMultiplier / mergeBenefit) : 1;
float minSizeMergeFactor2 = (1-factor2) * mMinSizeMergeFactor + factor2;
if (pair.second.mNeedCompile) if (minSizeMergeFactor2 > 0)
{ minSizeMerged *= minSizeMergeFactor2;
int mode = osgUtil::GLObjectsVisitor::COMPILE_STATE_ATTRIBUTES;
if (!merge)
mode |= osgUtil::GLObjectsVisitor::COMPILE_DISPLAY_LISTS;
stateToCompile._mode = mode;
const_cast<osg::Node*>(cnode)->accept(stateToCompile);
}
unsigned int numinstances = 0;
for (auto cref : pair.second.mInstances) for (auto cref : pair.second.mInstances)
{ {
const ESM::CellRef& ref = *cref; const ESM::CellRef& ref = *cref;
osg::Vec3f pos = ref.mPos.asVec3(); osg::Vec3f pos = ref.mPos.asVec3();
if (minSizeMerged != minSize)
{
float d = (viewPoint - pos).length();
float radius = cnode->getBound().radius() * cref->mScale;
if (radius < d*minSizeMerged)
continue;
}
osg::Matrixf matrix; osg::Matrixf matrix;
matrix.preMultTranslate(pos - worldCenter); matrix.preMultTranslate(pos - worldCenter);
matrix.preMultRotate( osg::Quat(ref.mPos.rot[2], osg::Vec3f(0,0,-1)) * matrix.preMultRotate( osg::Quat(ref.mPos.rot[2], osg::Vec3f(0,0,-1)) *
@ -474,6 +481,21 @@ namespace MWRender
mergeGroup->addChild(trans); mergeGroup->addChild(trans);
else else
group->addChild(trans); group->addChild(trans);
++numinstances;
}
if (numinstances > 0)
{
// add a ref to the original template, to hint to the cache that it's still being used and should be kept in cache
templateRefs->mObjects.push_back(cnode);
if (pair.second.mNeedCompile)
{
int mode = osgUtil::GLObjectsVisitor::COMPILE_STATE_ATTRIBUTES;
if (!merge)
mode |= osgUtil::GLObjectsVisitor::COMPILE_DISPLAY_LISTS;
stateToCompile._mode = mode;
const_cast<osg::Node*>(cnode)->accept(stateToCompile);
}
} }
} }

@ -42,6 +42,8 @@ namespace MWRender
Resource::SceneManager* mSceneManager; Resource::SceneManager* mSceneManager;
float mMergeFactor; float mMergeFactor;
float mMinSize; float mMinSize;
float mMinSizeMergeFactor;
float mMinSizeCostMultiplier;
OpenThreads::Mutex mDisabledMutex; OpenThreads::Mutex mDisabledMutex;
std::set<ESM::RefNum> mDisabled; std::set<ESM::RefNum> mDisabled;

@ -115,6 +115,12 @@ object paging merge factor = 1500
# Cull objects smaller than this size divided by distance # Cull objects smaller than this size divided by distance
object paging min size = 0.01 object paging min size = 0.01
# Adjusts 'min size' based on merging decision. Allows inexpensive objects to be rendered from a greater distance.
object paging min size merge factor = 0.6
# Controls how inexpensive an object needs to be to utilize 'min size merge factor'.
object paging min size cost multiplier = 4
[Fog] [Fog]
# If true, use extended fog parameters for distant terrain not controlled by # If true, use extended fog parameters for distant terrain not controlled by

Loading…
Cancel
Save