1
0
Fork 1
mirror of https://github.com/TES3MP/openmw-tes3mp.git synced 2025-01-31 04:45:33 +00:00

Rename Animation::Group to Animation::BlendMask

The old naming is problematic, because the term group was being used for another feature (text key groups) already.
This commit is contained in:
scrawl 2015-07-09 18:47:11 +02:00
parent 355ef14d23
commit 335ef97cf5
4 changed files with 74 additions and 74 deletions

View file

@ -251,26 +251,26 @@ void CharacterController::refreshCurrentAnims(CharacterState idle, CharacterStat
{ {
mHitState = CharState_KnockOut; mHitState = CharState_KnockOut;
mCurrentHit = "knockout"; mCurrentHit = "knockout";
mAnimation->play(mCurrentHit, Priority_Knockdown, MWRender::Animation::Group_All, false, 1, "start", "stop", 0.0f, ~0ul); mAnimation->play(mCurrentHit, Priority_Knockdown, MWRender::Animation::BlendMask_All, false, 1, "start", "stop", 0.0f, ~0ul);
mPtr.getClass().getCreatureStats(mPtr).setKnockedDown(true); mPtr.getClass().getCreatureStats(mPtr).setKnockedDown(true);
} }
else if(knockdown) else if(knockdown)
{ {
mHitState = CharState_KnockDown; mHitState = CharState_KnockDown;
mCurrentHit = "knockdown"; mCurrentHit = "knockdown";
mAnimation->play(mCurrentHit, Priority_Knockdown, MWRender::Animation::Group_All, true, 1, "start", "stop", 0.0f, 0); mAnimation->play(mCurrentHit, Priority_Knockdown, MWRender::Animation::BlendMask_All, true, 1, "start", "stop", 0.0f, 0);
} }
else if (recovery) else if (recovery)
{ {
mHitState = CharState_Hit; mHitState = CharState_Hit;
mCurrentHit = chooseRandomGroup("hit"); mCurrentHit = chooseRandomGroup("hit");
mAnimation->play(mCurrentHit, Priority_Hit, MWRender::Animation::Group_All, true, 1, "start", "stop", 0.0f, 0); mAnimation->play(mCurrentHit, Priority_Hit, MWRender::Animation::BlendMask_All, true, 1, "start", "stop", 0.0f, 0);
} }
else if (block) else if (block)
{ {
mHitState = CharState_Block; mHitState = CharState_Block;
mCurrentHit = "shield"; mCurrentHit = "shield";
mAnimation->play(mCurrentHit, Priority_Hit, MWRender::Animation::Group_All, true, 1, "block start", "block stop", 0.0f, 0); mAnimation->play(mCurrentHit, Priority_Hit, MWRender::Animation::BlendMask_All, true, 1, "block start", "block stop", 0.0f, 0);
} }
// Cancel upper body animations // Cancel upper body animations
@ -303,7 +303,7 @@ void CharacterController::refreshCurrentAnims(CharacterState idle, CharacterStat
{ {
mHitState = CharState_KnockDown; mHitState = CharState_KnockDown;
mAnimation->disable(mCurrentHit); mAnimation->disable(mCurrentHit);
mAnimation->play(mCurrentHit, Priority_Knockdown, MWRender::Animation::Group_All, true, 1, "loop stop", "stop", 0.0f, 0); mAnimation->play(mCurrentHit, Priority_Knockdown, MWRender::Animation::BlendMask_All, true, 1, "loop stop", "stop", 0.0f, 0);
} }
} }
@ -314,7 +314,7 @@ void CharacterController::refreshCurrentAnims(CharacterState idle, CharacterStat
if(force && mJumpState != JumpState_None) if(force && mJumpState != JumpState_None)
{ {
std::string jump; std::string jump;
MWRender::Animation::Group jumpgroup = MWRender::Animation::Group_All; MWRender::Animation::BlendMask jumpmask = MWRender::Animation::BlendMask_All;
if(mJumpState != JumpState_None) if(mJumpState != JumpState_None)
{ {
jump = "jump"; jump = "jump";
@ -323,7 +323,7 @@ void CharacterController::refreshCurrentAnims(CharacterState idle, CharacterStat
jump += weap->shortgroup; jump += weap->shortgroup;
if(!mAnimation->hasAnimation(jump)) if(!mAnimation->hasAnimation(jump))
{ {
jumpgroup = MWRender::Animation::Group_LowerBody; jumpmask = MWRender::Animation::BlendMask_LowerBody;
jump = "jump"; jump = "jump";
} }
} }
@ -336,7 +336,7 @@ void CharacterController::refreshCurrentAnims(CharacterState idle, CharacterStat
mAnimation->disable(mCurrentJump); mAnimation->disable(mCurrentJump);
mCurrentJump = jump; mCurrentJump = jump;
if (mAnimation->hasAnimation("jump")) if (mAnimation->hasAnimation("jump"))
mAnimation->play(mCurrentJump, Priority_Jump, jumpgroup, false, mAnimation->play(mCurrentJump, Priority_Jump, jumpmask, false,
1.0f, ((mode!=2)?"start":"loop start"), "stop", 0.0f, ~0ul); 1.0f, ((mode!=2)?"start":"loop start"), "stop", 0.0f, ~0ul);
} }
else else
@ -344,7 +344,7 @@ void CharacterController::refreshCurrentAnims(CharacterState idle, CharacterStat
mAnimation->disable(mCurrentJump); mAnimation->disable(mCurrentJump);
mCurrentJump.clear(); mCurrentJump.clear();
if (mAnimation->hasAnimation("jump")) if (mAnimation->hasAnimation("jump"))
mAnimation->play(jump, Priority_Jump, jumpgroup, true, mAnimation->play(jump, Priority_Jump, jumpmask, true,
1.0f, "loop stop", "stop", 0.0f, 0); 1.0f, "loop stop", "stop", 0.0f, 0);
} }
} }
@ -354,7 +354,7 @@ void CharacterController::refreshCurrentAnims(CharacterState idle, CharacterStat
mMovementState = movement; mMovementState = movement;
std::string movement; std::string movement;
MWRender::Animation::Group movegroup = MWRender::Animation::Group_All; MWRender::Animation::BlendMask movemask = MWRender::Animation::BlendMask_All;
const StateInfo *movestate = std::find_if(sMovementList, sMovementListEnd, FindCharState(mMovementState)); const StateInfo *movestate = std::find_if(sMovementList, sMovementListEnd, FindCharState(mMovementState));
if(movestate != sMovementListEnd) if(movestate != sMovementListEnd)
{ {
@ -364,7 +364,7 @@ void CharacterController::refreshCurrentAnims(CharacterState idle, CharacterStat
movement += weap->shortgroup; movement += weap->shortgroup;
if(!mAnimation->hasAnimation(movement)) if(!mAnimation->hasAnimation(movement))
{ {
movegroup = MWRender::Animation::Group_LowerBody; movemask = MWRender::Animation::BlendMask_LowerBody;
movement = movestate->groupname; movement = movestate->groupname;
} }
} }
@ -386,7 +386,7 @@ void CharacterController::refreshCurrentAnims(CharacterState idle, CharacterStat
} }
else else
{ {
movegroup = MWRender::Animation::Group_LowerBody; movemask = MWRender::Animation::BlendMask_LowerBody;
movement.erase(swimpos, 4); movement.erase(swimpos, 4);
if(!mAnimation->hasAnimation(movement)) if(!mAnimation->hasAnimation(movement))
movement.clear(); movement.clear();
@ -447,7 +447,7 @@ void CharacterController::refreshCurrentAnims(CharacterState idle, CharacterStat
} }
} }
mAnimation->play(mCurrentMovement, Priority_Movement, movegroup, false, mAnimation->play(mCurrentMovement, Priority_Movement, movemask, false,
speedmult, ((mode!=2)?"start":"loop start"), "stop", 0.0f, ~0ul); speedmult, ((mode!=2)?"start":"loop start"), "stop", 0.0f, ~0ul);
} }
} }
@ -486,7 +486,7 @@ void CharacterController::refreshCurrentAnims(CharacterState idle, CharacterStat
mAnimation->disable(mCurrentIdle); mAnimation->disable(mCurrentIdle);
mCurrentIdle = idle; mCurrentIdle = idle;
if(!mCurrentIdle.empty()) if(!mCurrentIdle.empty())
mAnimation->play(mCurrentIdle, Priority_Default, MWRender::Animation::Group_All, false, mAnimation->play(mCurrentIdle, Priority_Default, MWRender::Animation::BlendMask_All, false,
1.0f, "start", "stop", 0.0f, ~0ul, true); 1.0f, "start", "stop", 0.0f, ~0ul, true);
} }
@ -602,7 +602,7 @@ void CharacterController::playDeath(float startpoint, CharacterState death)
mCurrentJump = ""; mCurrentJump = "";
mMovementAnimationControlled = true; mMovementAnimationControlled = true;
mAnimation->play(mCurrentDeath, Priority_Death, MWRender::Animation::Group_All, mAnimation->play(mCurrentDeath, Priority_Death, MWRender::Animation::BlendMask_All,
false, 1.0f, "start", "stop", startpoint, 0); false, 1.0f, "start", "stop", startpoint, 0);
} }
@ -868,10 +868,10 @@ void CharacterController::updateIdleStormState()
mAnimation->getInfo("idlestorm", &complete); mAnimation->getInfo("idlestorm", &complete);
if (complete == 0) if (complete == 0)
mAnimation->play("idlestorm", Priority_Storm, MWRender::Animation::Group_RightArm, false, mAnimation->play("idlestorm", Priority_Storm, MWRender::Animation::BlendMask_RightArm, false,
1.0f, "start", "loop start", 0.0f, 0); 1.0f, "start", "loop start", 0.0f, 0);
else if (complete == 1) else if (complete == 1)
mAnimation->play("idlestorm", Priority_Storm, MWRender::Animation::Group_RightArm, false, mAnimation->play("idlestorm", Priority_Storm, MWRender::Animation::BlendMask_RightArm, false,
1.0f, "loop start", "loop stop", 0.0f, ~0ul); 1.0f, "loop start", "loop stop", 0.0f, ~0ul);
} }
else else
@ -882,7 +882,7 @@ void CharacterController::updateIdleStormState()
{ {
if (mAnimation->getCurrentTime("idlestorm") < mAnimation->getTextKeyTime("idlestorm: loop stop")) if (mAnimation->getCurrentTime("idlestorm") < mAnimation->getTextKeyTime("idlestorm: loop stop"))
{ {
mAnimation->play("idlestorm", Priority_Storm, MWRender::Animation::Group_RightArm, true, mAnimation->play("idlestorm", Priority_Storm, MWRender::Animation::BlendMask_RightArm, true,
1.0f, "loop stop", "stop", 0.0f, 0); 1.0f, "loop stop", "stop", 0.0f, 0);
} }
} }
@ -989,7 +989,7 @@ bool CharacterController::updateCreatureState()
if (!mCurrentWeapon.empty()) if (!mCurrentWeapon.empty())
{ {
mAnimation->play(mCurrentWeapon, Priority_Weapon, mAnimation->play(mCurrentWeapon, Priority_Weapon,
MWRender::Animation::Group_All, true, MWRender::Animation::BlendMask_All, true,
1, startKey, stopKey, 1, startKey, stopKey,
0.0f, 0); 0.0f, 0);
mUpperBodyState = UpperCharState_StartToMinAttack; mUpperBodyState = UpperCharState_StartToMinAttack;
@ -1064,7 +1064,7 @@ bool CharacterController::updateWeaponState()
{ {
getWeaponGroup(mWeaponType, weapgroup); getWeaponGroup(mWeaponType, weapgroup);
mAnimation->play(weapgroup, Priority_Weapon, mAnimation->play(weapgroup, Priority_Weapon,
MWRender::Animation::Group_UpperBody, true, MWRender::Animation::BlendMask_UpperBody, 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;
} }
@ -1075,7 +1075,7 @@ bool CharacterController::updateWeaponState()
mAnimation->setWeaponGroup(weapgroup); mAnimation->setWeaponGroup(weapgroup);
mAnimation->play(weapgroup, Priority_Weapon, mAnimation->play(weapgroup, Priority_Weapon,
MWRender::Animation::Group_UpperBody, true, MWRender::Animation::BlendMask_UpperBody, 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;
@ -1192,7 +1192,7 @@ bool CharacterController::updateWeaponState()
} }
mAnimation->play(mCurrentWeapon, Priority_Weapon, mAnimation->play(mCurrentWeapon, Priority_Weapon,
MWRender::Animation::Group_UpperBody, true, MWRender::Animation::BlendMask_UpperBody, true,
weapSpeed, mAttackType+" start", mAttackType+" stop", weapSpeed, mAttackType+" start", mAttackType+" stop",
0.0f, 0); 0.0f, 0);
mUpperBodyState = UpperCharState_CastingSpell; mUpperBodyState = UpperCharState_CastingSpell;
@ -1224,7 +1224,7 @@ bool CharacterController::updateWeaponState()
Security(mPtr).probeTrap(target, item, resultMessage, resultSound); Security(mPtr).probeTrap(target, item, resultMessage, resultSound);
} }
mAnimation->play(mCurrentWeapon, Priority_Weapon, mAnimation->play(mCurrentWeapon, Priority_Weapon,
MWRender::Animation::Group_UpperBody, true, MWRender::Animation::BlendMask_UpperBody, true,
1.0f, "start", "stop", 0.0, 0); 1.0f, "start", "stop", 0.0, 0);
mUpperBodyState = UpperCharState_FollowStartToFollowStop; mUpperBodyState = UpperCharState_FollowStartToFollowStop;
@ -1251,7 +1251,7 @@ bool CharacterController::updateWeaponState()
} }
mAnimation->play(mCurrentWeapon, Priority_Weapon, mAnimation->play(mCurrentWeapon, Priority_Weapon,
MWRender::Animation::Group_UpperBody, false, MWRender::Animation::BlendMask_UpperBody, 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;
@ -1302,7 +1302,7 @@ bool CharacterController::updateWeaponState()
mAnimation->disable(mCurrentWeapon); mAnimation->disable(mCurrentWeapon);
mAnimation->play(mCurrentWeapon, Priority_Weapon, mAnimation->play(mCurrentWeapon, Priority_Weapon,
MWRender::Animation::Group_UpperBody, false, MWRender::Animation::BlendMask_UpperBody, false,
weapSpeed, mAttackType+" max attack", mAttackType+" min hit", weapSpeed, mAttackType+" max attack", mAttackType+" min hit",
1.0f-complete, 0); 1.0f-complete, 0);
@ -1374,7 +1374,7 @@ bool CharacterController::updateWeaponState()
//don't allow to continue playing hit animation on UpperBody after actor had attacked during it //don't allow to continue playing hit animation on UpperBody after actor had attacked during it
if(mHitState == CharState_Hit) if(mHitState == CharState_Hit)
{ {
mAnimation->changeGroups(mCurrentHit, MWRender::Animation::Group_LowerBody); mAnimation->changeBlendMask(mCurrentHit, MWRender::Animation::BlendMask_LowerBody);
//commenting out following 2 lines will give a bit different combat dynamics(slower) //commenting out following 2 lines will give a bit different combat dynamics(slower)
mHitState = CharState_None; mHitState = CharState_None;
mCurrentHit.clear(); mCurrentHit.clear();
@ -1398,7 +1398,7 @@ bool CharacterController::updateWeaponState()
//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, Priority_Weapon,
MWRender::Animation::Group_UpperBody, false, MWRender::Animation::BlendMask_UpperBody, 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:
@ -1441,11 +1441,11 @@ 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, Priority_Weapon,
MWRender::Animation::Group_UpperBody, true, MWRender::Animation::BlendMask_UpperBody, true,
weapSpeed, start, stop, 0.0f, 0); weapSpeed, start, stop, 0.0f, 0);
else else
mAnimation->play(mCurrentWeapon, Priority_Weapon, mAnimation->play(mCurrentWeapon, Priority_Weapon,
MWRender::Animation::Group_UpperBody, false, MWRender::Animation::BlendMask_UpperBody, false,
weapSpeed, start, stop, 0.0f, 0); weapSpeed, start, stop, 0.0f, 0);
} }
} }
@ -1459,11 +1459,11 @@ bool CharacterController::updateWeaponState()
MWBase::Environment::get().getWorld()->isSwimming(mPtr) || MWBase::Environment::get().getWorld()->isSwimming(mPtr) ||
cls.getCreatureStats(mPtr).getMovementFlag(CreatureStats::Flag_Sneak)) cls.getCreatureStats(mPtr).getMovementFlag(CreatureStats::Flag_Sneak))
{ {
mAnimation->changeGroups(mCurrentWeapon, MWRender::Animation::Group_UpperBody); mAnimation->changeBlendMask(mCurrentWeapon, MWRender::Animation::BlendMask_UpperBody);
} }
else else
{ {
mAnimation->changeGroups(mCurrentWeapon, MWRender::Animation::Group_All); mAnimation->changeBlendMask(mCurrentWeapon, MWRender::Animation::BlendMask_All);
} }
} }
@ -1475,7 +1475,7 @@ bool CharacterController::updateWeaponState()
&& updateCarriedLeftVisible(mWeaponType)) && updateCarriedLeftVisible(mWeaponType))
{ {
mAnimation->play("torch", Priority_Torch, MWRender::Animation::Group_LeftArm, mAnimation->play("torch", Priority_Torch, MWRender::Animation::BlendMask_LeftArm,
false, 1.0f, "start", "stop", 0.0f, (~(size_t)0), true); false, 1.0f, "start", "stop", 0.0f, (~(size_t)0), true);
} }
else if (mAnimation->isPlaying("torch")) else if (mAnimation->isPlaying("torch"))
@ -1505,7 +1505,7 @@ void CharacterController::update(float duration)
mAnimQueue.pop_front(); mAnimQueue.pop_front();
mAnimation->play(mAnimQueue.front().first, Priority_Default, mAnimation->play(mAnimQueue.front().first, Priority_Default,
MWRender::Animation::Group_All, false, MWRender::Animation::BlendMask_All, false,
1.0f, "start", "stop", 0.0f, mAnimQueue.front().second); 1.0f, "start", "stop", 0.0f, mAnimQueue.front().second);
} }
} }
@ -1786,7 +1786,7 @@ void CharacterController::update(float duration)
mAnimQueue.pop_front(); mAnimQueue.pop_front();
mAnimation->play(mAnimQueue.front().first, Priority_Default, mAnimation->play(mAnimQueue.front().first, Priority_Default,
MWRender::Animation::Group_All, false, MWRender::Animation::BlendMask_All, false,
1.0f, "start", "stop", 0.0f, mAnimQueue.front().second); 1.0f, "start", "stop", 0.0f, mAnimQueue.front().second);
} }
} }
@ -1894,7 +1894,7 @@ void CharacterController::playGroup(const std::string &groupname, int mode, int
mIdleState = CharState_SpecialIdle; mIdleState = CharState_SpecialIdle;
mAnimation->play(groupname, Priority_Default, mAnimation->play(groupname, Priority_Default,
MWRender::Animation::Group_All, false, 1.0f, MWRender::Animation::BlendMask_All, false, 1.0f,
((mode==2) ? "loop start" : "start"), "stop", 0.0f, count-1); ((mode==2) ? "loop start" : "start"), "stop", 0.0f, count-1);
} }
else if(mode == 0) else if(mode == 0)

