Merge branch 'vfs_normalized_path_11' into 'master'

Use normalized path in SceneManager (#8138)

See merge request OpenMW/openmw!4370
pull/3236/head
psi29a 4 months ago
commit 04fe036360

@ -90,7 +90,7 @@ namespace CSVRender
{
auto sceneMgr = mData.getResourceSystem()->getSceneManager();
osg::ref_ptr<osg::Node> temp = sceneMgr->getInstance(model);
osg::ref_ptr<osg::Node> temp = sceneMgr->getInstance(VFS::Path::toNormalized(model));
mSkeleton = dynamic_cast<SceneUtil::Skeleton*>(temp.get());
if (!mSkeleton)
{
@ -123,7 +123,7 @@ namespace CSVRender
auto node = mNodeMap.find(boneName);
if (!mesh.empty() && node != mNodeMap.end())
{
auto instance = sceneMgr->getInstance(mesh);
auto instance = sceneMgr->getInstance(VFS::Path::toNormalized(mesh));
SceneUtil::attach(instance, mSkeleton, boneName, node->second, sceneMgr);
}
}

@ -151,7 +151,9 @@ void CSVRender::Object::update()
}
else if (!model.empty())
{
std::string path = "meshes\\" + model;
constexpr VFS::Path::NormalizedView meshes("meshes");
VFS::Path::Normalized path(meshes);
path /= model;
mResourceSystem->getSceneManager()->getInstance(path, mBaseNode);
}
else

@ -73,7 +73,8 @@ namespace MWRender
if (!parent)
return nullptr;
osg::ref_ptr<osg::Node> instance = mResourceSystem->getSceneManager()->getInstance(model, parent);
osg::ref_ptr<osg::Node> instance
= mResourceSystem->getSceneManager()->getInstance(VFS::Path::toNormalized(model), parent);
const NodeMap& nodeMap = getNodeMap();
NodeMap::const_iterator found = nodeMap.find(bonename);
@ -89,7 +90,8 @@ namespace MWRender
osg::ref_ptr<osg::Node> ActorAnimation::attach(
const std::string& model, std::string_view bonename, std::string_view bonefilter, bool isLight)
{
osg::ref_ptr<const osg::Node> templateNode = mResourceSystem->getSceneManager()->getTemplate(model);
osg::ref_ptr<const osg::Node> templateNode
= mResourceSystem->getSceneManager()->getTemplate(VFS::Path::toNormalized(model));
const NodeMap& nodeMap = getNodeMap();
auto found = nodeMap.find(bonename);
@ -145,7 +147,7 @@ namespace MWRender
if (mesh.empty())
return mesh;
const std::string holsteredName = addSuffixBeforeExtension(mesh, "_sh");
const VFS::Path::Normalized holsteredName(addSuffixBeforeExtension(mesh, "_sh"));
if (mResourceSystem->getVFS()->exists(holsteredName))
{
osg::ref_ptr<osg::Node> shieldTemplate = mResourceSystem->getSceneManager()->getInstance(holsteredName);
@ -243,7 +245,8 @@ namespace MWRender
// file.
if (shieldNode && !shieldNode->getNumChildren())
{
osg::ref_ptr<osg::Node> fallbackNode = mResourceSystem->getSceneManager()->getInstance(mesh, shieldNode);
osg::ref_ptr<osg::Node> fallbackNode
= mResourceSystem->getSceneManager()->getInstance(VFS::Path::toNormalized(mesh), shieldNode);
if (isEnchanted)
SceneUtil::addEnchantedGlow(shieldNode, mResourceSystem, glowColor);
}
@ -381,7 +384,7 @@ namespace MWRender
if (!weaponNode->getNumChildren())
{
osg::ref_ptr<osg::Node> fallbackNode
= mResourceSystem->getSceneManager()->getInstance(mesh, weaponNode);
= mResourceSystem->getSceneManager()->getInstance(VFS::Path::toNormalized(mesh), weaponNode);
resetControllers(fallbackNode);
}
@ -463,7 +466,7 @@ namespace MWRender
// Add new ones
osg::Vec4f glowColor = ammo->getClass().getEnchantmentColor(*ammo);
std::string model = ammo->getClass().getCorrectedModel(*ammo);
const VFS::Path::Normalized model(ammo->getClass().getCorrectedModel(*ammo));
for (unsigned int i = 0; i < ammoCount; ++i)
{
osg::ref_ptr<osg::Group> arrowNode = ammoNode->getChild(i)->asGroup();

@ -1473,7 +1473,7 @@ namespace MWRender
}
void loadBonesFromFile(
osg::ref_ptr<osg::Node>& baseNode, const std::string& model, Resource::ResourceSystem* resourceSystem)
osg::ref_ptr<osg::Node>& baseNode, VFS::Path::NormalizedView model, Resource::ResourceSystem* resourceSystem)
{
const osg::Node* node = resourceSystem->getSceneManager()->getTemplate(model).get();
osg::ref_ptr<osg::Node> sheathSkeleton(
@ -1511,7 +1511,7 @@ namespace MWRender
for (const auto& name : resourceSystem->getVFS()->getRecursiveDirectoryIterator(animationPath))
{
if (Misc::getFileExtension(name) == "nif")
loadBonesFromFile(node, name, resourceSystem);
loadBonesFromFile(node, VFS::Path::toNormalized(name), resourceSystem);
}
}
@ -1526,7 +1526,7 @@ namespace MWRender
Cache::iterator found = cache.find(model);
if (found == cache.end())
{
osg::ref_ptr<osg::Node> created = sceneMgr->getInstance(model);
osg::ref_ptr<osg::Node> created = sceneMgr->getInstance(VFS::Path::toNormalized(model));
if (inject)
{
@ -1547,7 +1547,7 @@ namespace MWRender
}
else
{
osg::ref_ptr<osg::Node> created = sceneMgr->getInstance(model);
osg::ref_ptr<osg::Node> created = sceneMgr->getInstance(VFS::Path::toNormalized(model));
if (inject)
{
@ -1762,7 +1762,8 @@ namespace MWRender
}
parentNode->addChild(trans);
osg::ref_ptr<osg::Node> node = mResourceSystem->getSceneManager()->getInstance(model, trans);
osg::ref_ptr<osg::Node> node
= mResourceSystem->getSceneManager()->getInstance(VFS::Path::toNormalized(model), trans);
// Morrowind has a white ambient light attached to the root VFX node of the scenegraph
node->getOrCreateStateSet()->setAttributeAndModes(

@ -27,7 +27,7 @@ namespace MWRender
clear();
}
void EffectManager::addEffect(const std::string& model, std::string_view textureOverride,
void EffectManager::addEffect(VFS::Path::NormalizedView model, std::string_view textureOverride,
const osg::Vec3f& worldPosition, float scale, bool isMagicVFX)
{
osg::ref_ptr<osg::Node> node = mResourceSystem->getSceneManager()->getInstance(model);

@ -2,11 +2,12 @@
#define OPENMW_MWRENDER_EFFECTMANAGER_H
#include <memory>
#include <string>
#include <vector>
#include <osg/ref_ptr>
#include <components/vfs/pathutil.hpp>
namespace osg
{
class Group;
@ -33,8 +34,8 @@ namespace MWRender
~EffectManager();
/// Add an effect. When it's finished playing, it will be removed automatically.
void addEffect(const std::string& model, std::string_view textureOverride, const osg::Vec3f& worldPosition,
float scale, bool isMagicVFX = true);
void addEffect(VFS::Path::NormalizedView model, std::string_view textureOverride,
const osg::Vec3f& worldPosition, float scale, bool isMagicVFX = true);
void update(float dt);

@ -53,7 +53,7 @@ namespace MWRender
if (model.empty())
return;
mResourceSystem->getSceneManager()->getInstance(
Misc::ResourceHelpers::correctMeshPath(model), mObjectRoot.get());
VFS::Path::toNormalized(Misc::ResourceHelpers::correctMeshPath(model)), mObjectRoot.get());
}
template <class Record>

@ -428,7 +428,7 @@ namespace MWRender
osg::Vec3f worldCenter = osg::Vec3f(center.x(), center.y(), 0) * ESM::Land::REAL_SIZE;
for (auto& pair : instances)
{
const osg::Node* temp = mSceneManager->getTemplate(pair.first);
const osg::Node* temp = mSceneManager->getTemplate(VFS::Path::toNormalized(pair.first));
osg::ref_ptr<osg::Node> node = static_cast<osg::Node*>(temp->clone(osg::CopyOp::DEEP_COPY_NODES
| osg::CopyOp::DEEP_COPY_DRAWABLES | osg::CopyOp::DEEP_COPY_USERDATA | osg::CopyOp::DEEP_COPY_ARRAYS
| osg::CopyOp::DEEP_COPY_PRIMITIVES));

@ -541,7 +541,7 @@ namespace MWRender
if (mesh.empty())
return std::string();
const std::string holsteredName = addSuffixBeforeExtension(mesh, "_sh");
const VFS::Path::Normalized holsteredName(addSuffixBeforeExtension(mesh, "_sh"));
if (mResourceSystem->getVFS()->exists(holsteredName))
{
osg::ref_ptr<osg::Node> shieldTemplate = mResourceSystem->getSceneManager()->getInstance(holsteredName);

@ -671,7 +671,7 @@ namespace MWRender
->second;
}
osg::ref_ptr<const osg::Node> cnode = mSceneManager->getTemplate(model, false);
osg::ref_ptr<const osg::Node> cnode = mSceneManager->getTemplate(VFS::Path::toNormalized(model), false);
if (activeGrid)
{

@ -1263,7 +1263,7 @@ namespace MWRender
mActorsPaths->updatePtr(old, updated);
}
void RenderingManager::spawnEffect(const std::string& model, std::string_view texture,
void RenderingManager::spawnEffect(VFS::Path::NormalizedView model, std::string_view texture,
const osg::Vec3f& worldPosition, float scale, bool isMagicVFX)
{
mEffectManager->addEffect(model, texture, worldPosition, scale, isMagicVFX);
@ -1649,7 +1649,7 @@ namespace MWRender
osg::Vec3f RenderingManager::getHalfExtents(const MWWorld::ConstPtr& object) const
{
osg::Vec3f halfExtents(0, 0, 0);
std::string modelName = object.getClass().getCorrectedModel(object);
VFS::Path::Normalized modelName(object.getClass().getCorrectedModel(object));
if (modelName.empty())
return halfExtents;
@ -1680,7 +1680,7 @@ namespace MWRender
MWWorld::Scene* worldScene = MWBase::Environment::get().getWorldScene();
if (!rootNode || worldScene->isPagedRef(ptr))
{
const std::string model = ptr.getClass().getCorrectedModel(ptr);
const VFS::Path::Normalized model(ptr.getClass().getCorrectedModel(ptr));
if (model.empty())
return {};

@ -1,21 +1,21 @@
#ifndef OPENMW_MWRENDER_RENDERINGMANAGER_H
#define OPENMW_MWRENDER_RENDERINGMANAGER_H
#include <span>
#include "objects.hpp"
#include "renderinginterface.hpp"
#include "rendermode.hpp"
#include <components/settings/settings.hpp>
#include <components/vfs/pathutil.hpp>
#include <osg/Light>
#include <osg/ref_ptr>
#include <components/settings/settings.hpp>
#include <osgUtil/IncrementalCompileOperation>
#include "objects.hpp"
#include "renderinginterface.hpp"
#include "rendermode.hpp"
#include <deque>
#include <memory>
#include <span>
#include <unordered_map>
namespace osg
@ -196,7 +196,7 @@ namespace MWRender
SkyManager* getSkyManager();
void spawnEffect(const std::string& model, std::string_view texture, const osg::Vec3f& worldPosition,
void spawnEffect(VFS::Path::NormalizedView model, std::string_view texture, const osg::Vec3f& worldPosition,
float scale = 1.f, bool isMagicVFX = true);
/// Clear all savegame-specific data

@ -188,7 +188,7 @@ namespace MWRender
osg::Vec4f mSkyColour;
osg::Vec4f mFogColour;
std::string mCurrentParticleEffect;
VFS::Path::Normalized mCurrentParticleEffect;
float mRemainingTransitionTime;

@ -86,7 +86,7 @@ namespace MWRender
MWWorld::ConstContainerStoreIterator ammo = inv.getSlot(MWWorld::InventoryStore::Slot_Ammunition);
if (ammo == inv.end())
return;
std::string model = ammo->getClass().getCorrectedModel(*ammo);
VFS::Path::Normalized model(ammo->getClass().getCorrectedModel(*ammo));
osg::ref_ptr<osg::Node> arrow = getResourceSystem()->getSceneManager()->getInstance(model, parent);

@ -1437,9 +1437,9 @@ namespace MWScript
osg::Vec3f pos(ptr.getRefData().getPosition().asVec3());
msg << "Coordinates: " << pos.x() << " " << pos.y() << " " << pos.z() << std::endl;
auto vfs = MWBase::Environment::get().getResourceSystem()->getVFS();
std::string model
= ::Misc::ResourceHelpers::correctActorModelPath(ptr.getClass().getCorrectedModel(ptr), vfs);
msg << "Model: " << model << std::endl;
const VFS::Path::Normalized model(
::Misc::ResourceHelpers::correctActorModelPath(ptr.getClass().getCorrectedModel(ptr), vfs));
msg << "Model: " << model.value() << std::endl;
if (!model.empty())
{
const std::string archive = vfs->getArchive(model);
@ -1714,7 +1714,7 @@ namespace MWScript
for (const T& record : store.get<T>())
{
MWWorld::ManualRef ref(store, record.mId);
std::string model = ref.getPtr().getClass().getCorrectedModel(ref.getPtr());
VFS::Path::Normalized model(ref.getPtr().getClass().getCorrectedModel(ref.getPtr()));
if (!model.empty())
{
sceneManager->getTemplate(model);

@ -133,7 +133,7 @@ namespace MWWorld
mPreloadedObjects.insert(mKeyframeManager->get(kfname));
}
}
mPreloadedObjects.insert(mSceneManager->getTemplate(mesh));
mPreloadedObjects.insert(mSceneManager->getTemplate(VFS::Path::toNormalized(mesh)));
if (mPreloadInstances)
mPreloadedObjects.insert(mBulletShapeManager->cacheInstance(mesh));
else

@ -207,7 +207,8 @@ namespace MWWorld
attachTo = rotateNode;
}
osg::ref_ptr<osg::Node> projectile = mResourceSystem->getSceneManager()->getInstance(model, attachTo);
osg::ref_ptr<osg::Node> projectile
= mResourceSystem->getSceneManager()->getInstance(VFS::Path::toNormalized(model), attachTo);
if (state.mIdMagic.size() > 1)
{
@ -222,7 +223,8 @@ namespace MWWorld
attachTo->accept(findVisitor);
if (findVisitor.mFoundNode)
mResourceSystem->getSceneManager()->getInstance(
Misc::ResourceHelpers::correctMeshPath(weapon->mModel), findVisitor.mFoundNode);
VFS::Path::toNormalized(Misc::ResourceHelpers::correctMeshPath(weapon->mModel)),
findVisitor.mFoundNode);
}
}

@ -22,6 +22,7 @@
#include <components/resource/scenemanager.hpp>
#include <components/sceneutil/positionattitudetransform.hpp>
#include <components/settings/values.hpp>
#include <components/vfs/pathutil.hpp>
#include "../mwbase/environment.hpp"
#include "../mwbase/luamanager.hpp"
@ -1094,7 +1095,7 @@ namespace MWWorld
class PreloadMeshItem : public SceneUtil::WorkItem
{
public:
PreloadMeshItem(const std::string& mesh, Resource::SceneManager* sceneManager)
explicit PreloadMeshItem(VFS::Path::NormalizedView mesh, Resource::SceneManager* sceneManager)
: mMesh(mesh)
, mSceneManager(sceneManager)
{
@ -1118,21 +1119,21 @@ namespace MWWorld
void abort() override { mAborted = true; }
private:
std::string mMesh;
VFS::Path::Normalized mMesh;
Resource::SceneManager* mSceneManager;
std::atomic_bool mAborted{ false };
};
void Scene::preload(const std::string& mesh, bool useAnim)
{
std::string mesh_ = mesh;
std::string meshPath = mesh;
if (useAnim)
mesh_ = Misc::ResourceHelpers::correctActorModelPath(mesh_, mRendering.getResourceSystem()->getVFS());
meshPath = Misc::ResourceHelpers::correctActorModelPath(meshPath, mRendering.getResourceSystem()->getVFS());
if (!mRendering.getResourceSystem()->getSceneManager()->checkLoaded(mesh_, mRendering.getReferenceTime()))
if (!mRendering.getResourceSystem()->getSceneManager()->checkLoaded(meshPath, mRendering.getReferenceTime()))
{
osg::ref_ptr<PreloadMeshItem> item(
new PreloadMeshItem(mesh_, mRendering.getResourceSystem()->getSceneManager()));
osg::ref_ptr<PreloadMeshItem> item(new PreloadMeshItem(
VFS::Path::toNormalized(meshPath), mRendering.getResourceSystem()->getSceneManager()));
mRendering.getWorkQueue()->addWorkItem(item);
const auto isDone = [](const osg::ref_ptr<SceneUtil::WorkItem>& v) { return v->isDone(); };
mWorkItems.erase(std::remove_if(mWorkItems.begin(), mWorkItems.end(), isDone), mWorkItems.end());

@ -3638,8 +3638,8 @@ namespace MWWorld
if (texture.empty())
texture = Fallback::Map::getString("Blood_Texture_0");
std::string model = Misc::ResourceHelpers::correctMeshPath(std::string{
Fallback::Map::getString("Blood_Model_" + std::to_string(Misc::Rng::rollDice(3))) } /*[0, 2]*/);
VFS::Path::Normalized model(Misc::ResourceHelpers::correctMeshPath(std::string{
Fallback::Map::getString("Blood_Model_" + std::to_string(Misc::Rng::rollDice(3))) } /*[0, 2]*/));
mRendering->spawnEffect(model, texture, worldPosition, 1.0f, false);
}
@ -3647,7 +3647,7 @@ namespace MWWorld
void World::spawnEffect(const std::string& model, const std::string& textureOverride, const osg::Vec3f& worldPos,
float scale, bool isMagicVFX)
{
mRendering->spawnEffect(model, textureOverride, worldPos, scale, isMagicVFX);
mRendering->spawnEffect(VFS::Path::toNormalized(model), textureOverride, worldPos, scale, isMagicVFX);
}
struct ResetActorsVisitor

@ -978,11 +978,9 @@ namespace Resource
return static_cast<osg::Node*>(mErrorMarker->clone(osg::CopyOp::DEEP_COPY_ALL));
}
osg::ref_ptr<const osg::Node> SceneManager::getTemplate(std::string_view name, bool compile)
osg::ref_ptr<const osg::Node> SceneManager::getTemplate(VFS::Path::NormalizedView path, bool compile)
{
const VFS::Path::Normalized normalized(name);
osg::ref_ptr<osg::Object> obj = mCache->getRefFromObjectCache(normalized);
osg::ref_ptr<osg::Object> obj = mCache->getRefFromObjectCache(path);
if (obj)
return osg::ref_ptr<const osg::Node>(static_cast<osg::Node*>(obj.get()));
else
@ -990,14 +988,14 @@ namespace Resource
osg::ref_ptr<osg::Node> loaded;
try
{
loaded = load(normalized, mVFS, mImageManager, mNifFileManager, mBgsmFileManager);
loaded = load(path, mVFS, mImageManager, mNifFileManager, mBgsmFileManager);
SceneUtil::ProcessExtraDataVisitor extraDataVisitor(this);
loaded->accept(extraDataVisitor);
}
catch (const std::exception& e)
{
Log(Debug::Error) << "Failed to load '" << name << "': " << e.what() << ", using marker_error instead";
Log(Debug::Error) << "Failed to load '" << path << "': " << e.what() << ", using marker_error instead";
loaded = cloneErrorMarker();
}
@ -1014,7 +1012,7 @@ namespace Resource
osg::ref_ptr<Shader::ShaderVisitor> shaderVisitor(createShaderVisitor());
loaded->accept(*shaderVisitor);
if (canOptimize(normalized))
if (canOptimize(path.value()))
{
SceneUtil::Optimizer optimizer;
optimizer.setSharedStateManager(mSharedStateManager, &mSharedStateMutex);
@ -1033,15 +1031,14 @@ namespace Resource
else
loaded->getBound();
mCache->addEntryToObjectCache(normalized, loaded);
mCache->addEntryToObjectCache(path.value(), loaded);
return loaded;
}
}
osg::ref_ptr<osg::Node> SceneManager::getInstance(std::string_view name)
osg::ref_ptr<osg::Node> SceneManager::getInstance(VFS::Path::NormalizedView path)
{
osg::ref_ptr<const osg::Node> scene = getTemplate(name);
return getInstance(scene);
return getInstance(getTemplate(path));
}
osg::ref_ptr<osg::Node> SceneManager::cloneNode(const osg::Node* base)
@ -1079,9 +1076,9 @@ namespace Resource
return cloned;
}
osg::ref_ptr<osg::Node> SceneManager::getInstance(std::string_view name, osg::Group* parentNode)
osg::ref_ptr<osg::Node> SceneManager::getInstance(VFS::Path::NormalizedView path, osg::Group* parentNode)
{
osg::ref_ptr<osg::Node> cloned = getInstance(name);
osg::ref_ptr<osg::Node> cloned = getInstance(path);
attachTo(cloned, parentNode);
return cloned;
}

@ -158,7 +158,7 @@ namespace Resource
/// @note If the given filename does not exist or fails to load, an error marker mesh will be used instead.
/// If even the error marker mesh can not be found, an exception is thrown.
/// @note Thread safe.
osg::ref_ptr<const osg::Node> getTemplate(std::string_view name, bool compile = true);
osg::ref_ptr<const osg::Node> getTemplate(VFS::Path::NormalizedView path, bool compile = true);
/// Clone osg::Node safely.
/// @note Thread safe.
@ -173,12 +173,12 @@ namespace Resource
/// Instance the given scene template.
/// @see getTemplate
/// @note Thread safe.
osg::ref_ptr<osg::Node> getInstance(std::string_view name);
osg::ref_ptr<osg::Node> getInstance(VFS::Path::NormalizedView path);
/// Instance the given scene template and immediately attach it to a parent node
/// @see getTemplate
/// @note Not thread safe, unless parentNode is not part of the main scene graph yet.
osg::ref_ptr<osg::Node> getInstance(std::string_view name, osg::Group* parentNode);
osg::ref_ptr<osg::Node> getInstance(VFS::Path::NormalizedView path, osg::Group* parentNode);
/// Attach the given scene instance to the given parent node
/// @note You should have the parentNode in its intended position before calling this method,

@ -166,6 +166,8 @@ namespace VFS::Path
std::string_view view() const { return mValue; }
bool empty() const { return mValue.empty(); }
operator std::string_view() const { return mValue; }
operator const std::string&() const { return mValue; }
@ -183,6 +185,8 @@ namespace VFS::Path
return true;
}
void clear() { mValue.clear(); }
Normalized& operator=(NormalizedView value)
{
mValue = value.value();
@ -284,6 +288,13 @@ namespace VFS::Path
return std::hash<std::string_view>{}(s.value());
}
};
// A special function to be removed once conversion to VFS::Path::Normalized* is complete
template <class T>
Normalized toNormalized(T&& value)
{
return Normalized(std::forward<T>(value));
}
}
#endif

Loading…
Cancel
Save