116 lines
4.7 KiB
C++
116 lines
4.7 KiB
C++
/**
|
|
*
|
|
* Copyright (c) 2009-2018, Kitty Barnett
|
|
*
|
|
* The source code in this file is provided to you under the terms of the
|
|
* GNU Lesser General Public License, version 2.1, but WITHOUT ANY WARRANTY;
|
|
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
|
* PARTICULAR PURPOSE. Terms of the LGPL can be found in doc/LGPL-licence.txt
|
|
* in this distribution, or online at http://www.gnu.org/licenses/lgpl-2.1.txt
|
|
*
|
|
* By copying, modifying or distributing this software, you acknowledge that
|
|
* you have read and understood your obligations described above, and agree to
|
|
* abide by those obligations.
|
|
*
|
|
*/
|
|
|
|
#include "llviewerprecompiledheaders.h"
|
|
|
|
#include "rlvmodifiers.h"
|
|
|
|
// ====================================================================================
|
|
// RlvBehaviourModifierAnimator
|
|
//
|
|
|
|
RlvBehaviourModifierAnimator::~RlvBehaviourModifierAnimator()
|
|
{
|
|
if (!m_TimerHandle.isDead())
|
|
m_TimerHandle.markDead();
|
|
}
|
|
|
|
void RlvBehaviourModifierAnimator::addTween(const LLUUID& idObject, ERlvBehaviourModifier eBhvrMod, RlvBehaviourModifierAnimationType eAnimType, const RlvBehaviourModifierValue& endValue, float nDuration)
|
|
{
|
|
// Make sure we don't run two animations on the same modifier for the same object
|
|
const auto itTween = std::find_if(m_Tweens.begin(), m_Tweens.end(), [&idObject, eBhvrMod](const RlvBehaviourModifierTween& t) { return t.idObject == idObject && t.eBhvrMod == eBhvrMod; });
|
|
if (m_Tweens.end() != itTween)
|
|
m_Tweens.erase(itTween);
|
|
|
|
if (const RlvBehaviourModifier* pBhvrModifier = RlvBehaviourDictionary::instance().getModifier(eBhvrMod))
|
|
{
|
|
RlvBehaviourModifierTween newTween;
|
|
newTween.idObject = idObject;
|
|
newTween.eBhvrMod = eBhvrMod;
|
|
newTween.eAnimType = RlvBehaviourModifierAnimationType::Lerp;
|
|
newTween.nStartTime = LLTimer::getElapsedSeconds();
|
|
newTween.nDuration = nDuration;
|
|
newTween.startValue = pBhvrModifier->getValue();
|
|
newTween.endValue = endValue;
|
|
if (newTween.startValue.which() == newTween.endValue.which())
|
|
{
|
|
if (m_TimerHandle.isDead())
|
|
m_TimerHandle = (new AnimationTimer())->getHandle();
|
|
m_Tweens.emplace_back(std::move(newTween));
|
|
}
|
|
}
|
|
}
|
|
|
|
void RlvBehaviourModifierAnimator::clearTweens(const LLUUID& idObject, ERlvBehaviourModifier eBhvrMod)
|
|
{
|
|
m_Tweens.erase(std::remove_if(m_Tweens.begin(), m_Tweens.end(),
|
|
[&idObject, eBhvrMod](const RlvBehaviourModifierTween& cmpTween)
|
|
{
|
|
return cmpTween.idObject == idObject && ((cmpTween.eBhvrMod == eBhvrMod) || (RLV_MODIFIER_UNKNOWN == eBhvrMod));
|
|
}), m_Tweens.end());
|
|
}
|
|
|
|
// ====================================================================================
|
|
// RlvBehaviourModifierAnimator timer
|
|
//
|
|
|
|
RlvBehaviourModifierAnimator::AnimationTimer::AnimationTimer()
|
|
: LLEventTimer(1.f / RLV_MODIFIER_ANIMATION_FREQUENCY)
|
|
{
|
|
}
|
|
|
|
|
|
BOOL RlvBehaviourModifierAnimator::AnimationTimer::tick()
|
|
{
|
|
RlvBehaviourModifierAnimator& modAnimatior = RlvBehaviourModifierAnimator::instance();
|
|
const double curTime = LLTimer::getElapsedSeconds();
|
|
|
|
const auto activeTweens = modAnimatior.m_Tweens;
|
|
for (const auto& curTween : activeTweens)
|
|
{
|
|
if (RlvBehaviourModifier* pBhvrModifier = RlvBehaviourDictionary::instance().getModifier(curTween.eBhvrMod))
|
|
{
|
|
// Update the modifier's value
|
|
float curFactor = (curTime - curTween.nStartTime) / curTween.nDuration;
|
|
if (curFactor < 1.0)
|
|
{
|
|
const auto& valueType = curTween.startValue.type();
|
|
if (typeid(float) == valueType)
|
|
pBhvrModifier->setValue(lerp(boost::get<float>(curTween.startValue), boost::get<float>(curTween.endValue), curFactor), curTween.idObject);
|
|
else if (typeid(int) == valueType)
|
|
pBhvrModifier->setValue(lerp(boost::get<int>(curTween.startValue), boost::get<int>(curTween.endValue), curFactor), curTween.idObject);
|
|
else if (typeid(LLVector3) == valueType)
|
|
pBhvrModifier->setValue(lerp(boost::get<LLVector3>(curTween.startValue), boost::get<LLVector3>(curTween.endValue), curFactor), curTween.idObject);
|
|
}
|
|
else
|
|
{
|
|
pBhvrModifier->setValue(curTween.endValue, curTween.idObject);
|
|
auto itTween = std::find_if(modAnimatior.m_Tweens.begin(), modAnimatior.m_Tweens.end(),
|
|
[&curTween](const RlvBehaviourModifierTween& t)
|
|
{
|
|
// NOTE: implementation leak - taking advantage of the fact that we know there can only be one active tween per object/modifier/type combination
|
|
return t.idObject == curTween.idObject && t.eBhvrMod == curTween.eBhvrMod && t.eAnimType == curTween.eAnimType;
|
|
});
|
|
modAnimatior.m_Tweens.erase(itTween);
|
|
}
|
|
}
|
|
}
|
|
|
|
return modAnimatior.m_Tweens.empty();
|
|
}
|
|
|
|
// ====================================================================================
|