Added @setoverlay_tween to animate the alpha and tint overlay modifier values

--HG--
branch : RLVa
meow-7.2.2
Kitty Barnett 2018-05-07 01:08:58 +02:00
parent 7c42ab5c28
commit f7dbbd3ad2
7 changed files with 238 additions and 0 deletions

View File

@ -718,6 +718,7 @@ set(viewer_SOURCE_FILES
rlvinventory.cpp
rlvextensions.cpp
rlvfloaters.cpp
rlvmodifiers.cpp
rlvui.cpp
)
@ -1343,6 +1344,7 @@ set(viewer_HEADER_FILES
rlvinventory.h
rlvextensions.h
rlvfloaters.h
rlvmodifiers.h
rlvui.h
roles_constants.h
VertexCache.h

View File

@ -237,6 +237,7 @@ enum ERlvBehaviour {
RLV_BHVR_SETOVERLAY_TEXTURE, // Changes the overlay texture
RLV_BHVR_SETOVERLAY_TINT, // Changes the tint that's applied to the overlay texture
RLV_BHVR_SETOVERLAY_TOUCH, // Block world interaction (=touching) based on the alpha channel of the overlay texture
RLV_BHVR_SETOVERLAY_TWEEN, // Animate between the current overlay settings and the supplied values
RLV_BHVR_COUNT,
RLV_BHVR_UNKNOWN

View File

@ -60,6 +60,7 @@
#include "rlvhelper.h"
#include "rlvinventory.h"
#include "rlvlocks.h"
#include "rlvmodifiers.h"
#include "rlvui.h"
#include "rlvextensions.h"
@ -2595,6 +2596,32 @@ ERlvCmdRet RlvForceHandler<RLV_BHVR_SETCAM_MODE>::onCommand(const RlvCommand& rl
return RLV_RET_SUCCESS;
}
// Handles: @setoverlay_tween:[<alpha>];[<tint>];<duration>=force
template<> template<>
ERlvCmdRet RlvForceHandler<RLV_BHVR_SETOVERLAY_TWEEN>::onCommand(const RlvCommand& rlvCmd)
{
std::vector<std::string> optionList;
if ( (!RlvCommandOptionHelper::parseStringList(rlvCmd.getOption(), optionList)) || (3 != optionList.size()) )
return RLV_RET_FAILED_OPTION;
// Parse the duration first (required param)
float tweenDuration = .0f;
if (!RlvCommandOptionHelper::parseOption(optionList[2], tweenDuration))
return RLV_RET_FAILED_OPTION;
// Process the overlay alpha tween (if there is one and it is a valid value)
float overlayAlpha = .0f;
if (RlvCommandOptionHelper::parseOption(optionList[0], overlayAlpha))
RlvBehaviourModifierAnimator::instance().addTween(rlvCmd.getObjectID(), RLV_MODIFIER_OVERLAY_ALPHA, RlvBehaviourModifierAnimationType::Lerp, overlayAlpha, tweenDuration);
// Process the overlay tint tween (if there is one and it is a valid value)
LLVector3 overlayColor;
if (RlvCommandOptionHelper::parseOption(optionList[1], overlayColor))
RlvBehaviourModifierAnimator::instance().addTween(rlvCmd.getObjectID(), RLV_MODIFIER_OVERLAY_TINT, RlvBehaviourModifierAnimationType::Lerp, overlayColor, tweenDuration);
return RLV_RET_SUCCESS;
}
// Checked: 2010-08-30 (RLVa-1.2.1c) | Modified: RLVa-1.2.1c
ERlvCmdRet RlvHandler::onForceWear(const LLViewerInventoryCategory* pFolder, U32 nFlags) const
{

View File

@ -25,6 +25,7 @@
#include "rlvhelper.h"
#include "rlvhandler.h"
#include "rlvinventory.h"
#include "rlvmodifiers.h"
#include <boost/algorithm/string.hpp>
@ -215,6 +216,7 @@ RlvBehaviourDictionary::RlvBehaviourDictionary()
RLV_MODIFIER_OVERLAY_TINT, new RlvBehaviourModifier("Overlay - Tint", LLVector3(1.0f, 1.0f, 1.0f), false, new RlvBehaviourModifier_Comp()));
addModifier(new RlvBehaviourGenericProcessor<RLV_OPTION_NONE_OR_MODIFIER>("setoverlay_touch", RLV_BHVR_SETOVERLAY_TOUCH, RlvBehaviourInfo::BHVR_EXPERIMENTAL),
RLV_MODIFIER_OVERLAY_TOUCH, new RlvBehaviourModifier("Overlay - Touch", true, true, new RlvBehaviourModifier_Comp()));
addEntry(new RlvForceProcessor<RLV_BHVR_SETOVERLAY_TWEEN>("setoverlay_tween", RlvBehaviourInfo::BHVR_EXPERIMENTAL));
//
// Force-wear
@ -482,6 +484,7 @@ void RlvBehaviourModifier::clearValues(const LLUUID& idRlvObj)
[&idRlvObj](const RlvBehaviourModifierValueTuple& modValue) {
return (std::get<1>(modValue) == idRlvObj) && (std::get<2>(modValue) == RLV_BHVR_UNKNOWN);
}), m_Values.end());
RlvBehaviourModifierAnimator::instance().clearTweens(idRlvObj);
if (origCount != m_Values.size())
{
onValueChange();
@ -501,6 +504,11 @@ bool RlvBehaviourModifier::hasValue() const {
return (!m_Values.empty()) ? std::get<1>(m_Values.front()) == m_pValueComparator->m_idPrimaryObject : false;
}
bool RlvBehaviourModifier::hasValue(const LLUUID& idRlvObj) const
{
return m_Values.end() != std::find_if(m_Values.begin(), m_Values.end(), [&idRlvObj](const RlvBehaviourModifierValueTuple& cmpValue) { return std::get<1>(cmpValue) == idRlvObj; });
}
void RlvBehaviourModifier::removeValue(const RlvBehaviourModifierValue& modValue, const LLUUID& idRlvObj, ERlvBehaviour eBhvr)
{
if ( (modValue.which() == m_DefaultValue.which()) )

View File

@ -284,6 +284,7 @@ public:
const RlvBehaviourModifierValue& getValue() const { return (hasValue()) ? std::get<0>(m_Values.front()) : m_DefaultValue; }
template<typename T> const T& getValue() const { return boost::get<T>(getValue()); }
bool hasValue() const;
bool hasValue(const LLUUID& idRlvObj) const;
void removeValue(const RlvBehaviourModifierValue& modValue, const LLUUID& idRlvObj, ERlvBehaviour eBhvr = RLV_BHVR_UNKNOWN);
void setValue(const RlvBehaviourModifierValue& modValue, const LLUUID& idRlvObj);
void setPrimaryObject(const LLUUID& idPrimaryObject);

View File

@ -0,0 +1,124 @@
/**
*
* 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_pTimer)
{
delete m_pTimer;
m_pTimer = nullptr;
}
}
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 (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_pTimer)
m_pTimer = new AnimationTimer();
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
//
#define ANIMATION_FREQUENCY 10
RlvBehaviourModifierAnimator::AnimationTimer::AnimationTimer()
: LLEventTimer(1.f / 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 combnination
return t.idObject == curTween.idObject && t.eBhvrMod == curTween.eBhvrMod && t.eAnimType == curTween.eAnimType;
});
modAnimatior.m_Tweens.erase(itTween);
}
}
}
if (modAnimatior.m_Tweens.empty())
{
modAnimatior.m_pTimer = nullptr;
return true;
}
return false;
}
// ====================================================================================

View File

@ -0,0 +1,75 @@
/**
*
* 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.
*
*/
#pragma once
#include "llsingleton.h"
#include "rlvhelper.h"
// ====================================================================================
// RlvBehaviourModifierAnimator - Helper types
//
enum class RlvBehaviourModifierAnimationType { Lerp };
struct RlvBehaviourModifierTween
{
LLUUID idObject;
ERlvBehaviourModifier eBhvrMod;
RlvBehaviourModifierAnimationType eAnimType;
double nStartTime;
float nDuration;
RlvBehaviourModifierValue startValue;
RlvBehaviourModifierValue endValue;
};
// ====================================================================================
// RlvBehaviourModifierAnimator - A class to animate behaviour modifiers
//
class RlvBehaviourModifierAnimator : public LLSingleton<RlvBehaviourModifierAnimator>
{
friend class AnimationTimer;
LLSINGLETON_EMPTY_CTOR(RlvBehaviourModifierAnimator);
public:
~RlvBehaviourModifierAnimator() override;
/*
* Member functions
*/
public:
void addTween(const LLUUID& idObject, ERlvBehaviourModifier eBhvrMod, RlvBehaviourModifierAnimationType eAnimType, const RlvBehaviourModifierValue& endValue, float nDuration);
void clearTweens(const LLUUID& idObject) { clearTweens(idObject, RLV_MODIFIER_UNKNOWN); }
void clearTweens(const LLUUID& idObject, ERlvBehaviourModifier eBhvrMod);
/*
* Animation timer
*/
class AnimationTimer : LLEventTimer
{
public:
AnimationTimer();
BOOL tick() override;
};
/*
* Member variables
*/
std::list<struct RlvBehaviourModifierTween> m_Tweens;
AnimationTimer* m_pTimer = nullptr;
};
// ====================================================================================