# Claude Code Session - ViBe3 Physics

## Estado del Proyecto

**Proyecto:** ViBe3 Physics - Simulador de sprites con físicas avanzadas
**Objetivo:** Implementar nuevas físicas experimentales expandiendo sobre el sistema de delta time
**Base:** Migrado desde vibe1_delta con sistema delta time ya implementado

## Progreso Actual

### ✅ Completado

#### 1. **Migración y Setup Inicial**
   - ✅ Renombrado vibe1_delta → vibe3_physics en todos los archivos
   - ✅ Carpeta resources → data
   - ✅ Actualizado CMakeLists.txt, .gitignore, defines.h, README.md
   - ✅ Añadido .claude/ al .gitignore
   - ✅ Sistema de compilación CMake funcionando

#### 2. **Sistema de Físicas Base (Heredado)**
   - ✅ **Delta time implementado** - Física independiente del framerate
   - ✅ Contador FPS en tiempo real (esquina superior derecha, amarillo)
   - ✅ Control V-Sync dinámico con tecla "V" (ON/OFF)
   - ✅ Display V-Sync (esquina superior izquierda, cian)
   - ✅ **Sistema de temas visuales** - 4 temas (SUNSET/OCEAN/NEON/FOREST)
   - ✅ **Batch rendering optimizado** - Maneja hasta 100,000 sprites

#### 3. **NUEVA CARACTERÍSTICA: Gravedad Direccional** 🎯
   - ✅ **Enum GravityDirection** (UP/DOWN/LEFT/RIGHT) en defines.h
   - ✅ **Ball class actualizada** para física multi-direccional
   - ✅ **Detección de superficie inteligente** - Adaptada a cada dirección
   - ✅ **Fricción direccional** - Se aplica en la superficie correcta
   - ✅ **Controles de cursor** - Cambio dinámico de gravedad
   - ✅ **Debug display actualizado** - Muestra dirección actual

#### 4. **NUEVA CARACTERÍSTICA: Coeficientes de Rebote Variables** ⚡
   - ✅ **Rango ampliado** - De 0.60-0.89 a 0.30-0.95 (+120% variabilidad)
   - ✅ **Comportamientos diversos** - Desde pelotas super rebotonas a muy amortiguadas
   - ✅ **Debug display** - Muestra coeficiente LOSS de primera pelota
   - ✅ **Física realista** - Elimina sincronización entre pelotas

#### 5. **🎯 NUEVA CARACTERÍSTICA: Modo RotoBall (Esfera 3D Rotante)** 🌐
   - ✅ **Fibonacci Sphere Algorithm** - Distribución uniforme de puntos en esfera 3D
   - ✅ **Rotación dual (X/Y)** - Efecto visual dinámico estilo demoscene
   - ✅ **Profundidad Z simulada** - Color mod según distancia (oscuro=lejos, brillante=cerca)
   - ✅ **Física de atracción con resorte** - Sistema de fuerzas con conservación de momento
   - ✅ **Transición física realista** - Pelotas atraídas a esfera rotante con aceleración
   - ✅ **Amortiguación variable** - Mayor damping cerca del punto (estabilización)
   - ✅ **Sin sprites adicionales** - Usa SDL_SetTextureColorMod para profundidad
   - ✅ **Proyección ortográfica** - Coordenadas 3D → 2D en tiempo real
   - ✅ **Conservación de inercia** - Al salir mantienen velocidad tangencial
   - ✅ **Compatible con temas** - Mantiene paleta de colores activa
   - ✅ **Performance optimizado** - Funciona con 1-100,000 pelotas

### 📋 Controles Actuales

| Tecla | Acción |
|-------|--------|
| **↑** | **Gravedad hacia ARRIBA** |
| **↓** | **Gravedad hacia ABAJO** |
| **←** | **Gravedad hacia IZQUIERDA** |
| **→** | **Gravedad hacia DERECHA** |
| **C** | **🌐 MODO ROTOBALL - Toggle esfera 3D rotante** |
| V | Alternar V-Sync ON/OFF |
| H | **Toggle debug display (FPS, V-Sync, física, gravedad, modo)** |
| Num 1-5 | Selección directa de tema (1-Atardecer/2-Océano/3-Neón/4-Bosque/5-RGB) |
| T | Ciclar entre temas de colores |
| 1-8 | Cambiar número de pelotas (1 a 100,000) |
| ESPACIO | Impulsar pelotas hacia arriba |
| G | Alternar gravedad ON/OFF (mantiene dirección) |
| ESC | Salir |

