// ship_animator.hpp - Sistema d'animació de naus 3D per a l'escena de títol // © 2026 JailDesigner // // Manté la mateixa màquina d'estats // (ENTERING → FLOATING → EXITING) però treballa amb posicions Vec3 i emet // wireframes a través d'una `Camera3D`. La geometria s'extrau de `ship.shp` // (P1) i `ship2.shp` (P2) per extrusió en Z. #pragma once #include #include #include #include "core/graphics/camera3d.hpp" #include "core/graphics/wireframe3d.hpp" #include "core/rendering/render_context.hpp" #include "core/types.hpp" namespace Title { enum class ShipState : std::uint8_t { ENTERING, FLOATING, EXITING, }; struct TitleShip { int player_id{0}; ShipState state{ShipState::ENTERING}; float state_time{0.0F}; Vec3 initial_position{}; Vec3 target_position{}; Vec3 current_position{}; float initial_scale{1.0F}; float target_scale{1.0F}; float current_scale{1.0F}; float oscillation_phase{0.0F}; float entry_delay{0.0F}; float amplitude_x{0.0F}; float amplitude_y{0.0F}; float frequency_x{0.0F}; float frequency_y{0.0F}; Graphics::Mesh3D mesh; // Vector mundial cap a on apunta el front del shape. Recalculat a cada // transició d'estat perquè draw() oriente la nau (look-at) en la // direcció del seu path actual. Vec3 forward_dir{.x = 0.0F, .y = 0.0F, .z = 1.0F}; bool visible{false}; }; class ShipAnimator { public: ShipAnimator(Rendering::Renderer* renderer, const Graphics::Camera3D* camera); void init(); void update(float delta_time); void draw() const; void startEntryAnimation(); void triggerExitAnimation(); void triggerExitAnimationForPlayer(int player_id); void skipToFloatingState(); void setVisible(bool visible); [[nodiscard]] auto isAnimationComplete() const -> bool; [[nodiscard]] auto isVisible() const -> bool; // Callback disparat quan una nau acaba l'EXITING (es torna invisible // al VP). Útil per a un destell que tapi el pop final. using ShipDisappearCallback = std::function; void setOnShipDisappear(ShipDisappearCallback cb) { on_ship_disappear_ = std::move(cb); } private: Rendering::Renderer* renderer_; const Graphics::Camera3D* camera_; std::array ships_; ShipDisappearCallback on_ship_disappear_; static void updateEntering(TitleShip& ship, float delta_time); static void updateFloating(TitleShip& ship, float delta_time); static void updateExiting(TitleShip& ship, float delta_time); static void configureShipP1(TitleShip& ship); static void configureShipP2(TitleShip& ship); }; } // namespace Title