phoenix-firestorm/indra/newview/llvisualeffect.h

220 lines
6.5 KiB
C++

/**
*
* Copyright (c) 2021, 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 <boost/optional.hpp>
#include <boost/none.hpp>
// ============================================================================
//
//
class LLRenderTarget;
// ============================================================================
//
//
enum class EVisualEffect
{
RlvOverlay,
RlvSphere,
};
enum class EVisualEffectType
{
PostProcessShader,
Custom,
};
// ============================================================================
//
//
struct LLVisualEffectParams
{
virtual void step(bool isLast) = 0;
};
struct LLShaderEffectParams : LLVisualEffectParams
{
explicit LLShaderEffectParams(LLRenderTarget* pSrcBuffer, LLRenderTarget* pScratchBuffer, bool fBindLast) : m_pSrcBuffer(pScratchBuffer), m_pDstBuffer(pSrcBuffer), m_fBindLast(fBindLast) {}
void step(bool isLast) override
{
LLRenderTarget* pPrevSrc = m_pSrcBuffer, *pPrevDst = m_pDstBuffer;
m_pSrcBuffer = pPrevDst;
m_pDstBuffer = (!isLast || !m_fBindLast) ? pPrevSrc : nullptr;
}
LLRenderTarget* m_pSrcBuffer = nullptr;
LLRenderTarget* m_pDstBuffer = nullptr;
bool m_fBindLast = false;
};
// ============================================================================
//
//
class LLVisualEffect
{
friend class LLVfxManager;
public:
LLVisualEffect(LLUUID id, EVisualEffect eCode, EVisualEffectType eType)
: m_id(id), m_eCode(eCode), m_eType(eType)
{}
virtual ~LLVisualEffect() {}
EVisualEffect getCode() const { return m_eCode;}
bool getEnabled() const { return m_fEnabled; }
const LLUUID& getId() const { return m_id;}
U32 getPriority() const { return m_nPriority; }
EVisualEffectType getType() const { return m_eType;}
void setEnabled(bool enable) { m_fEnabled = enable; }
virtual void run(const LLVisualEffectParams* pParams) = 0;
protected:
void setPriority(U32 priority) { m_nPriority = priority; }
/*
* Member variables
*/
protected:
LLUUID m_id;
EVisualEffect m_eCode;
EVisualEffectType m_eType;
bool m_fEnabled = true;
U32 m_nPriority = 0;
};
// ============================================================================
//
//
template<typename T>
class LLTweenableValue
{
public:
LLTweenableValue(const T& defaultValue) : m_CurValue(defaultValue) {}
virtual ~LLTweenableValue() {}
virtual T get() = 0;
virtual void start(const T& endValue, double duration) = 0;
T& operator =(const T& value) { m_CurValue = value; }
/*
* Member variables
*/
protected:
boost::optional<T> m_CurValue;
};
template<typename T>
class LLTweenableValueLerp : public LLTweenableValue<T>
{
public:
LLTweenableValueLerp(const T& defaultValue) : LLTweenableValue<T>(defaultValue) {}
T get() override;
void start(const T& endValue, double duration) override
{
m_StartValue = get();
this->m_CurValue = boost::none;
m_EndValue = endValue;
m_StartTime = LLTimer::getElapsedSeconds();
m_Duration = duration;
}
/*
* Member variables
*/
protected:
double m_StartTime;
double m_Duration;
T m_StartValue;
T m_EndValue;
};
// ============================================================================
//
//
class LLVfxManager : public LLSingleton<LLVfxManager>
{
LLSINGLETON(LLVfxManager);
protected:
~LLVfxManager() {}
/*
* Member functions
*/
public:
bool addEffect(LLVisualEffect* pEffectInst);
LLVisualEffect* getEffect(EVisualEffect eCode, const LLUUID& idEffect) const;
template<typename T> T* getEffect(const LLUUID& idEffect) const { return dynamic_cast<T*>(getEffect(T::EffectCode, idEffect)); }
bool getEffects(std::list<LLVisualEffect*>& effectList, std::function<bool(const LLVisualEffect*)> fnFilter);
template<typename T> bool getEffects(std::list<T*>& effectList);
bool hasEffect(EVisualEffect eCode) const;
bool removeEffect(EVisualEffect eCode, const LLUUID& idEffect);
template<typename T> bool removeEffect(const LLUUID& idEffect) { return removeEffect(T::EffectCode, idEffect); }
void runEffect(EVisualEffect eCode, LLVisualEffectParams* pParams = nullptr);
void runEffect(EVisualEffectType eType, LLVisualEffectParams* pParams = nullptr);
void updateEffect(LLVisualEffect* pEffect, bool fEnabled, U32 nPriority);
protected:
void runEffect(std::function<bool(const LLVisualEffect*)> fnFilter, LLVisualEffectParams* pParams);
static bool cmpEffect(const LLVisualEffect* pLHS, const LLVisualEffect* pRHS);
/*
* Member variables
*/
protected:
std::vector<LLVisualEffect*> m_Effects;
};
// ============================================================================
// Inlined member functions
//
inline bool LLVfxManager::hasEffect(EVisualEffect eCode) const
{
return m_Effects.end() != std::find_if(m_Effects.begin(), m_Effects.end(), [eCode](const LLVisualEffect* pEffect) { return pEffect->getCode() == eCode; });
}
template<typename T>
inline bool LLVfxManager::getEffects(std::list<T*>& effectList)
{
effectList.clear();
std::function<bool(const LLVisualEffect*)> fnFilter = [](const LLVisualEffect* pEffect) { return pEffect->getCode() == T::EffectCode; };
auto itEffect = boost::make_filter_iterator(fnFilter, m_Effects.begin(), m_Effects.end()),
endEffect = boost::make_filter_iterator(fnFilter, m_Effects.end(), m_Effects.end());
while (itEffect != endEffect)
{
if (T* pEffect = dynamic_cast<T*>(*itEffect++))
{
effectList.push_back(pEffect);
}
}
return effectList.size();
}
// ============================================================================