| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444 |
- /*
- * Copyright (c) Contributors to the Open 3D Engine Project.
- * For complete copyright and license terms please see the LICENSE at the root of this distribution.
- *
- * SPDX-License-Identifier: Apache-2.0 OR MIT
- *
- */
- #include <AzCore/Serialization/SerializeContext.h>
- #include <AzCore/std/smart_ptr/unique_ptr.h>
- #include "AnimPostFXNode.h"
- #include "AnimSplineTrack.h"
- #include "CompoundSplineTrack.h"
- #include "BoolTrack.h"
- #include "Maestro/Types/AnimNodeType.h"
- #include "Maestro/Types/AnimParamType.h"
- #include "Maestro/Types/AnimValueType.h"
- //////////////////////////////////////////////////////////////////////////
- //!
- class CFXNodeDescription
- : public _i_reference_target_t
- {
- public:
- //-----------------------------------------------------------------------------
- //!
- class CControlParamBase
- : public _i_reference_target_t
- {
- public:
- virtual void SetDefault(float val) = 0;
- virtual void SetDefault(bool val) = 0;
- virtual void SetDefault(Vec4 val) = 0;
- virtual void GetDefault(float& val) const = 0;
- virtual void GetDefault(bool& val) const = 0;
- virtual void GetDefault(Vec4& val) const = 0;
- AZStd::string m_name;
- protected:
- virtual ~CControlParamBase(){}
- };
- //-----------------------------------------------------------------------------
- //!
- template<typename T>
- class TControlParam
- : public CControlParamBase
- {
- public:
- virtual void SetDefault([[maybe_unused]] float val) { assert(0); }
- virtual void SetDefault([[maybe_unused]] bool val) { assert(0); }
- virtual void SetDefault([[maybe_unused]] Vec4 val) { assert(0); }
- virtual void GetDefault([[maybe_unused]] float& val) const { assert(0); }
- virtual void GetDefault([[maybe_unused]] bool& val) const { assert(0); }
- virtual void GetDefault([[maybe_unused]] Vec4& val) const { assert(0); }
- protected:
- virtual ~TControlParam(){}
- T m_defaultValue;
- };
- //-----------------------------------------------------------------------------
- //!
- CFXNodeDescription() {}
- //-----------------------------------------------------------------------------
- //!
- template<typename T>
- void AddSupportedParam(const char* sName, AnimValueType eValueType, const char* sControlName, T defaultValue)
- {
- CAnimNode::SParamInfo param;
- param.name = sName;
- param.paramType = static_cast<AnimParamType>(static_cast<int>(AnimParamType::User) + static_cast<int>(m_nodeParams.size()));
- param.valueType = eValueType;
- m_nodeParams.push_back(param);
- TControlParam<T>* control = new TControlParam<T>;
- control->m_name = sControlName;
- control->SetDefault(defaultValue);
- m_controlParams.push_back(control);
- }
- //-----------------------------------------------------------------------------
- //!
- AZStd::vector<CAnimNode::SParamInfo> m_nodeParams;
- AZStd::vector<_smart_ptr<CControlParamBase>> m_controlParams;
- };
- //-----------------------------------------------------------------------------
- template<>
- void CFXNodeDescription::TControlParam<float>::SetDefault(float val)
- {
- m_defaultValue = val;
- }
- template<>
- void CFXNodeDescription::TControlParam<bool>::SetDefault(bool val)
- {
- m_defaultValue = val;
- }
- template<>
- void CFXNodeDescription::TControlParam<Vec4>::SetDefault(Vec4 val)
- {
- m_defaultValue = val;
- }
- template<>
- void CFXNodeDescription::TControlParam<float>::GetDefault(float& val) const
- {
- val = m_defaultValue;
- }
- template<>
- void CFXNodeDescription::TControlParam<bool>::GetDefault(bool& val) const
- {
- val = m_defaultValue;
- }
- template<>
- void CFXNodeDescription::TControlParam<Vec4>::GetDefault(Vec4& val) const
- {
- val = m_defaultValue;
- }
- //-----------------------------------------------------------------------------
- CAnimPostFXNode::FxNodeDescriptionMap CAnimPostFXNode::s_fxNodeDescriptions;
- //-----------------------------------------------------------------------------
- CAnimPostFXNode::CAnimPostFXNode()
- : CAnimPostFXNode(0, AnimNodeType::Invalid, nullptr)
- {
- }
- //-----------------------------------------------------------------------------
- CAnimPostFXNode::CAnimPostFXNode(const int id, AnimNodeType nodeType, CFXNodeDescription* pDesc)
- : CAnimNode(id, nodeType)
- , m_pDescription(pDesc)
- {
- }
- //-----------------------------------------------------------------------------
- void CAnimPostFXNode::Initialize()
- {
- if (!s_initialized)
- {
- s_initialized = true;
- //////////////////////////////////////////////////////////////////////////
- //! Radial Blur
- {
- auto pDesc = AZStd::make_unique<CFXNodeDescription>();
- pDesc->m_nodeParams.reserve(4);
- pDesc->m_controlParams.reserve(4);
- pDesc->AddSupportedParam<float>("Amount", AnimValueType::Float, "FilterRadialBlurring_Amount", 0.0f);
- pDesc->AddSupportedParam<float>("ScreenPosX", AnimValueType::Float, "FilterRadialBlurring_ScreenPosX", 0.5f);
- pDesc->AddSupportedParam<float>("ScreenPosY", AnimValueType::Float, "FilterRadialBlurring_ScreenPosY", 0.5f);
- pDesc->AddSupportedParam<float>("BlurringRadius", AnimValueType::Float, "FilterRadialBlurring_Radius", 1.0f);
- s_fxNodeDescriptions.try_emplace(AnimNodeType::RadialBlur, AZStd::move(pDesc));
- }
- //////////////////////////////////////////////////////////////////////////
- //! Color Correction
- {
- auto pDesc = AZStd::make_unique<CFXNodeDescription>();
- pDesc->m_nodeParams.reserve(8);
- pDesc->m_controlParams.reserve(8);
- pDesc->AddSupportedParam<float>("Cyan", AnimValueType::Float, "Global_User_ColorC", 0.0f);
- pDesc->AddSupportedParam<float>("Magenta", AnimValueType::Float, "Global_User_ColorM", 0.0f);
- pDesc->AddSupportedParam<float>("Yellow", AnimValueType::Float, "Global_User_ColorY", 0.0f);
- pDesc->AddSupportedParam<float>("Luminance", AnimValueType::Float, "Global_User_ColorK", 0.0f);
- pDesc->AddSupportedParam<float>("Brightness", AnimValueType::Float, "Global_User_Brightness", 1.0f);
- pDesc->AddSupportedParam<float>("Contrast", AnimValueType::Float, "Global_User_Contrast", 1.0f);
- pDesc->AddSupportedParam<float>("Saturation", AnimValueType::Float, "Global_User_Saturation", 1.0f);
- pDesc->AddSupportedParam<float>("Hue", AnimValueType::Float, "Global_User_ColorHue", 0.0f);
- s_fxNodeDescriptions.try_emplace(AnimNodeType::ColorCorrection, AZStd::move(pDesc));
- }
- //////////////////////////////////////////////////////////////////////////
- //! Depth of Field
- {
- auto pDesc = AZStd::make_unique<CFXNodeDescription>();
- pDesc->m_nodeParams.reserve(4);
- pDesc->m_controlParams.reserve(4);
- pDesc->AddSupportedParam<bool>("Enable", AnimValueType::Bool, "Dof_User_Active", false);
- pDesc->AddSupportedParam<float>("FocusDistance", AnimValueType::Float, "Dof_User_FocusDistance", 3.5f);
- pDesc->AddSupportedParam<float>("FocusRange", AnimValueType::Float, "Dof_User_FocusRange", 5.0f);
- pDesc->AddSupportedParam<float>("BlurAmount", AnimValueType::Float, "Dof_User_BlurAmount", 1.0f);
- s_fxNodeDescriptions.try_emplace(AnimNodeType::DepthOfField, AZStd::move(pDesc));
- }
- //////////////////////////////////////////////////////////////////////////
- //! Shadow setup - expose couple shadow controls to cinematics
- {
- auto pDesc = AZStd::make_unique<CFXNodeDescription>();
- pDesc->m_nodeParams.reserve(1);
- pDesc->m_controlParams.reserve(1);
- pDesc->AddSupportedParam<float>("GSMCache", AnimValueType::Bool, "GSMCacheParam", true);
- s_fxNodeDescriptions.try_emplace(AnimNodeType::ShadowSetup, AZStd::move(pDesc));
- }
- }
- }
- //-----------------------------------------------------------------------------
- /*static*/ CFXNodeDescription* CAnimPostFXNode::GetFXNodeDescription(AnimNodeType nodeType)
- {
- CFXNodeDescription* retDescription = nullptr;
- CAnimPostFXNode::Initialize();
- FxNodeDescriptionMap::iterator itr = s_fxNodeDescriptions.find(nodeType);
- if (itr != s_fxNodeDescriptions.end())
- {
- retDescription = itr->second.get();
- }
- return retDescription;
- }
- //-----------------------------------------------------------------------------
- CAnimNode* CAnimPostFXNode::CreateNode(const int id, AnimNodeType nodeType)
- {
- CAnimNode* retNode = nullptr;
- CFXNodeDescription* pDesc = GetFXNodeDescription(nodeType);
- if (pDesc)
- {
- retNode = aznew CAnimPostFXNode(id, nodeType, pDesc);
- static_cast<CAnimPostFXNode*>(retNode)->m_nodeType = nodeType;
- }
- return retNode;
- }
- //-----------------------------------------------------------------------------
- void CAnimPostFXNode::InitPostLoad(IAnimSequence* sequence)
- {
- CAnimNode::InitPostLoad(sequence);
- // For AZ::Serialization, m_nodeType will have be reflected and deserialized. Find the appropriate FXNodeDescription for it
- // and store the pointer
- m_pDescription = GetFXNodeDescription(m_nodeType);
- if (!m_pDescription)
- {
- // This is not ideal - we should never get here unless someone is tampering with data. We can't remove the node at this point,
- // we can't use a defatult description without crashing later, so we simply assert.
- AZ_Assert(false, "Unrecognized PostFX nodeType in Track View node %s. Please remove this node from the sequence.", m_name.c_str());
- }
- }
- //-----------------------------------------------------------------------------
- void CAnimPostFXNode::SerializeAnims(XmlNodeRef& xmlNode, bool bLoading, bool bLoadEmptyTracks)
- {
- if (bLoading)
- {
- int paramIdVersion = 0;
- xmlNode->getAttr("ParamIdVersion", paramIdVersion);
- // Fix old param types
- if (paramIdVersion <= 2)
- {
- int num = xmlNode->getChildCount();
- for (int i = 0; i < num; ++i)
- {
- XmlNodeRef trackNode = xmlNode->getChild(i);
- CAnimParamType paramType;
- paramType.Serialize(trackNode, true);
- // Don't use APARAM_USER because it could change in newer versions
- // CAnimNode::SerializeAnims will then take care of that
- paramType = static_cast<AnimParamType>(static_cast<int>(paramType.GetType()) + OLD_APARAM_USER);
- paramType.Serialize(trackNode, false);
- }
- }
- }
- CAnimNode::SerializeAnims(xmlNode, bLoading, bLoadEmptyTracks);
- }
- //-----------------------------------------------------------------------------
- unsigned int CAnimPostFXNode::GetParamCount() const
- {
- return static_cast<unsigned int>(m_pDescription->m_nodeParams.size());
- }
- //-----------------------------------------------------------------------------
- CAnimParamType CAnimPostFXNode::GetParamType(unsigned int nIndex) const
- {
- if (nIndex < m_pDescription->m_nodeParams.size())
- {
- return m_pDescription->m_nodeParams[nIndex].paramType;
- }
- return AnimParamType::Invalid;
- }
- //-----------------------------------------------------------------------------
- bool CAnimPostFXNode::GetParamInfoFromType(const CAnimParamType& paramId, SParamInfo& info) const
- {
- for (size_t i = 0; i < m_pDescription->m_nodeParams.size(); ++i)
- {
- if (m_pDescription->m_nodeParams[i].paramType == paramId)
- {
- info = m_pDescription->m_nodeParams[i];
- return true;
- }
- }
- return false;
- }
- //-----------------------------------------------------------------------------
- void CAnimPostFXNode::CreateDefaultTracks()
- {
- for (size_t i = 0; i < m_pDescription->m_nodeParams.size(); ++i)
- {
- IAnimTrack* pTrack = CreateTrackInternal(m_pDescription->m_nodeParams[i].paramType,
- eAnimCurveType_BezierFloat, m_pDescription->m_nodeParams[i].valueType);
- //Setup default value
- AnimValueType valueType = m_pDescription->m_nodeParams[i].valueType;
- if (valueType == AnimValueType::Float)
- {
- C2DSplineTrack* pFloatTrack = static_cast<C2DSplineTrack*>(pTrack);
- float val(0);
- m_pDescription->m_controlParams[i]->GetDefault(val);
- pFloatTrack->SetDefaultValue(Vec2(0, val));
- }
- else if (valueType == AnimValueType::Bool)
- {
- CBoolTrack* pBoolTrack = static_cast<CBoolTrack*>(pTrack);
- bool val = false;
- m_pDescription->m_controlParams[i]->GetDefault(val);
- pBoolTrack->SetDefaultValue(val);
- }
- else if (valueType == AnimValueType::Vector4)
- {
- CCompoundSplineTrack* pCompoundTrack = static_cast<CCompoundSplineTrack*>(pTrack);
- Vec4 val(0.0f, 0.0f, 0.0f, 0.0f);
- m_pDescription->m_controlParams[i]->GetDefault(val);
- pCompoundTrack->SetValue(0.0f, val, true);
- }
- }
- }
- //-----------------------------------------------------------------------------
- void CAnimPostFXNode::Animate(SAnimContext& ac)
- {
- for (size_t i = 0; i < m_tracks.size(); ++i)
- {
- IAnimTrack* pTrack = m_tracks[i].get();
- assert(pTrack);
- size_t paramIndex = (size_t)static_cast<int>(m_tracks[i]->GetParameterType().GetType()) - static_cast<int>(AnimParamType::User);
- assert(paramIndex < m_pDescription->m_nodeParams.size());
- if (pTrack->GetFlags() & IAnimTrack::eAnimTrackFlags_Disabled)
- {
- continue;
- }
- if (pTrack->IsMasked(ac.trackMask))
- {
- continue;
- }
- AnimValueType valueType = m_pDescription->m_nodeParams[paramIndex].valueType;
- // sorry: quick & dirty solution for c2 shipping - custom type handling for shadows - make this properly after shipping
- if (GetType() == AnimNodeType::ShadowSetup && valueType == AnimValueType::Bool)
- {
- bool val(false);
- pTrack->GetValue(ac.time, val);
- }
- else
- if (valueType == AnimValueType::Float)
- {
- float val(0);
- pTrack->GetValue(ac.time, val);
- }
- else if (valueType == AnimValueType::Bool)
- {
- bool val(false);
- pTrack->GetValue(ac.time, val);
- }
- else if (valueType == AnimValueType::Vector4)
- {
- Vec4 val(0.0f, 0.0f, 0.0f, 0.0f);
- static_cast<CCompoundSplineTrack*>(pTrack)->GetValue(ac.time, val);
- }
- }
- }
- //-----------------------------------------------------------------------------
- void CAnimPostFXNode::OnReset()
- {
- CAnimNode::OnReset();
- // Reset each postFX param to its default.
- for (size_t i = 0; i < m_tracks.size(); ++i)
- {
- assert(m_tracks[i].get());
- size_t paramIndex = (size_t)static_cast<int>(m_tracks[i]->GetParameterType().GetType()) - static_cast<int>(AnimParamType::User);
- assert(paramIndex < m_pDescription->m_nodeParams.size());
- AnimValueType valueType = m_pDescription->m_nodeParams[paramIndex].valueType;
- // sorry: quick & dirty solution for c2 shipping - custom type handling for shadows - make this properly after shipping
- if (GetType() == AnimNodeType::ShadowSetup && valueType == AnimValueType::Bool)
- {
- bool val(false);
- m_pDescription->m_controlParams[paramIndex]->GetDefault(val);
- }
- else
- if (valueType == AnimValueType::Float)
- {
- float val(0);
- m_pDescription->m_controlParams[paramIndex]->GetDefault(val);
- }
- else if (valueType == AnimValueType::Bool)
- {
- bool val(false);
- m_pDescription->m_controlParams[paramIndex]->GetDefault(val);
- }
- else if (valueType == AnimValueType::Vector4)
- {
- Vec4 val(0.0f, 0.0f, 0.0f, 0.0f);
- m_pDescription->m_controlParams[paramIndex]->GetDefault(val);
- }
- }
- }
- //////////////////////////////////////////////////////////////////////////
- void CAnimPostFXNode::Reflect(AZ::ReflectContext* context)
- {
- if (auto serializeContext = azrtti_cast<AZ::SerializeContext*>(context))
- {
- serializeContext->Class<CAnimPostFXNode, CAnimNode>()
- ->Version(1);
- }
- }
|