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); getWeaponGroup(weaptype, weapgroup);
mAnimation->showWeapons(false); mAnimation->showWeapons(false);
mAnimation->setWeaponGroup(weapgroup);
mAnimation->play(weapgroup, Priority_Weapon, mAnimation->play(weapgroup, Priority_Weapon,
MWRender::Animation::Group_UpperBody, true, MWRender::Animation::Group_UpperBody, true,

@ -870,6 +870,27 @@ bool Animation::getInfo(const std::string &groupname, float *complete, float *sp
return true; 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) 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; 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; /** Disables the specified animation group;
* \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 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. */ /** 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;

@ -71,6 +71,27 @@ float HeadAnimationTime::getValue() const
return 1; 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() static NpcAnimation::PartBoneMap createPartListMap()
{ {
NpcAnimation::PartBoneMap result; NpcAnimation::PartBoneMap result;
@ -126,6 +147,7 @@ NpcAnimation::NpcAnimation(const MWWorld::Ptr& ptr, Ogre::SceneNode* node, int v
mNpc = mPtr.get<ESM::NPC>()->mBase; mNpc = mPtr.get<ESM::NPC>()->mBase;
mHeadAnimationTime = Ogre::SharedPtr<HeadAnimationTime>(new HeadAnimationTime(mPtr)); mHeadAnimationTime = Ogre::SharedPtr<HeadAnimationTime>(new HeadAnimationTime(mPtr));
mWeaponAnimationTime = Ogre::SharedPtr<WeaponAnimationTime>(new WeaponAnimationTime(this));
for(size_t i = 0;i < ESM::PRT_Count;i++) 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++) for(size_t i = 0;i < ESM::PRT_Count;i++)
removeIndividualPart((ESM::PartReferenceType)i); removeIndividualPart((ESM::PartReferenceType)i);
updateParts(); updateParts();
mWeaponAnimationTime->updateStartTime();
} }
void NpcAnimation::updateParts() void NpcAnimation::updateParts()
@ -588,9 +612,6 @@ bool NpcAnimation::addOrReplaceIndividualPart(ESM::PartReferenceType type, int g
updateSkeletonInstance(mSkelBase->getSkeleton(), skel); 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()); std::vector<Ogre::Controller<Ogre::Real> >::iterator ctrl(mObjectParts[type]->mControllers.begin());
for(;ctrl != mObjectParts[type]->mControllers.end();ctrl++) for(;ctrl != mObjectParts[type]->mControllers.end();ctrl++)
{ {
@ -600,6 +621,8 @@ bool NpcAnimation::addOrReplaceIndividualPart(ESM::PartReferenceType type, int g
if (type == ESM::PRT_Head) if (type == ESM::PRT_Head)
ctrl->setSource(mHeadAnimationTime); 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 class NpcAnimation : public Animation, public MWWorld::InventoryStoreListener
{ {
public: public:
@ -71,6 +88,7 @@ private:
Ogre::Vector3 mFirstPersonOffset; Ogre::Vector3 mFirstPersonOffset;
Ogre::SharedPtr<HeadAnimationTime> mHeadAnimationTime; Ogre::SharedPtr<HeadAnimationTime> mHeadAnimationTime;
Ogre::SharedPtr<WeaponAnimationTime> mWeaponAnimationTime;
float mAlpha; float mAlpha;
@ -105,6 +123,8 @@ public:
ViewMode viewMode=VM_Normal); ViewMode viewMode=VM_Normal);
virtual ~NpcAnimation(); virtual ~NpcAnimation();
virtual void setWeaponGroup(const std::string& group) { mWeaponAnimationTime->setGroup(group); }
virtual Ogre::Vector3 runAnimation(float timepassed); virtual Ogre::Vector3 runAnimation(float timepassed);
virtual void showWeapons(bool showWeapon); virtual void showWeapons(bool showWeapon);

Loading…
Cancel
Save