### 🎯 Debug Display (Tecla H)

Cuando está activado muestra:
```
FPS: 75           # Esquina superior derecha (amarillo)
VSYNC ON          # Esquina superior izquierda (cian)
GRAV 720          # Magnitud gravedad (magenta)
VY -145           # Velocidad Y primera pelota (magenta)
SURFACE YES       # En superficie (magenta)
LOSS 0.73         # Coeficiente rebote primera pelota (magenta)
GRAVITY DOWN      # Dirección actual (amarillo)
THEME SUNSET      # Tema activo (amarillo claro)
MODE PHYSICS      # Modo simulación actual (verde claro) - PHYSICS/ROTOBALL
```

## Arquitectura Actual

```
vibe3_physics/
├── source/
│   ├── main.cpp           # Bucle principal + controles + debug
│   ├── ball.h/.cpp        # Clase Ball con física direccional
│   ├── defines.h          # Constantes + enum GravityDirection
│   └── external/          # Utilidades externas
│       ├── texture.h/.cpp # Gestión texturas + nearest filter
│       ├── sprite.h/.cpp  # Sistema sprites
│       ├── dbgtxt.h       # Debug text + nearest filter
│       └── stb_image.h    # Carga imágenes
├── data/                  # Recursos (antes resources/)
│   └── ball.png          # Textura pelota 10x10px
├── CMakeLists.txt        # Build system
└── CLAUDE.md            # Este archivo de seguimiento
```

## Sistema de Gravedad Direccional

### 🔧 Implementación Técnica

#### Enum y Estados
```cpp
enum class GravityDirection {
    DOWN,    // ↓ Gravedad hacia abajo (por defecto)
    UP,      // ↑ Gravedad hacia arriba
    LEFT,    // ← Gravedad hacia la izquierda
    RIGHT    // → Gravedad hacia la derecha
};
```

#### Lógica de Física por Dirección
- **DOWN**: Pelotas caen hacia abajo, fricción en suelo inferior
- **UP**: Pelotas "caen" hacia arriba, fricción en techo
- **LEFT**: Pelotas "caen" hacia izquierda, fricción en pared izquierda
- **RIGHT**: Pelotas "caen" hacia derecha, fricción en pared derecha

#### Cambios en Ball Class
- `on_floor_` → `on_surface_` (más genérico)
- `gravity_direction_` (nuevo miembro)
- `setGravityDirection()` (nueva función)
- `update()` completamente reescrito para lógica direccional

## Lecciones Aprendidas de ViBe2 Modules

### ✅ Éxitos de Modularización
- **C++20 modules** son viables para código propio
- **CMake + Ninja** funciona bien para modules
- **Separación clara** de responsabilidades mejora arquitectura

### ❌ Limitaciones Encontradas
- **SDL3 + modules** generan conflictos irresolubles
- **Bibliotecas externas** requieren includes tradicionales
- **Enfoque híbrido** (modules propios + includes externos) es más práctico

### 🎯 Decisión para ViBe3 Physics
- **Headers tradicionales** (.h/.cpp) por compatibilidad
- **Enfoque en características** antes que arquitectura
- **Organización por clases** en lugar de modules inicialmente

## Sistema de Coeficientes de Rebote Variables

### 🔧 Implementación Técnica

#### Problema Anterior
```cpp
// Sistema ANTIGUO - Poca variabilidad
loss_ = ((rand() % 30) * 0.01f) + 0.6f;  // 0.60 - 0.89 (diferencia: 0.29)
```

**Resultado**: Pelotas con comportamientos muy similares → Sincronización visible

#### Solución Implementada
```cpp
// Sistema NUEVO - Alta variabilidad
loss_ = ((rand() % 66) * 0.01f) + 0.30f;  // 0.30 - 0.95 (diferencia: 0.65)
```

### 🎯 Tipos de Comportamiento

#### Categorías de Materiales
- **🏀 Super Rebotona** (0.85-0.95): Casi no pierde energía, rebota muchas veces
- **⚽ Normal** (0.65-0.85): Comportamiento estándar equilibrado
- **🎾 Amortiguada** (0.45-0.65): Pierde energía moderada, se estabiliza
- **🏐 Muy Amortiguada** (0.30-0.45): Se para rápidamente, pocas rebotes

### ✅ Beneficios Conseguidos
- **+120% variabilidad** en coeficientes de rebote
- **Eliminación de sincronización** entre pelotas
- **Comportamientos diversos** visibles inmediatamente
- **Física más realista** con materiales diferentes
- **Debug display** para monitoreo en tiempo real

