1 /*
2  * Copyright 2013 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include "interpolator.h"
18 #include <math.h>
19 #include "interpolator.h"
20 
21 namespace ndk_helper
22 {
23 
24 //-------------------------------------------------
25 //Ctor
26 //-------------------------------------------------
Interpolator()27 Interpolator::Interpolator()
28 {
29     list_params_.clear();
30 }
31 
32 //-------------------------------------------------
33 //Dtor
34 //-------------------------------------------------
~Interpolator()35 Interpolator::~Interpolator()
36 {
37     list_params_.clear();
38 }
39 
Clear()40 void Interpolator::Clear()
41 {
42     list_params_.clear();
43 }
44 
Set(const float start,const float dest,const INTERPOLATOR_TYPE type,const double duration)45 Interpolator& Interpolator::Set( const float start,
46         const float dest,
47         const INTERPOLATOR_TYPE type,
48         const double duration )
49 {
50     //init the parameters for the interpolation process
51     start_time_ = PerfMonitor::GetCurrentTime();
52     dest_time_ = start_time_ + duration;
53     type_ = type;
54 
55     start_value_ = start;
56     dest_value_ = dest;
57     return *this;
58 }
59 
Add(const float dest,const INTERPOLATOR_TYPE type,const double duration)60 Interpolator& Interpolator::Add( const float dest,
61         const INTERPOLATOR_TYPE type,
62         const double duration )
63 {
64     InterpolatorParams param;
65     param.dest_value_ = dest;
66     param.type_ = type;
67     param.duration_ = duration;
68     list_params_.push_back( param );
69     return *this;
70 }
71 
Update(const double current_time,float & p)72 bool Interpolator::Update( const double current_time, float& p )
73 {
74     bool bContinue;
75     if( current_time >= dest_time_ )
76     {
77         p = dest_value_;
78         if( list_params_.size() )
79         {
80             InterpolatorParams& item = list_params_.front();
81             Set( dest_value_, item.dest_value_, item.type_, item.duration_ );
82             list_params_.pop_front();
83 
84             bContinue = true;
85         }
86         else
87         {
88             bContinue = false;
89         }
90     }
91     else
92     {
93         float t = (float) (current_time - start_time_);
94         float d = (float) (dest_time_ - start_time_);
95         float b = start_value_;
96         float c = dest_value_ - start_value_;
97         p = GetFormula( type_, t, b, d, c );
98 
99         bContinue = true;
100     }
101     return bContinue;
102 }
103 
GetFormula(const INTERPOLATOR_TYPE type,const float t,const float b,const float d,const float c)104 float Interpolator::GetFormula( const INTERPOLATOR_TYPE type,
105         const float t,
106         const float b,
107         const float d,
108         const float c )
109 {
110     float t1;
111     switch( type )
112     {
113     case INTERPOLATOR_TYPE_LINEAR:
114         // simple linear interpolation - no easing
115         return (c * t / d + b);
116 
117     case INTERPOLATOR_TYPE_EASEINQUAD:
118         // quadratic (t^2) easing in - accelerating from zero velocity
119         t1 = t / d;
120         return (c * t1 * t1 + b);
121 
122     case INTERPOLATOR_TYPE_EASEOUTQUAD:
123         // quadratic (t^2) easing out - decelerating to zero velocity
124         t1 = t / d;
125         return (-c * t1 * (t1 - 2) + b);
126 
127     case INTERPOLATOR_TYPE_EASEINOUTQUAD:
128         // quadratic easing in/out - acceleration until halfway, then deceleration
129         t1 = t / d / 2;
130         if( t1 < 1 )
131             return (c / 2 * t1 * t1 + b);
132         else
133         {
134             t1 = t1 - 1;
135             return (-c / 2 * (t1 * (t1 - 2) - 1) + b);
136         }
137     case INTERPOLATOR_TYPE_EASEINCUBIC:
138         // cubic easing in - accelerating from zero velocity
139         t1 = t / d;
140         return (c * t1 * t1 * t1 + b);
141 
142     case INTERPOLATOR_TYPE_EASEOUTCUBIC:
143         // cubic easing in - accelerating from zero velocity
144         t1 = t / d - 1;
145         return (c * (t1 * t1 * t1 + 1) + b);
146 
147     case INTERPOLATOR_TYPE_EASEINOUTCUBIC:
148         // cubic easing in - accelerating from zero velocity
149         t1 = t / d / 2;
150 
151         if( t1 < 1 )
152             return (c / 2 * t1 * t1 * t1 + b);
153         else
154         {
155             t1 -= 2;
156             return (c / 2 * (t1 * t1 * t1 + 2) + b);
157         }
158     case INTERPOLATOR_TYPE_EASEINQUART:
159         // quartic easing in - accelerating from zero velocity
160         t1 = t / d;
161         return (c * t1 * t1 * t1 * t1 + b);
162 
163     case INTERPOLATOR_TYPE_EASEINEXPO:
164         // exponential (2^t) easing in - accelerating from zero velocity
165         if( t == 0 )
166             return b;
167         else
168             return (c * powf( 2, (10 * (t / d - 1)) ) + b);
169 
170     case INTERPOLATOR_TYPE_EASEOUTEXPO:
171         // exponential (2^t) easing out - decelerating to zero velocity
172         if( t == d )
173             return (b + c);
174         else
175             return (c * (-powf( 2, -10 * t / d ) + 1) + b);
176     default:
177         return 0;
178     }
179 }
180 
181 }   //namespace ndkHelper
182