mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-01-30 22:15:32 +00:00
Use the extended animation priority for weapon animations
This commit is contained in:
parent
e93a578f23
commit
50db6ed396
2 changed files with 66 additions and 75 deletions
|
@ -1051,6 +1051,9 @@ bool CharacterController::updateWeaponState()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MWRender::Animation::AnimPriority priorityWeapon(Priority_Weapon);
|
||||||
|
priorityWeapon.mPriority[MWRender::Animation::BoneGroup_LowerBody] = 0;
|
||||||
|
|
||||||
bool forcestateupdate = false;
|
bool forcestateupdate = false;
|
||||||
if(weaptype != mWeaponType && mHitState != CharState_KnockDown && mHitState != CharState_KnockOut
|
if(weaptype != mWeaponType && mHitState != CharState_KnockDown && mHitState != CharState_KnockOut
|
||||||
&& mHitState != CharState_Hit)
|
&& mHitState != CharState_Hit)
|
||||||
|
@ -1063,8 +1066,8 @@ bool CharacterController::updateWeaponState()
|
||||||
if(weaptype == WeapType_None)
|
if(weaptype == WeapType_None)
|
||||||
{
|
{
|
||||||
getWeaponGroup(mWeaponType, weapgroup);
|
getWeaponGroup(mWeaponType, weapgroup);
|
||||||
mAnimation->play(weapgroup, Priority_Weapon,
|
mAnimation->play(weapgroup, priorityWeapon,
|
||||||
MWRender::Animation::BlendMask_UpperBody, true,
|
MWRender::Animation::BlendMask_All, true,
|
||||||
1.0f, "unequip start", "unequip stop", 0.0f, 0);
|
1.0f, "unequip start", "unequip stop", 0.0f, 0);
|
||||||
mUpperBodyState = UpperCharState_UnEquipingWeap;
|
mUpperBodyState = UpperCharState_UnEquipingWeap;
|
||||||
}
|
}
|
||||||
|
@ -1074,8 +1077,8 @@ bool CharacterController::updateWeaponState()
|
||||||
mAnimation->showWeapons(false);
|
mAnimation->showWeapons(false);
|
||||||
mAnimation->setWeaponGroup(weapgroup);
|
mAnimation->setWeaponGroup(weapgroup);
|
||||||
|
|
||||||
mAnimation->play(weapgroup, Priority_Weapon,
|
mAnimation->play(weapgroup, priorityWeapon,
|
||||||
MWRender::Animation::BlendMask_UpperBody, true,
|
MWRender::Animation::BlendMask_All, true,
|
||||||
1.0f, "equip start", "equip stop", 0.0f, 0);
|
1.0f, "equip start", "equip stop", 0.0f, 0);
|
||||||
mUpperBodyState = UpperCharState_EquipingWeap;
|
mUpperBodyState = UpperCharState_EquipingWeap;
|
||||||
|
|
||||||
|
@ -1191,8 +1194,8 @@ bool CharacterController::updateWeaponState()
|
||||||
case 2: mAttackType = "target"; break;
|
case 2: mAttackType = "target"; break;
|
||||||
}
|
}
|
||||||
|
|
||||||
mAnimation->play(mCurrentWeapon, Priority_Weapon,
|
mAnimation->play(mCurrentWeapon, priorityWeapon,
|
||||||
MWRender::Animation::BlendMask_UpperBody, true,
|
MWRender::Animation::BlendMask_All, true,
|
||||||
weapSpeed, mAttackType+" start", mAttackType+" stop",
|
weapSpeed, mAttackType+" start", mAttackType+" stop",
|
||||||
0.0f, 0);
|
0.0f, 0);
|
||||||
mUpperBodyState = UpperCharState_CastingSpell;
|
mUpperBodyState = UpperCharState_CastingSpell;
|
||||||
|
@ -1223,8 +1226,8 @@ bool CharacterController::updateWeaponState()
|
||||||
else if(item.getTypeName() == typeid(ESM::Probe).name())
|
else if(item.getTypeName() == typeid(ESM::Probe).name())
|
||||||
Security(mPtr).probeTrap(target, item, resultMessage, resultSound);
|
Security(mPtr).probeTrap(target, item, resultMessage, resultSound);
|
||||||
}
|
}
|
||||||
mAnimation->play(mCurrentWeapon, Priority_Weapon,
|
mAnimation->play(mCurrentWeapon, priorityWeapon,
|
||||||
MWRender::Animation::BlendMask_UpperBody, true,
|
MWRender::Animation::BlendMask_All, true,
|
||||||
1.0f, "start", "stop", 0.0, 0);
|
1.0f, "start", "stop", 0.0, 0);
|
||||||
mUpperBodyState = UpperCharState_FollowStartToFollowStop;
|
mUpperBodyState = UpperCharState_FollowStartToFollowStop;
|
||||||
|
|
||||||
|
@ -1250,8 +1253,8 @@ bool CharacterController::updateWeaponState()
|
||||||
determineAttackType();
|
determineAttackType();
|
||||||
}
|
}
|
||||||
|
|
||||||
mAnimation->play(mCurrentWeapon, Priority_Weapon,
|
mAnimation->play(mCurrentWeapon, priorityWeapon,
|
||||||
MWRender::Animation::BlendMask_UpperBody, false,
|
MWRender::Animation::BlendMask_All, false,
|
||||||
weapSpeed, mAttackType+" start", mAttackType+" min attack",
|
weapSpeed, mAttackType+" start", mAttackType+" min attack",
|
||||||
0.0f, 0);
|
0.0f, 0);
|
||||||
mUpperBodyState = UpperCharState_StartToMinAttack;
|
mUpperBodyState = UpperCharState_StartToMinAttack;
|
||||||
|
@ -1301,8 +1304,8 @@ bool CharacterController::updateWeaponState()
|
||||||
mAttackStrength = attackStrength;
|
mAttackStrength = attackStrength;
|
||||||
|
|
||||||
mAnimation->disable(mCurrentWeapon);
|
mAnimation->disable(mCurrentWeapon);
|
||||||
mAnimation->play(mCurrentWeapon, Priority_Weapon,
|
mAnimation->play(mCurrentWeapon, priorityWeapon,
|
||||||
MWRender::Animation::BlendMask_UpperBody, false,
|
MWRender::Animation::BlendMask_All, false,
|
||||||
weapSpeed, mAttackType+" max attack", mAttackType+" min hit",
|
weapSpeed, mAttackType+" max attack", mAttackType+" min hit",
|
||||||
1.0f-complete, 0);
|
1.0f-complete, 0);
|
||||||
|
|
||||||
|
@ -1397,8 +1400,8 @@ bool CharacterController::updateWeaponState()
|
||||||
case UpperCharState_MinAttackToMaxAttack:
|
case UpperCharState_MinAttackToMaxAttack:
|
||||||
//hack to avoid body pos desync when jumping/sneaking in 'max attack' state
|
//hack to avoid body pos desync when jumping/sneaking in 'max attack' state
|
||||||
if(!mAnimation->isPlaying(mCurrentWeapon))
|
if(!mAnimation->isPlaying(mCurrentWeapon))
|
||||||
mAnimation->play(mCurrentWeapon, Priority_Weapon,
|
mAnimation->play(mCurrentWeapon, priorityWeapon,
|
||||||
MWRender::Animation::BlendMask_UpperBody, false,
|
MWRender::Animation::BlendMask_All, false,
|
||||||
0, mAttackType+" min attack", mAttackType+" max attack", 0.999f, 0);
|
0, mAttackType+" min attack", mAttackType+" max attack", 0.999f, 0);
|
||||||
break;
|
break;
|
||||||
case UpperCharState_MaxAttackToMinHit:
|
case UpperCharState_MaxAttackToMinHit:
|
||||||
|
@ -1440,33 +1443,16 @@ bool CharacterController::updateWeaponState()
|
||||||
{
|
{
|
||||||
mAnimation->disable(mCurrentWeapon);
|
mAnimation->disable(mCurrentWeapon);
|
||||||
if (mUpperBodyState == UpperCharState_FollowStartToFollowStop)
|
if (mUpperBodyState == UpperCharState_FollowStartToFollowStop)
|
||||||
mAnimation->play(mCurrentWeapon, Priority_Weapon,
|
mAnimation->play(mCurrentWeapon, priorityWeapon,
|
||||||
MWRender::Animation::BlendMask_UpperBody, true,
|
MWRender::Animation::BlendMask_All, true,
|
||||||
weapSpeed, start, stop, 0.0f, 0);
|
weapSpeed, start, stop, 0.0f, 0);
|
||||||
else
|
else
|
||||||
mAnimation->play(mCurrentWeapon, Priority_Weapon,
|
mAnimation->play(mCurrentWeapon, priorityWeapon,
|
||||||
MWRender::Animation::BlendMask_UpperBody, false,
|
MWRender::Animation::BlendMask_All, false,
|
||||||
weapSpeed, start, stop, 0.0f, 0);
|
weapSpeed, start, stop, 0.0f, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//if playing combat animation and lowerbody is not busy switch to whole body animation
|
|
||||||
if((weaptype != WeapType_None || mUpperBodyState == UpperCharState_UnEquipingWeap) && animPlaying)
|
|
||||||
{
|
|
||||||
if( mMovementState != CharState_None ||
|
|
||||||
mJumpState != JumpState_None ||
|
|
||||||
mHitState != CharState_None ||
|
|
||||||
MWBase::Environment::get().getWorld()->isSwimming(mPtr) ||
|
|
||||||
cls.getCreatureStats(mPtr).getMovementFlag(CreatureStats::Flag_Sneak))
|
|
||||||
{
|
|
||||||
mAnimation->changeBlendMask(mCurrentWeapon, MWRender::Animation::BlendMask_UpperBody);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
mAnimation->changeBlendMask(mCurrentWeapon, MWRender::Animation::BlendMask_All);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mPtr.getClass().hasInventoryStore(mPtr))
|
if (mPtr.getClass().hasInventoryStore(mPtr))
|
||||||
{
|
{
|
||||||
MWWorld::InventoryStore& inv = mPtr.getClass().getInventoryStore(mPtr);
|
MWWorld::InventoryStore& inv = mPtr.getClass().getInventoryStore(mPtr);
|
||||||
|
|
|
@ -67,9 +67,15 @@ typedef boost::shared_ptr<PartHolder> PartHolderPtr;
|
||||||
class Animation
|
class Animation
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
enum BoneGroup {
|
||||||
|
BoneGroup_LowerBody = 0,
|
||||||
|
BoneGroup_Torso,
|
||||||
|
BoneGroup_LeftArm,
|
||||||
|
BoneGroup_RightArm
|
||||||
|
};
|
||||||
|
|
||||||
enum BlendMask {
|
enum BlendMask {
|
||||||
BlendMask_LowerBody = 1<<0,
|
BlendMask_LowerBody = 1<<0,
|
||||||
|
|
||||||
BlendMask_Torso = 1<<1,
|
BlendMask_Torso = 1<<1,
|
||||||
BlendMask_LeftArm = 1<<2,
|
BlendMask_LeftArm = 1<<2,
|
||||||
BlendMask_RightArm = 1<<3,
|
BlendMask_RightArm = 1<<3,
|
||||||
|
@ -78,47 +84,10 @@ public:
|
||||||
|
|
||||||
BlendMask_All = BlendMask_LowerBody | BlendMask_UpperBody
|
BlendMask_All = BlendMask_LowerBody | BlendMask_UpperBody
|
||||||
};
|
};
|
||||||
|
/* This is the number of *discrete* blend masks. */
|
||||||
class TextKeyListener
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
virtual void handleTextKey(const std::string &groupname, const std::multimap<float, std::string>::const_iterator &key,
|
|
||||||
const std::multimap<float, std::string>& map) = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
void setTextKeyListener(TextKeyListener* listener);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
/* This is the number of *discrete* groups. */
|
|
||||||
static const size_t sNumBlendMasks = 4;
|
static const size_t sNumBlendMasks = 4;
|
||||||
|
|
||||||
class AnimationTime : public SceneUtil::ControllerSource
|
/// Holds an animation priority value for each BoneGroup.
|
||||||
{
|
|
||||||
private:
|
|
||||||
boost::shared_ptr<float> mTimePtr;
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
void setTimePtr(boost::shared_ptr<float> time)
|
|
||||||
{ mTimePtr = time; }
|
|
||||||
boost::shared_ptr<float> getTimePtr() const
|
|
||||||
{ return mTimePtr; }
|
|
||||||
|
|
||||||
virtual float getValue(osg::NodeVisitor* nv);
|
|
||||||
};
|
|
||||||
|
|
||||||
class NullAnimationTime : public SceneUtil::ControllerSource
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
virtual float getValue(osg::NodeVisitor *nv)
|
|
||||||
{
|
|
||||||
return 0.f;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct AnimSource;
|
|
||||||
|
|
||||||
/// Holds an animation priority value for each distinct bone blendmask.
|
|
||||||
struct AnimPriority
|
struct AnimPriority
|
||||||
{
|
{
|
||||||
/// Convenience constructor, initialises all priorities to the same value.
|
/// Convenience constructor, initialises all priorities to the same value.
|
||||||
|
@ -147,6 +116,42 @@ protected:
|
||||||
int mPriority[sNumBlendMasks];
|
int mPriority[sNumBlendMasks];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class TextKeyListener
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual void handleTextKey(const std::string &groupname, const std::multimap<float, std::string>::const_iterator &key,
|
||||||
|
const std::multimap<float, std::string>& map) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
void setTextKeyListener(TextKeyListener* listener);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
class AnimationTime : public SceneUtil::ControllerSource
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
boost::shared_ptr<float> mTimePtr;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
void setTimePtr(boost::shared_ptr<float> time)
|
||||||
|
{ mTimePtr = time; }
|
||||||
|
boost::shared_ptr<float> getTimePtr() const
|
||||||
|
{ return mTimePtr; }
|
||||||
|
|
||||||
|
virtual float getValue(osg::NodeVisitor* nv);
|
||||||
|
};
|
||||||
|
|
||||||
|
class NullAnimationTime : public SceneUtil::ControllerSource
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual float getValue(osg::NodeVisitor *nv)
|
||||||
|
{
|
||||||
|
return 0.f;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct AnimSource;
|
||||||
|
|
||||||
struct AnimState {
|
struct AnimState {
|
||||||
boost::shared_ptr<AnimSource> mSource;
|
boost::shared_ptr<AnimSource> mSource;
|
||||||
float mStartTime;
|
float mStartTime;
|
||||||
|
|
Loading…
Reference in a new issue