AnimNode.cpp 41 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252
  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 <Maestro/Types/AssetBlendKey.h>
  13. #include "AssetBlendTrack.h"
  14. #include "CharacterTrack.h"
  15. #include "AnimSplineTrack.h"
  16. #include "BoolTrack.h"
  17. #include "MathConversion.h"
  18. #include "SelectTrack.h"
  19. #include "EventTrack.h"
  20. #include "SoundTrack.h"
  21. #include "ConsoleTrack.h"
  22. #include "LookAtTrack.h"
  23. #include "TrackEventTrack.h"
  24. #include "SequenceTrack.h"
  25. #include "CompoundSplineTrack.h"
  26. #include "GotoTrack.h"
  27. #include "CaptureTrack.h"
  28. #include "CommentTrack.h"
  29. #include "ScreenFaderTrack.h"
  30. #include "TimeRangesTrack.h"
  31. #include "SoundTrack.h"
  32. #include <AzCore/std/sort.h>
  33. #include <AzCore/Math/MathUtils.h>
  34. #include <AzCore/Component/TickBus.h>
  35. #include <ctime>
  36. #include "Maestro/Types/AnimValueType.h"
  37. #include "Maestro/Types/AnimNodeType.h"
  38. #include "Maestro/Types/AnimParamType.h"
  39. //////////////////////////////////////////////////////////////////////////
  40. // Old deprecated IDs
  41. //////////////////////////////////////////////////////////////////////////
  42. #define APARAM_CHARACTER4 static_cast<AnimParamType>(static_cast<int>(AnimParamType::User) + 0x10)
  43. #define APARAM_CHARACTER5 static_cast<AnimParamType>(static_cast<int>(AnimParamType::User) + 0x11)
  44. #define APARAM_CHARACTER6 static_cast<AnimParamType>(static_cast<int>(AnimParamType::User) + 0x12)
  45. #define APARAM_CHARACTER7 static_cast<AnimParamType>(static_cast<int>(AnimParamType::User) + 0x13)
  46. #define APARAM_CHARACTER8 static_cast<AnimParamType>(static_cast<int>(AnimParamType::User) + 0x14)
  47. #define APARAM_CHARACTER9 static_cast<AnimParamType>(static_cast<int>(AnimParamType::User) + 0x15)
  48. #define APARAM_CHARACTER10 static_cast<AnimParamType>(static_cast<int>(AnimParamType::User) + 0x16)
  49. //////////////////////////////////////////////////////////////////////////
  50. static const EAnimCurveType DEFAULT_TRACK_TYPE = eAnimCurveType_BezierFloat;
  51. // Old serialization values that are no longer
  52. // defined in IMovieSystem.h, but needed for conversion:
  53. static const int OLD_ACURVE_GOTO = 21;
  54. static const int OLD_APARAM_PARTICLE_COUNT_SCALE = 95;
  55. static const int OLD_APARAM_PARTICLE_PULSE_PERIOD = 96;
  56. static const int OLD_APARAM_PARTICLE_SCALE = 97;
  57. static const int OLD_APARAM_PARTICLE_SPEED_SCALE = 98;
  58. static const int OLD_APARAM_PARTICLE_STRENGTH = 99;
  59. //////////////////////////////////////////////////////////////////////////
  60. // CAnimNode.
  61. //////////////////////////////////////////////////////////////////////////
  62. //////////////////////////////////////////////////////////////////////////
  63. void CAnimNode::Activate([[maybe_unused]] bool bActivate)
  64. {
  65. }
  66. //////////////////////////////////////////////////////////////////////////
  67. int CAnimNode::GetTrackCount() const
  68. {
  69. return static_cast<int>(m_tracks.size());
  70. }
  71. AZStd::string CAnimNode::GetParamName(const CAnimParamType& paramType) const
  72. {
  73. SParamInfo info;
  74. if (GetParamInfoFromType(paramType, info))
  75. {
  76. return info.name;
  77. }
  78. return "Unknown";
  79. }
  80. AnimValueType CAnimNode::GetParamValueType(const CAnimParamType& paramType) const
  81. {
  82. SParamInfo info;
  83. if (GetParamInfoFromType(paramType, info))
  84. {
  85. return info.valueType;
  86. }
  87. return AnimValueType::Unknown;
  88. }
  89. IAnimNode::ESupportedParamFlags CAnimNode::GetParamFlags(const CAnimParamType& paramType) const
  90. {
  91. SParamInfo info;
  92. if (GetParamInfoFromType(paramType, info))
  93. {
  94. return info.flags;
  95. }
  96. return IAnimNode::ESupportedParamFlags(0);
  97. }
  98. IAnimTrack* CAnimNode::GetTrackForParameter(const CAnimParamType& paramType) const
  99. {
  100. for (int i = 0, num = (int)m_tracks.size(); i < num; i++)
  101. {
  102. if (m_tracks[i]->GetParameterType() == paramType)
  103. {
  104. return m_tracks[i].get();
  105. }
  106. // Search the sub-tracks also if any.
  107. for (int k = 0; k < m_tracks[i]->GetSubTrackCount(); ++k)
  108. {
  109. if (m_tracks[i]->GetSubTrack(k)->GetParameterType() == paramType)
  110. {
  111. return m_tracks[i]->GetSubTrack(k);
  112. }
  113. }
  114. }
  115. return 0;
  116. }
  117. IAnimTrack* CAnimNode::GetTrackForParameter(const CAnimParamType& paramType, uint32 index) const
  118. {
  119. SParamInfo paramInfo;
  120. GetParamInfoFromType(paramType, paramInfo);
  121. if ((paramInfo.flags & IAnimNode::eSupportedParamFlags_MultipleTracks) == 0)
  122. {
  123. return GetTrackForParameter(paramType);
  124. }
  125. uint32 count = 0;
  126. for (int i = 0, num = (int)m_tracks.size(); i < num; i++)
  127. {
  128. if (m_tracks[i]->GetParameterType() == paramType && count++ == index)
  129. {
  130. return m_tracks[i].get();
  131. }
  132. // For this case, no subtracks are considered.
  133. }
  134. return 0;
  135. }
  136. uint32 CAnimNode::GetTrackParamIndex(const IAnimTrack* pTrack) const
  137. {
  138. assert(pTrack);
  139. uint32 index = 0;
  140. CAnimParamType paramType = pTrack->GetParameterType();
  141. SParamInfo paramInfo;
  142. GetParamInfoFromType(paramType, paramInfo);
  143. if ((paramInfo.flags & IAnimNode::eSupportedParamFlags_MultipleTracks) == 0)
  144. {
  145. return 0;
  146. }
  147. for (int i = 0, num = (int)m_tracks.size(); i < num; i++)
  148. {
  149. if (m_tracks[i].get() == pTrack)
  150. {
  151. return index;
  152. }
  153. if (m_tracks[i]->GetParameterType() == paramType)
  154. {
  155. ++index;
  156. }
  157. // For this case, no subtracks are considered.
  158. }
  159. assert(!"CAnimNode::GetTrackParamIndex() called with an invalid argument!");
  160. return 0;
  161. }
  162. IAnimTrack* CAnimNode::GetTrackByIndex(int nIndex) const
  163. {
  164. if (nIndex >= (int)m_tracks.size())
  165. {
  166. assert("nIndex>=m_tracks.size()" && false);
  167. return NULL;
  168. }
  169. return m_tracks[nIndex].get();
  170. }
  171. void CAnimNode::SetTrack(const CAnimParamType& paramType, IAnimTrack* pTrack)
  172. {
  173. if (pTrack)
  174. {
  175. for (unsigned int i = 0; i < m_tracks.size(); i++)
  176. {
  177. if (m_tracks[i]->GetParameterType() == paramType)
  178. {
  179. m_tracks[i].reset(pTrack);
  180. return;
  181. }
  182. }
  183. AddTrack(pTrack);
  184. }
  185. else
  186. {
  187. // Remove track at this id.
  188. for (unsigned int i = 0; i < m_tracks.size(); i++)
  189. {
  190. if (m_tracks[i]->GetParameterType() == paramType)
  191. {
  192. m_tracks.erase(m_tracks.begin() + i);
  193. }
  194. }
  195. }
  196. }
  197. //////////////////////////////////////////////////////////////////////////
  198. bool CAnimNode::TrackOrder(const AZStd::intrusive_ptr<IAnimTrack>& left, const AZStd::intrusive_ptr<IAnimTrack>& right)
  199. {
  200. return left->GetParameterType() < right->GetParameterType();
  201. }
  202. //////////////////////////////////////////////////////////////////////////
  203. void CAnimNode::AddTrack(IAnimTrack* pTrack)
  204. {
  205. RegisterTrack(pTrack);
  206. m_tracks.push_back(AZStd::intrusive_ptr<IAnimTrack>(pTrack));
  207. SortTracks();
  208. }
  209. //////////////////////////////////////////////////////////////////////////
  210. void CAnimNode::RegisterTrack(IAnimTrack* pTrack)
  211. {
  212. pTrack->SetTimeRange(GetSequence()->GetTimeRange());
  213. pTrack->SetNode(this);
  214. }
  215. void CAnimNode::SortTracks()
  216. {
  217. AZStd::insertion_sort(m_tracks.begin(), m_tracks.end(), TrackOrder);
  218. }
  219. //////////////////////////////////////////////////////////////////////////
  220. bool CAnimNode::RemoveTrack(IAnimTrack* pTrack)
  221. {
  222. for (unsigned int i = 0; i < m_tracks.size(); i++)
  223. {
  224. if (m_tracks[i].get() == pTrack)
  225. {
  226. m_tracks.erase(m_tracks.begin() + i);
  227. return true;
  228. }
  229. }
  230. return false;
  231. }
  232. //////////////////////////////////////////////////////////////////////////
  233. static bool AnimNodeVersionConverter(
  234. AZ::SerializeContext& serializeContext,
  235. AZ::SerializeContext::DataElementNode& rootElement)
  236. {
  237. if (rootElement.GetVersion() < 3)
  238. {
  239. rootElement.AddElement(serializeContext, "BaseClass1", azrtti_typeid<IAnimNode>());
  240. }
  241. if (rootElement.GetVersion() < 4)
  242. {
  243. // remove vector scale tracks from transform anim nodes
  244. AZStd::string name;
  245. if (rootElement.FindSubElementAndGetData<AZStd::string>(AZ_CRC_CE("Name"), name) && name == "Transform")
  246. {
  247. auto tracksElement = rootElement.FindSubElement(AZ_CRC_CE("Tracks"));
  248. if (tracksElement)
  249. {
  250. for (int trackIndex = tracksElement->GetNumSubElements() - 1; trackIndex >= 0; trackIndex--)
  251. {
  252. auto trackElement = tracksElement->GetSubElement(trackIndex);
  253. bool isScale = false;
  254. // trackElement should be an intrusive_ptr with one child
  255. if (trackElement.GetNumSubElements() == 1)
  256. {
  257. auto ptrElement = trackElement.GetSubElement(0);
  258. auto paramTypeElement = ptrElement.FindSubElement(AZ_CRC_CE("ParamType"));
  259. if (paramTypeElement)
  260. {
  261. AZStd::string paramName;
  262. if (paramTypeElement->FindSubElementAndGetData<AZStd::string>(AZ_CRC_CE("Name"), paramName) && paramName == "Scale")
  263. {
  264. isScale = true;
  265. }
  266. }
  267. }
  268. if (isScale)
  269. {
  270. tracksElement->RemoveElement(trackIndex);
  271. }
  272. }
  273. }
  274. }
  275. }
  276. return true;
  277. }
  278. void CAnimNode::Reflect(AZ::ReflectContext* context)
  279. {
  280. if (auto serializeContext = azrtti_cast<AZ::SerializeContext*>(context))
  281. {
  282. serializeContext->Class<CAnimNode, IAnimNode>()
  283. ->Version(4, &AnimNodeVersionConverter)
  284. ->Field("ID", &CAnimNode::m_id)
  285. ->Field("Name", &CAnimNode::m_name)
  286. ->Field("Flags", &CAnimNode::m_flags)
  287. ->Field("Tracks", &CAnimNode::m_tracks)
  288. ->Field("Parent", &CAnimNode::m_parentNodeId)
  289. ->Field("Type", &CAnimNode::m_nodeType)
  290. ->Field("Expanded", &CAnimNode::m_expanded);
  291. }
  292. }
  293. //////////////////////////////////////////////////////////////////////////
  294. IAnimTrack* CAnimNode::CreateTrackInternal(const CAnimParamType& paramType, EAnimCurveType trackType, AnimValueType valueType)
  295. {
  296. if (valueType == AnimValueType::Unknown)
  297. {
  298. SParamInfo info;
  299. // Try to get info from paramType, else we can't determine the track data type
  300. if (!GetParamInfoFromType(paramType, info))
  301. {
  302. return 0;
  303. }
  304. valueType = info.valueType;
  305. }
  306. IAnimTrack* pTrack = NULL;
  307. switch (paramType.GetType())
  308. {
  309. // Create sub-classed tracks
  310. case AnimParamType::Event:
  311. pTrack = aznew CEventTrack(m_pSequence->GetTrackEventStringTable());
  312. break;
  313. case AnimParamType::Sound:
  314. pTrack = aznew CSoundTrack;
  315. break;
  316. case AnimParamType::Animation:
  317. pTrack = aznew CCharacterTrack;
  318. break;
  319. case AnimParamType::Console:
  320. pTrack = aznew CConsoleTrack;
  321. break;
  322. case AnimParamType::LookAt:
  323. pTrack = aznew CLookAtTrack;
  324. break;
  325. case AnimParamType::TrackEvent:
  326. pTrack = aznew CTrackEventTrack(m_pSequence->GetTrackEventStringTable());
  327. break;
  328. case AnimParamType::Sequence:
  329. pTrack = aznew CSequenceTrack;
  330. break;
  331. case AnimParamType::Capture:
  332. pTrack = aznew CCaptureTrack;
  333. break;
  334. case AnimParamType::CommentText:
  335. pTrack = aznew CCommentTrack;
  336. break;
  337. case AnimParamType::ScreenFader:
  338. pTrack = aznew CScreenFaderTrack;
  339. break;
  340. case AnimParamType::Goto:
  341. pTrack = aznew CGotoTrack;
  342. break;
  343. case AnimParamType::TimeRanges:
  344. pTrack = aznew CTimeRangesTrack;
  345. break;
  346. case AnimParamType::Float:
  347. pTrack = CreateTrackInternalFloat(trackType);
  348. break;
  349. default:
  350. // Create standard tracks
  351. switch (valueType)
  352. {
  353. case AnimValueType::Float:
  354. pTrack = CreateTrackInternalFloat(trackType);
  355. break;
  356. case AnimValueType::RGB:
  357. case AnimValueType::Vector:
  358. pTrack = CreateTrackInternalVector(trackType, paramType, valueType);
  359. break;
  360. case AnimValueType::Quat:
  361. pTrack = CreateTrackInternalQuat(trackType, paramType);
  362. break;
  363. case AnimValueType::Bool:
  364. pTrack = aznew CBoolTrack;
  365. break;
  366. case AnimValueType::Select:
  367. pTrack = aznew CSelectTrack;
  368. break;
  369. case AnimValueType::Vector4:
  370. pTrack = CreateTrackInternalVector4(paramType);
  371. break;
  372. case AnimValueType::CharacterAnim:
  373. pTrack = aznew CCharacterTrack;
  374. break;
  375. case AnimValueType::AssetBlend:
  376. pTrack = aznew CAssetBlendTrack;
  377. break;
  378. }
  379. }
  380. if (pTrack)
  381. {
  382. pTrack->SetParameterType(paramType);
  383. // Assign a unique id for every track.
  384. pTrack->SetId(m_pSequence->GetUniqueTrackIdAndGenerateNext());
  385. int subTrackCount = pTrack->GetSubTrackCount();
  386. for (int subTrackIndex = 0; subTrackIndex < subTrackCount; subTrackIndex++)
  387. {
  388. IAnimTrack* subTrack = pTrack->GetSubTrack(subTrackIndex);
  389. subTrack->SetId(m_pSequence->GetUniqueTrackIdAndGenerateNext());
  390. }
  391. AddTrack(pTrack);
  392. }
  393. return pTrack;
  394. }
  395. //////////////////////////////////////////////////////////////////////////
  396. IAnimTrack* CAnimNode::CreateTrack(const CAnimParamType& paramType)
  397. {
  398. IAnimTrack* pTrack = CreateTrackInternal(paramType, DEFAULT_TRACK_TYPE, AnimValueType::Unknown);
  399. InitializeTrackDefaultValue(pTrack, paramType);
  400. return pTrack;
  401. }
  402. //////////////////////////////////////////////////////////////////////////
  403. void CAnimNode::SerializeAnims(XmlNodeRef& xmlNode, bool bLoading, bool bLoadEmptyTracks)
  404. {
  405. if (bLoading)
  406. {
  407. // Delete all tracks.
  408. stl::free_container(m_tracks);
  409. CAnimNode::SParamInfo info;
  410. // Loading.
  411. int paramTypeVersion = 0;
  412. xmlNode->getAttr("paramIdVersion", paramTypeVersion);
  413. CAnimParamType paramType;
  414. int num = xmlNode->getChildCount();
  415. for (int i = 0; i < num; i++)
  416. {
  417. XmlNodeRef trackNode = xmlNode->getChild(i);
  418. paramType.Serialize(trackNode, bLoading, paramTypeVersion);
  419. if (paramType.GetType() == AnimParamType::Music)
  420. {
  421. // skip loading AnimParamType::Music - it's deprecated
  422. continue;
  423. }
  424. if (paramTypeVersion == 0) // for old version with sound and animation param ids swapped
  425. {
  426. AnimParamType APARAM_ANIMATION_OLD = AnimParamType::Sound;
  427. AnimParamType APARAM_SOUND_OLD = AnimParamType::Animation;
  428. if (paramType.GetType() == APARAM_ANIMATION_OLD)
  429. {
  430. paramType = AnimParamType::Animation;
  431. }
  432. else if (paramType.GetType() == APARAM_SOUND_OLD)
  433. {
  434. paramType = AnimParamType::Sound;
  435. }
  436. }
  437. int curveType = eAnimCurveType_Unknown;
  438. trackNode->getAttr("Type", curveType);
  439. if (curveType == eAnimCurveType_Unknown)
  440. {
  441. if (paramTypeVersion == 0)
  442. {
  443. //////////////////////////////////////////////////////////////////////////
  444. // Backward compatibility code
  445. //////////////////////////////////////////////////////////////////////////
  446. // Legacy animation track.
  447. // Collapse parameter ID to the single type
  448. if (paramType.GetType() >= AnimParamType::Sound && paramType.GetType() <= static_cast<AnimParamType>(static_cast<int>(AnimParamType::Sound) + 2))
  449. {
  450. paramType = AnimParamType::Sound;
  451. }
  452. if (paramType.GetType() >= AnimParamType::Animation && paramType.GetType() <= static_cast<AnimParamType>(static_cast<int>(AnimParamType::Animation) + 2))
  453. {
  454. paramType = AnimParamType::Animation;
  455. }
  456. if (paramType.GetType() >= APARAM_CHARACTER4 && paramType.GetType() <= APARAM_CHARACTER10)
  457. {
  458. paramType = AnimParamType::Animation;
  459. }
  460. // Old tracks always used TCB tracks.
  461. // Backward compatibility to the CryEngine2 for track type (will make TCB controller)
  462. curveType = eAnimCurveType_TCBVector;
  463. }
  464. }
  465. if (paramTypeVersion <= 1)
  466. {
  467. // In old versions goto tracks were identified by a curve id
  468. if (curveType == OLD_ACURVE_GOTO)
  469. {
  470. paramType = AnimParamType::Goto;
  471. curveType = eAnimCurveType_Unknown;
  472. }
  473. }
  474. if (paramTypeVersion <= 3 && paramType.GetType() >= static_cast<AnimParamType>(OLD_APARAM_USER))
  475. {
  476. // APARAM_USER 100 => 100000
  477. paramType = static_cast<AnimParamType>(static_cast<int>(paramType.GetType()) + static_cast<int>(AnimParamType::User) - OLD_APARAM_USER);
  478. }
  479. if (paramTypeVersion <= 4)
  480. {
  481. // In old versions there was special code for particles
  482. // that is now handles by generic entity node code
  483. switch (paramType.GetType())
  484. {
  485. case static_cast<AnimParamType>(OLD_APARAM_PARTICLE_COUNT_SCALE) :
  486. paramType = CAnimParamType("ScriptTable:Properties/CountScale");
  487. break;
  488. case static_cast<AnimParamType>(OLD_APARAM_PARTICLE_PULSE_PERIOD) :
  489. paramType = CAnimParamType("ScriptTable:Properties/PulsePeriod");
  490. break;
  491. case static_cast<AnimParamType>(OLD_APARAM_PARTICLE_SCALE) :
  492. paramType = CAnimParamType("ScriptTable:Properties/Scale");
  493. break;
  494. case static_cast<AnimParamType>(OLD_APARAM_PARTICLE_SPEED_SCALE) :
  495. paramType = CAnimParamType("ScriptTable:Properties/SpeedScale");
  496. break;
  497. case static_cast<AnimParamType>(OLD_APARAM_PARTICLE_STRENGTH):
  498. paramType = CAnimParamType("ScriptTable:Properties/Strength");
  499. break;
  500. }
  501. }
  502. if (paramTypeVersion <= 5 && !(GetSequence()->GetFlags() & IAnimSequence::eSeqFlags_LightAnimationSet))
  503. {
  504. // In old versions there was special code for lights that is now handled
  505. // by generic entity node code if this is not a light animation set sequence
  506. switch (paramType.GetType())
  507. {
  508. case AnimParamType::LightDiffuse:
  509. paramType = CAnimParamType("ScriptTable:Properties/Color/clrDiffuse");
  510. break;
  511. case AnimParamType::LightRadius:
  512. paramType = CAnimParamType("ScriptTable:Properties/Radius");
  513. break;
  514. case AnimParamType::LightDiffuseMult:
  515. paramType = CAnimParamType("ScriptTable:Properties/Color/fDiffuseMultiplier");
  516. break;
  517. case AnimParamType::LightHDRDynamic:
  518. paramType = CAnimParamType("ScriptTable:Properties/Color/fHDRDynamic");
  519. break;
  520. case AnimParamType::LightSpecularMult:
  521. paramType = CAnimParamType("ScriptTable:Properties/Color/fSpecularMultiplier");
  522. break;
  523. case AnimParamType::LightSpecPercentage:
  524. paramType = CAnimParamType("ScriptTable:Properties/Color/fSpecularPercentage");
  525. break;
  526. }
  527. }
  528. if (paramTypeVersion <= 7 && paramType.GetType() == AnimParamType::Physics)
  529. {
  530. paramType = AnimParamType::PhysicsDriven;
  531. }
  532. int valueType = static_cast<int>(AnimValueType::Unknown);
  533. trackNode->getAttr("ValueType", valueType);
  534. IAnimTrack* pTrack = CreateTrackInternal(paramType, (EAnimCurveType)curveType, static_cast<AnimValueType>(valueType));
  535. bool trackRemoved = false;
  536. if (pTrack)
  537. {
  538. if (!pTrack->Serialize(trackNode, bLoading, bLoadEmptyTracks))
  539. {
  540. // Boolean tracks must always be loaded even if empty.
  541. if (pTrack->GetValueType() != AnimValueType::Bool)
  542. {
  543. RemoveTrack(pTrack);
  544. trackRemoved = true;
  545. }
  546. }
  547. }
  548. if (!trackRemoved && gEnv->IsEditor())
  549. {
  550. InitializeTrackDefaultValue(pTrack, paramType);
  551. }
  552. }
  553. }
  554. else
  555. {
  556. // Saving.
  557. xmlNode->setAttr("paramIdVersion", CAnimParamType::kParamTypeVersion);
  558. for (unsigned int i = 0; i < m_tracks.size(); i++)
  559. {
  560. IAnimTrack* pTrack = m_tracks[i].get();
  561. if (pTrack)
  562. {
  563. CAnimParamType paramType = m_tracks[i]->GetParameterType();
  564. XmlNodeRef trackNode = xmlNode->newChild("Track");
  565. paramType.Serialize(trackNode, bLoading);
  566. int nTrackType = pTrack->GetCurveType();
  567. trackNode->setAttr("Type", nTrackType);
  568. pTrack->Serialize(trackNode, bLoading);
  569. int valueType = static_cast<int>(pTrack->GetValueType());
  570. trackNode->setAttr("ValueType", valueType);
  571. }
  572. }
  573. }
  574. }
  575. //////////////////////////////////////////////////////////////////////////
  576. void CAnimNode::SetTimeRange(Range timeRange)
  577. {
  578. for (unsigned int i = 0; i < m_tracks.size(); i++)
  579. {
  580. if (m_tracks[i])
  581. {
  582. m_tracks[i]->SetTimeRange(timeRange);
  583. }
  584. }
  585. }
  586. //////////////////////////////////////////////////////////////////////////
  587. // AZ::Serialization requires a default constructor
  588. CAnimNode::CAnimNode()
  589. : CAnimNode(0, AnimNodeType::Invalid)
  590. {
  591. }
  592. //////////////////////////////////////////////////////////////////////////
  593. // explicit copy constructor is required to prevent compiler's generated copy constructor
  594. // from calling AZStd::mutex's private copy constructor
  595. CAnimNode::CAnimNode(const CAnimNode& other)
  596. : m_refCount(0)
  597. , m_id(0) // don't copy id - these should be unique
  598. , m_parentNodeId(other.m_parentNodeId)
  599. , m_nodeType(other.m_nodeType)
  600. , m_pOwner(other.m_pOwner)
  601. , m_pSequence(other.m_pSequence)
  602. , m_flags(other.m_flags)
  603. , m_pParentNode(other.m_pParentNode)
  604. , m_nLoadedParentNodeId(other.m_nLoadedParentNodeId)
  605. , m_expanded(other.m_expanded)
  606. , m_movieSystem(other.m_movieSystem)
  607. {
  608. // m_bIgnoreSetParam not copied
  609. }
  610. //////////////////////////////////////////////////////////////////////////
  611. CAnimNode::CAnimNode(const int id, AnimNodeType nodeType)
  612. : m_refCount(0)
  613. , m_id(id)
  614. , m_parentNodeId(0)
  615. , m_nodeType(nodeType)
  616. , m_movieSystem(AZ::Interface<IMovieSystem>::Get())
  617. {
  618. m_pOwner = 0;
  619. m_pSequence = 0;
  620. m_flags = 0;
  621. m_bIgnoreSetParam = false;
  622. m_pParentNode = 0;
  623. m_nLoadedParentNodeId = 0;
  624. m_expanded = true;
  625. AZ_Trace("CAnimNode", "CAnimNode type %i", static_cast<int>(nodeType));
  626. }
  627. //////////////////////////////////////////////////////////////////////////
  628. CAnimNode::~CAnimNode()
  629. {
  630. AZ_Trace("CAnimNode", "~CAnimNode %i", static_cast<int>(m_nodeType));
  631. }
  632. //////////////////////////////////////////////////////////////////////////
  633. void CAnimNode::add_ref()
  634. {
  635. ++m_refCount;
  636. }
  637. //////////////////////////////////////////////////////////////////////////
  638. void CAnimNode::release()
  639. {
  640. if (--m_refCount <= 0)
  641. {
  642. delete this;
  643. }
  644. }
  645. //////////////////////////////////////////////////////////////////////////
  646. void CAnimNode::SetFlags(int flags)
  647. {
  648. m_flags = flags;
  649. }
  650. //////////////////////////////////////////////////////////////////////////
  651. int CAnimNode::GetFlags() const
  652. {
  653. return m_flags;
  654. }
  655. //////////////////////////////////////////////////////////////////////////
  656. bool CAnimNode::AreFlagsSetOnNodeOrAnyParent(EAnimNodeFlags flagsToCheck) const
  657. {
  658. if (m_pParentNode)
  659. {
  660. // recurse up parent chain until we find the flagsToCheck set or get to the top of the chain
  661. return ((GetFlags() & flagsToCheck) != 0) || m_pParentNode->AreFlagsSetOnNodeOrAnyParent(flagsToCheck);
  662. }
  663. // top of parent chain
  664. return ((GetFlags() & flagsToCheck) != 0);
  665. }
  666. //////////////////////////////////////////////////////////////////////////
  667. void CAnimNode::Animate([[maybe_unused]] SAnimContext& ec)
  668. {
  669. }
  670. //////////////////////////////////////////////////////////////////////////
  671. bool CAnimNode::IsParamValid(const CAnimParamType& paramType) const
  672. {
  673. SParamInfo info;
  674. if (GetParamInfoFromType(paramType, info))
  675. {
  676. return true;
  677. }
  678. return false;
  679. }
  680. //////////////////////////////////////////////////////////////////////////
  681. bool CAnimNode::SetParamValue(float time, CAnimParamType param, float value)
  682. {
  683. if (m_bIgnoreSetParam)
  684. {
  685. return true;
  686. }
  687. IAnimTrack* pTrack = GetTrackForParameter(param);
  688. if (pTrack && pTrack->GetValueType() == AnimValueType::Float)
  689. {
  690. // Float track.
  691. bool bDefault = !(m_movieSystem->IsRecording() && (m_flags & eAnimNodeFlags_EntitySelected)); // Only selected nodes can be recorded
  692. pTrack->SetValue(time, value, bDefault);
  693. return true;
  694. }
  695. return false;
  696. }
  697. //////////////////////////////////////////////////////////////////////////
  698. bool CAnimNode::SetParamValue(float time, CAnimParamType param, const AZ::Vector3& value)
  699. {
  700. if (m_bIgnoreSetParam)
  701. {
  702. return true;
  703. }
  704. CCompoundSplineTrack* pTrack = static_cast<CCompoundSplineTrack*>(GetTrackForParameter(param));
  705. if (pTrack && pTrack->GetValueType() == AnimValueType::Vector)
  706. {
  707. // Vec3 track.
  708. bool bDefault = !(m_movieSystem->IsRecording() && (m_flags & eAnimNodeFlags_EntitySelected)); // Only selected nodes can be recorded
  709. pTrack->SetValue(time, value, bDefault);
  710. return true;
  711. }
  712. return false;
  713. }
  714. //////////////////////////////////////////////////////////////////////////
  715. bool CAnimNode::SetParamValue(float time, CAnimParamType param, const AZ::Vector4& value)
  716. {
  717. if (m_bIgnoreSetParam)
  718. {
  719. return true;
  720. }
  721. CCompoundSplineTrack* pTrack = static_cast<CCompoundSplineTrack*>(GetTrackForParameter(param));
  722. if (pTrack && pTrack->GetValueType() == AnimValueType::Vector4)
  723. {
  724. // Vec4 track.
  725. bool bDefault = !(m_movieSystem->IsRecording() && (m_flags & eAnimNodeFlags_EntitySelected)); // Only selected nodes can be recorded
  726. pTrack->SetValue(time, value, bDefault);
  727. return true;
  728. }
  729. return false;
  730. }
  731. //////////////////////////////////////////////////////////////////////////
  732. bool CAnimNode::GetParamValue(float time, CAnimParamType param, float& value)
  733. {
  734. IAnimTrack* pTrack = GetTrackForParameter(param);
  735. if (pTrack && pTrack->GetValueType() == AnimValueType::Float && pTrack->GetNumKeys() > 0)
  736. {
  737. // Float track.
  738. pTrack->GetValue(time, value);
  739. return true;
  740. }
  741. return false;
  742. }
  743. //////////////////////////////////////////////////////////////////////////
  744. bool CAnimNode::GetParamValue(float time, CAnimParamType param, AZ::Vector3& value)
  745. {
  746. CCompoundSplineTrack* pTrack = static_cast<CCompoundSplineTrack*>(GetTrackForParameter(param));
  747. if (pTrack && pTrack->GetValueType() == AnimValueType::Vector && pTrack->GetNumKeys() > 0)
  748. {
  749. // Vec3 track.
  750. pTrack->GetValue(time, value);
  751. return true;
  752. }
  753. return false;
  754. }
  755. //////////////////////////////////////////////////////////////////////////
  756. bool CAnimNode::GetParamValue(float time, CAnimParamType param, AZ::Vector4& value)
  757. {
  758. CCompoundSplineTrack* pTrack = static_cast<CCompoundSplineTrack*>(GetTrackForParameter(param));
  759. if (pTrack && pTrack->GetValueType() == AnimValueType::Vector4 && pTrack->GetNumKeys() > 0)
  760. {
  761. // Vec4 track.
  762. pTrack->GetValue(time, value);
  763. return true;
  764. }
  765. return false;
  766. }
  767. //////////////////////////////////////////////////////////////////////////
  768. /// @deprecated Serialization for Sequence data in Component Entity Sequences now occurs through AZ::SerializeContext and the Sequence Component
  769. void CAnimNode::Serialize(XmlNodeRef& xmlNode, bool bLoading, bool bLoadEmptyTracks)
  770. {
  771. if (bLoading)
  772. {
  773. xmlNode->getAttr("Id", m_id);
  774. const char* name = xmlNode->getAttr("Name");
  775. int flags;
  776. if (xmlNode->getAttr("Flags", flags))
  777. {
  778. // Don't load expanded or selected flags
  779. flags = flags & ~(eAnimNodeFlags_Expanded | eAnimNodeFlags_EntitySelected);
  780. SetFlags(flags);
  781. }
  782. SetName(name);
  783. m_nLoadedParentNodeId = 0;
  784. xmlNode->getAttr("ParentNode", m_nLoadedParentNodeId);
  785. }
  786. else
  787. {
  788. m_nLoadedParentNodeId = 0;
  789. xmlNode->setAttr("Id", m_id);
  790. AnimNodeType nodeType = GetType();
  791. GetMovieSystem()->SerializeNodeType(nodeType, xmlNode, bLoading, IAnimSequence::kSequenceVersion, m_flags);
  792. xmlNode->setAttr("Name", GetName());
  793. // Don't store expanded or selected flags
  794. int flags = GetFlags() & ~(eAnimNodeFlags_Expanded | eAnimNodeFlags_EntitySelected);
  795. xmlNode->setAttr("Flags", flags);
  796. if (m_pParentNode)
  797. {
  798. xmlNode->setAttr("ParentNode", static_cast<CAnimNode*>(m_pParentNode)->GetId());
  799. }
  800. }
  801. SerializeAnims(xmlNode, bLoading, bLoadEmptyTracks);
  802. }
  803. //////////////////////////////////////////////////////////////////////////
  804. void CAnimNode::InitPostLoad(IAnimSequence* sequence)
  805. {
  806. [[maybe_unused]] const AZ::EntityId& sequenceEntityId = sequence->GetSequenceEntityId();
  807. AZ_Trace("CAnimNode::InitPostLoad", "IAnimSequence is %s", sequenceEntityId.ToString().c_str());
  808. m_pSequence = sequence;
  809. m_pParentNode = ((CAnimSequence*)m_pSequence)->FindNodeById(m_parentNodeId);
  810. // fix up animNode pointers and time ranges on tracks, then sort them
  811. for (unsigned int i = 0; i < m_tracks.size(); i++)
  812. {
  813. RegisterTrack(m_tracks[i].get());
  814. m_tracks[i].get()->InitPostLoad(sequence);
  815. }
  816. SortTracks();
  817. }
  818. //////////////////////////////////////////////////////////////////////////
  819. void CAnimNode::SetNodeOwner(IAnimNodeOwner* pOwner)
  820. {
  821. m_pOwner = pOwner;
  822. if (pOwner)
  823. {
  824. pOwner->OnNodeAnimated(this);
  825. }
  826. }
  827. //////////////////////////////////////////////////////////////////////////
  828. void CAnimNode::PostLoad()
  829. {
  830. if (m_nLoadedParentNodeId)
  831. {
  832. IAnimNode* pParentNode = ((CAnimSequence*)m_pSequence)->FindNodeById(m_nLoadedParentNodeId);
  833. m_pParentNode = pParentNode;
  834. m_parentNodeId = m_nLoadedParentNodeId; // adding as a temporary fix while we support both serialization methods
  835. m_nLoadedParentNodeId = 0;
  836. }
  837. }
  838. //////////////////////////////////////////////////////////////////////////
  839. Matrix34 CAnimNode::GetReferenceMatrix() const
  840. {
  841. static Matrix34 tm(IDENTITY);
  842. return tm;
  843. }
  844. IAnimTrack* CAnimNode::CreateTrackInternalFloat([[maybe_unused]] int trackType) const
  845. {
  846. return aznew C2DSplineTrack;
  847. }
  848. IAnimTrack* CAnimNode::CreateTrackInternalVector([[maybe_unused]] EAnimCurveType trackType, const CAnimParamType& paramType, const AnimValueType animValue) const
  849. {
  850. CAnimParamType subTrackParamTypes[MAX_SUBTRACKS];
  851. for (unsigned int i = 0; i < MAX_SUBTRACKS; ++i)
  852. {
  853. subTrackParamTypes[i] = AnimParamType::Float;
  854. }
  855. if (paramType == AnimParamType::Position)
  856. {
  857. subTrackParamTypes[0] = AnimParamType::PositionX;
  858. subTrackParamTypes[1] = AnimParamType::PositionY;
  859. subTrackParamTypes[2] = AnimParamType::PositionZ;
  860. }
  861. else if (paramType == AnimParamType::Scale)
  862. {
  863. subTrackParamTypes[0] = AnimParamType::ScaleX;
  864. subTrackParamTypes[1] = AnimParamType::ScaleY;
  865. subTrackParamTypes[2] = AnimParamType::ScaleZ;
  866. }
  867. else if (paramType == AnimParamType::Rotation)
  868. {
  869. subTrackParamTypes[0] = AnimParamType::RotationX;
  870. subTrackParamTypes[1] = AnimParamType::RotationY;
  871. subTrackParamTypes[2] = AnimParamType::RotationZ;
  872. IAnimTrack* pTrack = aznew CCompoundSplineTrack(3, AnimValueType::Quat, subTrackParamTypes, false);
  873. return pTrack;
  874. }
  875. else if (paramType == AnimParamType::DepthOfField)
  876. {
  877. subTrackParamTypes[0] = AnimParamType::FocusDistance;
  878. subTrackParamTypes[1] = AnimParamType::FocusRange;
  879. subTrackParamTypes[2] = AnimParamType::BlurAmount;
  880. IAnimTrack* pTrack = aznew CCompoundSplineTrack(3, AnimValueType::Vector, subTrackParamTypes, false);
  881. pTrack->SetSubTrackName(0, "FocusDist");
  882. pTrack->SetSubTrackName(1, "FocusRange");
  883. pTrack->SetSubTrackName(2, "BlurAmount");
  884. return pTrack;
  885. }
  886. else if (animValue == AnimValueType::RGB || paramType == AnimParamType::LightDiffuse ||
  887. paramType == AnimParamType::MaterialDiffuse || paramType == AnimParamType::MaterialSpecular
  888. || paramType == AnimParamType::MaterialEmissive)
  889. {
  890. subTrackParamTypes[0] = AnimParamType::ColorR;
  891. subTrackParamTypes[1] = AnimParamType::ColorG;
  892. subTrackParamTypes[2] = AnimParamType::ColorB;
  893. IAnimTrack* pTrack = aznew CCompoundSplineTrack(3, AnimValueType::RGB, subTrackParamTypes, false);
  894. pTrack->SetSubTrackName(0, "Red");
  895. pTrack->SetSubTrackName(1, "Green");
  896. pTrack->SetSubTrackName(2, "Blue");
  897. return pTrack;
  898. }
  899. return aznew CCompoundSplineTrack(3, AnimValueType::Vector, subTrackParamTypes, false);
  900. }
  901. IAnimTrack* CAnimNode::CreateTrackInternalQuat([[maybe_unused]] EAnimCurveType trackType, const CAnimParamType& paramType) const
  902. {
  903. CAnimParamType subTrackParamTypes[MAX_SUBTRACKS];
  904. if (paramType == AnimParamType::Rotation)
  905. {
  906. subTrackParamTypes[0] = AnimParamType::RotationX;
  907. subTrackParamTypes[1] = AnimParamType::RotationY;
  908. subTrackParamTypes[2] = AnimParamType::RotationZ;
  909. }
  910. else
  911. {
  912. // Unknown param type
  913. assert(0);
  914. }
  915. return aznew CCompoundSplineTrack(3, AnimValueType::Quat, subTrackParamTypes, false);
  916. }
  917. IAnimTrack* CAnimNode::CreateTrackInternalVector4(const CAnimParamType& paramType) const
  918. {
  919. IAnimTrack* pTrack;
  920. CAnimParamType subTrackParamTypes[MAX_SUBTRACKS];
  921. // set up track subtypes
  922. if (paramType == AnimParamType::TransformNoise
  923. || paramType == AnimParamType::ShakeMultiplier)
  924. {
  925. subTrackParamTypes[0] = AnimParamType::ShakeAmpAMult;
  926. subTrackParamTypes[1] = AnimParamType::ShakeAmpBMult;
  927. subTrackParamTypes[2] = AnimParamType::ShakeFreqAMult;
  928. subTrackParamTypes[3] = AnimParamType::ShakeFreqBMult;
  929. }
  930. else
  931. {
  932. // default to a Vector4 of floats
  933. for (unsigned int i = 0; i < MAX_SUBTRACKS; ++i)
  934. {
  935. subTrackParamTypes[i] = AnimParamType::Float;
  936. }
  937. }
  938. // create track
  939. pTrack = aznew CCompoundSplineTrack(4, AnimValueType::Vector4, subTrackParamTypes, true);
  940. // label subtypes
  941. if (paramType == AnimParamType::TransformNoise)
  942. {
  943. pTrack->SetSubTrackName(0, "Pos Noise Amp");
  944. pTrack->SetSubTrackName(1, "Pos Noise Freq");
  945. pTrack->SetSubTrackName(2, "Rot Noise Amp");
  946. pTrack->SetSubTrackName(3, "Rot Noise Freq");
  947. }
  948. else if (paramType == AnimParamType::ShakeMultiplier)
  949. {
  950. pTrack->SetSubTrackName(0, "Amplitude A");
  951. pTrack->SetSubTrackName(1, "Amplitude B");
  952. pTrack->SetSubTrackName(2, "Frequency A");
  953. pTrack->SetSubTrackName(3, "Frequency B");
  954. }
  955. return pTrack;
  956. }
  957. void CAnimNode::TimeChanged(float newTime)
  958. {
  959. // if the newTime is on a sound key, then reset sounds so sound will playback on next call to Animate()
  960. if (IsTimeOnSoundKey(newTime))
  961. {
  962. ResetSounds();
  963. }
  964. }
  965. bool CAnimNode::IsTimeOnSoundKey(float queryTime) const
  966. {
  967. bool retIsTimeOnSoundKey = false;
  968. const float tolerance = 0.0333f; // one frame at 30 fps
  969. int trackCount = NumTracks();
  970. for (int trackIndex = 0; trackIndex < trackCount; trackIndex++)
  971. {
  972. CAnimParamType paramType = m_tracks[trackIndex]->GetParameterType();
  973. IAnimTrack* pTrack = m_tracks[trackIndex].get();
  974. if ((paramType.GetType() != AnimParamType::Sound)
  975. || (pTrack->HasKeys() == false && pTrack->GetParameterType() != AnimParamType::Visibility)
  976. || (pTrack->GetFlags() & IAnimTrack::eAnimTrackFlags_Disabled))
  977. {
  978. continue;
  979. }
  980. // if we're here, pTrack points to a AnimParamType::Sound track
  981. ISoundKey oSoundKey;
  982. int const nSoundKey = static_cast<CSoundTrack*>(pTrack)->GetActiveKey(queryTime, &oSoundKey);
  983. if (nSoundKey >= 0)
  984. {
  985. retIsTimeOnSoundKey = AZ::IsClose(queryTime, oSoundKey.time, tolerance);
  986. if (retIsTimeOnSoundKey)
  987. {
  988. break; // no need to search further, we have a hit
  989. }
  990. }
  991. }
  992. return retIsTimeOnSoundKey;
  993. }
  994. //////////////////////////////////////////////////////////////////////////
  995. void CAnimNode::AnimateSound(std::vector<SSoundInfo>& nodeSoundInfo, SAnimContext& ec, IAnimTrack* pTrack, size_t numAudioTracks)
  996. {
  997. bool const bMute = gEnv->IsEditor() && (pTrack->GetFlags() & IAnimTrack::eAnimTrackFlags_Muted);
  998. if (!bMute && ec.time >= 0.0f)
  999. {
  1000. ISoundKey oSoundKey;
  1001. int const nSoundKey = static_cast<CSoundTrack*>(pTrack)->GetActiveKey(ec.time, &oSoundKey);
  1002. SSoundInfo& rSoundInfo = nodeSoundInfo[numAudioTracks - 1];
  1003. if (nSoundKey >= 0)
  1004. {
  1005. float const fSoundKeyTime = (ec.time - oSoundKey.time);
  1006. if (rSoundInfo.nSoundKeyStart < nSoundKey && fSoundKeyTime < oSoundKey.fDuration)
  1007. {
  1008. ApplyAudioKey(oSoundKey.sStartTrigger.c_str());
  1009. }
  1010. if (rSoundInfo.nSoundKeyStart > nSoundKey)
  1011. {
  1012. rSoundInfo.nSoundKeyStop = nSoundKey;
  1013. }
  1014. rSoundInfo.nSoundKeyStart = nSoundKey;
  1015. if (fSoundKeyTime >= oSoundKey.fDuration)
  1016. {
  1017. if (rSoundInfo.nSoundKeyStop < nSoundKey)
  1018. {
  1019. rSoundInfo.nSoundKeyStop = nSoundKey;
  1020. if (oSoundKey.sStopTrigger.empty())
  1021. {
  1022. ApplyAudioKey(oSoundKey.sStartTrigger.c_str(), false);
  1023. }
  1024. else
  1025. {
  1026. ApplyAudioKey(oSoundKey.sStopTrigger.c_str());
  1027. }
  1028. }
  1029. }
  1030. else
  1031. {
  1032. rSoundInfo.nSoundKeyStop = -1;
  1033. }
  1034. }
  1035. else
  1036. {
  1037. rSoundInfo.Reset();
  1038. }
  1039. }
  1040. }
  1041. void CAnimNode::SetParent(IAnimNode* parent)
  1042. {
  1043. m_pParentNode = parent;
  1044. if (parent)
  1045. {
  1046. m_parentNodeId = static_cast<CAnimNode*>(m_pParentNode)->GetId();
  1047. }
  1048. else
  1049. {
  1050. m_parentNodeId = 0;
  1051. }
  1052. }
  1053. //////////////////////////////////////////////////////////////////////////
  1054. IAnimNode* CAnimNode::HasDirectorAsParent() const
  1055. {
  1056. IAnimNode* pParent = GetParent();
  1057. while (pParent)
  1058. {
  1059. if (pParent->GetType() == AnimNodeType::Director)
  1060. {
  1061. return pParent;
  1062. }
  1063. // There are some invalid data.
  1064. if (pParent->GetParent() == pParent)
  1065. {
  1066. pParent->SetParent(NULL);
  1067. return NULL;
  1068. }
  1069. pParent = pParent->GetParent();
  1070. }
  1071. return NULL;
  1072. }
  1073. void CAnimNode::UpdateDynamicParams()
  1074. {
  1075. if (gEnv->IsEditor())
  1076. {
  1077. // UpdateDynamicParams is called as the result of an editor event that is fired when a material is loaded,
  1078. // which could happen from multiple threads. Lock to avoid a crash iterating over the lua stack
  1079. AZStd::lock_guard<AZStd::mutex> lock(m_updateDynamicParamsLock);
  1080. // run this on the main thread to prevent further threading issues downstream in
  1081. // AnimNodes that may use EBuses that are not thread safe
  1082. if (gEnv && gEnv->mMainThreadId == CryGetCurrentThreadId())
  1083. {
  1084. UpdateDynamicParamsInternal();
  1085. }
  1086. else
  1087. {
  1088. AZ::TickBus::QueueFunction([this] {
  1089. UpdateDynamicParamsInternal();
  1090. });
  1091. }
  1092. }
  1093. else
  1094. {
  1095. UpdateDynamicParamsInternal();
  1096. }
  1097. }
  1098. //////////////////////////////////////////////////////////////////////////
  1099. void CAnimNode::SetExpanded(bool expanded)
  1100. {
  1101. m_expanded = expanded;
  1102. }
  1103. //////////////////////////////////////////////////////////////////////////
  1104. bool CAnimNode::GetExpanded() const
  1105. {
  1106. return m_expanded;
  1107. }
  1108. IMovieSystem* CAnimNode::GetMovieSystem() const
  1109. {
  1110. return AZ::Interface<IMovieSystem>::Get();
  1111. };