PROBLEMAS RESUELTOS: 1. getPoint3D() ignoraba optimización → usaba edge_points_ siempre 2. extractAlternateRows() era destructiva → filtraba sobre filtrado 3. Con 10,000 pelotas mostraba bordes → ahora muestra RELLENO 4. Con 100 pelotas solo primera fila → ahora muestra todo el texto CAMBIOS IMPLEMENTADOS: - Añadido optimized_points_ (vector resultado final) - extractAlternateRows() ahora es función pura (devuelve nuevo vector) - extractCornerVertices() ahora es función pura - Cada nivel recalcula desde original (no desde filtrado previo) - getPoint3D() usa optimized_points_ exclusivamente FLUJO CORRECTO: - 10,000 pelotas: RELLENO completo (capas reducidas) - 500 pelotas: RELLENO + filas alternas (texto completo visible) - 100 pelotas: BORDES completos (todo el texto visible) - 10 pelotas: VÉRTICES (esqueleto visible) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
64 lines
2.8 KiB
C++
64 lines
2.8 KiB
C++
#pragma once
|
|
|
|
#include "shape.h"
|
|
#include <vector>
|
|
|
|
// 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)
|
|
|
|
// 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<Point2D> extractAlternateRows(const std::vector<Point2D>& source, int row_skip); // Extraer filas alternas
|
|
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;
|
|
};
|