Use string_view in more animation code

crashfix_debugdraw
Evil Eye 2 years ago
parent 262b29ed40
commit 42e59878c5

@ -2,6 +2,7 @@
#define GAME_MWBASE_MECHANICSMANAGER_H
#include <string>
#include <string_view>
#include <vector>
#include <set>
#include <cstdint>
@ -158,7 +159,7 @@ namespace MWBase
virtual void forceStateUpdate(const MWWorld::Ptr &ptr) = 0;
///< Forces an object to refresh its animation state.
virtual bool playAnimationGroup(const MWWorld::Ptr& ptr, const std::string& groupName, int mode, int number=1, bool persist=false) = 0;
virtual bool playAnimationGroup(const MWWorld::Ptr& ptr, std::string_view groupName, int mode, int number=1, bool persist=false) = 0;
///< Run animation for a MW-reference. Calls to this function for references that are currently not
/// in the scene should be ignored.
///

@ -270,7 +270,7 @@ namespace MWMechanics
const VFS::Manager* const vfs = MWBase::Environment::get().getResourceSystem()->getVFS();
animation->addEffect(
Misc::ResourceHelpers::correctMeshPath(reflectStatic->mModel, vfs),
ESM::MagicEffect::Reflect, false, std::string());
ESM::MagicEffect::Reflect, false);
}
caster.getClass().getCreatureStats(caster).getActiveSpells().addSpell(*reflected);
}

@ -1935,7 +1935,7 @@ namespace MWMechanics
iter->second->getCharacterController().forceStateUpdate();
}
bool Actors::playAnimationGroup(const MWWorld::Ptr& ptr, const std::string& groupName, int mode, int number, bool persist) const
bool Actors::playAnimationGroup(const MWWorld::Ptr& ptr, std::string_view groupName, int mode, int number, bool persist) const
{
const auto iter = mIndex.find(ptr.mRef);
if(iter != mIndex.end())

@ -121,7 +121,7 @@ namespace MWMechanics
void forceStateUpdate(const MWWorld::Ptr &ptr) const;
bool playAnimationGroup(const MWWorld::Ptr& ptr, const std::string& groupName, int mode,
bool playAnimationGroup(const MWWorld::Ptr& ptr, std::string_view groupName, int mode,
int number, bool persist = false) const;
void skipAnimation(const MWWorld::Ptr& ptr) const;
bool checkAnimationPlaying(const MWWorld::Ptr& ptr, const std::string& groupName) const;

@ -2347,7 +2347,7 @@ void CharacterController::unpersistAnimationState()
}
}
bool CharacterController::playGroup(const std::string &groupname, int mode, int count, bool persist)
bool CharacterController::playGroup(std::string_view groupname, int mode, int count, bool persist)
{
if(!mAnimation || !mAnimation->hasAnimation(groupname))
return false;

@ -260,7 +260,7 @@ public:
void persistAnimationState() const;
void unpersistAnimationState();
bool playGroup(const std::string &groupname, int mode, int count, bool persist=false);
bool playGroup(std::string_view groupname, int mode, int count, bool persist=false);
void skipAnim();
bool isAnimPlaying(const std::string &groupName) const;

@ -761,7 +761,7 @@ namespace MWMechanics
mActors.forceStateUpdate(ptr);
}
bool MechanicsManager::playAnimationGroup(const MWWorld::Ptr& ptr, const std::string& groupName, int mode, int number, bool persist)
bool MechanicsManager::playAnimationGroup(const MWWorld::Ptr& ptr, std::string_view groupName, int mode, int number, bool persist)
{
if(ptr.getClass().isActor())
return mActors.playAnimationGroup(ptr, groupName, mode, number, persist);

@ -133,7 +133,7 @@ namespace MWMechanics
/// Attempt to play an animation group
/// @return Success or error
bool playAnimationGroup(const MWWorld::Ptr& ptr, const std::string& groupName, int mode, int number, bool persist=false) override;
bool playAnimationGroup(const MWWorld::Ptr& ptr, std::string_view groupName, int mode, int number, bool persist=false) override;
void skipAnimation(const MWWorld::Ptr& ptr) override;
bool checkAnimationPlaying(const MWWorld::Ptr& ptr, const std::string &groupName) override;
void persistAnimationStates() override;

@ -99,7 +99,7 @@ void Objects::onClose(const MWWorld::Ptr& ptr)
iter->second->onClose();
}
bool Objects::playAnimationGroup(const MWWorld::Ptr& ptr, const std::string& groupName, int mode, int number, bool persist)
bool Objects::playAnimationGroup(const MWWorld::Ptr& ptr, std::string_view groupName, int mode, int number, bool persist)
{
const auto iter = mIndex.find(ptr.mRef);
if (iter != mIndex.end())

@ -45,7 +45,7 @@ namespace MWMechanics
bool onOpen(const MWWorld::Ptr& ptr);
void onClose(const MWWorld::Ptr& ptr);
bool playAnimationGroup(const MWWorld::Ptr& ptr, const std::string& groupName, int mode, int number, bool persist=false);
bool playAnimationGroup(const MWWorld::Ptr& ptr, std::string_view groupName, int mode, int number, bool persist=false);
void skipAnimation(const MWWorld::Ptr& ptr);
void persistAnimationStates();

@ -478,7 +478,7 @@ namespace MWMechanics
{
animation->addEffect(
Misc::ResourceHelpers::correctMeshPath(castStatic->mModel, vfs),
effect->mIndex, false, "", effect->mParticle);
effect->mIndex, false, {}, effect->mParticle);
}
else
{
@ -561,7 +561,7 @@ namespace MWMechanics
const VFS::Manager* const vfs = MWBase::Environment::get().getResourceSystem()->getVFS();
anim->addEffect(
Misc::ResourceHelpers::correctMeshPath(castStatic->mModel, vfs),
magicEffect.mIndex, loop, "", magicEffect.mParticle);
magicEffect.mIndex, loop, {}, magicEffect.mParticle);
}
}
}

