1
0
Fork 1
mirror of https://github.com/TES3MP/openmw-tes3mp.git synced 2025-01-30 21:15:33 +00:00

Refactored, moved logic out of NpcAnimation

The logic is now handled by RenderingManager, and Camera sets its
animation's first person offset height. Due to how NpcAnimation seems to
be updated, it has to be the one to actually set its own nodes, in the
case of the hands. Otherwise, the hands would not move without a messier
hack.
This commit is contained in:
Alex "rainChu" Haddad 2013-10-02 05:16:52 -04:00
parent 0ddb5097fc
commit ed0c31b485
5 changed files with 40 additions and 1 deletions

View file

@ -187,6 +187,12 @@ namespace MWRender
rotateCamera(Ogre::Vector3(getPitch(), 0.f, getYaw()), false);
}
void Camera::setSneakOffset()
{
if(mAnimation)
mAnimation->addFirstPersonOffset(Ogre::Vector3(-9.8f, 0.f, 0.f));
}
float Camera::getYaw()
{
if(mVanity.enabled || mPreviewMode)

View file

@ -79,6 +79,12 @@ namespace MWRender
void togglePreviewMode(bool enable);
/// \brief Lowers the camera for sneak.
/// As animation is tied to the camera, this needs
/// to be set each frame after the animation is
/// applied.
void setSneakOffset();
bool isFirstPerson() const
{ return !(mVanity.enabled || mPreviewMode || !mFirstPersonView); }

View file

@ -84,7 +84,8 @@ NpcAnimation::NpcAnimation(const MWWorld::Ptr& ptr, Ogre::SceneNode* node, MWWor
mWeapon(inv.end()),
mShield(inv.end()),
mViewMode(viewMode),
mShowWeapons(false)
mShowWeapons(false),
mFirstPersonOffset(0.f, 0.f, 0.f)
{
mNpc = mPtr.get<ESM::NPC>()->mBase;
@ -392,6 +393,11 @@ void NpcAnimation::updateParts(bool forceupdate)
}
}
void NpcAnimation::addFirstPersonOffset(const Ogre::Vector3 &offset)
{
mFirstPersonOffset += offset;
}
class SetObjectGroup {
int mGroup;
@ -448,7 +454,12 @@ Ogre::Vector3 NpcAnimation::runAnimation(float timepassed)
float pitch = mCamera->getPitch();
Ogre::Node *node = baseinst->getBone("Bip01 Neck");
node->pitch(Ogre::Radian(pitch*0.75f), Ogre::Node::TS_WORLD);
// This has to be done before this function ends;
// updateSkeletonInstance, below, touches the hands.
node->translate(mFirstPersonOffset);
}
mFirstPersonOffset = 0.f; // reset the X, Y, Z offset for the next frame.
for(size_t i = 0;i < ESM::PRT_Count;i++)
{

View file

@ -64,6 +64,8 @@ private:
int mPartslots[ESM::PRT_Count]; //Each part slot is taken by clothing, armor, or is empty
int mPartPriorities[ESM::PRT_Count];
Ogre::Vector3 mFirstPersonOffset;
void updateNpcBase();
NifOgre::ObjectList insertBoundedPart(const std::string &model, int group, const std::string &bonename);
@ -89,6 +91,11 @@ public:
void updateParts(bool forceupdate = false);
/// \brief Applies a translation to the arms and hands.
/// This may be called multiple times before the animation
/// is updated to add additional offsets.
void addFirstPersonOffset(const Ogre::Vector3 &offset);
/// Rebuilds the NPC, updating their root model, animation sources, and equipment.
void rebuild();
};

View file

@ -354,6 +354,15 @@ void RenderingManager::update (float duration, bool paused)
mCamera->setCameraDistance(test.second * orig.distance(dest), false, false);
}
// Sink the camera while sneaking
bool isSneaking = MWWorld::Class::get(player).getStance(player, MWWorld::Class::Sneak);
bool isInAir = !world->isOnGround(player);
bool isSwimming = world->isSwimming(player);
if(isSneaking && !(isSwimming || isInAir))
mCamera->setSneakOffset();
mOcclusionQuery->update(duration);
mVideoPlayer->update ();