From 625f9a35e607459180860201e34c29ae1bd0b5a6 Mon Sep 17 00:00:00 2001 From: scrawl Date: Tue, 29 Jul 2014 01:16:08 +0200 Subject: [PATCH] Implement NPC eye blinking (Fixes #1721) --- apps/openmw/mwrender/npcanimation.cpp | 44 ++++++++++++++++++++++----- apps/openmw/mwrender/npcanimation.hpp | 8 +++++ 2 files changed, 44 insertions(+), 8 deletions(-) diff --git a/apps/openmw/mwrender/npcanimation.cpp b/apps/openmw/mwrender/npcanimation.cpp index 597d0c2df..e2a01f723 100644 --- a/apps/openmw/mwrender/npcanimation.cpp +++ b/apps/openmw/mwrender/npcanimation.cpp @@ -67,19 +67,45 @@ namespace MWRender { HeadAnimationTime::HeadAnimationTime(MWWorld::Ptr reference) - : mReference(reference), mTalkStart(0), mTalkStop(0), mBlinkStart(0), mBlinkStop(0) + : mReference(reference), mTalkStart(0), mTalkStop(0), mBlinkStart(0), mBlinkStop(0), mValue(0) { + resetBlinkTimer(); +} + +void HeadAnimationTime::resetBlinkTimer() +{ + mBlinkTimer = -(2 + (std::rand() / double(RAND_MAX*1.0)) * 6); +} + +void HeadAnimationTime::update(float dt) +{ + if (MWBase::Environment::get().getSoundManager()->sayDone(mReference)) + { + mBlinkTimer += dt; + + float duration = mBlinkStop - mBlinkStart; + + if (mBlinkTimer >= 0 && mBlinkTimer <= duration) + { + mValue = mBlinkStart + mBlinkTimer; + } + else + mValue = mBlinkStop; + + if (mBlinkTimer > duration) + resetBlinkTimer(); + } + else + { + mValue = mTalkStart + + (mTalkStop - mTalkStart) * + std::min(1.f, MWBase::Environment::get().getSoundManager()->getSaySoundLoudness(mReference)*4); // Rescale a bit (most voices are not very loud) + } } float HeadAnimationTime::getValue() const { - // TODO: Handle eye blinking - if (MWBase::Environment::get().getSoundManager()->sayDone(mReference)) - return mBlinkStop; - else - return mTalkStart + - (mTalkStop - mTalkStart) * - std::min(1.f, MWBase::Environment::get().getSoundManager()->getSaySoundLoudness(mReference)*4); // Rescale a bit (most voices are not very loud) + return mValue; } void HeadAnimationTime::setTalkStart(float value) @@ -541,6 +567,8 @@ Ogre::Vector3 NpcAnimation::runAnimation(float timepassed) { Ogre::Vector3 ret = Animation::runAnimation(timepassed); + mHeadAnimationTime->update(timepassed); + Ogre::SkeletonInstance *baseinst = mSkelBase->getSkeleton(); if(mViewMode == VM_FirstPerson) { diff --git a/apps/openmw/mwrender/npcanimation.hpp b/apps/openmw/mwrender/npcanimation.hpp index 057f67e2f..95cd35ddb 100644 --- a/apps/openmw/mwrender/npcanimation.hpp +++ b/apps/openmw/mwrender/npcanimation.hpp @@ -23,9 +23,17 @@ private: float mTalkStop; float mBlinkStart; float mBlinkStop; + + float mBlinkTimer; + + float mValue; +private: + void resetBlinkTimer(); public: HeadAnimationTime(MWWorld::Ptr reference); + void update(float dt); + void setTalkStart(float value); void setTalkStop(float value); void setBlinkStart(float value);