diff --git a/apps/openmw/mwrender/objectpaging.cpp b/apps/openmw/mwrender/objectpaging.cpp index 9f8b1ed86c..260ab90e4a 100644 --- a/apps/openmw/mwrender/objectpaging.cpp +++ b/apps/openmw/mwrender/objectpaging.cpp @@ -657,6 +657,7 @@ namespace MWRender std::map 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 mInstances; AnalyzeVisitor::Result mAnalyzeResult; bool mNeedCompile = false; + bool mToKeep = false; }; typedef std::map, InstanceList> NodeMap; NodeMap nodes; @@ -750,21 +752,29 @@ namespace MWRender } } + bool isLod = false; if (!activeGrid) { + VFS::Path::Normalized newModel; std::lock_guard 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 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 lock(mSizeCacheMutex); mSizeCache[refNum] = radius2; @@ -802,6 +812,7 @@ namespace MWRender const_cast(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; diff --git a/components/settings/categories/terrain.hpp b/components/settings/categories/terrain.hpp index d366aad97b..a4d5422960 100644 --- a/components/settings/categories/terrain.hpp +++ b/components/settings/categories/terrain.hpp @@ -38,6 +38,7 @@ namespace Settings SettingValue mObjectPagingMinSizeCostMultiplier{ mIndex, "Terrain", "object paging min size cost multiplier", makeMaxStrictSanitizerFloat(0) }; SettingValue mWaterCulling{ mIndex, "Terrain", "water culling" }; + SettingValue mChunkSizeLimit{ mIndex, "Terrain", "chunk size limit" }; }; } diff --git a/files/settings-default.cfg b/files/settings-default.cfg index 2c4bbab953..0ca8b35591 100644 --- a/files/settings-default.cfg +++ b/files/settings-default.cfg @@ -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