Files
vibe3_physics/source/input/input_handler.cpp
Sergio Valor d2e7f2ff86 refactor(gpu): eliminar GPU compute boids (prevé crash macOS)
Elimina el kernel Metal O(N²) de boids en GPU que causava GPU timeout
a macOS amb >50K boles, arrossegant WindowServer fins al crash.

- Elimina gpu_boid_buffer.hpp/cpp (GpuBoidBuffer, BallComputeData, BoidParams)
- Elimina kBoidComputeMSL i kBallComputeVertMSL de gpu_pipeline
- Elimina boid_compute_pipeline_ i ball_compute_pipeline_
- Elimina use_gpu_boids_, boid_params_, ball_screen_uniforms_ de Engine
- Elimina syncAndExitGpuBoids() i tot el compute dispatch de render()
- Mode BOIDS ara usa sempre boid_manager_ (CPU, spatial hash O(N))
  i renderitza via gpu_ball_buffer_ instanced (mateix path que PHYSICS)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-20 08:45:01 +01:00

298 lines
10 KiB
C++

#include "input_handler.hpp"
#include <SDL3/SDL_keycode.h> // for SDL_Keycode
#include <string> // for std::string, std::to_string
#include "defines.hpp" // for KIOSK_NOTIFICATION_TEXT
#include "engine.hpp" // for Engine
#include "external/mouse.hpp" // for Mouse namespace
bool InputHandler::processEvents(Engine& engine) {
SDL_Event event;
while (SDL_PollEvent(&event)) {
// Procesar eventos de ratón (auto-ocultar cursor)
Mouse::handleEvent(event);
// Salir del bucle si se detecta una petición de cierre
if (event.type == SDL_EVENT_QUIT) {
return true; // Solicitar salida
}
// Procesar eventos de teclado
if (event.type == SDL_EVENT_KEY_DOWN && event.key.repeat == 0) {
switch (event.key.key) {
case SDLK_ESCAPE:
if (engine.isKioskMode()) {
engine.showNotificationForAction(KIOSK_NOTIFICATION_TEXT);
break;
}
return true; // Solicitar salida
case SDLK_SPACE:
engine.pushBallsAwayFromGravity();
break;
case SDLK_G:
engine.handleGravityToggle();
break;
// Controles de dirección de gravedad con teclas de cursor
case SDLK_UP:
engine.handleGravityDirectionChange(GravityDirection::UP, "Gravedad Arriba");
break;
case SDLK_DOWN:
engine.handleGravityDirectionChange(GravityDirection::DOWN, "Gravedad Abajo");
break;
case SDLK_LEFT:
engine.handleGravityDirectionChange(GravityDirection::LEFT, "Gravedad Izquierda");
break;
case SDLK_RIGHT:
engine.handleGravityDirectionChange(GravityDirection::RIGHT, "Gravedad Derecha");
break;
case SDLK_V:
engine.toggleVSync();
break;
case SDLK_H:
engine.toggleHelp(); // Toggle ayuda de teclas
break;
// Toggle Física ↔ Última Figura (antes era C)
case SDLK_F:
engine.toggleShapeMode();
break;
// Selección directa de figuras 3D
case SDLK_Q:
engine.activateShape(ShapeType::SPHERE, "Esfera");
break;
case SDLK_W:
engine.activateShape(ShapeType::LISSAJOUS, "Lissajous");
break;
case SDLK_E:
engine.activateShape(ShapeType::HELIX, "Hélice");
break;
case SDLK_R:
engine.activateShape(ShapeType::TORUS, "Toroide");
break;
case SDLK_T:
engine.activateShape(ShapeType::CUBE, "Cubo");
break;
case SDLK_Y:
engine.activateShape(ShapeType::CYLINDER, "Cilindro");
break;
case SDLK_U:
engine.activateShape(ShapeType::ICOSAHEDRON, "Icosaedro");
break;
case SDLK_I:
engine.activateShape(ShapeType::ATOM, "Átomo");
break;
case SDLK_O:
// engine.activateShape(ShapeType::PNG_SHAPE, "Forma PNG");
break;
// Toggle Modo Boids (comportamiento de enjambre)
case SDLK_B:
engine.toggleBoidsMode();
break;
// Ciclar temas de color (movido de B a C)
case SDLK_C:
{
// Detectar si Shift está presionado
SDL_Keymod modstate = SDL_GetModState();
if (modstate & SDL_KMOD_SHIFT) {
// Shift+C: Ciclar hacia atrás (tema anterior)
engine.cycleTheme(false);
} else {
// C solo: Ciclar hacia adelante (tema siguiente)
engine.cycleTheme(true);
}
}
break;
// Temas de colores con teclado numérico (con transición suave)
case SDLK_KP_1:
engine.switchThemeByNumpad(1);
break;
case SDLK_KP_2:
engine.switchThemeByNumpad(2);
break;
case SDLK_KP_3:
engine.switchThemeByNumpad(3);
break;
case SDLK_KP_4:
engine.switchThemeByNumpad(4);
break;
case SDLK_KP_5:
engine.switchThemeByNumpad(5);
break;
case SDLK_KP_6:
engine.switchThemeByNumpad(6);
break;
case SDLK_KP_7:
engine.switchThemeByNumpad(7);
break;
case SDLK_KP_8:
engine.switchThemeByNumpad(8);
break;
case SDLK_KP_9:
engine.switchThemeByNumpad(9);
break;
case SDLK_KP_0:
engine.switchThemeByNumpad(0);
break;
// Toggle de página de temas (Numpad Enter)
case SDLK_KP_ENTER:
engine.toggleThemePage();
break;
// Cambio de sprite/textura dinámico
case SDLK_N:
engine.switchTexture();
break;
// Control de escala de figura (solo en modo SHAPE)
case SDLK_KP_PLUS:
engine.handleShapeScaleChange(true); // Aumentar
break;
case SDLK_KP_MINUS:
engine.handleShapeScaleChange(false); // Disminuir
break;
case SDLK_KP_MULTIPLY:
engine.resetShapeScale();
break;
case SDLK_KP_DIVIDE:
engine.toggleDepthZoom();
break;
// Cambio de número de pelotas (escenarios 1-8)
case SDLK_1:
engine.changeScenario(0, "10 Pelotas");
break;
case SDLK_2:
engine.changeScenario(1, "50 Pelotas");
break;
case SDLK_3:
engine.changeScenario(2, "100 Pelotas");
break;
case SDLK_4:
engine.changeScenario(3, "500 Pelotas");
break;
case SDLK_5:
engine.changeScenario(4, "1,000 Pelotas");
break;
case SDLK_6:
engine.changeScenario(5, "5,000 Pelotas");
break;
case SDLK_7:
engine.changeScenario(6, "10,000 Pelotas");
break;
case SDLK_8:
engine.changeScenario(7, "50,000 Pelotas");
break;
case SDLK_9:
if (engine.isCustomScenarioEnabled()) {
std::string custom_notif = std::to_string(engine.getCustomScenarioBalls()) + " Pelotas";
engine.changeScenario(CUSTOM_SCENARIO_IDX, custom_notif.c_str());
}
break;
// Controles de zoom dinámico (solo si no estamos en fullscreen)
case SDLK_F1:
if (engine.isKioskMode()) engine.showNotificationForAction(KIOSK_NOTIFICATION_TEXT);
else engine.handleZoomOut();
break;
case SDLK_F2:
if (engine.isKioskMode()) engine.showNotificationForAction(KIOSK_NOTIFICATION_TEXT);
else engine.handleZoomIn();
break;
// Control de pantalla completa
case SDLK_F3:
if (engine.isKioskMode()) engine.showNotificationForAction(KIOSK_NOTIFICATION_TEXT);
else engine.toggleFullscreen();
break;
// Modo real fullscreen (cambia resolución interna)
case SDLK_F4:
if (engine.isKioskMode()) engine.showNotificationForAction(KIOSK_NOTIFICATION_TEXT);
else engine.toggleRealFullscreen();
break;
// Toggle escalado entero/estirado (solo en fullscreen F3)
case SDLK_F5:
engine.toggleIntegerScaling();
break;
// Toggle Modo DEMO COMPLETO (auto-play) o Pausar tema dinámico (Shift+D)
case SDLK_D:
// Shift+D = Pausar tema dinámico
if (event.key.mod & SDL_KMOD_SHIFT) {
engine.pauseDynamicTheme();
} else {
// D sin Shift = Toggle DEMO ↔ SANDBOX
engine.toggleDemoMode();
}
break;
// Toggle Modo DEMO LITE (solo física/figuras)
case SDLK_L:
engine.toggleDemoLiteMode();
break;
// Toggle Modo LOGO (easter egg - marca de agua)
case SDLK_K:
engine.toggleLogoMode();
break;
// Ciclar presets PostFX (vinyeta/scanlines/cromàtica/complet/desactivat)
case SDLK_X:
engine.handlePostFXCycle();
break;
// Toggle Debug Display (movido de H a F12)
case SDLK_F12:
engine.toggleDebug();
break;
}
}
}
return false; // No se solicitó salida
}