# atanor
Motor 3D ray-traced que vive **solo y exclusivamente en la terminal**. Sin GPU,
sin ventana gráfica, sin un solo píxel fuera del emulador. Cada celda son dos
medios-bloques Unicode (`▀` con `fg`/`bg` distintos), y cada uno de esos
sub-píxeles sale de un rayo trazado contra la escena.
```
terminal cell ┌── pixel superior (fg)
┌─────┐ │
│ ▀ │ = ▄ + ▀ ────┤
└─────┘ │
└── pixel inferior (bg)
```
## Quickstart
Necesitas Rust estable (≥ 1.75 deberían bastar).
```
cargo run --release
```
La primera build tarda — descarga `glam`, `crossterm`, `ratatui` y `rayon`.
Lánzalo en un terminal con soporte truecolor (kitty, alacritty, wezterm,
ghostty, foot, iTerm2…). La resolución efectiva la decide el tamaño de la
ventana.
## Controles
| `W` / `S` | Avanzar / retroceder |
| `A` / `D` | Strafe izquierda / derecha |
| `Q` / `E` | Bajar / subir |
| flechas | Mirar (yaw + pitch) |
| `Shift` + ↑ | Sprint — 3.5× velocidad de movimiento y de look |
| `[` / `]` | Bajar / subir samples/pixel (SSAA) |
| `Espacio` | Pausa de la animación |
| `Esc` | Salir |
El HUD esquina sup-izq muestra FPS, rayos/frame, rebotes, posición de cámara.
## Stack
- **glam** — matemática 3D (`Vec3`, `Mat4`, quaternions). `fast-math` activado.
- **crossterm** — control crudo del terminal (raw mode, alt screen, eventos).
- **ratatui** — orquesta el frame y compone el HUD encima del viewport 3D.
- **rayon** — traza scanlines en paralelo (sin él el framerate se hunde en
terminales medianos).
## Arquitectura
```
src/
├── main.rs entry point
├── engine.rs loop, input, lifecycle del terminal
├── hud.rs overlay ratatui (stats + ayuda)
├── math.rs Ray, Hit, helpers sobre glam
└── render/
├── mod.rs
├── framebuffer.rs buffer RGB + Widget half-blocks ▀
├── camera.rs pinhole (yaw/pitch/fov), generación de rayos
├── scene.rs Sphere, Plane, Material, Light, Scene::demo()
└── tracer.rs ray tracer paralelo + Blinn-Phong + sombras + 1 rebote
```
El viewport 3D es un `Widget` custom de ratatui. Esto permite que crossterm
gestione el render bruto y ratatui orqueste, sin pelearse por el control de
pantalla.
## Demo
La escena por defecto monta:
- Plano suelo con material ajedrez procedural.
- 4 esferas (lambertian roja, espejo azul, mate amarilla, espejo casi puro).
- 2 luces puntuales (cálida + fría).
- Cielo gradiente vertical.
- 2 esferas orbitan automáticamente para que el movimiento sea visible sin
tocar nada.
## Roadmap corto
- [x] SSAA con muestras Halton(2,3), 1–16 spp ajustable en runtime.
- [ ] BVH cuando metamos mallas (las primitivas analíticas no lo necesitan).
- [ ] Carga `.obj` y rasterización de triángulos.
- [ ] Mouse-look real (crossterm `EnableMouseCapture`).
- [ ] Materiales PBR (Cook-Torrance) y rugosidad.
- [ ] Soft shadows (jitter del rayo de sombra).
## Verificación de firmas
Los commits van firmados con:
```
Pasqual Peñalver (Cypherpunks write code) <public@paski.dev>
EB82 8779 8FCD 2A89 4BFF DE35 017B F383 AB6B B586
```
Importa la clave pública desde un keyserver:
```
gpg --keyserver hkps://keys.openpgp.org --recv-keys EB8287798FCD2A894BFFDE35017BF383AB6BB586
```
Y verifica con tu herramienta favorita.
## Licencia
[MIT](LICENSE).