From b431ac5de3bf4775d7a93b31701ce4dacb6837b5 Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Thu, 4 Apr 2019 10:05:30 +0700 Subject: [PATCH] basic flipbook system impl --- headers/enduro2d/high/_all.hpp | 3 +- headers/enduro2d/high/_high.hpp | 3 +- .../high/components/flipbook_player.hpp | 88 +++++++++++++++++++ ...ook_controller.hpp => flipbook_source.hpp} | 14 +-- samples/sources/sample_03/sample_03.cpp | 26 ++++-- .../enduro2d/high/systems/flipbook_system.cpp | 71 ++++++++++++++- 6 files changed, 186 insertions(+), 19 deletions(-) create mode 100644 headers/enduro2d/high/components/flipbook_player.hpp rename headers/enduro2d/high/components/{flipbook_controller.hpp => flipbook_source.hpp} (57%) diff --git a/headers/enduro2d/high/_all.hpp b/headers/enduro2d/high/_all.hpp index e27a9d84..1c9c86ba 100644 --- a/headers/enduro2d/high/_all.hpp +++ b/headers/enduro2d/high/_all.hpp @@ -23,7 +23,8 @@ #include "components/actor.hpp" #include "components/camera.hpp" -#include "components/flipbook_controller.hpp" +#include "components/flipbook_player.hpp" +#include "components/flipbook_source.hpp" #include "components/model_renderer.hpp" #include "components/renderer.hpp" #include "components/scene.hpp" diff --git a/headers/enduro2d/high/_high.hpp b/headers/enduro2d/high/_high.hpp index 479d9075..fce12596 100644 --- a/headers/enduro2d/high/_high.hpp +++ b/headers/enduro2d/high/_high.hpp @@ -35,7 +35,8 @@ namespace e2d class actor; class camera; - class flipbook_controller; + class flipbook_player; + class flipbook_source; class model_renderer; class renderer; class scene; diff --git a/headers/enduro2d/high/components/flipbook_player.hpp b/headers/enduro2d/high/components/flipbook_player.hpp new file mode 100644 index 00000000..c8bd64d6 --- /dev/null +++ b/headers/enduro2d/high/components/flipbook_player.hpp @@ -0,0 +1,88 @@ +/******************************************************************************* + * This file is part of the "Enduro2D" + * For conditions of distribution and use, see copyright notice in LICENSE.md + * Copyright (C) 2018-2019 Matvey Cherevko + ******************************************************************************/ + +#pragma once + +#include "../_high.hpp" + +#include "../assets/flipbook_asset.hpp" + +namespace e2d +{ + class flipbook_player final { + public: + flipbook_player() = default; + + flipbook_player& time(f32 value) noexcept; + f32 time() const noexcept; + + flipbook_player& speed(f32 value) noexcept; + f32 speed() const noexcept; + + flipbook_player& paused(bool value) noexcept; + bool paused() const noexcept; + + flipbook_player& looped(bool value) noexcept; + bool looped() const noexcept; + + flipbook_player& sequence(str_hash value) noexcept; + str_hash sequence() const noexcept; + private: + f32 time_{0.f}; + f32 speed_{1.f}; + bool paused_{false}; + bool looped_{false}; + str_hash sequence_; + }; +} + +namespace e2d +{ + inline flipbook_player& flipbook_player::time(f32 value) noexcept { + time_ = value; + return *this; + } + + inline f32 flipbook_player::time() const noexcept { + return time_; + } + + inline flipbook_player& flipbook_player::speed(f32 value) noexcept { + speed_ = value; + return *this; + } + + inline f32 flipbook_player::speed() const noexcept { + return speed_; + } + + inline flipbook_player& flipbook_player::paused(bool value) noexcept { + paused_ = value; + return *this; + } + + inline bool flipbook_player::paused() const noexcept { + return paused_; + } + + inline flipbook_player& flipbook_player::looped(bool value) noexcept { + looped_ = value; + return *this; + } + + inline bool flipbook_player::looped() const noexcept { + return looped_; + } + + inline flipbook_player& flipbook_player::sequence(str_hash value) noexcept { + sequence_ = value; + return *this; + } + + inline str_hash flipbook_player::sequence() const noexcept { + return sequence_; + } +} diff --git a/headers/enduro2d/high/components/flipbook_controller.hpp b/headers/enduro2d/high/components/flipbook_source.hpp similarity index 57% rename from headers/enduro2d/high/components/flipbook_controller.hpp rename to headers/enduro2d/high/components/flipbook_source.hpp index 13e88db5..d5d4c5e3 100644 --- a/headers/enduro2d/high/components/flipbook_controller.hpp +++ b/headers/enduro2d/high/components/flipbook_source.hpp @@ -12,12 +12,12 @@ namespace e2d { - class flipbook_controller final { + class flipbook_source final { public: - flipbook_controller() = default; - flipbook_controller(const flipbook_asset::ptr& flipbook); + flipbook_source() = default; + flipbook_source(const flipbook_asset::ptr& flipbook); - flipbook_controller& flipbook(const flipbook_asset::ptr& value) noexcept; + flipbook_source& flipbook(const flipbook_asset::ptr& value) noexcept; const flipbook_asset::ptr& flipbook() const noexcept; private: flipbook_asset::ptr flipbook_; @@ -26,15 +26,15 @@ namespace e2d namespace e2d { - inline flipbook_controller::flipbook_controller(const flipbook_asset::ptr& flipbook) + inline flipbook_source::flipbook_source(const flipbook_asset::ptr& flipbook) : flipbook_(flipbook) {} - inline flipbook_controller& flipbook_controller::flipbook(const flipbook_asset::ptr& value) noexcept { + inline flipbook_source& flipbook_source::flipbook(const flipbook_asset::ptr& value) noexcept { flipbook_ = value; return *this; } - inline const flipbook_asset::ptr& flipbook_controller::flipbook() const noexcept { + inline const flipbook_asset::ptr& flipbook_source::flipbook() const noexcept { return flipbook_; } } diff --git a/samples/sources/sample_03/sample_03.cpp b/samples/sources/sample_03/sample_03.cpp index 6d92b067..8c5754c7 100644 --- a/samples/sources/sample_03/sample_03.cpp +++ b/samples/sources/sample_03/sample_03.cpp @@ -116,17 +116,25 @@ namespace } { - ecs::entity flipbook_e = the().registry().create_entity(); + for ( std::size_t i = 0; i < 2; ++i ) + for ( std::size_t j = 0; j < 5; ++j ) { + ecs::entity flipbook_e = the().registry().create_entity(); - ecs::entity_filler(flipbook_e) - .component(node::create(flipbook_e, scene_r)) - .component(renderer() - .materials({sprite_mat})) - .component() - .component(flipbook_res); + ecs::entity_filler(flipbook_e) + .component(node::create(flipbook_e, scene_r)) + .component(renderer() + .materials({sprite_mat})) + .component(sprite_renderer() + .filtering(false)) + .component(flipbook_res) + .component(flipbook_player() + .looped(true) + .sequence("idle")); - node_iptr flipbook_n = flipbook_e.get_component().node(); - flipbook_n->translation(v3f{0,-100.f,0}); + node_iptr flipbook_n = flipbook_e.get_component().node(); + flipbook_n->scale(v3f(2.f,2.f,1.f)); + flipbook_n->translation(v3f{-80.f + j * 40.f, -200.f + i * 40.f, 0}); + } } return true; diff --git a/sources/enduro2d/high/systems/flipbook_system.cpp b/sources/enduro2d/high/systems/flipbook_system.cpp index 71635ea9..5df2f795 100644 --- a/sources/enduro2d/high/systems/flipbook_system.cpp +++ b/sources/enduro2d/high/systems/flipbook_system.cpp @@ -6,9 +6,77 @@ #include +#include +#include +#include + namespace { using namespace e2d; + + void update_flipbook_timers(f32 dt, ecs::registry& owner) { + owner.for_joined_components([dt]( + const ecs::const_entity&, + flipbook_player& fp, + const flipbook_source& fs) + { + if ( fp.speed() <= 0.f || fp.paused() ) { + return; + } + const flipbook_asset::ptr& flipbook_res = fs.flipbook(); + if ( !flipbook_res ) { + fp.time(0.f); + fp.paused(true); + return; + } + const flipbook& flipbook = flipbook_res->content(); + const flipbook::sequence* sequence = flipbook.find_sequence(fp.sequence()); + if ( !sequence || sequence->frames.empty() ) { + fp.time(0.f); + fp.paused(true); + return; + } + fp.time(fp.time() + dt * fp.speed()); + if ( sequence->fps > 0.f ) { + const f32 loop_time = sequence->frames.size() / sequence->fps; + if ( fp.time() >= loop_time ) { + if ( fp.looped() ) { + fp.time(math::mod(fp.time(), loop_time)); + } else { + fp.time(loop_time); + fp.paused(true); + } + } + } + }); + } + + void update_flipbook_sprites(ecs::registry& owner) { + owner.for_joined_components([]( + const ecs::const_entity&, + const flipbook_player& fp, + const flipbook_source& fs, + sprite_renderer& sr) + { + const flipbook_asset::ptr& flipbook_res = fs.flipbook(); + if ( !flipbook_res ) { + sr.sprite(nullptr); + return; + } + const flipbook& flipbook = flipbook_res->content(); + const flipbook::sequence* sequence = flipbook.find_sequence(fp.sequence()); + if ( !sequence || sequence->frames.empty() ) { + sr.sprite(nullptr); + return; + } + const std::size_t frame_index = math::clamp( + math::numeric_cast(fp.time() * sequence->fps), + 0u, + sequence->frames.size() - 1u); + const flipbook::frame* frame = flipbook.find_frame(sequence->frames[frame_index]); + sr.sprite(frame ? frame->sprite : nullptr); + }); + } } namespace e2d @@ -23,7 +91,8 @@ namespace e2d ~internal_state() noexcept = default; void process(ecs::registry& owner) { - E2D_UNUSED(owner); + update_flipbook_timers(the().delta_time(), owner); + update_flipbook_sprites(owner); } };