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