mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-01-30 13:15:32 +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:
parent
0ddb5097fc
commit
ed0c31b485
5 changed files with 40 additions and 1 deletions
|
@ -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)
|
||||
|
|
|
@ -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); }
|
||||
|
||||
|
|
|
@ -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++)
|
||||
{
|
||||
|
|
|
@ -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();
|
||||
};
|
||||
|
|
|
@ -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 ();
|
||||
|
|
Loading…
Reference in a new issue