## 🚀 Próximos Pasos - Físicas Avanzadas

### Ideas Pendientes de Implementación

#### 1. **Colisiones Entre Partículas**
- Detección de colisión ball-to-ball
- Física de rebotes entre pelotas
- Conservación de momentum

#### 2. **Materiales y Propiedades**
- Diferentes coeficientes de rebote por pelota
- Fricción variable por material
- Densidad y masa como propiedades

#### 3. **Fuerzas Externas**
- **Viento** - Fuerza horizontal constante
- **Campos magnéticos** - Atracción/repulsión a puntos
- **Turbulencia** - Fuerzas aleatorias localizadas

#### 4. **Interactividad Avanzada**
- Click para aplicar fuerzas puntuales
- Arrastrar para crear campos de fuerza
- Herramientas de "pincel" de física

#### 5. **Visualización Avanzada**
- **Trails** - Estelas de movimiento
- **Heatmaps** - Visualización de velocidad/energía
- **Vectores de fuerza** - Visualizar gravedad y fuerzas

#### 6. **Optimizaciones**
- Spatial partitioning para colisiones
- Level-of-detail para muchas partículas
- GPU compute shaders para física masiva

### 🎮 Controles Futuros Sugeridos
```
Mouse Click:     Aplicar fuerza puntual
Mouse Drag:      Crear campo de fuerza
Mouse Wheel:     Ajustar intensidad
R:               Reset todas las pelotas
P:               Pausa/Resume física
M:               Modo materiales
W:               Toggle viento
```

## 🌐 Implementación Técnica: Modo RotoBall

### Algoritmo Fibonacci Sphere

Distribución uniforme de puntos en una esfera usando la secuencia de Fibonacci:

```cpp
const float golden_ratio = (1.0f + sqrtf(5.0f)) / 2.0f;
const float angle_increment = PI * 2.0f * golden_ratio;

for (int i = 0; i < num_points; i++) {
    float t = static_cast<float>(i) / static_cast<float>(num_points);
    float phi = acosf(1.0f - 2.0f * t);      // Latitud: 0 a π
    float theta = angle_increment * i;        // Longitud: 0 a 2π * golden_ratio

    // Coordenadas esféricas → cartesianas
    float x = cosf(theta) * sinf(phi) * radius;
    float y = sinf(theta) * sinf(phi) * radius;
    float z = cosf(phi) * radius;
}
```

**Ventajas:**
- Distribución uniforme sin clustering en polos
- O(1) cálculo por punto (no requiere iteraciones)
- Visualmente perfecto para demoscene effects

### Rotación 3D (Matrices de Rotación)

```cpp
// Rotación en eje Y (horizontal)
float cos_y = cosf(angle_y);
float sin_y = sinf(angle_y);
float x_rot = x * cos_y - z * sin_y;
float z_rot = x * sin_y + z * cos_y;

// Rotación en eje X (vertical)
float cos_x = cosf(angle_x);
float sin_x = sinf(angle_x);
float y_rot = y * cos_x - z_rot * sin_x;
float z_final = y * sin_x + z_rot * cos_x;
```

**Velocidades:**
- Eje Y: 1.5 rad/s (rotación principal horizontal)
- Eje X: 0.8 rad/s (rotación secundaria vertical)
- Ratio Y/X ≈ 2:1 para efecto visual dinámico

### Proyección 3D → 2D

**Proyección Ortográfica:**
```cpp
float screen_x = center_x + x_rotated;
float screen_y = center_y + y_rotated;
```

**Profundidad Z (Color Modulation):**
```cpp
// Normalizar Z de [-radius, +radius] a [0, 1]
float z_normalized = (z_final + radius) / (2.0f * radius);

// Mapear a rango de brillo [MIN_BRIGHTNESS, MAX_BRIGHTNESS]
float brightness_factor = (MIN + z_normalized * (MAX - MIN)) / 255.0f;

// Aplicar a color RGB
int r_mod = color.r * brightness_factor;
int g_mod = color.g * brightness_factor;
int b_mod = color.b * brightness_factor;
```

**Efecto visual:**
- Z cerca (+radius): Brillo máximo (255) → Color original
- Z lejos (-radius): Brillo mínimo (50) → Color oscuro
- Simula profundidad sin sprites adicionales

### Transición Suave (Interpolación)

