From e0e4cbbb4127eb2a0a694bcb8cf5d0329f31fe56 Mon Sep 17 00:00:00 2001 From: scrawl Date: Sun, 24 Aug 2014 01:50:29 +0200 Subject: [PATCH] Implement Light magic effect (Fixes #1122) --- apps/openmw/mwmechanics/character.cpp | 3 +++ apps/openmw/mwrender/animation.cpp | 34 +++++++++++++++++++++++++++ apps/openmw/mwrender/animation.hpp | 7 ++++++ 3 files changed, 44 insertions(+) diff --git a/apps/openmw/mwmechanics/character.cpp b/apps/openmw/mwmechanics/character.cpp index 641bd3f6b..0362b8e23 100644 --- a/apps/openmw/mwmechanics/character.cpp +++ b/apps/openmw/mwmechanics/character.cpp @@ -1663,6 +1663,9 @@ void CharacterController::updateVisibility() } mAnimation->setAlpha(alpha); + + float light = mPtr.getClass().getCreatureStats(mPtr).getMagicEffects().get(ESM::MagicEffect::Light).getMagnitude(); + mAnimation->setLightEffect(light); } void CharacterController::determineAttackType() diff --git a/apps/openmw/mwrender/animation.cpp b/apps/openmw/mwrender/animation.cpp index e179d7a1d..ab181ca77 100644 --- a/apps/openmw/mwrender/animation.cpp +++ b/apps/openmw/mwrender/animation.cpp @@ -71,6 +71,7 @@ Animation::Animation(const MWWorld::Ptr &ptr, Ogre::SceneNode *node) , mNonAccumCtrl(NULL) , mAccumulate(0.0f) , mNullAnimationTimePtr(OGRE_NEW NullAnimationTime) + , mGlowLight(NULL) { for(size_t i = 0;i < sNumGroups;i++) mAnimationTimePtr[i].bind(OGRE_NEW AnimationTime(this)); @@ -78,6 +79,8 @@ Animation::Animation(const MWWorld::Ptr &ptr, Ogre::SceneNode *node) Animation::~Animation() { + setLightEffect(0); + mEffects.clear(); mAnimSources.clear(); @@ -1397,6 +1400,37 @@ Ogre::Vector3 Animation::getEnchantmentColor(MWWorld::Ptr item) return result; } +void Animation::setLightEffect(float effect) +{ + if (effect == 0) + { + if (mGlowLight) + { + mInsert->getCreator()->destroySceneNode(mGlowLight->getParentSceneNode()); + mInsert->getCreator()->destroyLight(mGlowLight); + mGlowLight = NULL; + } + } + else + { + if (!mGlowLight) + { + mGlowLight = mInsert->getCreator()->createLight(); + + Ogre::AxisAlignedBox bounds = Ogre::AxisAlignedBox::BOX_NULL; + for(size_t i = 0;i < mObjectRoot->mEntities.size();i++) + { + Ogre::Entity *ent = mObjectRoot->mEntities[i]; + bounds.merge(ent->getBoundingBox()); + } + mInsert->createChildSceneNode(bounds.getCenter())->attachObject(mGlowLight); + } + mGlowLight->setType(Ogre::Light::LT_POINT); + effect += 3; + mGlowLight->setAttenuation(1.0f / (0.03 * (0.5/effect)), 0, 0.5/effect, 0); + } +} + ObjectAnimation::ObjectAnimation(const MWWorld::Ptr& ptr, const std::string &model) : Animation(ptr, ptr.getRefData().getBaseNode()) diff --git a/apps/openmw/mwrender/animation.hpp b/apps/openmw/mwrender/animation.hpp index dc4244c39..b85e74549 100644 --- a/apps/openmw/mwrender/animation.hpp +++ b/apps/openmw/mwrender/animation.hpp @@ -126,6 +126,8 @@ protected: MWWorld::Ptr mPtr; + Ogre::Light* mGlowLight; + Ogre::SceneNode *mInsert; Ogre::Entity *mSkelBase; NifOgre::ObjectScenePtr mObjectRoot; @@ -301,6 +303,11 @@ public: /// This is typically called as part of runAnimation, but may be called manually if needed. void updateEffects(float duration); + // TODO: move outside of this class + /// Makes this object glow, by placing a Light in its center. + /// @param effect Controls the radius and intensity of the light. + void setLightEffect(float effect); + virtual void showWeapons(bool showWeapon); virtual void showCarriedLeft(bool show) {} virtual void attachArrow() {}