movement.hpp 1.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. #ifndef SIMPLE_MOTION_MOVEMENT_HPP
  2. #define SIMPLE_MOTION_MOVEMENT_HPP
  3. #include "simple/support/algorithm.hpp"
  4. #include "common.hpp"
  5. #include <cassert>
  6. namespace simple::motion
  7. {
  8. template <typename Number>
  9. Number linear_curve(Number x) { return x; };
  10. template <typename Number>
  11. Number quadratic_curve(Number x) { return x*x; };
  12. template <typename Number>
  13. Number cubic_curve(Number x) { return x*x*x; };
  14. template <typename Number>
  15. using curve_t = decltype(&linear_curve<Number>);
  16. template <typename Duration, typename Type, typename Ratio, curve_t<Ratio> curve = linear_curve<Ratio>>
  17. struct movement
  18. {
  19. using duration = Duration;
  20. Duration total {};
  21. Type start;
  22. Type end;
  23. Duration elapsed {};
  24. decltype(auto) value()
  25. {
  26. assert(total != Duration{}); // nice
  27. auto ratio =
  28. (Ratio{} + elapsed.count()) /
  29. (Ratio{} + total.count());
  30. using support::way;
  31. return way(start, end, curve(ratio));
  32. }
  33. bool done()
  34. {
  35. return elapsed >= total;
  36. }
  37. advance_result<Duration> advance(Duration delta)
  38. {
  39. assert(!done());
  40. elapsed += delta;
  41. if(done())
  42. {
  43. auto remaining = elapsed - total;
  44. elapsed = total;
  45. return {true, remaining};
  46. }
  47. return {false};
  48. }
  49. void reset()
  50. {
  51. elapsed = Duration{};
  52. }
  53. advance_result<Duration> move(Type& target, Duration delta)
  54. {
  55. if(done())
  56. return {true, delta};
  57. auto result = advance(delta);
  58. target = value();
  59. return result;
  60. }
  61. };
  62. } // namespace simple::motion
  63. #endif /* end of include guard */