Feature #50: Handle weapon controllers (i.e. bowstring animations, etc)

actorid
scrawl 11 years ago
parent 975f0e05b4
commit 7cf22391a5

@ -547,6 +547,7 @@ bool CharacterController::updateWeaponState()
{
getWeaponGroup(weaptype, weapgroup);
mAnimation->showWeapons(false);
mAnimation->setWeaponGroup(weapgroup);
mAnimation->play(weapgroup, Priority_Weapon,
MWRender::Animation::Group_UpperBody, true,

@ -870,6 +870,27 @@ bool Animation::getInfo(const std::string &groupname, float *complete, float *sp
return true;
}
float Animation::getStartTime(const std::string &groupname) const
{
AnimSourceList::const_iterator iter(mAnimSources.begin());
for(;iter != mAnimSources.end();iter++)
{
const NifOgre::TextKeyMap &keys = (*iter)->mTextKeys;
NifOgre::TextKeyMap::const_iterator found = findGroupStart(keys, groupname);
if(found != keys.end())
return found->first;
}
return -1.f;
}
float Animation::getCurrentTime(const std::string &groupname) const
{
AnimStateMap::const_iterator iter = mStates.find(groupname);
if(iter == mStates.end())
return -1.f;
return iter->second.mTime;
}
void Animation::disable(const std::string &groupname)
{

@ -271,12 +271,20 @@ public:
*/
bool getInfo(const std::string &groupname, float *complete=NULL, float *speedmult=NULL) const;
/// Get the absolute position in the animation track of the first text key with the given group.
float getStartTime(const std::string &groupname) const;
/// Get the current absolute position in the animation track for the animation that is currently playing from the given group.
float getCurrentTime(const std::string& groupname) const;
/** Disables the specified animation group;
* \param groupname Animation group to disable.
*/
void disable(const std::string &groupname);
void changeGroups(const std::string &groupname, int group);
virtual void setWeaponGroup(const std::string& group) {}
/** Retrieves the velocity (in units per second) that the animation will move. */
float getVelocity(const std::string &groupname) const;

@ -71,6 +71,27 @@ float HeadAnimationTime::getValue() const
return 1;
}
float WeaponAnimationTime::getValue() const
{
if (mWeaponGroup.empty())
return 0;
float current = mAnimation->getCurrentTime(mWeaponGroup);
if (current == -1)
return 0;
return current - mStartTime;
}
void WeaponAnimationTime::setGroup(const std::string &group)
{
mWeaponGroup = group;
mStartTime = mAnimation->getStartTime(mWeaponGroup);
}
void WeaponAnimationTime::updateStartTime()
{
setGroup(mWeaponGroup);
}
static NpcAnimation::PartBoneMap createPartListMap()
{
NpcAnimation::PartBoneMap result;
@ -126,6 +147,7 @@ NpcAnimation::NpcAnimation(const MWWorld::Ptr& ptr, Ogre::SceneNode* node, int v
mNpc = mPtr.get<ESM::NPC>()->mBase;
mHeadAnimationTime = Ogre::SharedPtr<HeadAnimationTime>(new HeadAnimationTime(mPtr));
mWeaponAnimationTime = Ogre::SharedPtr<WeaponAnimationTime>(new WeaponAnimationTime(this));
for(size_t i = 0;i < ESM::PRT_Count;i++)
{
@ -223,6 +245,8 @@ void NpcAnimation::updateNpcBase()
for(size_t i = 0;i < ESM::PRT_Count;i++)
removeIndividualPart((ESM::PartReferenceType)i);
updateParts();
mWeaponAnimationTime->updateStartTime();
}
void NpcAnimation::updateParts()
@ -588,9 +612,6 @@ bool NpcAnimation::addOrReplaceIndividualPart(ESM::PartReferenceType type, int g
updateSkeletonInstance(mSkelBase->getSkeleton(), skel);
}
// TODO:
// type == ESM::PRT_Weapon should get an animation source based on the current offset
// of the weapon attack animation (from its beginning, or start marker?)
std::vector<Ogre::Controller<Ogre::Real> >::iterator ctrl(mObjectParts[type]->mControllers.begin());
for(;ctrl != mObjectParts[type]->mControllers.end();ctrl++)
{
@ -600,6 +621,8 @@ bool NpcAnimation::addOrReplaceIndividualPart(ESM::PartReferenceType type, int g
if (type == ESM::PRT_Head)
ctrl->setSource(mHeadAnimationTime);
else if (type == ESM::PRT_Weapon)
ctrl->setSource(mWeaponAnimationTime);
}
}

@ -25,6 +25,23 @@ public:
{ }
};
class WeaponAnimationTime : public Ogre::ControllerValue<Ogre::Real>
{
private:
Animation* mAnimation;
std::string mWeaponGroup;
float mStartTime;
public:
WeaponAnimationTime(Animation* animation) : mAnimation(animation), mStartTime(0) {}
void setGroup(const std::string& group);
void updateStartTime();
virtual Ogre::Real getValue() const;
virtual void setValue(Ogre::Real value)
{ }
};
class NpcAnimation : public Animation, public MWWorld::InventoryStoreListener
{
public:
@ -71,6 +88,7 @@ private:
Ogre::Vector3 mFirstPersonOffset;
Ogre::SharedPtr<HeadAnimationTime> mHeadAnimationTime;
Ogre::SharedPtr<WeaponAnimationTime> mWeaponAnimationTime;
float mAlpha;
@ -105,6 +123,8 @@ public:
ViewMode viewMode=VM_Normal);
virtual ~NpcAnimation();
virtual void setWeaponGroup(const std::string& group) { mWeaponAnimationTime->setGroup(group); }
virtual Ogre::Vector3 runAnimation(float timepassed);
virtual void showWeapons(bool showWeapon);

Loading…
Cancel
Save