1 // Copyright 2017 The Draco Authors.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //      http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 //
15 #include "draco/animation/keyframe_animation.h"
16 
17 #include "draco/core/draco_test_base.h"
18 
19 namespace {
20 
21 class KeyframeAnimationTest : public ::testing::Test {
22  protected:
KeyframeAnimationTest()23   KeyframeAnimationTest() {}
24 
CreateAndAddTimestamps(int32_t num_frames)25   bool CreateAndAddTimestamps(int32_t num_frames) {
26     timestamps_.resize(num_frames);
27     for (int i = 0; i < timestamps_.size(); ++i) {
28       timestamps_[i] = static_cast<draco::KeyframeAnimation::TimestampType>(i);
29     }
30     return keyframe_animation_.SetTimestamps(timestamps_);
31   }
32 
CreateAndAddAnimationData(int32_t num_frames,uint32_t num_components)33   int32_t CreateAndAddAnimationData(int32_t num_frames,
34                                     uint32_t num_components) {
35     // Create and add animation data with.
36     animation_data_.resize(num_frames * num_components);
37     for (int i = 0; i < animation_data_.size(); ++i) {
38       animation_data_[i] = static_cast<float>(i);
39     }
40     return keyframe_animation_.AddKeyframes(draco::DT_FLOAT32, num_components,
41                                             animation_data_);
42   }
43 
44   template <int num_components_t>
CompareAnimationData()45   void CompareAnimationData() {
46     // Compare time stamp.
47     const auto timestamp_att = keyframe_animation_.timestamps();
48     for (int i = 0; i < timestamps_.size(); ++i) {
49       std::array<float, 1> att_value;
50       ASSERT_TRUE((timestamp_att->GetValue<float, 1>(
51           draco::AttributeValueIndex(i), &att_value)));
52       ASSERT_FLOAT_EQ(att_value[0], i);
53     }
54 
55     // Compare keyframe data.
56     const auto keyframe_att = keyframe_animation_.keyframes(1);
57     for (int i = 0; i < animation_data_.size() / num_components_t; ++i) {
58       std::array<float, num_components_t> att_value;
59       ASSERT_TRUE((keyframe_att->GetValue<float, num_components_t>(
60           draco::AttributeValueIndex(i), &att_value)));
61       for (int j = 0; j < num_components_t; ++j) {
62         ASSERT_FLOAT_EQ(att_value[j], i * num_components_t + j);
63       }
64     }
65   }
66 
67   template <int num_components_t>
TestKeyframeAnimation(int32_t num_frames)68   void TestKeyframeAnimation(int32_t num_frames) {
69     ASSERT_TRUE(CreateAndAddTimestamps(num_frames));
70     ASSERT_EQ(CreateAndAddAnimationData(num_frames, num_components_t), 1);
71     CompareAnimationData<num_components_t>();
72   }
73 
74   draco::KeyframeAnimation keyframe_animation_;
75   std::vector<draco::KeyframeAnimation::TimestampType> timestamps_;
76   std::vector<float> animation_data_;
77 };
78 
79 // Test animation with 1 component and 10 frames.
TEST_F(KeyframeAnimationTest,OneComponent)80 TEST_F(KeyframeAnimationTest, OneComponent) { TestKeyframeAnimation<1>(10); }
81 
82 // Test animation with 4 component and 10 frames.
TEST_F(KeyframeAnimationTest,FourComponent)83 TEST_F(KeyframeAnimationTest, FourComponent) { TestKeyframeAnimation<4>(10); }
84 
85 // Test adding animation data before timestamp.
TEST_F(KeyframeAnimationTest,AddingAnimationFirst)86 TEST_F(KeyframeAnimationTest, AddingAnimationFirst) {
87   ASSERT_EQ(CreateAndAddAnimationData(5, 1), 1);
88   ASSERT_TRUE(CreateAndAddTimestamps(5));
89 }
90 
91 // Test adding timestamp more than once.
TEST_F(KeyframeAnimationTest,ErrorAddingTimestampsTwice)92 TEST_F(KeyframeAnimationTest, ErrorAddingTimestampsTwice) {
93   ASSERT_TRUE(CreateAndAddTimestamps(5));
94   ASSERT_FALSE(CreateAndAddTimestamps(5));
95 }
96 // Test animation with multiple animation data.
TEST_F(KeyframeAnimationTest,MultipleAnimationData)97 TEST_F(KeyframeAnimationTest, MultipleAnimationData) {
98   const int num_frames = 5;
99   ASSERT_TRUE(CreateAndAddTimestamps(num_frames));
100   ASSERT_EQ(CreateAndAddAnimationData(num_frames, 1), 1);
101   ASSERT_EQ(CreateAndAddAnimationData(num_frames, 2), 2);
102 }
103 
104 }  // namespace
105