Merge branch 'Only-lod-for-far-far-away-kingdom' into 'master'

For distant cells, only LODs are considered during object paging.

See merge request OpenMW/openmw!4872
This commit is contained in:
Cédric Mocquillon 2025-09-20 10:40:31 +00:00
commit 9715cd2dd3
3 changed files with 23 additions and 8 deletions

View File

@ -657,6 +657,7 @@ namespace MWRender
std::map<ESM::RefNum, PagedCellRef> refs;
const bool keepOnlyLOD = size >= Settings::terrain().mChunkSizeLimit;
if (mWorldspace == ESM::Cell::sDefaultWorldspaceId)
{
refs = collectESM3References(size, startCell, store);
@ -690,6 +691,7 @@ namespace MWRender
std::vector<const PagedCellRef*> mInstances;
AnalyzeVisitor::Result mAnalyzeResult;
bool mNeedCompile = false;
bool mToKeep = false;
};
typedef std::map<osg::ref_ptr<const osg::Node>, InstanceList> NodeMap;
NodeMap nodes;
@ -750,21 +752,29 @@ namespace MWRender
}
}
bool isLod = false;
if (!activeGrid)
{
VFS::Path::Normalized newModel;
std::lock_guard<std::mutex> lock(mLODNameCacheMutex);
LODNameCacheKey key{ model, lod };
LODNameCache::const_iterator found = mLODNameCache.lower_bound(key);
if (found != mLODNameCache.end() && found->first == key)
model = found->second;
newModel = found->second;
else
model = mLODNameCache
.emplace_hint(found, std::move(key),
Misc::ResourceHelpers::getLODMeshName(world.getESMVersions()[refNum.mContentFile],
model, *mSceneManager->getVFS(), lod))
->second;
newModel
= mLODNameCache
.emplace_hint(found, std::move(key),
Misc::ResourceHelpers::getLODMeshName(world.getESMVersions()[refNum.mContentFile],
model, *mSceneManager->getVFS(), lod))
->second;
isLod = model != newModel;
model = newModel;
}
if (keepOnlyLOD && !isLod)
continue;
osg::ref_ptr<const osg::Node> cnode = mSceneManager->getTemplate(model, false);
if (activeGrid)
@ -786,7 +796,7 @@ namespace MWRender
}
const float radius2 = cnode->getBound().radius2() * ref.mScale * ref.mScale;
if (radius2 < dSqr * minSize * minSize && !activeGrid)
if (!isLod && radius2 < dSqr * minSize * minSize && !activeGrid)
{
std::lock_guard<std::mutex> lock(mSizeCacheMutex);
mSizeCache[refNum] = radius2;
@ -802,6 +812,7 @@ namespace MWRender
const_cast<osg::Node*>(nodePtr)->accept(analyzeVisitor);
emplaced.first->second.mAnalyzeResult = analyzeVisitor.retrieveResult();
emplaced.first->second.mNeedCompile = compile && nodePtr->referenceCount() <= 2;
emplaced.first->second.mToKeep = isLod;
}
else
analyzeVisitor.addInstance(emplaced.first->second.mAnalyzeResult);
@ -834,7 +845,7 @@ namespace MWRender
{
const PagedCellRef& ref = *refPtr;
if (!activeGrid && minSizeMerged != minSize
if (!pair.second.mToKeep && !activeGrid && minSizeMerged != minSize
&& cnode->getBound().radius2() * ref.mScale * ref.mScale
< (viewPoint - ref.mPosition).length2() * minSizeMerged * minSizeMerged)
continue;

View File

@ -38,6 +38,7 @@ namespace Settings
SettingValue<float> mObjectPagingMinSizeCostMultiplier{ mIndex, "Terrain",
"object paging min size cost multiplier", makeMaxStrictSanitizerFloat(0) };
SettingValue<bool> mWaterCulling{ mIndex, "Terrain", "water culling" };
SettingValue<int> mChunkSizeLimit{ mIndex, "Terrain", "chunk size limit" };
};
}

View File

@ -122,6 +122,9 @@ object paging min size cost multiplier = 25
# Don't draw water if it's evaluated to be below all visible terrain
water culling = true
# The number of cells above which only LOD meshes are displayed
chunk size limit = 2048
[Fog]
# If true, use extended fog parameters for distant terrain not controlled by