Movie.cpp 59 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908
  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/Component/Entity.h>
  9. #include <AzCore/Serialization/Locale.h>
  10. #include <AzCore/Serialization/SerializeContext.h>
  11. #include <AzCore/std/containers/map.h>
  12. #include <AzCore/std/containers/unordered_map.h>
  13. #include <AzCore/Time/ITime.h>
  14. #include <AzFramework/Components/CameraBus.h>
  15. #include <Maestro/Bus/SequenceComponentBus.h>
  16. #include "Movie.h"
  17. #include "AnimSplineTrack.h"
  18. #include "AnimSerializer.h"
  19. #include "AnimSequence.h"
  20. #include "CVarNode.h"
  21. #include "ScriptVarNode.h"
  22. #include "SceneNode.h"
  23. #include "EventNode.h"
  24. #include "AnimPostFXNode.h"
  25. #include "AnimScreenFaderNode.h"
  26. #include "CommentNode.h"
  27. #include "LayerNode.h"
  28. #include "ShadowsSetupNode.h"
  29. #include <MathConversion.h>
  30. #include <ISystem.h>
  31. #include <ILog.h>
  32. #include <IConsole.h>
  33. #include <IRenderer.h>
  34. #include <Maestro/Types/AnimNodeType.h>
  35. #include <Maestro/Types/SequenceType.h>
  36. #include <Maestro/Types/AnimParamType.h>
  37. int CMovieSystem::m_mov_NoCutscenes = 0;
  38. float CMovieSystem::m_mov_cameraPrecacheTime = 1.f;
  39. #if !defined(_RELEASE)
  40. int CMovieSystem::m_mov_DebugEvents = 0;
  41. int CMovieSystem::m_mov_debugCamShake = 0;
  42. #endif
  43. #if !defined(_RELEASE)
  44. struct SMovieSequenceAutoComplete
  45. : public IConsoleArgumentAutoComplete
  46. {
  47. virtual int GetCount() const
  48. {
  49. IMovieSystem* movieSystem = AZ::Interface<IMovieSystem>::Get();
  50. return movieSystem ? movieSystem->GetNumSequences() : 0;
  51. }
  52. virtual const char* GetValue(int nIndex) const
  53. {
  54. IMovieSystem* movieSystem = AZ::Interface<IMovieSystem>::Get();
  55. if (movieSystem)
  56. {
  57. IAnimSequence* sequence = movieSystem->GetSequence(nIndex);
  58. if (sequence)
  59. {
  60. return sequence->GetName();
  61. }
  62. }
  63. return "";
  64. }
  65. };
  66. #endif //#if !defined(_RELEASE)
  67. #if !defined(_RELEASE)
  68. static SMovieSequenceAutoComplete s_movieSequenceAutoComplete;
  69. #endif
  70. //////////////////////////////////////////////////////////////////////////
  71. // Serialization for anim nodes & param types
  72. #define REGISTER_NODE_TYPE(name) assert(!m_animNodeEnumToStringMap.contains(AnimNodeType::name)); \
  73. m_animNodeEnumToStringMap[AnimNodeType::name] = AZ_STRINGIZE(name); \
  74. m_animNodeStringToEnumMap[AnimParamSystemString(AZ_STRINGIZE(name))] = AnimNodeType::name;
  75. #define REGISTER_PARAM_TYPE(name) assert(!m_animParamEnumToStringMap.contains(AnimParamType::name)); \
  76. m_animParamEnumToStringMap[AnimParamType::name] = AZ_STRINGIZE(name); \
  77. m_animParamStringToEnumMap[AnimParamSystemString(AZ_STRINGIZE(name))] = AnimParamType::name;
  78. // If you get an assert in this function, it means two node types have the same enum value.
  79. void CMovieSystem::RegisterNodeTypes()
  80. {
  81. REGISTER_NODE_TYPE(Entity)
  82. REGISTER_NODE_TYPE(Director)
  83. REGISTER_NODE_TYPE(CVar)
  84. REGISTER_NODE_TYPE(ScriptVar)
  85. REGISTER_NODE_TYPE(Material)
  86. REGISTER_NODE_TYPE(Event)
  87. REGISTER_NODE_TYPE(Group)
  88. REGISTER_NODE_TYPE(Layer)
  89. REGISTER_NODE_TYPE(Comment)
  90. REGISTER_NODE_TYPE(RadialBlur)
  91. REGISTER_NODE_TYPE(ColorCorrection)
  92. REGISTER_NODE_TYPE(DepthOfField)
  93. REGISTER_NODE_TYPE(ScreenFader)
  94. REGISTER_NODE_TYPE(Light)
  95. REGISTER_NODE_TYPE(ShadowSetup)
  96. REGISTER_NODE_TYPE(Alembic)
  97. REGISTER_NODE_TYPE(GeomCache)
  98. REGISTER_NODE_TYPE(AzEntity)
  99. REGISTER_NODE_TYPE(Component)
  100. }
  101. // If you get an assert in this function, it means two param types have the same enum value.
  102. void CMovieSystem::RegisterParamTypes()
  103. {
  104. REGISTER_PARAM_TYPE(Position)
  105. REGISTER_PARAM_TYPE(Rotation)
  106. REGISTER_PARAM_TYPE(Scale)
  107. REGISTER_PARAM_TYPE(Event)
  108. REGISTER_PARAM_TYPE(Visibility)
  109. REGISTER_PARAM_TYPE(Animation)
  110. REGISTER_PARAM_TYPE(Sound)
  111. REGISTER_PARAM_TYPE(Sequence)
  112. REGISTER_PARAM_TYPE(Console)
  113. REGISTER_PARAM_TYPE(Music) ///@deprecated in 1.11, left in for legacy serialization
  114. REGISTER_PARAM_TYPE(Float)
  115. REGISTER_PARAM_TYPE(LookAt)
  116. REGISTER_PARAM_TYPE(TrackEvent)
  117. REGISTER_PARAM_TYPE(ShakeAmplitudeA)
  118. REGISTER_PARAM_TYPE(ShakeAmplitudeB)
  119. REGISTER_PARAM_TYPE(ShakeFrequencyA)
  120. REGISTER_PARAM_TYPE(ShakeFrequencyB)
  121. REGISTER_PARAM_TYPE(ShakeMultiplier)
  122. REGISTER_PARAM_TYPE(ShakeNoise)
  123. REGISTER_PARAM_TYPE(ShakeWorking)
  124. REGISTER_PARAM_TYPE(ShakeAmpAMult)
  125. REGISTER_PARAM_TYPE(ShakeAmpBMult)
  126. REGISTER_PARAM_TYPE(ShakeFreqAMult)
  127. REGISTER_PARAM_TYPE(ShakeFreqBMult)
  128. REGISTER_PARAM_TYPE(DepthOfField)
  129. REGISTER_PARAM_TYPE(FocusDistance)
  130. REGISTER_PARAM_TYPE(FocusRange)
  131. REGISTER_PARAM_TYPE(BlurAmount)
  132. REGISTER_PARAM_TYPE(Capture)
  133. REGISTER_PARAM_TYPE(TransformNoise)
  134. REGISTER_PARAM_TYPE(TimeWarp)
  135. REGISTER_PARAM_TYPE(FixedTimeStep)
  136. REGISTER_PARAM_TYPE(NearZ)
  137. REGISTER_PARAM_TYPE(Goto)
  138. REGISTER_PARAM_TYPE(PositionX)
  139. REGISTER_PARAM_TYPE(PositionY)
  140. REGISTER_PARAM_TYPE(PositionZ)
  141. REGISTER_PARAM_TYPE(RotationX)
  142. REGISTER_PARAM_TYPE(RotationY)
  143. REGISTER_PARAM_TYPE(RotationZ)
  144. REGISTER_PARAM_TYPE(ScaleX)
  145. REGISTER_PARAM_TYPE(ScaleY)
  146. REGISTER_PARAM_TYPE(ScaleZ)
  147. REGISTER_PARAM_TYPE(ColorR)
  148. REGISTER_PARAM_TYPE(ColorG)
  149. REGISTER_PARAM_TYPE(ColorB)
  150. REGISTER_PARAM_TYPE(CommentText)
  151. REGISTER_PARAM_TYPE(ScreenFader)
  152. REGISTER_PARAM_TYPE(LightDiffuse)
  153. REGISTER_PARAM_TYPE(LightRadius)
  154. REGISTER_PARAM_TYPE(LightDiffuseMult)
  155. REGISTER_PARAM_TYPE(LightHDRDynamic)
  156. REGISTER_PARAM_TYPE(LightSpecularMult)
  157. REGISTER_PARAM_TYPE(LightSpecPercentage)
  158. REGISTER_PARAM_TYPE(MaterialDiffuse)
  159. REGISTER_PARAM_TYPE(MaterialSpecular)
  160. REGISTER_PARAM_TYPE(MaterialEmissive)
  161. REGISTER_PARAM_TYPE(MaterialEmissiveIntensity)
  162. REGISTER_PARAM_TYPE(MaterialOpacity)
  163. REGISTER_PARAM_TYPE(MaterialSmoothness)
  164. REGISTER_PARAM_TYPE(TimeRanges)
  165. REGISTER_PARAM_TYPE(Physics)
  166. REGISTER_PARAM_TYPE(GSMCache)
  167. REGISTER_PARAM_TYPE(ShutterSpeed)
  168. REGISTER_PARAM_TYPE(Physicalize)
  169. REGISTER_PARAM_TYPE(PhysicsDriven)
  170. REGISTER_PARAM_TYPE(SunLongitude)
  171. REGISTER_PARAM_TYPE(SunLatitude)
  172. REGISTER_PARAM_TYPE(MoonLongitude)
  173. REGISTER_PARAM_TYPE(MoonLatitude)
  174. REGISTER_PARAM_TYPE(ProceduralEyes)
  175. }
  176. namespace Internal
  177. {
  178. float ApplyDeltaTimeOverrideIfEnabled(float deltaTime)
  179. {
  180. if (auto* timeSystem = AZ::Interface<AZ::ITime>::Get())
  181. {
  182. const AZ::TimeUs deltatimeOverride = timeSystem->GetSimulationTickDeltaOverride();
  183. if (deltatimeOverride != AZ::Time::ZeroTimeUs)
  184. {
  185. deltaTime = AZ::TimeUsToSeconds(deltatimeOverride);
  186. }
  187. }
  188. return deltaTime;
  189. }
  190. } // namespace Internal
  191. //////////////////////////////////////////////////////////////////////////
  192. CMovieSystem::CMovieSystem(ISystem* pSystem)
  193. {
  194. if (!AZ::Interface<IMovieSystem>::Get())
  195. {
  196. AZ::Interface<IMovieSystem>::Register(this);
  197. }
  198. m_pSystem = pSystem;
  199. m_bRecording = false;
  200. m_pCallback = nullptr;
  201. m_pUser = nullptr;
  202. m_bPaused = false;
  203. m_bCutscenesPausedInEditor = true;
  204. m_sequenceStopBehavior = eSSB_GotoEndTime;
  205. m_lastUpdateTime = AZ::Time::ZeroTimeUs;
  206. m_bStartCapture = false;
  207. m_captureFrame = -1;
  208. m_bEndCapture = false;
  209. m_fixedTimeStepBackUp = AZ::Time::ZeroTimeUs;
  210. m_cvar_capture_frame_once = nullptr;
  211. m_cvar_capture_folder = nullptr;
  212. m_cvar_sys_maxTimeStepForMovieSystem = nullptr;
  213. m_cvar_capture_frames = nullptr;
  214. m_cvar_capture_file_prefix = nullptr;
  215. m_bPhysicsEventsEnabled = true;
  216. m_bBatchRenderMode = false;
  217. m_nextSequenceId = 1;
  218. REGISTER_CVAR2("mov_NoCutscenes", &m_mov_NoCutscenes, 0, 0, "Disable playing of Cut-Scenes");
  219. REGISTER_CVAR2("mov_cameraPrecacheTime", &m_mov_cameraPrecacheTime, 1.f, VF_NULL, "");
  220. m_mov_overrideCam = REGISTER_STRING("mov_overrideCam", "", VF_NULL, "Set the camera used for the sequence which overrides the camera track info in the sequence.\nUse the Camera Name for Object Entity Cameras (Legacy) or the Entity ID for Component Entity Cameras.");
  221. DoNodeStaticInitialisation();
  222. RegisterNodeTypes();
  223. RegisterParamTypes();
  224. }
  225. //////////////////////////////////////////////////////////////////////////
  226. CMovieSystem::CMovieSystem()
  227. : CMovieSystem(gEnv->pSystem)
  228. {
  229. }
  230. //////////////////////////////////////////////////////////////////////////
  231. CMovieSystem::~CMovieSystem()
  232. {
  233. if (AZ::Interface<IMovieSystem>::Get() == this)
  234. {
  235. AZ::Interface<IMovieSystem>::Unregister(this);
  236. }
  237. }
  238. //////////////////////////////////////////////////////////////////////////
  239. void CMovieSystem::DoNodeStaticInitialisation()
  240. {
  241. CAnimPostFXNode::Initialize();
  242. CAnimSceneNode::Initialize();
  243. CAnimScreenFaderNode::Initialize();
  244. CCommentNode::Initialize();
  245. CLayerNode::Initialize();
  246. }
  247. //////////////////////////////////////////////////////////////////////////
  248. IAnimSequence* CMovieSystem::CreateSequence(const char* sequenceName, bool load, uint32 id, SequenceType sequenceType, AZ::EntityId entityId)
  249. {
  250. if (!load)
  251. {
  252. id = m_nextSequenceId++;
  253. }
  254. IAnimSequence* sequence = aznew CAnimSequence(id, sequenceType);
  255. sequence->SetName(sequenceName);
  256. sequence->SetSequenceEntityId(entityId);
  257. m_sequences.push_back(sequence);;
  258. return sequence;
  259. }
  260. //////////////////////////////////////////////////////////////////////////
  261. IAnimSequence* CMovieSystem::FindLegacySequenceByName(const char* pSequenceName) const
  262. {
  263. assert(pSequenceName);
  264. if (!pSequenceName)
  265. {
  266. return NULL;
  267. }
  268. for (Sequences::const_iterator it = m_sequences.begin(); it != m_sequences.end(); ++it)
  269. {
  270. IAnimSequence* pCurrentSequence = it->get();
  271. const char* fullname = pCurrentSequence->GetName();
  272. if (_stricmp(fullname, pSequenceName) == 0)
  273. {
  274. return pCurrentSequence;
  275. }
  276. }
  277. return NULL;
  278. }
  279. //////////////////////////////////////////////////////////////////////////
  280. IAnimSequence* CMovieSystem::FindSequence(const AZ::EntityId& componentEntitySequenceId) const
  281. {
  282. IAnimSequence* retSequence = nullptr;
  283. if (componentEntitySequenceId.IsValid())
  284. {
  285. for (Sequences::const_iterator it = m_sequences.begin(); it != m_sequences.end(); ++it)
  286. {
  287. const AZ::EntityId& seqOwnerId = it->get()->GetSequenceEntityId();
  288. if (seqOwnerId == componentEntitySequenceId)
  289. {
  290. retSequence = it->get();
  291. break;
  292. }
  293. }
  294. }
  295. return retSequence;
  296. }
  297. //////////////////////////////////////////////////////////////////////////
  298. IAnimSequence* CMovieSystem::FindSequenceById(uint32 id) const
  299. {
  300. if (id == 0 || id >= m_nextSequenceId)
  301. {
  302. return NULL;
  303. }
  304. for (Sequences::const_iterator it = m_sequences.begin(); it != m_sequences.end(); ++it)
  305. {
  306. IAnimSequence* pCurrentSequence = it->get();
  307. if (id == pCurrentSequence->GetId())
  308. {
  309. return pCurrentSequence;
  310. }
  311. }
  312. return NULL;
  313. }
  314. //////////////////////////////////////////////////////////////////////////
  315. bool CMovieSystem::FindSequence(IAnimSequence* sequence, PlayingSequences::const_iterator& sequenceIteratorOut) const
  316. {
  317. PlayingSequences::const_iterator itend = m_playingSequences.end();
  318. for (sequenceIteratorOut = m_playingSequences.begin(); sequenceIteratorOut != itend; ++sequenceIteratorOut)
  319. {
  320. if (sequenceIteratorOut->sequence == sequence)
  321. {
  322. return true;
  323. }
  324. }
  325. return false;
  326. }
  327. //////////////////////////////////////////////////////////////////////////
  328. bool CMovieSystem::FindSequence(IAnimSequence* sequence, PlayingSequences::iterator& sequenceIteratorOut)
  329. {
  330. PlayingSequences::const_iterator itend = m_playingSequences.end();
  331. for (sequenceIteratorOut = m_playingSequences.begin(); sequenceIteratorOut != itend; ++sequenceIteratorOut)
  332. {
  333. if (sequenceIteratorOut->sequence == sequence)
  334. {
  335. return true;
  336. }
  337. }
  338. return false;
  339. }
  340. //////////////////////////////////////////////////////////////////////////
  341. IAnimSequence* CMovieSystem::GetSequence(int i) const
  342. {
  343. assert(i >= 0 && i < GetNumSequences());
  344. if (i < 0 || i >= GetNumSequences())
  345. {
  346. return NULL;
  347. }
  348. return m_sequences[i].get();
  349. }
  350. //////////////////////////////////////////////////////////////////////////
  351. int CMovieSystem::GetNumSequences() const
  352. {
  353. return static_cast<int>(m_sequences.size());
  354. }
  355. //////////////////////////////////////////////////////////////////////////
  356. IAnimSequence* CMovieSystem::GetPlayingSequence(int i) const
  357. {
  358. assert(i >= 0 && i < GetNumPlayingSequences());
  359. if (i < 0 || i >= GetNumPlayingSequences())
  360. {
  361. return NULL;
  362. }
  363. return m_playingSequences[i].sequence.get();
  364. }
  365. //////////////////////////////////////////////////////////////////////////
  366. int CMovieSystem::GetNumPlayingSequences() const
  367. {
  368. return static_cast<int>(m_playingSequences.size());
  369. }
  370. //////////////////////////////////////////////////////////////////////////
  371. void CMovieSystem::AddSequence(IAnimSequence* sequence)
  372. {
  373. [[maybe_unused]] const AZ::EntityId& sequenceEntityId = sequence->GetSequenceEntityId();
  374. if (AZStd::find(m_sequences.begin(), m_sequences.end(), sequence) == m_sequences.end())
  375. {
  376. AZ_Trace("CMovieSystem::AddSequence", "IAnimSequence %s push_back in m_sequences", sequenceEntityId.ToString().c_str());
  377. m_sequences.push_back(sequence);
  378. }
  379. else
  380. {
  381. AZ_Trace("CMovieSystem::AddSequence", "IAnimSequence %s already in m_sequences", sequenceEntityId.ToString().c_str());
  382. }
  383. }
  384. //////////////////////////////////////////////////////////////////////////
  385. bool CMovieSystem::IsCutScenePlaying() const
  386. {
  387. const uint numPlayingSequences = static_cast<uint>(m_playingSequences.size());
  388. for (uint i = 0; i < numPlayingSequences; ++i)
  389. {
  390. const IAnimSequence* pAnimSequence = m_playingSequences[i].sequence.get();
  391. if (pAnimSequence && (pAnimSequence->GetFlags() & IAnimSequence::eSeqFlags_CutScene) != 0)
  392. {
  393. return true;
  394. }
  395. }
  396. return false;
  397. }
  398. //////////////////////////////////////////////////////////////////////////
  399. void CMovieSystem::RemoveSequence(IAnimSequence* sequence)
  400. {
  401. AZ_Assert(sequence != nullptr, "sequence should not be nullptr.");
  402. if (sequence)
  403. {
  404. IMovieCallback* callback = GetCallback();
  405. SetCallback(nullptr);
  406. StopSequence(sequence);
  407. // remove from m_newlyActivatedSequences in the edge case something was added but not processed yet.
  408. for (auto iter = m_newlyActivatedSequences.begin(); iter != m_newlyActivatedSequences.end(); ++iter)
  409. {
  410. if (sequence == *iter)
  411. {
  412. m_newlyActivatedSequences.erase(iter);
  413. break;
  414. }
  415. }
  416. for (Sequences::iterator iter = m_sequences.begin(); iter != m_sequences.end(); ++iter)
  417. {
  418. if (sequence == *iter)
  419. {
  420. [[maybe_unused]] AZ::EntityId sequenceComponentEntityId(sequence->GetSequenceEntityId());
  421. AZ_Trace(
  422. "CMovieSystem::RemoveSequence",
  423. "Erasing %s from m_sequences",
  424. sequenceComponentEntityId.ToString().c_str());
  425. m_movieListenerMap.erase(sequence);
  426. m_sequences.erase(iter);
  427. break;
  428. }
  429. }
  430. #if defined(AZ_ENABLE_TRACING)
  431. if (!m_sequences.empty())
  432. {
  433. AZ_Trace("CMovieSystem::RemoveSequence","Left in m_sequences:");
  434. for (Sequences::iterator iter = m_sequences.begin(); iter != m_sequences.end(); ++iter)
  435. {
  436. AZ::EntityId sequenceComponentEntityId((*iter)->GetSequenceEntityId());
  437. AZ_Trace("CMovieSystem::RemoveSequence", " %s", sequenceComponentEntityId.ToString().c_str());
  438. }
  439. }
  440. #endif
  441. SetCallback(callback);
  442. }
  443. }
  444. //////////////////////////////////////////////////////////////////////////
  445. void CMovieSystem::OnSetSequenceId(uint32 sequenceId)
  446. {
  447. if (sequenceId >= m_nextSequenceId)
  448. {
  449. m_nextSequenceId = sequenceId + 1;
  450. }
  451. }
  452. //////////////////////////////////////////////////////////////////////////
  453. int CMovieSystem::OnSequenceRenamed(const char* before, const char* after)
  454. {
  455. assert(before && after);
  456. if (before == NULL || after == NULL)
  457. {
  458. return 0;
  459. }
  460. if (_stricmp(before, after) == 0)
  461. {
  462. return 0;
  463. }
  464. int count = 0;
  465. // For every sequence,
  466. for (Sequences::iterator it = m_sequences.begin(); it != m_sequences.end(); ++it)
  467. {
  468. // Find a director node, if any.
  469. for (int k = 0; k < (*it)->GetNodeCount(); ++k)
  470. {
  471. IAnimNode* node = (*it)->GetNode(k);
  472. if (node->GetType() != AnimNodeType::Director)
  473. {
  474. continue;
  475. }
  476. // If there is a director node, check whether it has a sequence track.
  477. IAnimTrack* track = node->GetTrackForParameter(AnimParamType::Sequence);
  478. if (track)
  479. {
  480. for (int m = 0; m < track->GetNumKeys(); ++m)
  481. {
  482. ISequenceKey seqKey;
  483. track->GetKey(m, &seqKey);
  484. // For each key that refers the sequence, update the name.
  485. if (!seqKey.szSelection.empty() && (_stricmp(seqKey.szSelection.c_str(), before) == 0))
  486. {
  487. seqKey.szSelection = after;
  488. track->SetKey(m, &seqKey);
  489. ++count;
  490. }
  491. }
  492. }
  493. break;
  494. }
  495. }
  496. return count;
  497. }
  498. //////////////////////////////////////////////////////////////////////////
  499. int CMovieSystem::OnCameraRenamed(const char* before, const char* after)
  500. {
  501. int count = 0;
  502. // For every sequence,
  503. for (Sequences::iterator it = m_sequences.begin(); it != m_sequences.end(); ++it)
  504. {
  505. // Find a director node, if any.
  506. for (int k = 0; k < (*it)->GetNodeCount(); ++k)
  507. {
  508. IAnimNode* node = (*it)->GetNode(k);
  509. if (node->GetType() != AnimNodeType::Director)
  510. {
  511. continue;
  512. }
  513. // If there is a director node, check whether it has a camera track.
  514. IAnimTrack* track = node->GetTrackForParameter(AnimParamType::Camera);
  515. if (track)
  516. {
  517. for (int m = 0; m < track->GetNumKeys(); ++m)
  518. {
  519. ISelectKey selKey;
  520. track->GetKey(m, &selKey);
  521. // For each key that refers the camera, update the name.
  522. if (_stricmp(selKey.szSelection.c_str(), before) == 0)
  523. {
  524. selKey.szSelection = after;
  525. track->SetKey(m, &selKey);
  526. ++count;
  527. }
  528. }
  529. }
  530. break;
  531. }
  532. }
  533. return count;
  534. }
  535. //////////////////////////////////////////////////////////////////////////
  536. void CMovieSystem::RemoveAllSequences()
  537. {
  538. IMovieCallback* pCallback = GetCallback();
  539. SetCallback(NULL);
  540. InternalStopAllSequences(true, false);
  541. m_sequences.clear();
  542. for (TMovieListenerMap::iterator it = m_movieListenerMap.begin(); it != m_movieListenerMap.end(); )
  543. {
  544. if (it->first)
  545. {
  546. m_movieListenerMap.erase(it++);
  547. }
  548. else
  549. {
  550. ++it;
  551. }
  552. }
  553. SetCallback(pCallback);
  554. }
  555. //////////////////////////////////////////////////////////////////////////
  556. void CMovieSystem::PlaySequence(const char* pSequenceName, IAnimSequence* pParentSeq, bool bResetFx, bool bTrackedSequence, float startTime, float endTime)
  557. {
  558. IAnimSequence* sequence = FindLegacySequenceByName(pSequenceName);
  559. if (sequence)
  560. {
  561. PlaySequence(sequence, pParentSeq, bResetFx, bTrackedSequence, startTime, endTime);
  562. }
  563. else
  564. {
  565. gEnv->pLog->Log ("CMovieSystem::PlaySequence: Error: Sequence \"%s\" not found", pSequenceName);
  566. }
  567. }
  568. //////////////////////////////////////////////////////////////////////////
  569. void CMovieSystem::PlaySequence(IAnimSequence* sequence, IAnimSequence* parentSeq,
  570. bool bResetFx, bool bTrackedSequence, float startTime, float endTime)
  571. {
  572. assert(sequence != 0);
  573. if (!sequence || IsPlaying(sequence))
  574. {
  575. return;
  576. }
  577. if ((sequence->GetFlags() & IAnimSequence::eSeqFlags_CutScene) || (sequence->GetFlags() & IAnimSequence::eSeqFlags_NoHUD))
  578. {
  579. // Don't play cut-scene if this console variable set.
  580. if (m_mov_NoCutscenes != 0)
  581. {
  582. return;
  583. }
  584. }
  585. // If this sequence is cut scene disable player.
  586. if (sequence->GetFlags() & IAnimSequence::eSeqFlags_CutScene)
  587. {
  588. OnCameraCut();
  589. sequence->SetParentSequence(parentSeq);
  590. if (!gEnv->IsEditing() || !m_bCutscenesPausedInEditor)
  591. {
  592. if (m_pUser)
  593. {
  594. m_pUser->BeginCutScene(sequence, sequence->GetCutSceneFlags(), bResetFx);
  595. }
  596. }
  597. }
  598. sequence->Activate();
  599. sequence->Resume();
  600. static_cast<CAnimSequence*>(sequence)->OnStart();
  601. PlayingSequence ps;
  602. ps.sequence = sequence;
  603. ps.startTime = startTime == -FLT_MAX ? sequence->GetTimeRange().start : startTime;
  604. ps.endTime = endTime == -FLT_MAX ? sequence->GetTimeRange().end : endTime;
  605. ps.currentTime = startTime == -FLT_MAX ? sequence->GetTimeRange().start : startTime;
  606. ps.currentSpeed = 1.0f;
  607. ps.trackedSequence = bTrackedSequence;
  608. ps.bSingleFrame = false;
  609. // Make sure all members are initialized before pushing.
  610. [[maybe_unused]] const AZ::EntityId& sequenceEntityId = sequence->GetSequenceEntityId();
  611. AZ_Trace("CMovieSystem::PlaySequence", "m_playingSequences.push_back %s", sequenceEntityId.ToString().c_str());
  612. m_playingSequences.push_back(ps);
  613. // tell all interested listeners
  614. NotifyListeners(sequence, IMovieListener::eMovieEvent_Started);
  615. }
  616. void CMovieSystem::NotifyListeners(IAnimSequence* sequence, IMovieListener::EMovieEvent event)
  617. {
  618. ////////////////////////////////
  619. // Legacy Notification System
  620. TMovieListenerMap::iterator found (m_movieListenerMap.find(sequence));
  621. if (found != m_movieListenerMap.end())
  622. {
  623. TMovieListenerVec listForSeq = (*found).second;
  624. TMovieListenerVec::iterator iter (listForSeq.begin());
  625. while (iter != listForSeq.end())
  626. {
  627. (*iter)->OnMovieEvent(event, sequence);
  628. ++iter;
  629. }
  630. }
  631. // 'NULL' ones are listeners interested in every sequence. Do not send "update" here
  632. if (event != IMovieListener::eMovieEvent_Updated)
  633. {
  634. TMovieListenerMap::iterator found2 (m_movieListenerMap.find((IAnimSequence*)0));
  635. if (found2 != m_movieListenerMap.end())
  636. {
  637. TMovieListenerVec listForSeq = (*found2).second;
  638. TMovieListenerVec::iterator iter (listForSeq.begin());
  639. while (iter != listForSeq.end())
  640. {
  641. (*iter)->OnMovieEvent(event, sequence);
  642. ++iter;
  643. }
  644. }
  645. }
  646. /////////////////////////////////////
  647. // SequenceComponentNotification EBus
  648. const AZ::EntityId& sequenceComponentEntityId = sequence->GetSequenceEntityId();
  649. switch (event)
  650. {
  651. /*
  652. * When a sequence is stopped, Resume is called just before stopped (not sure why). To ensure that a OnStop notification is sent out after the Resume,
  653. * notifications for eMovieEvent_Started and eMovieEvent_Stopped are handled in IAnimSequence::OnStart and IAnimSequence::OnStop
  654. */
  655. case IMovieListener::eMovieEvent_Aborted:
  656. {
  657. Maestro::SequenceComponentNotificationBus::Event(sequenceComponentEntityId, &Maestro::SequenceComponentNotificationBus::Events::OnAbort, GetPlayingTime(sequence));
  658. break;
  659. }
  660. case IMovieListener::eMovieEvent_Updated:
  661. {
  662. Maestro::SequenceComponentNotificationBus::Event(sequenceComponentEntityId, &Maestro::SequenceComponentNotificationBus::Events::OnUpdate, GetPlayingTime(sequence));
  663. break;
  664. }
  665. default:
  666. {
  667. // do nothing for unhandled IMovieListener events
  668. break;
  669. }
  670. }
  671. }
  672. //////////////////////////////////////////////////////////////////////////
  673. bool CMovieSystem::StopSequence(const char* pSequenceName)
  674. {
  675. IAnimSequence* sequence = FindLegacySequenceByName(pSequenceName);
  676. if (sequence)
  677. {
  678. return StopSequence(sequence);
  679. }
  680. return false;
  681. }
  682. //////////////////////////////////////////////////////////////////////////
  683. bool CMovieSystem::StopSequence(IAnimSequence* sequence)
  684. {
  685. return InternalStopSequence(sequence, false, true);
  686. }
  687. //////////////////////////////////////////////////////////////////////////
  688. void CMovieSystem::InternalStopAllSequences(bool bAbort, bool bAnimate)
  689. {
  690. while (!m_playingSequences.empty())
  691. {
  692. InternalStopSequence(m_playingSequences.begin()->sequence.get(), bAbort, bAnimate);
  693. }
  694. stl::free_container(m_playingSequences);
  695. }
  696. //////////////////////////////////////////////////////////////////////////
  697. bool CMovieSystem::InternalStopSequence(IAnimSequence* sequence, bool bAbort, bool bAnimate)
  698. {
  699. assert(sequence != 0);
  700. PlayingSequences::iterator it;
  701. if (!FindSequence(sequence, it))
  702. {
  703. return false;
  704. }
  705. if (bAnimate && sequence->IsActivated())
  706. {
  707. if (m_sequenceStopBehavior == eSSB_GotoEndTime)
  708. {
  709. SAnimContext ac;
  710. ac.singleFrame = true;
  711. ac.time = sequence->GetTimeRange().end;
  712. sequence->Animate(ac);
  713. }
  714. else if (m_sequenceStopBehavior == eSSB_GotoStartTime)
  715. {
  716. SAnimContext ac;
  717. ac.singleFrame = true;
  718. ac.time = sequence->GetTimeRange().start;
  719. sequence->Animate(ac);
  720. }
  721. sequence->Deactivate();
  722. }
  723. // If this sequence is cut scene end it.
  724. if (sequence->GetFlags() & IAnimSequence::eSeqFlags_CutScene)
  725. {
  726. if (!gEnv->IsEditing() || !m_bCutscenesPausedInEditor)
  727. {
  728. if (m_pUser)
  729. {
  730. m_pUser->EndCutScene(sequence, sequence->GetCutSceneFlags(true));
  731. }
  732. }
  733. sequence->SetParentSequence(NULL);
  734. }
  735. // tell all interested listeners
  736. NotifyListeners(sequence, bAbort ? IMovieListener::eMovieEvent_Aborted : IMovieListener::eMovieEvent_Stopped);
  737. // erase the sequence after notifying listeners so if they choose to they can get the ending time of this sequence
  738. if (FindSequence(sequence, it))
  739. {
  740. m_playingSequences.erase(it);
  741. }
  742. sequence->Resume();
  743. static_cast<CAnimSequence*>(sequence)->OnStop();
  744. return true;
  745. }
  746. //////////////////////////////////////////////////////////////////////////
  747. bool CMovieSystem::AbortSequence(IAnimSequence* sequence, bool bLeaveTime)
  748. {
  749. return InternalStopSequence(sequence, true, !bLeaveTime);
  750. }
  751. //////////////////////////////////////////////////////////////////////////
  752. void CMovieSystem::StopAllSequences()
  753. {
  754. InternalStopAllSequences(false, true);
  755. }
  756. //////////////////////////////////////////////////////////////////////////
  757. void CMovieSystem::StopAllCutScenes()
  758. {
  759. bool bAnyStoped;
  760. PlayingSequences::iterator next;
  761. do
  762. {
  763. bAnyStoped = false;
  764. for (PlayingSequences::iterator it = m_playingSequences.begin(); it != m_playingSequences.end(); it = next)
  765. {
  766. next = it;
  767. ++next;
  768. IAnimSequence* pCurrentSequence = it->sequence.get();
  769. if (pCurrentSequence->GetFlags() & IAnimSequence::eSeqFlags_CutScene)
  770. {
  771. bAnyStoped = true;
  772. StopSequence(pCurrentSequence);
  773. break;
  774. }
  775. }
  776. } while (bAnyStoped);
  777. if (m_playingSequences.empty())
  778. {
  779. stl::free_container(m_playingSequences);
  780. }
  781. }
  782. //////////////////////////////////////////////////////////////////////////
  783. bool CMovieSystem::IsPlaying(IAnimSequence* sequence) const
  784. {
  785. if (nullptr == sequence)
  786. {
  787. return false;
  788. }
  789. for (PlayingSequences::const_iterator it = m_playingSequences.begin(); it != m_playingSequences.end(); ++it)
  790. {
  791. if (it->sequence->GetSequenceEntityId() == sequence->GetSequenceEntityId())
  792. {
  793. return true;
  794. }
  795. }
  796. return false;
  797. }
  798. //////////////////////////////////////////////////////////////////////////
  799. void CMovieSystem::Reset(bool bPlayOnReset, bool bSeekToStart)
  800. {
  801. InternalStopAllSequences(true, false);
  802. // Reset all sequences.
  803. for (Sequences::const_iterator iter = m_sequences.cbegin(); iter != m_sequences.cend(); ++iter)
  804. {
  805. IAnimSequence* pCurrentSequence = iter->get();
  806. NotifyListeners(pCurrentSequence, IMovieListener::eMovieEvent_Started);
  807. pCurrentSequence->Reset(bSeekToStart);
  808. NotifyListeners(pCurrentSequence, IMovieListener::eMovieEvent_Stopped);
  809. }
  810. if (bPlayOnReset)
  811. {
  812. for (Sequences::iterator iter = m_sequences.begin(); iter != m_sequences.end(); ++iter)
  813. {
  814. IAnimSequence* pCurrentSequence = iter->get();
  815. if (pCurrentSequence->GetFlags() & IAnimSequence::eSeqFlags_PlayOnReset)
  816. {
  817. [[maybe_unused]] const AZ::EntityId& sequenceEntityId = pCurrentSequence->GetSequenceEntityId();
  818. AZ_Trace("CMovieSystem::Reset", "PlaySequence %s", sequenceEntityId.ToString().c_str());
  819. PlaySequence(pCurrentSequence);
  820. }
  821. }
  822. }
  823. // un-pause the movie system
  824. m_bPaused = false;
  825. // Reset camera.
  826. SCameraParams CamParams = GetCameraParams();
  827. CamParams.cameraEntityId.SetInvalid();
  828. CamParams.fov = 0.0f;
  829. CamParams.justActivated = true;
  830. SetCameraParams(CamParams);
  831. }
  832. //////////////////////////////////////////////////////////////////////////
  833. void CMovieSystem::PlayOnLoadSequences()
  834. {
  835. for (Sequences::const_iterator sit = m_sequences.cbegin(); sit != m_sequences.cend(); ++sit)
  836. {
  837. IAnimSequence* sequence = sit->get();
  838. if (sequence->GetFlags() & IAnimSequence::eSeqFlags_PlayOnReset)
  839. {
  840. PlaySequence(sequence);
  841. }
  842. }
  843. // Reset camera.
  844. SCameraParams CamParams = GetCameraParams();
  845. CamParams.cameraEntityId.SetInvalid();
  846. CamParams.fov = 0.0f;
  847. CamParams.justActivated = true;
  848. SetCameraParams(CamParams);
  849. }
  850. //////////////////////////////////////////////////////////////////////////
  851. void CMovieSystem::StillUpdate()
  852. {
  853. if (!gEnv->IsEditor())
  854. {
  855. return;
  856. }
  857. for (PlayingSequences::iterator it = m_playingSequences.begin(); it != m_playingSequences.end(); ++it)
  858. {
  859. PlayingSequence& playingSequence = *it;
  860. playingSequence.sequence->StillUpdate();
  861. }
  862. // Check for end capture here while in the editor.
  863. // In some cases, we might have signaled an end capture when leaving Game mode,
  864. // but ControlCapture hasn't been given a tick by Game to actually end the capture.
  865. // So make sure any pending end capture signaled gets shutdown here.
  866. CheckForEndCapture();
  867. }
  868. //////////////////////////////////////////////////////////////////////////
  869. void CMovieSystem::ShowPlayedSequencesDebug()
  870. {
  871. float y = 10.0f;
  872. AZStd::vector<const char*> names;
  873. AZStd::vector<float> rows;
  874. constexpr f32 green[4] = {0, 1, 0, 1};
  875. constexpr f32 purple[4] = {1, 0, 1, 1};
  876. constexpr f32 white[4] = {1, 1, 1, 1};
  877. //TODO: needs an implementation
  878. auto Draw2dLabel = [](float /*x*/,float /*y*/,float /*depth*/,const f32* /*color*/,bool /*center*/, const char* /*fmt*/, ...) {};
  879. for (PlayingSequences::iterator it = m_playingSequences.begin(); it != m_playingSequences.end(); ++it)
  880. {
  881. PlayingSequence& playingSequence = *it;
  882. if (playingSequence.sequence == nullptr)
  883. {
  884. continue;
  885. }
  886. const char* fullname = playingSequence.sequence->GetName();
  887. Draw2dLabel(1.0f, y, 1.3f, green, false, "Sequence %s : %f (x %f)", fullname, playingSequence.currentTime, playingSequence.currentSpeed);
  888. y += 16.0f;
  889. for (int i = 0; i < playingSequence.sequence->GetNodeCount(); ++i)
  890. {
  891. // Checks nodes which happen to be in several sequences.
  892. // Those can be a bug, since several sequences may try to control the same entity.
  893. const char* name = playingSequence.sequence->GetNode(i)->GetName();
  894. bool alreadyThere = false;
  895. for (size_t k = 0; k < names.size(); ++k)
  896. {
  897. if (strcmp(names[k], name) == 0)
  898. {
  899. alreadyThere = true;
  900. break;
  901. }
  902. }
  903. if (alreadyThere == false)
  904. {
  905. names.push_back(name);
  906. }
  907. Draw2dLabel((21.0f + 100.0f * i), ((i % 2) ? (y + 8.0f) : y), 1.0f, alreadyThere ? white : purple, false, "%s", name);
  908. }
  909. y += 32.0f;
  910. }
  911. }
  912. //////////////////////////////////////////////////////////////////////////
  913. void CMovieSystem::PreUpdate(float deltaTime)
  914. {
  915. // Sequences can be spawned in game via a dynamic slice, so process newly activated sequences to see
  916. // if they should be auto played.
  917. for (auto iter = m_newlyActivatedSequences.begin(); iter != m_newlyActivatedSequences.end(); ++iter)
  918. {
  919. IAnimSequence* sequence = *iter;
  920. if (sequence->GetFlags() & IAnimSequence::eSeqFlags_PlayOnReset && !IsPlaying(sequence))
  921. {
  922. PlaySequence(sequence);
  923. }
  924. }
  925. m_newlyActivatedSequences.clear();
  926. UpdateInternal(Internal::ApplyDeltaTimeOverrideIfEnabled(deltaTime), true);
  927. }
  928. //////////////////////////////////////////////////////////////////////////
  929. void CMovieSystem::PostUpdate(float deltaTime)
  930. {
  931. UpdateInternal(Internal::ApplyDeltaTimeOverrideIfEnabled(deltaTime), false);
  932. }
  933. //////////////////////////////////////////////////////////////////////////
  934. void CMovieSystem::UpdateInternal(const float deltaTime, const bool bPreUpdate)
  935. {
  936. SAnimContext animContext;
  937. if (m_bPaused)
  938. {
  939. return;
  940. }
  941. // don't update more than once if dt==0.0
  942. const AZ::TimeUs curTime = AZ::GetLastSimulationTickTime();
  943. if (deltaTime == 0.0f && curTime == m_lastUpdateTime && !gEnv->IsEditor())
  944. {
  945. return;
  946. }
  947. m_lastUpdateTime = curTime;
  948. float fps = 60.0f;
  949. std::vector<IAnimSequence*> stopSequences;
  950. const size_t numPlayingSequences = m_playingSequences.size();
  951. for (size_t i = 0; i < numPlayingSequences; ++i)
  952. {
  953. PlayingSequence& playingSequence = m_playingSequences[i];
  954. if (playingSequence.sequence->IsPaused())
  955. {
  956. continue;
  957. }
  958. const float scaledTimeDelta = deltaTime * playingSequence.currentSpeed;
  959. // Increase play time in pre-update
  960. if (bPreUpdate)
  961. {
  962. playingSequence.currentTime += scaledTimeDelta;
  963. }
  964. // Skip sequence if current update does not apply
  965. const bool bSequenceEarlyUpdate = (playingSequence.sequence->GetFlags() & IAnimSequence::eSeqFlags_EarlyMovieUpdate) != 0;
  966. if ((bPreUpdate && !bSequenceEarlyUpdate ) || (!bPreUpdate && bSequenceEarlyUpdate)
  967. )
  968. {
  969. continue;
  970. }
  971. int nSeqFlags = playingSequence.sequence->GetFlags();
  972. if ((nSeqFlags& IAnimSequence::eSeqFlags_CutScene) && m_mov_NoCutscenes != 0)
  973. {
  974. // Don't play cut-scene if no cut scenes console variable set.
  975. stopSequences.push_back(playingSequence.sequence.get());
  976. continue;
  977. }
  978. animContext.time = playingSequence.currentTime;
  979. animContext.sequence = playingSequence.sequence.get();
  980. animContext.dt = scaledTimeDelta;
  981. animContext.fps = fps;
  982. animContext.startTime = playingSequence.startTime;
  983. // Check time out of range, setting up playingSequence for the next Update
  984. bool wasLooped = false;
  985. // Add a tolerance to this check because we want currentTime == currentTime to keep
  986. // animating so the last frame is animated. This comes into play with a fixed time step
  987. // like when capturing render output.
  988. const float precisionTolerance = 0.0001f;
  989. if ((playingSequence.currentTime - precisionTolerance) > playingSequence.endTime)
  990. {
  991. int seqFlags = playingSequence.sequence->GetFlags();
  992. bool isLoop = ((seqFlags& IAnimSequence::eSeqFlags_OutOfRangeLoop) != 0);
  993. bool isConstant = ((seqFlags& IAnimSequence::eSeqFlags_OutOfRangeConstant) != 0);
  994. if (m_bBatchRenderMode || (!isLoop && !isConstant))
  995. {
  996. // If we're batch rendering or no out-of-range type specified sequence stopped when time reaches end of range.
  997. // Queue sequence for stopping.
  998. if (playingSequence.trackedSequence == false)
  999. {
  1000. stopSequences.push_back(playingSequence.sequence.get());
  1001. }
  1002. continue;
  1003. }
  1004. // note we'll never get here if in batchRenderMode or if outOfRange is set to 'Once' (not loop or constant)
  1005. if (isLoop)
  1006. {
  1007. // Time wrap's back to the start of the time range.
  1008. playingSequence.currentTime = playingSequence.startTime; // should there be a fmodf here?
  1009. wasLooped = true;
  1010. }
  1011. // Time just continues normally past the end of time range for isConstant (nothing to do for isConstant)
  1012. }
  1013. else
  1014. {
  1015. NotifyListeners(playingSequence.sequence.get(), IMovieListener::eMovieEvent_Updated);
  1016. }
  1017. animContext.singleFrame = playingSequence.bSingleFrame;
  1018. playingSequence.bSingleFrame = false;
  1019. // Animate sequence. (Can invalidate iterator)
  1020. playingSequence.sequence->Animate(animContext);
  1021. // we call OnLoop() *after* Animate() to reset sounds (for CAnimSceneNodes), for the next update (the looped update)
  1022. if (wasLooped)
  1023. {
  1024. playingSequence.sequence->OnLoop();
  1025. }
  1026. }
  1027. #if !defined(_RELEASE)
  1028. if (m_mov_DebugEvents)
  1029. {
  1030. ShowPlayedSequencesDebug();
  1031. }
  1032. #endif //#if !defined(_RELEASE)
  1033. // Stop queued sequences.
  1034. for (int i = 0; i < (int)stopSequences.size(); i++)
  1035. {
  1036. StopSequence(stopSequences[i]);
  1037. }
  1038. }
  1039. //////////////////////////////////////////////////////////////////////////
  1040. void CMovieSystem::Render()
  1041. {
  1042. for (PlayingSequences::iterator it = m_playingSequences.begin(); it != m_playingSequences.end(); ++it)
  1043. {
  1044. PlayingSequence& playingSequence = *it;
  1045. playingSequence.sequence->Render();
  1046. }
  1047. }
  1048. //////////////////////////////////////////////////////////////////////////
  1049. void CMovieSystem::Callback(IMovieCallback::ECallbackReason reason, IAnimNode* pNode)
  1050. {
  1051. if (m_pCallback)
  1052. {
  1053. m_pCallback->OnMovieCallback(reason, pNode);
  1054. }
  1055. }
  1056. //////////////////////////////////////////////////////////////////////////
  1057. void CMovieSystem::Reflect(AZ::ReflectContext* context)
  1058. {
  1059. if (auto serializeContext = azrtti_cast<AZ::SerializeContext*>(context))
  1060. {
  1061. serializeContext->Class<CMovieSystem>()
  1062. ->Version(1)
  1063. ->Field("Sequences", &CMovieSystem::m_sequences);
  1064. }
  1065. AnimSerializer::ReflectAnimTypes(context);
  1066. }
  1067. //////////////////////////////////////////////////////////////////////////
  1068. void CMovieSystem::SetCameraParams(const SCameraParams& Params)
  1069. {
  1070. m_ActiveCameraParams = Params;
  1071. // Make sure the camera entity is valid
  1072. if (m_ActiveCameraParams.cameraEntityId.IsValid())
  1073. {
  1074. // Component Camera
  1075. AZ::Entity* entity = nullptr;
  1076. AZ::ComponentApplicationBus::BroadcastResult(entity, &AZ::ComponentApplicationBus::Events::FindEntity, m_ActiveCameraParams.cameraEntityId);
  1077. if (entity)
  1078. {
  1079. // Make sure the camera component was not removed from an entity that is used as a camera.
  1080. if (!(entity->FindComponent(CameraComponentTypeId) || entity->FindComponent(EditorCameraComponentTypeId)))
  1081. {
  1082. // if this entity does not have a camera component, do not use it.
  1083. m_ActiveCameraParams.cameraEntityId.SetInvalid();
  1084. }
  1085. }
  1086. }
  1087. if (m_pUser)
  1088. {
  1089. m_pUser->SetActiveCamera(m_ActiveCameraParams);
  1090. }
  1091. }
  1092. //////////////////////////////////////////////////////////////////////////
  1093. void CMovieSystem::SendGlobalEvent(const char* pszEvent)
  1094. {
  1095. if (m_pUser)
  1096. {
  1097. m_pUser->SendGlobalEvent(pszEvent);
  1098. }
  1099. }
  1100. //////////////////////////////////////////////////////////////////////////
  1101. void CMovieSystem::Pause()
  1102. {
  1103. m_bPaused = true;
  1104. }
  1105. //////////////////////////////////////////////////////////////////////////
  1106. void CMovieSystem::Resume()
  1107. {
  1108. m_bPaused = false;
  1109. }
  1110. //////////////////////////////////////////////////////////////////////////
  1111. void CMovieSystem::PauseCutScenes()
  1112. {
  1113. m_bCutscenesPausedInEditor = true;
  1114. if (m_pUser != nullptr)
  1115. {
  1116. for (PlayingSequences::iterator it = m_playingSequences.begin(); it != m_playingSequences.end(); ++it)
  1117. {
  1118. if (it->sequence->GetFlags() & IAnimSequence::eSeqFlags_CutScene)
  1119. {
  1120. m_pUser->EndCutScene(it->sequence.get(), it->sequence->GetCutSceneFlags(true));
  1121. }
  1122. }
  1123. }
  1124. }
  1125. //////////////////////////////////////////////////////////////////////////
  1126. void CMovieSystem::ResumeCutScenes()
  1127. {
  1128. if (m_mov_NoCutscenes != 0)
  1129. {
  1130. return;
  1131. }
  1132. m_bCutscenesPausedInEditor = false;
  1133. if (m_pUser != nullptr)
  1134. {
  1135. for (PlayingSequences::iterator it = m_playingSequences.begin(); it != m_playingSequences.end(); ++it)
  1136. {
  1137. if (it->sequence->GetFlags() & IAnimSequence::eSeqFlags_CutScene)
  1138. {
  1139. m_pUser->BeginCutScene(it->sequence.get(), it->sequence->GetCutSceneFlags(), true);
  1140. }
  1141. }
  1142. }
  1143. }
  1144. //////////////////////////////////////////////////////////////////////////
  1145. float CMovieSystem::GetPlayingTime(IAnimSequence* sequence)
  1146. {
  1147. if (!sequence || !IsPlaying(sequence))
  1148. {
  1149. return -1.0;
  1150. }
  1151. PlayingSequences::const_iterator it;
  1152. if (FindSequence(sequence, it))
  1153. {
  1154. return it->currentTime;
  1155. }
  1156. return -1.0f;
  1157. }
  1158. float CMovieSystem::GetPlayingSpeed(IAnimSequence* sequence)
  1159. {
  1160. if (!sequence || !IsPlaying(sequence))
  1161. {
  1162. return -1.0f;
  1163. }
  1164. PlayingSequences::const_iterator it;
  1165. if (FindSequence(sequence, it))
  1166. {
  1167. return it->currentSpeed;
  1168. }
  1169. return -1.0f;
  1170. }
  1171. bool CMovieSystem::SetPlayingTime(IAnimSequence* sequence, float fTime)
  1172. {
  1173. if (!sequence || !IsPlaying(sequence))
  1174. {
  1175. return false;
  1176. }
  1177. PlayingSequences::iterator it;
  1178. if (FindSequence(sequence, it) && !(sequence->GetFlags() & IAnimSequence::eSeqFlags_NoSeek))
  1179. {
  1180. it->currentTime = fTime;
  1181. it->bSingleFrame = true;
  1182. NotifyListeners(sequence, IMovieListener::eMovieEvent_Updated);
  1183. return true;
  1184. }
  1185. return false;
  1186. }
  1187. bool CMovieSystem::SetPlayingSpeed(IAnimSequence* sequence, float fSpeed)
  1188. {
  1189. if (!sequence)
  1190. {
  1191. return false;
  1192. }
  1193. PlayingSequences::iterator it;
  1194. if (FindSequence(sequence, it) && !(sequence->GetFlags() & IAnimSequence::eSeqFlags_NoSpeed))
  1195. {
  1196. NotifyListeners(sequence, IMovieListener::eMovieEvent_Updated);
  1197. it->currentSpeed = fSpeed;
  1198. return true;
  1199. }
  1200. return false;
  1201. }
  1202. bool CMovieSystem::GetStartEndTime(IAnimSequence* sequence, float& fStartTime, float& fEndTime)
  1203. {
  1204. fStartTime = 0.0f;
  1205. fEndTime = 0.0f;
  1206. if (!sequence || !IsPlaying(sequence))
  1207. {
  1208. return false;
  1209. }
  1210. PlayingSequences::const_iterator it;
  1211. if (FindSequence(sequence, it))
  1212. {
  1213. fStartTime = it->startTime;
  1214. fEndTime = it->endTime;
  1215. return true;
  1216. }
  1217. return false;
  1218. }
  1219. bool CMovieSystem::SetStartEndTime(IAnimSequence* pSeq, const float fStartTime, const float fEndTime)
  1220. {
  1221. if (!pSeq || !IsPlaying(pSeq))
  1222. {
  1223. return false;
  1224. }
  1225. PlayingSequences::iterator it;
  1226. if (FindSequence(pSeq, it))
  1227. {
  1228. it->startTime = fStartTime;
  1229. it->endTime = fEndTime;
  1230. return true;
  1231. }
  1232. return false;
  1233. }
  1234. void CMovieSystem::SetSequenceStopBehavior(ESequenceStopBehavior behavior)
  1235. {
  1236. m_sequenceStopBehavior = behavior;
  1237. }
  1238. IMovieSystem::ESequenceStopBehavior CMovieSystem::GetSequenceStopBehavior()
  1239. {
  1240. return m_sequenceStopBehavior;
  1241. }
  1242. bool CMovieSystem::AddMovieListener(IAnimSequence* sequence, IMovieListener* pListener)
  1243. {
  1244. assert (pListener != 0);
  1245. if (sequence != NULL && std::find(m_sequences.begin(), m_sequences.end(), sequence) == m_sequences.end())
  1246. {
  1247. gEnv->pLog->Log ("CMovieSystem::AddMovieListener: Sequence %p unknown to CMovieSystem", sequence);
  1248. return false;
  1249. }
  1250. return stl::push_back_unique(m_movieListenerMap[sequence], pListener);
  1251. }
  1252. bool CMovieSystem::RemoveMovieListener(IAnimSequence* sequence, IMovieListener* pListener)
  1253. {
  1254. assert (pListener != 0);
  1255. if (sequence != NULL
  1256. && std::find(m_sequences.begin(), m_sequences.end(), sequence) == m_sequences.end())
  1257. {
  1258. gEnv->pLog->Log ("CMovieSystem::AddMovieListener: Sequence %p unknown to CMovieSystem", sequence);
  1259. return false;
  1260. }
  1261. return stl::find_and_erase(m_movieListenerMap[sequence], pListener);
  1262. }
  1263. #if !defined(_RELEASE)
  1264. void CMovieSystem::GoToFrameCmd(IConsoleCmdArgs* pArgs)
  1265. {
  1266. if (pArgs->GetArgCount() < 3)
  1267. {
  1268. gEnv->pLog->LogError("GoToFrame failed! You should provide two arguments of 'sequence name' & 'frame time'.");
  1269. return;
  1270. }
  1271. // Console commands are always interpreted in the culture invariant locale because
  1272. // they often come from files (as in, .cfg files) which need to be portable. We set the scoped locale
  1273. // to the invariant locale here so that atof() functions in that locale regardless of app locale.
  1274. AZ::Locale::ScopedSerializationLocale scopedLocale;
  1275. const char* pSeqName = pArgs->GetArg(1);
  1276. float targetFrame = (float)atof(pArgs->GetArg(2));
  1277. IMovieSystem* movieSystem = AZ::Interface<IMovieSystem>::Get();
  1278. (static_cast<CMovieSystem*>(movieSystem))->GoToFrame(pSeqName, targetFrame);
  1279. }
  1280. #endif //#if !defined(_RELEASE)
  1281. #if !defined(_RELEASE)
  1282. void CMovieSystem::ListSequencesCmd([[maybe_unused]] IConsoleCmdArgs* pArgs)
  1283. {
  1284. IMovieSystem* movieSystem = AZ::Interface<IMovieSystem>::Get();
  1285. if (movieSystem)
  1286. {
  1287. int numSequences = movieSystem->GetNumSequences();
  1288. for (int i = 0; i < numSequences; i++)
  1289. {
  1290. IAnimSequence* pSeq = movieSystem->GetSequence(i);
  1291. if (pSeq)
  1292. {
  1293. CryLogAlways("%s", pSeq->GetName());
  1294. }
  1295. }
  1296. }
  1297. }
  1298. #endif //#if !defined(_RELEASE)
  1299. #if !defined(_RELEASE)
  1300. void CMovieSystem::PlaySequencesCmd(IConsoleCmdArgs* pArgs)
  1301. {
  1302. const char* sequenceName = pArgs->GetArg(1);
  1303. IMovieSystem* movieSystem = AZ::Interface<IMovieSystem>::Get();
  1304. if (movieSystem)
  1305. {
  1306. movieSystem->PlaySequence(sequenceName, nullptr, false, false);
  1307. }
  1308. }
  1309. #endif //#if !defined(_RELEASE)
  1310. void CMovieSystem::GoToFrame(const char* seqName, float targetFrame)
  1311. {
  1312. AZ::Locale::ScopedSerializationLocale scopedLocale; // Ensures that %f uses "." as decimal separator
  1313. assert(seqName != NULL);
  1314. if (gEnv->IsEditor() && gEnv->IsEditorGameMode() == false)
  1315. {
  1316. AZStd::string editorCmd = AZStd::string::format("mov_goToFrameEditor %s %f", seqName, targetFrame);
  1317. gEnv->pConsole->ExecuteString(editorCmd.c_str());
  1318. return;
  1319. }
  1320. for (PlayingSequences::iterator it = m_playingSequences.begin();
  1321. it != m_playingSequences.end(); ++it)
  1322. {
  1323. PlayingSequence& ps = *it;
  1324. const char* fullname = ps.sequence->GetName();
  1325. if (strcmp(fullname, seqName) == 0)
  1326. {
  1327. assert(ps.sequence->GetTimeRange().start <= targetFrame && targetFrame <= ps.sequence->GetTimeRange().end);
  1328. ps.currentTime = targetFrame;
  1329. ps.bSingleFrame = true;
  1330. break;
  1331. }
  1332. }
  1333. }
  1334. void CMovieSystem::EnableFixedStepForCapture(float step)
  1335. {
  1336. if (auto* timeSystem = AZ::Interface<AZ::ITime>::Get())
  1337. {
  1338. m_fixedTimeStepBackUp = timeSystem->GetSimulationTickDeltaOverride();
  1339. timeSystem->SetSimulationTickDeltaOverride(AZ::SecondsToTimeUs(step));
  1340. }
  1341. if (nullptr == m_cvar_sys_maxTimeStepForMovieSystem)
  1342. {
  1343. m_cvar_sys_maxTimeStepForMovieSystem = gEnv->pConsole->GetCVar("sys_maxTimeStepForMovieSystem");
  1344. }
  1345. // Make sure the max step for the movie system is big enough
  1346. m_maxTimeStepForMovieSystemBackUp = m_cvar_sys_maxTimeStepForMovieSystem->GetFVal();
  1347. if (step > m_maxTimeStepForMovieSystemBackUp)
  1348. {
  1349. m_cvar_sys_maxTimeStepForMovieSystem->Set(step);
  1350. }
  1351. }
  1352. void CMovieSystem::DisableFixedStepForCapture()
  1353. {
  1354. if (auto* timeSystem = AZ::Interface<AZ::ITime>::Get())
  1355. {
  1356. timeSystem->SetSimulationTickDeltaOverride(m_fixedTimeStepBackUp);
  1357. }
  1358. m_cvar_sys_maxTimeStepForMovieSystem->Set(m_maxTimeStepForMovieSystemBackUp);
  1359. }
  1360. void CMovieSystem::StartCapture(const ICaptureKey& key, int frame)
  1361. {
  1362. m_bStartCapture = true;
  1363. m_captureKey = key;
  1364. m_captureFrame = frame;
  1365. }
  1366. void CMovieSystem::EndCapture()
  1367. {
  1368. m_bEndCapture = true;
  1369. }
  1370. void CMovieSystem::CheckForEndCapture()
  1371. {
  1372. if (m_bEndCapture)
  1373. {
  1374. m_captureFrame = -1;
  1375. m_cvar_capture_frames->Set(0);
  1376. m_bEndCapture = false;
  1377. }
  1378. }
  1379. void CMovieSystem::ControlCapture()
  1380. {
  1381. #if !defined(NDEBUG)
  1382. bool bBothStartAndEnd = m_bStartCapture && m_bEndCapture;
  1383. assert(!bBothStartAndEnd);
  1384. #endif
  1385. bool bAllCVarsReady
  1386. = m_cvar_capture_frame_once && m_cvar_capture_folder && m_cvar_capture_frames;
  1387. if (!bAllCVarsReady)
  1388. {
  1389. m_cvar_capture_frame_once = gEnv->pConsole->GetCVar("capture_frame_once");
  1390. m_cvar_capture_folder = gEnv->pConsole->GetCVar("capture_folder");
  1391. m_cvar_capture_frames = gEnv->pConsole->GetCVar("capture_frames");
  1392. m_cvar_capture_file_prefix = gEnv->pConsole->GetCVar("capture_file_prefix");
  1393. }
  1394. bAllCVarsReady
  1395. = m_cvar_capture_frame_once
  1396. && m_cvar_capture_folder && m_cvar_capture_frames
  1397. && m_cvar_capture_file_prefix;
  1398. assert(bAllCVarsReady);
  1399. if (!bAllCVarsReady)
  1400. {
  1401. m_bStartCapture = m_bEndCapture = false;
  1402. return;
  1403. }
  1404. if (m_bStartCapture)
  1405. {
  1406. m_cvar_capture_frame_once->Set(m_captureKey.once ? 1 : 0);
  1407. m_cvar_capture_folder->Set(m_captureKey.folder.c_str());
  1408. m_cvar_capture_file_prefix->Set(m_captureKey.prefix.c_str());
  1409. // one-based frame number, zero disables capture.
  1410. m_cvar_capture_frames->Set(1 + m_captureFrame);
  1411. m_bStartCapture = false;
  1412. }
  1413. CheckForEndCapture();
  1414. }
  1415. //////////////////////////////////////////////////////////////////////////
  1416. bool CMovieSystem::IsCapturing() const
  1417. {
  1418. return m_cvar_capture_frames ? m_cvar_capture_frames->GetIVal() != 0 : false;
  1419. }
  1420. //////////////////////////////////////////////////////////////////////////
  1421. void CMovieSystem::SerializeNodeType(AnimNodeType& animNodeType, XmlNodeRef& xmlNode, bool bLoading, const uint version, int flags)
  1422. {
  1423. static const char* kType = "Type";
  1424. if (bLoading)
  1425. {
  1426. // Old serialization values that are no longer
  1427. // defined in IMovieSystem.h, but needed for conversion:
  1428. static const int kOldParticleNodeType = 0x18;
  1429. animNodeType = AnimNodeType::Invalid;
  1430. // In old versions there was special code for particles
  1431. // that is now handles by generic entity node code
  1432. if (version == 0 && static_cast<int>(animNodeType) == kOldParticleNodeType)
  1433. {
  1434. animNodeType = AnimNodeType::Entity;
  1435. return;
  1436. }
  1437. // Convert light nodes that are not part of a light
  1438. // animation set to common entity nodes
  1439. if (version <= 1 && animNodeType == AnimNodeType::Light && !(flags & IAnimSequence::eSeqFlags_LightAnimationSet))
  1440. {
  1441. animNodeType = AnimNodeType::Entity;
  1442. return;
  1443. }
  1444. if (version <= 2)
  1445. {
  1446. int type;
  1447. if (xmlNode->getAttr(kType, type))
  1448. {
  1449. animNodeType = (AnimNodeType)type;
  1450. }
  1451. return;
  1452. }
  1453. else
  1454. {
  1455. XmlString nodeTypeString;
  1456. if (xmlNode->getAttr(kType, nodeTypeString))
  1457. {
  1458. assert(m_animNodeStringToEnumMap.find(nodeTypeString.c_str()) != m_animNodeStringToEnumMap.end());
  1459. animNodeType = stl::find_in_map(m_animNodeStringToEnumMap, nodeTypeString.c_str(), AnimNodeType::Invalid);
  1460. }
  1461. }
  1462. }
  1463. else
  1464. {
  1465. const char* pTypeString = "Invalid";
  1466. assert(m_animNodeEnumToStringMap.find(animNodeType) != m_animNodeEnumToStringMap.end());
  1467. pTypeString = m_animNodeEnumToStringMap[animNodeType].c_str();
  1468. xmlNode->setAttr(kType, pTypeString);
  1469. }
  1470. }
  1471. namespace CAnimParamTypeXmlNames
  1472. {
  1473. static const char* kParamUserValue = "paramUserValue";
  1474. static const char* kVirtualPropertyName = "virtualPropertyName";
  1475. }
  1476. //////////////////////////////////////////////////////////////////////////
  1477. void CMovieSystem::LoadParamTypeFromXml(CAnimParamType& animParamType, const XmlNodeRef& xmlNode, const uint version)
  1478. {
  1479. static const char* kByNameAttrName = "paramIdIsName";
  1480. animParamType.m_type = AnimParamType::Invalid;
  1481. if (version <= 6)
  1482. {
  1483. static const char* kParamId = "paramId";
  1484. if (xmlNode->haveAttr(kByNameAttrName))
  1485. {
  1486. XmlString name;
  1487. if (xmlNode->getAttr(kParamId, name))
  1488. {
  1489. animParamType.m_type = AnimParamType::ByString;
  1490. animParamType.m_name = name.c_str();
  1491. }
  1492. }
  1493. else
  1494. {
  1495. int type;
  1496. xmlNode->getAttr(kParamId, type);
  1497. animParamType.m_type = (AnimParamType)type;
  1498. }
  1499. }
  1500. else
  1501. {
  1502. static const char* kParamType = "paramType";
  1503. XmlString paramTypeString;
  1504. if (xmlNode->getAttr(kParamType, paramTypeString))
  1505. {
  1506. if (paramTypeString == "ByString")
  1507. {
  1508. animParamType.m_type = AnimParamType::ByString;
  1509. XmlString userValue;
  1510. xmlNode->getAttr(CAnimParamTypeXmlNames::kParamUserValue, userValue);
  1511. animParamType.m_name = userValue;
  1512. }
  1513. else if (paramTypeString == "User")
  1514. {
  1515. animParamType.m_type = AnimParamType::User;
  1516. int type;
  1517. xmlNode->getAttr(CAnimParamTypeXmlNames::kParamUserValue, type);
  1518. animParamType.m_type = (AnimParamType)type;
  1519. }
  1520. else
  1521. {
  1522. XmlString virtualPropertyValue;
  1523. if (xmlNode->getAttr(CAnimParamTypeXmlNames::kVirtualPropertyName, virtualPropertyValue))
  1524. {
  1525. animParamType.m_name = virtualPropertyValue;
  1526. }
  1527. assert(m_animParamStringToEnumMap.find(paramTypeString.c_str()) != m_animParamStringToEnumMap.end());
  1528. animParamType.m_type = stl::find_in_map(m_animParamStringToEnumMap, paramTypeString.c_str(), AnimParamType::Invalid);
  1529. }
  1530. }
  1531. }
  1532. }
  1533. //////////////////////////////////////////////////////////////////////////
  1534. void CMovieSystem::SaveParamTypeToXml(const CAnimParamType& animParamType, XmlNodeRef& xmlNode)
  1535. {
  1536. static const char* kParamType = "paramType";
  1537. const char* pTypeString = "Invalid";
  1538. if (animParamType.m_type == AnimParamType::ByString)
  1539. {
  1540. pTypeString = "ByString";
  1541. xmlNode->setAttr(CAnimParamTypeXmlNames::kParamUserValue, animParamType.m_name.c_str());
  1542. }
  1543. else if (animParamType.m_type >= AnimParamType::User)
  1544. {
  1545. pTypeString = "User";
  1546. xmlNode->setAttr(CAnimParamTypeXmlNames::kParamUserValue, (int)animParamType.m_type);
  1547. }
  1548. else
  1549. {
  1550. if (!animParamType.m_name.empty())
  1551. {
  1552. // we have a named parameter that is NOT an AnimParamType::ByString (handled above). This is used for VirtualProperty names for Component Entities.
  1553. xmlNode->setAttr(CAnimParamTypeXmlNames::kVirtualPropertyName, animParamType.m_name.c_str());
  1554. }
  1555. assert(m_animParamEnumToStringMap.find(animParamType.m_type) != m_animParamEnumToStringMap.end());
  1556. pTypeString = m_animParamEnumToStringMap[animParamType.m_type].c_str();
  1557. }
  1558. xmlNode->setAttr(kParamType, pTypeString);
  1559. }
  1560. //////////////////////////////////////////////////////////////////////////
  1561. void CMovieSystem::SerializeParamType(CAnimParamType& animParamType, XmlNodeRef& xmlNode, bool bLoading, const uint version)
  1562. {
  1563. if (bLoading)
  1564. {
  1565. LoadParamTypeFromXml(animParamType, xmlNode, version);
  1566. }
  1567. else
  1568. {
  1569. SaveParamTypeToXml(animParamType, xmlNode);
  1570. }
  1571. }
  1572. //////////////////////////////////////////////////////////////////////////
  1573. const char* CMovieSystem::GetParamTypeName(const CAnimParamType& animParamType)
  1574. {
  1575. if (animParamType.m_type == AnimParamType::ByString)
  1576. {
  1577. return animParamType.GetName();
  1578. }
  1579. else if (animParamType.m_type >= AnimParamType::User)
  1580. {
  1581. return "User";
  1582. }
  1583. else
  1584. {
  1585. if (m_animParamEnumToStringMap.contains(animParamType.m_type))
  1586. {
  1587. return m_animParamEnumToStringMap[animParamType.m_type].c_str();
  1588. }
  1589. }
  1590. return "Invalid";
  1591. }
  1592. //////////////////////////////////////////////////////////////////////////
  1593. void CMovieSystem::OnCameraCut()
  1594. {
  1595. }
  1596. void CMovieSystem::LogUserNotificationMsg([[maybe_unused]] const AZStd::string& msg)
  1597. {
  1598. #if !defined(_RELEASE)
  1599. if (!m_notificationLogMsgs.empty())
  1600. {
  1601. m_notificationLogMsgs.append("\n");
  1602. }
  1603. m_notificationLogMsgs.append(msg);
  1604. #endif
  1605. AZ_Warning("TrackView", false, "%s", msg.c_str());
  1606. }
  1607. void CMovieSystem::ClearUserNotificationMsgs()
  1608. {
  1609. #if !defined(_RELEASE)
  1610. m_notificationLogMsgs.clear();
  1611. #endif
  1612. }
  1613. const AZStd::string& CMovieSystem::GetUserNotificationMsgs() const
  1614. {
  1615. #if !defined(_RELEASE)
  1616. return m_notificationLogMsgs;
  1617. #else
  1618. static AZStd::string emptyMsg;
  1619. return emptyMsg;
  1620. #endif
  1621. }
  1622. //////////////////////////////////////////////////////////////////////////
  1623. void CMovieSystem::OnSequenceActivated(IAnimSequence* sequence)
  1624. {
  1625. // Queue for processing, sequences will be removed after checked for auto start.
  1626. m_newlyActivatedSequences.push_back(sequence);
  1627. }
  1628. #ifdef MOVIESYSTEM_SUPPORT_EDITING
  1629. //////////////////////////////////////////////////////////////////////////
  1630. AnimNodeType CMovieSystem::GetNodeTypeFromString(const char* pString) const
  1631. {
  1632. return stl::find_in_map(m_animNodeStringToEnumMap, pString, AnimNodeType::Invalid);
  1633. }
  1634. //////////////////////////////////////////////////////////////////////////
  1635. CAnimParamType CMovieSystem::GetParamTypeFromString(const char* pString) const
  1636. {
  1637. const AnimParamType paramType = stl::find_in_map(m_animParamStringToEnumMap, pString, AnimParamType::Invalid);
  1638. if (paramType != AnimParamType::Invalid)
  1639. {
  1640. return CAnimParamType(paramType);
  1641. }
  1642. return CAnimParamType(pString);
  1643. }
  1644. #endif