mirror of
https://github.com/OpenMW/openmw.git
synced 2025-02-06 08:45:33 +00:00
Preload items equipped by NPCs
This commit is contained in:
parent
a81b10b415
commit
c8054424c9
4 changed files with 73 additions and 7 deletions
|
@ -5,10 +5,14 @@
|
|||
#include <components/resource/scenemanager.hpp>
|
||||
#include <components/resource/resourcesystem.hpp>
|
||||
#include <components/resource/bulletshapemanager.hpp>
|
||||
#include <components/misc/resourcehelpers.hpp>
|
||||
|
||||
#include "../mwbase/environment.hpp"
|
||||
#include "../mwbase/world.hpp"
|
||||
|
||||
#include "../mwworld/inventorystore.hpp"
|
||||
#include "../mwworld/esmstore.hpp"
|
||||
|
||||
#include "cellstore.hpp"
|
||||
#include "manualref.hpp"
|
||||
#include "class.hpp"
|
||||
|
@ -23,11 +27,54 @@ namespace MWWorld
|
|||
{
|
||||
}
|
||||
|
||||
virtual bool operator()(const MWWorld::ConstPtr& ptr)
|
||||
virtual bool operator()(const MWWorld::Ptr& ptr)
|
||||
{
|
||||
std::string model = ptr.getClass().getModel(ptr);
|
||||
if (!model.empty())
|
||||
mOut.push_back(model);
|
||||
|
||||
// TODO: preload NPC body parts (mHead / mHair)
|
||||
|
||||
// FIXME: use const version of InventoryStore functions once they are available
|
||||
if (ptr.getClass().hasInventoryStore(ptr))
|
||||
{
|
||||
MWWorld::InventoryStore& invStore = ptr.getClass().getInventoryStore(ptr);
|
||||
for (int slot = 0; slot < MWWorld::InventoryStore::Slots; ++slot)
|
||||
{
|
||||
MWWorld::ContainerStoreIterator equipped = invStore.getSlot(slot);
|
||||
if (equipped != invStore.end())
|
||||
{
|
||||
std::vector<ESM::PartReference> parts;
|
||||
if(equipped->getTypeName() == typeid(ESM::Clothing).name())
|
||||
{
|
||||
const ESM::Clothing *clothes = equipped->get<ESM::Clothing>()->mBase;
|
||||
parts = clothes->mParts.mParts;
|
||||
}
|
||||
else if(equipped->getTypeName() == typeid(ESM::Armor).name())
|
||||
{
|
||||
const ESM::Armor *armor = equipped->get<ESM::Armor>()->mBase;
|
||||
parts = armor->mParts.mParts;
|
||||
}
|
||||
else
|
||||
{
|
||||
model = equipped->getClass().getModel(*equipped);
|
||||
if (!model.empty())
|
||||
mOut.push_back(model);
|
||||
}
|
||||
|
||||
for (std::vector<ESM::PartReference>::const_iterator it = parts.begin(); it != parts.end(); ++it)
|
||||
{
|
||||
const ESM::BodyPart* part = MWBase::Environment::get().getWorld()->getStore().get<ESM::BodyPart>().search(it->mMale);
|
||||
if (part && !part->mModel.empty())
|
||||
mOut.push_back("meshes/"+part->mModel);
|
||||
part = MWBase::Environment::get().getWorld()->getStore().get<ESM::BodyPart>().search(it->mFemale);
|
||||
if (part && !part->mModel.empty())
|
||||
mOut.push_back("meshes/"+part->mModel);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -39,14 +86,15 @@ namespace MWWorld
|
|||
{
|
||||
public:
|
||||
/// Constructor to be called from the main thread.
|
||||
PreloadItem(const MWWorld::CellStore* cell, Resource::SceneManager* sceneManager, Resource::BulletShapeManager* bulletShapeManager)
|
||||
PreloadItem(MWWorld::CellStore* cell, Resource::SceneManager* sceneManager, Resource::BulletShapeManager* bulletShapeManager)
|
||||
: mSceneManager(sceneManager)
|
||||
, mBulletShapeManager(bulletShapeManager)
|
||||
{
|
||||
osg::Timer timer;
|
||||
ListModelsVisitor visitor (mMeshes);
|
||||
if (cell->getState() == MWWorld::CellStore::State_Loaded)
|
||||
{
|
||||
ListModelsVisitor visitor (mMeshes);
|
||||
cell->forEachConst(visitor);
|
||||
cell->forEach(visitor);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -61,6 +109,7 @@ namespace MWWorld
|
|||
mMeshes.push_back(model);
|
||||
}
|
||||
}
|
||||
std::cout << "listed models in " << timer.time_m() << std::endl;
|
||||
}
|
||||
|
||||
/// Preload work to be called from the worker thread.
|
||||
|
@ -73,9 +122,16 @@ namespace MWWorld
|
|||
{
|
||||
try
|
||||
{
|
||||
std::string mesh = *it;
|
||||
Misc::ResourceHelpers::correctActorModelPath(mesh, mSceneManager->getVFS());
|
||||
|
||||
//std::cout << "preloading " << mesh << std::endl;
|
||||
|
||||
mPreloadedNodes.push_back(mSceneManager->getTemplate(*it));
|
||||
mPreloadedShapes.push_back(mBulletShapeManager->getShape(*it));
|
||||
|
||||
// TODO: load .kf
|
||||
|
||||
// TODO: do a createInstance() and hold on to it since we can make use of it when the cell goes active
|
||||
}
|
||||
catch (std::exception& e)
|
||||
|
@ -84,7 +140,7 @@ namespace MWWorld
|
|||
// error will be shown when visiting the cell
|
||||
}
|
||||
}
|
||||
std::cout << "preloaded " << mPreloadedNodes.size() << " nodes in " << preloadTimer.time_m() << std::endl;
|
||||
//std::cout << "preloaded " << mPreloadedNodes.size() << " nodes in " << preloadTimer.time_m() << std::endl;
|
||||
}
|
||||
|
||||
private:
|
||||
|
@ -128,7 +184,7 @@ namespace MWWorld
|
|||
mWorkQueue = new SceneUtil::WorkQueue;
|
||||
}
|
||||
|
||||
void CellPreloader::preload(const CellStore *cell, double timestamp)
|
||||
void CellPreloader::preload(CellStore *cell, double timestamp)
|
||||
{
|
||||
if (!mWorkQueue)
|
||||
{
|
||||
|
|
|
@ -22,7 +22,7 @@ namespace MWWorld
|
|||
|
||||
/// Ask a background thread to preload rendering meshes and collision shapes for objects in this cell.
|
||||
/// @note The cell itself must be in State_Loaded or State_Preloaded.
|
||||
void preload(const MWWorld::CellStore* cell, double timestamp);
|
||||
void preload(MWWorld::CellStore* cell, double timestamp);
|
||||
|
||||
/// Removes preloaded cells that have not had a preload request for a while.
|
||||
void updateCache(double timestamp);
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
#include <limits>
|
||||
#include <iostream>
|
||||
#include <osg/Timer>
|
||||
|
||||
#include <components/loadinglistener/loadinglistener.hpp>
|
||||
#include <components/misc/resourcehelpers.hpp>
|
||||
|
@ -329,6 +330,7 @@ namespace MWWorld
|
|||
|
||||
void Scene::changeCellGrid (int X, int Y)
|
||||
{
|
||||
osg::Timer timer;
|
||||
Loading::Listener* loadingListener = MWBase::Environment::get().getWindowManager()->getLoadingScreen();
|
||||
Loading::ScopedLoad load(loadingListener);
|
||||
|
||||
|
@ -413,6 +415,8 @@ namespace MWWorld
|
|||
|
||||
mPreloader->updateCache(mRendering.getReferenceTime());
|
||||
mRendering.clearCache();
|
||||
|
||||
std::cout << "changeCellGrid took " << timer.time_m() << std::endl;
|
||||
}
|
||||
|
||||
void Scene::changePlayerCell(CellStore *cell, const ESM::Position &pos, bool adjustPlayerPos)
|
||||
|
@ -477,6 +481,7 @@ namespace MWWorld
|
|||
|
||||
void Scene::changeToInteriorCell (const std::string& cellName, const ESM::Position& position)
|
||||
{
|
||||
osg::Timer timer;
|
||||
CellStore *cell = MWBase::Environment::get().getWorld()->getInterior(cellName);
|
||||
bool loadcell = (mCurrentCell == NULL);
|
||||
if(!loadcell)
|
||||
|
@ -537,6 +542,8 @@ namespace MWWorld
|
|||
|
||||
mPreloader->updateCache(mRendering.getReferenceTime());
|
||||
mRendering.clearCache();
|
||||
|
||||
std::cout << "change to interior took " << timer.time_m() << std::endl;
|
||||
}
|
||||
|
||||
void Scene::changeToExteriorCell (const ESM::Position& position, bool adjustPlayerPos)
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#include "scenemanager.hpp"
|
||||
|
||||
#include <iostream>
|
||||
#include <osg/Node>
|
||||
#include <osg/Geode>
|
||||
#include <osg/UserDataContainer>
|
||||
|
@ -364,6 +365,8 @@ namespace Resource
|
|||
if (mIncrementalCompileOperation)
|
||||
mIncrementalCompileOperation->add(loaded);
|
||||
|
||||
//std::cout << "loading " << normalized << std::endl;
|
||||
|
||||
mCache->addEntryToObjectCache(normalized, loaded);
|
||||
return loaded;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue