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

191 lines
5.0 KiB

  1. /*
  2. * Copyright (C) 2021 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 ANTKEEPER_TWEEN_HPP
  20. #define ANTKEEPER_TWEEN_HPP
  21. #include <algorithm>
  22. #include <functional>
  23. #include <type_traits>
  24. /**
  25. * Container which stores two states along with an interpolator, for quick and easy tween<T, S>ing.
  26. *
  27. * @tparam T Value type.
  28. * @tparam S Scalar type.
  29. */
  30. template <class T, class S = float>
  31. class tween
  32. {
  33. public:
  34. static_assert(std::is_scalar<S>::value);
  35. typedef T value_type;
  36. typedef S scalar_type;
  37. typedef typename std::decay<std::function<value_type(const value_type&, const value_type&, scalar_type)>>::type interpolator_type;
  38. private:
  39. /// Throws an error if no interpolator is set.
  40. static value_type interpolator_error(const value_type&, const value_type&, scalar_type);
  41. public:
  42. /**
  43. * Creates a tween.
  44. *
  45. * @param state0 Initial value of state 0.
  46. * @param state1 Initial value of state 1.
  47. * @param interpolator Function used to interpolate between states 0 and 1.
  48. */
  49. tween(const value_type& state0, const value_type& state1, interpolator_type interpolator = tween<T, S>::interpolator_error);
  50. /**
  51. * Creates a tween.
  52. *
  53. * @param value Initial value of states 0 and 1.
  54. * @param interpolator Function used to interpolate between states 0 and 1.
  55. */
  56. explicit tween(const value_type& value, interpolator_type interpolator = tween<T, S>::interpolator_error);
  57. /**
  58. * Creates a tween.
  59. */
  60. tween();
  61. /**
  62. * Returns a reference to the specified tween state.
  63. *
  64. * @param i Index of a tween state. Should be either `0` or `1`.
  65. * @return Reference to the specified tween state.
  66. */
  67. const value_type& operator[](int i) const;
  68. /// @copydoc tween<T, S>::operator[](int) const
  69. value_type& operator[](int i);
  70. /// @copydoc tween<T, S>::interpolate(scalar_type) const
  71. value_type operator[](scalar_type a) const;
  72. /**
  73. * Returns an interpolated state between state 0 and state 1. If no interpolator is set, state 1 will be returned.
  74. *
  75. * @param a Interpolation factor on `[0.0, 1.0]`.
  76. * @return Interpolated state, or state 1 if no interpolator is set.
  77. */
  78. value_type interpolate(scalar_type a) const;
  79. /**
  80. * Sets the function used to interpolate between states 0 and 1.
  81. *
  82. * @param interpolator Interpolator function.
  83. */
  84. void set_interpolator(const interpolator_type& interpolator);
  85. /**
  86. * Returns the function used to interpolate between states 0 and 1.
  87. */
  88. const interpolator_type& get_interpolator() const;
  89. /**
  90. * Sets state 0 = state 1.
  91. */
  92. void update();
  93. /**
  94. * Swaps state 0 and state 1.
  95. */
  96. void swap();
  97. private:
  98. value_type states[2];
  99. interpolator_type interpolator;
  100. };
  101. template <class T, class S>
  102. typename tween<T, S>::value_type tween<T, S>::interpolator_error(const value_type&, const value_type&, scalar_type)
  103. {
  104. throw std::runtime_error("tween interpolator not set");
  105. }
  106. template <class T, class S>
  107. tween<T, S>::tween(const value_type& value, interpolator_type interpolator):
  108. states{value, value},
  109. interpolator(interpolator)
  110. {}
  111. template <class T, class S>
  112. tween<T, S>::tween(const value_type& state0, const value_type& state1, interpolator_type interpolator):
  113. states{state0, state1},
  114. interpolator(interpolator)
  115. {}
  116. template <class T, class S>
  117. tween<T, S>::tween():
  118. interpolator(nullptr)
  119. {}
  120. template <class T, class S>
  121. inline const typename tween<T, S>::value_type& tween<T, S>::operator[](int i) const
  122. {
  123. return states[i];
  124. }
  125. template <class T, class S>
  126. inline typename tween<T, S>::value_type& tween<T, S>::operator[](int i)
  127. {
  128. return states[i];
  129. }
  130. template <class T, class S>
  131. inline typename tween<T, S>::value_type tween<T, S>::operator[](scalar_type a) const
  132. {
  133. return interpolate(a);
  134. }
  135. template <class T, class S>
  136. inline typename tween<T, S>::value_type tween<T, S>::interpolate(scalar_type a) const
  137. {
  138. return interpolator(states[0], states[1], a);
  139. }
  140. template <class T, class S>
  141. inline void tween<T, S>::set_interpolator(const interpolator_type& interpolator)
  142. {
  143. this->interpolator = interpolator;
  144. }
  145. template <class T, class S>
  146. inline const typename tween<T, S>::interpolator_type& tween<T, S>::get_interpolator() const
  147. {
  148. return interpolator;
  149. }
  150. template <class T, class S>
  151. inline void tween<T, S>::update()
  152. {
  153. states[0] = states[1];
  154. }
  155. template <class T, class S>
  156. inline void tween<T, S>::swap()
  157. {
  158. std::swap(states[0], states[1]);
  159. }
  160. #endif // ANTKEEPER_TWEEN_HPP