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

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