💿🐜 Antkeeper source code https://antkeeper.com
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

390 lines
7.6 KiB

7 years ago
  1. /*
  2. * Copyright (C) 2017 Christopher J. Howard
  3. *
  4. * This file is part of Antkeeper Source Code.
  5. *
  6. * Antkeeper Source Code is free software: you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation, either version 3 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * Antkeeper Source Code is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with Antkeeper Source Code. If not, see <http://www.gnu.org/licenses/>.
  18. */
  19. #include "tween.hpp"
  20. #include <cmath>
  21. const TweenBase::EaseFunctionPointer TweenBase::easeFunctionPointers[] =
  22. {
  23. &TweenBase::easeLinear,
  24. &TweenBase::easeInSine,
  25. &TweenBase::easeOutSine,
  26. &TweenBase::easeInOutSine,
  27. &TweenBase::easeInQuad,
  28. &TweenBase::easeOutQuad,
  29. &TweenBase::easeInOutQuad,
  30. &TweenBase::easeInCubic,
  31. &TweenBase::easeOutCubic,
  32. &TweenBase::easeInOutCubic,
  33. &TweenBase::easeInQuart,
  34. &TweenBase::easeOutQuart,
  35. &TweenBase::easeInOutQuart,
  36. &TweenBase::easeInQuint,
  37. &TweenBase::easeOutQuint,
  38. &TweenBase::easeInOutQuint,
  39. &TweenBase::easeInExpo,
  40. &TweenBase::easeOutExpo,
  41. &TweenBase::easeInOutExpo,
  42. &TweenBase::easeInCirc,
  43. &TweenBase::easeOutCirc,
  44. &TweenBase::easeInOutCirc,
  45. &TweenBase::easeInBack,
  46. &TweenBase::easeOutBack,
  47. &TweenBase::easeInOutBack,
  48. &TweenBase::easeInBounce,
  49. &TweenBase::easeOutBounce,
  50. &TweenBase::easeInOutBounce,
  51. };
  52. TweenBase::TweenBase(EaseFunction function, float time, float duration):
  53. time(time),
  54. duration(duration),
  55. stopped(true),
  56. oldStopped(true),
  57. paused(false)
  58. {
  59. setEaseFunction(function);
  60. }
  61. TweenBase::TweenBase():
  62. time(0.0f),
  63. duration(0.0f),
  64. stopped(true),
  65. oldStopped(true),
  66. paused(false)
  67. {
  68. setEaseFunction(EaseFunction::LINEAR);
  69. }
  70. TweenBase::~TweenBase()
  71. {}
  72. void TweenBase::start()
  73. {
  74. if (stopped)
  75. {
  76. stopped = false;
  77. oldStopped = true;
  78. time = 0.0f;
  79. }
  80. else if (paused)
  81. {
  82. paused = false;
  83. }
  84. }
  85. void TweenBase::stop()
  86. {
  87. if (!stopped)
  88. {
  89. stopped = true;
  90. oldStopped = false;
  91. paused = false;
  92. }
  93. }
  94. void TweenBase::pause()
  95. {
  96. if (!stopped && !paused)
  97. {
  98. paused = true;
  99. oldStopped = false;
  100. }
  101. }
  102. void TweenBase::reset()
  103. {
  104. time = 0.0f;
  105. }
  106. inline void TweenBase::setEaseFunction(EaseFunction function)
  107. {
  108. easeFunction = function;
  109. easeFunctionPointer = easeFunctionPointers[static_cast<std::size_t>(easeFunction)];
  110. }
  111. void TweenBase::setTime(float time)
  112. {
  113. this->time = time;
  114. }
  115. void TweenBase::setDuration(float duration)
  116. {
  117. this->duration = duration;
  118. }
  119. float TweenBase::easeLinear(float t, float b, float c, float d)
  120. {
  121. return c * t / d + b;
  122. }
  123. float TweenBase::easeInSine(float t, float b, float c, float d)
  124. {
  125. return -c * std::cos(t / d * glm::half_pi<float>()) + c + b;
  126. }
  127. float TweenBase::easeOutSine(float t, float b, float c, float d)
  128. {
  129. return c * std::sin(t / d * glm::half_pi<float>()) + b;
  130. }
  131. float TweenBase::easeInOutSine(float t, float b, float c, float d)
  132. {
  133. return -c * 0.5f * (std::cos(glm::pi<float>() * t / d) - 1.0f) + b;
  134. }
  135. float TweenBase::easeInQuad(float t, float b, float c, float d)
  136. {
  137. t /= d;
  138. return c * t * t + b;
  139. }
  140. float TweenBase::easeOutQuad(float t, float b, float c, float d)
  141. {
  142. t /= d;
  143. return -c * t * (t - 2.0f) + b;
  144. }
  145. float TweenBase::easeInOutQuad(float t, float b, float c, float d)
  146. {
  147. t /= d;
  148. if ((t * 0.5f) < 1.0f)
  149. {
  150. return c * 0.5f * t * t + b;
  151. }
  152. t -= 1.0f;
  153. return -c * 0.5f * (t * (t - 2.0f) - 1.0f) + b;
  154. }
  155. float TweenBase::easeInCubic(float t, float b, float c, float d)
  156. {
  157. t /= d;
  158. return c * t * t * t + b;
  159. }
  160. float TweenBase::easeOutCubic(float t, float b, float c, float d)
  161. {
  162. t = t / d - 1.0f;
  163. return c * (t * t * t + 1.0f) + b;
  164. }
  165. float TweenBase::easeInOutCubic(float t, float b, float c, float d)
  166. {
  167. t /= d * 0.5f;
  168. if (t < 1.0f)
  169. {
  170. return c * 0.5f * t * t * t + b;
  171. }
  172. t -= 2.0f;
  173. return c * 0.5f * (t * t * t + 2.0f) + b;
  174. }
  175. float TweenBase::easeInQuart(float t, float b, float c, float d)
  176. {
  177. t /= d;
  178. return c * t * t * t * t + b;
  179. }
  180. float TweenBase::easeOutQuart(float t, float b, float c, float d)
  181. {
  182. t = t / d - 1.0f;
  183. return -c * (t * t * t * t - 1.0f) + b;
  184. }
  185. float TweenBase::easeInOutQuart(float t, float b, float c, float d)
  186. {
  187. t /= d * 0.5f;
  188. if (t < 1.0f)
  189. {
  190. return c * 0.5f * t * t * t * t + b;
  191. }
  192. t -= 2.0f;
  193. return -c * 0.5f * (t * t * t * t - 2.0f) + b;
  194. }
  195. float TweenBase::easeInQuint(float t, float b, float c, float d)
  196. {
  197. t /= d;
  198. return c * t * t * t * t * t + b;
  199. }
  200. float TweenBase::easeOutQuint(float t, float b, float c, float d)
  201. {
  202. t = t / d - 1.0f;
  203. return c * (t * t * t * t * t + 1.0f) + b;
  204. }
  205. float TweenBase::easeInOutQuint(float t, float b, float c, float d)
  206. {
  207. t /= d * 0.5f;
  208. if (t < 1.0f)
  209. {
  210. return c * 0.5f * t * t * t * t * t + b;
  211. }
  212. t -= 2.0f;
  213. return c * 0.5f * (t * t * t * t * t + 2.0f) + b;
  214. }
  215. float TweenBase::easeInExpo(float t, float b, float c, float d)
  216. {
  217. return (t == 0.0f) ? b : c * std::pow(2.0f, 10.0f * (t / d - 1.0f)) + b - c * 0.001f;
  218. }
  219. float TweenBase::easeOutExpo(float t, float b, float c, float d)
  220. {
  221. return (t == d) ? b + c : c * 1.001f * (-std::pow(2.0f, -10.0f * t / d) + 1.0f) + b;
  222. }
  223. float TweenBase::easeInOutExpo(float t, float b, float c, float d)
  224. {
  225. if (t == 0.0f)
  226. {
  227. return b;
  228. }
  229. if (t == d)
  230. {
  231. return b + c;
  232. }
  233. t /= d * 0.5f;
  234. if (t < 1.0f)
  235. {
  236. return c * 0.5f * std::pow(2.0f, 10.0f * (t - 1.0f)) + b - c * 0.0005f;
  237. }
  238. t -= 1.0f;
  239. return c * 0.5f * 1.0005f * (-std::pow(2.0f, -10.0f * t) + 2.0f) + b;
  240. }
  241. float TweenBase::easeInCirc(float t, float b, float c, float d)
  242. {
  243. t /= d;
  244. return -c * (std::sqrt(1.0f - t * t) - 1.0f) + b;
  245. }
  246. float TweenBase::easeOutCirc(float t, float b, float c, float d)
  247. {
  248. t = t / d - 1.0f;
  249. return c * std::sqrt(1.0f - t * t) + b;
  250. }
  251. float TweenBase::easeInOutCirc(float t, float b, float c, float d)
  252. {
  253. t /= d * 0.5f;
  254. if (t < 1.0f)
  255. {
  256. return -c * 0.5f * (std::sqrt(1.0f - t * t) - 1.0f) + b;
  257. }
  258. t -= 2.0f;
  259. return c * 0.5f * (std::sqrt(1.0f - t * t) + 1.0f) + b;
  260. }
  261. float TweenBase::easeInBack(float t, float b, float c, float d)
  262. {
  263. float s = 1.70158f;
  264. t /= d;
  265. return c * t * t * ((s + 1.0f) * t - s) + b;
  266. }
  267. float TweenBase::easeOutBack(float t, float b, float c, float d)
  268. {
  269. float s = 1.70158f;
  270. t = t / d - 1.0f;
  271. return c * (t * t * ((s + 1.0f) * t + s) + 1.0f) + b;
  272. }
  273. float TweenBase::easeInOutBack(float t, float b, float c, float d)
  274. {
  275. float s = 1.70158f;
  276. t /= d * 0.5f;
  277. if (t < 1.0f)
  278. {
  279. s *= 1.525f;
  280. return c * 0.5f * (t * t * ((s + 1.0f) * t - s)) + b;
  281. }
  282. t -= 2.0f;
  283. s *= 1.525f;
  284. return c * 0.5f * (t * t * ((s + 1.0f) * t + s) + 2.0f) + b;
  285. }
  286. float TweenBase::easeInBounce(float t, float b, float c, float d)
  287. {
  288. return c - easeOutBounce(d - t, 0.0f, c, d) + b;
  289. }
  290. float TweenBase::easeOutBounce(float t, float b, float c, float d)
  291. {
  292. t /= d;
  293. if (t < (1.0f / 2.75f))
  294. {
  295. return c * (7.5625f * t * t) + b;
  296. }
  297. else if (t < (2.0f / 2.75f))
  298. {
  299. t -= (1.5f / 2.75f);
  300. return c * (7.5625f * t * t + 0.75f) + b;
  301. }
  302. else if (t < (2.5f / 2.75f))
  303. {
  304. t -= (2.25f / 2.75f);
  305. return c * (7.5625f * t * t + 0.9375f) + b;
  306. }
  307. t -= (2.625f / 2.75f);
  308. return c * (7.5625f * t * t + 0.984375f) + b;
  309. }
  310. float TweenBase::easeInOutBounce(float t, float b, float c, float d)
  311. {
  312. if (t < d * 0.5f)
  313. {
  314. return easeInBounce(t * 2.0f, 0.0f, c, d) * 0.5f + b;
  315. }
  316. return easeOutBounce(t * 2.0f - d, 0.0f, c, d) * 0.5f + c * 0.5f + b;
  317. }
  318. void Tweener::update(float dt)
  319. {
  320. for (TweenBase* tween: tweens)
  321. {
  322. tween->update(dt);
  323. }
  324. }
  325. void Tweener::addTween(TweenBase* tween)
  326. {
  327. tweens.push_back(tween);
  328. }
  329. void Tweener::removeTween(TweenBase* tween)
  330. {
  331. tweens.remove(tween);
  332. }
  333. void Tweener::removeTweens()
  334. {
  335. tweens.clear();
  336. }