Tween.cpp 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  1. #include "../../Include/RmlUi/Core/Tween.h"
  2. #include "../../Include/RmlUi/Core/Math.h"
  3. #include <utility>
  4. namespace Rml {
  5. namespace TweenFunctions {
  6. /**
  7. Tweening functions below.
  8. Partly based on http://libclaw.sourceforge.net/tweeners.html
  9. */
  10. static inline float square(float t)
  11. {
  12. return t * t;
  13. }
  14. static float back(float t)
  15. {
  16. return t * t * (2.70158f * t - 1.70158f);
  17. }
  18. static float bounce(float t)
  19. {
  20. if (t > 1.f - 1.f / 2.75f)
  21. return 1.f - 7.5625f * square(1.f - t);
  22. else if (t > 1.f - 2.f / 2.75f)
  23. return 1.0f - (7.5625f * square(1.f - t - 1.5f / 2.75f) + 0.75f);
  24. else if (t > 1.f - 2.5f / 2.75f)
  25. return 1.0f - (7.5625f * square(1.f - t - 2.25f / 2.75f) + 0.9375f);
  26. return 1.0f - (7.5625f * square(1.f - t - 2.625f / 2.75f) + 0.984375f);
  27. }
  28. static float circular(float t)
  29. {
  30. return 1.f - Math::SquareRoot(1.f - t * t);
  31. }
  32. static float cubic(float t)
  33. {
  34. return t * t * t;
  35. }
  36. static float elastic(float t)
  37. {
  38. if (t == 0)
  39. return t;
  40. if (t == 1)
  41. return t;
  42. return -Math::Exp(7.24f * (t - 1.f)) * Math::Sin((t - 1.1f) * 2.f * Math::RMLUI_PI / 0.4f);
  43. }
  44. static float exponential(float t)
  45. {
  46. if (t == 0)
  47. return t;
  48. if (t == 1)
  49. return t;
  50. return Math::Exp(7.24f * (t - 1.f));
  51. }
  52. static float linear(float t)
  53. {
  54. return t;
  55. }
  56. static float quadratic(float t)
  57. {
  58. return t * t;
  59. }
  60. static float quartic(float t)
  61. {
  62. return t * t * t * t;
  63. }
  64. static float quintic(float t)
  65. {
  66. return t * t * t * t * t;
  67. }
  68. static float sine(float t)
  69. {
  70. return 1.f - Math::Cos(t * Math::RMLUI_PI * 0.5f);
  71. }
  72. } // namespace TweenFunctions
  73. Tween::Tween(Type type, Direction direction)
  74. {
  75. if (direction & In)
  76. type_in = type;
  77. if (direction & Out)
  78. type_out = type;
  79. }
  80. Tween::Tween(Type type_in, Type type_out) : type_in(type_in), type_out(type_out) {}
  81. Tween::Tween(CallbackFnc callback, Direction direction) : callback(callback)
  82. {
  83. if (direction & In)
  84. type_in = Callback;
  85. if (direction & Out)
  86. type_out = Callback;
  87. }
  88. float Tween::operator()(float t) const
  89. {
  90. if (type_in != None && type_out == None)
  91. {
  92. return in(t);
  93. }
  94. if (type_in == None && type_out != None)
  95. {
  96. return out(t);
  97. }
  98. if (type_in != None && type_out != None)
  99. {
  100. return in_out(t);
  101. }
  102. return t;
  103. }
  104. void Tween::reverse()
  105. {
  106. std::swap(type_in, type_out);
  107. }
  108. bool Tween::operator==(const Tween& other) const
  109. {
  110. return type_in == other.type_in && type_out == other.type_out && callback == other.callback;
  111. }
  112. bool Tween::operator!=(const Tween& other) const
  113. {
  114. return !(*this == other);
  115. }
  116. String Tween::to_string() const
  117. {
  118. static const Array<String, size_t(Count)> type_str = {
  119. {"none", "back", "bounce", "circular", "cubic", "elastic", "exponential", "linear", "quadratic", "quartic", "quintic", "sine", "callback"}};
  120. if (size_t(type_in) < type_str.size() && size_t(type_out) < type_str.size())
  121. {
  122. if (type_in == None && type_out == None)
  123. {
  124. return "none";
  125. }
  126. else if (type_in == type_out)
  127. {
  128. return type_str[size_t(type_in)] + String("-in-out");
  129. }
  130. else if (type_in == None)
  131. {
  132. return type_str[size_t(type_out)] + String("-out");
  133. }
  134. else if (type_out == None)
  135. {
  136. return type_str[size_t(type_in)] + String("-in");
  137. }
  138. else if (type_in != type_out)
  139. {
  140. return type_str[size_t(type_in)] + String("-in-") + type_str[size_t(type_out)] + String("-out");
  141. }
  142. }
  143. return "unknown";
  144. }
  145. float Tween::tween(Type type, float t) const
  146. {
  147. using namespace TweenFunctions;
  148. switch (type)
  149. {
  150. case Back: return back(t);
  151. case Bounce: return bounce(t);
  152. case Circular: return circular(t);
  153. case Cubic: return cubic(t);
  154. case Elastic: return elastic(t);
  155. case Exponential: return exponential(t);
  156. case Linear: return linear(t);
  157. case Quadratic: return quadratic(t);
  158. case Quartic: return quartic(t);
  159. case Quintic: return quintic(t);
  160. case Sine: return sine(t);
  161. case Callback:
  162. if (callback)
  163. return (*callback)(t);
  164. break;
  165. default: break;
  166. }
  167. return t;
  168. }
  169. float Tween::in(float t) const
  170. {
  171. return tween(type_in, t);
  172. }
  173. float Tween::out(float t) const
  174. {
  175. return 1.0f - tween(type_out, 1.0f - t);
  176. }
  177. float Tween::in_out(float t) const
  178. {
  179. if (t < 0.5f)
  180. return tween(type_in, 2.0f * t) * 0.5f;
  181. else
  182. return 0.5f + out(2.0f * t - 1.0f) * 0.5f;
  183. }
  184. } // namespace Rml