AnimNode.cpp 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798
  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 "AnimNode.h"
  10. #include "AnimTrack.h"
  11. #include "AnimSequence.h"
  12. #include "AnimSplineTrack.h"
  13. #include "BoolTrack.h"
  14. #include "TrackEventTrack.h"
  15. #include "CompoundSplineTrack.h"
  16. #include <AzCore/std/sort.h>
  17. #include <ctime>
  18. //////////////////////////////////////////////////////////////////////////
  19. // Old deprecated IDs
  20. //////////////////////////////////////////////////////////////////////////
  21. #define APARAM_CHARACTER4 (eUiAnimParamType_User + 0x10)
  22. #define APARAM_CHARACTER5 (eUiAnimParamType_User + 0x11)
  23. #define APARAM_CHARACTER6 (eUiAnimParamType_User + 0x12)
  24. #define APARAM_CHARACTER7 (eUiAnimParamType_User + 0x13)
  25. #define APARAM_CHARACTER8 (eUiAnimParamType_User + 0x14)
  26. #define APARAM_CHARACTER9 (eUiAnimParamType_User + 0x15)
  27. #define APARAM_CHARACTER10 (eUiAnimParamType_User + 0x16)
  28. #define APARAM_EXPRESSION4 (eUiAnimParamType_User + 0x20)
  29. #define APARAM_EXPRESSION5 (eUiAnimParamType_User + 0x21)
  30. #define APARAM_EXPRESSION6 (eUiAnimParamType_User + 0x22)
  31. #define APARAM_EXPRESSION7 (eUiAnimParamType_User + 0x23)
  32. #define APARAM_EXPRESSION8 (eUiAnimParamType_User + 0x24)
  33. #define APARAM_EXPRESSION9 (eUiAnimParamType_User + 0x25)
  34. #define APARAM_EXPRESSION10 (eUiAnimParamType_User + 0x26)
  35. //////////////////////////////////////////////////////////////////////////
  36. static const EUiAnimCurveType DEFAULT_TRACK_TYPE = eUiAnimCurveType_BezierFloat;
  37. //////////////////////////////////////////////////////////////////////////
  38. // CUiAnimNode.
  39. //////////////////////////////////////////////////////////////////////////
  40. //////////////////////////////////////////////////////////////////////////
  41. void CUiAnimNode::Activate([[maybe_unused]] bool bActivate)
  42. {
  43. }
  44. //////////////////////////////////////////////////////////////////////////
  45. int CUiAnimNode::GetTrackCount() const
  46. {
  47. return static_cast<int>(m_tracks.size());
  48. }
  49. AZStd::string CUiAnimNode::GetParamName(const CUiAnimParamType& paramType) const
  50. {
  51. SParamInfo info;
  52. if (GetParamInfoFromType(paramType, info))
  53. {
  54. return info.name;
  55. }
  56. return "Unknown";
  57. }
  58. EUiAnimValue CUiAnimNode::GetParamValueType(const CUiAnimParamType& paramType) const
  59. {
  60. SParamInfo info;
  61. if (GetParamInfoFromType(paramType, info))
  62. {
  63. return info.valueType;
  64. }
  65. return eUiAnimValue_Unknown;
  66. }
  67. IUiAnimNode::ESupportedParamFlags CUiAnimNode::GetParamFlags(const CUiAnimParamType& paramType) const
  68. {
  69. SParamInfo info;
  70. if (GetParamInfoFromType(paramType, info))
  71. {
  72. return info.flags;
  73. }
  74. return IUiAnimNode::ESupportedParamFlags(0);
  75. }
  76. IUiAnimTrack* CUiAnimNode::GetTrackForParameter(const CUiAnimParamType& paramType) const
  77. {
  78. for (int i = 0, num = (int)m_tracks.size(); i < num; i++)
  79. {
  80. if (m_tracks[i]->GetParameterType() == paramType)
  81. {
  82. return m_tracks[i].get();
  83. }
  84. // Search the sub-tracks also if any.
  85. for (int k = 0; k < m_tracks[i]->GetSubTrackCount(); ++k)
  86. {
  87. if (m_tracks[i]->GetSubTrack(k)->GetParameterType() == paramType)
  88. {
  89. return m_tracks[i]->GetSubTrack(k);
  90. }
  91. }
  92. }
  93. return 0;
  94. }
  95. IUiAnimTrack* CUiAnimNode::GetTrackForParameter(const CUiAnimParamType& paramType, uint32 index) const
  96. {
  97. SParamInfo paramInfo;
  98. GetParamInfoFromType(paramType, paramInfo);
  99. if ((paramInfo.flags & IUiAnimNode::eSupportedParamFlags_MultipleTracks) == 0)
  100. {
  101. return GetTrackForParameter(paramType);
  102. }
  103. uint32 count = 0;
  104. for (int i = 0, num = (int)m_tracks.size(); i < num; i++)
  105. {
  106. if (m_tracks[i]->GetParameterType() == paramType && count++ == index)
  107. {
  108. return m_tracks[i].get();
  109. }
  110. // For this case, no subtracks are considered.
  111. }
  112. return 0;
  113. }
  114. uint32 CUiAnimNode::GetTrackParamIndex(const IUiAnimTrack* track) const
  115. {
  116. AZ_Assert(track, "Track is nullptr.");
  117. uint32 index = 0;
  118. CUiAnimParamType paramType = track->GetParameterType();
  119. SParamInfo paramInfo;
  120. GetParamInfoFromType(paramType, paramInfo);
  121. if ((paramInfo.flags & IUiAnimNode::eSupportedParamFlags_MultipleTracks) == 0)
  122. {
  123. return 0;
  124. }
  125. for (int i = 0, num = (int)m_tracks.size(); i < num; i++)
  126. {
  127. if (m_tracks[i].get() == track)
  128. {
  129. return index;
  130. }
  131. if (m_tracks[i]->GetParameterType() == paramType)
  132. {
  133. ++index;
  134. }
  135. // For this case, no subtracks are considered.
  136. }
  137. AZ_Assert(false, "CUiAnimNode::GetTrackParamIndex() called with an invalid argument!");
  138. return 0;
  139. }
  140. IUiAnimTrack* CUiAnimNode::GetTrackByIndex(int nIndex) const
  141. {
  142. AZ_Assert(nIndex >= 0 && nIndex < static_cast<int>(m_tracks.size()), "Track index out of range.");
  143. if (nIndex < 0 || nIndex >= static_cast<int>(m_tracks.size()))
  144. {
  145. return NULL;
  146. }
  147. return m_tracks[nIndex].get();
  148. }
  149. void CUiAnimNode::SetTrack(const CUiAnimParamType& paramType, IUiAnimTrack* track)
  150. {
  151. if (track)
  152. {
  153. for (unsigned int i = 0; i < m_tracks.size(); i++)
  154. {
  155. if (m_tracks[i]->GetParameterType() == paramType)
  156. {
  157. m_tracks[i].reset(track);
  158. return;
  159. }
  160. }
  161. AddTrack(track);
  162. }
  163. else
  164. {
  165. // Remove track at this id.
  166. for (unsigned int i = 0; i < m_tracks.size(); i++)
  167. {
  168. if (m_tracks[i]->GetParameterType() == paramType)
  169. {
  170. m_tracks.erase(m_tracks.begin() + i);
  171. }
  172. }
  173. }
  174. }
  175. //////////////////////////////////////////////////////////////////////////
  176. bool CUiAnimNode::TrackOrder(const AZStd::intrusive_ptr<IUiAnimTrack>& left, const AZStd::intrusive_ptr<IUiAnimTrack>& right)
  177. {
  178. return left->GetParameterType() < right->GetParameterType();
  179. }
  180. //////////////////////////////////////////////////////////////////////////
  181. void CUiAnimNode::AddTrack(IUiAnimTrack* track)
  182. {
  183. RegisterTrack(track);
  184. m_tracks.push_back(AZStd::intrusive_ptr<IUiAnimTrack>(track));
  185. SortTracks();
  186. }
  187. //////////////////////////////////////////////////////////////////////////
  188. void CUiAnimNode::RegisterTrack(IUiAnimTrack* track)
  189. {
  190. track->SetTimeRange(GetSequence()->GetTimeRange());
  191. }
  192. //////////////////////////////////////////////////////////////////////////
  193. void CUiAnimNode::SortTracks()
  194. {
  195. AZStd::insertion_sort(m_tracks.begin(), m_tracks.end(), TrackOrder);
  196. }
  197. //////////////////////////////////////////////////////////////////////////
  198. bool CUiAnimNode::RemoveTrack(IUiAnimTrack* track)
  199. {
  200. for (unsigned int i = 0; i < m_tracks.size(); i++)
  201. {
  202. if (m_tracks[i].get() == track)
  203. {
  204. m_tracks.erase(m_tracks.begin() + i);
  205. return true;
  206. }
  207. }
  208. return false;
  209. }
  210. //////////////////////////////////////////////////////////////////////////
  211. void CUiAnimNode::Reflect(AZ::SerializeContext* serializeContext)
  212. {
  213. // we do not currently serialize node type because all nodes are the same type (AzEntityNode)
  214. serializeContext->Class<CUiAnimNode>()
  215. ->Version(2)
  216. ->Field("ID", &CUiAnimNode::m_id)
  217. ->Field("Parent", &CUiAnimNode::m_parentNodeId)
  218. ->Field("Name", &CUiAnimNode::m_name)
  219. ->Field("Flags", &CUiAnimNode::m_flags)
  220. ->Field("Tracks", &CUiAnimNode::m_tracks)
  221. ->Field("Type", &CUiAnimNode::m_nodeType);
  222. }
  223. //////////////////////////////////////////////////////////////////////////
  224. IUiAnimTrack* CUiAnimNode::CreateTrackInternal(const CUiAnimParamType& paramType, EUiAnimCurveType trackType, EUiAnimValue valueType)
  225. {
  226. if (valueType == eUiAnimValue_Unknown)
  227. {
  228. SParamInfo info;
  229. // Try to get info from paramType, else we can't determine the track data type
  230. if (!GetParamInfoFromType(paramType, info))
  231. {
  232. return 0;
  233. }
  234. valueType = info.valueType;
  235. }
  236. IUiAnimTrack* track = NULL;
  237. switch (paramType.GetType())
  238. {
  239. // Create sub-classed tracks
  240. case eUiAnimParamType_TrackEvent:
  241. track = aznew CUiTrackEventTrack(m_pSequence->GetTrackEventStringTable());
  242. break;
  243. case eUiAnimParamType_Float:
  244. track = CreateTrackInternalFloat(trackType);
  245. break;
  246. default:
  247. // Create standard tracks
  248. switch (valueType)
  249. {
  250. case eUiAnimValue_Float:
  251. track = CreateTrackInternalFloat(trackType);
  252. break;
  253. case eUiAnimValue_RGB:
  254. case eUiAnimValue_Vector:
  255. track = CreateTrackInternalVector(trackType, paramType, valueType);
  256. break;
  257. case eUiAnimValue_Quat:
  258. track = CreateTrackInternalQuat(trackType, paramType);
  259. break;
  260. case eUiAnimValue_Bool:
  261. track = aznew UiBoolTrack;
  262. break;
  263. case eUiAnimValue_Vector2:
  264. track = CreateTrackInternalVector2(paramType);
  265. break;
  266. case eUiAnimValue_Vector3:
  267. track = CreateTrackInternalVector3(paramType);
  268. break;
  269. case eUiAnimValue_Vector4:
  270. track = CreateTrackInternalVector4(paramType);
  271. break;
  272. }
  273. }
  274. if (track)
  275. {
  276. track->SetParameterType(paramType);
  277. AddTrack(track);
  278. }
  279. return track;
  280. }
  281. //////////////////////////////////////////////////////////////////////////
  282. IUiAnimTrack* CUiAnimNode::CreateTrack(const CUiAnimParamType& paramType)
  283. {
  284. IUiAnimTrack* track = CreateTrackInternal(paramType, DEFAULT_TRACK_TYPE, eUiAnimValue_Unknown);
  285. return track;
  286. }
  287. //////////////////////////////////////////////////////////////////////////
  288. void CUiAnimNode::SerializeUiAnims(XmlNodeRef& xmlNode, bool bLoading, bool bLoadEmptyTracks)
  289. {
  290. if (bLoading)
  291. {
  292. // Delete all tracks.
  293. stl::free_container(m_tracks);
  294. CUiAnimNode::SParamInfo info;
  295. // Loading.
  296. int paramTypeVersion = 0;
  297. xmlNode->getAttr("paramIdVersion", paramTypeVersion);
  298. CUiAnimParamType paramType;
  299. const int num = xmlNode->getChildCount();
  300. for (int i = 0; i < num; i++)
  301. {
  302. XmlNodeRef trackNode = xmlNode->getChild(i);
  303. paramType.Serialize(GetUiAnimationSystem(), trackNode, bLoading, paramTypeVersion);
  304. int curveType = eUiAnimCurveType_Unknown;
  305. trackNode->getAttr("Type", curveType);
  306. int valueType = eUiAnimValue_Unknown;
  307. trackNode->getAttr("ValueType", valueType);
  308. IUiAnimTrack* track = CreateTrackInternal(paramType, (EUiAnimCurveType)curveType, (EUiAnimValue)valueType);
  309. if (track)
  310. {
  311. UiAnimParamData paramData;
  312. paramData.Serialize(GetUiAnimationSystem(), trackNode, bLoading);
  313. track->SetParamData(paramData);
  314. if (!track->Serialize(GetUiAnimationSystem(), trackNode, bLoading, bLoadEmptyTracks))
  315. {
  316. // Boolean tracks must always be loaded even if empty.
  317. if (track->GetValueType() != eUiAnimValue_Bool)
  318. {
  319. RemoveTrack(track);
  320. }
  321. }
  322. }
  323. }
  324. }
  325. else
  326. {
  327. // Saving.
  328. xmlNode->setAttr("paramIdVersion", CUiAnimParamType::kParamTypeVersion);
  329. for (unsigned int i = 0; i < m_tracks.size(); i++)
  330. {
  331. IUiAnimTrack* track = m_tracks[i].get();
  332. if (track)
  333. {
  334. CUiAnimParamType paramType = track->GetParameterType();
  335. XmlNodeRef trackNode = xmlNode->newChild("Track");
  336. paramType.Serialize(GetUiAnimationSystem(), trackNode, bLoading);
  337. UiAnimParamData paramData = track->GetParamData();
  338. paramData.Serialize(GetUiAnimationSystem(), trackNode, bLoading);
  339. int nTrackType = track->GetCurveType();
  340. trackNode->setAttr("Type", nTrackType);
  341. track->Serialize(GetUiAnimationSystem(), trackNode, bLoading);
  342. int valueType = track->GetValueType();
  343. trackNode->setAttr("ValueType", valueType);
  344. }
  345. }
  346. }
  347. }
  348. //////////////////////////////////////////////////////////////////////////
  349. void CUiAnimNode::SetTimeRange(Range timeRange)
  350. {
  351. for (unsigned int i = 0; i < m_tracks.size(); i++)
  352. {
  353. if (m_tracks[i])
  354. {
  355. m_tracks[i]->SetTimeRange(timeRange);
  356. }
  357. }
  358. }
  359. //////////////////////////////////////////////////////////////////////////
  360. // AZ::Serialization requires a default constructor
  361. CUiAnimNode::CUiAnimNode()
  362. : CUiAnimNode(0, eUiAnimNodeType_Invalid)
  363. {
  364. }
  365. //////////////////////////////////////////////////////////////////////////
  366. // explicit copy constructor is required to prevent compiler's generated copy constructor
  367. // from calling AZStd::mutex's private copy constructor
  368. CUiAnimNode::CUiAnimNode(const CUiAnimNode& other)
  369. : m_refCount(0)
  370. , m_id(0) // don't copy id - these should be unique
  371. , m_parentNodeId(other.m_parentNodeId)
  372. , m_nodeType(other.m_nodeType)
  373. , m_pOwner(other.m_pOwner)
  374. , m_pSequence(other.m_pSequence)
  375. , m_flags(other.m_flags)
  376. , m_pParentNode(other.m_pParentNode)
  377. , m_nLoadedParentNodeId(other.m_nLoadedParentNodeId)
  378. {
  379. // m_bIgnoreSetParam not copied
  380. }
  381. //////////////////////////////////////////////////////////////////////////
  382. CUiAnimNode::CUiAnimNode(const int id, EUiAnimNodeType nodeType)
  383. : m_refCount(0)
  384. , m_id(id)
  385. , m_parentNodeId(0)
  386. , m_nodeType(nodeType)
  387. {
  388. m_pOwner = 0;
  389. m_pSequence = 0;
  390. m_flags = 0;
  391. m_bIgnoreSetParam = false;
  392. m_pParentNode = 0;
  393. m_nLoadedParentNodeId = 0;
  394. }
  395. //////////////////////////////////////////////////////////////////////////
  396. CUiAnimNode::~CUiAnimNode()
  397. {
  398. }
  399. //////////////////////////////////////////////////////////////////////////
  400. void CUiAnimNode::add_ref()
  401. {
  402. ++m_refCount;
  403. }
  404. //////////////////////////////////////////////////////////////////////////
  405. void CUiAnimNode::release()
  406. {
  407. if (--m_refCount <= 0)
  408. {
  409. delete this;
  410. }
  411. }
  412. //////////////////////////////////////////////////////////////////////////
  413. void CUiAnimNode::SetFlags(int flags)
  414. {
  415. m_flags = flags;
  416. }
  417. //////////////////////////////////////////////////////////////////////////
  418. int CUiAnimNode::GetFlags() const
  419. {
  420. return m_flags;
  421. }
  422. //////////////////////////////////////////////////////////////////////////
  423. void CUiAnimNode::Animate([[maybe_unused]] SUiAnimContext& ec)
  424. {
  425. }
  426. //////////////////////////////////////////////////////////////////////////
  427. bool CUiAnimNode::IsParamValid(const CUiAnimParamType& paramType) const
  428. {
  429. SParamInfo info;
  430. if (GetParamInfoFromType(paramType, info))
  431. {
  432. return true;
  433. }
  434. return false;
  435. }
  436. //////////////////////////////////////////////////////////////////////////
  437. bool CUiAnimNode::SetParamValue(float time, CUiAnimParamType param, float value)
  438. {
  439. if (m_bIgnoreSetParam)
  440. {
  441. return true;
  442. }
  443. IUiAnimTrack* track = GetTrackForParameter(param);
  444. if (track && track->GetValueType() == eUiAnimValue_Float)
  445. {
  446. // Float track.
  447. bool bDefault = !(GetUiAnimationSystem()->IsRecording() && (m_flags & eUiAnimNodeFlags_EntitySelected)); // Only selected nodes can be recorded
  448. track->SetValue(time, value, bDefault);
  449. return true;
  450. }
  451. return false;
  452. }
  453. //////////////////////////////////////////////////////////////////////////
  454. bool CUiAnimNode::SetParamValue(float time, CUiAnimParamType param, const Vec3& value)
  455. {
  456. if (m_bIgnoreSetParam)
  457. {
  458. return true;
  459. }
  460. UiCompoundSplineTrack* track = static_cast<UiCompoundSplineTrack*>(GetTrackForParameter(param));
  461. if (track && track->GetValueType() == eUiAnimValue_Vector)
  462. {
  463. // Vec3 track.
  464. bool bDefault = !(GetUiAnimationSystem()->IsRecording() && (m_flags & eUiAnimNodeFlags_EntitySelected)); // Only selected nodes can be recorded
  465. track->SetValue(time, value, bDefault);
  466. return true;
  467. }
  468. return false;
  469. }
  470. //////////////////////////////////////////////////////////////////////////
  471. bool CUiAnimNode::SetParamValue(float time, CUiAnimParamType param, const Vec4& value)
  472. {
  473. if (m_bIgnoreSetParam)
  474. {
  475. return true;
  476. }
  477. UiCompoundSplineTrack* track = static_cast<UiCompoundSplineTrack*>(GetTrackForParameter(param));
  478. if (track && track->GetValueType() == eUiAnimValue_Vector4)
  479. {
  480. // Vec4 track.
  481. bool bDefault = !(GetUiAnimationSystem()->IsRecording() && (m_flags & eUiAnimNodeFlags_EntitySelected)); // Only selected nodes can be recorded
  482. track->SetValue(time, value, bDefault);
  483. return true;
  484. }
  485. return false;
  486. }
  487. //////////////////////////////////////////////////////////////////////////
  488. bool CUiAnimNode::GetParamValue(float time, CUiAnimParamType param, float& value)
  489. {
  490. IUiAnimTrack* track = GetTrackForParameter(param);
  491. if (track && track->GetValueType() == eUiAnimValue_Float && track->GetNumKeys() > 0)
  492. {
  493. // Float track.
  494. track->GetValue(time, value);
  495. return true;
  496. }
  497. return false;
  498. }
  499. //////////////////////////////////////////////////////////////////////////
  500. bool CUiAnimNode::GetParamValue(float time, CUiAnimParamType param, Vec3& value)
  501. {
  502. UiCompoundSplineTrack* track = static_cast<UiCompoundSplineTrack*>(GetTrackForParameter(param));
  503. if (track && track->GetValueType() == eUiAnimValue_Vector && track->GetNumKeys() > 0)
  504. {
  505. // Vec3 track.
  506. track->GetValue(time, value);
  507. return true;
  508. }
  509. return false;
  510. }
  511. //////////////////////////////////////////////////////////////////////////
  512. bool CUiAnimNode::GetParamValue(float time, CUiAnimParamType param, Vec4& value)
  513. {
  514. UiCompoundSplineTrack* track = static_cast<UiCompoundSplineTrack*>(GetTrackForParameter(param));
  515. if (track && track->GetValueType() == eUiAnimValue_Vector4 && track->GetNumKeys() > 0)
  516. {
  517. // Vec4 track.
  518. track->GetValue(time, value);
  519. return true;
  520. }
  521. return false;
  522. }
  523. //////////////////////////////////////////////////////////////////////////
  524. void CUiAnimNode::Serialize(XmlNodeRef& xmlNode, bool bLoading, bool bLoadEmptyTracks)
  525. {
  526. if (bLoading)
  527. {
  528. xmlNode->getAttr("Id", m_id);
  529. const char* name = xmlNode->getAttr("Name");
  530. int flags;
  531. if (xmlNode->getAttr("Flags", flags))
  532. {
  533. // Don't load expanded or selected flags
  534. flags = flags & ~(eUiAnimNodeFlags_Expanded | eUiAnimNodeFlags_EntitySelected);
  535. SetFlags(flags);
  536. }
  537. SetName(name);
  538. m_nLoadedParentNodeId = 0;
  539. xmlNode->getAttr("ParentNode", m_nLoadedParentNodeId);
  540. }
  541. else
  542. {
  543. m_nLoadedParentNodeId = 0;
  544. xmlNode->setAttr("Id", m_id);
  545. EUiAnimNodeType nodeType = GetType();
  546. static_cast<UiAnimationSystem*>(GetUiAnimationSystem())->SerializeNodeType(nodeType, xmlNode, bLoading, IUiAnimSequence::kSequenceVersion, m_flags);
  547. xmlNode->setAttr("Name", GetName().c_str());
  548. // Don't store expanded or selected flags
  549. int flags = GetFlags() & ~(eUiAnimNodeFlags_Expanded | eUiAnimNodeFlags_EntitySelected);
  550. xmlNode->setAttr("Flags", flags);
  551. if (m_pParentNode)
  552. {
  553. xmlNode->setAttr("ParentNode", static_cast<CUiAnimNode*>(m_pParentNode)->GetId());
  554. }
  555. }
  556. SerializeUiAnims(xmlNode, bLoading, bLoadEmptyTracks);
  557. }
  558. //////////////////////////////////////////////////////////////////////////
  559. void CUiAnimNode::InitPostLoad(IUiAnimSequence* pSequence, [[maybe_unused]] bool remapIds, [[maybe_unused]] LyShine::EntityIdMap* entityIdMap)
  560. {
  561. m_pSequence = pSequence;
  562. m_pParentNode = ((CUiAnimSequence*)m_pSequence)->FindNodeById(m_parentNodeId);
  563. // fix up animNode pointers and time ranges on tracks, then sort them
  564. for (unsigned int i = 0; i < m_tracks.size(); i++)
  565. {
  566. IUiAnimTrack* track = m_tracks[i].get();
  567. RegisterTrack(track);
  568. track->InitPostLoad(pSequence);
  569. }
  570. SortTracks();
  571. }
  572. //////////////////////////////////////////////////////////////////////////
  573. void CUiAnimNode::SetNodeOwner(IUiAnimNodeOwner* pOwner)
  574. {
  575. m_pOwner = pOwner;
  576. if (pOwner)
  577. {
  578. pOwner->OnNodeUiAnimated(this);
  579. }
  580. }
  581. //////////////////////////////////////////////////////////////////////////
  582. void CUiAnimNode::PostLoad()
  583. {
  584. if (m_nLoadedParentNodeId)
  585. {
  586. IUiAnimNode* pParentNode = ((CUiAnimSequence*)m_pSequence)->FindNodeById(m_nLoadedParentNodeId);
  587. m_pParentNode = pParentNode;
  588. m_parentNodeId = m_nLoadedParentNodeId; // adding as a temporary fix while we support both serialization methods
  589. m_nLoadedParentNodeId = 0;
  590. }
  591. }
  592. //////////////////////////////////////////////////////////////////////////
  593. Matrix34 CUiAnimNode::GetReferenceMatrix() const
  594. {
  595. static Matrix34 tm(IDENTITY);
  596. return tm;
  597. }
  598. IUiAnimTrack* CUiAnimNode::CreateTrackInternalFloat([[maybe_unused]] int trackType) const
  599. {
  600. // Don't need trackType any more
  601. return aznew C2DSplineTrack;
  602. }
  603. IUiAnimTrack* CUiAnimNode::CreateTrackInternalVector([[maybe_unused]] EUiAnimCurveType trackType, [[maybe_unused]] const CUiAnimParamType& paramType, [[maybe_unused]] const EUiAnimValue animValue) const
  604. {
  605. // Don't need trackType any more
  606. CUiAnimParamType subTrackParamTypes[MAX_SUBTRACKS];
  607. for (unsigned int i = 0; i < MAX_SUBTRACKS; ++i)
  608. {
  609. subTrackParamTypes[i] = eUiAnimParamType_AzComponentField;
  610. }
  611. return aznew UiCompoundSplineTrack(3, eUiAnimValue_Vector, subTrackParamTypes);
  612. }
  613. IUiAnimTrack* CUiAnimNode::CreateTrackInternalQuat([[maybe_unused]] EUiAnimCurveType trackType, [[maybe_unused]] const CUiAnimParamType& paramType) const
  614. {
  615. // UI_ANIMATION_REVISIT - my may want quat support at some point
  616. return nullptr;
  617. }
  618. //////////////////////////////////////////////////////////////////////////
  619. IUiAnimTrack* CUiAnimNode::CreateTrackInternalVector2([[maybe_unused]] const CUiAnimParamType& paramType) const
  620. {
  621. IUiAnimTrack* track;
  622. CUiAnimParamType subTrackParamTypes[MAX_SUBTRACKS];
  623. for (unsigned int i = 0; i < MAX_SUBTRACKS; ++i)
  624. {
  625. subTrackParamTypes[i] = eUiAnimParamType_Float;
  626. }
  627. track = aznew UiCompoundSplineTrack(2, eUiAnimValue_Vector2, subTrackParamTypes);
  628. return track;
  629. }
  630. IUiAnimTrack* CUiAnimNode::CreateTrackInternalVector3([[maybe_unused]] const CUiAnimParamType& paramType) const
  631. {
  632. IUiAnimTrack* track;
  633. CUiAnimParamType subTrackParamTypes[MAX_SUBTRACKS];
  634. for (unsigned int i = 0; i < MAX_SUBTRACKS; ++i)
  635. {
  636. subTrackParamTypes[i] = eUiAnimParamType_Float;
  637. }
  638. track = aznew UiCompoundSplineTrack(3, eUiAnimValue_Vector3, subTrackParamTypes);
  639. return track;
  640. }
  641. //////////////////////////////////////////////////////////////////////////
  642. IUiAnimTrack* CUiAnimNode::CreateTrackInternalVector4([[maybe_unused]] const CUiAnimParamType& paramType) const
  643. {
  644. IUiAnimTrack* track;
  645. CUiAnimParamType subTrackParamTypes[MAX_SUBTRACKS];
  646. for (unsigned int i = 0; i < MAX_SUBTRACKS; ++i)
  647. {
  648. subTrackParamTypes[i] = eUiAnimParamType_Float;
  649. }
  650. track = aznew UiCompoundSplineTrack(4, eUiAnimValue_Vector4, subTrackParamTypes);
  651. return track;
  652. }
  653. //////////////////////////////////////////////////////////////////////////
  654. void CUiAnimNode::SetParent(IUiAnimNode* pParent)
  655. {
  656. m_pParentNode = pParent;
  657. if (pParent)
  658. {
  659. m_parentNodeId = static_cast<CUiAnimNode*>(m_pParentNode)->GetId();
  660. }
  661. else
  662. {
  663. m_parentNodeId = 0;
  664. }
  665. }
  666. //////////////////////////////////////////////////////////////////////////
  667. IUiAnimNode* CUiAnimNode::HasDirectorAsParent() const
  668. {
  669. IUiAnimNode* pParent = GetParent();
  670. while (pParent)
  671. {
  672. if (pParent->GetType() == eUiAnimNodeType_Director)
  673. {
  674. return pParent;
  675. }
  676. // There are some invalid data.
  677. if (pParent->GetParent() == pParent)
  678. {
  679. pParent->SetParent(NULL);
  680. return NULL;
  681. }
  682. pParent = pParent->GetParent();
  683. }
  684. return NULL;
  685. }