/* * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or * its licensors. * * For complete copyright and license terms please see the LICENSE at the root of this * distribution (the "License"). All use of this software is governed by the License, * or, if provided, by the license below or the license accompanying this file. Do not * remove or modify any license notices. This file is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * */ #include "EMotionFX_precompiled.h" #include "SystemComponentFixture.h" #include #include #include #include namespace EMotionFX { //-------------------------------------------------------------------------- // The test fixture setup and helpers. //-------------------------------------------------------------------------- class KeyTrackLinearFixture : public SystemComponentFixture { public: KeyTrackLinearFixture() : SystemComponentFixture() { } void LogFloatTrack(KeyTrackLinear& track) { AZ_Printf("EMotionFX", "----------\n"); for (AZ::u32 i=0; i < track.GetNumKeys(); ++i) { AZ_Printf("EMotionFX", "#%d = time:%f value:%f\n", i, track.GetKey(i)->GetTime(), track.GetKey(i)->GetValue()); } } void FillFloatTrackZeroToThree(KeyTrackLinear& track) { track.ClearKeys(); track.AddKey(0.0f, 0.0f); track.AddKey(1.0f, 1.0f); track.AddKey(2.0f, 2.0f); track.AddKey(3.0f, 3.0f); track.Init(); } }; //-------------------------------------------------------------------------- // The actual tests. //-------------------------------------------------------------------------- TEST_F(KeyTrackLinearFixture, KeyTrackAdd) { EMotionFX::KeyTrackLinear track; FillFloatTrackZeroToThree(track); ASSERT_EQ(track.GetNumKeys(), 4); } TEST_F(KeyTrackLinearFixture, KeyTrackAddSorted) { EMotionFX::KeyTrackLinear track; track.AddKeySorted(1.0f, 1.0f); track.AddKeySorted(0.0f, 0.0f); track.AddKeySorted(3.0f, 3.0f); track.AddKeySorted(2.0f, 2.0f); track.Init(); ASSERT_EQ(track.GetNumKeys(), 4); ASSERT_TRUE(AZ::IsClose(track.GetKey(0)->GetTime(), 0.0f, 0.00001f)); ASSERT_TRUE(AZ::IsClose(track.GetKey(1)->GetTime(), 1.0f, 0.00001f)); ASSERT_TRUE(AZ::IsClose(track.GetKey(2)->GetTime(), 2.0f, 0.00001f)); ASSERT_TRUE(AZ::IsClose(track.GetKey(3)->GetTime(), 3.0f, 0.00001f)); } TEST_F(KeyTrackLinearFixture, KeyTrackRemoveKey) { EMotionFX::KeyTrackLinear track; FillFloatTrackZeroToThree(track); ASSERT_EQ(track.GetNumKeys(), 4); track.RemoveKey(1); track.Init(); ASSERT_FLOAT_EQ(track.GetKey(0)->GetTime(), 0.0f); ASSERT_FLOAT_EQ(track.GetKey(1)->GetTime(), 2.0f); ASSERT_FLOAT_EQ(track.GetKey(2)->GetTime(), 3.0f); track.RemoveKey(2); track.Init(); ASSERT_FLOAT_EQ(track.GetKey(0)->GetTime(), 0.0f); ASSERT_FLOAT_EQ(track.GetKey(1)->GetTime(), 2.0f); track.RemoveKey(0); track.Init(); // The time should be 0, because Init makes sure the first keyframe starts at time 0 ASSERT_FLOAT_EQ(track.GetKey(0)->GetTime(), 0.0f); track.RemoveKey(0); track.Init(); ASSERT_EQ(track.GetNumKeys(), 0); } TEST_F(KeyTrackLinearFixture, KeyTrackClearKeys) { EMotionFX::KeyTrackLinear track; FillFloatTrackZeroToThree(track); ASSERT_EQ(track.GetNumKeys(), 4); track.ClearKeys(); ASSERT_EQ(track.GetNumKeys(), 0); } TEST_F(KeyTrackLinearFixture, KeyTrackCheckIfIsAnimated) { EMotionFX::KeyTrackLinear track; FillFloatTrackZeroToThree(track); ASSERT_TRUE(track.CheckIfIsAnimated(0.0f, 0.00001f)); track.ClearKeys(); track.AddKey(0.0f, 1.0f); track.AddKey(1.0f, 1.0f); track.AddKey(2.0f, 1.0f); track.AddKey(3.0f, 1.0f); ASSERT_TRUE(!track.CheckIfIsAnimated(1.0f, 0.00001f)); track.ClearKeys(); track.AddKey(0.0f, 1.0f); track.AddKey(1.0f, 1.0f); track.AddKey(2.0f, 1.01f); track.AddKey(3.0f, 1.0f); ASSERT_TRUE(track.CheckIfIsAnimated(1.0f, 0.00001f)); } TEST_F(KeyTrackLinearFixture, KeyTrackGetFirstKey) { EMotionFX::KeyTrackLinear track; FillFloatTrackZeroToThree(track); ASSERT_FLOAT_EQ(track.GetFirstKey()->GetTime(), 0.0f); ASSERT_FLOAT_EQ(track.GetFirstKey()->GetValue(), 0.0f); track.RemoveKey(2); track.Init(); ASSERT_FLOAT_EQ(track.GetFirstKey()->GetTime(), 0.0f); ASSERT_FLOAT_EQ(track.GetFirstKey()->GetValue(), 0.0f); track.RemoveKey(0); track.Init(); // Time value is expected to be 0 for the first key, after calling Init. // It is remapped internally to 0, if the first key's time isn't. // The value remains the same though. ASSERT_FLOAT_EQ(track.GetFirstKey()->GetTime(), 0.0f); ASSERT_FLOAT_EQ(track.GetFirstKey()->GetValue(), 1.0f); track.ClearKeys(); track.Init(); ASSERT_TRUE(!track.GetFirstKey()); } TEST_F(KeyTrackLinearFixture, KeyTrackGetLastKey) { EMotionFX::KeyTrackLinear track; FillFloatTrackZeroToThree(track); ASSERT_FLOAT_EQ(track.GetLastKey()->GetTime(), 3.0f); ASSERT_FLOAT_EQ(track.GetLastKey()->GetValue(), 3.0f); track.RemoveKey(2); track.Init(); ASSERT_FLOAT_EQ(track.GetLastKey()->GetTime(), 3.0f); ASSERT_FLOAT_EQ(track.GetLastKey()->GetValue(), 3.0f); track.RemoveKey(track.GetNumKeys() - 1); track.Init(); ASSERT_FLOAT_EQ(track.GetLastKey()->GetTime(), 1.0f); ASSERT_FLOAT_EQ(track.GetLastKey()->GetValue(), 1.0f); track.ClearKeys(); track.Init(); ASSERT_TRUE(!track.GetLastKey()); } TEST_F(KeyTrackLinearFixture, KeyTrackFindKeyNumber) { EMotionFX::KeyTrackLinear track; FillFloatTrackZeroToThree(track); ASSERT_EQ(track.FindKeyNumber(-1.0f), MCORE_INVALIDINDEX32); ASSERT_EQ(track.FindKeyNumber(0.0f), 0); ASSERT_EQ(track.FindKeyNumber(1.0f), 1); ASSERT_EQ(track.FindKeyNumber(2.0f), 2); ASSERT_EQ(track.FindKeyNumber(2.4f), 2); ASSERT_EQ(track.FindKeyNumber(2.8f), 2); ASSERT_EQ(track.FindKeyNumber(2.999f), 2); ASSERT_EQ(track.FindKeyNumber(3.0f), MCORE_INVALIDINDEX32); ASSERT_EQ(track.FindKeyNumber(3.001f), MCORE_INVALIDINDEX32); ASSERT_EQ(track.FindKeyNumber(4.0f), MCORE_INVALIDINDEX32); } TEST_F(KeyTrackLinearFixture, KeyTrackSetNumKeys) { EMotionFX::KeyTrackLinear track; FillFloatTrackZeroToThree(track); track.SetNumKeys(10); ASSERT_EQ(track.GetNumKeys(), 10); track.SetNumKeys(15); ASSERT_EQ(track.GetNumKeys(), 15); track.SetNumKeys(5); ASSERT_EQ(track.GetNumKeys(), 5); track.SetNumKeys(0); ASSERT_EQ(track.GetNumKeys(), 0); } TEST_F(KeyTrackLinearFixture, KeyTrackOptimize) { EMotionFX::KeyTrackLinear track; track.AddKey(0.0f, 0.0f); track.AddKey(1.0f, 1.0f); track.AddKey(2.0f, 2.0f); track.AddKey(3.0f, 3.0f); track.Init(); track.Optimize(0.00001f); ASSERT_EQ(track.GetNumKeys(), 2); ASSERT_FLOAT_EQ(track.GetKey(0)->GetTime(), 0.0f); ASSERT_FLOAT_EQ(track.GetKey(1)->GetTime(), 3.0f); track.ClearKeys(); track.AddKey(0.0f, 0.0f); track.AddKey(1.0f, 1.0f); track.AddKey(2.0f, 1.0f); track.AddKey(2.01f, 1.0001f); track.AddKey(3.0f, 3.0f); track.Init(); const uint32 numKeysRemoved = track.Optimize(0.001f); ASSERT_EQ(numKeysRemoved, 1); ASSERT_EQ(track.GetNumKeys(), 4); ASSERT_FLOAT_EQ(track.GetKey(0)->GetTime(), 0.0f); ASSERT_FLOAT_EQ(track.GetKey(1)->GetTime(), 1.0f); ASSERT_FLOAT_EQ(track.GetKey(2)->GetTime(), 2.01f); ASSERT_FLOAT_EQ(track.GetKey(3)->GetTime(), 3.0f); } TEST_F(KeyTrackLinearFixture, KeyTrackGetValueAtTime) { EMotionFX::KeyTrackLinear track; FillFloatTrackZeroToThree(track); ASSERT_FLOAT_EQ(track.GetValueAtTime(0.0f), 0.0f); ASSERT_FLOAT_EQ(track.GetValueAtTime(0.5f), 0.5f); ASSERT_FLOAT_EQ(track.GetValueAtTime(1.0f), 1.0f); ASSERT_FLOAT_EQ(track.GetValueAtTime(3.0f), 3.0f); ASSERT_FLOAT_EQ(track.GetValueAtTime(4.0f), 3.0f); uint8 cacheHit = 0; uint32 cached = 0; ASSERT_FLOAT_EQ(track.GetValueAtTime(0.0f, cached, cacheHit), 0.0f); ASSERT_EQ(cached, 0); ASSERT_EQ(cacheHit, 1); ASSERT_FLOAT_EQ(track.GetValueAtTime(0.5f, cached, cacheHit), 0.5f); ASSERT_EQ(cached, 0); ASSERT_EQ(cacheHit, 1); ASSERT_FLOAT_EQ(track.GetValueAtTime(1.0f, cached, cacheHit), 1.0f); ASSERT_EQ(cached, 0); ASSERT_EQ(cacheHit, 1); ASSERT_FLOAT_EQ(track.GetValueAtTime(2.999f, cached, cacheHit), 2.999f); ASSERT_EQ(cached, 2); ASSERT_EQ(cacheHit, 0); ASSERT_FLOAT_EQ(track.GetValueAtTime(0.0f, cached, cacheHit), 0.0f); ASSERT_EQ(cached, 0); ASSERT_EQ(cacheHit, 0); } } // namespace EMotionFX