// 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/SkFloatingPoint.h" #include 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(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