1
0
Fork 1
mirror of https://github.com/TES3MP/openmw-tes3mp.git synced 2025-01-16 21:19:55 +00:00

Merge remote-tracking branch 'scrawl/animation'

This commit is contained in:
Marc Zinnschlag 2015-09-17 09:24:11 +02:00
commit ed373aa320
7 changed files with 67 additions and 46 deletions

View file

@ -1094,7 +1094,7 @@ namespace MWMechanics
static float sneakTimer = 0.f; // times update of sneak icon static float sneakTimer = 0.f; // times update of sneak icon
// if player is in sneak state see if anyone detects him // if player is in sneak state see if anyone detects him
if (player.getClass().getCreatureStats(player).getMovementFlag(MWMechanics::CreatureStats::Flag_Sneak)) if (playerCharacter && playerCharacter->isSneaking())
{ {
static float sneakSkillTimer = 0.f; // times sneak skill progress from "avoid notice" static float sneakSkillTimer = 0.f; // times sneak skill progress from "avoid notice"

View file

@ -278,7 +278,7 @@ void CharacterController::refreshCurrentAnims(CharacterState idle, CharacterStat
mHitState = CharState_Block; mHitState = CharState_Block;
mCurrentHit = "shield"; mCurrentHit = "shield";
MWRender::Animation::AnimPriority priorityBlock (Priority_Hit); MWRender::Animation::AnimPriority priorityBlock (Priority_Hit);
priorityBlock.mPriority[MWRender::Animation::BoneGroup_LeftArm] = Priority_Block; priorityBlock[MWRender::Animation::BoneGroup_LeftArm] = Priority_Block;
mAnimation->play(mCurrentHit, priorityBlock, MWRender::Animation::BlendMask_All, true, 1, "block start", "block stop", 0.0f, 0); mAnimation->play(mCurrentHit, priorityBlock, MWRender::Animation::BlendMask_All, true, 1, "block start", "block stop", 0.0f, 0);
} }
@ -483,7 +483,10 @@ void CharacterController::refreshCurrentAnims(CharacterState idle, CharacterStat
idlePriority = Priority_SwimIdle; idlePriority = Priority_SwimIdle;
} }
else if(mIdleState == CharState_IdleSneak && mAnimation->hasAnimation("idlesneak")) else if(mIdleState == CharState_IdleSneak && mAnimation->hasAnimation("idlesneak"))
{
idle = "idlesneak"; idle = "idlesneak";
idlePriority[MWRender::Animation::BoneGroup_LowerBody] = Priority_SneakIdleLowerBody;
}
else if(mIdleState != CharState_None) else if(mIdleState != CharState_None)
{ {
idle = "idle"; idle = "idle";
@ -1063,7 +1066,7 @@ bool CharacterController::updateWeaponState()
} }
MWRender::Animation::AnimPriority priorityWeapon(Priority_Weapon); MWRender::Animation::AnimPriority priorityWeapon(Priority_Weapon);
priorityWeapon.mPriority[MWRender::Animation::BoneGroup_LowerBody] = Priority_WeaponLowerBody; priorityWeapon[MWRender::Animation::BoneGroup_LowerBody] = Priority_WeaponLowerBody;
bool forcestateupdate = false; bool forcestateupdate = false;
if(weaptype != mWeaponType && mHitState != CharState_KnockDown && mHitState != CharState_KnockOut if(weaptype != mWeaponType && mHitState != CharState_KnockDown && mHitState != CharState_KnockOut
@ -1768,7 +1771,7 @@ void CharacterController::update(float duration)
if(mAnimQueue.empty() || inwater || sneak) if(mAnimQueue.empty() || inwater || sneak)
{ {
idlestate = (inwater ? CharState_IdleSwim : (sneak ? CharState_IdleSneak : CharState_Idle)); idlestate = (inwater ? CharState_IdleSwim : (sneak && !inJump ? CharState_IdleSneak : CharState_Idle));
} }
else if(mAnimQueue.size() > 1) else if(mAnimQueue.size() > 1)
{ {
@ -2048,6 +2051,15 @@ bool CharacterController::isKnockedOut() const
return mHitState == CharState_KnockOut; return mHitState == CharState_KnockOut;
} }
bool CharacterController::isSneaking() const
{
return mIdleState == CharState_IdleSneak ||
mMovementState == CharState_SneakForward ||
mMovementState == CharState_SneakBack ||
mMovementState == CharState_SneakLeft ||
mMovementState == CharState_SneakRight;
}
void CharacterController::setAttackingOrSpell(bool attackingOrSpell) void CharacterController::setAttackingOrSpell(bool attackingOrSpell)
{ {
mAttackingOrSpell = attackingOrSpell; mAttackingOrSpell = attackingOrSpell;

View file

@ -29,6 +29,7 @@ class CreatureStats;
enum Priority { enum Priority {
Priority_Default, Priority_Default,
Priority_WeaponLowerBody, Priority_WeaponLowerBody,
Priority_SneakIdleLowerBody,
Priority_SwimIdle, Priority_SwimIdle,
Priority_Jump, Priority_Jump,
Priority_Movement, Priority_Movement,
@ -241,6 +242,7 @@ public:
bool isReadyToBlock() const; bool isReadyToBlock() const;
bool isKnockedOut() const; bool isKnockedOut() const;
bool isSneaking() const;
void setAttackingOrSpell(bool attackingOrSpell); void setAttackingOrSpell(bool attackingOrSpell);

View file

@ -9,6 +9,8 @@
#include <osg/ComputeBoundsVisitor> #include <osg/ComputeBoundsVisitor>
#include <osg/MatrixTransform> #include <osg/MatrixTransform>
#include <osg/Geode> #include <osg/Geode>
#include <osg/BlendFunc>
#include <osg/Material>
#include <osgParticle/ParticleSystem> #include <osgParticle/ParticleSystem>
@ -292,6 +294,7 @@ namespace MWRender
, mTextKeyListener(NULL) , mTextKeyListener(NULL)
, mHeadYawRadians(0.f) , mHeadYawRadians(0.f)
, mHeadPitchRadians(0.f) , mHeadPitchRadians(0.f)
, mAlpha(1.f)
{ {
for(size_t i = 0;i < sNumBlendMasks;i++) for(size_t i = 0;i < sNumBlendMasks;i++)
mAnimationTimePtr[i].reset(new AnimationTime); mAnimationTimePtr[i].reset(new AnimationTime);
@ -680,7 +683,7 @@ namespace MWRender
if(!(state->second.mBlendMask&(1<<blendMask))) if(!(state->second.mBlendMask&(1<<blendMask)))
continue; continue;
if(active == mStates.end() || active->second.mPriority.mPriority[blendMask] < state->second.mPriority.mPriority[blendMask]) if(active == mStates.end() || active->second.mPriority[(BoneGroup)blendMask] < state->second.mPriority[(BoneGroup)blendMask])
active = state; active = state;
} }
@ -1247,6 +1250,37 @@ namespace MWRender
return found->second; return found->second;
} }
void Animation::setAlpha(float alpha)
{
if (alpha == mAlpha)
return;
mAlpha = alpha;
if (alpha != 1.f)
{
osg::StateSet* stateset (new osg::StateSet);
osg::BlendFunc* blendfunc (new osg::BlendFunc);
stateset->setAttributeAndModes(blendfunc, osg::StateAttribute::ON|osg::StateAttribute::OVERRIDE);
// FIXME: overriding diffuse/ambient/emissive colors
osg::Material* material (new osg::Material);
material->setColorMode(osg::Material::OFF);
material->setDiffuse(osg::Material::FRONT_AND_BACK, osg::Vec4f(1,1,1,alpha));
material->setAmbient(osg::Material::FRONT_AND_BACK, osg::Vec4f(1,1,1,1));
stateset->setAttributeAndModes(material, osg::StateAttribute::ON|osg::StateAttribute::OVERRIDE);
stateset->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
stateset->setRenderBinMode(osg::StateSet::OVERRIDE_RENDERBIN_DETAILS);
stateset->setNestRenderBins(false);
mObjectRoot->setStateSet(stateset);
}
else
{
mObjectRoot->setStateSet(NULL);
}
}
void Animation::setLightEffect(float effect) void Animation::setLightEffect(float effect)
{ {
if (effect == 0) if (effect == 0)

View file

@ -105,6 +105,16 @@ public:
return true; return true;
} }
int& operator[] (BoneGroup n)
{
return mPriority[n];
}
const int& operator[] (BoneGroup n) const
{
return mPriority[n];
}
bool contains(int priority) const bool contains(int priority) const
{ {
for (unsigned int i=0; i<sNumBlendMasks; ++i) for (unsigned int i=0; i<sNumBlendMasks; ++i)
@ -243,6 +253,8 @@ protected:
osg::ref_ptr<SceneUtil::LightSource> mGlowLight; osg::ref_ptr<SceneUtil::LightSource> mGlowLight;
float mAlpha;
/* Sets the appropriate animations on the bone groups based on priority. /* Sets the appropriate animations on the bone groups based on priority.
*/ */
void resetActiveGroups(); void resetActiveGroups();
@ -409,7 +421,8 @@ public:
virtual void showCarriedLeft(bool show) {} virtual void showCarriedLeft(bool show) {}
virtual void setWeaponGroup(const std::string& group) {} virtual void setWeaponGroup(const std::string& group) {}
virtual void setVampire(bool vampire) {} virtual void setVampire(bool vampire) {}
virtual void setAlpha(float alpha) {} /// A value < 1 makes the animation translucent, 1.f = fully opaque
void setAlpha(float alpha);
virtual void setPitchFactor(float factor) {} virtual void setPitchFactor(float factor) {}
virtual void attachArrow() {} virtual void attachArrow() {}
virtual void releaseArrow(float attackStrength) {} virtual void releaseArrow(float attackStrength) {}

View file

@ -2,8 +2,6 @@
#include <osg/UserDataContainer> #include <osg/UserDataContainer>
#include <osg/MatrixTransform> #include <osg/MatrixTransform>
#include <osg/BlendFunc>
#include <osg/Material>
#include <components/misc/rng.hpp> #include <components/misc/rng.hpp>
@ -278,7 +276,6 @@ NpcAnimation::NpcAnimation(const MWWorld::Ptr& ptr, osg::ref_ptr<osg::Group> par
mShowWeapons(false), mShowWeapons(false),
mShowCarriedLeft(true), mShowCarriedLeft(true),
mNpcType(Type_Normal), mNpcType(Type_Normal),
mAlpha(1.f),
mSoundsDisabled(disableSounds) mSoundsDisabled(disableSounds)
{ {
mNpc = mPtr.get<ESM::NPC>()->mBase; mNpc = mPtr.get<ESM::NPC>()->mBase;
@ -422,7 +419,6 @@ void NpcAnimation::updateParts()
if (!mObjectRoot.get()) if (!mObjectRoot.get())
return; return;
mAlpha = 1.f;
const MWWorld::Class &cls = mPtr.getClass(); const MWWorld::Class &cls = mPtr.getClass();
NpcType curType = Type_Normal; NpcType curType = Type_Normal;
@ -902,7 +898,6 @@ void NpcAnimation::showWeapons(bool showWeapon)
{ {
removeIndividualPart(ESM::PRT_Weapon); removeIndividualPart(ESM::PRT_Weapon);
} }
mAlpha = 1.f;
} }
void NpcAnimation::showCarriedLeft(bool show) void NpcAnimation::showCarriedLeft(bool show)
@ -988,37 +983,6 @@ void NpcAnimation::permanentEffectAdded(const ESM::MagicEffect *magicEffect, boo
} }
} }
void NpcAnimation::setAlpha(float alpha)
{
if (alpha == mAlpha)
return;
mAlpha = alpha;
if (alpha != 1.f)
{
osg::StateSet* stateset (new osg::StateSet);
osg::BlendFunc* blendfunc (new osg::BlendFunc);
stateset->setAttributeAndModes(blendfunc, osg::StateAttribute::ON|osg::StateAttribute::OVERRIDE);
// FIXME: overriding diffuse/ambient/emissive colors
osg::Material* material (new osg::Material);
material->setColorMode(osg::Material::OFF);
material->setDiffuse(osg::Material::FRONT_AND_BACK, osg::Vec4f(1,1,1,alpha));
material->setAmbient(osg::Material::FRONT_AND_BACK, osg::Vec4f(1,1,1,1));
stateset->setAttributeAndModes(material, osg::StateAttribute::ON|osg::StateAttribute::OVERRIDE);
stateset->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
stateset->setRenderBinMode(osg::StateSet::OVERRIDE_RENDERBIN_DETAILS);
stateset->setNestRenderBins(false);
mObjectRoot->setStateSet(stateset);
}
else
{
mObjectRoot->setStateSet(NULL);
}
}
void NpcAnimation::enableHeadAnimation(bool enable) void NpcAnimation::enableHeadAnimation(bool enable)
{ {
mHeadAnimationTime->setEnabled(enable); mHeadAnimationTime->setEnabled(enable);

View file

@ -65,7 +65,6 @@ private:
boost::shared_ptr<HeadAnimationTime> mHeadAnimationTime; boost::shared_ptr<HeadAnimationTime> mHeadAnimationTime;
boost::shared_ptr<WeaponAnimationTime> mWeaponAnimationTime; boost::shared_ptr<WeaponAnimationTime> mWeaponAnimationTime;
float mAlpha;
bool mSoundsDisabled; bool mSoundsDisabled;
void updateNpcBase(); void updateNpcBase();
@ -134,9 +133,6 @@ public:
/// Get the inventory slot that the given node path leads into, or -1 if not found. /// Get the inventory slot that the given node path leads into, or -1 if not found.
int getSlot(const osg::NodePath& path) const; int getSlot(const osg::NodePath& path) const;
/// Make the NPC only partially visible
virtual void setAlpha(float alpha);
virtual void setVampire(bool vampire); virtual void setVampire(bool vampire);
/// Set a translation offset (in object root space) to apply to meshes when in first person mode. /// Set a translation offset (in object root space) to apply to meshes when in first person mode.