AnimSplineTrack.h 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711
  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. #include "IMovieSystem.h"
  10. #include "2DSpline.h"
  11. #define MIN_TIME_PRECISION 0.01f
  12. #define MIN_VALUE_RANGE 1.0f // prevents fill sliders from being inoperable on the first key frame
  13. /*!
  14. Templated class that used as a base for all Tcb spline tracks.
  15. */
  16. template <class ValueType>
  17. class TAnimSplineTrack
  18. : public IAnimTrack
  19. {
  20. public:
  21. AZ_CLASS_ALLOCATOR(TAnimSplineTrack, AZ::SystemAllocator);
  22. AZ_RTTI((TAnimSplineTrack, "{6D72D5F6-61A7-43D4-9104-8F7DCCC19E10}", ValueType), IAnimTrack);
  23. static constexpr void DeprecatedTypeNameVisitor(
  24. const AZ::DeprecatedTypeNameCallback& visitCallback)
  25. {
  26. // TAnimSplineTrack previously restricted the typename to 128 bytes
  27. AZStd::array<char, 128> deprecatedName{};
  28. // The old TAnimSplineTrack TypeName mistakenly used Vec2 as the template parameter and not ValueType
  29. // Also the extra space before the '>' is due to the AZ::Internal::AggregateTypes template
  30. // always adding a space after each argument
  31. AZ::Internal::AzTypeInfoSafeCat(deprecatedName.data(), deprecatedName.size(), "TAnimSplineTrack<Vec2 >");
  32. if (visitCallback)
  33. {
  34. visitCallback(deprecatedName.data());
  35. }
  36. }
  37. TAnimSplineTrack()
  38. : m_refCount(0)
  39. {
  40. AllocSpline();
  41. m_flags = 0;
  42. m_bCustomColorSet = false;
  43. m_fMinKeyValue = 0.0f;
  44. m_fMaxKeyValue = 0.0f;
  45. m_node = nullptr;
  46. m_trackMultiplier = 1.0f;
  47. }
  48. ~TAnimSplineTrack()
  49. {
  50. m_spline.reset();
  51. }
  52. //////////////////////////////////////////////////////////////////////////
  53. // for intrusive_ptr support
  54. void add_ref() override;
  55. void release() override;
  56. //////////////////////////////////////////////////////////////////////////
  57. int GetSubTrackCount() const override { return 0; };
  58. IAnimTrack* GetSubTrack([[maybe_unused]] int nIndex) const override { return 0; };
  59. AZStd::string GetSubTrackName([[maybe_unused]] int nIndex) const override { return AZStd::string(); };
  60. void SetSubTrackName([[maybe_unused]] int nIndex, [[maybe_unused]] const char* name) override { assert(0); }
  61. void SetNode(IAnimNode* node) override { m_node = node; }
  62. // Return Animation Node that owns this Track.
  63. IAnimNode* GetNode() override { return m_node; }
  64. const CAnimParamType& GetParameterType() const override { return m_nParamType; };
  65. void SetParameterType(CAnimParamType type) override { m_nParamType = type; };
  66. void GetKeyValueRange(float& fMin, float& fMax) const override { fMin = m_fMinKeyValue; fMax = m_fMaxKeyValue; };
  67. void SetKeyValueRange(float fMin, float fMax) override{ m_fMinKeyValue = fMin; m_fMaxKeyValue = fMax; };
  68. ISplineInterpolator* GetSpline() const override { return m_spline.get(); };
  69. bool IsKeySelected(int key) const override
  70. {
  71. if (GetSpline() && GetSpline()->IsKeySelectedAtAnyDimension(key))
  72. {
  73. return true;
  74. }
  75. return false;
  76. }
  77. void SelectKey(int key, bool select) override
  78. {
  79. if (GetSpline())
  80. {
  81. GetSpline()->SelectKeyAllDimensions(key, select);
  82. }
  83. }
  84. int GetNumKeys() const override
  85. {
  86. return m_spline->num_keys();
  87. }
  88. void SetNumKeys(int numKeys) override
  89. {
  90. m_spline->resize(numKeys);
  91. }
  92. bool HasKeys() const override
  93. {
  94. return GetNumKeys() != 0;
  95. }
  96. void RemoveKey(int num) override
  97. {
  98. if (m_spline && m_spline->num_keys() > num)
  99. {
  100. m_spline->erase(num);
  101. }
  102. else
  103. {
  104. assert(0);
  105. }
  106. }
  107. void GetKey(int index, IKey* key) const override
  108. {
  109. assert(index >= 0 && index < GetNumKeys());
  110. assert(key != 0);
  111. typename Spline::key_type& k = m_spline->key(index);
  112. ITcbKey* tcbkey = (ITcbKey*)key;
  113. tcbkey->time = k.time;
  114. tcbkey->flags = k.flags;
  115. tcbkey->tens = k.tens;
  116. tcbkey->cont = k.cont;
  117. tcbkey->bias = k.bias;
  118. tcbkey->easeto = k.easeto;
  119. tcbkey->easefrom = k.easefrom;
  120. tcbkey->SetValue(k.value);
  121. }
  122. void SetKey(int index, IKey* key) override
  123. {
  124. assert(index >= 0 && index < GetNumKeys());
  125. assert(key != 0);
  126. typename Spline::key_type& k = m_spline->key(index);
  127. ITcbKey* tcbkey = (ITcbKey*)key;
  128. k.time = tcbkey->time;
  129. k.flags = tcbkey->flags;
  130. k.tens = tcbkey->tens;
  131. k.cont = tcbkey->cont;
  132. k.bias = tcbkey->bias;
  133. k.easeto = tcbkey->easeto;
  134. k.easefrom = tcbkey->easefrom;
  135. tcbkey->GetValue(k.value);
  136. Invalidate();
  137. }
  138. float GetKeyTime(int index) const override
  139. {
  140. assert(index >= 0 && index < GetNumKeys());
  141. return m_spline->time(index);
  142. }
  143. void SetKeyTime(int index, float time) override
  144. {
  145. assert(index >= 0 && index < GetNumKeys());
  146. m_spline->SetKeyTime(index, time);
  147. Invalidate();
  148. }
  149. int GetKeyFlags(int index) override
  150. {
  151. assert(index >= 0 && index < GetNumKeys());
  152. return m_spline->key(index).flags;
  153. }
  154. void SetKeyFlags(int index, int flags) override
  155. {
  156. assert(index >= 0 && index < GetNumKeys());
  157. m_spline->key(index).flags = flags;
  158. }
  159. EAnimCurveType GetCurveType() override { assert(0); return eAnimCurveType_Unknown; }
  160. AnimValueType GetValueType() override { assert(0); return static_cast<AnimValueType>(0xFFFFFFFF); }
  161. void GetValue(float time, float& value, bool applyMultiplier = false) override { assert(0); }
  162. void GetValue([[maybe_unused]] float time, [[maybe_unused]] Vec3& value, [[maybe_unused]] bool applyMultiplier = false) override { assert(0); }
  163. void GetValue([[maybe_unused]] float time, [[maybe_unused]] Vec4& value, [[maybe_unused]] bool applyMultiplier = false) override { assert(0); }
  164. void GetValue([[maybe_unused]] float time, [[maybe_unused]] Quat& value) override { assert(0); }
  165. void GetValue([[maybe_unused]] float time, [[maybe_unused]] bool& value) override { assert(0); }
  166. void GetValue([[maybe_unused]] float time, [[maybe_unused]] Maestro::AssetBlends<AZ::Data::AssetData>& value) override { assert(0); }
  167. void SetValue(float time, const float& value, bool bDefault = false, bool applyMultiplier = false) override { assert(0); }
  168. void SetValue([[maybe_unused]] float time, [[maybe_unused]] const Vec3& value, [[maybe_unused]] bool bDefault = false, [[maybe_unused]] bool applyMultiplier = false) override { assert(0); }
  169. void SetValue([[maybe_unused]] float time, [[maybe_unused]] const Vec4& value, [[maybe_unused]] bool bDefault = false, [[maybe_unused]] bool applyMultiplier = false) override { assert(0); }
  170. void SetValue([[maybe_unused]] float time, [[maybe_unused]] const Quat& value, [[maybe_unused]] bool bDefault = false) override { assert(0); }
  171. void SetValue([[maybe_unused]] float time, [[maybe_unused]] const bool& value, [[maybe_unused]] bool bDefault = false) override { assert(0); }
  172. void SetValue([[maybe_unused]] float time, [[maybe_unused]] const Maestro::AssetBlends<AZ::Data::AssetData>& value, [[maybe_unused]] bool bDefault = false) override { assert(0); }
  173. void OffsetKeyPosition([[maybe_unused]] const AZ::Vector3& value) override { assert(0); };
  174. void UpdateKeyDataAfterParentChanged([[maybe_unused]] const AZ::Transform& oldParentWorldTM, [[maybe_unused]] const AZ::Transform& newParentWorldTM) override { assert(0); };
  175. bool Serialize(XmlNodeRef& xmlNode, bool bLoading, bool bLoadEmptyTracks) override;
  176. bool SerializeSelection(XmlNodeRef& xmlNode, bool bLoading, bool bCopySelected, float fTimeOffset) override;
  177. void GetKeyInfo(int key, const char*& description, float& duration) override
  178. {
  179. description = 0;
  180. duration = 0;
  181. }
  182. //! Sort keys in track (after time of keys was modified).
  183. void SortKeys() override
  184. {
  185. m_spline->sort_keys();
  186. };
  187. //! Get track flags.
  188. int GetFlags() override { return m_flags; };
  189. //! Check if track is masked by mask
  190. bool IsMasked([[maybe_unused]] const uint32 mask) const override { return false; }
  191. //! Set track flags.
  192. void SetFlags(int flags) override
  193. {
  194. m_flags = flags;
  195. if (m_flags & eAnimTrackFlags_Loop)
  196. {
  197. m_spline->ORT(Spline::ORT_LOOP);
  198. }
  199. else if (m_flags & eAnimTrackFlags_Cycle)
  200. {
  201. m_spline->ORT(Spline::ORT_CYCLE);
  202. }
  203. else
  204. {
  205. m_spline->ORT(Spline::ORT_CONSTANT);
  206. }
  207. }
  208. void Invalidate()
  209. {
  210. m_spline->flag_set(Spline::MODIFIED);
  211. };
  212. void SetTimeRange(const Range& timeRange) override
  213. {
  214. m_spline->SetRange(timeRange.start, timeRange.end);
  215. }
  216. int FindKey(float time) override
  217. {
  218. // Find key with given time.
  219. int num = m_spline->num_keys();
  220. for (int i = 0; i < num; i++)
  221. {
  222. float keyt = m_spline->key(i).time;
  223. if (fabs(keyt - time) < MIN_TIME_PRECISION)
  224. {
  225. return i;
  226. }
  227. }
  228. return -1;
  229. }
  230. //! Create key at given time, and return its index.
  231. int CreateKey(float time) override
  232. {
  233. ValueType value;
  234. int nkey = GetNumKeys();
  235. if (nkey > 0)
  236. {
  237. GetValue(time, value);
  238. }
  239. else
  240. {
  241. value = m_defaultValue;
  242. }
  243. typename Spline::ValueType tmp;
  244. m_spline->ToValueType(value, tmp);
  245. return m_spline->InsertKey(time, tmp);
  246. }
  247. int CloneKey(int srcKey) override
  248. {
  249. return CopyKey(this, srcKey);
  250. }
  251. int CopyKey(IAnimTrack* pFromTrack, int nFromKey) override
  252. {
  253. ITcbKey key;
  254. pFromTrack->GetKey(nFromKey, &key);
  255. int nkey = GetNumKeys();
  256. SetNumKeys(nkey + 1);
  257. SetKey(nkey, &key);
  258. return nkey;
  259. }
  260. //! Get key at given time,
  261. //! If key not exist adds key at this time.
  262. void SetKeyAtTime(float time, IKey* key)
  263. {
  264. assert(key != 0);
  265. key->time = time;
  266. bool found = false;
  267. // Find key with given time.
  268. for (int i = 0; i < m_spline->num_keys(); i++)
  269. {
  270. float keyt = m_spline->key(i).time;
  271. if (fabs(keyt - time) < MIN_TIME_PRECISION)
  272. {
  273. key->flags = m_spline->key(i).flags; // Reserve the flag value.
  274. SetKey(i, key);
  275. found = true;
  276. break;
  277. }
  278. //if (keyt > time)
  279. //break;
  280. }
  281. if (!found)
  282. {
  283. // Key with this time not found.
  284. // Create a new one.
  285. int keyIndex = CreateKey(time);
  286. // Reserve the flag value.
  287. key->flags = m_spline->key(keyIndex).flags; // Reserve the flag value.
  288. SetKey(keyIndex, key);
  289. }
  290. }
  291. virtual void SetDefaultValue(const ValueType& value)
  292. {
  293. m_defaultValue = value;
  294. }
  295. ColorB GetCustomColor() const
  296. { return m_customColor; }
  297. void SetCustomColor(ColorB color)
  298. {
  299. m_customColor = color;
  300. m_bCustomColorSet = true;
  301. }
  302. bool HasCustomColor() const
  303. { return m_bCustomColorSet; }
  304. void ClearCustomColor()
  305. { m_bCustomColorSet = false; }
  306. void SetMultiplier(float trackMultiplier) override
  307. {
  308. m_trackMultiplier = trackMultiplier;
  309. }
  310. void SetExpanded([[maybe_unused]] bool expanded) override
  311. {
  312. AZ_Assert(false, "Not expected to be used.");
  313. }
  314. bool GetExpanded() const override
  315. {
  316. return false;
  317. }
  318. unsigned int GetId() const override
  319. {
  320. return m_id;
  321. }
  322. void SetId(unsigned int id) override
  323. {
  324. m_id = id;
  325. }
  326. static void Reflect([[maybe_unused]] AZ::ReflectContext* context) {}
  327. protected:
  328. void UpdateTrackValueRange(float newValue)
  329. {
  330. m_fMinKeyValue = (newValue < m_fMinKeyValue) ? newValue : m_fMinKeyValue;
  331. m_fMaxKeyValue = (newValue > m_fMaxKeyValue) ? newValue : m_fMaxKeyValue;
  332. if ((m_fMaxKeyValue - m_fMinKeyValue) < MIN_VALUE_RANGE)
  333. {
  334. // prevents fill sliders from being inoperable when min and max are identical (or close to it)
  335. m_fMaxKeyValue = (m_fMinKeyValue + MIN_VALUE_RANGE);
  336. }
  337. };
  338. private:
  339. //! Spawns new instance of Tcb spline.
  340. void AllocSpline()
  341. {
  342. m_spline = aznew spline::TrackSplineInterpolator<ValueType>;
  343. }
  344. int m_refCount;
  345. typedef spline::TrackSplineInterpolator<ValueType> Spline;
  346. AZStd::intrusive_ptr<Spline> m_spline;
  347. ValueType m_defaultValue;
  348. //! Keys of float track.
  349. int m_flags;
  350. CAnimParamType m_nParamType;
  351. ColorB m_customColor;
  352. bool m_bCustomColorSet;
  353. float m_fMinKeyValue;
  354. float m_fMaxKeyValue;
  355. IAnimNode* m_node;
  356. float m_trackMultiplier;
  357. unsigned int m_id = 0;
  358. };
  359. //////////////////////////////////////////////////////////////////////////
  360. template <class T>
  361. inline void TAnimSplineTrack<T>::add_ref()
  362. {
  363. ++m_refCount;
  364. }
  365. //////////////////////////////////////////////////////////////////////////
  366. template <class T>
  367. inline void TAnimSplineTrack<T>::release()
  368. {
  369. if (--m_refCount <= 0)
  370. {
  371. delete this;
  372. }
  373. }
  374. /// @deprecated Serialization for Sequence data in Component Entity Sequences now occurs through AZ::SerializeContext and the Sequence Component
  375. template <class T>
  376. inline bool TAnimSplineTrack<T>::Serialize(XmlNodeRef& xmlNode, bool bLoading, bool bLoadEmptyTracks)
  377. {
  378. if (bLoading)
  379. {
  380. int num = xmlNode->getChildCount();
  381. int flags = m_flags;
  382. xmlNode->getAttr("Flags", flags);
  383. xmlNode->getAttr("defaultValue", m_defaultValue);
  384. SetFlags(flags);
  385. xmlNode->getAttr("HasCustomColor", m_bCustomColorSet);
  386. if (m_bCustomColorSet)
  387. {
  388. unsigned int abgr;
  389. xmlNode->getAttr("CustomColor", abgr);
  390. m_customColor = ColorB(abgr);
  391. }
  392. T value;
  393. SetNumKeys(num);
  394. for (int i = 0; i < num; i++)
  395. {
  396. ITcbKey key; // Must be inside loop.
  397. XmlNodeRef keyNode = xmlNode->getChild(i);
  398. keyNode->getAttr("time", key.time);
  399. if (keyNode->getAttr("value", value))
  400. {
  401. key.SetValue(value);
  402. }
  403. keyNode->getAttr("tens", key.tens);
  404. keyNode->getAttr("cont", key.cont);
  405. keyNode->getAttr("bias", key.bias);
  406. keyNode->getAttr("easeto", key.easeto);
  407. keyNode->getAttr("easefrom", key.easefrom);
  408. keyNode->getAttr("flags", key.flags);
  409. SetKey(i, &key);
  410. // In-/Out-tangent
  411. keyNode->getAttr("ds", m_spline->key(i).ds);
  412. keyNode->getAttr("dd", m_spline->key(i).dd);
  413. }
  414. xmlNode->getAttr("Id", m_id);
  415. if ((!num) && (!bLoadEmptyTracks))
  416. {
  417. return false;
  418. }
  419. }
  420. else
  421. {
  422. int num = GetNumKeys();
  423. xmlNode->setAttr("Flags", GetFlags());
  424. xmlNode->setAttr("defaultValue", m_defaultValue);
  425. xmlNode->setAttr("HasCustomColor", m_bCustomColorSet);
  426. if (m_bCustomColorSet)
  427. {
  428. xmlNode->setAttr("CustomColor", m_customColor.pack_abgr8888());
  429. }
  430. ITcbKey key;
  431. T value;
  432. for (int i = 0; i < num; i++)
  433. {
  434. GetKey(i, &key);
  435. XmlNodeRef keyNode = xmlNode->newChild("Key");
  436. keyNode->setAttr("time", key.time);
  437. key.GetValue(value);
  438. keyNode->setAttr("value", value);
  439. if (key.tens != 0)
  440. {
  441. keyNode->setAttr("tens", key.tens);
  442. }
  443. if (key.cont != 0)
  444. {
  445. keyNode->setAttr("cont", key.cont);
  446. }
  447. if (key.bias != 0)
  448. {
  449. keyNode->setAttr("bias", key.bias);
  450. }
  451. if (key.easeto != 0)
  452. {
  453. keyNode->setAttr("easeto", key.easeto);
  454. }
  455. if (key.easefrom != 0)
  456. {
  457. keyNode->setAttr("easefrom", key.easefrom);
  458. }
  459. int flags = key.flags;
  460. // Just save the in/out mask part. Others are for editing convenience.
  461. flags &= (SPLINE_KEY_TANGENT_IN_MASK | SPLINE_KEY_TANGENT_OUT_MASK);
  462. if (flags != 0)
  463. {
  464. keyNode->setAttr("flags", flags);
  465. }
  466. // We also have to save in-/out-tangents, because TCB infos are not used for custom tangent keys.
  467. keyNode->setAttr("ds", m_spline->key(i).ds);
  468. keyNode->setAttr("dd", m_spline->key(i).dd);
  469. }
  470. xmlNode->setAttr("Id", m_id);
  471. }
  472. return true;
  473. }
  474. template <class T>
  475. inline bool TAnimSplineTrack<T>::SerializeSelection(XmlNodeRef& xmlNode, bool bLoading, bool bCopySelected, float fTimeOffset)
  476. {
  477. if (bLoading)
  478. {
  479. int numCur = GetNumKeys();
  480. int num = xmlNode->getChildCount();
  481. int type;
  482. xmlNode->getAttr("TrackType", type);
  483. if (type != GetCurveType())
  484. {
  485. return false;
  486. }
  487. T value;
  488. SetNumKeys(num + numCur);
  489. for (int i = 0; i < num; i++)
  490. {
  491. ITcbKey key; // Must be inside loop.
  492. XmlNodeRef keyNode = xmlNode->getChild(i);
  493. keyNode->getAttr("time", key.time);
  494. key.time += fTimeOffset;
  495. if (keyNode->getAttr("value", value))
  496. {
  497. key.SetValue(value);
  498. }
  499. keyNode->getAttr("tens", key.tens);
  500. keyNode->getAttr("cont", key.cont);
  501. keyNode->getAttr("bias", key.bias);
  502. keyNode->getAttr("easeto", key.easeto);
  503. keyNode->getAttr("easefrom", key.easefrom);
  504. keyNode->getAttr("flags", key.flags);
  505. SetKey(i + numCur, &key);
  506. if (bCopySelected)
  507. {
  508. SelectKey(i + numCur, true);
  509. }
  510. // In-/Out-tangent
  511. keyNode->getAttr("ds", m_spline->key(i + numCur).ds);
  512. keyNode->getAttr("dd", m_spline->key(i + numCur).dd);
  513. }
  514. SortKeys();
  515. }
  516. else
  517. {
  518. int num = GetNumKeys();
  519. xmlNode->setAttr("TrackType", GetCurveType());
  520. ITcbKey key;
  521. T value;
  522. for (int i = 0; i < num; i++)
  523. {
  524. GetKey(i, &key);
  525. if (!bCopySelected || IsKeySelected(i))
  526. {
  527. XmlNodeRef keyNode = xmlNode->newChild("Key");
  528. keyNode->setAttr("time", key.time);
  529. key.GetValue(value);
  530. keyNode->setAttr("value", value);
  531. if (key.tens != 0)
  532. {
  533. keyNode->setAttr("tens", key.tens);
  534. }
  535. if (key.cont != 0)
  536. {
  537. keyNode->setAttr("cont", key.cont);
  538. }
  539. if (key.bias != 0)
  540. {
  541. keyNode->setAttr("bias", key.bias);
  542. }
  543. if (key.easeto != 0)
  544. {
  545. keyNode->setAttr("easeto", key.easeto);
  546. }
  547. if (key.easefrom != 0)
  548. {
  549. keyNode->setAttr("easefrom", key.easefrom);
  550. }
  551. int flags = key.flags;
  552. // Just save the in/out mask part. Others are for editing convenience.
  553. flags &= (SPLINE_KEY_TANGENT_IN_MASK | SPLINE_KEY_TANGENT_OUT_MASK);
  554. if (flags != 0)
  555. {
  556. keyNode->setAttr("flags", flags);
  557. }
  558. // We also have to save in-/out-tangents, because TCB infos are not used for custom tangent keys.
  559. keyNode->setAttr("ds", m_spline->key(i).ds);
  560. keyNode->setAttr("dd", m_spline->key(i).dd);
  561. }
  562. }
  563. }
  564. return true;
  565. }
  566. template <>
  567. TAnimSplineTrack<Vec2>::TAnimSplineTrack();
  568. template <>
  569. void TAnimSplineTrack<Vec2>::GetValue(float time, float& value, bool applyMultiplier);
  570. template <>
  571. EAnimCurveType TAnimSplineTrack<Vec2>::GetCurveType();
  572. template <>
  573. AnimValueType TAnimSplineTrack<Vec2>::GetValueType();
  574. template <>
  575. void TAnimSplineTrack<Vec2>::SetValue(float time, const float& value, bool bDefault, bool applyMultiplier);
  576. template <>
  577. void TAnimSplineTrack<Vec2>::GetKey(int index, IKey* key) const;
  578. template <>
  579. void TAnimSplineTrack<Vec2>::SetKey(int index, IKey* key);
  580. //! Create key at given time, and return its index.
  581. template <>
  582. int TAnimSplineTrack<Vec2>::CreateKey(float time);
  583. template <>
  584. int TAnimSplineTrack<Vec2>::CopyKey(IAnimTrack* pFromTrack, int nFromKey);
  585. /// @deprecated Serialization for Sequence data in Component Entity Sequences now occurs through AZ::SerializeContext and the Sequence Component
  586. template <>
  587. bool TAnimSplineTrack<Vec2>::Serialize(XmlNodeRef& xmlNode, bool bLoading, bool bLoadEmptyTracks);
  588. template <>
  589. bool TAnimSplineTrack<Vec2>::SerializeSelection(XmlNodeRef& xmlNode, bool bLoading, bool bCopySelected, float fTimeOffset);
  590. template<>
  591. void TAnimSplineTrack<Vec2>::GetKeyInfo(int index, const char*& description, float& duration);
  592. template <>
  593. void TAnimSplineTrack<Vec2>::add_ref();
  594. template <>
  595. void TAnimSplineTrack<Vec2>::release();
  596. template <>
  597. void TAnimSplineTrack<Vec2>::Reflect(AZ::ReflectContext* context);
  598. using C2DSplineTrack = TAnimSplineTrack<Vec2>;