Merge pull request #1462 from kcat/master

Minor animation fixes
pull/294/head
scrawl 7 years ago committed by GitHub
commit 5688257837

@ -82,9 +82,6 @@ namespace MWBase
///< Play a soundifle ///< Play a soundifle
/// \param filename name of a sound file in "Music/" in the data directory. /// \param filename name of a sound file in "Music/" in the data directory.
virtual void startRandomTitle() = 0;
///< Starts a random track from the current playlist
virtual bool isMusicPlaying() = 0; virtual bool isMusicPlaying() = 0;
///< Returns true if music is playing ///< Returns true if music is playing

@ -2025,58 +2025,53 @@ void CharacterController::unpersistAnimationState()
bool CharacterController::playGroup(const std::string &groupname, int mode, int count, bool persist) bool CharacterController::playGroup(const std::string &groupname, int mode, int count, bool persist)
{ {
if(!mAnimation || !mAnimation->hasAnimation(groupname)) if(!mAnimation || !mAnimation->hasAnimation(groupname))
{
std::cerr<< "Animation "<<groupname<<" not found for " << mPtr.getCellRef().getRefId() << std::endl;
return false; return false;
}
else // If this animation is a looped animation (has a "loop start" key) that is already playing
// and has not yet reached the end of the loop, allow it to continue animating with its existing loop count
// and remove any other animations that were queued.
// This emulates observed behavior from the original allows the script "OutsideBanner" to animate banners correctly.
if (!mAnimQueue.empty() && mAnimQueue.front().mGroup == groupname &&
mAnimation->getTextKeyTime(mAnimQueue.front().mGroup + ": loop start") >= 0 &&
mAnimation->isPlaying(groupname))
{ {
// If this animation is a looped animation (has a "loop start" key) that is already playing float endOfLoop = mAnimation->getTextKeyTime(mAnimQueue.front().mGroup+": loop stop");
// and has not yet reached the end of the loop, allow it to continue animating with its existing loop count
// and remove any other animations that were queued.
// This emulates observed behavior from the original allows the script "OutsideBanner" to animate banners correctly.
if (!mAnimQueue.empty() && mAnimQueue.front().mGroup == groupname &&
mAnimation->getTextKeyTime(mAnimQueue.front().mGroup + ": loop start") >= 0 &&
mAnimation->isPlaying(groupname))
{
float endOfLoop = mAnimation->getTextKeyTime(mAnimQueue.front().mGroup+": loop stop");
if (endOfLoop < 0) // if no Loop Stop key was found, use the Stop key if (endOfLoop < 0) // if no Loop Stop key was found, use the Stop key
endOfLoop = mAnimation->getTextKeyTime(mAnimQueue.front().mGroup+": stop"); endOfLoop = mAnimation->getTextKeyTime(mAnimQueue.front().mGroup+": stop");
if (endOfLoop > 0 && (mAnimation->getCurrentTime(mAnimQueue.front().mGroup) < endOfLoop)) if (endOfLoop > 0 && (mAnimation->getCurrentTime(mAnimQueue.front().mGroup) < endOfLoop))
{ {
mAnimQueue.resize(1); mAnimQueue.resize(1);
return true; return true;
}
} }
}
count = std::max(count, 1); count = std::max(count, 1);
AnimationQueueEntry entry; AnimationQueueEntry entry;
entry.mGroup = groupname; entry.mGroup = groupname;
entry.mLoopCount = count-1; entry.mLoopCount = count-1;
entry.mPersist = persist; entry.mPersist = persist;
if(mode != 0 || mAnimQueue.empty() || !isAnimPlaying(mAnimQueue.front().mGroup)) if(mode != 0 || mAnimQueue.empty() || !isAnimPlaying(mAnimQueue.front().mGroup))
{ {
clearAnimQueue(); clearAnimQueue();
mAnimQueue.push_back(entry); mAnimQueue.push_back(entry);
mAnimation->disable(mCurrentIdle); mAnimation->disable(mCurrentIdle);
mCurrentIdle.clear(); mCurrentIdle.clear();
mIdleState = CharState_SpecialIdle; mIdleState = CharState_SpecialIdle;
bool loopfallback = (entry.mGroup.compare(0,4,"idle") == 0); bool loopfallback = (entry.mGroup.compare(0,4,"idle") == 0);
mAnimation->play(groupname, Priority_Default, mAnimation->play(groupname, Priority_Default,
MWRender::Animation::BlendMask_All, false, 1.0f, MWRender::Animation::BlendMask_All, false, 1.0f,
((mode==2) ? "loop start" : "start"), "stop", 0.0f, count-1, loopfallback); ((mode==2) ? "loop start" : "start"), "stop", 0.0f, count-1, loopfallback);
} }
else if(mode == 0) else if(mode == 0)
{ {
mAnimQueue.resize(1); mAnimQueue.resize(1);
mAnimQueue.push_back(entry); mAnimQueue.push_back(entry);
}
} }
return true; return true;
} }

