3
0

AnimComponentNode.cpp 49 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058
  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 "AnimComponentNode.h"
  9. #include <AzCore/Component/TransformBus.h>
  10. #include <AzCore/Math/Color.h>
  11. #include <AzCore/Serialization/SerializeContext.h>
  12. #include <AzFramework/Components/TransformComponent.h>
  13. #include <Maestro/Bus/EditorSequenceComponentBus.h>
  14. #include <Maestro/Bus/SequenceComponentBus.h>
  15. #include <Maestro/Types/AnimNodeType.h>
  16. #include <Maestro/Types/AnimValueType.h>
  17. #include <Maestro/Types/AnimParamType.h>
  18. #include <Maestro/Types/AssetBlends.h>
  19. #include "CharacterTrack.h"
  20. CAnimComponentNode::CAnimComponentNode(int id)
  21. : CAnimNode(id, AnimNodeType::Component)
  22. , m_componentTypeId(AZ::Uuid::CreateNull())
  23. , m_componentId(AZ::InvalidComponentId)
  24. , m_skipComponentAnimationUpdates(false)
  25. {
  26. }
  27. CAnimComponentNode::CAnimComponentNode()
  28. : CAnimComponentNode(0)
  29. {
  30. }
  31. CAnimComponentNode::~CAnimComponentNode()
  32. {
  33. if (m_characterTrackAnimator)
  34. {
  35. delete m_characterTrackAnimator;
  36. m_characterTrackAnimator = nullptr;
  37. }
  38. }
  39. void CAnimComponentNode::OnStart()
  40. {
  41. }
  42. void CAnimComponentNode::OnResume()
  43. {
  44. }
  45. //////////////////////////////////////////////////////////////////////////
  46. void CAnimComponentNode::OnReset()
  47. {
  48. // OnReset is called when sequences are loaded
  49. if (m_characterTrackAnimator)
  50. {
  51. m_characterTrackAnimator->OnReset(this);
  52. }
  53. UpdateDynamicParams();
  54. }
  55. //////////////////////////////////////////////////////////////////////////
  56. void CAnimComponentNode::OnResetHard()
  57. {
  58. OnReset();
  59. if (m_pOwner)
  60. {
  61. m_pOwner->OnNodeReset(this);
  62. }
  63. }
  64. //////////////////////////////////////////////////////////////////////////
  65. CAnimParamType CAnimComponentNode::GetParamType(unsigned int nIndex) const
  66. {
  67. (void)nIndex;
  68. return AnimParamType::Invalid;
  69. };
  70. //////////////////////////////////////////////////////////////////////////
  71. void CAnimComponentNode::SetComponent(AZ::ComponentId componentId, const AZ::Uuid& componentTypeId)
  72. {
  73. m_componentId = componentId;
  74. m_componentTypeId = componentTypeId;
  75. // call OnReset() to update dynamic params
  76. // (i.e. virtual properties from the exposed EBuses from the BehaviorContext)
  77. OnReset();
  78. }
  79. //////////////////////////////////////////////////////////////////////////
  80. bool CAnimComponentNode::GetParamInfoFromType(const CAnimParamType& paramId, SParamInfo& info) const
  81. {
  82. auto findIter = m_paramTypeToBehaviorPropertyInfoMap.find(paramId);
  83. if (findIter != m_paramTypeToBehaviorPropertyInfoMap.end())
  84. {
  85. info = findIter->second.m_animNodeParamInfo;
  86. return true;
  87. }
  88. return false;
  89. }
  90. //////////////////////////////////////////////////////////////////////////
  91. bool CAnimComponentNode::SetTrackMultiplier(IAnimTrack* track) const
  92. {
  93. bool trackMultiplierWasSet = false;
  94. CAnimParamType paramType(track->GetParameterType());
  95. if (paramType.GetType() == AnimParamType::ByString)
  96. {
  97. // check to see if we need to use a track multiplier
  98. // Get Property TypeId
  99. Maestro::SequenceComponentRequests::AnimatablePropertyAddress propertyAddress(m_componentId, paramType.GetName());
  100. AZ::Uuid propertyTypeId = AZ::Uuid::CreateNull();
  101. Maestro::SequenceComponentRequestBus::EventResult(propertyTypeId, m_pSequence->GetSequenceEntityId(), &Maestro::SequenceComponentRequestBus::Events::GetAnimatedAddressTypeId,
  102. GetParentAzEntityId(), propertyAddress);
  103. if (propertyTypeId == AZ::Color::TYPEINFO_Uuid())
  104. {
  105. track->SetMultiplier(255.0f);
  106. trackMultiplierWasSet = true;
  107. }
  108. }
  109. return trackMultiplierWasSet;
  110. }
  111. int CAnimComponentNode::SetKeysForChangedBoolTrackValue(IAnimTrack* track, int keyIdx, float time)
  112. {
  113. int retNumKeysSet = 0;
  114. bool currTrackValue;
  115. track->GetValue(time, currTrackValue);
  116. Maestro::SequenceComponentRequests::AnimatedBoolValue currValue(currTrackValue);
  117. Maestro::SequenceComponentRequests::AnimatablePropertyAddress animatableAddress(m_componentId, track->GetParameterType().GetName());
  118. Maestro::SequenceComponentRequestBus::Event(m_pSequence->GetSequenceEntityId(), &Maestro::SequenceComponentRequestBus::Events::GetAnimatedPropertyValue, currValue, GetParentAzEntityId(), animatableAddress);
  119. if (currTrackValue != currValue.GetBoolValue())
  120. {
  121. keyIdx = track->FindKey(time);
  122. if (keyIdx == -1)
  123. {
  124. keyIdx = track->CreateKey(time);
  125. }
  126. // no need to set a value of a Bool key - it's existence implies a Boolean toggle.
  127. retNumKeysSet++;
  128. }
  129. return retNumKeysSet;
  130. }
  131. int CAnimComponentNode::SetKeysForChangedFloatTrackValue(IAnimTrack* track, int keyIdx, float time)
  132. {
  133. int retNumKeysSet = 0;
  134. float currTrackValue;
  135. track->GetValue(time, currTrackValue);
  136. Maestro::SequenceComponentRequests::AnimatedFloatValue currValue(currTrackValue);
  137. Maestro::SequenceComponentRequests::AnimatablePropertyAddress animatableAddress(m_componentId, track->GetParameterType().GetName());
  138. Maestro::SequenceComponentRequestBus::Event(m_pSequence->GetSequenceEntityId(), &Maestro::SequenceComponentRequestBus::Events::GetAnimatedPropertyValue, currValue, GetParentAzEntityId(), animatableAddress);
  139. if (currTrackValue != currValue.GetFloatValue())
  140. {
  141. keyIdx = track->FindKey(time);
  142. if (keyIdx == -1)
  143. {
  144. keyIdx = track->CreateKey(time);
  145. }
  146. if (track->GetValueType() == AnimValueType::DiscreteFloat)
  147. {
  148. IDiscreteFloatKey key;
  149. track->GetKey(keyIdx, &key);
  150. key.SetValue(currValue.GetFloatValue());
  151. }
  152. else
  153. {
  154. I2DBezierKey key;
  155. track->GetKey(keyIdx, &key);
  156. key.value.y = currValue.GetFloatValue();
  157. track->SetKey(keyIdx, &key);
  158. }
  159. retNumKeysSet++;
  160. }
  161. return retNumKeysSet;
  162. }
  163. int CAnimComponentNode::SetKeysForChangedVector3TrackValue(IAnimTrack* track, [[maybe_unused]] int keyIdx, float time, bool applyTrackMultiplier, float isChangedTolerance)
  164. {
  165. int retNumKeysSet = 0;
  166. AZ::Vector3 currTrackValue;
  167. track->GetValue(time, currTrackValue, applyTrackMultiplier);
  168. Maestro::SequenceComponentRequests::AnimatedVector3Value currValue(currTrackValue);
  169. Maestro::SequenceComponentRequests::AnimatablePropertyAddress animatableAddress(m_componentId, track->GetParameterType().GetName());
  170. Maestro::SequenceComponentRequestBus::Event(m_pSequence->GetSequenceEntityId(), &Maestro::SequenceComponentRequestBus::Events::GetAnimatedPropertyValue, currValue, GetParentAzEntityId(), animatableAddress);
  171. AZ::Vector3 currVector3Value;
  172. currValue.GetValue(currVector3Value);
  173. if (!currTrackValue.IsClose(currVector3Value, isChangedTolerance))
  174. {
  175. // track will be a CCompoundSplineTrack. For these we can simply call SetValue at the and keys will be added if needed.
  176. track->SetValue(time, currVector3Value, false, applyTrackMultiplier);
  177. retNumKeysSet++; // we treat the compound vector as a single key for simplicity and speed - if needed, we can go through each component and count them up if this is important.
  178. }
  179. return retNumKeysSet;
  180. }
  181. int CAnimComponentNode::SetKeysForChangedQuaternionTrackValue(IAnimTrack* track, [[maybe_unused]] int keyIdx, float time)
  182. {
  183. int retNumKeysSet = 0;
  184. AZ::Quaternion currTrackValue;
  185. track->GetValue(time, currTrackValue);
  186. Maestro::SequenceComponentRequests::AnimatedQuaternionValue currValue(currTrackValue);
  187. Maestro::SequenceComponentRequests::AnimatablePropertyAddress animatableAddress(m_componentId, track->GetParameterType().GetName());
  188. Maestro::SequenceComponentRequestBus::Event(m_pSequence->GetSequenceEntityId(), &Maestro::SequenceComponentRequestBus::Events::GetAnimatedPropertyValue, currValue, GetParentAzEntityId(), animatableAddress);
  189. AZ::Quaternion currQuaternionValue;
  190. currValue.GetValue(currQuaternionValue);
  191. if (!currTrackValue.IsClose(currQuaternionValue))
  192. {
  193. // track will be a CCompoundSplineTrack. For these we can simply call SetValue at the and keys will be added if needed.
  194. track->SetValue(time, currQuaternionValue, false);
  195. retNumKeysSet++; // we treat the compound vector as a single key for simplicity and speed - if needed, we can go through each component and count them up if this is important.
  196. }
  197. return retNumKeysSet;
  198. }
  199. //////////////////////////////////////////////////////////////////////////
  200. int CAnimComponentNode::SetKeysForChangedTrackValues(float time)
  201. {
  202. int retNumKeysSet = 0;
  203. for (int i = GetTrackCount(); --i >= 0;)
  204. {
  205. IAnimTrack* track = GetTrackByIndex(i);
  206. int keyIdx = -1;
  207. switch (track->GetValueType())
  208. {
  209. case AnimValueType::Bool:
  210. retNumKeysSet += SetKeysForChangedBoolTrackValue(track, keyIdx, time);
  211. break;
  212. case AnimValueType::Float:
  213. case AnimValueType::DiscreteFloat:
  214. retNumKeysSet += SetKeysForChangedFloatTrackValue(track, keyIdx, time);
  215. break;
  216. case AnimValueType::RGB:
  217. retNumKeysSet += SetKeysForChangedVector3TrackValue(track, keyIdx, time, true, (1.0f) / 255.0f);
  218. break;
  219. case AnimValueType::Vector:
  220. retNumKeysSet += SetKeysForChangedVector3TrackValue(track, keyIdx, time, true);
  221. break;
  222. case AnimValueType::Quat:
  223. retNumKeysSet += SetKeysForChangedQuaternionTrackValue(track, keyIdx, time);
  224. break;
  225. case AnimValueType::Vector4:
  226. AZ_Warning("TrackView", false, "Vector4's are not supported for recording.");
  227. break;
  228. }
  229. }
  230. return retNumKeysSet;
  231. }
  232. //////////////////////////////////////////////////////////////////////////
  233. void CAnimComponentNode::OnStartPlayInEditor()
  234. {
  235. // reset key states for entering AI/Physics SIM mode
  236. ForceAnimKeyChangeInCharacterTrackAnimator();
  237. }
  238. void CAnimComponentNode::OnStopPlayInEditor()
  239. {
  240. // reset key states for returning to Editor mode
  241. ForceAnimKeyChangeInCharacterTrackAnimator();
  242. }
  243. void CAnimComponentNode::SetNodeOwner(IAnimNodeOwner* pOwner)
  244. {
  245. CAnimNode::SetNodeOwner(pOwner);
  246. if (pOwner && gEnv->IsEditor())
  247. {
  248. // SetNodeOwner is called when a node is added on undo/redo - we have to update dynamic params in such a case
  249. UpdateDynamicParams();
  250. }
  251. }
  252. //////////////////////////////////////////////////////////////////////////
  253. void CAnimComponentNode::GetParentWorldTransform(AZ::Transform& retTransform) const
  254. {
  255. AZ::EntityId parentId;
  256. AZ::TransformBus::EventResult(parentId, GetParentAzEntityId(), &AZ::TransformBus::Events::GetParentId);
  257. if (parentId.IsValid())
  258. {
  259. AZ::TransformBus::EventResult(retTransform, parentId, &AZ::TransformBus::Events::GetWorldTM);
  260. }
  261. }
  262. //////////////////////////////////////////////////////////////////////////
  263. void CAnimComponentNode::ConvertBetweenWorldAndLocalPosition(Vec3& position, ETransformSpaceConversionDirection conversionDirection) const
  264. {
  265. AZ::Vector3 pos(position.x, position.y, position.z);
  266. AZ::Transform parentTransform = AZ::Transform::Identity();
  267. GetParentWorldTransform(parentTransform);
  268. if (conversionDirection == eTransformConverstionDirection_toLocalSpace)
  269. {
  270. parentTransform.Invert();
  271. }
  272. pos = parentTransform.TransformPoint(pos);
  273. position.Set(pos.GetX(), pos.GetY(), pos.GetZ());
  274. }
  275. //////////////////////////////////////////////////////////////////////////
  276. void CAnimComponentNode::ConvertBetweenWorldAndLocalRotation(Quat& rotation, ETransformSpaceConversionDirection conversionDirection) const
  277. {
  278. AZ::Quaternion rot(rotation.v.x, rotation.v.y, rotation.v.z, rotation.w);
  279. AZ::Transform rotTransform = AZ::Transform::CreateFromQuaternion(rot);
  280. rotTransform.ExtractUniformScale();
  281. AZ::Transform parentTransform = AZ::Transform::Identity();
  282. GetParentWorldTransform(parentTransform);
  283. parentTransform.ExtractUniformScale();
  284. if (conversionDirection == eTransformConverstionDirection_toLocalSpace)
  285. {
  286. parentTransform.Invert();
  287. }
  288. rotTransform = parentTransform * rotTransform;
  289. rot = rotTransform.GetRotation();
  290. rotation = Quat(rot);
  291. }
  292. //////////////////////////////////////////////////////////////////////////
  293. void CAnimComponentNode::ConvertBetweenWorldAndLocalScale(Vec3& scale, ETransformSpaceConversionDirection conversionDirection) const
  294. {
  295. AZ::Transform parentTransform = AZ::Transform::Identity();
  296. AZ::Transform scaleTransform = AZ::Transform::CreateUniformScale(AZ::Vector3(scale.x, scale.y, scale.z).GetMaxElement());
  297. GetParentWorldTransform(parentTransform);
  298. if (conversionDirection == eTransformConverstionDirection_toLocalSpace)
  299. {
  300. parentTransform.Invert();
  301. }
  302. scaleTransform = parentTransform * scaleTransform;
  303. const float uniformScale = scaleTransform.GetUniformScale();
  304. scale.Set(uniformScale, uniformScale, uniformScale);
  305. }
  306. //////////////////////////////////////////////////////////////////////////
  307. void CAnimComponentNode::SetPos(float time, const Vec3& pos)
  308. {
  309. if (m_componentTypeId == AZ::Uuid(AZ::EditorTransformComponentTypeId) || m_componentTypeId == AzFramework::TransformComponent::TYPEINFO_Uuid())
  310. {
  311. bool bDefault = !(gEnv->pMovieSystem->IsRecording() && (GetParent()->GetFlags() & eAnimNodeFlags_EntitySelected)); // Only selected nodes can be recorded
  312. IAnimTrack* posTrack = GetTrackForParameter(AnimParamType::Position);
  313. if (posTrack)
  314. {
  315. // pos is in world position, even if the entity is parented - because Component Entity AZ::Transforms do not correctly set
  316. // CBaseObject parenting. This should probably be fixed, but for now, we explicitly change from World to Local space here
  317. Vec3 localPos(pos);
  318. ConvertBetweenWorldAndLocalPosition(localPos, eTransformConverstionDirection_toLocalSpace);
  319. posTrack->SetValue(time, localPos, bDefault);
  320. }
  321. if (!bDefault)
  322. {
  323. GetCMovieSystem()->Callback(IMovieCallback::CBR_CHANGETRACK, this);
  324. }
  325. }
  326. }
  327. Vec3 CAnimComponentNode::GetPos()
  328. {
  329. Maestro::SequenceComponentRequests::AnimatablePropertyAddress animatableAddress(m_componentId, "Position");
  330. Maestro::SequenceComponentRequests::AnimatedVector3Value posValue(AZ::Vector3::CreateZero());
  331. Maestro::SequenceComponentRequestBus::Event(m_pSequence->GetSequenceEntityId(), &Maestro::SequenceComponentRequestBus::Events::GetAnimatedPropertyValue, posValue, GetParentAzEntityId(), animatableAddress);
  332. // Always return world position because Component Entity AZ::Transforms do not correctly set
  333. // CBaseObject parenting. This should probably be fixed, but for now, we explicitly change from Local to World space here.
  334. Vec3 worldPos(posValue.GetVector3Value());
  335. ConvertBetweenWorldAndLocalPosition(worldPos, eTransformConverstionDirection_toWorldSpace);
  336. return worldPos;
  337. }
  338. //////////////////////////////////////////////////////////////////////////
  339. void CAnimComponentNode::SetRotate(float time, const Quat& rotation)
  340. {
  341. if (m_componentTypeId == AZ::Uuid(AZ::EditorTransformComponentTypeId) || m_componentTypeId == AzFramework::TransformComponent::TYPEINFO_Uuid())
  342. {
  343. bool bDefault = !(gEnv->pMovieSystem->IsRecording() && (GetParent()->GetFlags() & eAnimNodeFlags_EntitySelected)); // Only selected nodes can be recorded
  344. IAnimTrack* rotTrack = GetTrackForParameter(AnimParamType::Rotation);
  345. if (rotTrack)
  346. {
  347. // Rotation is in world space, even if the entity is parented - because Component Entity AZ::Transforms do not correctly set
  348. // CBaseObject parenting, so we convert it to Local space here. This should probably be fixed, but for now, we explicitly change from World to Local space here.
  349. Quat localRot(rotation);
  350. ConvertBetweenWorldAndLocalRotation(localRot, eTransformConverstionDirection_toLocalSpace);
  351. rotTrack->SetValue(time, localRot, bDefault);
  352. }
  353. if (!bDefault)
  354. {
  355. GetCMovieSystem()->Callback(IMovieCallback::CBR_CHANGETRACK, this);
  356. }
  357. }
  358. }
  359. Quat CAnimComponentNode::GetRotate(float time)
  360. {
  361. Quat worldRot;
  362. // If there is rotation track data, get the rotation from there.
  363. // Otherwise just use the current entity rotation value.
  364. IAnimTrack* rotTrack = GetTrackForParameter(AnimParamType::Rotation);
  365. if (rotTrack != nullptr && rotTrack->GetNumKeys() > 0)
  366. {
  367. rotTrack->GetValue(time, worldRot);
  368. // Track values are always stored as relative to the parent (local), so convert to world.
  369. ConvertBetweenWorldAndLocalRotation(worldRot, eTransformConverstionDirection_toWorldSpace);
  370. }
  371. else
  372. {
  373. worldRot = GetRotate();
  374. }
  375. return worldRot;
  376. }
  377. Quat CAnimComponentNode::GetRotate()
  378. {
  379. Maestro::SequenceComponentRequests::AnimatablePropertyAddress animatableAddress(m_componentId, "Rotation");
  380. Maestro::SequenceComponentRequests::AnimatedQuaternionValue rotValue(AZ::Quaternion::CreateIdentity());
  381. Maestro::SequenceComponentRequestBus::Event(m_pSequence->GetSequenceEntityId(), &Maestro::SequenceComponentRequestBus::Events::GetAnimatedPropertyValue, rotValue, GetParentAzEntityId(), animatableAddress);
  382. // Always return world rotation because Component Entity AZ::Transforms do not correctly set
  383. // CBaseObject parenting. This should probably be fixed, but for now, we explicitly change from Local to World space here.
  384. Quat worldRot(rotValue.GetQuaternionValue());
  385. ConvertBetweenWorldAndLocalRotation(worldRot, eTransformConverstionDirection_toWorldSpace);
  386. return worldRot;
  387. }
  388. //////////////////////////////////////////////////////////////////////////
  389. void CAnimComponentNode::SetScale(float time, const Vec3& scale)
  390. {
  391. if (m_componentTypeId == AZ::Uuid(AZ::EditorTransformComponentTypeId) || m_componentTypeId == AzFramework::TransformComponent::TYPEINFO_Uuid())
  392. {
  393. bool bDefault = !(gEnv->pMovieSystem->IsRecording() && (GetParent()->GetFlags() & eAnimNodeFlags_EntitySelected)); // Only selected nodes can be recorded
  394. IAnimTrack* scaleTrack = GetTrackForParameter(AnimParamType::Scale);
  395. if (scaleTrack)
  396. {
  397. // Scale is in World space, even if the entity is parented - because Component Entity AZ::Transforms do not correctly set
  398. // CBaseObject parenting, so we convert it to Local space here. This should probably be fixed, but for now, we explicitly change from World to Local space here.
  399. Vec3 localScale(scale);
  400. ConvertBetweenWorldAndLocalScale(localScale, eTransformConverstionDirection_toLocalSpace);
  401. scaleTrack->SetValue(time, localScale, bDefault);
  402. }
  403. if (!bDefault)
  404. {
  405. GetCMovieSystem()->Callback(IMovieCallback::CBR_CHANGETRACK, this);
  406. }
  407. }
  408. }
  409. Vec3 CAnimComponentNode::GetScale()
  410. {
  411. Maestro::SequenceComponentRequests::AnimatablePropertyAddress animatableAddress(m_componentId, "Scale");
  412. Maestro::SequenceComponentRequests::AnimatedVector3Value scaleValue(AZ::Vector3::CreateZero());
  413. Maestro::SequenceComponentRequestBus::Event(m_pSequence->GetSequenceEntityId(), &Maestro::SequenceComponentRequestBus::Events::GetAnimatedPropertyValue, scaleValue, GetParentAzEntityId(), animatableAddress);
  414. // Always return World scale because Component Entity AZ::Transforms do not correctly set
  415. // CBaseObject parenting. This should probably be fixed, but for now, we explicitly change from Local to World space here.
  416. Vec3 worldScale(scaleValue.GetVector3Value());
  417. ConvertBetweenWorldAndLocalScale(worldScale, eTransformConverstionDirection_toWorldSpace);
  418. return worldScale;
  419. }
  420. void CAnimComponentNode::Activate(bool bActivate)
  421. {
  422. // Connect to EditorSequenceAgentComponentNotificationBus. The Sequence Agent Component
  423. // is always added to the Entity that is being animated aka the entity at GetParentAzEntityId().
  424. if (bActivate)
  425. {
  426. Maestro::EditorSequenceAgentComponentNotificationBus::Handler::BusConnect(GetParentAzEntityId());
  427. }
  428. else
  429. {
  430. Maestro::EditorSequenceAgentComponentNotificationBus::Handler::BusDisconnect();
  431. }
  432. }
  433. ///////////////////////////////////////////////////////////////////////////
  434. void CAnimComponentNode::OnSequenceAgentConnected()
  435. {
  436. // Whenever the Sequence Agent is connected to the Sequence, refresh the params.
  437. // This is redundant in most cases, but sometimes depending on the order of entity activation
  438. // a slice may be activated while a animated entity with the Sequence Agent is not active
  439. // (and thus not connected to the Sequence). This happens during save slice overrides.
  440. UpdateDynamicParamsInternal();
  441. }
  442. ///////////////////////////////////////////////////////////////////////////
  443. void CAnimComponentNode::ForceAnimKeyChangeInCharacterTrackAnimator()
  444. {
  445. if (m_characterTrackAnimator)
  446. {
  447. IAnimTrack* animTrack = GetTrackForParameter(AnimParamType::Animation);
  448. if (animTrack && animTrack->HasKeys())
  449. {
  450. // resets anim key change states so animation will update correctly on the next Animate()
  451. m_characterTrackAnimator->ForceAnimKeyChange();
  452. }
  453. }
  454. }
  455. //////////////////////////////////////////////////////////////////////////
  456. IAnimTrack* CAnimComponentNode::CreateTrack(const CAnimParamType& paramType)
  457. {
  458. IAnimTrack* retTrack = CAnimNode::CreateTrack(paramType);
  459. if (retTrack)
  460. {
  461. SetTrackMultiplier(retTrack);
  462. if (paramType.GetType() == AnimParamType::Animation && !m_characterTrackAnimator)
  463. {
  464. m_characterTrackAnimator = new CCharacterTrackAnimator();
  465. }
  466. }
  467. return retTrack;
  468. }
  469. //////////////////////////////////////////////////////////////////////////
  470. bool CAnimComponentNode::RemoveTrack(IAnimTrack* pTrack)
  471. {
  472. if (pTrack && pTrack->GetParameterType().GetType() == AnimParamType::Animation && m_characterTrackAnimator)
  473. {
  474. delete m_characterTrackAnimator;
  475. m_characterTrackAnimator = nullptr;
  476. }
  477. return CAnimNode::RemoveTrack(pTrack);
  478. }
  479. //////////////////////////////////////////////////////////////////////////
  480. /// @deprecated Serialization for Sequence data in Component Entity Sequences now occurs through AZ::SerializeContext and the Sequence Component
  481. void CAnimComponentNode::Serialize(XmlNodeRef& xmlNode, bool bLoading, bool bLoadEmptyTracks)
  482. {
  483. CAnimNode::Serialize(xmlNode, bLoading, bLoadEmptyTracks);
  484. if (bLoading)
  485. {
  486. XmlString uuidString;
  487. xmlNode->getAttr("ComponentId", m_componentId);
  488. if (xmlNode->getAttr("ComponentTypeId", uuidString))
  489. {
  490. m_componentTypeId = AZ::Uuid::CreateString(uuidString);
  491. }
  492. else
  493. {
  494. m_componentTypeId = AZ::Uuid::CreateNull();
  495. }
  496. }
  497. else
  498. {
  499. // saving
  500. xmlNode->setAttr("ComponentId", m_componentId);
  501. xmlNode->setAttr("ComponentTypeId", m_componentTypeId.ToFixedString().c_str());
  502. }
  503. }
  504. //////////////////////////////////////////////////////////////////////////
  505. // Property Value types are detected in this function
  506. void CAnimComponentNode::AddPropertyToParamInfoMap(const CAnimParamType& paramType)
  507. {
  508. BehaviorPropertyInfo propertyInfo; // the default value type is AnimValueType::Float
  509. {
  510. // property is handled by Component animation (Behavior Context getter/setters). Regardless of the param Type, it must have a non-empty name
  511. // (the VirtualProperty name)
  512. AZ_Assert(paramType.GetName() && strlen(paramType.GetName()), "All AnimParamTypes animated on Components must have a name for its VirtualProperty");
  513. // Initialize property name string, which sets to AnimParamType::ByString by default
  514. propertyInfo = paramType.GetName();
  515. if (paramType.GetType() != AnimParamType::ByString)
  516. {
  517. // This sets the eAnimParamType enumeration but leaves the string name untouched
  518. propertyInfo.m_animNodeParamInfo.paramType = paramType.GetType();
  519. }
  520. //////////////////////////////////////////////////////////////////////////////////////////////////
  521. //! Detect the value type from reflection in the Behavior Context
  522. //
  523. // Query the property type Id from the Sequence Component and set it if a supported type is found
  524. AZ::Uuid propertyTypeId = AZ::Uuid::CreateNull();
  525. Maestro::SequenceComponentRequests::AnimatablePropertyAddress propertyAddress(m_componentId, propertyInfo.m_displayName.c_str());
  526. Maestro::SequenceComponentRequestBus::EventResult(propertyTypeId, m_pSequence->GetSequenceEntityId(), &Maestro::SequenceComponentRequestBus::Events::GetAnimatedAddressTypeId,
  527. GetParentAzEntityId(), propertyAddress);
  528. if (propertyTypeId == AZ::Vector3::TYPEINFO_Uuid())
  529. {
  530. propertyInfo.m_animNodeParamInfo.valueType = AnimValueType::Vector;
  531. }
  532. else if (propertyTypeId == AZ::Color::TYPEINFO_Uuid())
  533. {
  534. propertyInfo.m_animNodeParamInfo.valueType = AnimValueType::RGB;
  535. }
  536. else if (propertyTypeId == AZ::Quaternion::TYPEINFO_Uuid())
  537. {
  538. propertyInfo.m_animNodeParamInfo.valueType = AnimValueType::Quat;
  539. }
  540. else if (propertyTypeId == AZ::AzTypeInfo<bool>::Uuid())
  541. {
  542. propertyInfo.m_animNodeParamInfo.valueType = AnimValueType::Bool;
  543. }
  544. // Special case, if an AssetId property named "Motion" is found, create an AssetBlend.
  545. // The Simple Motion Component exposes a virtual property named "motion" of type AssetId.
  546. // We it is detected here create an AssetBlend type in Track View. The Asset Blend has special
  547. // UI and will be used to drive mulitple properties on this component, not just the motion AssetId.
  548. else if (propertyTypeId == AZ::Data::AssetId::TYPEINFO_Uuid() && 0 == azstricmp(paramType.GetName(), "motion"))
  549. {
  550. propertyInfo.m_animNodeParamInfo.valueType = AnimValueType::AssetBlend;
  551. }
  552. // the fall-through default type is propertyInfo.m_animNodeParamInfo.valueType = AnimValueType::Float
  553. }
  554. m_paramTypeToBehaviorPropertyInfoMap[paramType] = propertyInfo;
  555. }
  556. //////////////////////////////////////////////////////////////////////////
  557. void CAnimComponentNode::Reflect(AZ::ReflectContext* context)
  558. {
  559. if (auto serializeContext = azrtti_cast<AZ::SerializeContext*>(context))
  560. {
  561. serializeContext->Class<CAnimComponentNode, CAnimNode>()
  562. ->Version(1)
  563. ->Field("ComponentID", &CAnimComponentNode::m_componentId)
  564. ->Field("ComponentTypeID", &CAnimComponentNode::m_componentTypeId);
  565. }
  566. }
  567. //////////////////////////////////////////////////////////////////////////
  568. void CAnimComponentNode::UpdateDynamicParams_Editor()
  569. {
  570. IAnimNode::AnimParamInfos animatableParams;
  571. // add all parameters supported by the component
  572. Maestro::EditorSequenceComponentRequestBus::Event(m_pSequence->GetSequenceEntityId(), &Maestro::EditorSequenceComponentRequestBus::Events::GetAllAnimatablePropertiesForComponent,
  573. animatableParams, GetParentAzEntityId(), m_componentId);
  574. for (int i = 0; i < animatableParams.size(); i++)
  575. {
  576. AddPropertyToParamInfoMap(animatableParams[i].paramType);
  577. }
  578. }
  579. //////////////////////////////////////////////////////////////////////////
  580. void CAnimComponentNode::UpdateDynamicParams_Game()
  581. {
  582. // Fill m_paramTypeToBehaviorPropertyInfoMap based on our animated tracks
  583. for (uint32 i = 0; i < m_tracks.size(); ++i)
  584. {
  585. AddPropertyToParamInfoMap(m_tracks[i]->GetParameterType());
  586. }
  587. }
  588. //////////////////////////////////////////////////////////////////////////
  589. void CAnimComponentNode::UpdateDynamicParamsInternal()
  590. {
  591. m_paramTypeToBehaviorPropertyInfoMap.clear();
  592. // editor stores *all* properties of *every* entity used in an AnimEntityNode.
  593. // In pure game mode we just need to store the properties that we know are going to be used in a track, so we can save a lot of memory.
  594. if (gEnv->IsEditor() && !gEnv->IsEditorSimulationMode() && !gEnv->IsEditorGameMode())
  595. {
  596. UpdateDynamicParams_Editor();
  597. }
  598. else
  599. {
  600. UpdateDynamicParams_Game();
  601. }
  602. // Go through all tracks and set Multipliers if required
  603. for (uint32 i = 0; i < m_tracks.size(); ++i)
  604. {
  605. AZStd::intrusive_ptr<IAnimTrack> track = m_tracks[i];
  606. SetTrackMultiplier(track.get());
  607. }
  608. }
  609. //////////////////////////////////////////////////////////////////////////
  610. void CAnimComponentNode::InitializeTrackDefaultValue(IAnimTrack* pTrack, const CAnimParamType& paramType)
  611. {
  612. // Initialize new track to property value
  613. if (paramType.GetType() == AnimParamType::ByString && pTrack)
  614. {
  615. auto findIter = m_paramTypeToBehaviorPropertyInfoMap.find(paramType);
  616. if (findIter != m_paramTypeToBehaviorPropertyInfoMap.end())
  617. {
  618. BehaviorPropertyInfo& propertyInfo = findIter->second;
  619. Maestro::SequenceComponentRequests::AnimatablePropertyAddress address(m_componentId, propertyInfo.m_animNodeParamInfo.name);
  620. switch (pTrack->GetValueType())
  621. {
  622. case AnimValueType::Float:
  623. {
  624. Maestro::SequenceComponentRequests::AnimatedFloatValue defaultValue(.0f);
  625. Maestro::SequenceComponentRequestBus::Event(m_pSequence->GetSequenceEntityId(), &Maestro::SequenceComponentRequestBus::Events::GetAnimatedPropertyValue, defaultValue, GetParentAzEntityId(), address);
  626. pTrack->SetValue(0, defaultValue.GetFloatValue(), true);
  627. break;
  628. }
  629. case AnimValueType::Vector:
  630. {
  631. Maestro::SequenceComponentRequests::AnimatedVector3Value defaultValue(AZ::Vector3::CreateZero());
  632. AZ::Vector3 vector3Value = AZ::Vector3::CreateZero();
  633. Maestro::SequenceComponentRequestBus::Event(m_pSequence->GetSequenceEntityId(), &Maestro::SequenceComponentRequestBus::Events::GetAnimatedPropertyValue, defaultValue, GetParentAzEntityId(), address);
  634. defaultValue.GetValue(vector3Value);
  635. pTrack->SetValue(0, Vec3(vector3Value.GetX(), vector3Value.GetY(), vector3Value.GetZ()), true);
  636. break;
  637. }
  638. case AnimValueType::Quat:
  639. {
  640. Maestro::SequenceComponentRequests::AnimatedQuaternionValue defaultValue(AZ::Quaternion::CreateIdentity());
  641. Maestro::SequenceComponentRequestBus::Event(m_pSequence->GetSequenceEntityId(), &Maestro::SequenceComponentRequestBus::Events::GetAnimatedPropertyValue, defaultValue, GetParentAzEntityId(), address);
  642. pTrack->SetValue(0, Quat(defaultValue.GetQuaternionValue()), true);
  643. break;
  644. }
  645. case AnimValueType::RGB:
  646. {
  647. Maestro::SequenceComponentRequests::AnimatedVector3Value defaultValue(AZ::Vector3::CreateOne());
  648. AZ::Vector3 vector3Value = AZ::Vector3::CreateOne();
  649. Maestro::SequenceComponentRequestBus::Event(m_pSequence->GetSequenceEntityId(), &Maestro::SequenceComponentRequestBus::Events::GetAnimatedPropertyValue, defaultValue, GetParentAzEntityId(), address);
  650. defaultValue.GetValue(vector3Value);
  651. pTrack->SetValue(0, Vec3(clamp_tpl((float)vector3Value.GetX(), .0f, 1.0f), clamp_tpl((float)vector3Value.GetY(), .0f, 1.0f), clamp_tpl((float)vector3Value.GetZ(), .0f, 1.0f)), /*setDefault=*/ true, /*applyMultiplier=*/ true);
  652. break;
  653. }
  654. case AnimValueType::Bool:
  655. {
  656. Maestro::SequenceComponentRequests::AnimatedBoolValue defaultValue(true);
  657. Maestro::SequenceComponentRequestBus::Event(m_pSequence->GetSequenceEntityId(), &Maestro::SequenceComponentRequestBus::Events::GetAnimatedPropertyValue, defaultValue, GetParentAzEntityId(), address);
  658. pTrack->SetValue(0, defaultValue.GetBoolValue(), true);
  659. break;
  660. }
  661. case AnimValueType::AssetBlend:
  662. {
  663. // Just init to an empty value.
  664. Maestro::AssetBlends<AZ::Data::AssetData> assetData;
  665. pTrack->SetValue(0, assetData, true);
  666. break;
  667. }
  668. default:
  669. {
  670. AZ_Warning("TrackView", false, "Unsupported value type requested for Component Node Track %s, skipping...", paramType.GetName());
  671. break;
  672. }
  673. }
  674. }
  675. }
  676. }
  677. //////////////////////////////////////////////////////////////////////////
  678. void CAnimComponentNode::Animate(SAnimContext& ac)
  679. {
  680. if (m_skipComponentAnimationUpdates)
  681. {
  682. return;
  683. }
  684. // Evaluate all tracks
  685. // indices used for character animation (SimpleAnimationComponent)
  686. int characterAnimationLayer = 0;
  687. int characterAnimationTrackIdx = 0;
  688. int trackCount = NumTracks();
  689. for (int paramIndex = 0; paramIndex < trackCount; paramIndex++)
  690. {
  691. CAnimParamType paramType = m_tracks[paramIndex]->GetParameterType();
  692. IAnimTrack* pTrack = m_tracks[paramIndex].get();
  693. if ((pTrack->HasKeys() == false) || (pTrack->GetFlags() & IAnimTrack::eAnimTrackFlags_Disabled) || pTrack->IsMasked(ac.trackMask))
  694. {
  695. continue;
  696. }
  697. if (!ac.resetting)
  698. {
  699. if (paramType.GetType() == AnimParamType::Animation)
  700. {
  701. // special handling for Character Animation. We short-circuit the SimpleAnimation behavior using m_characterTrackAnimator
  702. if (!m_characterTrackAnimator)
  703. {
  704. m_characterTrackAnimator = new CCharacterTrackAnimator;
  705. }
  706. if (characterAnimationLayer < MAX_CHARACTER_TRACKS + ADDITIVE_LAYERS_OFFSET)
  707. {
  708. int index = characterAnimationLayer;
  709. CCharacterTrack* pCharTrack = (CCharacterTrack*)pTrack;
  710. if (pCharTrack->GetAnimationLayerIndex() >= 0) // If the track has an animation layer specified,
  711. {
  712. assert(pCharTrack->GetAnimationLayerIndex() < 16);
  713. index = pCharTrack->GetAnimationLayerIndex(); // use it instead.
  714. }
  715. m_characterTrackAnimator->AnimateTrack(pCharTrack, ac, index, characterAnimationTrackIdx);
  716. if (characterAnimationLayer == 0)
  717. {
  718. characterAnimationLayer += ADDITIVE_LAYERS_OFFSET;
  719. }
  720. ++characterAnimationLayer;
  721. ++characterAnimationTrackIdx;
  722. }
  723. }
  724. else
  725. {
  726. // handle all other non-specialized Components
  727. auto findIter = m_paramTypeToBehaviorPropertyInfoMap.find(paramType);
  728. if (findIter != m_paramTypeToBehaviorPropertyInfoMap.end())
  729. {
  730. BehaviorPropertyInfo& propertyInfo = findIter->second;
  731. Maestro::SequenceComponentRequests::AnimatablePropertyAddress animatableAddress(m_componentId, propertyInfo.m_animNodeParamInfo.name);
  732. switch (pTrack->GetValueType())
  733. {
  734. case AnimValueType::Float:
  735. {
  736. if (pTrack->HasKeys())
  737. {
  738. float floatValue = .0f;
  739. pTrack->GetValue(ac.time, floatValue, /*applyMultiplier= */ true);
  740. Maestro::SequenceComponentRequests::AnimatedFloatValue value(floatValue);
  741. Maestro::SequenceComponentRequests::AnimatedFloatValue prevValue(floatValue);
  742. Maestro::SequenceComponentRequestBus::Event(m_pSequence->GetSequenceEntityId(), &Maestro::SequenceComponentRequestBus::Events::GetAnimatedPropertyValue, prevValue, GetParentAzEntityId(), animatableAddress);
  743. if (!value.IsClose(prevValue))
  744. {
  745. // only set the value if it's changed
  746. Maestro::SequenceComponentRequestBus::Event(m_pSequence->GetSequenceEntityId(), &Maestro::SequenceComponentRequestBus::Events::SetAnimatedPropertyValue, GetParentAzEntityId(), animatableAddress, value);
  747. }
  748. }
  749. break;
  750. }
  751. case AnimValueType::Vector: // fall-through
  752. case AnimValueType::RGB:
  753. {
  754. float tolerance = AZ::Constants::FloatEpsilon;
  755. Vec3 vec3Value(.0f, .0f, .0f);
  756. pTrack->GetValue(ac.time, vec3Value, /*applyMultiplier= */ true);
  757. AZ::Vector3 vector3Value(vec3Value.x, vec3Value.y, vec3Value.z);
  758. if (pTrack->GetValueType() == AnimValueType::RGB)
  759. {
  760. vec3Value.x = clamp_tpl(vec3Value.x, 0.0f, 1.0f);
  761. vec3Value.y = clamp_tpl(vec3Value.y, 0.0f, 1.0f);
  762. vec3Value.z = clamp_tpl(vec3Value.z, 0.0f, 1.0f);
  763. // set tolerance to just under 1 unit in normalized RGB space
  764. tolerance = (1.0f - AZ::Constants::FloatEpsilon) / 255.0f;
  765. }
  766. Maestro::SequenceComponentRequests::AnimatedVector3Value value(AZ::Vector3(vec3Value.x, vec3Value.y, vec3Value.z));
  767. Maestro::SequenceComponentRequests::AnimatedVector3Value prevValue(AZ::Vector3(vec3Value.x, vec3Value.y, vec3Value.z));
  768. Maestro::SequenceComponentRequestBus::Event(m_pSequence->GetSequenceEntityId(), &Maestro::SequenceComponentRequestBus::Events::GetAnimatedPropertyValue, prevValue, GetParentAzEntityId(), animatableAddress);
  769. AZ::Vector3 vector3PrevValue;
  770. prevValue.GetValue(vector3PrevValue);
  771. // Check sub-tracks for keys. If there are none, use the prevValue for that track (essentially making a non-keyed track a no-op)
  772. vector3Value.Set(pTrack->GetSubTrack(0)->HasKeys() ? vector3Value.GetX() : vector3PrevValue.GetX(),
  773. pTrack->GetSubTrack(1)->HasKeys() ? vector3Value.GetY() : vector3PrevValue.GetY(),
  774. pTrack->GetSubTrack(2)->HasKeys() ? vector3Value.GetZ() : vector3PrevValue.GetZ());
  775. value.SetValue(vector3Value);
  776. if (!value.IsClose(prevValue, tolerance))
  777. {
  778. // only set the value if it's changed
  779. Maestro::SequenceComponentRequestBus::Event(m_pSequence->GetSequenceEntityId(), &Maestro::SequenceComponentRequestBus::Events::SetAnimatedPropertyValue, GetParentAzEntityId(), animatableAddress, value);
  780. }
  781. break;
  782. }
  783. case AnimValueType::Quat:
  784. {
  785. if (pTrack->HasKeys())
  786. {
  787. float tolerance = AZ::Constants::FloatEpsilon;
  788. AZ::Quaternion quaternionValue(AZ::Quaternion::CreateIdentity());
  789. pTrack->GetValue(ac.time, quaternionValue);
  790. Maestro::SequenceComponentRequests::AnimatedQuaternionValue value(quaternionValue);
  791. Maestro::SequenceComponentRequests::AnimatedQuaternionValue prevValue(quaternionValue);
  792. Maestro::SequenceComponentRequestBus::Event(m_pSequence->GetSequenceEntityId(), &Maestro::SequenceComponentRequestBus::Events::GetAnimatedPropertyValue, prevValue, GetParentAzEntityId(), animatableAddress);
  793. AZ::Quaternion prevQuaternionValue;
  794. prevValue.GetValue(prevQuaternionValue);
  795. if (!prevQuaternionValue.IsClose(quaternionValue, tolerance))
  796. {
  797. // only set the value if it's changed
  798. Maestro::SequenceComponentRequestBus::Event(m_pSequence->GetSequenceEntityId(), &Maestro::SequenceComponentRequestBus::Events::SetAnimatedPropertyValue, GetParentAzEntityId(), animatableAddress, value);
  799. }
  800. }
  801. break;
  802. }
  803. case AnimValueType::Bool:
  804. {
  805. if (pTrack->HasKeys())
  806. {
  807. bool boolValue = true;
  808. pTrack->GetValue(ac.time, boolValue);
  809. Maestro::SequenceComponentRequests::AnimatedBoolValue value(boolValue);
  810. Maestro::SequenceComponentRequests::AnimatedBoolValue prevValue(boolValue);
  811. Maestro::SequenceComponentRequestBus::Event(m_pSequence->GetSequenceEntityId(), &Maestro::SequenceComponentRequestBus::Events::GetAnimatedPropertyValue, prevValue, GetParentAzEntityId(), animatableAddress);
  812. if (!value.IsClose(prevValue))
  813. {
  814. // only set the value if it's changed
  815. Maestro::SequenceComponentRequestBus::Event(m_pSequence->GetSequenceEntityId(), &Maestro::SequenceComponentRequestBus::Events::SetAnimatedPropertyValue, GetParentAzEntityId(), animatableAddress, value);
  816. }
  817. }
  818. break;
  819. }
  820. case AnimValueType::AssetBlend:
  821. {
  822. if (pTrack->HasKeys())
  823. {
  824. // Get the AssetBlends from the Track and update Properties on Component
  825. Maestro::AssetBlends<AZ::Data::AssetData> assetBlendValue;
  826. pTrack->GetValue(ac.time, assetBlendValue);
  827. AnimateAssetBlendSubProperties(assetBlendValue);
  828. }
  829. break;
  830. }
  831. default:
  832. {
  833. AZ_Warning("TrackView", false, "Unsupported value type %d requested for Component Node Track %s, skipping...", pTrack->GetValueType(), paramType.GetName());
  834. break;
  835. }
  836. }
  837. }
  838. }
  839. }
  840. }
  841. if (m_pOwner)
  842. {
  843. m_bIgnoreSetParam = true; // Prevents feedback change of track.
  844. m_pOwner->OnNodeAnimated(this);
  845. m_bIgnoreSetParam = false;
  846. }
  847. }
  848. //////////////////////////////////////////////////////////////////////////
  849. void CAnimComponentNode::AnimateAssetBlendSubProperties(const Maestro::AssetBlends<AZ::Data::AssetData>& assetBlendValue)
  850. {
  851. // These are the params to set for the Simple Motion Component
  852. bool previewInEditor = true;
  853. float playTime = 0.0f;
  854. float playSpeed = 0.0f;
  855. AZ::Data::AssetId assetId;
  856. float blendInTime = 0.0f;
  857. float blendOutTime = 0.0f;
  858. // Populate params based on the last AssetBlend found.
  859. // So new keys will be picked up and played on top of currently
  860. // playing animations (resulting in a blend).
  861. if (assetBlendValue.m_assetBlends.size() > 0)
  862. {
  863. Maestro::AssetBlend assetData = assetBlendValue.m_assetBlends.back();
  864. playTime = assetData.m_time;
  865. assetId = assetData.m_assetId;
  866. blendInTime = assetData.m_blendInTime;
  867. blendOutTime = assetData.m_blendOutTime;
  868. }
  869. // Set Preview in Editor
  870. Maestro::SequenceComponentRequests::AnimatablePropertyAddress previewInEditorAnimatableAddress(m_componentId, "PreviewInEditor");
  871. Maestro::SequenceComponentRequests::AnimatedFloatValue prevPreviewInEditorValue(previewInEditor);
  872. Maestro::SequenceComponentRequestBus::Event(m_pSequence->GetSequenceEntityId(), &Maestro::SequenceComponentRequestBus::Events::GetAnimatedPropertyValue, prevPreviewInEditorValue, GetParentAzEntityId(), previewInEditorAnimatableAddress);
  873. Maestro::SequenceComponentRequests::AnimatedFloatValue previewInEditorValue(previewInEditor);
  874. if (!previewInEditorValue.IsClose(prevPreviewInEditorValue))
  875. {
  876. Maestro::SequenceComponentRequestBus::Event(m_pSequence->GetSequenceEntityId(), &Maestro::SequenceComponentRequestBus::Events::SetAnimatedPropertyValue, GetParentAzEntityId(), previewInEditorAnimatableAddress, previewInEditorValue);
  877. }
  878. // Set Blend In Time before Motion so the Blend In will be used on the Motion that is about to Play.
  879. Maestro::SequenceComponentRequests::AnimatablePropertyAddress blendInTimeAnimatableAddress(m_componentId, "BlendInTime");
  880. Maestro::SequenceComponentRequests::AnimatedFloatValue prevBlendInTimeValue(blendInTime);
  881. Maestro::SequenceComponentRequestBus::Event(m_pSequence->GetSequenceEntityId(), &Maestro::SequenceComponentRequestBus::Events::GetAnimatedPropertyValue, prevBlendInTimeValue, GetParentAzEntityId(), blendInTimeAnimatableAddress);
  882. Maestro::SequenceComponentRequests::AnimatedFloatValue blendInTimeValue(blendInTime);
  883. if (!blendInTimeValue.IsClose(prevBlendInTimeValue))
  884. {
  885. Maestro::SequenceComponentRequestBus::Event(m_pSequence->GetSequenceEntityId(), &Maestro::SequenceComponentRequestBus::Events::SetAnimatedPropertyValue, GetParentAzEntityId(), blendInTimeAnimatableAddress, blendInTimeValue);
  886. }
  887. // Set Motion
  888. Maestro::SequenceComponentRequests::AnimatablePropertyAddress motionAnimatableAddress(m_componentId, "Motion");
  889. Maestro::SequenceComponentRequests::AnimatedAssetIdValue prevMotionValue(assetId);
  890. Maestro::SequenceComponentRequestBus::Event(m_pSequence->GetSequenceEntityId(), &Maestro::SequenceComponentRequestBus::Events::GetAnimatedPropertyValue, prevMotionValue, GetParentAzEntityId(), motionAnimatableAddress);
  891. Maestro::SequenceComponentRequests::AnimatedAssetIdValue motionValue(assetId);
  892. if (!motionValue.IsClose(prevMotionValue))
  893. {
  894. Maestro::SequenceComponentRequestBus::Event(m_pSequence->GetSequenceEntityId(), &Maestro::SequenceComponentRequestBus::Events::SetAnimatedPropertyValue, GetParentAzEntityId(), motionAnimatableAddress, motionValue);
  895. }
  896. // Set Blend Out Time after Motion so the Blend Out will not be used on Play, but instead used on that 'last' Motion 'Stop' as fade out.
  897. Maestro::SequenceComponentRequests::AnimatablePropertyAddress blendOutTimeAnimatableAddress(m_componentId, "BlendOutTime");
  898. Maestro::SequenceComponentRequests::AnimatedFloatValue prevBlendOutTimeValue(blendOutTime);
  899. Maestro::SequenceComponentRequestBus::Event(m_pSequence->GetSequenceEntityId(), &Maestro::SequenceComponentRequestBus::Events::GetAnimatedPropertyValue, prevBlendOutTimeValue, GetParentAzEntityId(), blendOutTimeAnimatableAddress);
  900. Maestro::SequenceComponentRequests::AnimatedFloatValue blendOutTimeValue(blendOutTime);
  901. if (!blendOutTimeValue.IsClose(prevBlendOutTimeValue))
  902. {
  903. Maestro::SequenceComponentRequestBus::Event(m_pSequence->GetSequenceEntityId(), &Maestro::SequenceComponentRequestBus::Events::SetAnimatedPropertyValue, GetParentAzEntityId(), blendOutTimeAnimatableAddress, blendOutTimeValue);
  904. }
  905. // Set Play Time
  906. Maestro::SequenceComponentRequests::AnimatablePropertyAddress playTimeAnimatableAddress(m_componentId, "PlayTime");
  907. Maestro::SequenceComponentRequests::AnimatedFloatValue prevPlayTimeValue(playTime);
  908. Maestro::SequenceComponentRequestBus::Event(m_pSequence->GetSequenceEntityId(), &Maestro::SequenceComponentRequestBus::Events::GetAnimatedPropertyValue, prevPlayTimeValue, GetParentAzEntityId(), playTimeAnimatableAddress);
  909. Maestro::SequenceComponentRequests::AnimatedFloatValue playTimeValue(playTime);
  910. if (!playTimeValue.IsClose(prevPlayTimeValue))
  911. {
  912. Maestro::SequenceComponentRequestBus::Event(m_pSequence->GetSequenceEntityId(), &Maestro::SequenceComponentRequestBus::Events::SetAnimatedPropertyValue, GetParentAzEntityId(), playTimeAnimatableAddress, playTimeValue);
  913. }
  914. // Set Play Speed
  915. Maestro::SequenceComponentRequests::AnimatablePropertyAddress playSpeedAnimatableAddress(m_componentId, "PlaySpeed");
  916. Maestro::SequenceComponentRequests::AnimatedFloatValue prevPlaySpeedValue(playSpeed);
  917. Maestro::SequenceComponentRequestBus::Event(m_pSequence->GetSequenceEntityId(), &Maestro::SequenceComponentRequestBus::Events::GetAnimatedPropertyValue, prevPlaySpeedValue, GetParentAzEntityId(), playSpeedAnimatableAddress);
  918. Maestro::SequenceComponentRequests::AnimatedFloatValue playSpeedValue(playSpeed);
  919. if (!playSpeedValue.IsClose(prevPlaySpeedValue))
  920. {
  921. Maestro::SequenceComponentRequestBus::Event(m_pSequence->GetSequenceEntityId(), &Maestro::SequenceComponentRequestBus::Events::SetAnimatedPropertyValue, GetParentAzEntityId(), playSpeedAnimatableAddress, playSpeedValue);
  922. }
  923. }