AnimScreenFaderNode.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393
  1. /*
  2. * Copyright (c) Contributors to the Open 3D Engine Project.
  3. * For complete copyright and license terms please see the LICENSE at the root of this distribution.
  4. *
  5. * SPDX-License-Identifier: Apache-2.0 OR MIT
  6. *
  7. */
  8. #include <AzCore/Serialization/SerializeContext.h>
  9. #include "AnimScreenFaderNode.h"
  10. #include "ScreenFaderTrack.h"
  11. #include <IRenderer.h>
  12. #include "Maestro/Types/AnimNodeType.h"
  13. #include "Maestro/Types/AnimValueType.h"
  14. #include "Maestro/Types/AnimParamType.h"
  15. //-----------------------------------------------------------------------------
  16. namespace
  17. {
  18. bool s_screenFaderNodeParamsInitialized = false;
  19. AZStd::vector<CAnimNode::SParamInfo> s_screenFaderNodeParams;
  20. void AddSupportedParams(const char* sName, AnimParamType paramId, AnimValueType valueType)
  21. {
  22. CAnimNode::SParamInfo param;
  23. param.name = sName;
  24. param.paramType = paramId;
  25. param.valueType = valueType;
  26. param.flags = IAnimNode::eSupportedParamFlags_MultipleTracks;
  27. s_screenFaderNodeParams.push_back(param);
  28. }
  29. };
  30. //-----------------------------------------------------------------------------
  31. bool CalculateIsolatedKeyColor(const IScreenFaderKey& key, float fTime, Vec4& colorOut)
  32. {
  33. float ratio = fTime - key.time;
  34. if (ratio < 0.f)
  35. {
  36. return false;
  37. }
  38. if (key.m_fadeTime == 0.f)
  39. {
  40. colorOut(key.m_fadeColor.GetR(), key.m_fadeColor.GetG(), key.m_fadeColor.GetB(), key.m_fadeColor.GetA());
  41. if (key.m_fadeType == IScreenFaderKey::eFT_FadeIn)
  42. {
  43. colorOut.w = 0.f;
  44. }
  45. else
  46. {
  47. colorOut.w = 1.f;
  48. }
  49. }
  50. else
  51. {
  52. colorOut(key.m_fadeColor.GetR(), key.m_fadeColor.GetG(), key.m_fadeColor.GetB(), key.m_fadeColor.GetA());
  53. ratio = ratio / key.m_fadeTime;
  54. if (key.m_fadeType == IScreenFaderKey::eFT_FadeIn)
  55. {
  56. colorOut.w = MAX(0.f, 1.f - ratio);
  57. }
  58. else
  59. {
  60. colorOut.w = MIN(1.f, ratio);
  61. }
  62. }
  63. return true;
  64. }
  65. //-----------------------------------------------------------------------------
  66. CAnimScreenFaderNode::CAnimScreenFaderNode(const int id)
  67. : CAnimNode(id, AnimNodeType::ScreenFader)
  68. , m_bActive(false)
  69. , m_screenWidth(800.f)
  70. , m_screenHeight(600.f)
  71. , m_lastActivatedKey(-1)
  72. , m_texPrecached(false)
  73. {
  74. m_startColor = Vec4(1, 1, 1, 1);
  75. CAnimScreenFaderNode::Initialize();
  76. PrecacheTexData();
  77. }
  78. CAnimScreenFaderNode::CAnimScreenFaderNode()
  79. : CAnimScreenFaderNode(0)
  80. {
  81. }
  82. CAnimScreenFaderNode::~CAnimScreenFaderNode()
  83. {
  84. }
  85. //-----------------------------------------------------------------------------
  86. void CAnimScreenFaderNode::Initialize()
  87. {
  88. if (!s_screenFaderNodeParamsInitialized)
  89. {
  90. s_screenFaderNodeParamsInitialized = true;
  91. s_screenFaderNodeParams.reserve(1);
  92. AddSupportedParams("Fader", AnimParamType::ScreenFader, AnimValueType::Unknown);
  93. }
  94. }
  95. //-----------------------------------------------------------------------------
  96. void CAnimScreenFaderNode::Animate(SAnimContext& ac)
  97. {
  98. size_t const nScreenFaderTracksNumber = m_tracks.size();
  99. for (size_t nFaderTrackNo = 0; nFaderTrackNo < nScreenFaderTracksNumber; ++nFaderTrackNo)
  100. {
  101. CScreenFaderTrack* pTrack = static_cast<CScreenFaderTrack*>(GetTrackForParameter(AnimParamType::ScreenFader, static_cast<uint32>(nFaderTrackNo)));
  102. if (!pTrack)
  103. {
  104. continue;
  105. }
  106. if (pTrack->GetNumKeys() == 0)
  107. {
  108. continue;
  109. }
  110. if (pTrack->GetFlags() & IAnimTrack::eAnimTrackFlags_Disabled)
  111. {
  112. continue;
  113. }
  114. if (pTrack->IsMasked(ac.trackMask))
  115. {
  116. continue;
  117. }
  118. if (ac.singleFrame)
  119. {
  120. m_lastActivatedKey = -1;
  121. }
  122. IScreenFaderKey key;
  123. int nActiveKeyIndex = pTrack->GetActiveKey(ac.time, &key);
  124. if (nActiveKeyIndex >= 0)
  125. {
  126. if (m_lastActivatedKey != nActiveKeyIndex)
  127. {
  128. m_lastActivatedKey = nActiveKeyIndex;
  129. m_bActive = true;
  130. if (!key.m_strTexture.empty())
  131. {
  132. if (pTrack->SetActiveTexture(nActiveKeyIndex))
  133. {
  134. pTrack->SetTextureVisible(true);
  135. }
  136. else
  137. {
  138. pTrack->SetTextureVisible(false);
  139. }
  140. }
  141. else
  142. {
  143. pTrack->SetTextureVisible(false);
  144. }
  145. }
  146. if (m_bActive || key.m_fadeTime + key.time > ac.time)
  147. {
  148. float ratio = (key.m_fadeTime > 0) ? (ac.time - key.time) / key.m_fadeTime : 1.f;
  149. if (ratio < 0.f)
  150. {
  151. ratio = 0.f;
  152. }
  153. ratio = MIN(ratio, 1.f);
  154. switch (key.m_fadeChangeType)
  155. {
  156. case IScreenFaderKey::eFCT_Square:
  157. ratio = ratio * ratio;
  158. break;
  159. case IScreenFaderKey::eFCT_CubicSquare:
  160. ratio = ratio * ratio * ratio;
  161. break;
  162. case IScreenFaderKey::eFCT_SquareRoot:
  163. ratio = sqrt(ratio);
  164. break;
  165. case IScreenFaderKey::eFCT_Sin:
  166. ratio = sinf(ratio * 3.14159265f * 0.5f);
  167. break;
  168. }
  169. if (!key.m_bUseCurColor || nActiveKeyIndex == 0)
  170. {
  171. m_startColor(key.m_fadeColor.GetR(), key.m_fadeColor.GetG(), key.m_fadeColor.GetB(), key.m_fadeColor.GetA());
  172. }
  173. else
  174. {
  175. IScreenFaderKey preKey;
  176. pTrack->GetKey(nActiveKeyIndex - 1, &preKey);
  177. CalculateIsolatedKeyColor(preKey, ac.time, m_startColor);
  178. }
  179. if (key.m_fadeType == IScreenFaderKey::eFT_FadeIn)
  180. {
  181. if (!key.m_bUseCurColor || nActiveKeyIndex == 0)
  182. {
  183. m_startColor.w = 1.f;
  184. }
  185. key.m_fadeColor.SetA(0.f);
  186. }
  187. else
  188. {
  189. if (!key.m_bUseCurColor || nActiveKeyIndex == 0)
  190. {
  191. m_startColor.w = 0.f;
  192. }
  193. key.m_fadeColor.SetA(1.f);
  194. }
  195. Vec4 fadeColorAsVec4(key.m_fadeColor.GetR(), key.m_fadeColor.GetG(), key.m_fadeColor.GetB(), key.m_fadeColor.GetA());
  196. pTrack->SetDrawColor(m_startColor + (fadeColorAsVec4 - m_startColor) * ratio);
  197. if (pTrack->GetDrawColor().w < 0.01f)
  198. {
  199. m_bActive = IsAnyTextureVisible();
  200. }
  201. else
  202. {
  203. m_bActive = true;
  204. }
  205. }
  206. }
  207. else
  208. {
  209. pTrack->SetTextureVisible(false);
  210. m_bActive = IsAnyTextureVisible();
  211. }
  212. }
  213. }
  214. //-----------------------------------------------------------------------------
  215. void CAnimScreenFaderNode::CreateDefaultTracks()
  216. {
  217. CreateTrack(AnimParamType::ScreenFader);
  218. }
  219. //-----------------------------------------------------------------------------
  220. void CAnimScreenFaderNode::OnReset()
  221. {
  222. CAnimNode::OnReset();
  223. m_bActive = false;
  224. }
  225. //-----------------------------------------------------------------------------
  226. void CAnimScreenFaderNode::Activate(bool bActivate)
  227. {
  228. if (bActivate)
  229. {
  230. m_bActive = false;
  231. }
  232. if (m_texPrecached == false)
  233. {
  234. PrecacheTexData();
  235. }
  236. }
  237. //-----------------------------------------------------------------------------
  238. /// @deprecated Serialization for Sequence data in Component Entity Sequences now occurs through AZ::SerializeContext and the Sequence Component
  239. void CAnimScreenFaderNode::Serialize
  240. (XmlNodeRef& xmlNode, bool bLoading, bool bLoadEmptyTracks)
  241. {
  242. CAnimNode::Serialize(xmlNode, bLoading, bLoadEmptyTracks);
  243. if (bLoading)
  244. {
  245. PrecacheTexData();
  246. }
  247. }
  248. //////////////////////////////////////////////////////////////////////////
  249. void CAnimScreenFaderNode::Reflect(AZ::ReflectContext* context)
  250. {
  251. if (auto serializeContext = azrtti_cast<AZ::SerializeContext*>(context))
  252. {
  253. serializeContext->Class<CAnimScreenFaderNode, CAnimNode>()
  254. ->Version(1);
  255. }
  256. }
  257. //-----------------------------------------------------------------------------
  258. unsigned int CAnimScreenFaderNode::GetParamCount() const
  259. {
  260. return static_cast<unsigned int>(s_screenFaderNodeParams.size());
  261. }
  262. //-----------------------------------------------------------------------------
  263. CAnimParamType CAnimScreenFaderNode::GetParamType(unsigned int nIndex) const
  264. {
  265. if (nIndex < s_screenFaderNodeParams.size())
  266. {
  267. return s_screenFaderNodeParams[nIndex].paramType;
  268. }
  269. return AnimParamType::Invalid;
  270. }
  271. //-----------------------------------------------------------------------------
  272. void CAnimScreenFaderNode::SetFlags(int flags)
  273. {
  274. // call base class implementation. I'm avoiding the use of the Microsoft specific __super::SetFlags(flags) because it is not
  275. // platform agnostic
  276. CAnimNode::SetFlags(flags);
  277. if (flags & eAnimNodeFlags_Disabled)
  278. {
  279. // for screen faders, when disabling, we want to reset so the screen doesn't stay partially faded if a fade was in
  280. // effect when disabled
  281. OnReset();
  282. }
  283. }
  284. //-----------------------------------------------------------------------------
  285. bool CAnimScreenFaderNode::GetParamInfoFromType(const CAnimParamType& paramId, SParamInfo& info) const
  286. {
  287. for (size_t i = 0; i < s_screenFaderNodeParams.size(); ++i)
  288. {
  289. if (s_screenFaderNodeParams[i].paramType == paramId)
  290. {
  291. info = s_screenFaderNodeParams[i];
  292. return true;
  293. }
  294. }
  295. return false;
  296. }
  297. //-----------------------------------------------------------------------------
  298. void CAnimScreenFaderNode::Render()
  299. {
  300. }
  301. bool CAnimScreenFaderNode::IsAnyTextureVisible() const
  302. {
  303. size_t const paramCount = m_tracks.size();
  304. for (size_t paramIndex = 0; paramIndex < paramCount; ++paramIndex)
  305. {
  306. CScreenFaderTrack* pTrack = static_cast<CScreenFaderTrack*>(GetTrackForParameter(AnimParamType::ScreenFader, static_cast<uint32>(paramIndex)));
  307. if (!pTrack)
  308. {
  309. continue;
  310. }
  311. if (pTrack->IsTextureVisible())
  312. {
  313. return true;
  314. }
  315. }
  316. return false;
  317. }
  318. void CAnimScreenFaderNode::PrecacheTexData()
  319. {
  320. size_t const paramCount = m_tracks.size();
  321. for (size_t paramIndex = 0; paramIndex < paramCount; ++paramIndex)
  322. {
  323. IAnimTrack* pTrack = m_tracks[paramIndex].get();
  324. if (!pTrack)
  325. {
  326. continue;
  327. }
  328. switch (m_tracks[paramIndex]->GetParameterType().GetType())
  329. {
  330. case AnimParamType::ScreenFader:
  331. {
  332. CScreenFaderTrack* pFaderTrack = static_cast<CScreenFaderTrack*>(pTrack);
  333. pFaderTrack->PreloadTextures();
  334. }
  335. break;
  336. }
  337. }
  338. m_texPrecached = true;
  339. }