@ -757,8 +757,6 @@ namespace MWRender
break; break;
} }
} }
if(iter == mAnimSources.rend())
std::cerr<< "Failed to find animation "<<groupname<<" for "<<mPtr.getCellRef().getRefId() <<std::endl;
resetActiveGroups(); resetActiveGroups();
} }
@ -795,7 +793,7 @@ namespace MWRender
// We have to ignore extra garbage at the end. // We have to ignore extra garbage at the end.
// The Scrib's idle3 animation has "Idle3: Stop." instead of "Idle3: Stop". // The Scrib's idle3 animation has "Idle3: Stop." instead of "Idle3: Stop".
// Why, just why? :( // Why, just why? :(
&& (stopkey->second.size() < stoptag.size() || stopkey->second.substr(0,stoptag.size()) != stoptag)) && (stopkey->second.size() < stoptag.size() || stopkey->second.compare(0,stoptag.size(), stoptag) != 0))
++stopkey; ++stopkey;
if(stopkey == keys.rend()) if(stopkey == keys.rend())
return false; return false;

@ -391,11 +391,6 @@ namespace MWSound
mMusic->setFadeout(0.5f); mMusic->setFadeout(0.5f);
} }
void SoundManager::streamMusic(const std::string& filename)
{
advanceMusic("Music/"+filename);
}
void SoundManager::startRandomTitle() void SoundManager::startRandomTitle()
{ {
std::vector<std::string> filelist; std::vector<std::string> filelist;
@ -446,6 +441,12 @@ namespace MWSound
tracklist.pop_back(); tracklist.pop_back();
} }
void SoundManager::streamMusic(const std::string& filename)
{
advanceMusic("Music/"+filename);
}
bool SoundManager::isMusicPlaying() bool SoundManager::isMusicPlaying()
{ {
return mMusic && mOutput->isStreamPlaying(mMusic); return mMusic && mOutput->isStreamPlaying(mMusic);

@ -127,6 +127,7 @@ namespace MWSound
void streamMusicFull(const std::string& filename); void streamMusicFull(const std::string& filename);
void advanceMusic(const std::string& filename); void advanceMusic(const std::string& filename);
void startRandomTitle();
void updateSounds(float duration); void updateSounds(float duration);
void updateRegionSound(float duration); void updateRegionSound(float duration);
@ -157,9 +158,6 @@ namespace MWSound
///< Play a soundifle ///< Play a soundifle
/// \param filename name of a sound file in "Music/" in the data directory. /// \param filename name of a sound file in "Music/" in the data directory.
virtual void startRandomTitle();
///< Starts a random track from the current playlist
virtual bool isMusicPlaying(); virtual bool isMusicPlaying();
///< Returns true if music is playing ///< Returns true if music is playing

@ -141,11 +141,11 @@ namespace Resource
void setUnRefImageDataAfterApply(bool unref); void setUnRefImageDataAfterApply(bool unref);
/// @see ResourceManager::updateCache /// @see ResourceManager::updateCache
virtual void updateCache(double referenceTime); void updateCache(double referenceTime) override;
virtual void clearCache(); void clearCache() override;
virtual void reportStats(unsigned int frameNumber, osg::Stats* stats) const; void reportStats(unsigned int frameNumber, osg::Stats* stats) const override;
private: private:

@ -32,9 +32,9 @@ namespace Terrain
osg::ref_ptr<osg::Node> getChunk(float size, const osg::Vec2f& center, int lod, unsigned int lodFlags); osg::ref_ptr<osg::Node> getChunk(float size, const osg::Vec2f& center, int lod, unsigned int lodFlags);
virtual void reportStats(unsigned int frameNumber, osg::Stats* stats) const; void reportStats(unsigned int frameNumber, osg::Stats* stats) const override;
virtual void clearCache(); void clearCache() override;
void releaseGLObjects(osg::State* state) override; void releaseGLObjects(osg::State* state) override;

Loading…
Cancel
Save