mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-01-30 15:15:31 +00:00
Feature #50: Allow body pitch in third person for ranged weapon aiming
This commit is contained in:
parent
5ee105c812
commit
a07eaa0c0d
6 changed files with 67 additions and 11 deletions
|
@ -773,6 +773,50 @@ bool CharacterController::updateWeaponState()
|
|||
}
|
||||
}
|
||||
|
||||
mAnimation->setPitchFactor(0.f);
|
||||
if (mWeaponType == WeapType_BowAndArrow || mWeaponType == WeapType_Thrown)
|
||||
{
|
||||
switch (mUpperBodyState)
|
||||
{
|
||||
case UpperCharState_StartToMinAttack:
|
||||
mAnimation->setPitchFactor(complete);
|
||||
break;
|
||||
case UpperCharState_MinAttackToMaxAttack:
|
||||
case UpperCharState_MaxAttackToMinHit:
|
||||
case UpperCharState_MinHitToHit:
|
||||
mAnimation->setPitchFactor(1.f);
|
||||
break;
|
||||
case UpperCharState_FollowStartToFollowStop:
|
||||
if (animPlaying)
|
||||
mAnimation->setPitchFactor(1.f-complete);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (mWeaponType == WeapType_Crossbow)
|
||||
{
|
||||
switch (mUpperBodyState)
|
||||
{
|
||||
case UpperCharState_EquipingWeap:
|
||||
mAnimation->setPitchFactor(complete);
|
||||
break;
|
||||
case UpperCharState_UnEquipingWeap:
|
||||
mAnimation->setPitchFactor(1.f-complete);
|
||||
break;
|
||||
case UpperCharState_WeapEquiped:
|
||||
case UpperCharState_StartToMinAttack:
|
||||
case UpperCharState_MinAttackToMaxAttack:
|
||||
case UpperCharState_MaxAttackToMinHit:
|
||||
case UpperCharState_MinHitToHit:
|
||||
case UpperCharState_FollowStartToFollowStop:
|
||||
mAnimation->setPitchFactor(1.f);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(!animPlaying)
|
||||
{
|
||||
if(mUpperBodyState == UpperCharState_EquipingWeap ||
|
||||
|
|
|
@ -53,7 +53,6 @@ void Animation::EffectAnimationTime::setValue(Ogre::Real)
|
|||
|
||||
Animation::Animation(const MWWorld::Ptr &ptr, Ogre::SceneNode *node)
|
||||
: mPtr(ptr)
|
||||
, mCamera(NULL)
|
||||
, mInsert(node)
|
||||
, mSkelBase(NULL)
|
||||
, mAccumRoot(NULL)
|
||||
|
|
|
@ -121,7 +121,6 @@ protected:
|
|||
std::vector<EffectParams> mEffects;
|
||||
|
||||
MWWorld::Ptr mPtr;
|
||||
Camera *mCamera;
|
||||
|
||||
Ogre::SceneNode *mInsert;
|
||||
Ogre::Entity *mSkelBase;
|
||||
|
@ -288,6 +287,10 @@ public:
|
|||
/** Retrieves the velocity (in units per second) that the animation will move. */
|
||||
float getVelocity(const std::string &groupname) const;
|
||||
|
||||
/// A relative factor (0-1) that decides if and how much the skeleton should be pitched
|
||||
/// to indicate the facing orientation of the character.
|
||||
virtual void setPitchFactor(float factor) {}
|
||||
|
||||
virtual Ogre::Vector3 runAnimation(float duration);
|
||||
|
||||
virtual void showWeapons(bool showWeapon);
|
||||
|
@ -297,9 +300,6 @@ public:
|
|||
|
||||
Ogre::AxisAlignedBox getWorldBounds();
|
||||
|
||||
void setCamera(Camera *cam)
|
||||
{ mCamera = cam; }
|
||||
|
||||
Ogre::Node *getNode(const std::string &name);
|
||||
|
||||
// Attaches the given object to a bone on this object's base skeleton. If the bone doesn't
|
||||
|
|
|
@ -338,11 +338,9 @@ namespace MWRender
|
|||
if(mAnimation && mAnimation != anim)
|
||||
{
|
||||
mAnimation->setViewMode(NpcAnimation::VM_Normal);
|
||||
mAnimation->setCamera(NULL);
|
||||
mAnimation->detachObjectFromBone(mCamera);
|
||||
}
|
||||
mAnimation = anim;
|
||||
mAnimation->setCamera(this);
|
||||
|
||||
processViewChange();
|
||||
}
|
||||
|
|
|
@ -142,7 +142,8 @@ NpcAnimation::NpcAnimation(const MWWorld::Ptr& ptr, Ogre::SceneNode* node, int v
|
|||
mShowCarriedLeft(true),
|
||||
mFirstPersonOffset(0.f, 0.f, 0.f),
|
||||
mAlpha(1.f),
|
||||
mNpcType(Type_Normal)
|
||||
mNpcType(Type_Normal),
|
||||
mPitchFactor(0)
|
||||
{
|
||||
mNpc = mPtr.get<ESM::NPC>()->mBase;
|
||||
|
||||
|
@ -522,16 +523,25 @@ Ogre::Vector3 NpcAnimation::runAnimation(float timepassed)
|
|||
Ogre::Vector3 ret = Animation::runAnimation(timepassed);
|
||||
|
||||
Ogre::SkeletonInstance *baseinst = mSkelBase->getSkeleton();
|
||||
if(mViewMode == VM_FirstPerson && mCamera)
|
||||
if(mViewMode == VM_FirstPerson)
|
||||
{
|
||||
float pitch = mCamera->getPitch();
|
||||
float pitch = mPtr.getRefData().getPosition().rot[0];
|
||||
Ogre::Node *node = baseinst->getBone("Bip01 Neck");
|
||||
node->pitch(Ogre::Radian(pitch*0.75f), Ogre::Node::TS_WORLD);
|
||||
node->pitch(Ogre::Radian(pitch), Ogre::Node::TS_WORLD);
|
||||
|
||||
// This has to be done before this function ends;
|
||||
// updateSkeletonInstance, below, touches the hands.
|
||||
node->translate(mFirstPersonOffset, Ogre::Node::TS_WORLD);
|
||||
}
|
||||
else if (mPitchFactor > 0)
|
||||
{
|
||||
// In third person mode we may still need pitch for ranged weapon targeting
|
||||
float pitch = mPtr.getRefData().getPosition().rot[0] * mPitchFactor;
|
||||
Ogre::Node *node = baseinst->getBone("Bip01 Spine2");
|
||||
node->pitch(Ogre::Radian(pitch/2), Ogre::Node::TS_WORLD);
|
||||
node = baseinst->getBone("Bip01 Spine1");
|
||||
node->pitch(Ogre::Radian(pitch/2), Ogre::Node::TS_WORLD);
|
||||
}
|
||||
mFirstPersonOffset = 0.f; // reset the X, Y, Z offset for the next frame.
|
||||
|
||||
for(size_t i = 0;i < ESM::PRT_Count;i++)
|
||||
|
|
|
@ -91,6 +91,7 @@ private:
|
|||
Ogre::SharedPtr<WeaponAnimationTime> mWeaponAnimationTime;
|
||||
|
||||
float mAlpha;
|
||||
float mPitchFactor;
|
||||
|
||||
void updateNpcBase();
|
||||
|
||||
|
@ -127,6 +128,10 @@ public:
|
|||
|
||||
virtual Ogre::Vector3 runAnimation(float timepassed);
|
||||
|
||||
/// A relative factor (0-1) that decides if and how much the skeleton should be pitched
|
||||
/// to indicate the facing orientation of the character.
|
||||
virtual void setPitchFactor(float factor) { mPitchFactor = factor; }
|
||||
|
||||
virtual void showWeapons(bool showWeapon);
|
||||
virtual void showCarriedLeft(bool showa);
|
||||
|
||||
|
|
Loading…
Reference in a new issue