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:
parent
58d08d402a
commit
6a3d27ce82
7 changed files with 76 additions and 4 deletions
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue