blob: daeee613e9eb603e89929d156692dbabf5bf59c5 [file] [log] [blame]
Andrew Top2a796462018-06-29 09:04:04 -07001// Copyright 2016 The Cobalt Authors. All Rights Reserved.
David Ghandehari60170302017-03-10 21:18:13 -08002//
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.
David Ghandehari9e5b5872016-07-28 09:50:04 -070014
David Ghandehari9e5b5872016-07-28 09:50:04 -070015#include "cobalt/renderer/smoothed_value.h"
Andrew Top0d1858f2019-05-15 22:01:47 -070016#include "base/time/time.h"
David Ghandehari9e5b5872016-07-28 09:50:04 -070017#include "testing/gtest/include/gtest/gtest.h"
18
19using cobalt::renderer::SmoothedValue;
20
21namespace {
22base::TimeTicks SecondsToTime(double seconds) {
23 return base::TimeTicks() + base::TimeDelta::FromSecondsD(seconds);
24}
25} // namespace
26
27TEST(SmoothedValueTest, FirstValueSnaps) {
28 SmoothedValue value(base::TimeDelta::FromSeconds(1));
29
30 value.SetTarget(0.5, SecondsToTime(0.0));
31
32 EXPECT_EQ(0.5, value.GetValueAtTime(SecondsToTime(0.0)));
33 EXPECT_EQ(0.5, value.GetValueAtTime(SecondsToTime(0.5)));
34 EXPECT_EQ(0.5, value.GetValueAtTime(SecondsToTime(1.0)));
35 EXPECT_EQ(0.5, value.GetValueAtTime(SecondsToTime(1.5)));
36}
37
38TEST(SmoothedValueTest, BezierSplineValues) {
39 SmoothedValue value(base::TimeDelta::FromSeconds(1));
40
41 value.SetTarget(0.0, SecondsToTime(0.0));
42 value.SetTarget(1.0, SecondsToTime(1.0));
43
44 EXPECT_DOUBLE_EQ(0.0, value.GetValueAtTime(SecondsToTime(1.0)));
45 EXPECT_DOUBLE_EQ(0.104, value.GetValueAtTime(SecondsToTime(1.2)));
46 EXPECT_DOUBLE_EQ(0.5, value.GetValueAtTime(SecondsToTime(1.5)));
47 EXPECT_DOUBLE_EQ(0.784, value.GetValueAtTime(SecondsToTime(1.7)));
48 EXPECT_DOUBLE_EQ(1.0, value.GetValueAtTime(SecondsToTime(2.0)));
49 EXPECT_DOUBLE_EQ(1.0, value.GetValueAtTime(SecondsToTime(2.5)));
50}
51
52TEST(SmoothedValueTest, BezierSplineFromSecondToThirdTarget) {
53 // Setup an initial source and target value, and then half-way through that
54 // transition, setup a new target value, and ensure that we transition
55 // smoothly to it from within the first transition.
56 SmoothedValue value(base::TimeDelta::FromSeconds(1));
57
58 value.SetTarget(0.0, SecondsToTime(0.0));
59 value.SetTarget(1.0, SecondsToTime(1.0));
60 value.SetTarget(2.0, SecondsToTime(2.0));
61
62 EXPECT_DOUBLE_EQ(1.0, value.GetValueAtTime(SecondsToTime(2.0)));
63 EXPECT_DOUBLE_EQ(1.104, value.GetValueAtTime(SecondsToTime(2.2)));
64 EXPECT_DOUBLE_EQ(1.5, value.GetValueAtTime(SecondsToTime(2.5)));
65 EXPECT_DOUBLE_EQ(1.784, value.GetValueAtTime(SecondsToTime(2.7)));
66 EXPECT_DOUBLE_EQ(2.0, value.GetValueAtTime(SecondsToTime(3.0)));
67 EXPECT_DOUBLE_EQ(2.0, value.GetValueAtTime(SecondsToTime(3.5)));
68}
69
70TEST(SmoothedValueTest, SnapToTarget) {
71 SmoothedValue value(base::TimeDelta::FromSeconds(1));
72
73 value.SetTarget(0.0, SecondsToTime(0.0));
74 value.SetTarget(1.0, SecondsToTime(1.0));
75 value.SnapToTarget();
76
77 EXPECT_DOUBLE_EQ(1.0, value.GetValueAtTime(SecondsToTime(1.0)));
78 EXPECT_DOUBLE_EQ(1.0, value.GetValueAtTime(SecondsToTime(1.2)));
79 EXPECT_DOUBLE_EQ(1.0, value.GetValueAtTime(SecondsToTime(1.5)));
80 EXPECT_DOUBLE_EQ(1.0, value.GetValueAtTime(SecondsToTime(1.7)));
81 EXPECT_DOUBLE_EQ(1.0, value.GetValueAtTime(SecondsToTime(2.0)));
82 EXPECT_DOUBLE_EQ(1.0, value.GetValueAtTime(SecondsToTime(2.5)));
83}
84
85TEST(SmoothedValueTest, TransitionFromTransition) {
86 // Setup an initial source and target value, and then half-way through that
87 // transition, setup a new target value, and ensure that we transition
88 // smoothly to it from within the first transition.
89 SmoothedValue value(base::TimeDelta::FromSeconds(1));
90
91 value.SetTarget(0.0, SecondsToTime(0.0));
92 value.SetTarget(1.0, SecondsToTime(1.0));
93 // Retarget halfway through the previous transition.
94 value.SetTarget(2.0, SecondsToTime(1.5));
95
96 EXPECT_DOUBLE_EQ(0.5, value.GetValueAtTime(SecondsToTime(1.5)));
97 EXPECT_DOUBLE_EQ(0.848, value.GetValueAtTime(SecondsToTime(1.7)));
98 EXPECT_DOUBLE_EQ(1.4375, value.GetValueAtTime(SecondsToTime(2.0)));
99 EXPECT_DOUBLE_EQ(1.7705, value.GetValueAtTime(SecondsToTime(2.2)));
100 EXPECT_DOUBLE_EQ(2.0, value.GetValueAtTime(SecondsToTime(2.5)));
101 EXPECT_DOUBLE_EQ(2.0, value.GetValueAtTime(SecondsToTime(3.0)));
102}
Andrew Top15449552016-12-08 22:08:30 -0800103
104// If a maximum slope magnitude is specified, check that we take longer to
105// converge (in the positive direction) in order to meet that constraint.
106TEST(SmoothedValueTest, PositiveRateCapEnforced) {
107 SmoothedValue value(base::TimeDelta::FromSeconds(1), 0.5);
108
109 value.SetTarget(0.0, SecondsToTime(0.0));
110 value.SnapToTarget();
111 value.SetTarget(100.0, SecondsToTime(0.0));
112
113 EXPECT_DOUBLE_EQ(0.00083240740740740757,
114 value.GetValueAtTime(SecondsToTime(0.5)));
115 EXPECT_DOUBLE_EQ(0.0033259259259259271,
116 value.GetValueAtTime(SecondsToTime(1.0)));
117 EXPECT_DOUBLE_EQ(0.0074749999999999999,
118 value.GetValueAtTime(SecondsToTime(1.5)));
119 EXPECT_DOUBLE_EQ(7.4074074074074066,
120 value.GetValueAtTime(SecondsToTime(50.0)));
121 EXPECT_DOUBLE_EQ(25.925925925925924,
122 value.GetValueAtTime(SecondsToTime(100.0)));
123 EXPECT_DOUBLE_EQ(100.0, value.GetValueAtTime(SecondsToTime(300.0)));
124 EXPECT_DOUBLE_EQ(100.0, value.GetValueAtTime(SecondsToTime(400.0)));
125}
126
127// If a maximum slope magnitude is specified, check that we take longer to
128// converge (in the negative direction) in order to meet that constraint.
129TEST(SmoothedValueTest, NegativeRateCapEnforced) {
130 SmoothedValue value(base::TimeDelta::FromSeconds(1), 0.5);
131
132 value.SetTarget(100.0, SecondsToTime(0.0));
133 value.SnapToTarget();
134 value.SetTarget(0.0, SecondsToTime(0.0));
135
136 EXPECT_DOUBLE_EQ(99.999167592592585,
137 value.GetValueAtTime(SecondsToTime(0.5)));
138 EXPECT_DOUBLE_EQ(99.996674074074079,
139 value.GetValueAtTime(SecondsToTime(1.0)));
140 EXPECT_DOUBLE_EQ(99.992525000000001,
141 value.GetValueAtTime(SecondsToTime(1.5)));
142 EXPECT_DOUBLE_EQ(92.592592592592609,
143 value.GetValueAtTime(SecondsToTime(50.0)));
144 EXPECT_DOUBLE_EQ(74.07407407407409,
145 value.GetValueAtTime(SecondsToTime(100.0)));
146 EXPECT_DOUBLE_EQ(0.0, value.GetValueAtTime(SecondsToTime(300.0)));
147 EXPECT_DOUBLE_EQ(0.0, value.GetValueAtTime(SecondsToTime(400.0)));
148}
149
150// If a maximum slope magnitude is specified, ensure that it is not used if
151// we stay under the rate cap. Borrowing tests from TransitionFromTransition.
152TEST(SmoothedValueTest, RateCapDoesNothingIfValuesStayUnderTheCap) {
153 SmoothedValue value(base::TimeDelta::FromSeconds(1), 10.0);
154
155 value.SetTarget(0.0, SecondsToTime(0.0));
156 value.SetTarget(1.0, SecondsToTime(1.0));
157 // Retarget halfway through the previous transition.
158 value.SetTarget(2.0, SecondsToTime(1.5));
159
160 EXPECT_DOUBLE_EQ(0.5, value.GetValueAtTime(SecondsToTime(1.5)));
161 EXPECT_DOUBLE_EQ(0.848, value.GetValueAtTime(SecondsToTime(1.7)));
162 EXPECT_DOUBLE_EQ(1.4375, value.GetValueAtTime(SecondsToTime(2.0)));
163 EXPECT_DOUBLE_EQ(1.7705, value.GetValueAtTime(SecondsToTime(2.2)));
164 EXPECT_DOUBLE_EQ(2.0, value.GetValueAtTime(SecondsToTime(2.5)));
165 EXPECT_DOUBLE_EQ(2.0, value.GetValueAtTime(SecondsToTime(3.0)));
166}
167
168TEST(SmoothedValueTest, ZeroSlopeRateCapWorksFine) {
169 SmoothedValue value(base::TimeDelta::FromSeconds(1), 0.5);
170
171 value.SetTarget(50.0, SecondsToTime(0.0));
172 value.SnapToTarget();
173 value.SetTarget(50.0, SecondsToTime(0.0));
174
175 EXPECT_DOUBLE_EQ(50.0, value.GetValueAtTime(SecondsToTime(0.0)));
176 EXPECT_DOUBLE_EQ(50.0, value.GetValueAtTime(SecondsToTime(0.5)));
177 EXPECT_DOUBLE_EQ(50.0, value.GetValueAtTime(SecondsToTime(0.75)));
178 EXPECT_DOUBLE_EQ(50.0, value.GetValueAtTime(SecondsToTime(1.0)));
179}