@ -277,7 +277,7 @@ namespace
const VFS::Manager* const vfs = MWBase::Environment::get().getResourceSystem()->getVFS();
animation->addEffect(
Misc::ResourceHelpers::correctMeshPath(absorbStatic->mModel, vfs),
ESM::MagicEffect::SpellAbsorption, false, std::string());
ESM::MagicEffect::SpellAbsorption, false);
}
const ESM::Spell* spell = esmStore.get<ESM::Spell>().search(spellId);
int spellCost = 0;

@ -734,7 +734,7 @@ namespace MWRender
return -1.f;
}
float Animation::getTextKeyTime(const std::string &textKey) const
float Animation::getTextKeyTime(std::string_view textKey) const
{
for(AnimSourceList::const_reverse_iterator iter(mAnimSources.rbegin()); iter != mAnimSources.rend(); ++iter)
{
@ -742,7 +742,7 @@ namespace MWRender
for(auto iterKey = keys.begin(); iterKey != keys.end(); ++iterKey)
{
if(iterKey->second.compare(0, textKey.size(), textKey) == 0)
if(iterKey->second.starts_with(textKey) == 0)
return iterKey->first;
}
}
@ -750,20 +750,17 @@ namespace MWRender
return -1.f;
}
void Animation::handleTextKey(AnimState &state, const std::string &groupname, SceneUtil::TextKeyMap::ConstIterator key,
void Animation::handleTextKey(AnimState &state, std::string_view groupname, SceneUtil::TextKeyMap::ConstIterator key,
const SceneUtil::TextKeyMap& map)
{
const std::string &evt = key->second;
std::string_view evt = key->second;
size_t off = groupname.size()+2;
size_t len = evt.size() - off;
if(evt.compare(0, groupname.size(), groupname) == 0 &&
evt.compare(groupname.size(), 2, ": ") == 0)
if(evt.starts_with(groupname) && evt.substr(groupname.size()).starts_with(": "))
{
if(evt.compare(off, len, "loop start") == 0)
size_t off = groupname.size() + 2;
if(evt.substr(off) == "loop start")
state.mLoopStartTime = key->first;
else if(evt.compare(off, len, "loop stop") == 0)
else if(evt.substr(off) == "loop stop")
state.mLoopStopTime = key->first;
}
@ -780,8 +777,8 @@ namespace MWRender
}
}
void Animation::play(const std::string &groupname, const AnimPriority& priority, int blendMask, bool autodisable, float speedmult,
const std::string &start, const std::string &stop, float startpoint, size_t loops, bool loopfallback)
void Animation::play(std::string_view groupname, const AnimPriority& priority, int blendMask, bool autodisable, float speedmult,
std::string_view start, std::string_view stop, float startpoint, size_t loops, bool loopfallback)
{
if(!mObjectRoot || mAnimSources.empty())
return;
@ -824,7 +821,7 @@ namespace MWRender
state.mPriority = priority;
state.mBlendMask = blendMask;
state.mAutoDisable = autodisable;
mStates[groupname] = state;
mStates[std::string{groupname}] = state;
if (state.mPlaying)
{
@ -859,39 +856,48 @@ namespace MWRender
resetActiveGroups();
}
bool Animation::reset(AnimState &state, const SceneUtil::TextKeyMap &keys, const std::string &groupname, const std::string &start, const std::string &stop, float startpoint, bool loopfallback)
bool Animation::reset(AnimState& state, const SceneUtil::TextKeyMap& keys, std::string_view groupname, std::string_view start, std::string_view stop, float startpoint, bool loopfallback)
{
// Look for text keys in reverse. This normally wouldn't matter, but for some reason undeadwolf_2.nif has two
// separate walkforward keys, and the last one is supposed to be used.
auto groupend = keys.rbegin();
for(;groupend != keys.rend();++groupend)
{
if(groupend->second.compare(0, groupname.size(), groupname) == 0 &&
if(groupend->second.starts_with(groupname) &&
groupend->second.compare(groupname.size(), 2, ": ") == 0)
break;
}
std::string starttag = groupname+": "+start;
auto equals = [] (std::string_view value, std::string_view s1, std::string_view s2, std::string_view s3 = {})
{
if (value.starts_with(s1))
{
value = value.substr(s1.size());
if(value.starts_with(s2))
return value.substr(s2.size()) == s3;
}
return false;
};
auto startkey = groupend;
while(startkey != keys.rend() && startkey->second != starttag)
while(startkey != keys.rend() && !equals(startkey->second, groupname, ": ", start))
++startkey;
if(startkey == keys.rend() && start == "loop start")
{
starttag = groupname+": start";
startkey = groupend;
while(startkey != keys.rend() && startkey->second != starttag)
while(startkey != keys.rend() && !equals(startkey->second, groupname, ": start"))
++startkey;
}
if(startkey == keys.rend())
return false;
const std::string stoptag = groupname+": "+stop;
auto stopkey = groupend;
std::size_t checkLength = groupname.size() + 2 + stop.size();
while(stopkey != keys.rend()
// We have to ignore extra garbage at the end.
// The Scrib's idle3 animation has "Idle3: Stop." instead of "Idle3: Stop".
// Why, just why? :(
&& (stopkey->second.size() < stoptag.size() || stopkey->second.compare(0,stoptag.size(), stoptag) != 0))
&& !equals(std::string_view{stopkey->second}.substr(0, checkLength), groupname, ": ", stop))
++stopkey;
if(stopkey == keys.rend())
return false;
@ -916,8 +922,6 @@ namespace MWRender
// mLoopStartTime and mLoopStopTime normally get assigned when encountering these keys while playing the animation
// (see handleTextKey). But if startpoint is already past these keys, or start time is == stop time, we need to assign them now.
const std::string loopstarttag = groupname+": loop start";
const std::string loopstoptag = groupname+": loop stop";
auto key = groupend;
for (; key != startkey && key != keys.rend(); ++key)
@ -925,9 +929,9 @@ namespace MWRender
if (key->first > state.getTime())
continue;
if (key->second == loopstarttag)
if (equals(key->second, groupname, ": loop start"))
state.mLoopStartTime = key->first;
else if (key->second == loopstoptag)
else if (equals(key->second, groupname, ": loop stop"))
state.mLoopStopTime = key->first;
}
@ -1021,7 +1025,7 @@ namespace MWRender
state->second.mSpeedMult = speedmult;
}
bool Animation::isPlaying(const std::string &groupname) const
bool Animation::isPlaying(std::string_view groupname) const
{
AnimStateMap::const_iterator state(mStates.find(groupname));
if(state != mStates.end())
@ -1029,7 +1033,7 @@ namespace MWRender
return false;
}
bool Animation::getInfo(const std::string &groupname, float *complete, float *speedmult) const
bool Animation::getInfo(std::string_view groupname, float *complete, float *speedmult) const
{
AnimStateMap::const_iterator iter = mStates.find(groupname);
if(iter == mStates.end())
@ -1069,7 +1073,7 @@ namespace MWRender
return iter->second.mLoopCount;
}
void Animation::disable(const std::string &groupname)
void Animation::disable(std::string_view groupname)
{
AnimStateMap::iterator iter = mStates.find(groupname);
if(iter != mStates.end())
@ -1272,7 +1276,7 @@ namespace MWRender
return movement;
}
void Animation::setLoopingEnabled(const std::string &groupname, bool enabled)
void Animation::setLoopingEnabled(std::string_view groupname, bool enabled)
{
AnimStateMap::iterator state(mStates.find(groupname));
if(state != mStates.end())
@ -1511,7 +1515,7 @@ namespace MWRender
mExtraLightSource->setActorFade(mAlpha);
}
void Animation::addEffect (const std::string& model, int effectId, bool loop, const std::string& bonename, const std::string& texture)
void Animation::addEffect(const std::string& model, int effectId, bool loop, std::string_view bonename, std::string_view texture)
{
if (!mObjectRoot.get())
return;
@ -1537,7 +1541,7 @@ namespace MWRender
{
NodeMap::const_iterator found = getNodeMap().find(bonename);
if (found == getNodeMap().end())
throw std::runtime_error("Can't find bone " + bonename);
throw std::runtime_error("Can't find bone " + std::string{bonename});
parentNode = found->second;
}
@ -1648,7 +1652,7 @@ namespace MWRender
return true;
}
const osg::Node* Animation::getNode(const std::string &name) const
const osg::Node* Animation::getNode(std::string_view name) const
{
NodeMap::const_iterator found = getNodeMap().find(name);
if (found == getNodeMap().end())
@ -1733,7 +1737,7 @@ namespace MWRender
mRootController = addRotateController("bip01");
}
osg::ref_ptr<RotateController> Animation::addRotateController(const std::string &bone)
osg::ref_ptr<RotateController> Animation::addRotateController(std::string_view bone)
{
auto iter = getNodeMap().find(bone);
if (iter == getNodeMap().end())

@ -228,7 +228,7 @@ protected:
return getTime() >= mLoopStopTime && mLoopingEnabled && mLoopCount > 0;
}
};
typedef std::map<std::string,AnimState> AnimStateMap;
typedef std::map<std::string, AnimState, std::less<>> AnimStateMap;
AnimStateMap mStates;
typedef std::vector<std::shared_ptr<AnimSource> > AnimSourceList;
@ -274,7 +274,7 @@ protected:
float mLegsYawRadians;
float mBodyPitchRadians;
osg::ref_ptr<RotateController> addRotateController(const std::string& bone);
osg::ref_ptr<RotateController> addRotateController(std::string_view bone);
bool mHasMagicEffects;
@ -307,10 +307,10 @@ protected:
* false.
*/
bool reset(AnimState &state, const SceneUtil::TextKeyMap &keys,
const std::string &groupname, const std::string &start, const std::string &stop,
std::string_view groupname, std::string_view start, std::string_view stop,
float startpoint, bool loopfallback);
void handleTextKey(AnimState &state, const std::string &groupname, SceneUtil::TextKeyMap::ConstIterator key,
void handleTextKey(AnimState &state, std::string_view groupname, SceneUtil::TextKeyMap::ConstIterator key,
const SceneUtil::TextKeyMap& map);
/** Sets the root model of the object.
@ -374,7 +374,7 @@ public:
* @param texture override the texture specified in the model's materials - if empty, do not override
* @note Will not add an effect twice.
*/
void addEffect (const std::string& model, int effectId, bool loop = false, const std::string& bonename = "", const std::string& texture = "");
void addEffect(const std::string& model, int effectId, bool loop = false, std::string_view bonename = {}, std::string_view texture = {});
void removeEffect (int effectId);
void removeEffects ();
void getLoopingEffects (std::vector<int>& out) const;
@ -412,8 +412,8 @@ public:
* \param loopFallback Allow looping an animation that has no loop keys, i.e. fall back to use
* the "start" and "stop" keys for looping?
*/
void play(const std::string &groupname, const AnimPriority& priority, int blendMask, bool autodisable,
float speedmult, const std::string &start, const std::string &stop,
void play(std::string_view groupname, const AnimPriority& priority, int blendMask, bool autodisable,
float speedmult, std::string_view start,std::string_view stop,
float startpoint, size_t loops, bool loopfallback=false);
/** Adjust the speed multiplier of an already playing animation.
@ -421,7 +421,7 @@ public:
void adjustSpeedMult (const std::string& groupname, float speedmult);
/** Returns true if the named animation group is playing. */
bool isPlaying(const std::string &groupname) const;
bool isPlaying(std::string_view groupname) const;
/// Returns true if no important animations are currently playing on the upper body.
bool upperBodyReady() const;
@ -432,13 +432,13 @@ public:
* \param speedmult Stores the animation speed multiplier
* \return True if the animation is active, false otherwise.
*/
bool getInfo(const std::string &groupname, float *complete=nullptr, float *speedmult=nullptr) const;
bool getInfo(std::string_view groupname, float *complete=nullptr, float *speedmult=nullptr) const;
/// Get the absolute position in the animation track of the first text key with the given group.
float getStartTime(const std::string &groupname) const;
/// Get the absolute position in the animation track of the text key
float getTextKeyTime(const std::string &textKey) const;
float getTextKeyTime(std::string_view textKey) const;
/// Get the current absolute position in the animation track for the animation that is currently playing from the given group.
float getCurrentTime(const std::string& groupname) const;
@ -448,21 +448,21 @@ public:
/** Disables the specified animation group;
* \param groupname Animation group to disable.
*/
void disable(const std::string &groupname);
void disable(std::string_view groupname);
/** Retrieves the velocity (in units per second) that the animation will move. */
float getVelocity(const std::string &groupname) const;
virtual osg::Vec3f runAnimation(float duration);
void setLoopingEnabled(const std::string &groupname, bool enabled);
void setLoopingEnabled(std::string_view groupname, bool enabled);
/// This is typically called as part of runAnimation, but may be called manually if needed.
void updateEffects();
/// Return a node with the specified name, or nullptr if not existing.
/// @note The matching is case-insensitive.
const osg::Node* getNode(const std::string& name) const;
const osg::Node* getNode(std::string_view name) const;
virtual bool useShieldAnimations() const { return false; }
virtual bool getWeaponsShown() const { return false; }

@ -14,7 +14,7 @@ namespace MWRender
class TextureOverrideVisitor : public osg::NodeVisitor
{
public:
TextureOverrideVisitor(const std::string& texture, Resource::ResourceSystem* resourcesystem)
TextureOverrideVisitor(std::string_view texture, Resource::ResourceSystem* resourcesystem)
: osg::NodeVisitor(TRAVERSE_ALL_CHILDREN)
, mTexture(texture)
, mResourcesystem(resourcesystem)
@ -36,13 +36,13 @@ class TextureOverrideVisitor : public osg::NodeVisitor
Resource::ResourceSystem* mResourcesystem;
};
void overrideFirstRootTexture(const std::string &texture, Resource::ResourceSystem *resourceSystem, osg::ref_ptr<osg::Node> node)
void overrideFirstRootTexture(std::string_view texture, Resource::ResourceSystem *resourceSystem, osg::ref_ptr<osg::Node> node)
{
TextureOverrideVisitor overrideVisitor(texture, resourceSystem);
node->accept(overrideVisitor);
}
void overrideTexture(const std::string &texture, Resource::ResourceSystem *resourceSystem, osg::ref_ptr<osg::Node> node)
void overrideTexture(std::string_view texture, Resource::ResourceSystem *resourceSystem, osg::ref_ptr<osg::Node> node)
{
if (texture.empty())
return;

@ -19,9 +19,9 @@ namespace MWRender
{
// Overrides the texture of nodes in the mesh that had the same NiTexturingProperty as the first NiTexturingProperty of the .NIF file's root node,
// if it had a NiTexturingProperty. Used for applying "particle textures" to magic effects.
void overrideFirstRootTexture(const std::string &texture, Resource::ResourceSystem *resourceSystem, osg::ref_ptr<osg::Node> node);
void overrideFirstRootTexture(std::string_view texture, Resource::ResourceSystem* resourceSystem, osg::ref_ptr<osg::Node> node);
void overrideTexture(const std::string& texture, Resource::ResourceSystem* resourceSystem, osg::ref_ptr<osg::Node> node);
void overrideTexture(std::string_view texture, Resource::ResourceSystem* resourceSystem, osg::ref_ptr<osg::Node> node);
// Node callback to entirely skip the traversal.
class NoTraverseCallback : public osg::NodeCallback

@ -58,7 +58,7 @@ namespace MWScript
throw std::runtime_error ("animation mode out of range");
}
MWBase::Environment::get().getMechanicsManager()->playAnimationGroup(ptr, std::string{group}, mode, std::numeric_limits<int>::max(), true);
MWBase::Environment::get().getMechanicsManager()->playAnimationGroup(ptr, group, mode, std::numeric_limits<int>::max(), true);
}
};
@ -94,7 +94,7 @@ namespace MWScript
throw std::runtime_error ("animation mode out of range");
}
MWBase::Environment::get().getMechanicsManager()->playAnimationGroup(ptr, std::string{group}, mode, loops + 1, true);
MWBase::Environment::get().getMechanicsManager()->playAnimationGroup(ptr, group, mode, loops + 1, true);
}
};

Loading…
Cancel
Save