From 60698e6f8aab18b612653dc7acd4c242cdf3b3d1 Mon Sep 17 00:00:00 2001 From: Andrei Kortunov Date: Sun, 26 Aug 2018 21:02:14 +0400 Subject: [PATCH] Optimize new magic effects update system --- apps/openmw/mwmechanics/actors.cpp | 2 +- apps/openmw/mwmechanics/character.cpp | 3 --- apps/openmw/mwrender/animation.cpp | 32 ++++++++++++++++++++++----- apps/openmw/mwrender/animation.hpp | 3 ++- 4 files changed, 29 insertions(+), 11 deletions(-) diff --git a/apps/openmw/mwmechanics/actors.cpp b/apps/openmw/mwmechanics/actors.cpp index d203dccf4..ba8f62e2f 100644 --- a/apps/openmw/mwmechanics/actors.cpp +++ b/apps/openmw/mwmechanics/actors.cpp @@ -1679,7 +1679,7 @@ namespace MWMechanics MWRender::Animation* animation = MWBase::Environment::get().getWorld()->getAnimation(iter->first); if (animation) - animation->updateEffects(duration); + animation->updateEffects(); } diff --git a/apps/openmw/mwmechanics/character.cpp b/apps/openmw/mwmechanics/character.cpp index 49e2c4e6d..9d5db08b0 100644 --- a/apps/openmw/mwmechanics/character.cpp +++ b/apps/openmw/mwmechanics/character.cpp @@ -2219,9 +2219,6 @@ void CharacterController::update(float duration) moved *= (l / newLength); } - if (mSkipAnim) - mAnimation->updateEffects(duration); - if (mFloatToSurface && cls.isActor() && cls.getCreatureStats(mPtr).isDead() && cls.canSwim(mPtr)) moved.z() = 1.0; diff --git a/apps/openmw/mwrender/animation.cpp b/apps/openmw/mwrender/animation.cpp index 4da3ec4a8..1ace2f8b4 100644 --- a/apps/openmw/mwrender/animation.cpp +++ b/apps/openmw/mwrender/animation.cpp @@ -208,8 +208,11 @@ namespace class RemoveFinishedCallbackVisitor : public RemoveVisitor { public: + bool mHasMagicEffects; + RemoveFinishedCallbackVisitor() : RemoveVisitor() + , mHasMagicEffects(false) , mEffectId(-1) { } @@ -234,11 +237,14 @@ namespace { // We should remove empty transformation nodes and finished callbacks here MWRender::UpdateVfxCallback* vfxCallback = dynamic_cast(callback); - bool finished = vfxCallback && vfxCallback->mFinished; - bool toRemove = vfxCallback && mEffectId >= 0 && vfxCallback->mParams.mEffectId == mEffectId; - if (finished || toRemove) + if (vfxCallback) { - mToRemove.push_back(std::make_pair(group.asNode(), group.getParent(0))); + bool finished = vfxCallback->mFinished; + bool toRemove = mEffectId >= 0 && vfxCallback->mParams.mEffectId == mEffectId; + if (finished || toRemove) + mToRemove.push_back(std::make_pair(group.asNode(), group.getParent(0))); + else + mHasMagicEffects = true; } } } @@ -610,6 +616,7 @@ namespace MWRender , mTextKeyListener(NULL) , mHeadYawRadians(0.f) , mHeadPitchRadians(0.f) + , mHasMagicEffects(false) , mAlpha(1.f) { for(size_t i = 0;i < sNumBlendMasks;i++) @@ -1321,7 +1328,7 @@ namespace MWRender ++stateiter; } - updateEffects(duration); + updateEffects(); if (mHeadController) { @@ -1633,6 +1640,9 @@ namespace MWRender SceneUtil::AssignControllerSourcesVisitor assignVisitor(std::shared_ptr(params.mAnimTime)); node->accept(assignVisitor); + // Notify that this animation has attached magic effects + mHasMagicEffects = true; + overrideFirstRootTexture(texture, mResourceSystem, node); } @@ -1641,10 +1651,14 @@ namespace MWRender RemoveFinishedCallbackVisitor visitor(effectId); mInsert->accept(visitor); visitor.remove(); + mHasMagicEffects = visitor.mHasMagicEffects; } void Animation::getLoopingEffects(std::vector &out) const { + if (!mHasMagicEffects) + return; + FindVfxCallbacksVisitor visitor; mInsert->accept(visitor); @@ -1657,13 +1671,19 @@ namespace MWRender } } - void Animation::updateEffects(float duration) + void Animation::updateEffects() { + // We do not need to visit scene every frame. + // We can use a bool flag to check in spellcasting effect found. + if (!mHasMagicEffects) + return; + // TODO: objects without animation still will have // transformation nodes with finished callbacks RemoveFinishedCallbackVisitor visitor; mInsert->accept(visitor); visitor.remove(); + mHasMagicEffects = visitor.mHasMagicEffects; } bool Animation::upperBodyReady() const diff --git a/apps/openmw/mwrender/animation.hpp b/apps/openmw/mwrender/animation.hpp index 1da1fe4ef..e10d2c995 100644 --- a/apps/openmw/mwrender/animation.hpp +++ b/apps/openmw/mwrender/animation.hpp @@ -263,6 +263,7 @@ protected: osg::ref_ptr mHeadController; float mHeadYawRadians; float mHeadPitchRadians; + bool mHasMagicEffects; osg::ref_ptr mGlowLight; osg::ref_ptr mGlowUpdater; @@ -450,7 +451,7 @@ public: void setLoopingEnabled(const std::string &groupname, bool enabled); /// This is typically called as part of runAnimation, but may be called manually if needed. - void updateEffects(float duration); + void updateEffects(); /// Return a node with the specified name, or NULL if not existing. /// @note The matching is case-insensitive.