#pragma once #include "shape.h" #include "../defines.h" // Para PNG_IDLE_TIME_MIN/MAX constantes #include #include // Para rand() // Figura: Shape generada desde PNG 1-bit (blanco sobre negro) // Enfoque A: Extrusión 2D (implementado) // Enfoque B: Voxelización 3D (preparado para futuro) class PNGShape : public Shape { private: // Datos de la imagen cargada int image_width_ = 0; int image_height_ = 0; std::vector pixel_data_; // Mapa de píxeles blancos (true = blanco) // Puntos generados (Enfoque A: Extrusión 2D) struct Point2D { float x, y; }; std::vector edge_points_; // Contorno (solo bordes) - ORIGINAL sin optimizar std::vector filled_points_; // Relleno completo - ORIGINAL sin optimizar std::vector optimized_points_; // Puntos finales optimizados (usado por getPoint3D) // Parámetros de extrusión float extrusion_depth_ = 0.0f; // Profundidad de extrusión en Z int num_layers_ = 0; // Capas de extrusión (más capas = más denso) // Rotación "legible" (de frente con volteretas ocasionales) float angle_x_ = 0.0f; float angle_y_ = 0.0f; float idle_timer_ = 0.0f; // Timer para tiempo de frente float flip_timer_ = 0.0f; // Timer para voltereta float next_idle_time_ = 5.0f; // Próximo tiempo de espera (aleatorio) bool is_flipping_ = false; // Estado: quieto o voltereta int flip_axis_ = 0; // Eje de voltereta (0=X, 1=Y, 2=ambos) // Pivoteo sutil en estado IDLE float tilt_x_ = 0.0f; // Oscilación sutil en eje X float tilt_y_ = 0.0f; // Oscilación sutil en eje Y // Modo LOGO (intervalos de flip más largos) bool is_logo_mode_ = false; // true = usar intervalos LOGO (más lentos) // Sistema de convergencia (solo relevante en modo LOGO) float current_convergence_ = 0.0f; // Porcentaje actual de convergencia (0.0-1.0) bool convergence_threshold_reached_ = false; // true si ha alcanzado umbral mínimo (80%) // Sistema de tracking de flips (para modo LOGO - espera de flips) int flip_count_ = 0; // Contador de flips completados (reset al entrar a LOGO) bool was_flipping_last_frame_ = false; // Estado previo para detectar transiciones // Dimensiones normalizadas float scale_factor_ = 1.0f; float center_offset_x_ = 0.0f; float center_offset_y_ = 0.0f; int num_points_ = 0; // Total de puntos generados (para indexación) // Métodos internos bool loadPNG(const char* path); // Cargar PNG con stb_image void detectEdges(); // Detectar contorno (Enfoque A) void floodFill(); // Rellenar interior (Enfoque B - futuro) void generateExtrudedPoints(); // Generar puntos con extrusión 2D // Métodos de distribución adaptativa (funciones puras, no modifican parámetros) std::vector extractAlternateRows(const std::vector& source, int row_skip); // Extraer filas alternas std::vector extractCornerVertices(const std::vector& source); // Extraer vértices/esquinas public: // Constructor: recibe path relativo al PNG PNGShape(const char* png_path = "data/shapes/jailgames.png"); void generatePoints(int num_points, float screen_width, float screen_height) override; void update(float delta_time, float screen_width, float screen_height) override; void getPoint3D(int index, float& x, float& y, float& z) const override; const char* getName() const override { return "PNG SHAPE"; } float getScaleFactor(float screen_height) const override; // Consultar estado de flip bool isFlipping() const { return is_flipping_; } // Obtener progreso del flip actual (0.0 = inicio, 1.0 = fin) float getFlipProgress() const; // Obtener número de flips completados (para modo LOGO) int getFlipCount() const { return flip_count_; } // Resetear contador de flips (llamar al entrar a LOGO MODE) void resetFlipCount() { flip_count_ = 0; was_flipping_last_frame_ = false; } // Control de modo LOGO (flip intervals más largos) void setLogoMode(bool enable) { is_logo_mode_ = enable; // Recalcular next_idle_time_ con el rango apropiado float idle_min = enable ? PNG_IDLE_TIME_MIN_LOGO : PNG_IDLE_TIME_MIN; float idle_max = enable ? PNG_IDLE_TIME_MAX_LOGO : PNG_IDLE_TIME_MAX; next_idle_time_ = idle_min + (rand() % 1000) / 1000.0f * (idle_max - idle_min); } // Sistema de convergencia (override de Shape::setConvergence) void setConvergence(float convergence) override; };