diff --git a/bunny.cpp b/bunny.cpp index cd7a7e9598b8d2cbb3c384d2b28be2256e301ed9..3528b35defd0b78445c3791edb1cea6ccb120333 100644 --- a/bunny.cpp +++ b/bunny.cpp @@ -157,8 +157,8 @@ range2f nose_bounds; const framebuffer * furbuffer; -using poke_motion = motion<float2, quadratic_curve>; -symphony<poke_motion, poke_motion> poke; +using poke_motion = movement<float2, motion::quadratic_curve>; +melody<poke_motion, poke_motion> poke; void start(Program& program) { @@ -255,7 +255,7 @@ void start(Program& program) float fade = std::min(ratio*fade_in, (1-ratio)*fade_out); return lerp(0.f,std::sin(ratio * 170 * poke_ratio), std::min(fade, 1.f)); }, 100ms}, 0); - poke = symphony( + poke = melody( poke_motion{float2::zero(), offset/2, 100ms}, poke_motion{offset/2, float2::zero(), 100ms} ); diff --git a/circular_maze.cpp b/circular_maze.cpp index 75bb88ee1a3c194189f7b70671819280b503fe64..0832939930b2b5d3db964b02d546fe6ac63fb1ac 100644 --- a/circular_maze.cpp +++ b/circular_maze.cpp @@ -388,10 +388,10 @@ class circular_maze } maze(float2::one(400)); -using radial_motion_t = motion<float, quadratic_curve>; -using circular_motion_t = motion<float, quadratic_curve>; +using radial_motion_t = movement<float, motion::quadratic_curve>; +using circular_motion_t = movement<float, motion::quadratic_curve>; -symphony<circular_motion_t, radial_motion_t> +melody<circular_motion_t, radial_motion_t> radial_motion; struct radial_movement @@ -505,7 +505,7 @@ void start(Program& program) auto circular_distance = mod_difference(maze.current_angle, wrap(3/4.f - movement.path, 1.f), 1.f); auto radial_distance = movement.level - maze.player_level; - radial_motion = symphony( + radial_motion = melody( circular_motion_t{ maze.current_angle, maze.current_angle + circular_distance, diff --git a/common/motion.hpp b/common/motion.hpp deleted file mode 100644 index b7e72e09cc0d21c7ea61609d7fe3339d045306bc..0000000000000000000000000000000000000000 --- a/common/motion.hpp +++ /dev/null @@ -1,194 +0,0 @@ -// what even is a tween? -// shorhand for between?? -// what even is between??? - -#ifndef COMMON_MOTION_HPP -#define COMMON_MOTION_HPP - -float linear_curve(float x) { return x; }; -float quadratic_curve(float x) { return x*x; }; -float cubic_curve(float x) { return x*x*x; }; - -using curve_t = decltype(&linear_curve); - -struct advance_result -{ - bool success = false; - Program::duration remaining = 0s; - explicit operator bool() { return success; } -}; -struct multi_advance_result : public advance_result -{ - range<size_t> updated = range<size_t>{0,0}; - using advance_result::operator bool; -}; - -template <typename Type, curve_t curve = linear_curve> -struct motion -{ - Type start; - Type end; - Program::duration total = 0s; - Program::duration elapsed = 0s; - - decltype(auto) value() - { - auto ratio = total == 0s ? 0 : elapsed.count()/total.count(); - return lerp(start, end, curve(ratio)); - } - - bool done() - { - return elapsed >= total; - } - - advance_result advance(Program::duration delta) - { - elapsed += delta; - if(done()) - { - elapsed = total; - return {false}; - } - return {true}; - } - - void reset() - { - elapsed = 0s; - } - - bool move(Type& target, Program::duration delta) - { - bool success = advance(delta).success; - target = value(); - return !success; - } -}; - -// welcome to proper looping -// TODO: for know total duration mod(remaining, total) -// TODO: for unknown total while(move, !success){delta = remaining} -template <typename Motion, typename Target> -bool loop(Target&& target, Motion& motion, Program::duration delta) -{ - if(auto [success, remaining] = motion.move(std::forward<Target>(target), delta); - !success) - { - motion.reset(); - motion.advance(remaining); - return true; - } - return false; -} - -template <typename... Motions> -class ensemble // TODO -{ - std::tuple<Motions...> instruments; - bool done(); - bool advance(Program::duration delta); - void reset(); - template <typename T> - bool move(T& target, Program::duration delta); -}; - -template <typename... Motions> -class symphony -{ - std::tuple<Motions...> movements; - size_t current_index = 0; - - template<typename F, size_t I = sizeof...(Motions) - 1> - void for_all(F&& f) - { - static_assert(I >= 0 && I < sizeof...(Motions)); - std::forward<F>(f)(std::get<I>(movements)); - if constexpr (I > 0) - for_all<F, I-1>(std::forward<F>(f)); - } - - multi_advance_result advance(Program::duration delta, range<size_t> updated) - { - auto [success, remaining] = support::apply_for(current_index, [&delta](auto&& movement) - { - return movement.advance(delta); - }, movements); - - if(!success) - { - if(current_index == sizeof...(Motions) - 1) - return {success, remaining, updated}; - - ++current_index; - - if(remaining > 0s) - return advance(remaining, {updated.lower(), updated.upper()+1}); - else - return {true, remaining, updated}; - } - else - { - return {success, remaining, updated}; - } - } - - public: - - symphony() = default; - symphony(Motions... motions) : movements{motions...} {} - - bool done() - { - return std::get<sizeof...(Motions) - 1>(movements).done(); - } - - auto advance(Program::duration delta) - { - return advance(delta, {current_index, current_index + 1}); - } - - template <size_t... I> - std::tuple<decltype(std::declval<Motions>().value())...> value(std::index_sequence<I...>) - { - return {std::get<I>(movements).value()...}; - } - - std::tuple<decltype(std::declval<Motions>().value())...> value() - { - return value(std::make_index_sequence<sizeof...(Motions)>{}); - } - - void reset() - { - for_all([](auto& movement) {movement.reset();}); - current_index = 0; - } - - template <typename T> - advance_result move(T& target, Program::duration delta) - { - auto result = advance(delta); - support::apply_for(current_index, [&target](auto&& movement) - { - target = movement.value(); - }, movements); - return result; - } - - template <typename... T, - std::enable_if_t<sizeof...(T) == sizeof...(Motions)>* = nullptr> - advance_result move(std::tuple<T...>&& targets, Program::duration delta) - { - auto r = advance(delta); - support::apply_for(r.updated, [](auto&& movement, auto&& target) - { - target = movement.value(); - }, movements, std::forward<std::tuple<T...>>(targets)); - return r; - } -}; - -class conductor; // TODO: dynamic symphony with all strings attached - -#endif /* end of include guard */ diff --git a/common/sketchbook.hpp b/common/sketchbook.hpp index 48e6bcb56c79edf41c172e2ae1d13f768d06ce28..5ab76f6576cf3940d431f8d4e5bb24a4eb549632 100644 --- a/common/sketchbook.hpp +++ b/common/sketchbook.hpp @@ -15,6 +15,7 @@ #include "simple/musical.hpp" #include "simple/interactive/initializer.h" #include "simple/interactive/event.h" +#include "simple/motion.hpp" #include "simple_vg.h" #include "simple_vg.cpp" // TODO: woops, don't do this @@ -197,10 +198,11 @@ class Program friend int main(int argc, char* argv[]); }; -inline void process_events(Program&); +template <typename T, motion::curve_t<float> curve = motion::linear_curve<float>> +using movement = motion::movement<Program::duration, T, float, curve>; +using motion::melody; -// TODO: move dependent stuff out of here and include this at the top -#include "motion.hpp" +inline void process_events(Program&); void start(Program&); diff --git a/tools/setup/init.sh b/tools/setup/init.sh index e4dd73f22ab03ed12d5cf90489000b88f0786eb5..d6b3caa77c7f393cc49fdc404d43452d7b1f5706 100755 --- a/tools/setup/init.sh +++ b/tools/setup/init.sh @@ -5,6 +5,7 @@ rm -rf .dependencies/* cd .dependencies git clone https://notabug.org/namark/cpp_tools git clone https://notabug.org/namark/libsimple_support +git clone https://notabug.org/namark/libsimple_motion git clone https://notabug.org/namark/libsimple_geom git clone https://notabug.org/namark/libsimple_sdlcore git clone https://notabug.org/namark/libsimple_graphical diff --git a/tools/setup/install.sh b/tools/setup/install.sh index 28b2a397065297a9e4aecd29dbde68566d5646ff..c49372f1e63ffa7cf42e1fb1950474a245a91059 100755 --- a/tools/setup/install.sh +++ b/tools/setup/install.sh @@ -3,6 +3,7 @@ cd .dependencies cd cpp_tools make PREFIX=../libsimple_support ../libsimple_support/include/make_templates/header_only_lib +make PREFIX=../libsimple_motion ../libsimple_support/include/make_templates/header_only_lib make PREFIX=../libsimple_geom ../libsimple_geom/include/make_templates/header_only_lib make PREFIX=../libsimple_sdlcore ../libsimple_sdlcore/include/make_templates/static_lib make PREFIX=../libsimple_graphical ../libsimple_graphical/include/make_templates/static_lib @@ -19,6 +20,10 @@ make install PREFIX=../libsimple_interactive "$@" make install PREFIX=../libsimple_musical "$@" cd .. +cd libsimple_motion +make install PREFIX=../../ "$@" +cd .. + cd libsimple_geom make install PREFIX=../../ "$@" make install PREFIX=../libsimple_sdlcore "$@" diff --git a/tools/setup/update.sh b/tools/setup/update.sh index c5d368c56f9ad263c179a3e9a1a6424e3c1004d1..97d4cea580e3f3a8f9a60fc269caf0ae06d7ce7c 100755 --- a/tools/setup/update.sh +++ b/tools/setup/update.sh @@ -10,6 +10,10 @@ cd libsimple_support git pull -r cd .. +cd libsimple_motion +git pull -r +cd .. + cd libsimple_geom git pull -r cd .. diff --git a/various_motion.cpp b/various_motion.cpp index daa5a89fa0e3acb067ad07837fe25a140fa2c296..762fe48889df2d517238d3dca90374c43bdf6f6a 100644 --- a/various_motion.cpp +++ b/various_motion.cpp @@ -1,19 +1,19 @@ #include "common/sketchbook.hpp" -using quadratic_motion = motion<float, quadratic_curve>; +using quadratic_move = movement<float, motion::quadratic_curve>; float block = 0; -auto diagonal_back_and_forth = symphony( - quadratic_motion{0,1, 500ms}, - quadratic_motion{1,0, 500ms} +auto diagonal_back_and_forth = melody( + quadratic_move{0,1, 500ms}, + quadratic_move{1,0, 500ms} ); float2 block2 = float2::zero(); -auto square_around = symphony( - quadratic_motion{0,1, 500ms}, - quadratic_motion{0,1, 500ms}, - quadratic_motion{1,0, 500ms}, - quadratic_motion{1,0, 500ms} +auto square_around = melody( + quadratic_move{0,1, 500ms}, + quadratic_move{0,1, 500ms}, + quadratic_move{1,0, 500ms}, + quadratic_move{1,0, 500ms} ); void start(Program& program)