Implementar control manual de escala para figuras 3D + actualizar README
NUEVAS CARACTERÍSTICAS: - Control de escala dinámico con Numpad +/-/* (30%-300%) - Protección automática contra clipping según resolución - Texto informativo muestra porcentaje de escala - Fix: Redondeo correcto en display de escala (79% → 80%) CAMBIOS EN README: - Actualizar tabla de controles (C→F, T→B, añadir Q/W/E/R/T/Y/U/I) - Documentar sistema polimórfico de figuras 3D - Añadir sección "Controles de Figuras 3D" con Numpad +/-/* - Actualizar debug display (8 líneas ahora) - Expandir sección "Modo RotoBall" → "Sistema de Figuras 3D" - Documentar Esfera y Cubo implementados - Listar 6 figuras futuras (Wave/Helix/Torus/Cylinder/Icosahedron/Atom) - Actualizar estructura del proyecto (añadir source/shapes/) - Añadir parámetros de escala manual a sección técnica IMPLEMENTACIÓN TÉCNICA: - defines.h: Constantes SHAPE_SCALE_MIN/MAX/STEP/DEFAULT - engine.h: Variable shape_scale_factor_, método clampShapeScale() - engine.cpp: Handlers Numpad +/-/*, multiplicar scale_factor en updateShape() - clampShapeScale(): Límite dinámico según tamaño de pantalla (90% máximo) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -100,4 +100,10 @@ constexpr float CUBE_ROTATION_SPEED_X = 0.5f; // Velocidad rotación eje X
|
||||
constexpr float CUBE_ROTATION_SPEED_Y = 0.7f; // Velocidad rotación eje Y (rad/s)
|
||||
constexpr float CUBE_ROTATION_SPEED_Z = 0.3f; // Velocidad rotación eje Z (rad/s)
|
||||
|
||||
// Control manual de escala de figuras 3D (Numpad +/-)
|
||||
constexpr float SHAPE_SCALE_MIN = 0.3f; // Escala mínima (30%)
|
||||
constexpr float SHAPE_SCALE_MAX = 3.0f; // Escala máxima (300%)
|
||||
constexpr float SHAPE_SCALE_STEP = 0.1f; // Incremento por pulsación
|
||||
constexpr float SHAPE_SCALE_DEFAULT = 1.0f; // Escala por defecto (100%)
|
||||
|
||||
constexpr float PI = 3.14159265358979323846f; // Constante PI
|
||||
@@ -310,6 +310,42 @@ void Engine::handleEvents() {
|
||||
initBalls(scenario_);
|
||||
break;
|
||||
|
||||
// Control de escala de figura (solo en modo SHAPE)
|
||||
case SDLK_KP_PLUS:
|
||||
if (current_mode_ == SimulationMode::SHAPE) {
|
||||
shape_scale_factor_ += SHAPE_SCALE_STEP;
|
||||
clampShapeScale();
|
||||
text_ = "SCALE " + std::to_string(static_cast<int>(shape_scale_factor_ * 100.0f + 0.5f)) + "%";
|
||||
int text_width = static_cast<int>(text_.length() * 8);
|
||||
text_pos_ = (current_screen_width_ - text_width) / 2;
|
||||
text_init_time_ = SDL_GetTicks();
|
||||
show_text_ = true;
|
||||
}
|
||||
break;
|
||||
|
||||
case SDLK_KP_MINUS:
|
||||
if (current_mode_ == SimulationMode::SHAPE) {
|
||||
shape_scale_factor_ -= SHAPE_SCALE_STEP;
|
||||
clampShapeScale();
|
||||
text_ = "SCALE " + std::to_string(static_cast<int>(shape_scale_factor_ * 100.0f + 0.5f)) + "%";
|
||||
int text_width = static_cast<int>(text_.length() * 8);
|
||||
text_pos_ = (current_screen_width_ - text_width) / 2;
|
||||
text_init_time_ = SDL_GetTicks();
|
||||
show_text_ = true;
|
||||
}
|
||||
break;
|
||||
|
||||
case SDLK_KP_MULTIPLY:
|
||||
if (current_mode_ == SimulationMode::SHAPE) {
|
||||
shape_scale_factor_ = SHAPE_SCALE_DEFAULT;
|
||||
text_ = "SCALE RESET (100%)";
|
||||
int text_width = static_cast<int>(text_.length() * 8);
|
||||
text_pos_ = (current_screen_width_ - text_width) / 2;
|
||||
text_init_time_ = SDL_GetTicks();
|
||||
show_text_ = true;
|
||||
}
|
||||
break;
|
||||
|
||||
case SDLK_1:
|
||||
scenario_ = 0;
|
||||
initBalls(scenario_);
|
||||
@@ -1052,8 +1088,8 @@ void Engine::updateShape() {
|
||||
// Actualizar animación de la figura
|
||||
active_shape_->update(delta_time_, static_cast<float>(current_screen_width_), static_cast<float>(current_screen_height_));
|
||||
|
||||
// Obtener factor de escala para física
|
||||
float scale_factor = active_shape_->getScaleFactor(static_cast<float>(current_screen_height_));
|
||||
// Obtener factor de escala para física (base de figura + escala manual)
|
||||
float scale_factor = active_shape_->getScaleFactor(static_cast<float>(current_screen_height_)) * shape_scale_factor_;
|
||||
|
||||
// Centro de la pantalla
|
||||
float center_x = current_screen_width_ / 2.0f;
|
||||
@@ -1065,6 +1101,11 @@ void Engine::updateShape() {
|
||||
float x_3d, y_3d, z_3d;
|
||||
active_shape_->getPoint3D(static_cast<int>(i), x_3d, y_3d, z_3d);
|
||||
|
||||
// Aplicar escala manual a las coordenadas 3D
|
||||
x_3d *= shape_scale_factor_;
|
||||
y_3d *= shape_scale_factor_;
|
||||
z_3d *= shape_scale_factor_;
|
||||
|
||||
// Proyección 2D ortográfica (punto objetivo móvil)
|
||||
float target_x = center_x + x_3d;
|
||||
float target_y = center_y + y_3d;
|
||||
@@ -1080,4 +1121,18 @@ void Engine::updateShape() {
|
||||
z_normalized = std::max(0.0f, std::min(1.0f, z_normalized));
|
||||
balls_[i]->setDepthBrightness(z_normalized);
|
||||
}
|
||||
}
|
||||
|
||||
// Limitar escala de figura para evitar que se salga de pantalla
|
||||
void Engine::clampShapeScale() {
|
||||
// Calcular tamaño máximo permitido según resolución actual
|
||||
// La figura más grande (esfera/cubo) usa ~33% de altura por defecto
|
||||
// Permitir hasta que la figura ocupe 90% de la dimensión más pequeña
|
||||
float max_dimension = std::min(current_screen_width_, current_screen_height_);
|
||||
float base_size_factor = 0.333f; // ROTOBALL_RADIUS_FACTOR o similar
|
||||
float max_scale_for_screen = (max_dimension * 0.9f) / (max_dimension * base_size_factor);
|
||||
|
||||
// Limitar entre SHAPE_SCALE_MIN y el mínimo de (SHAPE_SCALE_MAX, max_scale_for_screen)
|
||||
float max_allowed = std::min(SHAPE_SCALE_MAX, max_scale_for_screen);
|
||||
shape_scale_factor_ = std::max(SHAPE_SCALE_MIN, std::min(max_allowed, shape_scale_factor_));
|
||||
}
|
||||
@@ -86,6 +86,7 @@ private:
|
||||
ShapeType current_shape_type_ = ShapeType::SPHERE; // Tipo de figura actual
|
||||
ShapeType last_shape_type_ = ShapeType::SPHERE; // Última figura para toggle F
|
||||
std::unique_ptr<Shape> active_shape_; // Puntero polimórfico a figura activa
|
||||
float shape_scale_factor_ = 1.0f; // Factor de escala manual (Numpad +/-)
|
||||
|
||||
// Batch rendering
|
||||
std::vector<SDL_Vertex> batch_vertices_;
|
||||
@@ -129,4 +130,5 @@ private:
|
||||
void activateShape(ShapeType type); // Activar figura específica (teclas Q/W/E/R/Y/U/I)
|
||||
void updateShape(); // Actualizar figura activa
|
||||
void generateShape(); // Generar puntos de figura activa
|
||||
void clampShapeScale(); // Limitar escala para evitar clipping
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user