forked from mirror/openmw-tes3mp
Add NifFileManager to avoid duplicate parsing of the NIFFile in SceneManager and BulletShapeManager.
This commit is contained in:
parent
84305a1297
commit
3d12b2ca9d
11 changed files with 153 additions and 16 deletions
|
@ -636,7 +636,7 @@ namespace MWPhysics
|
||||||
// ---------------------------------------------------------------
|
// ---------------------------------------------------------------
|
||||||
|
|
||||||
PhysicsSystem::PhysicsSystem(Resource::ResourceSystem* resourceSystem, osg::ref_ptr<osg::Group> parentNode)
|
PhysicsSystem::PhysicsSystem(Resource::ResourceSystem* resourceSystem, osg::ref_ptr<osg::Group> parentNode)
|
||||||
: mShapeManager(new Resource::BulletShapeManager(resourceSystem->getVFS(), resourceSystem->getSceneManager()))
|
: mShapeManager(new Resource::BulletShapeManager(resourceSystem->getVFS(), resourceSystem->getSceneManager(), resourceSystem->getNifFileManager()))
|
||||||
, mDebugDrawEnabled(false)
|
, mDebugDrawEnabled(false)
|
||||||
, mTimeAccum(0.0f)
|
, mTimeAccum(0.0f)
|
||||||
, mWaterHeight(0)
|
, mWaterHeight(0)
|
||||||
|
|
|
@ -403,6 +403,8 @@ namespace MWWorld
|
||||||
// Delay the map update until scripts have been given a chance to run.
|
// Delay the map update until scripts have been given a chance to run.
|
||||||
// If we don't do this, objects that should be disabled will still appear on the map.
|
// If we don't do this, objects that should be disabled will still appear on the map.
|
||||||
mNeedMapUpdate = true;
|
mNeedMapUpdate = true;
|
||||||
|
|
||||||
|
mRendering.getResourceSystem()->clearCache();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Scene::changePlayerCell(CellStore *cell, const ESM::Position &pos, bool adjustPlayerPos)
|
void Scene::changePlayerCell(CellStore *cell, const ESM::Position &pos, bool adjustPlayerPos)
|
||||||
|
@ -518,6 +520,8 @@ namespace MWWorld
|
||||||
// Delay the map update until scripts have been given a chance to run.
|
// Delay the map update until scripts have been given a chance to run.
|
||||||
// If we don't do this, objects that should be disabled will still appear on the map.
|
// If we don't do this, objects that should be disabled will still appear on the map.
|
||||||
mNeedMapUpdate = true;
|
mNeedMapUpdate = true;
|
||||||
|
|
||||||
|
mRendering.getResourceSystem()->clearCache();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Scene::changeToExteriorCell (const ESM::Position& position, bool adjustPlayerPos)
|
void Scene::changeToExteriorCell (const ESM::Position& position, bool adjustPlayerPos)
|
||||||
|
|
|
@ -37,7 +37,7 @@ add_component_dir (vfs
|
||||||
)
|
)
|
||||||
|
|
||||||
add_component_dir (resource
|
add_component_dir (resource
|
||||||
scenemanager texturemanager resourcesystem bulletshapemanager bulletshape
|
scenemanager texturemanager resourcesystem bulletshapemanager bulletshape niffilemanager
|
||||||
)
|
)
|
||||||
|
|
||||||
add_component_dir (sceneutil
|
add_component_dir (sceneutil
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
|
|
||||||
#include "bulletshape.hpp"
|
#include "bulletshape.hpp"
|
||||||
#include "scenemanager.hpp"
|
#include "scenemanager.hpp"
|
||||||
|
#include "niffilemanager.hpp"
|
||||||
|
|
||||||
|
|
||||||
namespace Resource
|
namespace Resource
|
||||||
|
@ -94,9 +95,10 @@ private:
|
||||||
btTriangleMesh* mTriangleMesh;
|
btTriangleMesh* mTriangleMesh;
|
||||||
};
|
};
|
||||||
|
|
||||||
BulletShapeManager::BulletShapeManager(const VFS::Manager* vfs, SceneManager* sceneMgr)
|
BulletShapeManager::BulletShapeManager(const VFS::Manager* vfs, SceneManager* sceneMgr, NifFileManager* nifFileManager)
|
||||||
: mVFS(vfs)
|
: mVFS(vfs)
|
||||||
, mSceneManager(sceneMgr)
|
, mSceneManager(sceneMgr)
|
||||||
|
, mNifFileManager(nifFileManager)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -115,8 +117,6 @@ osg::ref_ptr<BulletShapeInstance> BulletShapeManager::createInstance(const std::
|
||||||
Index::iterator it = mIndex.find(normalized);
|
Index::iterator it = mIndex.find(normalized);
|
||||||
if (it == mIndex.end())
|
if (it == mIndex.end())
|
||||||
{
|
{
|
||||||
Files::IStreamPtr file = mVFS->get(normalized);
|
|
||||||
|
|
||||||
size_t extPos = normalized.find_last_of('.');
|
size_t extPos = normalized.find_last_of('.');
|
||||||
std::string ext;
|
std::string ext;
|
||||||
if (extPos != std::string::npos && extPos+1 < normalized.size())
|
if (extPos != std::string::npos && extPos+1 < normalized.size())
|
||||||
|
@ -126,7 +126,7 @@ osg::ref_ptr<BulletShapeInstance> BulletShapeManager::createInstance(const std::
|
||||||
{
|
{
|
||||||
NifBullet::BulletNifLoader loader;
|
NifBullet::BulletNifLoader loader;
|
||||||
// might be worth sharing NIFFiles with SceneManager in some way
|
// might be worth sharing NIFFiles with SceneManager in some way
|
||||||
shape = loader.load(Nif::NIFFilePtr(new Nif::NIFFile(file, normalized)));
|
shape = loader.load(mNifFileManager->get(normalized));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -16,6 +16,7 @@ namespace VFS
|
||||||
namespace Resource
|
namespace Resource
|
||||||
{
|
{
|
||||||
class SceneManager;
|
class SceneManager;
|
||||||
|
class NifFileManager;
|
||||||
|
|
||||||
class BulletShape;
|
class BulletShape;
|
||||||
class BulletShapeInstance;
|
class BulletShapeInstance;
|
||||||
|
@ -23,7 +24,7 @@ namespace Resource
|
||||||
class BulletShapeManager
|
class BulletShapeManager
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
BulletShapeManager(const VFS::Manager* vfs, SceneManager* sceneMgr);
|
BulletShapeManager(const VFS::Manager* vfs, SceneManager* sceneMgr, NifFileManager* nifFileManager);
|
||||||
~BulletShapeManager();
|
~BulletShapeManager();
|
||||||
|
|
||||||
osg::ref_ptr<BulletShapeInstance> createInstance(const std::string& name);
|
osg::ref_ptr<BulletShapeInstance> createInstance(const std::string& name);
|
||||||
|
@ -31,6 +32,7 @@ namespace Resource
|
||||||
private:
|
private:
|
||||||
const VFS::Manager* mVFS;
|
const VFS::Manager* mVFS;
|
||||||
SceneManager* mSceneManager;
|
SceneManager* mSceneManager;
|
||||||
|
NifFileManager* mNifFileManager;
|
||||||
|
|
||||||
typedef std::map<std::string, osg::ref_ptr<BulletShape> > Index;
|
typedef std::map<std::string, osg::ref_ptr<BulletShape> > Index;
|
||||||
Index mIndex;
|
Index mIndex;
|
||||||
|
|
64
components/resource/niffilemanager.cpp
Normal file
64
components/resource/niffilemanager.cpp
Normal file
|
@ -0,0 +1,64 @@
|
||||||
|
#include "niffilemanager.hpp"
|
||||||
|
|
||||||
|
#include <osgDB/ObjectCache>
|
||||||
|
#include <components/vfs/manager.hpp>
|
||||||
|
|
||||||
|
#include <osg/Timer>
|
||||||
|
|
||||||
|
namespace Resource
|
||||||
|
{
|
||||||
|
|
||||||
|
class NifFileHolder : public osg::Object
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
NifFileHolder(const Nif::NIFFilePtr& file)
|
||||||
|
: mNifFile(file)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
NifFileHolder(const NifFileHolder& copy, const osg::CopyOp& copyop)
|
||||||
|
: mNifFile(copy.mNifFile)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
NifFileHolder()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
META_Object(Resource, NifFileHolder)
|
||||||
|
|
||||||
|
Nif::NIFFilePtr mNifFile;
|
||||||
|
};
|
||||||
|
|
||||||
|
NifFileManager::NifFileManager(const VFS::Manager *vfs)
|
||||||
|
: mVFS(vfs)
|
||||||
|
{
|
||||||
|
mCache = new osgDB::ObjectCache;
|
||||||
|
}
|
||||||
|
|
||||||
|
NifFileManager::~NifFileManager()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void NifFileManager::clearCache()
|
||||||
|
{
|
||||||
|
// NIF files aren't needed any more when the converted objects are cached in SceneManager / BulletShapeManager,
|
||||||
|
// so we'll simply drop all nif files here, unlikely to need them again
|
||||||
|
mCache->clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
Nif::NIFFilePtr NifFileManager::get(const std::string &name)
|
||||||
|
{
|
||||||
|
osg::ref_ptr<osg::Object> obj = mCache->getRefFromObjectCache(name);
|
||||||
|
if (obj)
|
||||||
|
return static_cast<NifFileHolder*>(obj.get())->mNifFile;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Nif::NIFFilePtr file (new Nif::NIFFile(mVFS->get(name), name));
|
||||||
|
obj = new NifFileHolder(file);
|
||||||
|
mCache->addEntryToObjectCache(name, obj);
|
||||||
|
return file;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
45
components/resource/niffilemanager.hpp
Normal file
45
components/resource/niffilemanager.hpp
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
#ifndef OPENMW_COMPONENTS_RESOURCE_NIFFILEMANAGER_H
|
||||||
|
#define OPENMW_COMPONENTS_RESOURCE_NIFFILEMANAGER_H
|
||||||
|
|
||||||
|
#include <osg/ref_ptr>
|
||||||
|
|
||||||
|
#include <components/nif/niffile.hpp>
|
||||||
|
|
||||||
|
namespace VFS
|
||||||
|
{
|
||||||
|
class Manager;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace osgDB
|
||||||
|
{
|
||||||
|
class ObjectCache;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace Resource
|
||||||
|
{
|
||||||
|
|
||||||
|
/// @brief Handles caching of NIFFiles.
|
||||||
|
/// @note The NifFileManager is completely thread safe.
|
||||||
|
class NifFileManager
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
NifFileManager(const VFS::Manager* vfs);
|
||||||
|
~NifFileManager();
|
||||||
|
|
||||||
|
void clearCache();
|
||||||
|
|
||||||
|
/// Retrieve a NIF file from the cache, or load it from the VFS if not cached yet.
|
||||||
|
/// @note For performance reasons the NifFileManager does not handle case folding, needs
|
||||||
|
/// to be done in advance by other managers accessing the NifFileManager.
|
||||||
|
Nif::NIFFilePtr get(const std::string& name);
|
||||||
|
|
||||||
|
private:
|
||||||
|
// Use the osgDB::ObjectCache so objects are retrieved in thread safe way
|
||||||
|
osg::ref_ptr<osgDB::ObjectCache> mCache;
|
||||||
|
|
||||||
|
const VFS::Manager* mVFS;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
#include "scenemanager.hpp"
|
#include "scenemanager.hpp"
|
||||||
#include "texturemanager.hpp"
|
#include "texturemanager.hpp"
|
||||||
|
#include "niffilemanager.hpp"
|
||||||
|
|
||||||
namespace Resource
|
namespace Resource
|
||||||
{
|
{
|
||||||
|
@ -9,8 +10,9 @@ namespace Resource
|
||||||
ResourceSystem::ResourceSystem(const VFS::Manager *vfs)
|
ResourceSystem::ResourceSystem(const VFS::Manager *vfs)
|
||||||
: mVFS(vfs)
|
: mVFS(vfs)
|
||||||
{
|
{
|
||||||
|
mNifFileManager.reset(new NifFileManager(vfs));
|
||||||
mTextureManager.reset(new TextureManager(vfs));
|
mTextureManager.reset(new TextureManager(vfs));
|
||||||
mSceneManager.reset(new SceneManager(vfs, mTextureManager.get()));
|
mSceneManager.reset(new SceneManager(vfs, mTextureManager.get(), mNifFileManager.get()));
|
||||||
}
|
}
|
||||||
|
|
||||||
ResourceSystem::~ResourceSystem()
|
ResourceSystem::~ResourceSystem()
|
||||||
|
@ -28,6 +30,16 @@ namespace Resource
|
||||||
return mTextureManager.get();
|
return mTextureManager.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NifFileManager *ResourceSystem::getNifFileManager()
|
||||||
|
{
|
||||||
|
return mNifFileManager.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ResourceSystem::clearCache()
|
||||||
|
{
|
||||||
|
mNifFileManager->clearCache();
|
||||||
|
}
|
||||||
|
|
||||||
const VFS::Manager* ResourceSystem::getVFS() const
|
const VFS::Manager* ResourceSystem::getVFS() const
|
||||||
{
|
{
|
||||||
return mVFS;
|
return mVFS;
|
||||||
|
|
|
@ -13,8 +13,9 @@ namespace Resource
|
||||||
|
|
||||||
class SceneManager;
|
class SceneManager;
|
||||||
class TextureManager;
|
class TextureManager;
|
||||||
|
class NifFileManager;
|
||||||
|
|
||||||
/// @brief Wrapper class that constructs and provides access to the various resource subsystems.
|
/// @brief Wrapper class that constructs and provides access to the most commonly used resource subsystems.
|
||||||
/// @par Resource subsystems can be used with multiple OpenGL contexts, just like the OSG equivalents, but
|
/// @par Resource subsystems can be used with multiple OpenGL contexts, just like the OSG equivalents, but
|
||||||
/// are built around the use of a single virtual file system.
|
/// are built around the use of a single virtual file system.
|
||||||
class ResourceSystem
|
class ResourceSystem
|
||||||
|
@ -25,12 +26,17 @@ namespace Resource
|
||||||
|
|
||||||
SceneManager* getSceneManager();
|
SceneManager* getSceneManager();
|
||||||
TextureManager* getTextureManager();
|
TextureManager* getTextureManager();
|
||||||
|
NifFileManager* getNifFileManager();
|
||||||
|
|
||||||
|
/// Indicates to each resource manager to clear the cache, i.e. to drop cached objects that are no longer referenced.
|
||||||
|
void clearCache();
|
||||||
|
|
||||||
const VFS::Manager* getVFS() const;
|
const VFS::Manager* getVFS() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::auto_ptr<SceneManager> mSceneManager;
|
std::auto_ptr<SceneManager> mSceneManager;
|
||||||
std::auto_ptr<TextureManager> mTextureManager;
|
std::auto_ptr<TextureManager> mTextureManager;
|
||||||
|
std::auto_ptr<NifFileManager> mNifFileManager;
|
||||||
|
|
||||||
const VFS::Manager* mVFS;
|
const VFS::Manager* mVFS;
|
||||||
|
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
#include <components/sceneutil/util.hpp>
|
#include <components/sceneutil/util.hpp>
|
||||||
|
|
||||||
#include "texturemanager.hpp"
|
#include "texturemanager.hpp"
|
||||||
|
#include "niffilemanager.hpp"
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
|
@ -104,9 +105,10 @@ namespace
|
||||||
namespace Resource
|
namespace Resource
|
||||||
{
|
{
|
||||||
|
|
||||||
SceneManager::SceneManager(const VFS::Manager *vfs, Resource::TextureManager* textureManager)
|
SceneManager::SceneManager(const VFS::Manager *vfs, Resource::TextureManager* textureManager, Resource::NifFileManager* nifFileManager)
|
||||||
: mVFS(vfs)
|
: mVFS(vfs)
|
||||||
, mTextureManager(textureManager)
|
, mTextureManager(textureManager)
|
||||||
|
, mNifFileManager(nifFileManager)
|
||||||
, mParticleSystemMask(~0u)
|
, mParticleSystemMask(~0u)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -150,11 +152,11 @@ namespace Resource
|
||||||
return std::string();
|
return std::string();
|
||||||
}
|
}
|
||||||
|
|
||||||
osg::ref_ptr<osg::Node> load (Files::IStreamPtr file, const std::string& normalizedFilename, Resource::TextureManager* textureMgr)
|
osg::ref_ptr<osg::Node> load (Files::IStreamPtr file, const std::string& normalizedFilename, Resource::TextureManager* textureMgr, Resource::NifFileManager* nifFileManager)
|
||||||
{
|
{
|
||||||
std::string ext = getFileExtension(normalizedFilename);
|
std::string ext = getFileExtension(normalizedFilename);
|
||||||
if (ext == "nif")
|
if (ext == "nif")
|
||||||
return NifOsg::Loader::load(Nif::NIFFilePtr(new Nif::NIFFile(file, normalizedFilename)), textureMgr);
|
return NifOsg::Loader::load(nifFileManager->get(normalizedFilename), textureMgr);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
osgDB::ReaderWriter* reader = osgDB::Registry::instance()->getReaderWriterForExtension(ext);
|
osgDB::ReaderWriter* reader = osgDB::Registry::instance()->getReaderWriterForExtension(ext);
|
||||||
|
@ -195,14 +197,14 @@ namespace Resource
|
||||||
{
|
{
|
||||||
Files::IStreamPtr file = mVFS->get(normalized);
|
Files::IStreamPtr file = mVFS->get(normalized);
|
||||||
|
|
||||||
loaded = load(file, normalized, mTextureManager);
|
loaded = load(file, normalized, mTextureManager, mNifFileManager);
|
||||||
}
|
}
|
||||||
catch (std::exception& e)
|
catch (std::exception& e)
|
||||||
{
|
{
|
||||||
std::cerr << "Failed to load '" << name << "': " << e.what() << ", using marker_error.nif instead" << std::endl;
|
std::cerr << "Failed to load '" << name << "': " << e.what() << ", using marker_error.nif instead" << std::endl;
|
||||||
Files::IStreamPtr file = mVFS->get("meshes/marker_error.nif");
|
Files::IStreamPtr file = mVFS->get("meshes/marker_error.nif");
|
||||||
normalized = "meshes/marker_error.nif";
|
normalized = "meshes/marker_error.nif";
|
||||||
loaded = load(file, normalized, mTextureManager);
|
loaded = load(file, normalized, mTextureManager, mNifFileManager);
|
||||||
}
|
}
|
||||||
|
|
||||||
osgDB::Registry::instance()->getOrCreateSharedStateManager()->share(loaded.get());
|
osgDB::Registry::instance()->getOrCreateSharedStateManager()->share(loaded.get());
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
namespace Resource
|
namespace Resource
|
||||||
{
|
{
|
||||||
class TextureManager;
|
class TextureManager;
|
||||||
|
class NifFileManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace VFS
|
namespace VFS
|
||||||
|
@ -34,7 +35,7 @@ namespace Resource
|
||||||
class SceneManager
|
class SceneManager
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
SceneManager(const VFS::Manager* vfs, Resource::TextureManager* textureManager);
|
SceneManager(const VFS::Manager* vfs, Resource::TextureManager* textureManager, Resource::NifFileManager* nifFileManager);
|
||||||
~SceneManager();
|
~SceneManager();
|
||||||
|
|
||||||
/// Get a read-only copy of this scene "template"
|
/// Get a read-only copy of this scene "template"
|
||||||
|
@ -66,7 +67,7 @@ namespace Resource
|
||||||
/// Set up an IncrementalCompileOperation for background compiling of loaded scenes.
|
/// Set up an IncrementalCompileOperation for background compiling of loaded scenes.
|
||||||
void setIncrementalCompileOperation(osgUtil::IncrementalCompileOperation* ico);
|
void setIncrementalCompileOperation(osgUtil::IncrementalCompileOperation* ico);
|
||||||
|
|
||||||
/// @note If you used SceneManager::attachTo, this was called automatically.
|
/// @note SceneManager::attachTo calls this method automatically, only needs to be called by users if manually attaching
|
||||||
void notifyAttached(osg::Node* node) const;
|
void notifyAttached(osg::Node* node) const;
|
||||||
|
|
||||||
const VFS::Manager* getVFS() const;
|
const VFS::Manager* getVFS() const;
|
||||||
|
@ -79,6 +80,7 @@ namespace Resource
|
||||||
private:
|
private:
|
||||||
const VFS::Manager* mVFS;
|
const VFS::Manager* mVFS;
|
||||||
Resource::TextureManager* mTextureManager;
|
Resource::TextureManager* mTextureManager;
|
||||||
|
Resource::NifFileManager* mNifFileManager;
|
||||||
|
|
||||||
osg::ref_ptr<osgUtil::IncrementalCompileOperation> mIncrementalCompileOperation;
|
osg::ref_ptr<osgUtil::IncrementalCompileOperation> mIncrementalCompileOperation;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue