Files
vibe3_physics/source/shapes/png_shape.hpp
Sergio c9bcce6f9b style: aplicar fixes de clang-tidy (todo excepto uppercase-literal-suffix)
Corregidos ~2570 issues automáticamente con clang-tidy --fix-errors
más ajustes manuales posteriores:

- modernize: designated-initializers, trailing-return-type, use-auto,
  avoid-c-arrays (→ std::array<>), use-ranges, use-emplace,
  deprecated-headers, use-equals-default, pass-by-value,
  return-braced-init-list, use-default-member-init
- readability: math-missing-parentheses, implicit-bool-conversion,
  braces-around-statements, isolate-declaration, use-std-min-max,
  identifier-naming, else-after-return, redundant-casting,
  convert-member-functions-to-static, make-member-function-const,
  static-accessed-through-instance
- performance: avoid-endl, unnecessary-value-param, type-promotion,
  inefficient-vector-operation
- dead code: XOR_KEY (orphan tras eliminar encryptData/decryptData),
  dead stores en engine.cpp y png_shape.cpp
- NOLINT justificado en 10 funciones con alta complejidad cognitiva
  (initialize, render, main, processEvents, update×3, performDemoAction,
  randomizeOnDemoStart, renderDebugHUD, AppLogo::update)

Compilación: gcc -Wall sin warnings. clang-tidy: 0 issues.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-21 10:52:07 +01:00

109 lines
5.0 KiB
C++

#pragma once
#include <cstdlib> // Para rand()
#include <vector>
#include "defines.hpp" // Para PNG_IDLE_TIME_MIN/MAX constantes
#include "shape.hpp"
// 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<bool> pixel_data_; // Mapa de píxeles blancos (true = blanco)
// Puntos generados (Enfoque A: Extrusión 2D)
struct Point2D {
float x, y;
};
std::vector<Point2D> edge_points_; // Contorno (solo bordes) - ORIGINAL sin optimizar
std::vector<Point2D> filled_points_; // Relleno completo - ORIGINAL sin optimizar
std::vector<Point2D> 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* resource_key); // 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)
static std::vector<Point2D> extractAlternateRows(const std::vector<Point2D>& source, int row_skip); // Extraer filas alternas
static std::vector<Point2D> extractCornerVertices(const std::vector<Point2D>& 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;
};