diff --git a/src/engine/animation/animation-channel.hpp b/src/engine/animation/animation-channel.hpp deleted file mode 100644 index 81d2d7aa..00000000 --- a/src/engine/animation/animation-channel.hpp +++ /dev/null @@ -1,187 +0,0 @@ -// SPDX-FileCopyrightText: 2023 C. J. Howard -// SPDX-License-Identifier: GPL-3.0-or-later - -#ifndef ANTKEEPER_ANIMATION_CHANNEL_HPP -#define ANTKEEPER_ANIMATION_CHANNEL_HPP - -#include -#include -#include - -/** - * Single channel in a keyframe animation. - * - * @see animation - */ -template -class animation_channel -{ -public: - /// Keyframe consisting of a time and a value. - typedef std::tuple keyframe; - - /** - * Creates an animation channel. - * - * @param id ID of the channel. - */ - explicit animation_channel(int id); - - /// Creates an animation channel. - animation_channel(); - - /// Creates an animation channel. - animation_channel(const animation_channel& other); - - /// Assigns the contents of another channel to this channel. - animation_channel& operator=(const animation_channel& other); - - /** - * Adds a keyframe to the animation. - * - * @param k Keyframe to add. - */ - void insert_keyframe(const keyframe& k); - - /** - * Removes all keyframes on `[start, end)`. - * - * @param start Starting position in time (inclusive). - * @param end Ending position in time (non-inclusive). - */ - void remove_keyframes(float start, float end); - - /// Removes all keyframes from the animation. - void remove_keyframes(); - - /** - * Finds the keyframes to the left and right of @p position. - * - * @param position Position in time. - * @return Array containing the the keyframes on the left and right of @p position. - */ - std::array find_keyframes(float position) const; - - /** - * Finds all the keyframes on `[start, end)`. - * - * @param start Starting position in time (inclusive). - * @param end Ending position in time (non-inclusive). - * @return All keyframes on `[start, end)`. - */ - std::list find_keyframes(float start, float end) const; - - /// Returns the ID of the animation channel. - int get_id() const; - - /// Returns the duration of the animation channel. - float get_duration() const; - -private: - struct keyframe_compare - { - inline bool operator()(const keyframe& lhs, const keyframe& rhs) const - { - return std::get<0>(lhs) < std::get<0>(rhs); - } - }; - - int id; - std::set keyframes; -}; - -template -animation_channel::animation_channel(int id): - id(id), - keyframes(keyframe_compare()) -{} - -template -animation_channel::animation_channel(): - animation_channel(-1) -{} - -template -animation_channel::animation_channel(const animation_channel& other): - id(other.id), - keyframes(other.keyframes) -{} - -template -animation_channel& animation_channel::operator=(const animation_channel& other) -{ - id = other.id; - keyframes = other.keyframes; - return *this; -} - -template -void animation_channel::insert_keyframe(const keyframe& k) -{ - keyframes.emplace(k); -} - -template -void animation_channel::remove_keyframes(float start, float end) -{ - auto lower_bound = keyframes.lower_bound({start, T()}); - auto upper_bound = keyframes.upper_bound({end, T()}); - keyframes.erase(lower_bound, upper_bound); -} - -template -void animation_channel::remove_keyframes() -{ - keyframes.clear(); -} - -template -std::array::keyframe*, 2> animation_channel::find_keyframes(float position) const -{ - // Find the following keyframe - auto upper_bound = keyframes.upper_bound({position, T()}); - - // Find the preceding keyframe - auto lower_bound = upper_bound; - --lower_bound; - - std::array frames; - frames[0] = (lower_bound != keyframes.end()) ? &(*lower_bound) : nullptr; - frames[1] = (upper_bound != keyframes.end()) ? &(*upper_bound) : nullptr; - - return frames; -} - -template -std::list::keyframe> animation_channel::find_keyframes(float start, float end) const -{ - std::list keyframe_list; - - auto lower_bound = keyframes.lower_bound({start, T()}); - auto upper_bound = keyframes.upper_bound({end, T()}); - for (auto iterator = lower_bound; iterator != upper_bound; ++iterator) - { - keyframe_list.push_back(*iterator); - } - - return keyframe_list; -} - -template -inline int animation_channel::get_id() const -{ - return id; -} - -template -float animation_channel::get_duration() const -{ - if (keyframes.empty()) - { - return 0.0; - } - - return std::get<0>(*keyframes.rbegin()); -} - -#endif // ANTKEEPER_ANIMATION_CHANNEL_HPP diff --git a/src/engine/animation/animation-player.cpp b/src/engine/animation/animation-player.cpp index 203951ae..92e72e56 100644 --- a/src/engine/animation/animation-player.cpp +++ b/src/engine/animation/animation-player.cpp @@ -2,9 +2,13 @@ // SPDX-License-Identifier: GPL-3.0-or-later #include +#include void animation_player::advance(float seconds) { + // Prevent negative timesteps + seconds = std::max(0.0f, seconds); + if (!m_sequence) { // No active animation sequence, advance position and return diff --git a/src/engine/animation/animation-sequence.cpp b/src/engine/animation/animation-sequence.cpp index a5414472..2cb96f97 100644 --- a/src/engine/animation/animation-sequence.cpp +++ b/src/engine/animation/animation-sequence.cpp @@ -14,7 +14,7 @@ void animation_sequence::trigger_cues(float start_time, float end_time, animatio { const auto start_it = m_cues.lower_bound(start_time); const auto end_it = m_cues.upper_bound(end_time); - + for (auto it = start_it; it != end_it; ++it) { // Make end time exclusive diff --git a/src/engine/animation/animation.cpp b/src/engine/animation/animation.cpp deleted file mode 100644 index 67ec7312..00000000 --- a/src/engine/animation/animation.cpp +++ /dev/null @@ -1,79 +0,0 @@ -// SPDX-FileCopyrightText: 2023 C. J. Howard -// SPDX-License-Identifier: GPL-3.0-or-later - -#include - -animation_base::animation_base(): - looped(false), - loop_count(0), - paused(false), - stopped(true), - position(0.0), - speed(1.0), - start_callback(nullptr), - end_callback(nullptr), - loop_callback(nullptr) -{} - -void animation_base::seek(float t) -{ - position = t; -} - -void animation_base::rewind() -{ - seek(0.0); -} - -void animation_base::loop(bool enabled) -{ - looped = enabled; -} - -void animation_base::pause() -{ - paused = true; -} - -void animation_base::play() -{ - if (stopped) - { - stopped = false; - - if (start_callback) - { - start_callback(); - } - } - - paused = false; -} - -void animation_base::stop() -{ - rewind(); - stopped = true; - paused = false; - loop_count = 0; -} - -void animation_base::set_speed(float value) -{ - this->speed = value; -} - -void animation_base::set_start_callback(std::function callback) -{ - start_callback = callback; -} - -void animation_base::set_end_callback(std::function callback) -{ - end_callback = callback; -} - -void animation_base::set_loop_callback(std::function callback) -{ - loop_callback = callback; -} diff --git a/src/engine/animation/animation.hpp b/src/engine/animation/animation.hpp deleted file mode 100644 index 39a6ed77..00000000 --- a/src/engine/animation/animation.hpp +++ /dev/null @@ -1,378 +0,0 @@ -// SPDX-FileCopyrightText: 2023 C. J. Howard -// SPDX-License-Identifier: GPL-3.0-or-later - -#ifndef ANTKEEPER_ANIMATION_HPP -#define ANTKEEPER_ANIMATION_HPP - -#include -#include -#include -#include -#include - -/** - * Abstract base class for keyframe animations. - */ -class animation_base -{ -public: - /** Constructs an animation base. */ - animation_base(); - - /** Destructs an animation base. */ - virtual ~animation_base() = default; - - /** - * Advances the animation position (t) by @p dt. - * - * @param dt Delta time by which the animation position will be advanced. - */ - virtual void advance(float dt) = 0; - - /** - * Sets the animation position to @p t. - * - * @param t Position in time to which the animation position will be set. - */ - void seek(float t); - - /// Sets the animation position to `0.0`. - void rewind(); - - /// Enables or disables looping of the animation. - void loop(bool enabled); - - /// Pauses the animation. - void pause(); - - /// Plays the animation. - void play(); - - /// Stops the animation, rewinds it, and resets the loop count. - void stop(); - - /** - * Sets the speed of the animation. - * - * @param value Speed multiplier. - */ - void set_speed(float value); - - /// Returns `true` if looping of the animation is enabled, `false` otherwise. - bool is_looped() const; - - /// Returns `true` if the animation is paused, `false` otherwise. - bool is_paused() const; - - /// Returns `true` if the animation is stopped, `false` otherwise. - bool is_stopped() const; - - /// Returns the current position in time of the animation. - float get_position() const; - - /// Returns the current loop count of the animation. - int get_loop_count() const; - - /// Returns the duration of the animation. - virtual float get_duration() const = 0; - - /// Sets the callback that's executed when the animation is started from a stopped state. - void set_start_callback(std::function callback); - - /// Sets the callback that's executed when a non-looped animation has finished. - void set_end_callback(std::function callback); - - /** - * Sets the callback that's executed when the animation loops. - * - * @param callback Loop callback function which is passed the current loop count. - */ - void set_loop_callback(std::function callback); - -protected: - bool looped; - int loop_count; - bool paused; - bool stopped; - float position; - float speed; - - std::function start_callback; - std::function end_callback; - std::function loop_callback; -}; - -inline bool animation_base::is_looped() const -{ - return looped; -} - -inline bool animation_base::is_paused() const -{ - return paused; -} - -inline bool animation_base::is_stopped() const -{ - return stopped; -} - -inline float animation_base::get_position() const -{ - return position; -} - -inline int animation_base::get_loop_count() const -{ - return loop_count; -} - -/** - * Keyframe animation. - * - * @tparam T Animated data type. - */ -template -class animation: public animation_base -{ -public: - /// Channel for this animation type. - typedef animation_channel channel; - - // Keyframe type for this animation. - typedef typename channel::keyframe keyframe; - - /// Interpolator function type. - typedef typename std::decay>::type interpolator_type; - - /// Creates an animation. - animation(); - - /** Destructs an animation. */ - ~animation() override = default; - - /// @copydoc animation_base::advance() - virtual void advance(float dt); - - /** - * Adds a channel to the animation. - * - * @param id ID of the channel. - * @return Added or pre-existing channel. - */ - channel* add_channel(int id); - - /** - * Removes a channel from the animation. - * - * @param id ID of the channel to remove. - */ - void remove_channel(int id); - - /// Removes all channels from the animation. - void remove_channels(); - - /** - * Sets the frame interpolator function object. - * - * @param interp Frame interpolator function object. - */ - void set_interpolator(interpolator_type interp); - - /** - * Sets the callback that's executed on each frame of animation. - * - * @param callback Frame callback which receives the index of an animation channel and value of an interpolated frame. - */ - void set_frame_callback(std::function callback); - - /** - * Returns the channel with the specified ID. - * - * @param id ID of the channel to get. - */ - const channel* get_channel(int id) const; - - /// @copydoc animation::get_channel(int) const - channel* get_channel(int id); - - /// @copydoc animation_base::get_duration() const - virtual float get_duration() const; - -private: - std::unordered_map channels; - interpolator_type interpolator; - std::function frame_callback; -}; - -template -animation::animation(): - interpolator(nullptr), - frame_callback(nullptr) -{} - -template -void animation::advance(float dt) -{ - if (paused || stopped) - { - return; - } - - // Advance position by dt - position += dt * speed; - - // Determine duration of the animation - float duration = get_duration(); - - if (position < duration) - { - if (frame_callback != nullptr && interpolator != nullptr) - { - for (const auto& channel: channels) - { - auto frames = channel.second.find_keyframes(position); - - if (frames[0] != nullptr && frames[1] != nullptr) - { - // Calculate interpolated frame - float t0 = std::get<0>(*frames[0]); - float t1 = std::get<0>(*frames[1]); - float alpha = (position - t0) / (t1 - t0); - T frame = interpolator(std::get<1>(*frames[0]), std::get<1>(*frames[1]), alpha); - - // Pass frame to frame callback - frame_callback(channel.first, frame); - } - else if (frames[0] != nullptr) - { - // Pass frame to frame callback - frame_callback(channel.first, std::get<1>(*frames[0])); - } - else if (frames[1] != nullptr) - { - // Pass frame to frame callback - frame_callback(channel.first, std::get<1>(*frames[1])); - } - } - } - } - else - { - if (looped) - { - ++loop_count; - - // Subtract duration of animation from position - position -= duration; - - // Execute loop callback - if (loop_callback) - { - loop_callback(loop_count); - } - - // Call frame callback on looped frame - if (frame_callback) - { - advance(0.0); - } - } - else - { - // Call frame callback for end frame - if (frame_callback != nullptr) - { - for (auto& channel: channels) - { - auto frames = channel.second.find_keyframes(channel.second.get_duration()); - if (frames[0] != nullptr) - { - frame_callback(channel.first, std::get<1>(*frames[0])); - } - } - } - - stopped = true; - - // Call end callback - if (end_callback) - { - end_callback(); - } - } - } -} - -template -typename animation::channel* animation::add_channel(int id) -{ - return &(*channels.emplace(id, id).first).second; -} - -template -void animation::remove_channel(int id) -{ - auto it = channels.find(id); - if (it != channels.end()) - { - channels.erase(it); - } -} - -template -void animation::remove_channels() -{ - channels.clear(); -} - -template -void animation::set_interpolator(interpolator_type interp) -{ - this->interpolator = interp; -} - -template -void animation::set_frame_callback(std::function callback) -{ - this->frame_callback = callback; -} - -template -const typename animation::channel* animation::get_channel(int id) const -{ - auto it = channels.find(id); - if (it != channels.end()) - { - return &it->second; - } - - return nullptr; -} - -template -typename animation::channel* animation::get_channel(int id) -{ - auto it = channels.find(id); - if (it != channels.end()) - { - return &it->second; - } - - return nullptr; -} - -template -float animation::get_duration() const -{ - float duration = 0.0; - - for (auto it = channels.begin(); it != channels.end(); ++it) - { - duration = std::max(duration, it->second.get_duration()); - } - - return duration; -} - -#endif // ANTKEEPER_ANIMATION_HPP diff --git a/src/engine/animation/animator.cpp b/src/engine/animation/animator.cpp deleted file mode 100644 index fde7c1e1..00000000 --- a/src/engine/animation/animator.cpp +++ /dev/null @@ -1,49 +0,0 @@ -// SPDX-FileCopyrightText: 2023 C. J. Howard -// SPDX-License-Identifier: GPL-3.0-or-later - -#include -#include -#include - -animator::animator(): - animating(0) -{} - -void animator::animate(float dt) -{ - // Advance animations - ++animating; - for (animation_base* animation: animations) - { - animation->advance(dt); - } - --animating; -} - -void animator::add_animation(animation_base* animation) -{ - if (animating) - throw std::runtime_error("Attempting to add animation to animator while animating"); - - animations.emplace(animation); -} - -void animator::remove_animation(animation_base* animation) -{ - if (animating) - throw std::runtime_error("Attempting to remove animation from animator while animating"); - - auto it = animations.find(animation); - if (it != animations.end()) - { - animations.erase(it); - } -} - -void animator::remove_animations() -{ - if (animating) - throw std::runtime_error("Attempting to remove animations from animator while animating"); - - animations.clear(); -} diff --git a/src/engine/animation/animator.hpp b/src/engine/animation/animator.hpp deleted file mode 100644 index 80698fa4..00000000 --- a/src/engine/animation/animator.hpp +++ /dev/null @@ -1,52 +0,0 @@ -// SPDX-FileCopyrightText: 2023 C. J. Howard -// SPDX-License-Identifier: GPL-3.0-or-later - -#ifndef ANTKEEPER_ANIMATOR_HPP -#define ANTKEEPER_ANIMATOR_HPP - -#include -#include - -class animation_base; - -/** - * Progresses a set of animations. - */ -class animator -{ -public: - /// Constructs an animator. - animator(); - - /** - * Progresses all active animations by @p dt. - * - * @param dt Delta time by which the animations will be progressed. - */ - void animate(float dt); - - /** - * Adds an animation to the animator. - * - * @param animation Animation to add. - */ - void add_animation(animation_base* animation); - - /** - * Removes an animation from the animator. - * - * @param animation Animation to remove. - */ - void remove_animation(animation_base* animation); - - /// Removes all animations from the animator. - void remove_animations(); - -private: - std::unordered_set animations; - std::list animations_to_add; - std::list animations_to_remove; - int animating; -}; - -#endif // ANTKEEPER_ANIMATOR_HPP diff --git a/src/engine/animation/screen-transition.cpp b/src/engine/animation/screen-transition.cpp deleted file mode 100644 index 666b754f..00000000 --- a/src/engine/animation/screen-transition.cpp +++ /dev/null @@ -1,94 +0,0 @@ -// SPDX-FileCopyrightText: 2023 C. J. Howard -// SPDX-License-Identifier: GPL-3.0-or-later - -#include -#include -#include - -screen_transition::screen_transition() -{ - progress = std::make_shared(1, 0.0f); - - // Setup material - material = std::make_shared(); - material->set_blend_mode(render::material_blend_mode::translucent); - material->set_variable("progress", progress); - - // Setup billboard - billboard.set_material(material); - billboard.set_layer_mask(0); - - // Add single channel to transition animation - channel = animation.add_channel(0); - - // Setup animation start callback to show transition billboard - // animation.set_start_callback - // ( - // std::bind(&scene::object_base::set_active, &billboard, true) - // ); - - // Setup animation end callback to hide transition billboard - // animation.set_end_callback - // ( - // std::bind(&scene::object_base::set_active, &billboard, false) - // ); - - // Setup animation frame callback to update transition progress material property - animation.set_frame_callback - ( - [this]([[maybe_unused]] int channel, float progress) - { - this->progress->set(progress); - } - ); - - // Setup animation frame callback to update transition progress material property - animation.set_frame_callback - ( - [this]([[maybe_unused]] int channel, float progress) - { - this->progress->set(progress); - } - ); -} - -void screen_transition::transition(float duration, bool reverse, ::animation::interpolator_type interpolator, bool hide, const std::function& function) -{ - float initial_state = (reverse) ? 1.0f : 0.0f; - float final_state = (reverse) ? 0.0f : 1.0f; - - // Build transition animation - channel->remove_keyframes(); - channel->insert_keyframe({0.0f, initial_state}); - channel->insert_keyframe({duration, final_state}); - - // Set transition animation interpolator - animation.set_interpolator(interpolator); - - this->callback = function; - if (hide) - { - // Setup animation end callback to hide transition billboard - animation.set_end_callback - ( - [this]() - { - this->billboard.set_layer_mask(0); - if (this->callback) - this->callback(); - } - ); - } - else - { - animation.set_end_callback(callback); - } - - // Update tweens - progress->set(initial_state); - - // Reset and play transition animation - animation.stop(); - animation.play(); - this->billboard.set_layer_mask(1); -} diff --git a/src/engine/animation/screen-transition.hpp b/src/engine/animation/screen-transition.hpp deleted file mode 100644 index cfe89b2d..00000000 --- a/src/engine/animation/screen-transition.hpp +++ /dev/null @@ -1,50 +0,0 @@ -// SPDX-FileCopyrightText: 2023 C. J. Howard -// SPDX-License-Identifier: GPL-3.0-or-later - -#ifndef ANTKEEPER_SCREEN_TRANSITION_HPP -#define ANTKEEPER_SCREEN_TRANSITION_HPP - -#include -#include -#include -#include - -/** - * Encapsulates a shader-based animated screen transition. - */ -class screen_transition -{ -public: - screen_transition(); - - void transition(float duration, bool reverse, animation::interpolator_type interpolator, bool hide = true, const std::function& function = nullptr); - - scene::billboard* get_billboard(); - std::shared_ptr get_material(); - ::animation* get_animation(); - -private: - scene::billboard billboard; - std::shared_ptr material; - std::shared_ptr progress; - ::animation animation; - ::animation::channel* channel; - std::function callback; -}; - -inline scene::billboard* screen_transition::get_billboard() -{ - return &billboard; -} - -inline std::shared_ptr screen_transition::get_material() -{ - return material; -} - -inline animation* screen_transition::get_animation() -{ - return &animation; -} - -#endif // ANTKEEPER_SCREEN_TRANSITION_HPP diff --git a/src/engine/config.hpp.in b/src/engine/config.hpp.in index b5f360b5..a1497908 100644 --- a/src/engine/config.hpp.in +++ b/src/engine/config.hpp.in @@ -84,7 +84,7 @@ inline constexpr float menu_fade_out_duration = 0.125f; inline constexpr float menu_mouseover_padding = 0.1f; /// Opacity of the menu background. -inline constexpr float menu_bg_opacity = 2.0f / 4.0f; +inline constexpr float menu_bg_opacity = 3.0f / 4.0f; /// RGBA color of active menu items. inline constexpr math::vector menu_active_color{1.0f, 1.0f, 1.0f, 1.0f}; diff --git a/src/game/game.cpp b/src/game/game.cpp index 4799887a..2785aa7f 100644 --- a/src/game/game.cpp +++ b/src/game/game.cpp @@ -36,12 +36,11 @@ #include "game/systems/reproductive-system.hpp" #include "game/systems/metabolic-system.hpp" #include "game/systems/metamorphosis-system.hpp" +#include "game/components/animation-component.hpp" #include #include -#include -#include #include -#include +#include #include #include #include @@ -105,11 +104,11 @@ game::game(int argc, const char* const* argv) setup_input(); load_language(); setup_rendering(); + setup_entities(); setup_scenes(); setup_animation(); setup_ui(); setup_rng(); - setup_entities(); setup_systems(); setup_controls(); setup_debugging(); @@ -714,8 +713,6 @@ void game::setup_scenes() void game::setup_animation() { - // Setup animator - animator = std::make_unique<::animator>(); } void game::setup_ui() @@ -784,69 +781,105 @@ void game::setup_ui() menu_bg_billboard->set_material(menu_bg_material); menu_bg_billboard->set_scale({std::ceil(viewport_size.x() * 0.5f), std::ceil(viewport_size.y() * 0.5f), 1.0f}); menu_bg_billboard->set_translation({std::floor(viewport_size.x() * 0.5f), std::floor(viewport_size.y() * 0.5f), -100.0f}); - - // Create fade transition - fade_transition = std::make_unique(); - fade_transition->get_material()->set_shader_template(resource_manager->load("fade-transition.glsl")); - fade_transition_color = std::make_shared(1, math::fvec3{0, 0, 0}); - fade_transition->get_material()->set_variable("color", fade_transition_color); - fade_transition->get_billboard()->set_translation({0, 0, 98}); - - // Menu BG animations + + // Menu BG material + screen_transition_material = std::make_shared(); + screen_transition_material->set_shader_template(resource_manager->load("ui-element-untextured.glsl")); + std::shared_ptr screen_transition_tint = std::make_shared(1, math::fvec4{0.0f, 0.0f, 0.0f, 1.0f}); + screen_transition_material->set_variable("tint", screen_transition_tint); + screen_transition_material->set_blend_mode(render::material_blend_mode::translucent); + + // Screen transition billboard + screen_transition_billboard = std::make_unique(); + screen_transition_billboard->set_material(screen_transition_material); + screen_transition_billboard->set_scale({std::ceil(viewport_size.x() * 0.5f), std::ceil(viewport_size.y() * 0.5f), 1.0f}); + screen_transition_billboard->set_translation({std::floor(viewport_size.x() * 0.5f), std::floor(viewport_size.y() * 0.5f), 98.0f}); + screen_transition_billboard->set_layer_mask(0); + + // Construct menu bg entity + menu_bg_entity = entity_registry->create(); + entity_registry->emplace(menu_bg_entity); + + // Construct menu bg fade in sequence { - auto menu_bg_frame_callback = [menu_bg_tint]([[maybe_unused]] int channel, const float& opacity) + menu_bg_fade_in_sequence = std::make_shared(); + auto& opacity_track = menu_bg_fade_in_sequence->tracks()["opacity"]; + auto& opacity_channel = opacity_track.channels().emplace_back(); + opacity_channel.keyframes().emplace(0.0f, 0.0f); + opacity_channel.keyframes().emplace(config::menu_fade_in_duration, config::menu_bg_opacity); + + opacity_track.output() = [menu_bg_tint](auto samples, auto&) { - menu_bg_tint->set(math::fvec4{0.0f, 0.0f, 0.0f, opacity}); + menu_bg_tint->set(math::fvec4{0.0f, 0.0f, 0.0f, samples[0]}); }; - - // Menu BG fade in animation - menu_bg_fade_in_animation = std::make_unique>(); + + menu_bg_fade_in_sequence->cues().emplace(0.0f, [&](auto&) { - menu_bg_fade_in_animation->set_interpolator(ease::out_cubic); - animation_channel* channel = menu_bg_fade_in_animation->add_channel(0); - channel->insert_keyframe({0.0f, 0.0f}); - channel->insert_keyframe({config::menu_fade_in_duration, config::menu_bg_opacity}); - menu_bg_fade_in_animation->set_frame_callback(menu_bg_frame_callback); - menu_bg_fade_in_animation->set_start_callback - ( - [&, menu_bg_tint]() - { - ui_canvas->get_scene().add_object(*menu_bg_billboard); - - menu_bg_tint->set(math::fvec4{0.0f, 0.0f, 0.0f, 0.0f}); - //menu_bg_billboard->set_active(true); - } - ); - } - - // Menu BG fade out animation - menu_bg_fade_out_animation = std::make_unique>(); + ui_canvas->get_scene().add_object(*menu_bg_billboard); + }); + } + + // Construct menu bg fade out sequence + { + menu_bg_fade_out_sequence = std::make_shared(); + auto& opacity_track = menu_bg_fade_out_sequence->tracks()["opacity"]; + auto& opacity_channel = opacity_track.channels().emplace_back(); + opacity_channel.keyframes().emplace(0.0f, config::menu_bg_opacity); + opacity_channel.keyframes().emplace(config::menu_fade_out_duration, 0.0f); + + opacity_track.output() = [menu_bg_tint](auto samples, auto&) { - menu_bg_fade_out_animation->set_interpolator(ease::out_cubic); - animation_channel* channel = menu_bg_fade_out_animation->add_channel(0); - channel->insert_keyframe({0.0f, config::menu_bg_opacity}); - channel->insert_keyframe({config::menu_fade_out_duration, 0.0f}); - menu_bg_fade_out_animation->set_frame_callback(menu_bg_frame_callback); - menu_bg_fade_out_animation->set_end_callback - ( - [&]() - { - ui_canvas->get_scene().remove_object(*menu_bg_billboard); - //menu_bg_billboard->set_active(false); - } - ); - } + menu_bg_tint->set(math::fvec4{0.0f, 0.0f, 0.0f, samples[0]}); + }; + + menu_bg_fade_out_sequence->cues().emplace(1.0f, [&](auto&) + { + ui_canvas->get_scene().remove_object(*menu_bg_billboard); + }); + } + + // Construct screen fade in sequence + { + screen_fade_in_sequence = std::make_shared(); + auto& opacity_track = screen_fade_in_sequence->tracks()["opacity"]; + auto& opacity_channel = opacity_track.channels().emplace_back(); + opacity_channel.keyframes().emplace(0.0f, 1.0f); + opacity_channel.keyframes().emplace(1.0f, 0.0f); + + opacity_track.output() = [screen_transition_tint](auto samples, auto&) + { + screen_transition_tint->set(math::fvec4{0.0f, 0.0f, 0.0f, samples[0]}); + }; + } + + // Construct screen fade out sequence + { + screen_fade_out_sequence = std::make_shared(); + auto& opacity_track = screen_fade_out_sequence->tracks()["opacity"]; + auto& opacity_channel = opacity_track.channels().emplace_back(); + opacity_channel.keyframes().emplace(0.0f, 0.0f); + opacity_channel.keyframes().emplace(1.0f, 1.0f); + + opacity_track.output() = [screen_transition_tint](auto samples, auto&) + { + screen_transition_tint->set(math::fvec4{0.0f, 0.0f, 0.0f, samples[0]}); + }; } + + // Construct screen transition entity + screen_transition_entity = entity_registry->create(); + entity_registry->emplace(screen_transition_entity); + + // Construct menu entity + menu_entity = entity_registry->create(); + entity_registry->emplace(menu_entity); + + // Setup menu animations + menu::setup_animations(*this); // Add UI scene objects to UI scene ui_canvas->get_scene().add_object(*ui_camera); - ui_canvas->get_scene().add_object(*fade_transition->get_billboard()); - - // Add UI animations to animator - animator->add_animation(fade_transition->get_animation()); - animator->add_animation(menu_bg_fade_in_animation.get()); - animator->add_animation(menu_bg_fade_out_animation.get()); - + ui_canvas->get_scene().add_object(*screen_transition_billboard); auto version_label = std::make_shared(); version_label->set_font(debug_font); @@ -910,6 +943,10 @@ void game::setup_ui() ui_camera->get_clip_near(), ui_camera->get_clip_far() ); + + // Resize screen transition billboard + screen_transition_billboard->set_scale({std::ceil(viewport_size.x() * 0.5f), std::ceil(viewport_size.y() * 0.5f), 1.0f}); + screen_transition_billboard->set_translation({std::floor(viewport_size.x() * 0.5f), std::floor(viewport_size.y() * 0.5f), -100.0f}); // Resize menu BG billboard menu_bg_billboard->set_scale({std::ceil(viewport_size.x() * 0.5f), std::ceil(viewport_size.y() * 0.5f), 1.0f}); @@ -1250,7 +1287,6 @@ void game::fixed_update(::frame_scheduler::duration_type fixed_update_time, ::fr astronomy_system->update(t, dt); spatial_system->update(t, dt); constraint_system->update(t, dt); - animator->animate(dt); camera_system->update(t, dt); render_system->update(t, dt); } diff --git a/src/game/game.hpp b/src/game/game.hpp index 466f6032..da349549 100644 --- a/src/game/game.hpp +++ b/src/game/game.hpp @@ -50,14 +50,10 @@ #include // Forward declarations -class animator; class resource_manager; -class screen_transition; class shell; class shell_buffer; -template class animation; - namespace render { class bloom_pass; @@ -93,6 +89,7 @@ class physics_system; class subterrain_system; class terrain_system; class ik_system; +class animation_sequence; struct control_profile; @@ -325,9 +322,9 @@ class game std::unique_ptr ui_camera; std::unique_ptr menu_bg_billboard; std::shared_ptr menu_bg_material; - std::unique_ptr> menu_fade_animation; - std::unique_ptr> menu_bg_fade_in_animation; - std::unique_ptr> menu_bg_fade_out_animation; + + std::unique_ptr screen_transition_billboard; + std::shared_ptr screen_transition_material; float font_scale; bool dyslexia_font; @@ -354,9 +351,15 @@ class game scene::collection* active_scene; // Animation - std::unique_ptr animator; - std::unique_ptr fade_transition; - std::shared_ptr fade_transition_color; + entity::id menu_bg_entity{entt::null}; + entity::id menu_entity{entt::null}; + std::shared_ptr menu_bg_fade_in_sequence; + std::shared_ptr menu_bg_fade_out_sequence; + std::shared_ptr menu_fade_in_sequence; + std::shared_ptr menu_fade_out_sequence; + entity::id screen_transition_entity{entt::null}; + std::shared_ptr screen_fade_in_sequence; + std::shared_ptr screen_fade_out_sequence; // Sound std::unique_ptr sound_system; diff --git a/src/game/menu.cpp b/src/game/menu.cpp index 89d7b261..2428b5e0 100644 --- a/src/game/menu.cpp +++ b/src/game/menu.cpp @@ -3,12 +3,11 @@ #include "game/menu.hpp" #include -#include -#include #include #include #include #include +#include "game/components/animation-component.hpp" namespace menu { @@ -191,12 +190,6 @@ void delete_text(::game& ctx) ctx.menu_item_texts.clear(); } -void delete_animations(::game& ctx) -{ - ctx.animator->remove_animation(ctx.menu_fade_animation.get()); - ctx.menu_fade_animation.reset(); -} - void clear_callbacks(::game& ctx) { // Clear menu item callbacks @@ -208,86 +201,89 @@ void clear_callbacks(::game& ctx) void setup_animations(::game& ctx) { - ctx.menu_fade_animation = std::make_unique>(); - [[maybe_unused]] animation_channel* opacity_channel = ctx.menu_fade_animation->add_channel(0); - - ctx.menu_fade_animation->set_frame_callback - ( - [&ctx]([[maybe_unused]] int channel, const float& opacity) + auto output_function = [&ctx](auto samples, auto&) + { + for (std::size_t i = 0; i < ctx.menu_item_texts.size(); ++i) { - for (std::size_t i = 0; i < ctx.menu_item_texts.size(); ++i) - { - auto [name, value] = ctx.menu_item_texts[i]; - - math::fvec4 color = (i == *ctx.menu_item_index) ? config::menu_active_color : config::menu_inactive_color; - color[3] = color[3] * opacity; - - if (name) - name->set_color(color); - if (value) - value->set_color(color); - } + auto [name, value] = ctx.menu_item_texts[i]; + + math::fvec4 color = (i == *ctx.menu_item_index) ? config::menu_active_color : config::menu_inactive_color; + color[3] = color[3] * samples[0]; + + if (name) + name->set_color(color); + if (value) + value->set_color(color); } - ); - - ctx.animator->add_animation(ctx.menu_fade_animation.get()); + }; + + // Construct menu fade in sequence + { + ctx.menu_fade_in_sequence = std::make_shared(); + auto& opacity_track = ctx.menu_fade_in_sequence->tracks()["opacity"]; + auto& opacity_channel = opacity_track.channels().emplace_back(); + opacity_channel.keyframes().emplace(0.0f, 0.0f); + opacity_channel.keyframes().emplace(config::menu_fade_in_duration, 1.0f); + opacity_track.output() = output_function; + } + + // Construct menu fade in sequence + { + ctx.menu_fade_out_sequence = std::make_shared(); + auto& opacity_track = ctx.menu_fade_out_sequence->tracks()["opacity"]; + auto& opacity_channel = opacity_track.channels().emplace_back(); + opacity_channel.keyframes().emplace(0.0f, 1.0f); + opacity_channel.keyframes().emplace(config::menu_fade_out_duration, 0.0f); + opacity_track.output() = output_function; + } } void fade_in(::game& ctx, const std::function& end_callback) { - ctx.menu_fade_animation->set_interpolator(ease::out_cubic); - animation_channel* opacity_channel = ctx.menu_fade_animation->get_channel(0); - opacity_channel->remove_keyframes(); - opacity_channel->insert_keyframe({0.0f, 0.0f}); - opacity_channel->insert_keyframe({config::menu_fade_in_duration, 1.0f}); - ctx.menu_fade_animation->set_end_callback(end_callback); - - for (std::size_t i = 0; i < ctx.menu_item_texts.size(); ++i) + ctx.menu_fade_in_sequence->cues().clear(); + if (end_callback) { - auto [name, value] = ctx.menu_item_texts[i]; - - math::fvec4 color = (i == *ctx.menu_item_index) ? config::menu_active_color : config::menu_inactive_color; - color[3] = 0.0f; - - if (name) - { - name->set_color(color); - } - if (value) + ctx.menu_fade_in_sequence->cues().emplace(config::menu_fade_in_duration, [end_callback](auto&) { - value->set_color(color); - } + end_callback(); + }); } - - ctx.menu_fade_animation->stop(); - ctx.menu_fade_animation->play(); + + auto& player = ctx.entity_registry->get(ctx.menu_entity).player; + player.rewind(); + player.play(ctx.menu_fade_in_sequence); + // player.advance(0.0f); } void fade_out(::game& ctx, const std::function& end_callback) { - ctx.menu_fade_animation->set_interpolator(ease::out_cubic); - animation_channel* opacity_channel = ctx.menu_fade_animation->get_channel(0); - opacity_channel->remove_keyframes(); - opacity_channel->insert_keyframe({0.0f, 1.0f}); - opacity_channel->insert_keyframe({config::menu_fade_out_duration, 0.0f}); - ctx.menu_fade_animation->set_end_callback(end_callback); - - ctx.menu_fade_animation->stop(); - ctx.menu_fade_animation->play(); + ctx.menu_fade_out_sequence->cues().clear(); + if (end_callback) + { + ctx.menu_fade_out_sequence->cues().emplace(config::menu_fade_out_duration, [end_callback](auto&) + { + end_callback(); + }); + } + + auto& player = ctx.entity_registry->get(ctx.menu_entity).player; + player.rewind(); + player.play(ctx.menu_fade_out_sequence); + // player.advance(0.0f); } void fade_in_bg(::game& ctx) { - ctx.menu_bg_fade_out_animation->stop(); - ctx.menu_bg_fade_in_animation->stop(); - ctx.menu_bg_fade_in_animation->play(); + auto& player = ctx.entity_registry->get(ctx.menu_bg_entity).player; + player.rewind(); + player.play(ctx.menu_bg_fade_in_sequence); } void fade_out_bg(::game& ctx) { - ctx.menu_bg_fade_in_animation->stop(); - ctx.menu_bg_fade_out_animation->stop(); - ctx.menu_bg_fade_out_animation->play(); + auto& player = ctx.entity_registry->get(ctx.menu_bg_entity).player; + player.rewind(); + player.play(ctx.menu_bg_fade_out_sequence); } } // namespace menu diff --git a/src/game/menu.hpp b/src/game/menu.hpp index d986c568..029f6ed1 100644 --- a/src/game/menu.hpp +++ b/src/game/menu.hpp @@ -14,7 +14,6 @@ void setup_animations(::game& ctx); void clear_callbacks(::game& ctx); void remove_text_from_ui(::game& ctx); void delete_text(::game& ctx); -void delete_animations(::game& ctx); diff --git a/src/game/screen-transition.cpp b/src/game/screen-transition.cpp new file mode 100644 index 00000000..986d31e9 --- /dev/null +++ b/src/game/screen-transition.cpp @@ -0,0 +1,54 @@ +// SPDX-FileCopyrightText: 2023 C. J. Howard +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "game/screen-transition.hpp" +#include "game/game.hpp" +#include "game/components/animation-component.hpp" + +void fade_out_to(::game& ctx, const std::function& callback) +{ + ctx.screen_fade_out_sequence->cues().clear(); + + ctx.screen_fade_out_sequence->cues().emplace(0.0f, [&](auto&) + { + ctx.screen_transition_billboard->set_layer_mask(1); + }); + + ctx.screen_fade_out_sequence->cues().emplace(ctx.screen_fade_out_sequence->duration() + 0.1f, [&, callback](auto&) + { + ctx.screen_transition_billboard->set_layer_mask(0); + if (callback) + { + callback(); + } + }); + + // Start credits roll + auto& player = ctx.entity_registry->get(ctx.screen_transition_entity).player; + player.rewind(); + player.play(ctx.screen_fade_out_sequence); +} + +void fade_in_to(::game& ctx, const std::function& callback) +{ + ctx.screen_fade_in_sequence->cues().clear(); + + ctx.screen_fade_in_sequence->cues().emplace(0.0f, [&](auto&) + { + ctx.screen_transition_billboard->set_layer_mask(1); + }); + + ctx.screen_fade_in_sequence->cues().emplace(ctx.screen_fade_in_sequence->duration() + 0.1f, [&, callback](auto&) + { + ctx.screen_transition_billboard->set_layer_mask(0); + if (callback) + { + callback(); + } + }); + + // Start credits roll + auto& player = ctx.entity_registry->get(ctx.screen_transition_entity).player; + player.rewind(); + player.play(ctx.screen_fade_in_sequence); +} diff --git a/src/game/screen-transition.hpp b/src/game/screen-transition.hpp new file mode 100644 index 00000000..9bd4ae83 --- /dev/null +++ b/src/game/screen-transition.hpp @@ -0,0 +1,14 @@ +// SPDX-FileCopyrightText: 2023 C. J. Howard +// SPDX-License-Identifier: GPL-3.0-or-later + +#ifndef ANTKEEPER_GAME_SCREEN_TRANSITION_HPP +#define ANTKEEPER_GAME_SCREEN_TRANSITION_HPP + +#include + +class game; + +void fade_out_to(::game& ctx, const std::function& callback); +void fade_in_to(::game& ctx, const std::function& callback); + +#endif // ANTKEEPER_GAME_SCREEN_TRANSITION_HPP diff --git a/src/game/states/collection-menu-state.cpp b/src/game/states/collection-menu-state.cpp deleted file mode 100644 index 6b81204d..00000000 --- a/src/game/states/collection-menu-state.cpp +++ /dev/null @@ -1,153 +0,0 @@ -// SPDX-FileCopyrightText: 2023 C. J. Howard -// SPDX-License-Identifier: GPL-3.0-or-later - -#include "game/states/collection-menu-state.hpp" -#include "game/states/main-menu-state.hpp" -#include "game/controls.hpp" -#include -#include -#include "game/menu.hpp" -#include "game/strings.hpp" -#include -#include -#include -#include -#include - -using namespace hash::literals; - -collection_menu_state::collection_menu_state(::game& ctx): - game_state(ctx) -{ - debug::log_trace("Entering collection menu state..."); - - // Construct box material - box_material = std::make_shared(); - box_material->set_blend_mode(render::material_blend_mode::translucent); - box_material->set_shader_template(ctx.resource_manager->load("ui-element-untextured.glsl")); - box_material->set_variable("tint", std::make_shared(1, math::fvec4{0.5f, 0.5f, 0.5f, 1})); - - // Construct box billboard - box_billboard.set_material(box_material); - - // Construct selection material - selection_material = std::make_shared(); - selection_material->set_blend_mode(render::material_blend_mode::translucent); - selection_material->set_shader_template(ctx.resource_manager->load("ui-element-untextured.glsl")); - box_material->set_variable("tint", std::make_shared(1, math::fvec4{1, 1, 1, 1})); - - // Construct selection billboard - selection_billboard.set_material(selection_material); - - // Add box and selection billboard to UI scene - ctx.ui_canvas->get_scene().add_object(box_billboard); - ctx.ui_canvas->get_scene().add_object(selection_billboard); - - row_count = 64; - column_count = 6; - selected_row = 0; - selected_column = 0; - resize_box(); - - mouse_moved_subscription = ctx.input_manager->get_event_dispatcher().subscribe - ( - [&]([[maybe_unused]] const auto& event) - { - - } - ); - - mouse_button_pressed_subscription = ctx.input_manager->get_event_dispatcher().subscribe - ( - [&](const auto& event) - { - const auto& viewport_size = ctx.window->get_viewport_size(); - const math::fvec2 mouse_position = - { - static_cast(event.position.x()), - static_cast(viewport_size.y() - event.position.y() + 1) - }; - - if (box_bounds.contains(mouse_position)) - { - int column = static_cast((mouse_position.x() - box_bounds.min.x()) / selection_size); - int row = static_cast((box_bounds.max.y() - mouse_position.y()) / selection_size); - - if (column != selected_column || row != selected_row) - { - selected_column = column; - selected_row = row; - - selection_billboard.set_translation - ( - { - (box_bounds.min.x() + selection_size * 0.5f) + selection_size * selected_column, - (box_bounds.max.y() - selection_size * 0.5f) - selection_size * selected_row , - 0.0f - } - ); - - debug::log_debug("selected colony: ({}, {})", selected_column, selected_row); - } - } - } - ); - - window_resized_subscription = ctx.window->get_resized_channel().subscribe - ( - [&]([[maybe_unused]] const auto& event) - { - this->resize_box(); - } - ); - - // Queue enable menu controls - //ctx.function_queue.push(std::bind(::enable_menu_controls, std::ref(ctx))); - - // Fade in from black - ctx.fade_transition->transition(config::title_fade_in_duration, true, ease::out_cubic); - - debug::log_trace("Entered collection menu state"); -} - -collection_menu_state::~collection_menu_state() -{ - debug::log_trace("Exiting collection menu state..."); - - // Destruct menu - //::disable_menu_controls(ctx); - - debug::log_trace("Exited collection menu state"); -} - -void collection_menu_state::resize_box() -{ - const float padding = 64.0f; - const auto viewport_size = math::fvec2(ctx.window->get_viewport_size()); - - box_bounds.min.x() = viewport_size.x() * 0.5f + padding; - box_bounds.max.x() = viewport_size.x() - padding; - - selection_size = (box_bounds.max.x() - box_bounds.min.x()) / static_cast(column_count); - - box_bounds.max.y() = viewport_size.y() - padding; - box_bounds.min.y() = std::max(padding, box_bounds.max.y() - selection_size * row_count); - - const math::fvec2 box_size = box_bounds.size(); - const math::fvec2 box_center = box_bounds.center(); - - // Resize box - box_billboard.set_scale({box_size.x() * 0.5f, box_size.y() * 0.5f, 1.0f}); - box_billboard.set_translation({box_center.x(), box_center.y(), -1.0f}); - - // Resize selection - selection_billboard.set_scale({selection_size * 0.5f, selection_size * 0.5f, 1.0f}); - selection_billboard.set_translation - ( - { - (box_bounds.min.x() + selection_size * 0.5f) + selection_size * selected_column, - (box_bounds.max.y() - selection_size * 0.5f) - selection_size * selected_row, - 0.0f - } - ); -} diff --git a/src/game/states/collection-menu-state.hpp b/src/game/states/collection-menu-state.hpp deleted file mode 100644 index 09465be3..00000000 --- a/src/game/states/collection-menu-state.hpp +++ /dev/null @@ -1,43 +0,0 @@ -// SPDX-FileCopyrightText: 2023 C. J. Howard -// SPDX-License-Identifier: GPL-3.0-or-later - -#ifndef ANTKEEPER_COLLECTION_MENU_STATE_HPP -#define ANTKEEPER_COLLECTION_MENU_STATE_HPP - -#include "game/states/game-state.hpp" -#include -#include -#include -#include -#include -#include - - -class collection_menu_state: public game_state -{ -public: - explicit collection_menu_state(::game& ctx); - virtual ~collection_menu_state(); - -private: - void resize_box(); - - std::shared_ptr selection_material; - scene::billboard selection_billboard; - - std::shared_ptr box_material; - scene::billboard box_billboard; - - std::shared_ptr mouse_moved_subscription; - std::shared_ptr mouse_button_pressed_subscription; - std::shared_ptr window_resized_subscription; - - geom::rectangle box_bounds; - int row_count; - int column_count; - int selected_row; - int selected_column; - float selection_size; -}; - -#endif // ANTKEEPER_COLLECTION_MENU_STATE_HPP diff --git a/src/game/states/controls-menu-state.cpp b/src/game/states/controls-menu-state.cpp index 3c5ea135..d06c4667 100644 --- a/src/game/states/controls-menu-state.cpp +++ b/src/game/states/controls-menu-state.cpp @@ -41,7 +41,6 @@ controls_menu_state::controls_menu_state(::game& ctx): ::menu::update_text_font(ctx); ::menu::align_text(ctx, true); ::menu::add_text_to_ui(ctx); - ::menu::setup_animations(ctx); // Construct menu item callbacks auto select_keyboard_callback = [&ctx]() @@ -145,7 +144,6 @@ controls_menu_state::~controls_menu_state() // Destruct menu ::disable_menu_controls(ctx); ::menu::clear_callbacks(ctx); - ::menu::delete_animations(ctx); ::menu::remove_text_from_ui(ctx); ::menu::delete_text(ctx); diff --git a/src/game/states/credits-state.cpp b/src/game/states/credits-state.cpp index 229d3fc8..f25f5b22 100644 --- a/src/game/states/credits-state.cpp +++ b/src/game/states/credits-state.cpp @@ -5,11 +5,10 @@ #include "game/states/extras-menu-state.hpp" #include "game/game.hpp" #include -#include -#include #include #include #include "game/strings.hpp" +#include "game/components/animation-component.hpp" #include #include @@ -36,23 +35,26 @@ credits_state::credits_state(::game& ctx): // Set up animation timing configuration const float credits_fade_in_duration = 0.5; - auto set_credits_opacity = [this]([[maybe_unused]] int channel, const float& opacity) + // Construct roll credits sequence { - this->credits_text.set_color({1.0f, 1.0f, 1.0f, opacity}); - }; - - // Build credits fade in animation - credits_fade_in_animation.set_interpolator(ease::in_quad); - animation_channel* credits_fade_in_opacity_channel = credits_fade_in_animation.add_channel(0); - credits_fade_in_opacity_channel->insert_keyframe({0.0f, 0.0f}); - credits_fade_in_opacity_channel->insert_keyframe({credits_fade_in_duration, 1.0f}); - credits_fade_in_animation.set_frame_callback(set_credits_opacity); + m_roll_credits_sequence = std::make_shared(); + auto& opacity_track = m_roll_credits_sequence->tracks()["opacity"]; + auto& opacity_channel = opacity_track.channels().emplace_back(); + opacity_channel.keyframes().emplace(0.0f, 0.0f); + opacity_channel.keyframes().emplace(credits_fade_in_duration, 1.0f); + opacity_track.output() = [&](auto samples, auto&) + { + credits_text.set_color({1.0f, 1.0f, 1.0f, samples[0]}); + }; + } - // Add credits animations to animator - ctx.animator->add_animation(&credits_fade_in_animation); + // Constructs credits entity + m_credits_entity = ctx.entity_registry->create(); + ctx.entity_registry->emplace(m_credits_entity); - // Start credits fade in animation - credits_fade_in_animation.play(); + // Start credits roll + auto& credits_player = ctx.entity_registry->get(m_credits_entity).player; + credits_player.play(m_roll_credits_sequence); // Setup window resized callback window_resized_subscription = ctx.window->get_resized_channel().subscribe @@ -128,10 +130,8 @@ credits_state::~credits_state() input_mapped_subscriptions.clear(); // Destruct credits text + ctx.entity_registry->destroy(m_credits_entity); ctx.ui_canvas->get_scene().remove_object(credits_text); - // Destruct credits animations - ctx.animator->remove_animation(&credits_fade_in_animation); - debug::log_trace("Exited credits state"); } diff --git a/src/game/states/credits-state.hpp b/src/game/states/credits-state.hpp index 841e6fd3..99fca293 100644 --- a/src/game/states/credits-state.hpp +++ b/src/game/states/credits-state.hpp @@ -6,8 +6,9 @@ #include "game/states/game-state.hpp" #include -#include +#include #include +#include #include @@ -19,8 +20,9 @@ class credits_state: public game_state private: scene::text credits_text; - animation credits_fade_in_animation; - animation credits_scroll_animation; + entity::id m_credits_entity{entt::null}; + std::shared_ptr m_roll_credits_sequence; + std::vector> input_mapped_subscriptions; std::shared_ptr window_resized_subscription; }; diff --git a/src/game/states/experiments/test-state.cpp b/src/game/states/experiments/test-state.cpp index b4602e13..b675de80 100644 --- a/src/game/states/experiments/test-state.cpp +++ b/src/game/states/experiments/test-state.cpp @@ -41,6 +41,7 @@ #include "game/constraints/track-to-constraint.hpp" #include "game/controls.hpp" #include "game/spawn.hpp" +#include "game/screen-transition.hpp" #include "game/states/pause-menu-state.hpp" #include "game/systems/astronomy-system.hpp" #include "game/systems/atmosphere-system.hpp" @@ -50,7 +51,6 @@ #include "game/systems/terrain-system.hpp" #include "game/world.hpp" #include -#include #include #include #include @@ -314,8 +314,7 @@ test_state::test_state(::game& ctx): ); // Queue fade in - ctx.fade_transition_color->set({0, 0, 0}); - ctx.function_queue.push(std::bind(&screen_transition::transition, ctx.fade_transition.get(), 1.0f, true, ease::out_sine, true, nullptr)); + fade_in_to(ctx, nullptr); // Refresh frame scheduler ctx.frame_scheduler.refresh(); diff --git a/src/game/states/experiments/treadmill-experiment-state.cpp b/src/game/states/experiments/treadmill-experiment-state.cpp index 32fce94e..2f4e80e3 100644 --- a/src/game/states/experiments/treadmill-experiment-state.cpp +++ b/src/game/states/experiments/treadmill-experiment-state.cpp @@ -40,6 +40,7 @@ #include "game/constraints/track-to-constraint.hpp" #include "game/controls.hpp" #include "game/spawn.hpp" +#include "game/screen-transition.hpp" #include "game/states/pause-menu-state.hpp" #include "game/systems/astronomy-system.hpp" #include "game/systems/atmosphere-system.hpp" @@ -49,7 +50,6 @@ #include "game/systems/terrain-system.hpp" #include "game/world.hpp" #include -#include #include #include #include @@ -361,8 +361,7 @@ treadmill_experiment_state::treadmill_experiment_state(::game& ctx): ); // Queue fade in - ctx.fade_transition_color->set({0, 0, 0}); - ctx.function_queue.push(std::bind(&screen_transition::transition, ctx.fade_transition.get(), 1.0f, true, ease::out_sine, true, nullptr)); + fade_in_to(ctx, nullptr); // Refresh frame scheduler ctx.frame_scheduler.refresh(); diff --git a/src/game/states/extras-menu-state.cpp b/src/game/states/extras-menu-state.cpp index 1256ea75..fcabe7b7 100644 --- a/src/game/states/extras-menu-state.cpp +++ b/src/game/states/extras-menu-state.cpp @@ -38,7 +38,6 @@ extras_menu_state::extras_menu_state(::game& ctx): ::menu::update_text_font(ctx); ::menu::align_text(ctx); ::menu::add_text_to_ui(ctx); - ::menu::setup_animations(ctx); // Construct menu item callbacks auto select_credits_callback = [&ctx]() @@ -117,7 +116,6 @@ extras_menu_state::~extras_menu_state() // Destruct menu ::disable_menu_controls(ctx); ::menu::clear_callbacks(ctx); - ::menu::delete_animations(ctx); ::menu::remove_text_from_ui(ctx); ::menu::delete_text(ctx); diff --git a/src/game/states/gamepad-config-menu-state.cpp b/src/game/states/gamepad-config-menu-state.cpp index d0dfd92f..745daa8f 100644 --- a/src/game/states/gamepad-config-menu-state.cpp +++ b/src/game/states/gamepad-config-menu-state.cpp @@ -47,7 +47,6 @@ gamepad_config_menu_state::gamepad_config_menu_state(::game& ctx): ::menu::update_text_font(ctx); ::menu::align_text(ctx); ::menu::add_text_to_ui(ctx); - ::menu::setup_animations(ctx); // Construct menu item callbacks auto select_back_callback = [&ctx]() @@ -101,7 +100,6 @@ gamepad_config_menu_state::~gamepad_config_menu_state() // Destruct menu ::disable_menu_controls(ctx); ::menu::clear_callbacks(ctx); - ::menu::delete_animations(ctx); ::menu::remove_text_from_ui(ctx); ::menu::delete_text(ctx); diff --git a/src/game/states/graphics-menu-state.cpp b/src/game/states/graphics-menu-state.cpp index 580756d4..c1de0efc 100644 --- a/src/game/states/graphics-menu-state.cpp +++ b/src/game/states/graphics-menu-state.cpp @@ -61,7 +61,6 @@ graphics_menu_state::graphics_menu_state(::game& ctx): ::menu::update_text_font(ctx); ::menu::align_text(ctx); ::menu::add_text_to_ui(ctx); - ::menu::setup_animations(ctx); // Construct menu item callbacks auto toggle_fullscreen_callback = [this, &ctx]() @@ -335,7 +334,6 @@ graphics_menu_state::~graphics_menu_state() // Destruct menu ::disable_menu_controls(ctx); ::menu::clear_callbacks(ctx); - ::menu::delete_animations(ctx); ::menu::remove_text_from_ui(ctx); ::menu::delete_text(ctx); diff --git a/src/game/states/keyboard-config-menu-state.cpp b/src/game/states/keyboard-config-menu-state.cpp index ee67da2c..68e7e849 100644 --- a/src/game/states/keyboard-config-menu-state.cpp +++ b/src/game/states/keyboard-config-menu-state.cpp @@ -47,7 +47,6 @@ keyboard_config_menu_state::keyboard_config_menu_state(::game& ctx): ::menu::update_text_font(ctx); ::menu::align_text(ctx); ::menu::add_text_to_ui(ctx); - ::menu::setup_animations(ctx); // Construct menu item callbacks auto select_back_callback = [&ctx]() @@ -101,7 +100,6 @@ keyboard_config_menu_state::~keyboard_config_menu_state() // Destruct menu ::disable_menu_controls(ctx); ::menu::clear_callbacks(ctx); - ::menu::delete_animations(ctx); ::menu::remove_text_from_ui(ctx); ::menu::delete_text(ctx); diff --git a/src/game/states/language-menu-state.cpp b/src/game/states/language-menu-state.cpp index 36097820..8e41b749 100644 --- a/src/game/states/language-menu-state.cpp +++ b/src/game/states/language-menu-state.cpp @@ -47,7 +47,6 @@ language_menu_state::language_menu_state(::game& ctx): ::menu::update_text_font(ctx); ::menu::align_text(ctx); ::menu::add_text_to_ui(ctx); - ::menu::setup_animations(ctx); auto change_language = [&]() { @@ -154,7 +153,6 @@ language_menu_state::~language_menu_state() // Destruct menu ::disable_menu_controls(ctx); ::menu::clear_callbacks(ctx); - ::menu::delete_animations(ctx); ::menu::remove_text_from_ui(ctx); ::menu::delete_text(ctx); diff --git a/src/game/states/main-menu-state.cpp b/src/game/states/main-menu-state.cpp index 1722aad8..3836fa36 100644 --- a/src/game/states/main-menu-state.cpp +++ b/src/game/states/main-menu-state.cpp @@ -2,23 +2,21 @@ // SPDX-License-Identifier: GPL-3.0-or-later #include "game/states/main-menu-state.hpp" -#include -#include #include -#include #include #include "game/components/steering-component.hpp" #include "game/components/transform-component.hpp" +#include "game/components/animation-component.hpp" #include "game/controls.hpp" #include "game/ecoregion.hpp" #include "game/menu.hpp" -#include "game/states/collection-menu-state.hpp" #include "game/states/extras-menu-state.hpp" #include "game/states/nuptial-flight-state.hpp" #include "game/states/options-menu-state.hpp" #include "game/states/experiments/test-state.hpp" #include "game/strings.hpp" #include "game/world.hpp" +#include "game/screen-transition.hpp" #include "game/debug/shell.hpp" #include #include @@ -59,19 +57,35 @@ main_menu_state::main_menu_state(::game& ctx, bool fade_in): // Add text to UI ctx.ui_canvas->get_scene().add_object(*title_text); - // Construct title fade animation - title_fade_animation.set_interpolator(ease::out_cubic); - [[maybe_unused]] animation_channel* opacity_channel = title_fade_animation.add_channel(0); - title_fade_animation.set_frame_callback - ( - [this, &ctx]([[maybe_unused]] int channel, const float& opacity) + // Construct title fade in animation + { + m_title_fade_in_sequence = std::make_shared(); + auto& opacity_track = m_title_fade_in_sequence->tracks()["opacity"]; + auto& opacity_channel = opacity_track.channels().emplace_back(); + opacity_channel.keyframes().emplace(0.0f, 0.0f); + opacity_channel.keyframes().emplace(config::menu_fade_in_duration, 1.0f); + opacity_track.output() = [&](auto samples, auto&) { - math::fvec4 color = this->title_text->get_color(); - color[3] = opacity; - this->title_text->set_color(color); - } - ); - ctx.animator->add_animation(&title_fade_animation); + title_text->set_color({1.0f, 1.0f, 1.0f, samples[0]}); + }; + } + + // Construct title fade out animation + { + m_title_fade_out_sequence = std::make_shared(); + auto& opacity_track = m_title_fade_out_sequence->tracks()["opacity"]; + auto& opacity_channel = opacity_track.channels().emplace_back(); + opacity_channel.keyframes().emplace(0.0f, 1.0f); + opacity_channel.keyframes().emplace(config::menu_fade_out_duration, 0.0f); + opacity_track.output() = [&](auto samples, auto&) + { + title_text->set_color({1.0f, 1.0f, 1.0f, samples[0]}); + }; + } + + // Constructs title entity + m_title_entity = ctx.entity_registry->create(); + ctx.entity_registry->emplace(m_title_entity); // Construct menu item texts start_text = std::make_unique(); @@ -98,7 +112,6 @@ main_menu_state::main_menu_state(::game& ctx, bool fade_in): ::menu::update_text_font(ctx); ::menu::align_text(ctx, true, false, (-viewport_size.y() / 3.0f) / 2.0f); ::menu::add_text_to_ui(ctx); - ::menu::setup_animations(ctx); auto select_start_callback = [this, &ctx]() { @@ -126,9 +139,7 @@ main_menu_state::main_menu_state(::game& ctx, bool fade_in): ::menu::fade_out(ctx, nullptr); // Start fade out to white - //ctx.fade_transition_color->set_value({1, 1, 1}); - ctx.fade_transition_color->set({0, 0, 0}); - ctx.fade_transition->transition(config::new_colony_fade_out_duration, false, ease::out_cubic, false, change_state); + fade_out_to(ctx, change_state); }; auto select_options_callback = [this, &ctx]() { @@ -194,7 +205,7 @@ main_menu_state::main_menu_state(::game& ctx, bool fade_in): ::menu::fade_out(ctx, nullptr); // Fade to black then quit - ctx.fade_transition->transition(config::quit_fade_out_duration, false, ease::out_cubic, false, [&ctx](){ctx.closed=true;}); + fade_out_to(ctx, [&ctx](){ctx.closed=true;}); // Quit immediately //ctx.function_queue.push([&ctx](){ctx.closed=true;}); @@ -224,7 +235,7 @@ main_menu_state::main_menu_state(::game& ctx, bool fade_in): if (fade_in) { // Fade in from black - ctx.fade_transition->transition(config::title_fade_in_duration, true, ease::out_cubic); + fade_in_to(ctx, nullptr); } else { @@ -285,15 +296,14 @@ main_menu_state::~main_menu_state() // Destruct menu ::disable_menu_controls(ctx); ::menu::clear_callbacks(ctx); - ::menu::delete_animations(ctx); ::menu::remove_text_from_ui(ctx); ::menu::delete_text(ctx); // Hide menu BG //ctx.menu_bg_billboard->set_active(false); - // Destruct title animation - ctx.animator->remove_animation(&title_fade_animation); + // Destruct title entity + ctx.entity_registry->destroy(m_title_entity); // Destruct text ctx.ui_canvas->get_scene().remove_object(*title_text); @@ -303,20 +313,14 @@ main_menu_state::~main_menu_state() void main_menu_state::fade_in_title() { - animation_channel* opacity_channel = title_fade_animation.get_channel(0); - opacity_channel->remove_keyframes(); - opacity_channel->insert_keyframe({0.0f, 0.0f}); - opacity_channel->insert_keyframe({config::menu_fade_in_duration, 1.0f}); - title_fade_animation.stop(); - title_fade_animation.play(); + auto& title_player = ctx.entity_registry->get(m_title_entity).player; + title_player.rewind(); + title_player.play(m_title_fade_in_sequence); } void main_menu_state::fade_out_title() { - animation_channel* opacity_channel = title_fade_animation.get_channel(0); - opacity_channel->remove_keyframes(); - opacity_channel->insert_keyframe({0.0f, 1.0f}); - opacity_channel->insert_keyframe({config::menu_fade_out_duration, 0.0f}); - title_fade_animation.stop(); - title_fade_animation.play(); + auto& title_player = ctx.entity_registry->get(m_title_entity).player; + title_player.rewind(); + title_player.play(m_title_fade_out_sequence); } diff --git a/src/game/states/main-menu-state.hpp b/src/game/states/main-menu-state.hpp index 2d27cc2e..21f85ac2 100644 --- a/src/game/states/main-menu-state.hpp +++ b/src/game/states/main-menu-state.hpp @@ -6,7 +6,7 @@ #include "game/states/game-state.hpp" #include -#include +#include #include #include #include @@ -28,7 +28,9 @@ class main_menu_state: public game_state std::unique_ptr extras_text; std::unique_ptr quit_text; - animation title_fade_animation; + entity::id m_title_entity{entt::null}; + std::shared_ptr m_title_fade_in_sequence; + std::shared_ptr m_title_fade_out_sequence; std::shared_ptr window_resized_subscription; }; diff --git a/src/game/states/nuptial-flight-state.cpp b/src/game/states/nuptial-flight-state.cpp index 936e0970..745eb977 100644 --- a/src/game/states/nuptial-flight-state.cpp +++ b/src/game/states/nuptial-flight-state.cpp @@ -32,7 +32,7 @@ #include #include "game/controls.hpp" #include "game/commands/commands.hpp" -#include +#include "game/screen-transition.hpp" #include #include #include "game/world.hpp" @@ -151,8 +151,7 @@ nuptial_flight_state::nuptial_flight_state(::game& ctx): ); // Queue fade in - ctx.fade_transition_color->set({0, 0, 0}); - ctx.function_queue.push(std::bind(&screen_transition::transition, ctx.fade_transition.get(), 1.0f, true, ease::out_sine, true, nullptr)); + fade_in_to(ctx, nullptr); // Refresh frame scheduler ctx.frame_scheduler.refresh(); diff --git a/src/game/states/options-menu-state.cpp b/src/game/states/options-menu-state.cpp index 58a29cf3..5ac0692e 100644 --- a/src/game/states/options-menu-state.cpp +++ b/src/game/states/options-menu-state.cpp @@ -11,8 +11,6 @@ #include "game/menu.hpp" #include "game/controls.hpp" #include -#include -#include #include #include #include "game/strings.hpp" @@ -53,7 +51,6 @@ options_menu_state::options_menu_state(::game& ctx): ::menu::update_text_font(ctx); ::menu::align_text(ctx, true); ::menu::add_text_to_ui(ctx); - ::menu::setup_animations(ctx); // Construct menu item callbacks auto select_controls_callback = [&ctx]() @@ -209,7 +206,6 @@ options_menu_state::~options_menu_state() // Destruct menu ::disable_menu_controls(ctx); ::menu::clear_callbacks(ctx); - ::menu::delete_animations(ctx); ::menu::remove_text_from_ui(ctx); ::menu::delete_text(ctx); diff --git a/src/game/states/pause-menu-state.cpp b/src/game/states/pause-menu-state.cpp index 99f63470..0db207bd 100644 --- a/src/game/states/pause-menu-state.cpp +++ b/src/game/states/pause-menu-state.cpp @@ -7,12 +7,10 @@ #include "game/states/nuptial-flight-state.hpp" #include "game/menu.hpp" #include "game/controls.hpp" +#include "game/screen-transition.hpp" #include -#include -#include #include #include -#include #include #include "game/strings.hpp" #include @@ -49,7 +47,6 @@ pause_menu_state::pause_menu_state(::game& ctx): ::menu::update_text_font(ctx); ::menu::align_text(ctx, true, false); ::menu::add_text_to_ui(ctx); - ::menu::setup_animations(ctx); // Construct menu item callbacks auto select_resume_callback = [&ctx]() @@ -132,8 +129,7 @@ pause_menu_state::pause_menu_state(::game& ctx): ::menu::fade_out(ctx, nullptr); // Fade out to black then return to main menu - ctx.fade_transition_color->set({0, 0, 0}); - ctx.fade_transition->transition(config::quit_fade_out_duration, false, ease::out_cubic, false, fade_out_callback); + fade_out_to(ctx, fade_out_callback); }; auto select_quit_callback = [&ctx]() { @@ -150,8 +146,7 @@ pause_menu_state::pause_menu_state(::game& ctx): ::menu::fade_out(ctx, nullptr); // Fade out to black then quit - ctx.fade_transition_color->set({0, 0, 0}); - ctx.fade_transition->transition(config::quit_fade_out_duration, false, ease::out_cubic, false, [&ctx](){ctx.closed=true;}); + fade_out_to(ctx, [&ctx](){ctx.closed=true;}); }; // Build list of menu select callbacks @@ -200,7 +195,6 @@ pause_menu_state::~pause_menu_state() // Destruct menu ::disable_menu_controls(ctx); ::menu::clear_callbacks(ctx); - ::menu::delete_animations(ctx); ::menu::remove_text_from_ui(ctx); ::menu::delete_text(ctx); diff --git a/src/game/states/sound-menu-state.cpp b/src/game/states/sound-menu-state.cpp index 06a9db45..5b5242cb 100644 --- a/src/game/states/sound-menu-state.cpp +++ b/src/game/states/sound-menu-state.cpp @@ -59,7 +59,6 @@ sound_menu_state::sound_menu_state(::game& ctx): ::menu::update_text_font(ctx); ::menu::align_text(ctx); ::menu::add_text_to_ui(ctx); - ::menu::setup_animations(ctx); // Construct menu item callbacks auto increase_volume_callback = [this, &ctx](float* volume) @@ -209,7 +208,6 @@ sound_menu_state::~sound_menu_state() // Destruct menu ::disable_menu_controls(ctx); ::menu::clear_callbacks(ctx); - ::menu::delete_animations(ctx); ::menu::remove_text_from_ui(ctx); ::menu::delete_text(ctx); diff --git a/src/game/states/splash-state.cpp b/src/game/states/splash-state.cpp index a9682d20..48912742 100644 --- a/src/game/states/splash-state.cpp +++ b/src/game/states/splash-state.cpp @@ -4,10 +4,8 @@ #include "game/states/splash-state.hpp" #include "game/game.hpp" #include "game/states/main-menu-state.hpp" -#include -#include +#include "game/components/animation-component.hpp" #include -#include #include #include #include @@ -34,7 +32,7 @@ splash_state::splash_state(::game& ctx): splash_billboard_material->set_shader_template(ctx.resource_manager->load("ui-element-textured.glsl")); splash_billboard_material->set_variable("background", std::make_shared(1, splash_texture)); - auto splash_tint = std::make_shared(1, math::fvec4{1, 1, 1, 0}); + auto splash_tint = std::make_shared(1, math::fvec4{1, 1, 1, 1}); splash_billboard_material->set_variable("tint", splash_tint); // Construct splash billboard @@ -44,46 +42,27 @@ splash_state::splash_state(::game& ctx): // Add splash billboard to UI scene ctx.ui_canvas->get_scene().add_object(splash_billboard); + + // Setup animation timing configuration + const auto splash_fade_in_duration = 0.5f; + const auto splash_duration = 2.0f; + const auto splash_fade_out_duration = 0.5f; - // Load animation timing configuration - const float splash_fade_in_duration = 0.5; - const float splash_duration = 2.0; - const float splash_fade_out_duration = 0.5; - - // Construct splash fade in animation - splash_fade_in_animation.set_interpolator(ease::out_cubic); - animation_channel* splash_fade_in_opacity_channel = splash_fade_in_animation.add_channel(0); - splash_fade_in_opacity_channel->insert_keyframe({0.0f, 0.0f}); - splash_fade_in_opacity_channel->insert_keyframe({splash_fade_in_duration, 1.0f}); - splash_fade_in_opacity_channel->insert_keyframe({splash_fade_in_duration + splash_duration, 1.0f}); - - // Build splash fade out animation - splash_fade_out_animation.set_interpolator(ease::out_cubic); - animation_channel* splash_fade_out_opacity_channel = splash_fade_out_animation.add_channel(0); - splash_fade_out_opacity_channel->insert_keyframe({0.0f, 1.0f}); - splash_fade_out_opacity_channel->insert_keyframe({splash_fade_out_duration, 0.0f}); - - // Setup animation frame callbacks - auto set_splash_opacity = [splash_tint]([[maybe_unused]] int channel, const float& opacity) + // Construct splash sequence { - splash_tint->set(math::fvec4{1, 1, 1, opacity}); - }; - splash_fade_in_animation.set_frame_callback(set_splash_opacity); - splash_fade_out_animation.set_frame_callback(set_splash_opacity); - - // Trigger splash fade out animation when splash fade in animation ends - splash_fade_in_animation.set_end_callback - ( - [this]() + m_splash_sequence = std::make_shared(); + auto& opacity_track = m_splash_sequence->tracks()["opacity"]; + auto& opacity_channel = opacity_track.channels().emplace_back(); + opacity_channel.keyframes().emplace(0.0f, 0.0f); + opacity_channel.keyframes().emplace(splash_fade_in_duration, 1.0f); + opacity_channel.keyframes().emplace(opacity_channel.duration() + splash_duration, 1.0f); + opacity_channel.keyframes().emplace(opacity_channel.duration() + splash_fade_out_duration, 0.0f); + opacity_track.output() = [splash_tint](auto samples, auto&) { - this->splash_fade_out_animation.play(); - } - ); - - // Trigger a state change when the splash fade out animation ends - splash_fade_out_animation.set_end_callback - ( - [&ctx]() + splash_tint->set(math::fvec4{1, 1, 1, samples[0]}); + }; + + m_splash_sequence->cues().emplace(opacity_track.duration(), [&](auto&) { // Queue change to main menu state ctx.function_queue.push @@ -94,15 +73,16 @@ splash_state::splash_state(::game& ctx): ctx.state_machine.emplace(std::make_unique(ctx, true)); } ); - } - ); + }); + } - // Add splash fade animations to animator - ctx.animator->add_animation(&splash_fade_in_animation); - ctx.animator->add_animation(&splash_fade_out_animation); + // Constructs credits entity + m_splash_entity = ctx.entity_registry->create(); + ctx.entity_registry->emplace(m_splash_entity); - // Start splash fade in animation - splash_fade_in_animation.play(); + // Play splash sequence + auto& splash_player = ctx.entity_registry->get(m_splash_entity).player; + splash_player.play(m_splash_sequence); // Setup window resized callback window_resized_subscription = ctx.window->get_resized_channel().subscribe @@ -176,9 +156,8 @@ splash_state::~splash_state() ctx.input_mapper.disconnect(); input_mapped_subscriptions.clear(); - // Remove splash fade animations from animator - ctx.animator->remove_animation(&splash_fade_in_animation); - ctx.animator->remove_animation(&splash_fade_out_animation); + // Destruct splash entity + ctx.entity_registry->destroy(m_splash_entity); // Remove splash billboard from UI scene ctx.ui_canvas->get_scene().remove_object(splash_billboard); diff --git a/src/game/states/splash-state.hpp b/src/game/states/splash-state.hpp index f001103f..90aa18cd 100644 --- a/src/game/states/splash-state.hpp +++ b/src/game/states/splash-state.hpp @@ -7,8 +7,9 @@ #include "game/states/game-state.hpp" #include #include -#include +#include #include +#include #include @@ -21,8 +22,8 @@ class splash_state: public game_state private: std::shared_ptr splash_billboard_material; scene::billboard splash_billboard; - animation splash_fade_in_animation; - animation splash_fade_out_animation; + entity::id m_splash_entity; + std::shared_ptr m_splash_sequence; std::vector> input_mapped_subscriptions; std::shared_ptr window_resized_subscription; }; diff --git a/src/game/systems/animation-system.cpp b/src/game/systems/animation-system.cpp index 6e6e9862..fe2c85a2 100644 --- a/src/game/systems/animation-system.cpp +++ b/src/game/systems/animation-system.cpp @@ -63,7 +63,7 @@ void animation_system::interpolate(float alpha) m_previous_render_time = m_render_time; m_render_time = m_previous_update_time + m_fixed_timestep * alpha; - const auto dt = m_render_time - m_previous_render_time; + const auto dt = std::max(0.0f, m_render_time - m_previous_render_time); auto animation_view = m_registry.view(); std::for_each diff --git a/src/game/world.cpp b/src/game/world.cpp index 5f90070c..46c69712 100644 --- a/src/game/world.cpp +++ b/src/game/world.cpp @@ -40,7 +40,6 @@ #include #include #include -#include #include #include @@ -451,10 +450,4 @@ void enter_ecoregion(::game& ctx, const ecoregion& ecoregion) debug::log_trace("Entered ecoregion {}", ecoregion.name); } -void switch_scene(::game& ctx) -{ - ctx.fade_transition_color->set({0, 0, 0}); - ctx.fade_transition->transition(1.0f, false, ease::out_cubic, false, [](){}); -} - } // namespace world diff --git a/src/game/world.hpp b/src/game/world.hpp index b678c1f6..fa078da3 100644 --- a/src/game/world.hpp +++ b/src/game/world.hpp @@ -64,8 +64,6 @@ void set_time_scale(::game& ctx, double scale); */ void enter_ecoregion(::game& ctx, const ecoregion& ecoregion); -void switch_scene(::game& ctx); - } // namespace menu #endif // ANTKEEPER_GAME_WORLD_HPP