diff --git a/apps/openmw/mwworld/cellpreloader.cpp b/apps/openmw/mwworld/cellpreloader.cpp index 48b058d9e..9f613ac80 100644 --- a/apps/openmw/mwworld/cellpreloader.cpp +++ b/apps/openmw/mwworld/cellpreloader.cpp @@ -45,7 +45,7 @@ namespace MWWorld { public: /// Constructor to be called from the main thread. - PreloadItem(MWWorld::CellStore* cell, Resource::SceneManager* sceneManager, Resource::BulletShapeManager* bulletShapeManager, Resource::KeyframeManager* keyframeManager, Terrain::World* terrain) + PreloadItem(MWWorld::CellStore* cell, Resource::SceneManager* sceneManager, Resource::BulletShapeManager* bulletShapeManager, Resource::KeyframeManager* keyframeManager, Terrain::World* terrain, bool preloadInstances) : mIsExterior(cell->getCell()->isExterior()) , mX(cell->getCell()->getGridX()) , mY(cell->getCell()->getGridY()) @@ -53,6 +53,7 @@ namespace MWWorld , mBulletShapeManager(bulletShapeManager) , mKeyframeManager(keyframeManager) , mTerrain(terrain) + , mPreloadInstances(preloadInstances) { ListModelsVisitor visitor (mMeshes); if (cell->getState() == MWWorld::CellStore::State_Loaded) @@ -84,8 +85,16 @@ namespace MWWorld std::string mesh = *it; mesh = Misc::ResourceHelpers::correctActorModelPath(mesh, mSceneManager->getVFS()); - mPreloadedObjects.push_back(mSceneManager->cacheInstance(mesh)); - mPreloadedObjects.push_back(mBulletShapeManager->cacheInstance(mesh)); + if (mPreloadInstances) + { + mPreloadedObjects.push_back(mSceneManager->cacheInstance(mesh)); + mPreloadedObjects.push_back(mBulletShapeManager->cacheInstance(mesh)); + } + else + { + mPreloadedObjects.push_back(mSceneManager->getTemplate(mesh)); + mPreloadedObjects.push_back(mBulletShapeManager->getShape(mesh)); + } size_t slashpos = mesh.find_last_of("/\\"); if (slashpos != std::string::npos && slashpos != mesh.size()-1) @@ -132,6 +141,7 @@ namespace MWWorld Resource::BulletShapeManager* mBulletShapeManager; Resource::KeyframeManager* mKeyframeManager; Terrain::World* mTerrain; + bool mPreloadInstances; // keep a ref to the loaded objects to make sure it stays loaded as long as this cell is in the preloaded state std::vector > mPreloadedObjects; @@ -168,6 +178,7 @@ namespace MWWorld , mExpiryDelay(0.0) , mMinCacheSize(0) , mMaxCacheSize(0) + , mPreloadInstances(true) { } @@ -220,7 +231,7 @@ namespace MWWorld return; } - osg::ref_ptr item (new PreloadItem(cell, mResourceSystem->getSceneManager(), mBulletShapeManager, mResourceSystem->getKeyframeManager(), mTerrain)); + osg::ref_ptr item (new PreloadItem(cell, mResourceSystem->getSceneManager(), mBulletShapeManager, mResourceSystem->getKeyframeManager(), mTerrain, mPreloadInstances)); mWorkQueue->addWorkItem(item); mPreloadCells[cell] = PreloadEntry(timestamp, item); @@ -260,6 +271,11 @@ namespace MWWorld mMaxCacheSize = num; } + void CellPreloader::setPreloadInstances(bool preload) + { + mPreloadInstances = preload; + } + unsigned int CellPreloader::getMaxCacheSize() const { return mMaxCacheSize; diff --git a/apps/openmw/mwworld/cellpreloader.hpp b/apps/openmw/mwworld/cellpreloader.hpp index e236a3783..35c52baf6 100644 --- a/apps/openmw/mwworld/cellpreloader.hpp +++ b/apps/openmw/mwworld/cellpreloader.hpp @@ -44,6 +44,9 @@ namespace MWWorld /// The maximum number of preloaded cells. void setMaxCacheSize(unsigned int num); + /// Enables the creation of instances in the preloading thread. + void setPreloadInstances(bool preload); + unsigned int getMaxCacheSize() const; void setWorkQueue(osg::ref_ptr workQueue); @@ -56,6 +59,7 @@ namespace MWWorld double mExpiryDelay; unsigned int mMinCacheSize; unsigned int mMaxCacheSize; + bool mPreloadInstances; struct PreloadEntry { diff --git a/apps/openmw/mwworld/scene.cpp b/apps/openmw/mwworld/scene.cpp index 33ea9b6a8..ba9fb95d0 100644 --- a/apps/openmw/mwworld/scene.cpp +++ b/apps/openmw/mwworld/scene.cpp @@ -478,6 +478,7 @@ namespace MWWorld mPreloader->setExpiryDelay(Settings::Manager::getFloat("preload cell expiry delay", "Cells")); mPreloader->setMinCacheSize(Settings::Manager::getInt("preload cell cache min", "Cells")); mPreloader->setMaxCacheSize(Settings::Manager::getInt("preload cell cache max", "Cells")); + mPreloader->setPreloadInstances(Settings::Manager::getBool("preload instances", "Cells")); } Scene::~Scene() diff --git a/files/settings-default.cfg b/files/settings-default.cfg index ef3d95b3d..3d2cd49bf 100644 --- a/files/settings-default.cfg +++ b/files/settings-default.cfg @@ -52,6 +52,11 @@ preload doors = true # Preloading distance threshold preload distance = 1000 +# Controls whether or not the nodes/collision shapes are pre-"instanced" (i.e. cloned) when a cell is preloaded. +# Enabling this option slightly reduces the time it takes to transition into a preloaded cell, but also results in higher memory usage +# proportional to the number of cells that are preloaded. +preload instances = true + # The minimum amount of cells in the preload cache before unused cells start to get thrown out (see "preload cell expiry delay"). # This value should be lower or equal to 'preload cell cache max'. preload cell cache min = 12