1
0
Fork 0
mirror of https://github.com/OpenMW/openmw.git synced 2025-02-03 18:45:34 +00:00

Optimize new magic effects update system

This commit is contained in:
Andrei Kortunov 2018-08-26 21:02:14 +04:00
parent 327f36b081
commit 60698e6f8a
4 changed files with 29 additions and 11 deletions

View file

@ -1679,7 +1679,7 @@ namespace MWMechanics
MWRender::Animation* animation = MWBase::Environment::get().getWorld()->getAnimation(iter->first); MWRender::Animation* animation = MWBase::Environment::get().getWorld()->getAnimation(iter->first);
if (animation) if (animation)
animation->updateEffects(duration); animation->updateEffects();
} }

View file

@ -2219,9 +2219,6 @@ void CharacterController::update(float duration)
moved *= (l / newLength); moved *= (l / newLength);
} }
if (mSkipAnim)
mAnimation->updateEffects(duration);
if (mFloatToSurface && cls.isActor() && cls.getCreatureStats(mPtr).isDead() && cls.canSwim(mPtr)) if (mFloatToSurface && cls.isActor() && cls.getCreatureStats(mPtr).isDead() && cls.canSwim(mPtr))
moved.z() = 1.0; moved.z() = 1.0;

View file

@ -208,8 +208,11 @@ namespace
class RemoveFinishedCallbackVisitor : public RemoveVisitor class RemoveFinishedCallbackVisitor : public RemoveVisitor
{ {
public: public:
bool mHasMagicEffects;
RemoveFinishedCallbackVisitor() RemoveFinishedCallbackVisitor()
: RemoveVisitor() : RemoveVisitor()
, mHasMagicEffects(false)
, mEffectId(-1) , mEffectId(-1)
{ {
} }
@ -234,11 +237,14 @@ namespace
{ {
// We should remove empty transformation nodes and finished callbacks here // We should remove empty transformation nodes and finished callbacks here
MWRender::UpdateVfxCallback* vfxCallback = dynamic_cast<MWRender::UpdateVfxCallback*>(callback); MWRender::UpdateVfxCallback* vfxCallback = dynamic_cast<MWRender::UpdateVfxCallback*>(callback);
bool finished = vfxCallback && vfxCallback->mFinished; if (vfxCallback)
bool toRemove = vfxCallback && mEffectId >= 0 && vfxCallback->mParams.mEffectId == mEffectId;
if (finished || toRemove)
{ {
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) , mTextKeyListener(NULL)
, mHeadYawRadians(0.f) , mHeadYawRadians(0.f)
, mHeadPitchRadians(0.f) , mHeadPitchRadians(0.f)
, mHasMagicEffects(false)
, mAlpha(1.f) , mAlpha(1.f)
{ {
for(size_t i = 0;i < sNumBlendMasks;i++) for(size_t i = 0;i < sNumBlendMasks;i++)
@ -1321,7 +1328,7 @@ namespace MWRender
++stateiter; ++stateiter;
} }
updateEffects(duration); updateEffects();
if (mHeadController) if (mHeadController)
{ {
@ -1633,6 +1640,9 @@ namespace MWRender
SceneUtil::AssignControllerSourcesVisitor assignVisitor(std::shared_ptr<SceneUtil::ControllerSource>(params.mAnimTime)); SceneUtil::AssignControllerSourcesVisitor assignVisitor(std::shared_ptr<SceneUtil::ControllerSource>(params.mAnimTime));
node->accept(assignVisitor); node->accept(assignVisitor);
// Notify that this animation has attached magic effects
mHasMagicEffects = true;
overrideFirstRootTexture(texture, mResourceSystem, node); overrideFirstRootTexture(texture, mResourceSystem, node);
} }
@ -1641,10 +1651,14 @@ namespace MWRender
RemoveFinishedCallbackVisitor visitor(effectId); RemoveFinishedCallbackVisitor visitor(effectId);
mInsert->accept(visitor); mInsert->accept(visitor);
visitor.remove(); visitor.remove();
mHasMagicEffects = visitor.mHasMagicEffects;
} }
void Animation::getLoopingEffects(std::vector<int> &out) const void Animation::getLoopingEffects(std::vector<int> &out) const
{ {
if (!mHasMagicEffects)
return;
FindVfxCallbacksVisitor visitor; FindVfxCallbacksVisitor visitor;
mInsert->accept(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 // TODO: objects without animation still will have
// transformation nodes with finished callbacks // transformation nodes with finished callbacks
RemoveFinishedCallbackVisitor visitor; RemoveFinishedCallbackVisitor visitor;
mInsert->accept(visitor); mInsert->accept(visitor);
visitor.remove(); visitor.remove();
mHasMagicEffects = visitor.mHasMagicEffects;
} }
bool Animation::upperBodyReady() const bool Animation::upperBodyReady() const

View file

@ -263,6 +263,7 @@ protected:
osg::ref_ptr<RotateController> mHeadController; osg::ref_ptr<RotateController> mHeadController;
float mHeadYawRadians; float mHeadYawRadians;
float mHeadPitchRadians; float mHeadPitchRadians;
bool mHasMagicEffects;
osg::ref_ptr<SceneUtil::LightSource> mGlowLight; osg::ref_ptr<SceneUtil::LightSource> mGlowLight;
osg::ref_ptr<GlowUpdater> mGlowUpdater; osg::ref_ptr<GlowUpdater> mGlowUpdater;
@ -450,7 +451,7 @@ public:
void setLoopingEnabled(const std::string &groupname, bool enabled); void setLoopingEnabled(const std::string &groupname, bool enabled);
/// This is typically called as part of runAnimation, but may be called manually if needed. /// 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. /// Return a node with the specified name, or NULL if not existing.
/// @note The matching is case-insensitive. /// @note The matching is case-insensitive.