```cpp
// Progress de 0.0 a 1.0 en ROTOBALL_TRANSITION_TIME (1.5s)
transition_progress += delta_time / ROTOBALL_TRANSITION_TIME;

// Lerp desde posición actual a posición de esfera
float lerp_x = current_x + (target_sphere_x - current_x) * progress;
float lerp_y = current_y + (target_sphere_y - current_y) * progress;
```

**Características:**
- Independiente del framerate (usa delta_time)
- Suave y orgánico
- Sin pop visual

### Performance

- **Batch rendering**: Una sola llamada `SDL_RenderGeometry` para todos los puntos
- **Recalculación**: Fibonacci sphere recalculada cada frame (O(n) predecible)
- **Sin malloc**: Usa datos ya almacenados en Ball objects
- **Color mod**: CPU-side, sin overhead GPU adicional

**Rendimiento medido:**
- 100 pelotas: >300 FPS
- 1,000 pelotas: >200 FPS
- 10,000 pelotas: >100 FPS
- 100,000 pelotas: >60 FPS (mismo que modo física)

---

## 🔬 Sistema de Física con Atracción (Spring Force)

### Mejora Implementada: Transición Física Realista

**Problema anterior:** Interpolación lineal artificial (lerp) sin física real
**Solución:** Sistema de resorte (Hooke's Law) con conservación de momento

### Ecuaciones Implementadas

#### Fuerza de Resorte (Ley de Hooke)
```cpp
F_spring = k * (target - position)
```
- `k = 300.0`: Constante de rigidez del resorte (N/m)
- Mayor k = atracción más fuerte

#### Fuerza de Amortiguación (Damping)
```cpp
F_damping = c * velocity
F_total = F_spring - F_damping
```
- `c_base = 15.0`: Amortiguación lejos del punto
- `c_near = 50.0`: Amortiguación cerca (estabilización)
- Evita oscilaciones infinitas

#### Aplicación de Fuerzas
```cpp
acceleration = F_total / mass  // Asumiendo mass = 1
velocity += acceleration * deltaTime
position += velocity * deltaTime
```

### Comportamiento Físico

**Al activar RotoBall (tecla C):**
1. Esfera comienza a rotar inmediatamente
2. Cada pelota mantiene su velocidad actual (`vx`, `vy`)
3. Se aplica fuerza de atracción hacia punto móvil en esfera
4. Las pelotas se aceleran hacia sus destinos
5. Amortiguación las estabiliza al llegar

**Durante RotoBall:**
- Punto destino rota constantemente (actualización cada frame)
- Fuerza se recalcula hacia posición rotada
- Pelotas "persiguen" su punto mientras este se mueve
- Efecto: Convergencia con ligera oscilación orbital

**Al desactivar RotoBall (tecla C):**
1. Atracción se desactiva (`enableRotoBallAttraction(false)`)
2. Pelotas conservan velocidad tangencial actual
3. Gravedad vuelve a aplicarse
4. Transición suave a física normal

### Constantes Físicas Ajustables

```cpp
// En defines.h (VALORES ACTUALES - Amortiguamiento crítico)
ROTOBALL_SPRING_K = 300.0f;        // Rigidez resorte
ROTOBALL_DAMPING_BASE = 35.0f;     // Amortiguación lejos (crítico ≈ 2*√k*m)
ROTOBALL_DAMPING_NEAR = 80.0f;     // Amortiguación cerca (absorción rápida)
ROTOBALL_NEAR_THRESHOLD = 5.0f;    // Distancia "cerca" (px)
ROTOBALL_MAX_FORCE = 1000.0f;      // Límite fuerza (seguridad)
```

**Changelog de Ajustes:**
- **v1:** `DAMPING_BASE=15.0, NEAR=50.0` → Oscilación visible (subdamped)
- **v2:** `DAMPING_BASE=35.0, NEAR=80.0` → **Absorción rápida sin oscilación** ✅

### Ajustes Recomendados

**Si siguen oscilando (poco probable):**
```cpp
ROTOBALL_DAMPING_BASE = 50.0f;   // Amortiguamiento super crítico
ROTOBALL_DAMPING_NEAR = 100.0f;  // Absorción instantánea
```

**Si llegan muy lento:**
```cpp
ROTOBALL_SPRING_K = 400.0f;      // Más fuerza
ROTOBALL_DAMPING_BASE = 40.0f;   // Compensar con más damping
```

**Si quieres más "rebote" visual:**
```cpp
ROTOBALL_DAMPING_BASE = 25.0f;   // Menos amortiguación
ROTOBALL_DAMPING_NEAR = 60.0f;   // Ligera oscilación
```

### Ventajas del Sistema

✅ **Física realista**: Conservación de momento angular
✅ **Transición orgánica**: Aceleración natural, no artificial
✅ **Inercia preservada**: Al salir conservan velocidad
✅ **Estabilización automática**: Damping evita oscilaciones infinitas
✅ **Performance**: O(1) por pelota, muy eficiente

---

## 🎨 Z-Sorting (Painter's Algorithm)

### Problema de Renderizado 3D

**Antes del Z-sorting:**
- Pelotas renderizadas en orden fijo del vector: `Ball[0] → Ball[1] → ... → Ball[N]`
- Orden aleatorio respecto a profundidad Z
- **Problema:** Pelotas oscuras (fondo) pintadas sobre claras (frente)
- Resultado: Inversión de profundidad visual incorrecta

**Después del Z-sorting:**
- Pelotas ordenadas por `depth_brightness` antes de renderizar
- Painter's Algorithm: **Fondo primero, frente último**
- Pelotas oscuras (Z bajo) renderizadas primero
- Pelotas claras (Z alto) renderizadas último (encima)
- **Resultado:** Oclusión 3D correcta ✅

### Implementación (engine.cpp::render())

```cpp
if (current_mode_ == SimulationMode::ROTOBALL) {
    // 1. Crear vector de índices
    std::vector<size_t> render_order;
    for (size_t i = 0; i < balls_.size(); i++) {
        render_order.push_back(i);
    }

    // 2. Ordenar por depth_brightness (menor primero = fondo primero)
    std::sort(render_order.begin(), render_order.end(),
        [this](size_t a, size_t b) {
            return balls_[a]->getDepthBrightness() < balls_[b]->getDepthBrightness();
        });

    // 3. Renderizar en orden de profundidad
    for (size_t idx : render_order) {
        // Renderizar balls_[idx]...
    }
}
```

### Complejidad y Performance

| Operación | Complejidad | Tiempo (estimado) |
|-----------|-------------|-------------------|
| Crear índices | O(n) | ~0.001ms (1K pelotas) |
| std::sort | O(n log n) | ~0.01ms (1K pelotas) |
| Renderizar | O(n) | ~variable |
| **Total** | **O(n log n)** | **~0.15ms (10K pelotas)** |

**Impacto en FPS:**
- 100 pelotas: Imperceptible (<0.001ms)
- 1,000 pelotas: Imperceptible (~0.01ms)
- 10,000 pelotas: Leve (~0.15ms, ~1-2 FPS)
- 100,000 pelotas: Moderado (~2ms, ~10-15 FPS)

### Optimizaciones Aplicadas

✅ **Solo en modo RotoBall**: Modo física no tiene overhead
✅ **Vector de índices**: `balls_` no se modifica (física estable)
✅ **Reserve() usado**: Evita realocaciones
✅ **Lambda eficiente**: Acceso directo sin copias

### Resultado Visual

✅ **Profundidad correcta**: Fondo detrás, frente delante
✅ **Oclusión apropiada**: Pelotas claras cubren oscuras
✅ **Efecto 3D realista**: Percepción de profundidad correcta
✅ **Sin artefactos visuales**: Ordenamiento estable cada frame

## Métricas del Proyecto

### ✅ Logros Actuales
- **Compilación exitosa** con CMake
- **Commit inicial** creado (dec8d43)
- **17 archivos** versionados
- **9,767 líneas** de código
- **Física direccional** 100% funcional
- **Coeficientes variables** implementados

### 🎯 Objetivos Cumplidos
- ✅ Migración limpia desde vibe1_delta
- ✅ Sistema de gravedad direccional implementado
- ✅ Coeficientes de rebote variables (+120% diversidad)
- ✅ **Modo RotoBall (esfera 3D rotante) implementado**
- ✅ **Fibonacci sphere algorithm funcionando**
- ✅ **Profundidad Z con color modulation**
- ✅ Debug display completo y funcional
- ✅ Controles intuitivos con teclas de cursor
- ✅ Eliminación de sincronización entre pelotas

---

## Comandos Útiles

### Compilación
```bash
mkdir -p build && cd build && cmake .. && cmake --build .
```

### Ejecución
```bash
./vibe3_physics.exe    # Windows
./vibe3_physics        # Linux/macOS
```

### Git
```bash
git status             # Ver cambios
git add .              # Añadir archivos
git commit -m "..."    # Crear commit
```

---

*Archivo de seguimiento para sesiones Claude Code - ViBe3 Physics*
*Actualizado: Implementación de gravedad direccional completada*