• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2019 Google LLC
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef TimeUtils_DEFINED
6 #define TimeUtils_DEFINED
7 
8 #include "include/core/SkTypes.h"
9 #include "include/private/SkFloatingPoint.h"
10 
11 #include <cmath>
12 
13 namespace TimeUtils {
14     // Returns 0 if the timer is stopped. Behavior is undefined if the timer
15     // has been running longer than SK_MSecMax.
NanosToMSec(double nanos)16     static inline SkMSec NanosToMSec(double nanos) {
17         const double msec = nanos * 1e-6;
18         SkASSERT(SK_MSecMax >= msec);
19         return static_cast<SkMSec>(msec);
20     }
21 
NanosToSeconds(double nanos)22     static inline double NanosToSeconds(double nanos) {
23         return nanos * 1e-9;
24     }
25 
26     // Return the time scaled by "speed" and (if not zero) mod by period.
27     static inline float Scaled(float time, float speed, float period = 0) {
28         double value = time * speed;
29         if (period) {
30             value = ::fmod(value, (double)(period));
31         }
32         return (float)value;
33     }
34 
35     // Transitions from ends->mid->ends linearly over period time. The phase
36     // specifies a phase shift in time units.
PingPong(double time,float period,float phase,float ends,float mid)37     static inline float PingPong(double time,
38                                  float period,
39                                  float phase,
40                                  float ends,
41                                  float mid) {
42         double value = ::fmod(time + phase, period);
43         double half  = period / 2.0;
44         double diff  = ::fabs(value - half);
45         return (float)(ends + (1.0 - diff / half) * (mid - ends));
46     }
47 
SineWave(double time,float periodInSecs,float phaseInSecs,float min,float max)48     static inline float SineWave(double time,
49                                  float periodInSecs,
50                                  float phaseInSecs,
51                                  float min,
52                                  float max) {
53         if (periodInSecs < 0.f) {
54             return (min + max) / 2.f;
55         }
56         double t = NanosToSeconds(time) + phaseInSecs;
57         t *= 2 * SK_FloatPI / periodInSecs;
58         float halfAmplitude = (max - min) / 2.f;
59         return halfAmplitude * std::sin(t) + halfAmplitude + min;
60     }
61 }  // namespace TimeUtils
62 #endif
63