1
0
Fork 0
mirror of https://github.com/OpenMW/openmw.git synced 2025-01-30 02:15:34 +00:00

Add a dictionary to retrieve the LOD mesh name of a mesh cache

This commit is contained in:
Cédric Mocquillon 2022-08-31 22:02:19 +02:00
parent 58d08d402a
commit 6a3d27ce82
7 changed files with 76 additions and 4 deletions

View file

@ -76,6 +76,7 @@ namespace MWRender
osg::ref_ptr<osg::Node> ObjectPaging::getChunk(float size, const osg::Vec2f& center, unsigned char lod, unsigned int lodFlags, bool activeGrid, const osg::Vec3f& viewPoint, bool compile)
{
lod = static_cast<unsigned char>(lodFlags >> (4 * 4));
if (activeGrid && !mActiveGrid)
return nullptr;
@ -86,7 +87,7 @@ namespace MWRender
return static_cast<osg::Node*>(obj.get());
else
{
osg::ref_ptr<osg::Node> node = createChunk(size, center, activeGrid, viewPoint, compile);
osg::ref_ptr<osg::Node> node = createChunk(size, center, activeGrid, viewPoint, compile, lod);
mCache->addEntryToObjectCache(id, node.get());
return node;
}
@ -411,7 +412,7 @@ namespace MWRender
mMinSizeCostMultiplier = Settings::Manager::getFloat("object paging min size cost multiplier", "Terrain");
}
osg::ref_ptr<osg::Node> ObjectPaging::createChunk(float size, const osg::Vec2f& center, bool activeGrid, const osg::Vec3f& viewPoint, bool compile)
osg::ref_ptr<osg::Node> ObjectPaging::createChunk(float size, const osg::Vec2f& center, bool activeGrid, const osg::Vec3f& viewPoint, bool compile, unsigned char lod)
{
osg::Vec2i startCell = osg::Vec2i(std::floor(center.x() - size/2.f), std::floor(center.y() - size/2.f));
@ -548,6 +549,17 @@ namespace MWRender
}
}
if (!activeGrid)
{
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;
else
model = mLODNameCache.insert(found, { key, Misc::ResourceHelpers::getLODMeshName(model, mSceneManager->getVFS(), lod) })->second;
}
osg::ref_ptr<const osg::Node> cnode = mSceneManager->getTemplate(model, false);
if (activeGrid)

View file

@ -29,7 +29,7 @@ namespace MWRender
osg::ref_ptr<osg::Node> getChunk(float size, const osg::Vec2f& center, unsigned char lod, unsigned int lodFlags, bool activeGrid, const osg::Vec3f& viewPoint, bool compile) override;
osg::ref_ptr<osg::Node> createChunk(float size, const osg::Vec2f& center, bool activeGrid, const osg::Vec3f& viewPoint, bool compile);
osg::ref_ptr<osg::Node> createChunk(float size, const osg::Vec2f& center, bool activeGrid, const osg::Vec3f& viewPoint, bool compile, unsigned char lod);
unsigned int getNodeMask() override;
@ -75,6 +75,11 @@ namespace MWRender
std::mutex mSizeCacheMutex;
typedef std::map<ESM::RefNum, float> SizeCache;
SizeCache mSizeCache;
std::mutex mLODNameCacheMutex;
typedef std::pair<std::string, unsigned char> LODNameCacheKey; //Key: mesh name, lod level
typedef std::map<LODNameCacheKey, std::string> LODNameCache; //Cache: key, mesh name to use
LODNameCache mLODNameCache;
};
class RefnumMarker : public osg::Object

View file

@ -5,9 +5,14 @@
namespace Misc
{
inline size_t findExtension(std::string_view file)
{
return file.find_last_of('.');
}
inline std::string_view getFileExtension(std::string_view file)
{
if (auto extPos = file.find_last_of('.'); extPos != std::string::npos)
if (auto extPos = findExtension(file); extPos != std::string::npos)
{
file.remove_prefix(extPos + 1);
return file;

View file

@ -4,9 +4,11 @@
#include <string_view>
#include <algorithm>
#include <components/misc/pathhelpers.hpp>
#include <components/misc/strings/lower.hpp>
#include <components/misc/strings/algorithm.hpp>
#include <components/settings/settings.hpp>
#include <components/vfs/manager.hpp>
namespace
@ -164,3 +166,38 @@ bool Misc::ResourceHelpers::isHiddenMarker(std::string_view id)
{
return Misc::StringUtils::ciEqual(id, "prisonmarker") || Misc::StringUtils::ciEqual(id, "divinemarker") || Misc::StringUtils::ciEqual(id, "templemarker") || Misc::StringUtils::ciEqual(id, "northmarker");
}
namespace
{
std::string getLODMeshNameImpl(std::string resPath, const VFS::Manager* vfs, std::string_view pattern)
{
if (auto w = Misc::findExtension(resPath); w != std::string::npos)
resPath.insert(w, pattern);
return vfs->normalizeFilename(resPath);
}
std::string getBestLODMeshName(std::string const& resPath, const VFS::Manager* vfs, std::string_view pattern)
{
if (const auto& result = getLODMeshNameImpl(resPath, vfs, pattern); vfs->exists(result))
return result;
return resPath;
}
}
std::string Misc::ResourceHelpers::getLODMeshName(std::string resPath, const VFS::Manager* vfs, unsigned char lod)
{
static const std::string distantMeshPattern = Settings::Manager::getString("distant mesh pattern", "Terrain");
std::string meshName = getBestLODMeshName(resPath, vfs, distantMeshPattern + "_" + std::to_string(lod));
if (meshName != resPath)
return meshName;
for (char l = lod; l >= 0; --l)
{
std::stringstream patern;
patern << distantMeshPattern << "_" << int(l);
meshName = getBestLODMeshName(resPath, vfs, patern.str());
if (meshName != resPath)
return meshName;
}
return getBestLODMeshName(resPath, vfs, distantMeshPattern);
}

View file

@ -30,6 +30,7 @@ namespace Misc
/// marker objects that have a hardcoded function in the game logic, should be hidden from the player
bool isHiddenMarker(std::string_view id);
std::string getLODMeshName(std::string resPath, const VFS::Manager* vfs, unsigned char lod = 0);
}
}

View file

@ -205,3 +205,12 @@ object paging min size cost multiplier
This setting adjusts the calculated cost of merging an object used in the mentioned functionality.
The larger this value is, the less expensive objects can be before they are discarded.
See the formula above to figure out the math.
distant mesh pattern
------------------
:Type: string
:Range:
:Default: _dist
The mesh filename pattern to look for when detecting distant meshes (it will replace original mesh outside active grid)

View file

@ -119,6 +119,9 @@ object paging min size merge factor = 0.3
# Controls how inexpensive an object needs to be to utilize 'min size merge factor'.
object paging min size cost multiplier = 25
# The mesh filename pattern to look for when detecting distant meshes (it will replace original mesh outside active grid)
distant mesh pattern = _dist
[Fog]
# If true, use extended fog parameters for distant terrain not controlled by