View file

@ -219,7 +219,7 @@ namespace MWRender
typedef std::map<std::string, osg::ref_ptr<NifOsg::KeyframeController> > ControllerMap; typedef std::map<std::string, osg::ref_ptr<NifOsg::KeyframeController> > ControllerMap;
ControllerMap mControllerMap[Animation::sNumGroups]; ControllerMap mControllerMap[Animation::sNumBlendMasks];
const std::multimap<float, std::string>& getTextKeys(); const std::multimap<float, std::string>& getTextKeys();
}; };
@ -261,7 +261,7 @@ namespace MWRender
, mHeadYawRadians(0.f) , mHeadYawRadians(0.f)
, mHeadPitchRadians(0.f) , mHeadPitchRadians(0.f)
{ {
for(size_t i = 0;i < sNumGroups;i++) for(size_t i = 0;i < sNumBlendMasks;i++)
mAnimationTimePtr[i].reset(new AnimationTime); mAnimationTimePtr[i].reset(new AnimationTime);
} }
@ -299,9 +299,9 @@ namespace MWRender
mResetAccumRootCallback->setAccumulate(mAccumulate); mResetAccumRootCallback->setAccumulate(mAccumulate);
} }
size_t Animation::detectAnimGroup(osg::Node* node) size_t Animation::detectBlendMask(osg::Node* node)
{ {
static const char sGroupRoots[sNumGroups][32] = { static const char sBlendMaskRoots[sNumBlendMasks][32] = {
"", /* Lower body / character root */ "", /* Lower body / character root */
"Bip01 Spine1", /* Torso */ "Bip01 Spine1", /* Torso */
"Bip01 L Clavicle", /* Left arm */ "Bip01 L Clavicle", /* Left arm */
@ -311,9 +311,9 @@ namespace MWRender
while(node != mObjectRoot) while(node != mObjectRoot)
{ {
const std::string &name = node->getName(); const std::string &name = node->getName();
for(size_t i = 1;i < sNumGroups;i++) for(size_t i = 1;i < sNumBlendMasks;i++)
{ {
if(name == sGroupRoots[i]) if(name == sBlendMaskRoots[i])
return i; return i;
} }
@ -361,13 +361,13 @@ namespace MWRender
osg::Node* node = found->second; osg::Node* node = found->second;
size_t group = detectAnimGroup(node); size_t blendMask = detectBlendMask(node);
// clone the controller, because each Animation needs its own ControllerSource // clone the controller, because each Animation needs its own ControllerSource
osg::ref_ptr<NifOsg::KeyframeController> cloned = osg::clone(it->second.get(), osg::CopyOp::DEEP_COPY_ALL); osg::ref_ptr<NifOsg::KeyframeController> cloned = osg::clone(it->second.get(), osg::CopyOp::DEEP_COPY_ALL);
cloned->setSource(mAnimationTimePtr[group]); cloned->setSource(mAnimationTimePtr[blendMask]);
animsrc->mControllerMap[group].insert(std::make_pair(bonename, cloned)); animsrc->mControllerMap[blendMask].insert(std::make_pair(bonename, cloned));
} }
mAnimSources.push_back(animsrc); mAnimSources.push_back(animsrc);
@ -390,7 +390,7 @@ namespace MWRender
{ {
mStates.clear(); mStates.clear();
for(size_t i = 0;i < sNumGroups;i++) for(size_t i = 0;i < sNumBlendMasks;i++)
mAnimationTimePtr[i]->setTimePtr(boost::shared_ptr<float>()); mAnimationTimePtr[i]->setTimePtr(boost::shared_ptr<float>());
mAccumCtrl = NULL; mAccumCtrl = NULL;
@ -461,7 +461,7 @@ namespace MWRender
mTextKeyListener->handleTextKey(groupname, key, map); mTextKeyListener->handleTextKey(groupname, key, map);
} }
void Animation::play(const std::string &groupname, int priority, int groups, bool autodisable, float speedmult, void Animation::play(const std::string &groupname, int priority, int blendMask, bool autodisable, float speedmult,
const std::string &start, const std::string &stop, float startpoint, size_t loops, bool loopfallback) const std::string &start, const std::string &stop, float startpoint, size_t loops, bool loopfallback)
{ {
if(!mObjectRoot || mAnimSources.empty()) if(!mObjectRoot || mAnimSources.empty())
@ -505,7 +505,7 @@ namespace MWRender
state.mLoopCount = loops; state.mLoopCount = loops;
state.mPlaying = (state.getTime() < state.mStopTime); state.mPlaying = (state.getTime() < state.mStopTime);
state.mPriority = priority; state.mPriority = priority;
state.mGroups = groups; state.mBlendMask = blendMask;
state.mAutoDisable = autodisable; state.mAutoDisable = autodisable;
mStates[groupname] = state; mStates[groupname] = state;
@ -643,35 +643,35 @@ namespace MWRender
mAccumCtrl = NULL; mAccumCtrl = NULL;
for(size_t grp = 0;grp < sNumGroups;grp++) for(size_t blendMask = 0;blendMask < sNumBlendMasks;blendMask++)
{ {
AnimStateMap::const_iterator active = mStates.end(); AnimStateMap::const_iterator active = mStates.end();
AnimStateMap::const_iterator state = mStates.begin(); AnimStateMap::const_iterator state = mStates.begin();
for(;state != mStates.end();++state) for(;state != mStates.end();++state)
{ {
if(!(state->second.mGroups&(1<<grp))) if(!(state->second.mBlendMask&(1<<blendMask)))
continue; continue;
if(active == mStates.end() || active->second.mPriority < state->second.mPriority) if(active == mStates.end() || active->second.mPriority < state->second.mPriority)
active = state; active = state;
} }
mAnimationTimePtr[grp]->setTimePtr(active == mStates.end() ? boost::shared_ptr<float>() : active->second.mTime); mAnimationTimePtr[blendMask]->setTimePtr(active == mStates.end() ? boost::shared_ptr<float>() : active->second.mTime);
// add external controllers for the AnimSource active in this group // add external controllers for the AnimSource active in this blend mask
if (active != mStates.end()) if (active != mStates.end())
{ {
boost::shared_ptr<AnimSource> animsrc = active->second.mSource; boost::shared_ptr<AnimSource> animsrc = active->second.mSource;
for (AnimSource::ControllerMap::iterator it = animsrc->mControllerMap[grp].begin(); it != animsrc->mControllerMap[grp].end(); ++it) for (AnimSource::ControllerMap::iterator it = animsrc->mControllerMap[blendMask].begin(); it != animsrc->mControllerMap[blendMask].end(); ++it)
{ {
osg::ref_ptr<osg::Node> node = mNodeMap.at(it->first); // this should not throw, we already checked for the node existing in addAnimSource osg::ref_ptr<osg::Node> node = mNodeMap.at(it->first); // this should not throw, we already checked for the node existing in addAnimSource
node->addUpdateCallback(it->second); node->addUpdateCallback(it->second);
mActiveControllers.insert(std::make_pair(node, it->second)); mActiveControllers.insert(std::make_pair(node, it->second));
if (grp == 0 && node == mAccumRoot) if (blendMask == 0 && node == mAccumRoot)
{ {
mAccumCtrl = it->second; mAccumCtrl = it->second;
@ -690,14 +690,14 @@ namespace MWRender
addControllers(); addControllers();
} }
void Animation::changeGroups(const std::string &groupname, int groups) void Animation::changeBlendMask(const std::string &groupname, int mask)
{ {
AnimStateMap::iterator stateiter = mStates.find(groupname); AnimStateMap::iterator stateiter = mStates.find(groupname);
if(stateiter != mStates.end()) if(stateiter != mStates.end())
{ {
if(stateiter->second.mGroups != groups) if(stateiter->second.mBlendMask != mask)
{ {
stateiter->second.mGroups = groups; stateiter->second.mBlendMask = mask;
resetActiveGroups(); resetActiveGroups();
} }
return; return;

View file

@ -67,16 +67,16 @@ typedef boost::shared_ptr<PartHolder> PartHolderPtr;
class Animation class Animation
{ {
public: public:
enum Group { enum BlendMask {
Group_LowerBody = 1<<0, BlendMask_LowerBody = 1<<0,
Group_Torso = 1<<1, BlendMask_Torso = 1<<1,
Group_LeftArm = 1<<2, BlendMask_LeftArm = 1<<2,
Group_RightArm = 1<<3, BlendMask_RightArm = 1<<3,
Group_UpperBody = Group_Torso | Group_LeftArm | Group_RightArm, BlendMask_UpperBody = BlendMask_Torso | BlendMask_LeftArm | BlendMask_RightArm,
Group_All = Group_LowerBody | Group_UpperBody BlendMask_All = BlendMask_LowerBody | BlendMask_UpperBody
}; };
class TextKeyListener class TextKeyListener
@ -90,7 +90,7 @@ public:
protected: protected:
/* This is the number of *discrete* groups. */ /* This is the number of *discrete* groups. */
static const size_t sNumGroups = 4; static const size_t sNumBlendMasks = 4;
class AnimationTime : public SceneUtil::ControllerSource class AnimationTime : public SceneUtil::ControllerSource
{ {
@ -133,12 +133,12 @@ protected:
size_t mLoopCount; size_t mLoopCount;
int mPriority; int mPriority;
int mGroups; int mBlendMask;
bool mAutoDisable; bool mAutoDisable;
AnimState() : mStartTime(0.0f), mLoopStartTime(0.0f), mLoopStopTime(0.0f), mStopTime(0.0f), AnimState() : mStartTime(0.0f), mLoopStartTime(0.0f), mLoopStopTime(0.0f), mStopTime(0.0f),
mTime(new float), mSpeedMult(1.0f), mPlaying(false), mLoopCount(0), mTime(new float), mSpeedMult(1.0f), mPlaying(false), mLoopCount(0),
mPriority(0), mGroups(0), mAutoDisable(true) mPriority(0), mBlendMask(0), mAutoDisable(true)
{ {
} }
~AnimState(); ~AnimState();
@ -176,7 +176,7 @@ protected:
typedef std::multimap<osg::ref_ptr<osg::Node>, osg::ref_ptr<osg::NodeCallback> > ControllerMap; typedef std::multimap<osg::ref_ptr<osg::Node>, osg::ref_ptr<osg::NodeCallback> > ControllerMap;
ControllerMap mActiveControllers; ControllerMap mActiveControllers;
boost::shared_ptr<AnimationTime> mAnimationTimePtr[sNumGroups]; boost::shared_ptr<AnimationTime> mAnimationTimePtr[sNumBlendMasks];
// Stored in all lowercase for a case-insensitive lookup // Stored in all lowercase for a case-insensitive lookup
typedef std::map<std::string, osg::ref_ptr<osg::MatrixTransform> > NodeMap; typedef std::map<std::string, osg::ref_ptr<osg::MatrixTransform> > NodeMap;
@ -213,7 +213,7 @@ protected:
*/ */
void resetActiveGroups(); void resetActiveGroups();
size_t detectAnimGroup(osg::Node* node); size_t detectBlendMask(osg::Node* node);
/* Updates the position of the accum root node for the given time, and /* Updates the position of the accum root node for the given time, and
* returns the wanted movement vector from the previous time. */ * returns the wanted movement vector from the previous time. */
@ -304,7 +304,7 @@ public:
* \param priority Priority of the animation. The animation will play on * \param priority Priority of the animation. The animation will play on
* bone groups that don't have another animation set of a * bone groups that don't have another animation set of a
* higher priority. * higher priority.
* \param groups Bone groups to play the animation on. * \param blendMask Bone groups to play the animation on.
* \param autodisable Automatically disable the animation when it stops * \param autodisable Automatically disable the animation when it stops
* playing. * playing.
* \param speedmult Speed multiplier for the animation. * \param speedmult Speed multiplier for the animation.
@ -319,7 +319,7 @@ public:
* \param loopFallback Allow looping an animation that has no loop keys, i.e. fall back to use * \param loopFallback Allow looping an animation that has no loop keys, i.e. fall back to use
* the "start" and "stop" keys for looping? * the "start" and "stop" keys for looping?
*/ */
void play(const std::string &groupname, int priority, int groups, bool autodisable, void play(const std::string &groupname, int priority, int blendMask, bool autodisable,
float speedmult, const std::string &start, const std::string &stop, float speedmult, const std::string &start, const std::string &stop,
float startpoint, size_t loops, bool loopfallback=false); float startpoint, size_t loops, bool loopfallback=false);
@ -358,7 +358,7 @@ public:
* \param groupname Animation group to disable. * \param groupname Animation group to disable.
*/ */
void disable(const std::string &groupname); void disable(const std::string &groupname);
void changeGroups(const std::string &groupname, int group); void changeBlendMask(const std::string &groupname, int mask);
/** Retrieves the velocity (in units per second) that the animation will move. */ /** Retrieves the velocity (in units per second) that the animation will move. */
float getVelocity(const std::string &groupname) const; float getVelocity(const std::string &groupname) const;

View file

@ -241,13 +241,13 @@ namespace MWRender
mAnimation->showCarriedLeft(showCarriedLeft); mAnimation->showCarriedLeft(showCarriedLeft);
mCurrentAnimGroup = groupname; mCurrentAnimGroup = groupname;
mAnimation->play(mCurrentAnimGroup, 1, Animation::Group_All, false, 1.0f, "start", "stop", 0.0f, 0); mAnimation->play(mCurrentAnimGroup, 1, Animation::BlendMask_All, false, 1.0f, "start", "stop", 0.0f, 0);
MWWorld::ContainerStoreIterator torch = inv.getSlot(MWWorld::InventoryStore::Slot_CarriedLeft); MWWorld::ContainerStoreIterator torch = inv.getSlot(MWWorld::InventoryStore::Slot_CarriedLeft);
if(torch != inv.end() && torch->getTypeName() == typeid(ESM::Light).name() && showCarriedLeft) if(torch != inv.end() && torch->getTypeName() == typeid(ESM::Light).name() && showCarriedLeft)
{ {
if(!mAnimation->getInfo("torch")) if(!mAnimation->getInfo("torch"))
mAnimation->play("torch", 2, MWRender::Animation::Group_LeftArm, false, mAnimation->play("torch", 2, Animation::BlendMask_LeftArm, false,
1.0f, "start", "stop", 0.0f, ~0ul, true); 1.0f, "start", "stop", 0.0f, ~0ul, true);
} }
else if(mAnimation->getInfo("torch")) else if(mAnimation->getInfo("torch"))
@ -357,7 +357,7 @@ namespace MWRender
void RaceSelectionPreview::onSetup () void RaceSelectionPreview::onSetup ()
{ {
mAnimation->play("idle", 1, Animation::Group_All, false, 1.0f, "start", "stop", 0.0f, 0); mAnimation->play("idle", 1, Animation::BlendMask_All, false, 1.0f, "start", "stop", 0.0f, 0);
mAnimation->runAnimation(0.f); mAnimation->runAnimation(0.f);
// attach camera to follow the head node // attach camera to follow the head node