AnimTrack.h 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608
  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. #pragma once
  9. //forward declarations.
  10. #include <LyShine/Animation/IUiAnimation.h>
  11. #include "UiAnimSerialize.h"
  12. #include <AzCore/RTTI/TypeInfo.h>
  13. /** General templated track for event type keys.
  14. KeyType class must be derived from IKey.
  15. */
  16. template <class KeyType>
  17. class TUiAnimTrack
  18. : public IUiAnimTrack
  19. {
  20. public:
  21. AZ_CLASS_ALLOCATOR(TUiAnimTrack, AZ::SystemAllocator)
  22. AZ_RTTI((TUiAnimTrack, "{5513FA16-991D-40DD-99B2-9C5531AC872C}", KeyType), IUiAnimTrack);
  23. TUiAnimTrack();
  24. EUiAnimCurveType GetCurveType() override { return eUiAnimCurveType_Unknown; };
  25. EUiAnimValue GetValueType() override { return eUiAnimValue_Unknown; }
  26. int GetSubTrackCount() const override { return 0; };
  27. IUiAnimTrack* GetSubTrack([[maybe_unused]] int nIndex) const override { return 0; };
  28. AZStd::string GetSubTrackName([[maybe_unused]] int nIndex) const override { return AZStd::string(); };
  29. void SetSubTrackName([[maybe_unused]] int nIndex, [[maybe_unused]] const char* name) override { assert(0); }
  30. const CUiAnimParamType& GetParameterType() const override { return m_nParamType; };
  31. void SetParameterType(CUiAnimParamType type) override { m_nParamType = type; };
  32. const UiAnimParamData& GetParamData() const override { return m_componentParamData; }
  33. void SetParamData(const UiAnimParamData& param) override { m_componentParamData = param; }
  34. //////////////////////////////////////////////////////////////////////////
  35. // for intrusive_ptr support
  36. void add_ref() override;
  37. void release() override;
  38. //////////////////////////////////////////////////////////////////////////
  39. bool IsKeySelected(int key) const override
  40. {
  41. AZ_Assert(key >= 0 && key < (int)m_keys.size(), "Key index is out of range");
  42. if (m_keys[key].flags & AKEY_SELECTED)
  43. {
  44. return true;
  45. }
  46. return false;
  47. }
  48. void SelectKey(int key, bool select) override
  49. {
  50. AZ_Assert(key >= 0 && key < (int)m_keys.size(), "Key index is out of range");
  51. if (select)
  52. {
  53. m_keys[key].flags |= AKEY_SELECTED;
  54. }
  55. else
  56. {
  57. m_keys[key].flags &= ~AKEY_SELECTED;
  58. }
  59. }
  60. //! Return number of keys in track.
  61. int GetNumKeys() const override { return static_cast<int>(m_keys.size()); };
  62. //! Return true if keys exists in this track
  63. bool HasKeys() const override { return !m_keys.empty(); }
  64. //! Set number of keys in track.
  65. //! If needed adds empty keys at end or remove keys from end.
  66. void SetNumKeys(int numKeys) override { m_keys.resize(numKeys); };
  67. //! Remove specified key.
  68. void RemoveKey(int num) override;
  69. int CreateKey(float time) override;
  70. int CloneKey(int fromKey) override;
  71. int CopyKey(IUiAnimTrack* pFromTrack, int nFromKey) override;
  72. //! Get key at specified location.
  73. //! @param key Must be valid pointer to compatible key structure, to be filled with specified key location.
  74. void GetKey(int index, IKey* key) const override;
  75. //! Get time of specified key.
  76. //! @return key time.
  77. float GetKeyTime(int index) const override;
  78. //! Find key at given time.
  79. //! @return Index of found key, or -1 if key with this time not found.
  80. int FindKey(float time) override;
  81. //! Get flags of specified key.
  82. //! @return key time.
  83. int GetKeyFlags(int index) override;
  84. //! Set key at specified location.
  85. //! @param key Must be valid pointer to compatible key structure.
  86. void SetKey(int index, IKey* key) override;
  87. //! Set time of specified key.
  88. void SetKeyTime(int index, float time) override;
  89. //! Set flags of specified key.
  90. void SetKeyFlags(int index, int flags) override;
  91. //! Sort keys in track (after time of keys was modified).
  92. void SortKeys() override;
  93. //! Get track flags.
  94. int GetFlags() override { return m_flags; }
  95. //! Check if track is masked
  96. bool IsMasked([[maybe_unused]] const uint32 mask) const override { return false; }
  97. //! Set track flags.
  98. void SetFlags(int flags) override { m_flags = flags; }
  99. //////////////////////////////////////////////////////////////////////////
  100. // Get track value at specified time.
  101. // Interpolates keys if needed.
  102. //////////////////////////////////////////////////////////////////////////
  103. void GetValue([[maybe_unused]] float time, [[maybe_unused]] float& value) override { assert(0); };
  104. void GetValue([[maybe_unused]] float time, [[maybe_unused]] Vec3& value) override { assert(0); };
  105. void GetValue([[maybe_unused]] float time, [[maybe_unused]] Vec4& value) override { assert(0); };
  106. void GetValue([[maybe_unused]] float time, [[maybe_unused]] Quat& value) override { assert(0); };
  107. void GetValue([[maybe_unused]] float time, [[maybe_unused]] bool& value) override { assert(0); };
  108. void GetValue([[maybe_unused]] float time, [[maybe_unused]] AZ::Vector2& value) override { assert(0); };
  109. void GetValue([[maybe_unused]] float time, [[maybe_unused]] AZ::Vector3& value) override { assert(0); };
  110. void GetValue([[maybe_unused]] float time, [[maybe_unused]] AZ::Vector4& value) override { assert(0); };
  111. void GetValue([[maybe_unused]] float time, [[maybe_unused]] AZ::Color& value) override { assert(0); };
  112. //////////////////////////////////////////////////////////////////////////
  113. // Set track value at specified time.
  114. // Adds new keys if required.
  115. //////////////////////////////////////////////////////////////////////////
  116. void SetValue([[maybe_unused]] float time, [[maybe_unused]] const float& value, [[maybe_unused]] bool bDefault = false) override { assert(0); };
  117. void SetValue([[maybe_unused]] float time, [[maybe_unused]] const Vec3& value, [[maybe_unused]] bool bDefault = false) override { assert(0); };
  118. void SetValue([[maybe_unused]] float time, [[maybe_unused]] const Vec4& value, [[maybe_unused]] bool bDefault = false) override { assert(0); };
  119. void SetValue([[maybe_unused]] float time, [[maybe_unused]] const Quat& value, [[maybe_unused]] bool bDefault = false) override { assert(0); };
  120. void SetValue([[maybe_unused]] float time, [[maybe_unused]] const bool& value, [[maybe_unused]] bool bDefault = false) override { assert(0); };
  121. void SetValue([[maybe_unused]] float time, [[maybe_unused]] const AZ::Vector2& value, [[maybe_unused]] bool bDefault = false) override { assert(0); };
  122. void SetValue([[maybe_unused]] float time, [[maybe_unused]] const AZ::Vector3& value, [[maybe_unused]] bool bDefault = false) override { assert(0); };
  123. void SetValue([[maybe_unused]] float time, [[maybe_unused]] const AZ::Vector4& value, [[maybe_unused]] bool bDefault = false) override { assert(0); };
  124. void SetValue([[maybe_unused]] float time, [[maybe_unused]] const AZ::Color& value, [[maybe_unused]] bool bDefault = false) override { assert(0); };
  125. void OffsetKeyPosition([[maybe_unused]] const AZ::Vector3& value) override { AZ_Assert(0, "Not implemented"); };
  126. /** Assign active time range for this track.
  127. */
  128. void SetTimeRange(const Range& timeRange) override { m_timeRange = timeRange; };
  129. /** Serialize this animation track to XML.
  130. Do not override this method, prefer to override SerializeKey.
  131. */
  132. bool Serialize(IUiAnimationSystem* uiAnimationSystem, XmlNodeRef& xmlNode, bool bLoading, bool bLoadEmptyTracks = true) override;
  133. bool SerializeSelection(XmlNodeRef& xmlNode, bool bLoading, bool bCopySelected = false, float fTimeOffset = 0) override;
  134. /** Serialize single key of this track.
  135. Override this in derived classes.
  136. Do not save time attribute, it is already saved in Serialize of the track.
  137. */
  138. virtual void SerializeKey(KeyType& key, XmlNodeRef& keyNode, bool bLoading) = 0;
  139. //////////////////////////////////////////////////////////////////////////
  140. //////////////////////////////////////////////////////////////////////////
  141. /** Get last key before specified time.
  142. @return Index of key, or -1 if such key not exist.
  143. */
  144. int GetActiveKey(float time, KeyType* key);
  145. #ifdef UI_ANIMATION_SYSTEM_SUPPORT_EDITING
  146. ColorB GetCustomColor() const override
  147. { return m_customColor; }
  148. void SetCustomColor(ColorB color) override
  149. {
  150. m_customColor = color;
  151. m_bCustomColorSet = true;
  152. }
  153. bool HasCustomColor() const override
  154. { return m_bCustomColorSet; }
  155. void ClearCustomColor() override
  156. { m_bCustomColorSet = false; }
  157. #endif
  158. void GetKeyValueRange(float& fMin, float& fMax) const override { fMin = m_fMinKeyValue; fMax = m_fMaxKeyValue; };
  159. void SetKeyValueRange(float fMin, float fMax) override{ m_fMinKeyValue = fMin; m_fMaxKeyValue = fMax; };
  160. static void Reflect(AZ::SerializeContext* serializeContext) {}
  161. protected:
  162. void CheckValid()
  163. {
  164. if (m_bModified)
  165. {
  166. SortKeys();
  167. }
  168. };
  169. void Invalidate() { m_bModified = 1; };
  170. int m_refCount;
  171. typedef AZStd::vector<KeyType> Keys;
  172. Keys m_keys;
  173. Range m_timeRange;
  174. CUiAnimParamType m_nParamType;
  175. unsigned int m_currKey : 31;
  176. unsigned int m_bModified : 1;
  177. float m_lastTime;
  178. int m_flags;
  179. static constexpr unsigned int InvalidKey = 0x7FFFFFFF;
  180. UiAnimParamData m_componentParamData;
  181. #ifdef UI_ANIMATION_SYSTEM_SUPPORT_EDITING
  182. ColorB m_customColor;
  183. bool m_bCustomColorSet;
  184. #endif
  185. float m_fMinKeyValue;
  186. float m_fMaxKeyValue;
  187. };
  188. //////////////////////////////////////////////////////////////////////////
  189. template <class KeyType>
  190. inline TUiAnimTrack<KeyType>::TUiAnimTrack()
  191. : m_refCount(0)
  192. {
  193. m_currKey = 0;
  194. m_flags = 0;
  195. m_lastTime = -1;
  196. m_bModified = 0;
  197. #ifdef UI_ANIMATION_SYSTEM_SUPPORT_EDITING
  198. m_bCustomColorSet = false;
  199. #endif
  200. }
  201. //////////////////////////////////////////////////////////////////////////
  202. template <class KeyType>
  203. inline void TUiAnimTrack<KeyType>::add_ref()
  204. {
  205. ++m_refCount;
  206. }
  207. //////////////////////////////////////////////////////////////////////////
  208. template <class KeyType>
  209. inline void TUiAnimTrack<KeyType>::release()
  210. {
  211. if (--m_refCount <= 0)
  212. {
  213. delete this;
  214. }
  215. }
  216. //////////////////////////////////////////////////////////////////////////
  217. template <class KeyType>
  218. inline void TUiAnimTrack<KeyType>::RemoveKey(int index)
  219. {
  220. AZ_Assert(index >= 0 && index < (int)m_keys.size(), "Key index is out of range");
  221. m_keys.erase(m_keys.begin() + index);
  222. Invalidate();
  223. }
  224. //////////////////////////////////////////////////////////////////////////
  225. template <class KeyType>
  226. inline void TUiAnimTrack<KeyType>::GetKey(int index, IKey* key) const
  227. {
  228. AZ_Assert(index >= 0 && index < (int)m_keys.size(), "Key index is out of range");
  229. AZ_Assert(key != 0, "Key cannot be null!");
  230. *(KeyType*)key = m_keys[index];
  231. }
  232. //////////////////////////////////////////////////////////////////////////
  233. template <class KeyType>
  234. inline void TUiAnimTrack<KeyType>::SetKey(int index, IKey* key)
  235. {
  236. AZ_Assert(index >= 0 && index < (int)m_keys.size(), "Key index is out of range");
  237. AZ_Assert(key != 0, "Key cannot be null!");
  238. m_keys[index] = *(KeyType*)key;
  239. Invalidate();
  240. }
  241. //////////////////////////////////////////////////////////////////////////
  242. template <class KeyType>
  243. inline float TUiAnimTrack<KeyType>::GetKeyTime(int index) const
  244. {
  245. AZ_Assert(index >= 0 && index < (int)m_keys.size(), "Key index is out of range");
  246. return m_keys[index].time;
  247. }
  248. //////////////////////////////////////////////////////////////////////////
  249. template <class KeyType>
  250. inline void TUiAnimTrack<KeyType>::SetKeyTime(int index, float time)
  251. {
  252. AZ_Assert(index >= 0 && index < (int)m_keys.size(), "Key index is out of range");
  253. m_keys[index].time = time;
  254. Invalidate();
  255. }
  256. //////////////////////////////////////////////////////////////////////////
  257. template <class KeyType>
  258. inline int TUiAnimTrack<KeyType>::FindKey(float time)
  259. {
  260. for (int i = 0; i < (int)m_keys.size(); i++)
  261. {
  262. if (m_keys[i].time == time)
  263. {
  264. return i;
  265. }
  266. }
  267. return -1;
  268. }
  269. //////////////////////////////////////////////////////////////////////////
  270. template <class KeyType>
  271. inline int TUiAnimTrack<KeyType>::GetKeyFlags(int index)
  272. {
  273. AZ_Assert(index >= 0 && index < (int)m_keys.size(), "Key index is out of range");
  274. return m_keys[index].flags;
  275. }
  276. //////////////////////////////////////////////////////////////////////////
  277. template <class KeyType>
  278. inline void TUiAnimTrack<KeyType>::SetKeyFlags(int index, int flags)
  279. {
  280. AZ_Assert(index >= 0 && index < (int)m_keys.size(), "Key index is out of range");
  281. m_keys[index].flags = flags;
  282. Invalidate();
  283. }
  284. //////////////////////////////////////////////////////////////////////////
  285. template <class KeyType>
  286. inline void TUiAnimTrack<KeyType>::SortKeys()
  287. {
  288. std::sort(m_keys.begin(), m_keys.end());
  289. m_bModified = 0;
  290. }
  291. //////////////////////////////////////////////////////////////////////////
  292. template <class KeyType>
  293. inline bool TUiAnimTrack<KeyType>::Serialize([[maybe_unused]] IUiAnimationSystem* uiAnimationSystem, XmlNodeRef& xmlNode, bool bLoading, bool bLoadEmptyTracks)
  294. {
  295. if (bLoading)
  296. {
  297. int num = xmlNode->getChildCount();
  298. Range timeRange;
  299. int flags = m_flags;
  300. xmlNode->getAttr("Flags", flags);
  301. xmlNode->getAttr("StartTime", timeRange.start);
  302. xmlNode->getAttr("EndTime", timeRange.end);
  303. SetFlags(flags);
  304. SetTimeRange(timeRange);
  305. #ifdef UI_ANIMATION_SYSTEM_SUPPORT_EDITING
  306. xmlNode->getAttr("HasCustomColor", m_bCustomColorSet);
  307. if (m_bCustomColorSet)
  308. {
  309. unsigned int abgr;
  310. xmlNode->getAttr("CustomColor", abgr);
  311. m_customColor = ColorB(abgr);
  312. }
  313. #endif
  314. SetNumKeys(num);
  315. for (int i = 0; i < num; i++)
  316. {
  317. XmlNodeRef keyNode = xmlNode->getChild(i);
  318. keyNode->getAttr("time", m_keys[i].time);
  319. SerializeKey(m_keys[i], keyNode, bLoading);
  320. }
  321. if ((!num) && (!bLoadEmptyTracks))
  322. {
  323. return false;
  324. }
  325. }
  326. else
  327. {
  328. int num = GetNumKeys();
  329. CheckValid();
  330. xmlNode->setAttr("Flags", GetFlags());
  331. xmlNode->setAttr("StartTime", m_timeRange.start);
  332. xmlNode->setAttr("EndTime", m_timeRange.end);
  333. #ifdef UI_ANIMATION_SYSTEM_SUPPORT_EDITING
  334. xmlNode->setAttr("HasCustomColor", m_bCustomColorSet);
  335. if (m_bCustomColorSet)
  336. {
  337. xmlNode->setAttr("CustomColor", m_customColor.pack_abgr8888());
  338. }
  339. #endif
  340. for (int i = 0; i < num; i++)
  341. {
  342. XmlNodeRef keyNode = xmlNode->newChild("Key");
  343. keyNode->setAttr("time", m_keys[i].time);
  344. SerializeKey(m_keys[i], keyNode, bLoading);
  345. }
  346. }
  347. return true;
  348. }
  349. //////////////////////////////////////////////////////////////////////////
  350. template <class KeyType>
  351. inline bool TUiAnimTrack<KeyType>::SerializeSelection(XmlNodeRef& xmlNode, bool bLoading, bool bCopySelected, float fTimeOffset)
  352. {
  353. if (bLoading)
  354. {
  355. int numCur = GetNumKeys();
  356. int num = xmlNode->getChildCount();
  357. unsigned int type;
  358. xmlNode->getAttr("TrackType", type);
  359. if (type != GetCurveType())
  360. {
  361. return false;
  362. }
  363. SetNumKeys(num + numCur);
  364. for (int i = 0; i < num; i++)
  365. {
  366. XmlNodeRef keyNode = xmlNode->getChild(i);
  367. keyNode->getAttr("time", m_keys[i + numCur].time);
  368. m_keys[i + numCur].time += fTimeOffset;
  369. SerializeKey(m_keys[i + numCur], keyNode, bLoading);
  370. if (bCopySelected)
  371. {
  372. m_keys[i + numCur].flags |= AKEY_SELECTED;
  373. }
  374. }
  375. SortKeys();
  376. }
  377. else
  378. {
  379. int num = GetNumKeys();
  380. xmlNode->setAttr("TrackType", GetCurveType());
  381. //CheckValid();
  382. for (int i = 0; i < num; i++)
  383. {
  384. if (!bCopySelected || GetKeyFlags(i) & AKEY_SELECTED)
  385. {
  386. XmlNodeRef keyNode = xmlNode->newChild("Key");
  387. keyNode->setAttr("time", m_keys[i].time);
  388. SerializeKey(m_keys[i], keyNode, bLoading);
  389. }
  390. }
  391. }
  392. return true;
  393. }
  394. //////////////////////////////////////////////////////////////////////////
  395. template <class KeyType>
  396. inline int TUiAnimTrack<KeyType>::CreateKey(float time)
  397. {
  398. KeyType key, akey;
  399. int nkey = GetNumKeys();
  400. SetNumKeys(nkey + 1);
  401. key.time = time;
  402. SetKey(nkey, &key);
  403. return nkey;
  404. }
  405. //////////////////////////////////////////////////////////////////////////
  406. template <class KeyType>
  407. inline int TUiAnimTrack<KeyType>::CloneKey(int fromKey)
  408. {
  409. KeyType key;
  410. GetKey(fromKey, &key);
  411. int nkey = GetNumKeys();
  412. SetNumKeys(nkey + 1);
  413. SetKey(nkey, &key);
  414. return nkey;
  415. }
  416. //////////////////////////////////////////////////////////////////////////
  417. template <class KeyType>
  418. inline int TUiAnimTrack<KeyType>::CopyKey(IUiAnimTrack* pFromTrack, int nFromKey)
  419. {
  420. KeyType key;
  421. pFromTrack->GetKey(nFromKey, &key);
  422. int nkey = GetNumKeys();
  423. SetNumKeys(nkey + 1);
  424. SetKey(nkey, &key);
  425. return nkey;
  426. }
  427. //////////////////////////////////////////////////////////////////////////
  428. template <class KeyType>
  429. inline int TUiAnimTrack<KeyType>::GetActiveKey(float time, KeyType* key)
  430. {
  431. CheckValid();
  432. if (key == NULL)
  433. {
  434. return -1;
  435. }
  436. int nkeys = static_cast<int>(m_keys.size());
  437. if (nkeys == 0)
  438. {
  439. m_lastTime = time;
  440. m_currKey = InvalidKey;
  441. return m_currKey;
  442. }
  443. bool bTimeWrap = false;
  444. if ((m_flags & eUiAnimTrackFlags_Cycle) || (m_flags & eUiAnimTrackFlags_Loop))
  445. {
  446. // Warp time.
  447. const char* desc = 0;
  448. float duration = 0;
  449. GetKeyInfo(nkeys - 1, desc, duration);
  450. float endtime = GetKeyTime(nkeys - 1) + duration;
  451. time = fmod_tpl(time, endtime);
  452. if (time < m_lastTime)
  453. {
  454. // Time is wrapped.
  455. bTimeWrap = true;
  456. }
  457. }
  458. m_lastTime = time;
  459. // Time is before first key.
  460. if (m_keys[0].time > time)
  461. {
  462. if (bTimeWrap)
  463. {
  464. // If time wrapped, active key is last key.
  465. m_currKey = nkeys - 1;
  466. *key = m_keys[m_currKey];
  467. }
  468. else
  469. {
  470. m_currKey = InvalidKey;
  471. }
  472. return m_currKey;
  473. }
  474. if (m_currKey < 0)
  475. {
  476. m_currKey = 0;
  477. }
  478. // Start from current key.
  479. int i;
  480. for (i = m_currKey; i < nkeys; i++)
  481. {
  482. if (time >= m_keys[i].time)
  483. {
  484. if ((i >= nkeys - 1) || (time < m_keys[i + 1].time))
  485. {
  486. m_currKey = i;
  487. *key = m_keys[m_currKey];
  488. return m_currKey;
  489. }
  490. }
  491. else
  492. {
  493. break;
  494. }
  495. }
  496. // Start from begining.
  497. for (i = 0; i < nkeys; i++)
  498. {
  499. if (time >= m_keys[i].time)
  500. {
  501. if ((i >= nkeys - 1) || (time < m_keys[i + 1].time))
  502. {
  503. m_currKey = i;
  504. *key = m_keys[m_currKey];
  505. return m_currKey;
  506. }
  507. }
  508. else
  509. {
  510. break;
  511. }
  512. }
  513. m_currKey = InvalidKey;
  514. return m_currKey;
  515. }