From 1893617ec98491c5729c9d5bd59d24814d7567e8 Mon Sep 17 00:00:00 2001 From: scrawl Date: Sat, 8 Oct 2016 23:59:28 +0200 Subject: [PATCH] Improvements to ignored light list setting The pointer to the LightListCallback is now stored in the Animation, which eliminates the need for dynamic_cast. Also, when the object root is recreated, the previously used LightListCallback will be reused, so we no longer need the objectRootReset() notifier. Finally, there was a bug when saving and reloading the game, the getIgnoredLightSources() were not being set, as the ActorAnimation constructor completes before the NpcAnimation sets the ObjectRoot. This was solved by creating the LightListCallback in advance in the Animation constructor. --- apps/openmw/mwrender/actoranimation.cpp | 29 ++----------------------- apps/openmw/mwrender/actoranimation.hpp | 5 ----- apps/openmw/mwrender/animation.cpp | 8 ++++++- apps/openmw/mwrender/animation.hpp | 3 +++ 4 files changed, 12 insertions(+), 33 deletions(-) diff --git a/apps/openmw/mwrender/actoranimation.cpp b/apps/openmw/mwrender/actoranimation.cpp index 1a3285713..c16fbfd50 100644 --- a/apps/openmw/mwrender/actoranimation.cpp +++ b/apps/openmw/mwrender/actoranimation.cpp @@ -83,17 +83,6 @@ void ActorAnimation::itemRemoved(const MWWorld::ConstPtr& item, int /*count*/) } } -void ActorAnimation::objectRootReset() -{ - if (SceneUtil::LightListCallback* callback = findLightListCallback()) - { - for (ItemLightMap::iterator iter = mItemLights.begin(); iter != mItemLights.end(); ++iter) - { - callback->getIgnoredLightSources().insert(iter->second); - } - } -} - void ActorAnimation::addHiddenItemLight(const MWWorld::ConstPtr& item, const ESM::Light* esmLight) { if (mItemLights.find(item) != mItemLights.end()) @@ -115,7 +104,7 @@ void ActorAnimation::addHiddenItemLight(const MWWorld::ConstPtr& item, const ESM mInsert->addChild(lightSource); - if (SceneUtil::LightListCallback* callback = findLightListCallback()) + if (SceneUtil::LightListCallback* callback = mLightListCallback) callback->getIgnoredLightSources().insert(lightSource.get()); mItemLights.insert(std::make_pair(item, lightSource)); @@ -127,7 +116,7 @@ void ActorAnimation::removeHiddenItemLight(const MWWorld::ConstPtr& item) if (iter == mItemLights.end()) return; - if (SceneUtil::LightListCallback* callback = findLightListCallback()) + if (SceneUtil::LightListCallback* callback = mLightListCallback) { std::set::iterator ignoredIter = callback->getIgnoredLightSources().find(iter->second.get()); if (ignoredIter != callback->getIgnoredLightSources().end()) @@ -138,18 +127,4 @@ void ActorAnimation::removeHiddenItemLight(const MWWorld::ConstPtr& item) mItemLights.erase(iter); } -SceneUtil::LightListCallback* ActorAnimation::findLightListCallback() -{ - if (osg::Callback* callback = mObjectRoot->getCullCallback()) - { - do - { - if (SceneUtil::LightListCallback* lightListCallback = dynamic_cast(callback)) - return lightListCallback; - } - while ((callback = callback->getNestedCallback())); - } - return NULL; -} - } diff --git a/apps/openmw/mwrender/actoranimation.hpp b/apps/openmw/mwrender/actoranimation.hpp index e08df54f2..6922603e1 100644 --- a/apps/openmw/mwrender/actoranimation.hpp +++ b/apps/openmw/mwrender/actoranimation.hpp @@ -38,15 +38,10 @@ class ActorAnimation : public Animation, public MWWorld::ContainerStoreListener virtual void itemAdded(const MWWorld::ConstPtr& item, int count); virtual void itemRemoved(const MWWorld::ConstPtr& item, int count); - protected: - virtual void objectRootReset(); - private: void addHiddenItemLight(const MWWorld::ConstPtr& item, const ESM::Light* esmLight); void removeHiddenItemLight(const MWWorld::ConstPtr& item); - SceneUtil::LightListCallback* findLightListCallback(); - typedef std::map > ItemLightMap; ItemLightMap mItemLights; diff --git a/apps/openmw/mwrender/animation.cpp b/apps/openmw/mwrender/animation.cpp index e4855064a..e6a72f74c 100644 --- a/apps/openmw/mwrender/animation.cpp +++ b/apps/openmw/mwrender/animation.cpp @@ -429,6 +429,8 @@ namespace MWRender { for(size_t i = 0;i < sNumBlendMasks;i++) mAnimationTimePtr[i].reset(new AnimationTime); + + mLightListCallback = new SceneUtil::LightListCallback; } Animation::~Animation() @@ -1095,6 +1097,8 @@ namespace MWRender osg::ref_ptr previousStateset; if (mObjectRoot) { + if (mLightListCallback) + mObjectRoot->removeCullCallback(mLightListCallback); previousStateset = mObjectRoot->getStateSet(); mObjectRoot->getParent(0)->removeChild(mObjectRoot); } @@ -1150,7 +1154,9 @@ namespace MWRender removeTriBipVisitor.remove(); } - mObjectRoot->addCullCallback(new SceneUtil::LightListCallback); + if (!mLightListCallback) + mLightListCallback = new SceneUtil::LightListCallback; + mObjectRoot->addCullCallback(mLightListCallback); objectRootReset(); } diff --git a/apps/openmw/mwrender/animation.hpp b/apps/openmw/mwrender/animation.hpp index cf6afd613..6c4f18a0f 100644 --- a/apps/openmw/mwrender/animation.hpp +++ b/apps/openmw/mwrender/animation.hpp @@ -25,6 +25,7 @@ namespace NifOsg namespace SceneUtil { class LightSource; + class LightListCallback; class Skeleton; } @@ -273,6 +274,8 @@ protected: float mAlpha; + osg::ref_ptr mLightListCallback; + const NodeMap& getNodeMap() const; /* Sets the appropriate animations on the bone groups based on priority.