diff --git a/apps/openmw/mwrender/actoranimation.cpp b/apps/openmw/mwrender/actoranimation.cpp index d92b95a71c..e6aff8d19e 100644 --- a/apps/openmw/mwrender/actoranimation.cpp +++ b/apps/openmw/mwrender/actoranimation.cpp @@ -40,6 +40,9 @@ ActorAnimation::ActorAnimation(const MWWorld::Ptr& ptr, osg::ref_ptr addHiddenItemLight(*iter, light); } } + + // Make sure we cleaned object from effects, just in cast if we re-use node + removeEffects(); } ActorAnimation::~ActorAnimation() diff --git a/apps/openmw/mwrender/animation.cpp b/apps/openmw/mwrender/animation.cpp index 7410dbf037..e7c3f22004 100644 --- a/apps/openmw/mwrender/animation.cpp +++ b/apps/openmw/mwrender/animation.cpp @@ -213,14 +213,12 @@ namespace RemoveFinishedCallbackVisitor() : RemoveVisitor() , mHasMagicEffects(false) - , mEffectId(-1) { } RemoveFinishedCallbackVisitor(int effectId) : RemoveVisitor() , mHasMagicEffects(false) - , mEffectId(effectId) { } @@ -240,9 +238,63 @@ namespace MWRender::UpdateVfxCallback* vfxCallback = dynamic_cast(callback); if (vfxCallback) { - bool finished = vfxCallback->mFinished; - bool toRemove = mEffectId >= 0 && vfxCallback->mParams.mEffectId == mEffectId; - if (finished || toRemove) + if (vfxCallback->mFinished) + mToRemove.push_back(std::make_pair(group.asNode(), group.getParent(0))); + else + mHasMagicEffects = true; + } + } + } + + virtual void apply(osg::MatrixTransform &node) + { + traverse(node); + } + + virtual void apply(osg::Geometry&) + { + } + + private: + int mEffectId; + }; + + class RemoveCallbackVisitor : public RemoveVisitor + { + public: + bool mHasMagicEffects; + + RemoveCallbackVisitor() + : RemoveVisitor() + , mHasMagicEffects(false) + , mEffectId(-1) + { + } + + RemoveCallbackVisitor(int effectId) + : RemoveVisitor() + , mHasMagicEffects(false) + , mEffectId(effectId) + { + } + + virtual void apply(osg::Node &node) + { + traverse(node); + } + + virtual void apply(osg::Group &group) + { + traverse(group); + + osg::Callback* callback = group.getUpdateCallback(); + if (callback) + { + MWRender::UpdateVfxCallback* vfxCallback = dynamic_cast(callback); + if (vfxCallback) + { + bool toRemove = mEffectId < 0 || vfxCallback->mParams.mEffectId == mEffectId; + if (toRemove) mToRemove.push_back(std::make_pair(group.asNode(), group.getParent(0))); else mHasMagicEffects = true; @@ -1649,12 +1701,17 @@ namespace MWRender void Animation::removeEffect(int effectId) { - RemoveFinishedCallbackVisitor visitor(effectId); + RemoveCallbackVisitor visitor(effectId); mInsert->accept(visitor); visitor.remove(); mHasMagicEffects = visitor.mHasMagicEffects; } + void Animation::removeEffects() + { + removeEffect(-1); + } + void Animation::getLoopingEffects(std::vector &out) const { if (!mHasMagicEffects) diff --git a/apps/openmw/mwrender/animation.hpp b/apps/openmw/mwrender/animation.hpp index e10d2c995a..5828bd52f7 100644 --- a/apps/openmw/mwrender/animation.hpp +++ b/apps/openmw/mwrender/animation.hpp @@ -370,6 +370,7 @@ public: */ void addEffect (const std::string& model, int effectId, bool loop = false, const std::string& bonename = "", const std::string& texture = "", float scale = 1.0f); void removeEffect (int effectId); + void removeEffects (); void getLoopingEffects (std::vector& out) const; // Add a spell casting glow to an object. From measuring video taken from the original engine,