mirror of
https://github.com/OpenMW/openmw.git
synced 2025-01-20 08:53:52 +00:00
Feature #50: Handle weapon controllers (i.e. bowstring animations, etc)
This commit is contained in:
parent
975f0e05b4
commit
7cf22391a5
5 changed files with 76 additions and 3 deletions
|
@ -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…
Reference in a new issue