mirror of
				https://github.com/OpenMW/openmw.git
				synced 2025-10-31 20:56:39 +00:00 
			
		
		
		
	Make cell models preloading a const operation
This commit is contained in:
		
							parent
							
								
									51426eb754
								
							
						
					
					
						commit
						6ff14e19d1
					
				
					 10 changed files with 63 additions and 91 deletions
				
			
		|  | @ -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); | ||||
|     } | ||||
|  |  | |||
|  | @ -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().
 | ||||
| 
 | ||||
|  |  | |||
|  | @ -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 | ||||
|     { | ||||
|  |  | |||
|  | @ -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
 | ||||
|  |  | |||
|  | @ -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)); | ||||
|             } | ||||
|  |  | |||
|  | @ -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().
 | ||||
| 
 | ||||
|  |  | |||
|  | @ -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; } | ||||
|  |  | |||
|  | @ -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; | ||||
|  |  | |||
|  | @ -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()) | ||||
|  |  | |||
|  | @ -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().
 | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue