TrackViewPythonFuncs.cpp 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720
  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 "EditorDefs.h"
  9. #include "TrackViewPythonFuncs.h"
  10. // CryCommon
  11. #include <CryCommon/Maestro/Types/AnimNodeType.h>
  12. #include <CryCommon/Maestro/Types/AnimParamType.h>
  13. #include <CryCommon/Maestro/Types/AnimValueType.h>
  14. // Editor
  15. #include "AnimationContext.h"
  16. #include <AzCore/Asset/AssetSerializer.h>
  17. #include <AzCore/std/containers/set.h>
  18. #include <AzCore/std/iterator.h>
  19. namespace
  20. {
  21. CTrackViewSequence* GetSequenceByEntityIdOrName(const CTrackViewSequenceManager* pSequenceManager, const char* entityIdOrName)
  22. {
  23. // the "name" string will be an AZ::EntityId in string form if this was called from
  24. // TrackView code. But for backward compatibility we also support a sequence name.
  25. bool isNameAValidU64 = false;
  26. QString entityIdString = entityIdOrName;
  27. AZ::u64 nameAsU64 = entityIdString.toULongLong(&isNameAValidU64);
  28. CTrackViewSequence* pSequence = nullptr;
  29. if (isNameAValidU64)
  30. {
  31. // "name" string was a valid u64 represented as a string. Use as an entity Id to search for sequence.
  32. pSequence = pSequenceManager->GetSequenceByEntityId(AZ::EntityId(nameAsU64));
  33. }
  34. if (!pSequence)
  35. {
  36. // name passed in could not find a sequence by using it as an EntityId. Use it as a
  37. // sequence name for backward compatibility
  38. pSequence = pSequenceManager->GetSequenceByName(entityIdOrName);
  39. }
  40. return pSequence;
  41. }
  42. }
  43. namespace
  44. {
  45. // Misc
  46. void PyTrackViewSetRecording(bool bRecording)
  47. {
  48. CAnimationContext* pAnimationContext = GetIEditor()->GetAnimation();
  49. if (pAnimationContext)
  50. {
  51. pAnimationContext->SetRecording(bRecording);
  52. }
  53. }
  54. // Sequences
  55. void PyTrackViewNewSequence(const char* name, int sequenceType)
  56. {
  57. CTrackViewSequenceManager* pSequenceManager = GetIEditor()->GetSequenceManager();
  58. CTrackViewSequence* pSequence = pSequenceManager->GetSequenceByName(name);
  59. if (pSequence)
  60. {
  61. throw std::runtime_error("A sequence with this name already exists");
  62. }
  63. CUndo undo("Create TrackView sequence");
  64. pSequenceManager->CreateSequence(name, static_cast<SequenceType>(sequenceType));
  65. }
  66. void PyTrackViewDeleteSequence(const char* name)
  67. {
  68. CTrackViewSequenceManager* pSequenceManager = GetIEditor()->GetSequenceManager();
  69. CTrackViewSequence* pSequence = GetSequenceByEntityIdOrName(pSequenceManager, name);
  70. if (pSequence)
  71. {
  72. pSequenceManager->DeleteSequence(pSequence);
  73. return;
  74. }
  75. throw std::runtime_error("Could not find sequence");
  76. }
  77. void PyTrackViewSetCurrentSequence(const char* name)
  78. {
  79. const CTrackViewSequenceManager* sequenceManager = GetIEditor()->GetSequenceManager();
  80. CTrackViewSequence* sequence = GetSequenceByEntityIdOrName(sequenceManager, name);
  81. CAnimationContext* animationContext = GetIEditor()->GetAnimation();
  82. bool force = false;
  83. bool noNotify = false;
  84. bool user = true;
  85. animationContext->SetSequence(sequence, force, noNotify, user);
  86. }
  87. int PyTrackViewGetNumSequences()
  88. {
  89. const CTrackViewSequenceManager* pSequenceManager = GetIEditor()->GetSequenceManager();
  90. AZ_TracePrintf("", "PyTrackViewGetNumSequences called")
  91. return pSequenceManager->GetCount();
  92. }
  93. AZStd::string PyTrackViewGetSequenceName(unsigned int index)
  94. {
  95. if (static_cast<int>(index) < PyTrackViewGetNumSequences())
  96. {
  97. const CTrackViewSequenceManager* pSequenceManager = GetIEditor()->GetSequenceManager();
  98. return pSequenceManager->GetSequenceByIndex(index)->GetName();
  99. }
  100. throw std::runtime_error("Could not find sequence");
  101. }
  102. Range PyTrackViewGetSequenceTimeRange(const char* name)
  103. {
  104. const CTrackViewSequenceManager* pSequenceManager = GetIEditor()->GetSequenceManager();
  105. CTrackViewSequence* pSequence = GetSequenceByEntityIdOrName(pSequenceManager, name);
  106. if (!pSequence)
  107. {
  108. throw std::runtime_error("A sequence with this name doesn't exists");
  109. }
  110. return pSequence->GetTimeRange();
  111. }
  112. void PyTrackViewSetSequenceTimeRange(const char* name, float start, float end)
  113. {
  114. const CTrackViewSequenceManager* pSequenceManager = GetIEditor()->GetSequenceManager();
  115. CTrackViewSequence* pSequence = GetSequenceByEntityIdOrName(pSequenceManager, name);
  116. if (!pSequence)
  117. {
  118. throw std::runtime_error("A sequence with this name doesn't exists");
  119. }
  120. CUndo undo("Set sequence time range");
  121. pSequence->SetTimeRange(Range(start, end));
  122. pSequence->MarkAsModified();
  123. }
  124. void PyTrackViewPlaySequence()
  125. {
  126. CAnimationContext* pAnimationContext = GetIEditor()->GetAnimation();
  127. if (pAnimationContext->IsPlaying())
  128. {
  129. throw std::runtime_error("A sequence is already playing");
  130. }
  131. pAnimationContext->SetPlaying(true);
  132. }
  133. void PyTrackViewStopSequence()
  134. {
  135. CAnimationContext* pAnimationContext = GetIEditor()->GetAnimation();
  136. if (!pAnimationContext->IsPlaying())
  137. {
  138. throw std::runtime_error("No sequence is playing");
  139. }
  140. pAnimationContext->SetPlaying(false);
  141. }
  142. void PyTrackViewSetSequenceTime(float time)
  143. {
  144. CAnimationContext* pAnimationContext = GetIEditor()->GetAnimation();
  145. pAnimationContext->SetTime(time);
  146. }
  147. // Nodes
  148. void PyTrackViewAddNode(const char* nodeTypeString, const char* nodeName)
  149. {
  150. CTrackViewSequence* pSequence = GetIEditor()->GetAnimation()->GetSequence();
  151. if (!pSequence)
  152. {
  153. throw std::runtime_error("No sequence is active");
  154. }
  155. IMovieSystem* movieSystem = AZ::Interface<IMovieSystem>::Get();
  156. if (movieSystem)
  157. {
  158. const AnimNodeType nodeType = movieSystem->GetNodeTypeFromString(nodeTypeString);
  159. if (nodeType == AnimNodeType::Invalid)
  160. {
  161. throw std::runtime_error("Invalid node type");
  162. }
  163. CUndo undo("Create anim node");
  164. pSequence->CreateSubNode(nodeName, nodeType);
  165. }
  166. }
  167. void PyTrackViewAddSelectedEntities()
  168. {
  169. CAnimationContext* animationContext = GetIEditor()->GetAnimation();
  170. CTrackViewSequence* sequence = animationContext->GetSequence();
  171. if (!sequence)
  172. {
  173. throw std::runtime_error("No sequence is active");
  174. }
  175. AZStd::vector<AnimParamType> tracks = {
  176. AnimParamType::Position,
  177. AnimParamType::Rotation
  178. };
  179. AzToolsFramework::ScopedUndoBatch undoBatch("Add entities to Track View");
  180. sequence->AddSelectedEntities(tracks);
  181. sequence->BindToEditorObjects();
  182. undoBatch.MarkEntityDirty(sequence->GetSequenceComponentEntityId());
  183. }
  184. void PyTrackViewAddLayerNode()
  185. {
  186. CAnimationContext* pAnimationContext = GetIEditor()->GetAnimation();
  187. CTrackViewSequence* pSequence = pAnimationContext->GetSequence();
  188. if (!pSequence)
  189. {
  190. throw std::runtime_error("No sequence is active");
  191. }
  192. CUndo undo("Add current layer to TrackView");
  193. pSequence->AddCurrentLayer();
  194. }
  195. CTrackViewAnimNode* GetNodeFromName(const char* nodeName, const char* parentDirectorName)
  196. {
  197. CAnimationContext* pAnimationContext = GetIEditor()->GetAnimation();
  198. CTrackViewSequence* pSequence = pAnimationContext->GetSequence();
  199. if (!pSequence)
  200. {
  201. throw std::runtime_error("No sequence is active");
  202. }
  203. CTrackViewAnimNode* pParentDirector = pSequence;
  204. if (strlen(parentDirectorName) > 0)
  205. {
  206. CTrackViewAnimNodeBundle foundNodes = pSequence->GetAnimNodesByName(parentDirectorName);
  207. if (foundNodes.GetCount() == 0 || foundNodes.GetNode(0)->GetType() != AnimNodeType::Director)
  208. {
  209. throw std::runtime_error("Director node not found");
  210. }
  211. pParentDirector = foundNodes.GetNode(0);
  212. }
  213. CTrackViewAnimNodeBundle foundNodes = pParentDirector->GetAnimNodesByName(nodeName);
  214. return (foundNodes.GetCount() > 0) ? foundNodes.GetNode(0) : nullptr;
  215. }
  216. void PyTrackViewDeleteNode(AZStd::string_view nodeName, AZStd::string_view parentDirectorName)
  217. {
  218. CTrackViewAnimNode* pNode = GetNodeFromName(nodeName.data(), parentDirectorName.data());
  219. if (pNode == nullptr)
  220. {
  221. throw std::runtime_error("Couldn't find node");
  222. }
  223. CTrackViewAnimNode* pParentNode = static_cast<CTrackViewAnimNode*>(pNode->GetParentNode());
  224. CUndo undo("Delete TrackView Node");
  225. pParentNode->RemoveSubNode(pNode);
  226. }
  227. void PyTrackViewAddTrack(const char* paramName, const char* nodeName, const char* parentDirectorName)
  228. {
  229. CTrackViewAnimNode* pNode = GetNodeFromName(nodeName, parentDirectorName);
  230. if (!pNode)
  231. {
  232. throw std::runtime_error("Couldn't find node");
  233. }
  234. // Add tracks to menu, that can be added to animation node.
  235. const int paramCount = pNode->GetParamCount();
  236. for (int i = 0; i < paramCount; ++i)
  237. {
  238. CAnimParamType paramType = pNode->GetParamType(i);
  239. if (paramType == AnimParamType::Invalid)
  240. {
  241. continue;
  242. }
  243. IAnimNode::ESupportedParamFlags paramFlags = pNode->GetParamFlags(paramType);
  244. CTrackViewTrack* pTrack = pNode->GetTrackForParameter(paramType);
  245. if (!pTrack || (paramFlags & IAnimNode::eSupportedParamFlags_MultipleTracks))
  246. {
  247. AZStd::string name = pNode->GetParamName(paramType);
  248. if (name == paramName)
  249. {
  250. CUndo undo("Create track");
  251. if (!pNode->CreateTrack(paramType))
  252. {
  253. undo.Cancel();
  254. throw std::runtime_error("Could not create track");
  255. }
  256. pNode->SetSelected(true);
  257. return;
  258. }
  259. }
  260. }
  261. throw std::runtime_error("Could not create track");
  262. }
  263. void PyTrackViewDeleteTrack(const char* paramName, uint32 index, const char* nodeName, const char* parentDirectorName)
  264. {
  265. CTrackViewAnimNode* pNode = GetNodeFromName(nodeName, parentDirectorName);
  266. if (!pNode)
  267. {
  268. throw std::runtime_error("Couldn't find node");
  269. }
  270. IMovieSystem* movieSystem = AZ::Interface<IMovieSystem>::Get();
  271. if (movieSystem)
  272. {
  273. const CAnimParamType paramType = movieSystem->GetParamTypeFromString(paramName);
  274. CTrackViewTrack* pTrack = pNode->GetTrackForParameter(paramType, index);
  275. if (!pTrack)
  276. {
  277. throw std::runtime_error("Could not find track");
  278. }
  279. CUndo undo("Delete TrackView track");
  280. pNode->RemoveTrack(pTrack);
  281. }
  282. }
  283. int PyTrackViewGetNumNodes(AZStd::string_view parentDirectorName)
  284. {
  285. CAnimationContext* pAnimationContext = GetIEditor()->GetAnimation();
  286. CTrackViewSequence* pSequence = pAnimationContext->GetSequence();
  287. if (!pSequence)
  288. {
  289. throw std::runtime_error("No sequence is active");
  290. }
  291. CTrackViewAnimNode* pParentDirector = pSequence;
  292. if (!parentDirectorName.empty())
  293. {
  294. CTrackViewAnimNodeBundle foundNodes = pSequence->GetAnimNodesByName(parentDirectorName.data());
  295. if (foundNodes.GetCount() == 0 || foundNodes.GetNode(0)->GetType() != AnimNodeType::Director)
  296. {
  297. throw std::runtime_error("Director node not found");
  298. }
  299. pParentDirector = foundNodes.GetNode(0);
  300. }
  301. CTrackViewAnimNodeBundle foundNodes = pParentDirector->GetAllAnimNodes();
  302. return foundNodes.GetCount();
  303. }
  304. AZStd::string PyTrackViewGetNodeName(int index, AZStd::string_view parentDirectorName)
  305. {
  306. CAnimationContext* pAnimationContext = GetIEditor()->GetAnimation();
  307. CTrackViewSequence* pSequence = pAnimationContext->GetSequence();
  308. if (!pSequence)
  309. {
  310. throw std::runtime_error("No sequence is active");
  311. }
  312. CTrackViewAnimNode* pParentDirector = pSequence;
  313. if (!parentDirectorName.empty())
  314. {
  315. CTrackViewAnimNodeBundle foundNodes = pSequence->GetAnimNodesByName(parentDirectorName.data());
  316. if (foundNodes.GetCount() == 0 || foundNodes.GetNode(0)->GetType() != AnimNodeType::Director)
  317. {
  318. throw std::runtime_error("Director node not found");
  319. }
  320. pParentDirector = foundNodes.GetNode(0);
  321. }
  322. CTrackViewAnimNodeBundle foundNodes = pParentDirector->GetAllAnimNodes();
  323. if (index < 0 || index >= static_cast<int>(foundNodes.GetCount()))
  324. {
  325. throw std::runtime_error("Invalid node index");
  326. }
  327. return foundNodes.GetNode(index)->GetName();
  328. }
  329. // Tracks
  330. CTrackViewTrack* GetTrack(const char* paramName, uint32 index, const char* nodeName, const char* parentDirectorName)
  331. {
  332. CTrackViewAnimNode* pNode = GetNodeFromName(nodeName, parentDirectorName);
  333. if (!pNode)
  334. {
  335. throw std::runtime_error("Couldn't find node");
  336. }
  337. IMovieSystem* movieSystem = AZ::Interface<IMovieSystem>::Get();
  338. if (movieSystem)
  339. {
  340. const CAnimParamType paramType = movieSystem->GetParamTypeFromString(paramName);
  341. CTrackViewTrack* pTrack = pNode->GetTrackForParameter(paramType, index);
  342. if (!pTrack)
  343. {
  344. throw std::runtime_error("Track doesn't exist");
  345. }
  346. return pTrack;
  347. }
  348. else
  349. {
  350. throw std::runtime_error("MovieSystem does not exist");
  351. }
  352. }
  353. AZStd::set<float> GetKeyTimeSet(CTrackViewTrack* pTrack)
  354. {
  355. AZStd::set<float> keyTimeSet;
  356. for (uint i = 0; i < pTrack->GetKeyCount(); ++i)
  357. {
  358. CTrackViewKeyHandle keyHandle = pTrack->GetKey(i);
  359. keyTimeSet.insert(keyHandle.GetTime());
  360. }
  361. return keyTimeSet;
  362. }
  363. int PyTrackViewGetNumTrackKeys(const char* paramName, int trackIndex, const char* nodeName, const char* parentDirectorName)
  364. {
  365. CTrackViewTrack* pTrack = GetTrack(paramName, trackIndex, nodeName, parentDirectorName);
  366. return (int)GetKeyTimeSet(pTrack).size();
  367. }
  368. AZStd::any PyTrackViewGetInterpolatedValue(const char* paramName, int trackIndex, float time, const char* nodeName, const char* parentDirectorName)
  369. {
  370. CTrackViewTrack* pTrack = GetTrack(paramName, trackIndex, nodeName, parentDirectorName);
  371. switch (pTrack->GetValueType())
  372. {
  373. case AnimValueType::Float:
  374. case AnimValueType::DiscreteFloat:
  375. {
  376. float value;
  377. pTrack->GetValue(time, value);
  378. return AZStd::make_any<float>(value);
  379. }
  380. break;
  381. case AnimValueType::Bool:
  382. {
  383. bool value;
  384. pTrack->GetValue(time, value);
  385. return AZStd::make_any<bool>(value);
  386. }
  387. break;
  388. case AnimValueType::Quat:
  389. {
  390. AZ::Quaternion value;
  391. pTrack->GetValue(time, value);
  392. const AZ::Vector3 rotation = value.GetEulerDegrees();
  393. return AZStd::make_any<AZ::Vector3>(rotation);
  394. }
  395. case AnimValueType::Vector:
  396. {
  397. AZ::Vector3 value;
  398. pTrack->GetValue(time, value);
  399. return AZStd::make_any<AZ::Vector3>(value);
  400. }
  401. break;
  402. case AnimValueType::Vector4:
  403. {
  404. AZ::Vector4 value;
  405. pTrack->GetValue(time, value);
  406. return AZStd::make_any<AZ::Vector4>(value);
  407. }
  408. break;
  409. case AnimValueType::RGB:
  410. {
  411. AZ::Vector3 value;
  412. pTrack->GetValue(time, value);
  413. return AZStd::make_any<AZ::Color>(value.GetX(), value.GetY(), value.GetZ(), 0.0f);
  414. }
  415. break;
  416. default:
  417. throw std::runtime_error("Unsupported key type");
  418. }
  419. }
  420. AZStd::any PyTrackViewGetKeyValue(const char* paramName, int trackIndex, int keyIndex, const char* nodeName, const char* parentDirectorName)
  421. {
  422. CTrackViewTrack* pTrack = GetTrack(paramName, trackIndex, nodeName, parentDirectorName);
  423. AZStd::set<float> keyTimeSet = GetKeyTimeSet(pTrack);
  424. if (keyIndex < 0 || keyIndex >= keyTimeSet.size())
  425. {
  426. throw std::runtime_error("Invalid key index");
  427. }
  428. auto keyTimeIter = keyTimeSet.begin();
  429. AZStd::advance(keyTimeIter, keyIndex);
  430. const float keyTime = *keyTimeIter;
  431. return PyTrackViewGetInterpolatedValue(paramName, trackIndex, keyTime, nodeName, parentDirectorName);
  432. }
  433. }
  434. namespace AzToolsFramework
  435. {
  436. void TrackViewComponent::Reflect(AZ::ReflectContext* context)
  437. {
  438. if (AZ::BehaviorContext* behaviorContext = azrtti_cast<AZ::BehaviorContext*>(context))
  439. {
  440. behaviorContext->EBus<EditorLayerTrackViewRequestBus>("EditorLayerTrackViewRequestBus")
  441. ->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Automation)
  442. ->Attribute(AZ::Script::Attributes::Module, "track_view")
  443. ->Event("AddNode", &EditorLayerTrackViewRequestBus::Events::AddNode)
  444. ->Event("AddTrack", &EditorLayerTrackViewRequestBus::Events::AddTrack)
  445. ->Event("AddLayerNode", &EditorLayerTrackViewRequestBus::Events::AddLayerNode)
  446. ->Event("AddSelectedEntities", &EditorLayerTrackViewRequestBus::Events::AddSelectedEntities)
  447. ->Event("DeleteNode", &EditorLayerTrackViewRequestBus::Events::DeleteNode)
  448. ->Event("DeleteTrack", &EditorLayerTrackViewRequestBus::Events::DeleteTrack)
  449. ->Event("DeleteSequence", &EditorLayerTrackViewRequestBus::Events::DeleteSequence)
  450. ->Event("GetInterpolatedValue", &EditorLayerTrackViewRequestBus::Events::GetInterpolatedValue)
  451. ->Event("GetKeyValue", &EditorLayerTrackViewRequestBus::Events::GetKeyValue)
  452. ->Event("GetNodeName", &EditorLayerTrackViewRequestBus::Events::GetNodeName)
  453. ->Event("GetNumNodes", &EditorLayerTrackViewRequestBus::Events::GetNumNodes)
  454. ->Event("GetNumSequences", &EditorLayerTrackViewRequestBus::Events::GetNumSequences)
  455. ->Event("GetNumTrackKeys", &EditorLayerTrackViewRequestBus::Events::GetNumTrackKeys)
  456. ->Event("GetSequenceName", &EditorLayerTrackViewRequestBus::Events::GetSequenceName)
  457. ->Event("GetSequenceTimeRange", &EditorLayerTrackViewRequestBus::Events::GetSequenceTimeRange)
  458. ->Event("NewSequence", &EditorLayerTrackViewRequestBus::Events::NewSequence)
  459. ->Event("PlaySequence", &EditorLayerTrackViewRequestBus::Events::PlaySequence)
  460. ->Event("SetCurrentSequence", &EditorLayerTrackViewRequestBus::Events::SetCurrentSequence)
  461. ->Event("SetRecording", &EditorLayerTrackViewRequestBus::Events::SetRecording)
  462. ->Event("SetSequenceTimeRange", &EditorLayerTrackViewRequestBus::Events::SetSequenceTimeRange)
  463. ->Event("SetTime", &EditorLayerTrackViewRequestBus::Events::SetSequenceTime)
  464. ->Event("StopSequence", &EditorLayerTrackViewRequestBus::Events::StopSequence)
  465. ;
  466. }
  467. }
  468. void TrackViewComponent::Activate()
  469. {
  470. EditorLayerTrackViewRequestBus::Handler::BusConnect(GetEntityId());
  471. }
  472. void TrackViewComponent::Deactivate()
  473. {
  474. EditorLayerTrackViewRequestBus::Handler::BusDisconnect();
  475. }
  476. int TrackViewComponent::GetNumSequences()
  477. {
  478. return PyTrackViewGetNumSequences();
  479. }
  480. void TrackViewComponent::NewSequence(const char* name, int sequenceType)
  481. {
  482. return PyTrackViewNewSequence(name, sequenceType);
  483. }
  484. void TrackViewComponent::PlaySequence()
  485. {
  486. return PyTrackViewPlaySequence();
  487. }
  488. void TrackViewComponent::StopSequence()
  489. {
  490. return PyTrackViewStopSequence();
  491. }
  492. void TrackViewComponent::SetSequenceTime(float time)
  493. {
  494. return PyTrackViewSetSequenceTime(time);
  495. }
  496. void TrackViewComponent::AddSelectedEntities()
  497. {
  498. return PyTrackViewAddSelectedEntities();
  499. }
  500. void TrackViewComponent::AddLayerNode()
  501. {
  502. return PyTrackViewAddLayerNode();
  503. }
  504. void TrackViewComponent::AddTrack(const char* paramName, const char* nodeName, const char* parentDirectorName)
  505. {
  506. return PyTrackViewAddTrack(paramName, nodeName, parentDirectorName);
  507. }
  508. void TrackViewComponent::DeleteTrack(const char* paramName, uint32 index, const char* nodeName, const char* parentDirectorName)
  509. {
  510. return PyTrackViewDeleteTrack(paramName, index, nodeName, parentDirectorName);
  511. }
  512. int TrackViewComponent::GetNumTrackKeys(const char* paramName, int trackIndex, const char* nodeName, const char* parentDirectorName)
  513. {
  514. return PyTrackViewGetNumTrackKeys(paramName, trackIndex, nodeName, parentDirectorName);
  515. }
  516. void TrackViewComponent::SetRecording(bool bRecording)
  517. {
  518. return PyTrackViewSetRecording(bRecording);
  519. }
  520. void TrackViewComponent::DeleteSequence(const char* name)
  521. {
  522. return PyTrackViewDeleteSequence(name);
  523. }
  524. void TrackViewComponent::SetCurrentSequence(const char* name)
  525. {
  526. return PyTrackViewSetCurrentSequence(name);
  527. }
  528. AZStd::string TrackViewComponent::GetSequenceName(unsigned int index)
  529. {
  530. return PyTrackViewGetSequenceName(index);
  531. }
  532. Range TrackViewComponent::GetSequenceTimeRange(const char* name)
  533. {
  534. return PyTrackViewGetSequenceTimeRange(name);
  535. }
  536. void TrackViewComponent::AddNode(const char* nodeTypeString, const char* nodeName)
  537. {
  538. return PyTrackViewAddNode(nodeTypeString, nodeName);
  539. }
  540. void TrackViewComponent::DeleteNode(AZStd::string_view nodeName, AZStd::string_view parentDirectorName)
  541. {
  542. return PyTrackViewDeleteNode(nodeName, parentDirectorName);
  543. }
  544. int TrackViewComponent::GetNumNodes(AZStd::string_view parentDirectorName)
  545. {
  546. return PyTrackViewGetNumNodes(parentDirectorName);
  547. }
  548. AZStd::string TrackViewComponent::GetNodeName(int index, AZStd::string_view parentDirectorName)
  549. {
  550. return PyTrackViewGetNodeName(index, parentDirectorName);
  551. }
  552. AZStd::any TrackViewComponent::GetKeyValue(const char* paramName, int trackIndex, int keyIndex, const char* nodeName, const char* parentDirectorName)
  553. {
  554. return PyTrackViewGetKeyValue(paramName, trackIndex, keyIndex, nodeName, parentDirectorName);
  555. }
  556. AZStd::any TrackViewComponent::GetInterpolatedValue(const char* paramName, int trackIndex, float time, const char* nodeName, const char* parentDirectorName)
  557. {
  558. return PyTrackViewGetInterpolatedValue(paramName, trackIndex, time, nodeName, parentDirectorName);
  559. }
  560. void TrackViewComponent::SetSequenceTimeRange(const char* name, float start, float end)
  561. {
  562. return PyTrackViewSetSequenceTimeRange(name, start, end);
  563. }
  564. }
  565. namespace AzToolsFramework
  566. {
  567. void TrackViewFuncsHandler::Reflect(AZ::ReflectContext* context)
  568. {
  569. if (auto behaviorContext = azrtti_cast<AZ::BehaviorContext*>(context))
  570. {
  571. behaviorContext->Class<Range>("CryRange")
  572. ->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Automation)
  573. ->Attribute(AZ::Script::Attributes::Module, "legacy.trackview")
  574. ->Property("start", BehaviorValueProperty(&Range::start))
  575. ->Property("end", BehaviorValueProperty(&Range::end))
  576. ;
  577. // this will put these methods into the 'azlmbr.legacy.trackview' module
  578. auto addLegacyTrackview = [](AZ::BehaviorContext::GlobalMethodBuilder methodBuilder)
  579. {
  580. methodBuilder->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Automation)
  581. ->Attribute(AZ::Script::Attributes::Category, "Legacy/TrackView")
  582. ->Attribute(AZ::Script::Attributes::Module, "legacy.trackview");
  583. };
  584. addLegacyTrackview(behaviorContext->Method("set_recording", PyTrackViewSetRecording, nullptr, "Activates/deactivates TrackView recording mode."));
  585. addLegacyTrackview(behaviorContext->Method("new_sequence", PyTrackViewNewSequence, nullptr, "Creates a new sequence of the given type (0=Object Entity Sequence (Legacy), 1=Component Entity Sequence) with the given name."));
  586. addLegacyTrackview(behaviorContext->Method("delete_sequence", PyTrackViewDeleteSequence, nullptr, "Deletes the specified sequence."));
  587. addLegacyTrackview(behaviorContext->Method("set_current_sequence", PyTrackViewSetCurrentSequence, nullptr, "Sets the specified sequence as a current one in TrackView."));
  588. addLegacyTrackview(behaviorContext->Method("get_num_sequences", PyTrackViewGetNumSequences, nullptr, "Gets the number of sequences."));
  589. addLegacyTrackview(behaviorContext->Method("get_sequence_name", PyTrackViewGetSequenceName, nullptr, "Gets the name of a sequence by its index."));
  590. addLegacyTrackview(behaviorContext->Method("get_sequence_time_range", PyTrackViewGetSequenceTimeRange, nullptr, "Gets the time range of a sequence as a pair."));
  591. addLegacyTrackview(behaviorContext->Method("set_sequence_time_range", PyTrackViewSetSequenceTimeRange, nullptr, "Sets the time range of a sequence."));
  592. addLegacyTrackview(behaviorContext->Method("play_sequence", PyTrackViewPlaySequence, nullptr, "Plays the current sequence in TrackView."));
  593. addLegacyTrackview(behaviorContext->Method("stop_sequence", PyTrackViewStopSequence, nullptr, "Stops any sequence currently playing in TrackView."));
  594. addLegacyTrackview(behaviorContext->Method("set_time", PyTrackViewSetSequenceTime, nullptr, "Sets the time of the sequence currently playing in TrackView."));
  595. addLegacyTrackview(behaviorContext->Method("add_node", PyTrackViewAddNode, nullptr, "Adds a new node with the given type & name to the current sequence."));
  596. addLegacyTrackview(behaviorContext->Method("add_selected_entities", PyTrackViewAddSelectedEntities, nullptr, "Adds an entity node(s) from viewport selection to the current sequence."));
  597. addLegacyTrackview(behaviorContext->Method("add_layer_node", PyTrackViewAddLayerNode, nullptr, "Adds a layer node from the current layer to the current sequence."));
  598. addLegacyTrackview(behaviorContext->Method("delete_node", PyTrackViewDeleteNode, nullptr, "Deletes the specified node from the current sequence."));
  599. addLegacyTrackview(behaviorContext->Method("add_track", PyTrackViewAddTrack, nullptr, "Adds a track of the given parameter ID to the node."));
  600. addLegacyTrackview(behaviorContext->Method("delete_track", PyTrackViewDeleteTrack, nullptr, "Deletes a track of the given parameter ID (in the given index in case of a multi-track) from the node."));
  601. addLegacyTrackview(behaviorContext->Method("get_num_nodes", PyTrackViewGetNumNodes, nullptr, "Gets the number of nodes."));
  602. addLegacyTrackview(behaviorContext->Method("get_node_name", PyTrackViewGetNodeName, nullptr, "Gets the name of a sequence by its index."));
  603. addLegacyTrackview(behaviorContext->Method("get_num_track_keys", PyTrackViewGetNumTrackKeys, nullptr, "Gets number of keys of the specified track."));
  604. addLegacyTrackview(behaviorContext->Method("get_key_value", PyTrackViewGetKeyValue, nullptr, "Gets the value of the specified key."));
  605. addLegacyTrackview(behaviorContext->Method("get_interpolated_value", PyTrackViewGetInterpolatedValue, nullptr, "Gets the interpolated value of a track at the specified time."));
  606. }
  607. }
  608. }