1
0
mirror of https://gitlab.com/OpenMW/openmw.git synced 2025-02-06 00:40:04 +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);
}
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);
if (!model.empty())
models.push_back(model);
// FIXME: use const version of InventoryStore functions once they are available
if (hasInventoryStore(ptr))
const MWWorld::CustomData* customData = ptr.getRefData().getCustomData();
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)
{
MWWorld::ConstContainerStoreIterator equipped = invStore.getSlot(slot);
@ -513,7 +514,7 @@ namespace MWClass
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);
}

View File

@ -79,7 +79,7 @@ namespace MWClass
MWWorld::InventoryStore& getInventoryStore(const MWWorld::Ptr& ptr) const override;
///< 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;
///< Return name of the script attached to ptr
@ -107,7 +107,7 @@ namespace MWClass
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:
///< list getModel().

View File

@ -99,25 +99,6 @@ namespace MWClass
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(
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;
///< @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,
MWRender::RenderingInterface& renderingInterface) const override;
///< Add reference into a cell for rendering

View File

@ -436,10 +436,11 @@ namespace MWClass
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 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)
models.push_back(Settings::models().mBaseanimkna);
@ -453,56 +454,57 @@ namespace MWClass
if (!npc->mBase->mHead.empty())
{
const ESM::BodyPart* head
= MWBase::Environment::get().getESMStore()->get<ESM::BodyPart>().search(npc->mBase->mHead);
const ESM::BodyPart* head = esmStore->get<ESM::BodyPart>().search(npc->mBase->mHead);
if (head)
models.push_back(Misc::ResourceHelpers::correctMeshPath(head->mModel));
}
if (!npc->mBase->mHair.empty())
{
const ESM::BodyPart* hair
= MWBase::Environment::get().getESMStore()->get<ESM::BodyPart>().search(npc->mBase->mHair);
const ESM::BodyPart* hair = esmStore->get<ESM::BodyPart>().search(npc->mBase->mHair);
if (hair)
models.push_back(Misc::ResourceHelpers::correctMeshPath(hair->mModel));
}
bool female = (npc->mBase->mFlags & ESM::NPC::Female);
// FIXME: use const version of InventoryStore functions once they are available
// preload equipped items
const MWWorld::InventoryStore& invStore = getInventoryStore(ptr);
for (int slot = 0; slot < MWWorld::InventoryStore::Slots; ++slot)
const MWWorld::CustomData* customData = ptr.getRefData().getCustomData();
if (customData)
{
MWWorld::ConstContainerStoreIterator equipped = invStore.getSlot(slot);
if (equipped != invStore.end())
const MWWorld::InventoryStore& invStore = customData->asNpcCustomData().mInventoryStore;
for (int slot = 0; slot < MWWorld::InventoryStore::Slots; ++slot)
{
std::vector<ESM::PartReference> parts;
if (equipped->getType() == ESM::Clothing::sRecordId)
MWWorld::ConstContainerStoreIterator equipped = invStore.getSlot(slot);
if (equipped != invStore.end())
{
const ESM::Clothing* clothes = equipped->get<ESM::Clothing>()->mBase;
parts = clothes->mParts.mParts;
}
else if (equipped->getType() == ESM::Armor::sRecordId)
{
const ESM::Armor* armor = equipped->get<ESM::Armor>()->mBase;
parts = armor->mParts.mParts;
}
else
{
std::string model = equipped->getClass().getModel(*equipped);
if (!model.empty())
models.push_back(model);
}
const auto addParts = [&](const std::vector<ESM::PartReference>& parts) {
for (const ESM::PartReference& partRef : parts)
{
const ESM::RefId& partname
= (female && !partRef.mFemale.empty()) || (!female && partRef.mMale.empty())
? partRef.mFemale
: partRef.mMale;
for (std::vector<ESM::PartReference>::const_iterator it = parts.begin(); it != parts.end(); ++it)
{
const ESM::RefId& partname
= (female && !it->mFemale.empty()) || (!female && it->mMale.empty()) ? it->mFemale : it->mMale;
const ESM::BodyPart* part
= MWBase::Environment::get().getESMStore()->get<ESM::BodyPart>().search(partname);
if (part && !part->mModel.empty())
models.push_back(Misc::ResourceHelpers::correctMeshPath(part->mModel));
const ESM::BodyPart* part = esmStore->get<ESM::BodyPart>().search(partname);
if (part && !part->mModel.empty())
models.push_back(Misc::ResourceHelpers::correctMeshPath(part->mModel));
}
};
if (equipped->getType() == ESM::Clothing::sRecordId)
{
const ESM::Clothing* clothes = equipped->get<ESM::Clothing>()->mBase;
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
= 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())
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;
///< 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;
@ -85,7 +85,7 @@ namespace MWClass
const MWWorld::Ptr& attacker, const osg::Vec3f& hitPosition, bool successful,
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:
///< list getModel().

View File

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

View File

@ -224,12 +224,12 @@ namespace MWWorld
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;
if (!visitor(MWWorld::Ptr(mMergedRefs[i], this)))
if (!visitor(MWWorld::Ptr(mergedRef, this)))
return false;
}
return true;
@ -249,12 +249,12 @@ namespace MWWorld
if (mMergedRefsNeedsUpdate)
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;
if (!visitor(MWWorld::ConstPtr(mMergedRefs[i], this)))
if (!visitor(MWWorld::ConstPtr(mergedRef, this)))
return false;
}
return true;

View File

@ -149,7 +149,7 @@ namespace MWWorld
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;
}
@ -320,7 +320,7 @@ namespace MWWorld
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);
if (!model.empty())

View File

@ -170,7 +170,7 @@ namespace MWWorld
///< Return inventory store or throw an exception, if class does not have a
/// 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)
virtual bool canLock(const ConstPtr& ptr) const;
@ -284,7 +284,7 @@ namespace MWWorld
virtual bool useAnim() const;
///< 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:
///< list getModel().