From 4dc424036f218dda617b98d4ff4218e072da31a9 Mon Sep 17 00:00:00 2001 From: Andrei Kortunov Date: Fri, 28 Sep 2018 13:57:13 +0400 Subject: [PATCH 1/4] Cleanup magic effects, when create a new ActorAnimation --- apps/openmw/mwrender/actoranimation.cpp | 3 ++ apps/openmw/mwrender/animation.cpp | 69 ++++++++++++++++++++++--- apps/openmw/mwrender/animation.hpp | 1 + 3 files changed, 67 insertions(+), 6 deletions(-) diff --git a/apps/openmw/mwrender/actoranimation.cpp b/apps/openmw/mwrender/actoranimation.cpp index d92b95a71..e6aff8d19 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 7410dbf03..e7c3f2200 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 e10d2c995..5828bd52f 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, From 632045e145c4162a5cc095a77db3ee498791b14b Mon Sep 17 00:00:00 2001 From: Andrei Kortunov Date: Sun, 30 Sep 2018 10:35:01 +0400 Subject: [PATCH 2/4] Improve the 'part has no parents' warning --- apps/openmw/mwrender/animation.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/openmw/mwrender/animation.cpp b/apps/openmw/mwrender/animation.cpp index e7c3f2200..85d4aae9d 100644 --- a/apps/openmw/mwrender/animation.cpp +++ b/apps/openmw/mwrender/animation.cpp @@ -1975,12 +1975,12 @@ namespace MWRender PartHolder::~PartHolder() { if (mNode.get() && !mNode->getNumParents()) - Log(Debug::Verbose) << "Part has no parents" ; + Log(Debug::Verbose) << "Part \"" << mNode->getName() << "\" has no parents" ; if (mNode.get() && mNode->getNumParents()) { if (mNode->getNumParents() > 1) - Log(Debug::Verbose) << "Part has multiple (" << mNode->getNumParents() << ") parents"; + Log(Debug::Verbose) << "Part \"" << mNode->getName() << "\" has multiple (" << mNode->getNumParents() << ") parents"; mNode->getParent(0)->removeChild(mNode); } } From 3896a2eba6da63a227094b1cc38fd3a3e22c4c26 Mon Sep 17 00:00:00 2001 From: Andrei Kortunov Date: Sun, 30 Sep 2018 11:12:28 +0400 Subject: [PATCH 3/4] Do not use a PartHolder for spell effect node --- apps/openmw/mwrender/animation.cpp | 5 ++--- apps/openmw/mwrender/animation.hpp | 1 - 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/apps/openmw/mwrender/animation.cpp b/apps/openmw/mwrender/animation.cpp index 85d4aae9d..840e59290 100644 --- a/apps/openmw/mwrender/animation.cpp +++ b/apps/openmw/mwrender/animation.cpp @@ -624,8 +624,8 @@ namespace MWRender } else { - // Remove effect immediately - mParams.mObjects.reset(); + // Hide effect immediately + node->setNodeMask(0); mFinished = true; } } @@ -1686,7 +1686,6 @@ namespace MWRender params.mLoop = loop; params.mEffectId = effectId; params.mBoneName = bonename; - params.mObjects = PartHolderPtr(new PartHolder(node)); params.mAnimTime = std::shared_ptr(new EffectAnimationTime); trans->addUpdateCallback(new UpdateVfxCallback(params)); diff --git a/apps/openmw/mwrender/animation.hpp b/apps/openmw/mwrender/animation.hpp index 5828bd52f..2d8ac152f 100644 --- a/apps/openmw/mwrender/animation.hpp +++ b/apps/openmw/mwrender/animation.hpp @@ -74,7 +74,6 @@ typedef std::shared_ptr PartHolderPtr; struct EffectParams { std::string mModelName; // Just here so we don't add the same effect twice - PartHolderPtr mObjects; std::shared_ptr mAnimTime; float mMaxControllerLength; int mEffectId; From 07ccc5abdb3f18d946a57d34ddd9161ef297bee2 Mon Sep 17 00:00:00 2001 From: Andrei Kortunov Date: Mon, 1 Oct 2018 21:57:13 +0400 Subject: [PATCH 4/4] Remove non-looping effects after rest --- apps/openmw/mwmechanics/actors.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/apps/openmw/mwmechanics/actors.cpp b/apps/openmw/mwmechanics/actors.cpp index 92f2ba34d..4f051f40a 100644 --- a/apps/openmw/mwmechanics/actors.cpp +++ b/apps/openmw/mwmechanics/actors.cpp @@ -1683,7 +1683,10 @@ namespace MWMechanics MWRender::Animation* animation = MWBase::Environment::get().getWorld()->getAnimation(iter->first); if (animation) - animation->updateEffects(); + { + animation->removeEffects(); + MWBase::Environment::get().getWorld()->applyLoopingParticles(iter->first); + } }