💿🐜 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.

378 lines
9.0 KiB

7 years ago
7 years ago
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. #ifndef TWEEN_HPP
  20. #define TWEEN_HPP
  21. #include <algorithm>
  22. #include <functional>
  23. #include <list>
  24. #include <iostream>
  25. #include <emergent/emergent.hpp>
  26. using namespace Emergent;
  27. /// @see http://easings.net/
  28. /// @see http://wiki.unity3d.com/index.php?title=Tween
  29. enum class EaseFunction
  30. {
  31. LINEAR,
  32. IN_SINE,
  33. OUT_SINE,
  34. IN_OUT_SINE,
  35. IN_QUAD,
  36. OUT_QUAD,
  37. IN_OUT_QUAD,
  38. IN_CUBIC,
  39. OUT_CUBIC,
  40. IN_OUT_CUBIC,
  41. IN_QUART,
  42. OUT_QUART,
  43. IN_OUT_QUART,
  44. IN_QUINT,
  45. OUT_QUINT,
  46. IN_OUT_QUINT,
  47. IN_EXPO,
  48. OUT_EXPO,
  49. IN_OUT_EXPO,
  50. IN_CIRC,
  51. OUT_CIRC,
  52. IN_OUT_CIRC,
  53. IN_BACK,
  54. OUT_BACK,
  55. IN_OUT_BACK,
  56. IN_BOUNCE,
  57. OUT_BOUNCE,
  58. IN_OUT_BOUNCE
  59. };
  60. class TweenBase
  61. {
  62. public:
  63. TweenBase(EaseFunction function, float time, float duration);
  64. TweenBase();
  65. virtual ~TweenBase();
  66. void start();
  67. void stop();
  68. void pause();
  69. void reset();
  70. void setEaseFunction(EaseFunction function);
  71. void setTime(float time);
  72. void setDuration(float duration);
  73. EaseFunction getEaseFunction() const;
  74. float getTime() const;
  75. float getDuration() const;
  76. bool isStopped() const;
  77. bool wasStopped() const;
  78. bool isPaused() const;
  79. protected:
  80. typedef float (*EaseFunctionPointer)(float, float, float, float);
  81. EaseFunction easeFunction;
  82. EaseFunctionPointer easeFunctionPointer;
  83. float time;
  84. float duration;
  85. bool stopped;
  86. bool oldStopped;
  87. bool paused;
  88. private:
  89. friend class Tweener;
  90. static const EaseFunctionPointer easeFunctionPointers[28];
  91. virtual void update(float dt) = 0;
  92. static float easeLinear(float t, float b, float c, float d);
  93. static float easeInSine(float t, float b, float c, float d);
  94. static float easeOutSine(float t, float b, float c, float d);
  95. static float easeInOutSine(float t, float b, float c, float d);
  96. static float easeInQuad(float t, float b, float c, float d);
  97. static float easeOutQuad(float t, float b, float c, float d);
  98. static float easeInOutQuad(float t, float b, float c, float d);
  99. static float easeInCubic(float t, float b, float c, float d);
  100. static float easeOutCubic(float t, float b, float c, float d);
  101. static float easeInOutCubic(float t, float b, float c, float d);
  102. static float easeInQuart(float t, float b, float c, float d);
  103. static float easeOutQuart(float t, float b, float c, float d);
  104. static float easeInOutQuart(float t, float b, float c, float d);
  105. static float easeInQuint(float t, float b, float c, float d);
  106. static float easeOutQuint(float t, float b, float c, float d);
  107. static float easeInOutQuint(float t, float b, float c, float d);
  108. static float easeInExpo(float t, float b, float c, float d);
  109. static float easeOutExpo(float t, float b, float c, float d);
  110. static float easeInOutExpo(float t, float b, float c, float d);
  111. static float easeInCirc(float t, float b, float c, float d);
  112. static float easeOutCirc(float t, float b, float c, float d);
  113. static float easeInOutCirc(float t, float b, float c, float d);
  114. static float easeInBack(float t, float b, float c, float d);
  115. static float easeOutBack(float t, float b, float c, float d);
  116. static float easeInOutBack(float t, float b, float c, float d);
  117. static float easeInBounce(float t, float b, float c, float d);
  118. static float easeOutBounce(float t, float b, float c, float d);
  119. static float easeInOutBounce(float t, float b, float c, float d);
  120. };
  121. inline EaseFunction TweenBase::getEaseFunction() const
  122. {
  123. return easeFunction;
  124. }
  125. inline float TweenBase::getTime() const
  126. {
  127. return time;
  128. }
  129. inline float TweenBase::getDuration() const
  130. {
  131. return duration;
  132. }
  133. inline bool TweenBase::isStopped() const
  134. {
  135. return stopped;
  136. }
  137. inline bool TweenBase::wasStopped() const
  138. {
  139. return oldStopped;
  140. }
  141. inline bool TweenBase::isPaused() const
  142. {
  143. return paused;
  144. }
  145. template <typename T>
  146. class Tween: public TweenBase
  147. {
  148. public:
  149. Tween(EaseFunction function, float time, float duration, const T& startValue, const T& deltaValue);
  150. Tween();
  151. virtual ~Tween();
  152. void setStartValue(const T& startValue);
  153. void setDeltaValue(const T& deltaValue);
  154. void setStartCallback(std::function<void(const T&)> callback);
  155. void setUpdateCallback(std::function<void(const T&)> callback);
  156. void setEndCallback(std::function<void(const T&)> callback);
  157. const T& getStartValue() const;
  158. const T& getDeltaValue() const;
  159. const T& getTweenValue() const;
  160. std::function<void(const T&)> getStartCallback() const;
  161. std::function<void(const T&)> getUpdateCallback() const;
  162. std::function<void(const T&)> getEndCallback() const;
  163. private:
  164. virtual void update(float dt);
  165. void calculateTweenValue();
  166. T startValue;
  167. T deltaValue;
  168. T tweenValue;
  169. std::function<void(const T&)> startCallback;
  170. std::function<void(const T&)> updateCallback;
  171. std::function<void(const T&)> endCallback;
  172. };
  173. template <typename T>
  174. Tween<T>::Tween(EaseFunction function, float time, float duration, const T& startValue, const T& deltaValue):
  175. TweenBase(function, time, duration),
  176. startValue(startValue),
  177. deltaValue(deltaValue),
  178. tweenValue(startValue),
  179. startCallback(nullptr),
  180. updateCallback(nullptr),
  181. endCallback(nullptr)
  182. {}
  183. template <typename T>
  184. Tween<T>::Tween():
  185. startCallback(nullptr),
  186. updateCallback(nullptr),
  187. endCallback(nullptr)
  188. {}
  189. template <typename T>
  190. Tween<T>::~Tween()
  191. {}
  192. template <typename T>
  193. void Tween<T>::update(float dt)
  194. {
  195. if (isStopped() || isPaused())
  196. {
  197. return;
  198. }
  199. // Check if tween was just started
  200. if (!isStopped() && wasStopped())
  201. {
  202. // Execute start callback
  203. if (startCallback != nullptr)
  204. {
  205. startCallback(startValue);
  206. }
  207. }
  208. oldStopped = stopped;
  209. // Add delta time to time and calculate tween value
  210. time = std::min<float>(duration, time + dt);
  211. calculateTweenValue();
  212. // Execute update callback
  213. if (updateCallback != nullptr)
  214. {
  215. updateCallback(tweenValue);
  216. }
  217. // Check if tween has ended
  218. if (time >= duration)
  219. {
  220. if (!isStopped())
  221. {
  222. // Stop tween
  223. stop();
  224. // Execute end callback
  225. if (endCallback != nullptr)
  226. {
  227. endCallback(tweenValue);
  228. }
  229. }
  230. }
  231. }
  232. template <typename T>
  233. inline void Tween<T>::setStartValue(const T& startValue)
  234. {
  235. this->startValue = startValue;
  236. }
  237. template <typename T>
  238. inline void Tween<T>::setDeltaValue(const T& deltaValue)
  239. {
  240. this->deltaValue = deltaValue;
  241. }
  242. template <typename T>
  243. inline void Tween<T>::setStartCallback(std::function<void(const T&)> callback)
  244. {
  245. this->startCallback = callback;
  246. }
  247. template <typename T>
  248. inline void Tween<T>::setUpdateCallback(std::function<void(const T&)> callback)
  249. {
  250. this->updateCallback = callback;
  251. }
  252. template <typename T>
  253. inline void Tween<T>::setEndCallback(std::function<void(const T&)> callback)
  254. {
  255. this->endCallback = callback;
  256. }
  257. template <typename T>
  258. inline const T& Tween<T>::getStartValue() const
  259. {
  260. return startValue;
  261. }
  262. template <typename T>
  263. inline const T& Tween<T>::getDeltaValue() const
  264. {
  265. return deltaValue;
  266. }
  267. template <typename T>
  268. inline const T& Tween<T>::getTweenValue() const
  269. {
  270. return tweenValue;
  271. }
  272. template <typename T>
  273. inline std::function<void(const T&)> Tween<T>::getStartCallback() const
  274. {
  275. return startCallback;
  276. }
  277. template <typename T>
  278. inline std::function<void(const T&)> Tween<T>::getUpdateCallback() const
  279. {
  280. return updateCallback;
  281. }
  282. template <typename T>
  283. inline std::function<void(const T&)> Tween<T>::getEndCallback() const
  284. {
  285. return endCallback;
  286. }
  287. template <typename T>
  288. inline void Tween<T>::calculateTweenValue()
  289. {
  290. tweenValue = easeFunctionPointer(time, startValue, deltaValue, duration);
  291. }
  292. template <>
  293. inline void Tween<Vector2>::calculateTweenValue()
  294. {
  295. tweenValue.x = easeFunctionPointer(time, startValue.x, deltaValue.x, duration);
  296. tweenValue.y = easeFunctionPointer(time, startValue.y, deltaValue.y, duration);
  297. }
  298. template <>
  299. inline void Tween<Vector3>::calculateTweenValue()
  300. {
  301. tweenValue.x = easeFunctionPointer(time, startValue.x, deltaValue.x, duration);
  302. tweenValue.y = easeFunctionPointer(time, startValue.y, deltaValue.y, duration);
  303. tweenValue.z = easeFunctionPointer(time, startValue.z, deltaValue.z, duration);
  304. }
  305. template <>
  306. inline void Tween<Vector4>::calculateTweenValue()
  307. {
  308. tweenValue.x = easeFunctionPointer(time, startValue.x, deltaValue.x, duration);
  309. tweenValue.y = easeFunctionPointer(time, startValue.y, deltaValue.y, duration);
  310. tweenValue.z = easeFunctionPointer(time, startValue.z, deltaValue.z, duration);
  311. tweenValue.w = easeFunctionPointer(time, startValue.w, deltaValue.w, duration);
  312. }
  313. class Tweener
  314. {
  315. public:
  316. void update(float dt);
  317. void addTween(TweenBase* tween);
  318. void removeTween(TweenBase* tween);
  319. void removeTweens();
  320. private:
  321. std::list<TweenBase*> tweens;
  322. };
  323. #endif // TWEEN_HPP