MotionDataTests.cpp 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  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/UnitTest/UnitTest.h>
  9. #include <EMotionFX/Source/MotionData/MotionData.h>
  10. #include <Tests/SystemComponentFixture.h>
  11. namespace EMotionFX
  12. {
  13. class MotionDataTests
  14. : public SystemComponentFixture
  15. , public UnitTest::TraceBusRedirector
  16. {
  17. public:
  18. void SetUp()
  19. {
  20. UnitTest::TraceBusRedirector::BusConnect();
  21. SystemComponentFixture::SetUp();
  22. }
  23. void TearDown()
  24. {
  25. SystemComponentFixture::TearDown();
  26. UnitTest::TraceBusRedirector::BusDisconnect();
  27. }
  28. };
  29. TEST_F(MotionDataTests, CalculateSampleInformation)
  30. {
  31. struct TestSample
  32. {
  33. float m_duration;
  34. float m_sampleRate;
  35. float m_expectedSampleRate;
  36. float m_expectedSampleSpacing;
  37. size_t m_expectedNumSamples;
  38. };
  39. AZStd::vector<TestSample> samples{
  40. { 1.0f, 10.0f, 10.0f, 0.1f, 11 },
  41. { 1.0f, 3.0f, 3.0f, 1.0f / 3.0f, 4 },
  42. { 0.5f, 1.0f, 2.0f, 0.5f, 2 },
  43. { 1.05f, 10.0f, 1.0f / (1.05f / 10.0f), 1.05f / 10.0f, 11 }
  44. };
  45. for (const TestSample& sample : samples)
  46. {
  47. float sampleRate = sample.m_sampleRate;
  48. float sampleSpacing = -1.0f;
  49. size_t numSamples = InvalidIndex;
  50. MotionData::CalculateSampleInformation(sample.m_duration, sampleRate, numSamples, sampleSpacing);
  51. EXPECT_NEAR(sampleSpacing, sample.m_expectedSampleSpacing, 0.0001f);
  52. EXPECT_NEAR(sampleRate, sample.m_expectedSampleRate, 0.0001f);
  53. EXPECT_EQ(numSamples, sample.m_expectedNumSamples);
  54. }
  55. }
  56. TEST_F(MotionDataTests, CalculateNumRequiredSamples)
  57. {
  58. EXPECT_EQ(MotionData::CalculateNumRequiredSamples(1.0f, 0.1f), 11);
  59. EXPECT_EQ(MotionData::CalculateNumRequiredSamples(1.0f, 2.0f), 2);
  60. EXPECT_EQ(MotionData::CalculateNumRequiredSamples(1.0f, 0.333333f), 4);
  61. EXPECT_EQ(MotionData::CalculateNumRequiredSamples(1.0f, 1.0f), 2);
  62. }
  63. TEST_F(MotionDataTests, CalculateInterpolationIndices)
  64. {
  65. struct TestSample
  66. {
  67. float m_sampleTime = 0.0f;
  68. size_t m_indexA = InvalidIndex;
  69. size_t m_indexB = InvalidIndex;
  70. float m_t = -1.0f;
  71. };
  72. AZStd::vector<TestSample> testSamples = {
  73. {
  74. // Negative time value, out of range.
  75. -1.0f, // Sample time.
  76. 0, // Expected IndexA.
  77. 0, // Expected IndexB.
  78. 0.0f // Expected t.
  79. },
  80. {
  81. // Exactly on the first sample.
  82. 0.0f,
  83. 0,
  84. 1,
  85. 0.0f
  86. },
  87. {
  88. // Exactly on the last sample.
  89. 1.0f,
  90. 10,
  91. 10,
  92. 0.0f
  93. },
  94. {
  95. // Exactly on the second sample.
  96. 0.1f,
  97. 1,
  98. 2,
  99. 0.0f
  100. },
  101. {
  102. // In between two samples.
  103. 0.15f,
  104. 1,
  105. 2,
  106. 0.5f
  107. },
  108. {
  109. // Another in-between two samples test.
  110. 0.725f,
  111. 7,
  112. 8,
  113. 0.25f
  114. },
  115. {
  116. // Past the maximum duration.
  117. 100.0f,
  118. 10,
  119. 10,
  120. 0.0f
  121. }
  122. };
  123. // Create some track for our non-uniform test.
  124. AZStd::vector<float> track;
  125. const float sampleSpacing = 0.1f;
  126. const float duration = 1.0f;
  127. const size_t numSamples = 11;
  128. track.resize(numSamples);
  129. for (size_t i = 0; i < numSamples; ++i)
  130. {
  131. track[i] = static_cast<float>(i * sampleSpacing);
  132. }
  133. for (TestSample& testSample : testSamples)
  134. {
  135. // Test uniform sampling.
  136. size_t indexA = InvalidIndex;
  137. size_t indexB = InvalidIndex;
  138. float t = -1.0f;
  139. MotionData::CalculateInterpolationIndicesUniform(testSample.m_sampleTime, sampleSpacing, duration, numSamples, indexA, indexB, t);
  140. EXPECT_EQ(indexA, testSample.m_indexA);
  141. EXPECT_EQ(indexB, testSample.m_indexB);
  142. EXPECT_TRUE(AZ::IsClose(t, testSample.m_t, 0.0001f));
  143. // Test non-uniform sampling.
  144. indexA = InvalidIndex;
  145. indexB = InvalidIndex;
  146. t = -1.0f;
  147. MotionData::CalculateInterpolationIndicesNonUniform(track, testSample.m_sampleTime, indexA, indexB, t);
  148. EXPECT_EQ(indexA, testSample.m_indexA);
  149. EXPECT_EQ(indexB, testSample.m_indexB);
  150. EXPECT_TRUE(AZ::IsClose(t, testSample.m_t, 0.0001f));
  151. }
  152. }
  153. }; // namespace EMotionFX