GotoTrack.cpp 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. /*
  2. * Copyright (c) Contributors to the Open 3D Engine Project.
  3. * For complete copyright and license terms please see the LICENSE at the root of this distribution.
  4. *
  5. * SPDX-License-Identifier: Apache-2.0 OR MIT
  6. *
  7. */
  8. #include <AzCore/Serialization/SerializeContext.h>
  9. #include "GotoTrack.h"
  10. #include "Maestro/Types/AnimValueType.h"
  11. #define MIN_TIME_PRECISION 0.01f
  12. //////////////////////////////////////////////////////////////////////////
  13. CGotoTrack::CGotoTrack()
  14. {
  15. m_flags = 0;
  16. m_DefaultValue = -1.0f;
  17. }
  18. AnimValueType CGotoTrack::GetValueType()
  19. {
  20. return AnimValueType::DiscreteFloat;
  21. }
  22. ////////////////////////////////////////////////////////////////////////
  23. void CGotoTrack::GetValue(float time, float& value, bool applyMultiplier)
  24. {
  25. size_t nTotalKeys(m_keys.size());
  26. value = m_DefaultValue;
  27. if (nTotalKeys < 1)
  28. {
  29. return;
  30. }
  31. CheckValid();
  32. size_t nKey(0);
  33. for (nKey = 0; nKey < nTotalKeys; ++nKey)
  34. {
  35. if (time >= m_keys[nKey].time)
  36. {
  37. value = m_keys[nKey].m_fValue;
  38. }
  39. else
  40. {
  41. break;
  42. }
  43. }
  44. if (applyMultiplier && m_trackMultiplier != 1.0f)
  45. {
  46. value /= m_trackMultiplier;
  47. }
  48. }
  49. //////////////////////////////////////////////////////////////////////////
  50. void CGotoTrack::SetValue(float time, const float& value, bool bDefault, bool applyMultiplier)
  51. {
  52. if (!bDefault)
  53. {
  54. IDiscreteFloatKey oKey;
  55. if (applyMultiplier && m_trackMultiplier != 1.0f)
  56. {
  57. oKey.SetValue(value * m_trackMultiplier);
  58. }
  59. else
  60. {
  61. oKey.SetValue(value);
  62. }
  63. SetKeyAtTime(time, &oKey);
  64. }
  65. else
  66. {
  67. if (applyMultiplier && m_trackMultiplier != 1.0f)
  68. {
  69. m_DefaultValue = value * m_trackMultiplier;
  70. }
  71. else
  72. {
  73. m_DefaultValue = value;
  74. }
  75. }
  76. }
  77. ////////////////////////////////////////////////////////////////////////
  78. void CGotoTrack::SerializeKey(IDiscreteFloatKey& key, XmlNodeRef& keyNode, bool bLoading)
  79. {
  80. if (bLoading)
  81. {
  82. keyNode->getAttr("time", key.time);
  83. keyNode->getAttr("value", key.m_fValue);
  84. //assert(key.time == key.m_fValue);
  85. keyNode->getAttr("flags", key.flags);
  86. }
  87. else
  88. {
  89. keyNode->setAttr("time", key.time);
  90. keyNode->setAttr("value", key.m_fValue);
  91. int flags = key.flags;
  92. if (flags != 0)
  93. {
  94. keyNode->setAttr("flags", flags);
  95. }
  96. }
  97. }
  98. //////////////////////////////////////////////////////////////////////////
  99. void CGotoTrack::GetKeyInfo(int index, const char*& description, [[maybe_unused]] float& duration)
  100. {
  101. static char str[64];
  102. description = str;
  103. assert(index >= 0 && index < GetNumKeys());
  104. float& k = m_keys[index].m_fValue;
  105. sprintf_s(str, "%.2f", k);
  106. }
  107. //////////////////////////////////////////////////////////////////////////
  108. void CGotoTrack::SetKeyAtTime(float time, IKey* key)
  109. {
  110. assert(key != 0);
  111. key->time = time;
  112. bool found = false;
  113. // Find key with given time.
  114. for (size_t i = 0; i < m_keys.size(); i++)
  115. {
  116. float keyt = m_keys[i].time;
  117. if (fabs(keyt - time) < MIN_TIME_PRECISION)
  118. {
  119. key->flags = m_keys[i].flags; // Reserve the flag value.
  120. SetKey(static_cast<int>(i), key);
  121. found = true;
  122. break;
  123. }
  124. //if (keyt > time)
  125. //break;
  126. }
  127. if (!found)
  128. {
  129. // Key with this time not found.
  130. // Create a new one.
  131. int keyIndex = CreateKey(time);
  132. // Reserve the flag value.
  133. key->flags = m_keys[keyIndex].flags; // Reserve the flag value.
  134. SetKey(keyIndex, key);
  135. }
  136. }
  137. //////////////////////////////////////////////////////////////////////////
  138. static bool GotoTrackVersionConverter(
  139. AZ::SerializeContext& serializeContext,
  140. AZ::SerializeContext::DataElementNode& rootElement)
  141. {
  142. if (rootElement.GetVersion() < 3)
  143. {
  144. rootElement.AddElement(serializeContext, "BaseClass1", azrtti_typeid<IAnimTrack>());
  145. }
  146. return true;
  147. }
  148. template<>
  149. inline void TAnimTrack<IDiscreteFloatKey>::Reflect(AZ::ReflectContext* context)
  150. {
  151. if (auto serializeContext = azrtti_cast<AZ::SerializeContext*>(context))
  152. {
  153. serializeContext->Class<TAnimTrack<IDiscreteFloatKey>, IAnimTrack>()
  154. ->Version(3, &GotoTrackVersionConverter)
  155. ->Field("Flags", &TAnimTrack<IDiscreteFloatKey>::m_flags)
  156. ->Field("Range", &TAnimTrack<IDiscreteFloatKey>::m_timeRange)
  157. ->Field("ParamType", &TAnimTrack<IDiscreteFloatKey>::m_nParamType)
  158. ->Field("Keys", &TAnimTrack<IDiscreteFloatKey>::m_keys)
  159. ->Field("Id", &TAnimTrack<IDiscreteFloatKey>::m_id);
  160. }
  161. }
  162. //////////////////////////////////////////////////////////////////////////
  163. void CGotoTrack::Reflect(AZ::ReflectContext* context)
  164. {
  165. TAnimTrack<IDiscreteFloatKey>::Reflect(context);
  166. if (auto serializeContext = azrtti_cast<AZ::SerializeContext*>(context))
  167. {
  168. serializeContext->Class<CGotoTrack, TAnimTrack<IDiscreteFloatKey>>()
  169. ->Version(1);
  170. }
  171. }