| // Copyright 2019 Google LLC | |
| // Use of this source code is governed by a BSD-style license that can be | |
| // found in the LICENSE file. | |
| #ifndef TimeUtils_DEFINED | |
| #define TimeUtils_DEFINED | |
| #include "include/core/SkTypes.h" | |
| #include "include/private/base/SkFloatingPoint.h" | |
| #include <cmath> | |
| namespace TimeUtils { | |
| // Returns 0 if the timer is stopped. Behavior is undefined if the timer | |
| // has been running longer than SK_MSecMax. | |
| static inline SkMSec NanosToMSec(double nanos) { | |
| const double msec = nanos * 1e-6; | |
| SkASSERT(SK_MSecMax >= msec); | |
| return static_cast<SkMSec>(msec); | |
| } | |
| static inline double NanosToSeconds(double nanos) { | |
| return nanos * 1e-9; | |
| } | |
| // Return the time scaled by "speed" and (if not zero) mod by period. | |
| static inline float Scaled(float time, float speed, float period = 0) { | |
| double value = time * speed; | |
| if (period) { | |
| value = ::fmod(value, (double)(period)); | |
| } | |
| return (float)value; | |
| } | |
| // Transitions from ends->mid->ends linearly over period time. The phase | |
| // specifies a phase shift in time units. | |
| static inline float PingPong(double time, | |
| float period, | |
| float phase, | |
| float ends, | |
| float mid) { | |
| double value = ::fmod(time + phase, period); | |
| double half = period / 2.0; | |
| double diff = ::fabs(value - half); | |
| return (float)(ends + (1.0 - diff / half) * (mid - ends)); | |
| } | |
| static inline float SineWave(double time, | |
| float periodInSecs, | |
| float phaseInSecs, | |
| float min, | |
| float max) { | |
| if (periodInSecs < 0.f) { | |
| return (min + max) / 2.f; | |
| } | |
| double t = NanosToSeconds(time) + phaseInSecs; | |
| t *= 2 * SK_FloatPI / periodInSecs; | |
| float halfAmplitude = (max - min) / 2.f; | |
| return halfAmplitude * std::sin(t) + halfAmplitude + min; | |
| } | |
| } // namespace TimeUtils | |
| #endif |