1
0
mirror of https://gitlab.com/OpenMW/openmw.git synced 2025-02-11 06:40:34 +00:00

Make cell models preloading a const operation

This commit is contained in:
Evil Eye 2024-01-14 16:41:55 +01:00
parent 51426eb754
commit 6ff14e19d1
10 changed files with 63 additions and 91 deletions

View File

@ -183,16 +183,17 @@ namespace MWClass
return getClassModel<ESM::Creature>(ptr); return getClassModel<ESM::Creature>(ptr);
} }
void Creature::getModelsToPreload(const MWWorld::Ptr& ptr, std::vector<std::string>& models) const void Creature::getModelsToPreload(const MWWorld::ConstPtr& ptr, std::vector<std::string>& models) const
{ {
std::string model = getModel(ptr); std::string model = getModel(ptr);
if (!model.empty()) if (!model.empty())
models.push_back(model); models.push_back(model);
// FIXME: use const version of InventoryStore functions once they are available const MWWorld::CustomData* customData = ptr.getRefData().getCustomData();
if (hasInventoryStore(ptr)) if (customData && hasInventoryStore(ptr))
{ {
const MWWorld::InventoryStore& invStore = getInventoryStore(ptr); const auto& invStore
= static_cast<const MWWorld::InventoryStore&>(*customData->asCreatureCustomData().mContainerStore);
for (int slot = 0; slot < MWWorld::InventoryStore::Slots; ++slot) for (int slot = 0; slot < MWWorld::InventoryStore::Slots; ++slot)
{ {
MWWorld::ConstContainerStoreIterator equipped = invStore.getSlot(slot); MWWorld::ConstContainerStoreIterator equipped = invStore.getSlot(slot);
@ -513,7 +514,7 @@ namespace MWClass
throw std::runtime_error("this creature has no inventory store"); throw std::runtime_error("this creature has no inventory store");
} }
bool Creature::hasInventoryStore(const MWWorld::Ptr& ptr) const bool Creature::hasInventoryStore(const MWWorld::ConstPtr& ptr) const
{ {
return isFlagBitSet(ptr, ESM::Creature::Weapon); return isFlagBitSet(ptr, ESM::Creature::Weapon);
} }

View File

@ -79,7 +79,7 @@ namespace MWClass
MWWorld::InventoryStore& getInventoryStore(const MWWorld::Ptr& ptr) const override; MWWorld::InventoryStore& getInventoryStore(const MWWorld::Ptr& ptr) const override;
///< Return inventory store ///< Return inventory store
bool hasInventoryStore(const MWWorld::Ptr& ptr) const override; bool hasInventoryStore(const MWWorld::ConstPtr& ptr) const override;
ESM::RefId getScript(const MWWorld::ConstPtr& ptr) const override; ESM::RefId getScript(const MWWorld::ConstPtr& ptr) const override;
///< Return name of the script attached to ptr ///< Return name of the script attached to ptr
@ -107,7 +107,7 @@ namespace MWClass
std::string getModel(const MWWorld::ConstPtr& ptr) const override; std::string getModel(const MWWorld::ConstPtr& ptr) const override;
void getModelsToPreload(const MWWorld::Ptr& ptr, std::vector<std::string>& models) const override; void getModelsToPreload(const MWWorld::ConstPtr& ptr, std::vector<std::string>& models) const override;
///< Get a list of models to preload that this object may use (directly or indirectly). default implementation: ///< Get a list of models to preload that this object may use (directly or indirectly). default implementation:
///< list getModel(). ///< list getModel().

View File

@ -99,25 +99,6 @@ namespace MWClass
customData.mSpawn = true; customData.mSpawn = true;
} }
void CreatureLevList::getModelsToPreload(const MWWorld::Ptr& ptr, std::vector<std::string>& models) const
{
// disable for now, too many false positives
/*
const MWWorld::LiveCellRef<ESM::CreatureLevList> *ref = ptr.get<ESM::CreatureLevList>();
for (std::vector<ESM::LevelledListBase::LevelItem>::const_iterator it = ref->mBase->mList.begin(); it !=
ref->mBase->mList.end(); ++it)
{
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr();
if (it->mLevel > player.getClass().getCreatureStats(player).getLevel())
continue;
const MWWorld::ESMStore& store = *MWBase::Environment::get().getESMStore();
MWWorld::ManualRef ref(store, it->mId);
ref.getPtr().getClass().getModelsToPreload(ref.getPtr(), models);
}
*/
}
void CreatureLevList::insertObjectRendering( void CreatureLevList::insertObjectRendering(
const MWWorld::Ptr& ptr, const std::string& model, MWRender::RenderingInterface& renderingInterface) const const MWWorld::Ptr& ptr, const std::string& model, MWRender::RenderingInterface& renderingInterface) const
{ {

View File

@ -20,10 +20,6 @@ namespace MWClass
bool hasToolTip(const MWWorld::ConstPtr& ptr) const override; bool hasToolTip(const MWWorld::ConstPtr& ptr) const override;
///< @return true if this object has a tooltip when focused (default implementation: true) ///< @return true if this object has a tooltip when focused (default implementation: true)
void getModelsToPreload(const MWWorld::Ptr& ptr, std::vector<std::string>& models) const override;
///< Get a list of models to preload that this object may use (directly or indirectly). default implementation:
///< list getModel().
void insertObjectRendering(const MWWorld::Ptr& ptr, const std::string& model, void insertObjectRendering(const MWWorld::Ptr& ptr, const std::string& model,
MWRender::RenderingInterface& renderingInterface) const override; MWRender::RenderingInterface& renderingInterface) const override;
///< Add reference into a cell for rendering ///< Add reference into a cell for rendering

View File

@ -436,10 +436,11 @@ namespace MWClass
return model; return model;
} }
void Npc::getModelsToPreload(const MWWorld::Ptr& ptr, std::vector<std::string>& models) const void Npc::getModelsToPreload(const MWWorld::ConstPtr& ptr, std::vector<std::string>& models) const
{ {
const MWWorld::LiveCellRef<ESM::NPC>* npc = ptr.get<ESM::NPC>(); const MWWorld::LiveCellRef<ESM::NPC>* npc = ptr.get<ESM::NPC>();
const ESM::Race* race = MWBase::Environment::get().getESMStore()->get<ESM::Race>().search(npc->mBase->mRace); const auto& esmStore = MWBase::Environment::get().getESMStore();
const ESM::Race* race = esmStore->get<ESM::Race>().search(npc->mBase->mRace);
if (race && race->mData.mFlags & ESM::Race::Beast) if (race && race->mData.mFlags & ESM::Race::Beast)
models.push_back(Settings::models().mBaseanimkna); models.push_back(Settings::models().mBaseanimkna);
@ -453,56 +454,57 @@ namespace MWClass
if (!npc->mBase->mHead.empty()) if (!npc->mBase->mHead.empty())
{ {
const ESM::BodyPart* head const ESM::BodyPart* head = esmStore->get<ESM::BodyPart>().search(npc->mBase->mHead);
= MWBase::Environment::get().getESMStore()->get<ESM::BodyPart>().search(npc->mBase->mHead);
if (head) if (head)
models.push_back(Misc::ResourceHelpers::correctMeshPath(head->mModel)); models.push_back(Misc::ResourceHelpers::correctMeshPath(head->mModel));
} }
if (!npc->mBase->mHair.empty()) if (!npc->mBase->mHair.empty())
{ {
const ESM::BodyPart* hair const ESM::BodyPart* hair = esmStore->get<ESM::BodyPart>().search(npc->mBase->mHair);
= MWBase::Environment::get().getESMStore()->get<ESM::BodyPart>().search(npc->mBase->mHair);
if (hair) if (hair)
models.push_back(Misc::ResourceHelpers::correctMeshPath(hair->mModel)); models.push_back(Misc::ResourceHelpers::correctMeshPath(hair->mModel));
} }
bool female = (npc->mBase->mFlags & ESM::NPC::Female); bool female = (npc->mBase->mFlags & ESM::NPC::Female);
// FIXME: use const version of InventoryStore functions once they are available const MWWorld::CustomData* customData = ptr.getRefData().getCustomData();
// preload equipped items if (customData)
const MWWorld::InventoryStore& invStore = getInventoryStore(ptr);
for (int slot = 0; slot < MWWorld::InventoryStore::Slots; ++slot)
{ {
MWWorld::ConstContainerStoreIterator equipped = invStore.getSlot(slot); const MWWorld::InventoryStore& invStore = customData->asNpcCustomData().mInventoryStore;
if (equipped != invStore.end()) for (int slot = 0; slot < MWWorld::InventoryStore::Slots; ++slot)
{ {
std::vector<ESM::PartReference> parts; MWWorld::ConstContainerStoreIterator equipped = invStore.getSlot(slot);
if (equipped->getType() == ESM::Clothing::sRecordId) if (equipped != invStore.end())
{ {
const ESM::Clothing* clothes = equipped->get<ESM::Clothing>()->mBase; const auto addParts = [&](const std::vector<ESM::PartReference>& parts) {
parts = clothes->mParts.mParts; for (const ESM::PartReference& partRef : parts)
} {
else if (equipped->getType() == ESM::Armor::sRecordId) const ESM::RefId& partname
{ = (female && !partRef.mFemale.empty()) || (!female && partRef.mMale.empty())
const ESM::Armor* armor = equipped->get<ESM::Armor>()->mBase; ? partRef.mFemale
parts = armor->mParts.mParts; : partRef.mMale;
}
else
{
std::string model = equipped->getClass().getModel(*equipped);
if (!model.empty())
models.push_back(model);
}
for (std::vector<ESM::PartReference>::const_iterator it = parts.begin(); it != parts.end(); ++it) const ESM::BodyPart* part = esmStore->get<ESM::BodyPart>().search(partname);
{ if (part && !part->mModel.empty())
const ESM::RefId& partname models.push_back(Misc::ResourceHelpers::correctMeshPath(part->mModel));
= (female && !it->mFemale.empty()) || (!female && it->mMale.empty()) ? it->mFemale : it->mMale; }
};
const ESM::BodyPart* part if (equipped->getType() == ESM::Clothing::sRecordId)
= MWBase::Environment::get().getESMStore()->get<ESM::BodyPart>().search(partname); {
if (part && !part->mModel.empty()) const ESM::Clothing* clothes = equipped->get<ESM::Clothing>()->mBase;
models.push_back(Misc::ResourceHelpers::correctMeshPath(part->mModel)); addParts(clothes->mParts.mParts);
}
else if (equipped->getType() == ESM::Armor::sRecordId)
{
const ESM::Armor* armor = equipped->get<ESM::Armor>()->mBase;
addParts(armor->mParts.mParts);
}
else
{
std::string model = equipped->getClass().getModel(*equipped);
if (!model.empty())
models.push_back(model);
}
} }
} }
} }
@ -512,9 +514,8 @@ namespace MWClass
{ {
const std::vector<const ESM::BodyPart*>& parts const std::vector<const ESM::BodyPart*>& parts
= MWRender::NpcAnimation::getBodyParts(race->mId, female, false, false); = MWRender::NpcAnimation::getBodyParts(race->mId, female, false, false);
for (std::vector<const ESM::BodyPart*>::const_iterator it = parts.begin(); it != parts.end(); ++it) for (const ESM::BodyPart* part : parts)
{ {
const ESM::BodyPart* part = *it;
if (part && !part->mModel.empty()) if (part && !part->mModel.empty())
models.push_back(Misc::ResourceHelpers::correctMeshPath(part->mModel)); models.push_back(Misc::ResourceHelpers::correctMeshPath(part->mModel));
} }

View File

@ -74,7 +74,7 @@ namespace MWClass
MWWorld::InventoryStore& getInventoryStore(const MWWorld::Ptr& ptr) const override; MWWorld::InventoryStore& getInventoryStore(const MWWorld::Ptr& ptr) const override;
///< Return inventory store ///< Return inventory store
bool hasInventoryStore(const MWWorld::Ptr& ptr) const override { return true; } bool hasInventoryStore(const MWWorld::ConstPtr& ptr) const override { return true; }
bool evaluateHit(const MWWorld::Ptr& ptr, MWWorld::Ptr& victim, osg::Vec3f& hitPosition) const override; bool evaluateHit(const MWWorld::Ptr& ptr, MWWorld::Ptr& victim, osg::Vec3f& hitPosition) const override;
@ -85,7 +85,7 @@ namespace MWClass
const MWWorld::Ptr& attacker, const osg::Vec3f& hitPosition, bool successful, const MWWorld::Ptr& attacker, const osg::Vec3f& hitPosition, bool successful,
const MWMechanics::DamageSourceType sourceType) const override; const MWMechanics::DamageSourceType sourceType) const override;
void getModelsToPreload(const MWWorld::Ptr& ptr, std::vector<std::string>& models) const override; void getModelsToPreload(const MWWorld::ConstPtr& ptr, std::vector<std::string>& models) const override;
///< Get a list of models to preload that this object may use (directly or indirectly). default implementation: ///< Get a list of models to preload that this object may use (directly or indirectly). default implementation:
///< list getModel(). ///< list getModel().

View File

@ -52,20 +52,13 @@ namespace MWWorld
struct ListModelsVisitor struct ListModelsVisitor
{ {
ListModelsVisitor(std::vector<std::string>& out) bool operator()(const MWWorld::ConstPtr& ptr)
: mOut(out)
{
}
virtual bool operator()(const MWWorld::Ptr& ptr)
{ {
ptr.getClass().getModelsToPreload(ptr, mOut); ptr.getClass().getModelsToPreload(ptr, mOut);
return true; return true;
} }
virtual ~ListModelsVisitor() = default;
std::vector<std::string>& mOut; std::vector<std::string>& mOut;
}; };
@ -90,8 +83,8 @@ namespace MWWorld
{ {
mTerrainView = mTerrain->createView(); mTerrainView = mTerrain->createView();
ListModelsVisitor visitor(mMeshes); ListModelsVisitor visitor{ mMeshes };
cell->forEach(visitor); cell->forEachConst(visitor);
} }
void abort() override { mAbort = true; } void abort() override { mAbort = true; }

View File

@ -224,12 +224,12 @@ namespace MWWorld
mHasState = true; mHasState = true;
for (unsigned int i = 0; i < mMergedRefs.size(); ++i) for (LiveCellRefBase* mergedRef : mMergedRefs)
{ {
if (!isAccessible(mMergedRefs[i]->mData, mMergedRefs[i]->mRef)) if (!isAccessible(mergedRef->mData, mergedRef->mRef))
continue; continue;
if (!visitor(MWWorld::Ptr(mMergedRefs[i], this))) if (!visitor(MWWorld::Ptr(mergedRef, this)))
return false; return false;
} }
return true; return true;
@ -249,12 +249,12 @@ namespace MWWorld
if (mMergedRefsNeedsUpdate) if (mMergedRefsNeedsUpdate)
updateMergedRefs(); updateMergedRefs();
for (unsigned int i = 0; i < mMergedRefs.size(); ++i) for (const LiveCellRefBase* mergedRef : mMergedRefs)
{ {
if (!isAccessible(mMergedRefs[i]->mData, mMergedRefs[i]->mRef)) if (!isAccessible(mergedRef->mData, mergedRef->mRef))
continue; continue;
if (!visitor(MWWorld::ConstPtr(mMergedRefs[i], this))) if (!visitor(MWWorld::ConstPtr(mergedRef, this)))
return false; return false;
} }
return true; return true;

View File

@ -149,7 +149,7 @@ namespace MWWorld
throw std::runtime_error("class does not have an inventory store"); throw std::runtime_error("class does not have an inventory store");
} }
bool Class::hasInventoryStore(const Ptr& ptr) const bool Class::hasInventoryStore(const ConstPtr& ptr) const
{ {
return false; return false;
} }
@ -320,7 +320,7 @@ namespace MWWorld
return false; return false;
} }
void Class::getModelsToPreload(const Ptr& ptr, std::vector<std::string>& models) const void Class::getModelsToPreload(const ConstPtr& ptr, std::vector<std::string>& models) const
{ {
std::string model = getModel(ptr); std::string model = getModel(ptr);
if (!model.empty()) if (!model.empty())

View File

@ -170,7 +170,7 @@ namespace MWWorld
///< Return inventory store or throw an exception, if class does not have a ///< Return inventory store or throw an exception, if class does not have a
/// inventory store (default implementation: throw an exception) /// inventory store (default implementation: throw an exception)
virtual bool hasInventoryStore(const Ptr& ptr) const; virtual bool hasInventoryStore(const ConstPtr& ptr) const;
///< Does this object have an inventory store, i.e. equipment slots? (default implementation: false) ///< Does this object have an inventory store, i.e. equipment slots? (default implementation: false)
virtual bool canLock(const ConstPtr& ptr) const; virtual bool canLock(const ConstPtr& ptr) const;
@ -284,7 +284,7 @@ namespace MWWorld
virtual bool useAnim() const; virtual bool useAnim() const;
///< Whether or not to use animated variant of model (default false) ///< Whether or not to use animated variant of model (default false)
virtual void getModelsToPreload(const MWWorld::Ptr& ptr, std::vector<std::string>& models) const; virtual void getModelsToPreload(const MWWorld::ConstPtr& ptr, std::vector<std::string>& models) const;
///< Get a list of models to preload that this object may use (directly or indirectly). default implementation: ///< Get a list of models to preload that this object may use (directly or indirectly). default implementation:
///< list getModel(). ///< list getModel().