KeyTrackLinearTests.cpp 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278
  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 "SystemComponentFixture.h"
  9. #include <AzTest/AzTest.h>
  10. #include <AzCore/Math/MathUtils.h>
  11. #include <EMotionFX/Source/KeyTrackLinearDynamic.h>
  12. #include <Integration/System/SystemCommon.h>
  13. namespace EMotionFX
  14. {
  15. //--------------------------------------------------------------------------
  16. // The test fixture setup and helpers.
  17. //--------------------------------------------------------------------------
  18. class KeyTrackLinearDynamicFixture : public SystemComponentFixture
  19. {
  20. public:
  21. KeyTrackLinearDynamicFixture()
  22. : SystemComponentFixture()
  23. {
  24. }
  25. void LogFloatTrack(KeyTrackLinearDynamic<float, float>& track)
  26. {
  27. AZ_Printf("EMotionFX", "----------\n");
  28. for (size_t i=0; i < track.GetNumKeys(); ++i)
  29. {
  30. AZ_Printf("EMotionFX", "#%zu = time:%f value:%f\n", i, track.GetKey(i)->GetTime(), track.GetKey(i)->GetValue());
  31. }
  32. }
  33. void FillFloatTrackZeroToThree(KeyTrackLinearDynamic<float, float>& track)
  34. {
  35. track.ClearKeys();
  36. track.AddKey(0.0f, 0.0f);
  37. track.AddKey(1.0f, 1.0f);
  38. track.AddKey(2.0f, 2.0f);
  39. track.AddKey(3.0f, 3.0f);
  40. track.Init();
  41. }
  42. };
  43. //--------------------------------------------------------------------------
  44. // The actual tests.
  45. //--------------------------------------------------------------------------
  46. TEST_F(KeyTrackLinearDynamicFixture, KeyTrackAdd)
  47. {
  48. EMotionFX::KeyTrackLinearDynamic<float, float> track;
  49. FillFloatTrackZeroToThree(track);
  50. ASSERT_EQ(track.GetNumKeys(), 4);
  51. }
  52. TEST_F(KeyTrackLinearDynamicFixture, KeyTrackAddSorted)
  53. {
  54. EMotionFX::KeyTrackLinearDynamic<float, float> track;
  55. track.AddKeySorted(1.0f, 1.0f);
  56. track.AddKeySorted(0.0f, 0.0f);
  57. track.AddKeySorted(3.0f, 3.0f);
  58. track.AddKeySorted(2.0f, 2.0f);
  59. track.Init();
  60. ASSERT_EQ(track.GetNumKeys(), 4);
  61. ASSERT_TRUE(AZ::IsClose(track.GetKey(0)->GetTime(), 0.0f, 0.00001f));
  62. ASSERT_TRUE(AZ::IsClose(track.GetKey(1)->GetTime(), 1.0f, 0.00001f));
  63. ASSERT_TRUE(AZ::IsClose(track.GetKey(2)->GetTime(), 2.0f, 0.00001f));
  64. ASSERT_TRUE(AZ::IsClose(track.GetKey(3)->GetTime(), 3.0f, 0.00001f));
  65. }
  66. TEST_F(KeyTrackLinearDynamicFixture, KeyTrackRemoveKey)
  67. {
  68. EMotionFX::KeyTrackLinearDynamic<float, float> track;
  69. FillFloatTrackZeroToThree(track);
  70. ASSERT_EQ(track.GetNumKeys(), 4);
  71. track.RemoveKey(1);
  72. track.Init();
  73. ASSERT_FLOAT_EQ(track.GetKey(0)->GetTime(), 0.0f);
  74. ASSERT_FLOAT_EQ(track.GetKey(1)->GetTime(), 2.0f);
  75. ASSERT_FLOAT_EQ(track.GetKey(2)->GetTime(), 3.0f);
  76. track.RemoveKey(2);
  77. track.Init();
  78. ASSERT_FLOAT_EQ(track.GetKey(0)->GetTime(), 0.0f);
  79. ASSERT_FLOAT_EQ(track.GetKey(1)->GetTime(), 2.0f);
  80. track.RemoveKey(0);
  81. track.Init();
  82. // The time should be 0, because Init makes sure the first keyframe starts at time 0
  83. ASSERT_FLOAT_EQ(track.GetKey(0)->GetTime(), 0.0f);
  84. track.RemoveKey(0);
  85. track.Init();
  86. ASSERT_EQ(track.GetNumKeys(), 0);
  87. }
  88. TEST_F(KeyTrackLinearDynamicFixture, KeyTrackClearKeys)
  89. {
  90. EMotionFX::KeyTrackLinearDynamic<float, float> track;
  91. FillFloatTrackZeroToThree(track);
  92. ASSERT_EQ(track.GetNumKeys(), 4);
  93. track.ClearKeys();
  94. ASSERT_EQ(track.GetNumKeys(), 0);
  95. }
  96. TEST_F(KeyTrackLinearDynamicFixture, KeyTrackCheckIfIsAnimated)
  97. {
  98. EMotionFX::KeyTrackLinearDynamic<float, float> track;
  99. FillFloatTrackZeroToThree(track);
  100. ASSERT_TRUE(track.CheckIfIsAnimated(0.0f, 0.00001f));
  101. track.ClearKeys();
  102. track.AddKey(0.0f, 1.0f);
  103. track.AddKey(1.0f, 1.0f);
  104. track.AddKey(2.0f, 1.0f);
  105. track.AddKey(3.0f, 1.0f);
  106. ASSERT_TRUE(!track.CheckIfIsAnimated(1.0f, 0.00001f));
  107. track.ClearKeys();
  108. track.AddKey(0.0f, 1.0f);
  109. track.AddKey(1.0f, 1.0f);
  110. track.AddKey(2.0f, 1.01f);
  111. track.AddKey(3.0f, 1.0f);
  112. ASSERT_TRUE(track.CheckIfIsAnimated(1.0f, 0.00001f));
  113. }
  114. TEST_F(KeyTrackLinearDynamicFixture, KeyTrackGetFirstKey)
  115. {
  116. EMotionFX::KeyTrackLinearDynamic<float, float> track;
  117. FillFloatTrackZeroToThree(track);
  118. ASSERT_FLOAT_EQ(track.GetFirstKey()->GetTime(), 0.0f);
  119. ASSERT_FLOAT_EQ(track.GetFirstKey()->GetValue(), 0.0f);
  120. track.RemoveKey(2);
  121. track.Init();
  122. ASSERT_FLOAT_EQ(track.GetFirstKey()->GetTime(), 0.0f);
  123. ASSERT_FLOAT_EQ(track.GetFirstKey()->GetValue(), 0.0f);
  124. track.RemoveKey(0);
  125. track.Init();
  126. // Time value is expected to be 0 for the first key, after calling Init.
  127. // It is remapped internally to 0, if the first key's time isn't.
  128. // The value remains the same though.
  129. ASSERT_FLOAT_EQ(track.GetFirstKey()->GetTime(), 0.0f);
  130. ASSERT_FLOAT_EQ(track.GetFirstKey()->GetValue(), 1.0f);
  131. track.ClearKeys();
  132. track.Init();
  133. ASSERT_TRUE(!track.GetFirstKey());
  134. }
  135. TEST_F(KeyTrackLinearDynamicFixture, KeyTrackGetLastKey)
  136. {
  137. EMotionFX::KeyTrackLinearDynamic<float, float> track;
  138. FillFloatTrackZeroToThree(track);
  139. ASSERT_FLOAT_EQ(track.GetLastKey()->GetTime(), 3.0f);
  140. ASSERT_FLOAT_EQ(track.GetLastKey()->GetValue(), 3.0f);
  141. track.RemoveKey(2);
  142. track.Init();
  143. ASSERT_FLOAT_EQ(track.GetLastKey()->GetTime(), 3.0f);
  144. ASSERT_FLOAT_EQ(track.GetLastKey()->GetValue(), 3.0f);
  145. track.RemoveKey(track.GetNumKeys() - 1);
  146. track.Init();
  147. ASSERT_FLOAT_EQ(track.GetLastKey()->GetTime(), 1.0f);
  148. ASSERT_FLOAT_EQ(track.GetLastKey()->GetValue(), 1.0f);
  149. track.ClearKeys();
  150. track.Init();
  151. ASSERT_TRUE(!track.GetLastKey());
  152. }
  153. TEST_F(KeyTrackLinearDynamicFixture, KeyTrackFindKeyNumber)
  154. {
  155. EMotionFX::KeyTrackLinearDynamic<float, float> track;
  156. FillFloatTrackZeroToThree(track);
  157. ASSERT_EQ(track.FindKeyNumber(-1.0f), InvalidIndex);
  158. ASSERT_EQ(track.FindKeyNumber(0.0f), 0);
  159. ASSERT_EQ(track.FindKeyNumber(1.0f), 1);
  160. ASSERT_EQ(track.FindKeyNumber(2.0f), 2);
  161. ASSERT_EQ(track.FindKeyNumber(2.4f), 2);
  162. ASSERT_EQ(track.FindKeyNumber(2.8f), 2);
  163. ASSERT_EQ(track.FindKeyNumber(2.999f), 2);
  164. ASSERT_EQ(track.FindKeyNumber(3.0f), InvalidIndex);
  165. ASSERT_EQ(track.FindKeyNumber(3.001f), InvalidIndex);
  166. ASSERT_EQ(track.FindKeyNumber(4.0f), InvalidIndex);
  167. }
  168. TEST_F(KeyTrackLinearDynamicFixture, KeyTrackSetNumKeys)
  169. {
  170. EMotionFX::KeyTrackLinearDynamic<float, float> track;
  171. FillFloatTrackZeroToThree(track);
  172. track.SetNumKeys(10);
  173. ASSERT_EQ(track.GetNumKeys(), 10);
  174. track.SetNumKeys(15);
  175. ASSERT_EQ(track.GetNumKeys(), 15);
  176. track.SetNumKeys(5);
  177. ASSERT_EQ(track.GetNumKeys(), 5);
  178. track.SetNumKeys(0);
  179. ASSERT_EQ(track.GetNumKeys(), 0);
  180. }
  181. TEST_F(KeyTrackLinearDynamicFixture, KeyTrackOptimize)
  182. {
  183. EMotionFX::KeyTrackLinearDynamic<float, float> track;
  184. track.AddKey(0.0f, 0.0f);
  185. track.AddKey(1.0f, 1.0f);
  186. track.AddKey(2.0f, 2.0f);
  187. track.AddKey(3.0f, 3.0f);
  188. track.Init();
  189. track.Optimize(0.00001f);
  190. ASSERT_EQ(track.GetNumKeys(), 2);
  191. ASSERT_FLOAT_EQ(track.GetKey(0)->GetTime(), 0.0f);
  192. ASSERT_FLOAT_EQ(track.GetKey(1)->GetTime(), 3.0f);
  193. track.ClearKeys();
  194. track.AddKey(0.0f, 0.0f);
  195. track.AddKey(1.0f, 1.0f);
  196. track.AddKey(2.0f, 1.0f);
  197. track.AddKey(2.01f, 1.0001f);
  198. track.AddKey(3.0f, 3.0f);
  199. track.Init();
  200. const size_t numKeysRemoved = track.Optimize(0.001f);
  201. ASSERT_EQ(numKeysRemoved, 1);
  202. ASSERT_EQ(track.GetNumKeys(), 4);
  203. ASSERT_FLOAT_EQ(track.GetKey(0)->GetTime(), 0.0f);
  204. ASSERT_FLOAT_EQ(track.GetKey(1)->GetTime(), 1.0f);
  205. ASSERT_FLOAT_EQ(track.GetKey(2)->GetTime(), 2.01f);
  206. ASSERT_FLOAT_EQ(track.GetKey(3)->GetTime(), 3.0f);
  207. }
  208. TEST_F(KeyTrackLinearDynamicFixture, KeyTrackGetValueAtTime)
  209. {
  210. EMotionFX::KeyTrackLinearDynamic<float, float> track;
  211. FillFloatTrackZeroToThree(track);
  212. ASSERT_FLOAT_EQ(track.GetValueAtTime(0.0f), 0.0f);
  213. ASSERT_FLOAT_EQ(track.GetValueAtTime(0.5f), 0.5f);
  214. ASSERT_FLOAT_EQ(track.GetValueAtTime(1.0f), 1.0f);
  215. ASSERT_FLOAT_EQ(track.GetValueAtTime(3.0f), 3.0f);
  216. ASSERT_FLOAT_EQ(track.GetValueAtTime(4.0f), 3.0f);
  217. uint8 cacheHit = 0;
  218. size_t cached = 0;
  219. ASSERT_FLOAT_EQ(track.GetValueAtTime(0.0f, &cached, &cacheHit), 0.0f);
  220. ASSERT_EQ(cached, 0);
  221. ASSERT_EQ(cacheHit, 1);
  222. ASSERT_FLOAT_EQ(track.GetValueAtTime(0.5f, &cached, &cacheHit), 0.5f);
  223. ASSERT_EQ(cached, 0);
  224. ASSERT_EQ(cacheHit, 1);
  225. ASSERT_FLOAT_EQ(track.GetValueAtTime(1.0f, &cached, &cacheHit), 1.0f);
  226. ASSERT_EQ(cached, 0);
  227. ASSERT_EQ(cacheHit, 1);
  228. ASSERT_FLOAT_EQ(track.GetValueAtTime(2.999f, &cached, &cacheHit), 2.999f);
  229. ASSERT_EQ(cached, 2);
  230. ASSERT_EQ(cacheHit, 0);
  231. ASSERT_FLOAT_EQ(track.GetValueAtTime(0.0f, &cached, &cacheHit), 0.0f);
  232. ASSERT_EQ(cached, 0);
  233. ASSERT_EQ(cacheHit, 0);
  234. }
  235. } // namespace EMotionFX