mirror of
https://github.com/OpenMW/openmw.git
synced 2025-02-22 23:09:43 +00:00
Make non-actors glow when they cast spells
This commit is contained in:
parent
dca7b4beb7
commit
3841a8fb40
4 changed files with 93 additions and 10 deletions
|
@ -1531,10 +1531,11 @@ void CharacterController::update(float duration)
|
|||
osg::Vec3f movement(0.f, 0.f, 0.f);
|
||||
float speed = 0.f;
|
||||
|
||||
updateMagicEffects();
|
||||
|
||||
if(!cls.isActor())
|
||||
{
|
||||
updateMagicEffects();
|
||||
MWRender::Animation* animation = MWBase::Environment::get().getWorld()->getAnimation(mPtr);
|
||||
animation->updateSpellGlow(duration);
|
||||
if(mAnimQueue.size() > 1)
|
||||
{
|
||||
if(mAnimation->isPlaying(mAnimQueue.front().mGroup) == false)
|
||||
|
|
|
@ -943,6 +943,8 @@ namespace MWMechanics
|
|||
const ESM::MagicEffect *effect;
|
||||
effect = store.get<ESM::MagicEffect>().find(effectentry.mEffectID);
|
||||
|
||||
MWRender::Animation* animation = MWBase::Environment::get().getWorld()->getAnimation(mCaster);
|
||||
|
||||
if (mCaster.getClass().isActor()) // TODO: Non-actors (except for large statics?) should also create a visual casting effect
|
||||
{
|
||||
const ESM::Static* castStatic;
|
||||
|
@ -951,8 +953,17 @@ namespace MWMechanics
|
|||
else
|
||||
castStatic = store.get<ESM::Static>().find ("VFX_DefaultCast");
|
||||
|
||||
MWBase::Environment::get().getWorld()->getAnimation(mCaster)->addEffect(
|
||||
"meshes\\" + castStatic->mModel, effect->mIndex);
|
||||
animation->addEffect("meshes\\" + castStatic->mModel, effect->mIndex);
|
||||
}
|
||||
|
||||
if (!mCaster.getClass().isActor())
|
||||
{
|
||||
osg::Vec4f glowcolor(1,1,1,1);
|
||||
glowcolor.x() = effect->mData.mRed / 255.f;
|
||||
glowcolor.y() = effect->mData.mGreen / 255.f;
|
||||
glowcolor.z() = effect->mData.mBlue / 255.f;
|
||||
|
||||
animation->addSpellCastGlow(glowcolor);
|
||||
}
|
||||
|
||||
static const std::string schools[] = {
|
||||
|
|
|
@ -38,6 +38,7 @@
|
|||
#include "../mwworld/esmstore.hpp"
|
||||
#include "../mwworld/class.hpp"
|
||||
#include "../mwworld/cellstore.hpp"
|
||||
#include "../mwbase/mechanicsmanager.hpp"
|
||||
|
||||
#include "../mwmechanics/character.hpp" // FIXME: for MWMechanics::Priority
|
||||
|
||||
|
@ -89,10 +90,11 @@ namespace
|
|||
class GlowUpdater : public SceneUtil::StateSetUpdater
|
||||
{
|
||||
public:
|
||||
GlowUpdater(int texUnit, osg::Vec4f color, const std::vector<osg::ref_ptr<osg::Texture2D> >& textures)
|
||||
GlowUpdater(int texUnit, osg::Vec4f color, const std::vector<osg::ref_ptr<osg::Texture2D> >& textures, bool hasDuration)
|
||||
: mTexUnit(texUnit)
|
||||
, mColor(color)
|
||||
, mTextures(textures)
|
||||
, mHasDuration(hasDuration)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -122,10 +124,26 @@ namespace
|
|||
stateset->setTextureAttribute(mTexUnit, mTextures[index], osg::StateAttribute::ON|osg::StateAttribute::OVERRIDE);
|
||||
}
|
||||
|
||||
bool const getHasDuration()
|
||||
{
|
||||
return mHasDuration;
|
||||
}
|
||||
|
||||
std::vector<osg::ref_ptr<osg::Texture2D> > const getTextures()
|
||||
{
|
||||
return mTextures;
|
||||
}
|
||||
|
||||
int const getTexUnit()
|
||||
{
|
||||
return mTexUnit;
|
||||
}
|
||||
|
||||
private:
|
||||
int mTexUnit;
|
||||
osg::Vec4f mColor;
|
||||
std::vector<osg::ref_ptr<osg::Texture2D> > mTextures;
|
||||
bool mHasDuration;
|
||||
};
|
||||
|
||||
class NodeMapVisitor : public osg::NodeVisitor
|
||||
|
@ -340,6 +358,7 @@ namespace MWRender
|
|||
, mHeadYawRadians(0.f)
|
||||
, mHeadPitchRadians(0.f)
|
||||
, mAlpha(1.f)
|
||||
, mSpellGlowDuration(0.f)
|
||||
{
|
||||
for(size_t i = 0;i < sNumBlendMasks;i++)
|
||||
mAnimationTimePtr[i].reset(new AnimationTime);
|
||||
|
@ -1106,7 +1125,44 @@ namespace MWRender
|
|||
int mLowestUnusedTexUnit;
|
||||
};
|
||||
|
||||
void Animation::addGlow(osg::ref_ptr<osg::Node> node, osg::Vec4f glowColor)
|
||||
void Animation::addSpellCastGlow(osg::Vec4f glowColor){
|
||||
addGlow(mObjectRoot, glowColor, true);
|
||||
MWBase::Environment::get().getMechanicsManager()->add(mPtr);
|
||||
}
|
||||
|
||||
void Animation::updateSpellGlow(float duration){
|
||||
if (mGlowUpdater != NULL && (mGlowUpdater->getHasDuration()))
|
||||
mSpellGlowDuration += duration;
|
||||
if (mSpellGlowDuration >= 1.5f) // length of spell glow effect was measured from original game as around 1.5 seconds
|
||||
removeSpellGlow();
|
||||
}
|
||||
|
||||
void Animation::removeSpellGlow()
|
||||
{
|
||||
osg::ref_ptr<osg::StateSet> writableStateSet = NULL;
|
||||
if (!mObjectRoot->getStateSet())
|
||||
writableStateSet = mObjectRoot->getOrCreateStateSet();
|
||||
else
|
||||
writableStateSet = osg::clone(mObjectRoot->getStateSet(), osg::CopyOp::SHALLOW_COPY);
|
||||
|
||||
std::vector<osg::ref_ptr<osg::Texture2D> > Textures = mGlowUpdater->getTextures();
|
||||
int TexUnit = mGlowUpdater->getTexUnit();
|
||||
mObjectRoot->removeUpdateCallback(mGlowUpdater);
|
||||
mGlowUpdater = NULL;
|
||||
|
||||
for (size_t index = 0; index < Textures.size(); index++)
|
||||
{
|
||||
writableStateSet->setTextureAttribute(TexUnit, Textures[index], osg::StateAttribute::OFF|osg::StateAttribute::OVERRIDE);
|
||||
writableStateSet->removeTextureAttribute(TexUnit, Textures[index]);
|
||||
}
|
||||
|
||||
mObjectRoot->setStateSet(writableStateSet);
|
||||
writableStateSet->removeUniform(mUniform);
|
||||
mResourceSystem->getSceneManager()->recreateShaders(mObjectRoot);
|
||||
mSpellGlowDuration = 0.f;
|
||||
}
|
||||
|
||||
void Animation::addGlow(osg::ref_ptr<osg::Node> node, osg::Vec4f glowColor, bool hasDuration)
|
||||
{
|
||||
std::vector<osg::ref_ptr<osg::Texture2D> > textures;
|
||||
for (int i=0; i<32; ++i)
|
||||
|
@ -1130,8 +1186,9 @@ namespace MWRender
|
|||
FindLowestUnusedTexUnitVisitor findLowestUnusedTexUnitVisitor;
|
||||
node->accept(findLowestUnusedTexUnitVisitor);
|
||||
int texUnit = findLowestUnusedTexUnitVisitor.mLowestUnusedTexUnit;
|
||||
osg::ref_ptr<GlowUpdater> glowupdater (new GlowUpdater(texUnit, glowColor, textures));
|
||||
node->addUpdateCallback(glowupdater);
|
||||
mGlowUpdater = new GlowUpdater(texUnit, glowColor, textures, hasDuration);
|
||||
//osg::ref_ptr<GlowUpdater> glowupdater (new GlowUpdater(texUnit, glowColor, textures));
|
||||
node->addUpdateCallback(mGlowUpdater);
|
||||
|
||||
// set a texture now so that the ShaderVisitor can find it
|
||||
osg::ref_ptr<osg::StateSet> writableStateSet = NULL;
|
||||
|
@ -1143,7 +1200,8 @@ namespace MWRender
|
|||
node->setStateSet(writableStateSet);
|
||||
}
|
||||
writableStateSet->setTextureAttributeAndModes(texUnit, textures.front(), osg::StateAttribute::ON);
|
||||
writableStateSet->addUniform(new osg::Uniform("envMapColor", glowColor));
|
||||
mUniform = new osg::Uniform("envMapColor", glowColor);
|
||||
writableStateSet->addUniform(mUniform);
|
||||
|
||||
mResourceSystem->getSceneManager()->recreateShaders(node);
|
||||
}
|
||||
|
|
|
@ -5,6 +5,11 @@
|
|||
|
||||
#include <components/sceneutil/controller.hpp>
|
||||
|
||||
namespace
|
||||
{
|
||||
class GlowUpdater;
|
||||
}
|
||||
|
||||
namespace ESM
|
||||
{
|
||||
struct Light;
|
||||
|
@ -263,6 +268,10 @@ protected:
|
|||
osg::ref_ptr<SceneUtil::LightSource> mGlowLight;
|
||||
|
||||
float mAlpha;
|
||||
float mSpellGlowDuration;
|
||||
|
||||
osg::ref_ptr<GlowUpdater> mGlowUpdater;
|
||||
osg::Uniform* mUniform;
|
||||
|
||||
const NodeMap& getNodeMap() const;
|
||||
|
||||
|
@ -317,7 +326,7 @@ protected:
|
|||
|
||||
osg::Vec4f getEnchantmentColor(const MWWorld::ConstPtr& item) const;
|
||||
|
||||
void addGlow(osg::ref_ptr<osg::Node> node, osg::Vec4f glowColor);
|
||||
void addGlow(osg::ref_ptr<osg::Node> node, osg::Vec4f glowColor, bool hasDuration = false);
|
||||
|
||||
/// Set the render bin for this animation's object root. May be customized by subclasses.
|
||||
virtual void setRenderBin();
|
||||
|
@ -351,6 +360,10 @@ public:
|
|||
void removeEffect (int effectId);
|
||||
void getLoopingEffects (std::vector<int>& out) const;
|
||||
|
||||
void addSpellCastGlow(osg::Vec4f glowColor);
|
||||
void updateSpellGlow(float duration);
|
||||
void removeSpellGlow();
|
||||
|
||||
virtual void updatePtr(const MWWorld::Ptr &ptr);
|
||||
|
||||
bool hasAnimation(const std::string &anim) const;
|
||||
|
|
Loading…
Reference in a new issue