---
title: "P3D: Fundamentos y configuración"
---

# Espacio 3D Computacional

## Ejes y coordenadas

Por defecto, en Processing:

* El eje X aumenta hacia la derecha de la pantalla
* El eje Y aumenta hacia abajo de la pantalla
* El eje Z aumenta hacia la persona viendo la pantalla

A diferencia del trabajo en 2D, en el que cada unidad de distancia generalmente correspondía a *un pixel*, en 3D las unidades se vuelven arbitrarias debido a que su tamaño aparente depende completamente de dónde se ubica la *cámara* (ver abajo). 

Y no solo el tamaño, sino también la orientación y localización: Para bien y para mal, todo se vuelve relativo. 

Por eso abajo escribo entre comillas palabras como "arriba" y "origen".

Si lo que estamos modelando tiene equivalente en el mundo fuera de la pantalla, nos tocará determinar la equivalencia entre las unidades del mundo "virtual" y el "real".

## Cámara

Por el momento trabajaremos en un mundo 3D virtual al que podremos acceder solamente a través de una pantalla 2D. Esto requiere *proyectar* el mundo 3D hacia un plano finito.

Nos saltaremos las matemáticas involucradas y automatizadas en el proceso, y nos quedaremos con que normalmente una cámara virtual "ve" lo que está adentro de un volumen con forma de pirámide truncada (*view frustum* en inglés), y lo proyecta sobre un plano que corresponde a la ventana de nuestro *sketch*.

(imagen)

Algunos atributos de una cámara virtual típica:

* Posición en el espacio (un punto en 3D)
* Posición a la que está *viendo*, "*lookAt point*" (otro punto en 3D)
* Dirección de "arriba" (un vector 3D apuntando hacia "arriba")
* Distancia mínima: la distancia a partir de la cual la cámara empieza a ver 
* Distancia máxima: la distancia hasta la cual la cámara alcanza a ver
* Relación de aspecto (*aspect ratio*): Proporción entre el ancho y alto del plano de proyección
* Ángulo de campo de visión (*field of view*): El ángulo máximo que puede formarse entre dos "rayos de luz" virtuales que llegan a la cámara en cuestión.

Es conveniente tener presentes esos conceptos para entender mejor qué se ve (y por qué) dentro de nuestro sketch. 

En Processing es posible manipular la cámara a ese nivel de detalle, pero es una complicación que va más allá del objetivo del curso.

Así que empezaremos utilizando una biblioteca/*library* llamada PEasyCam, que nos permite manipular la cámara 3D de manera intuitiva con un mouse. 

**Recomendación**: *así como en otros programas que trabajan en 3D, es de gran ayuda utilizar un mouse de dos botones y una "scroll wheel"*

## Salidas

Empezaremos trabajando con mundos en 3D que se ven y navegan a través de una pantalla 2D.

Eventulamente podremos exportar como archivos OBJ lo que construyamos - esto nos permitirá añadirlo a otros programas de 3D por ejemplo para hacer un *render* con características específicas, o incluso llevarlo a programas de fabricación digital para de ahí materializarlos con las máquinas de control numérico correspondientes.

También, lo que hagamos puede llegar a tener como salida un visor de VR (presencia en espacios virtuales) y/o aplicaciones de AR.

# Configuración

## Instalación

Para trabajar en 3D en Processing, vamos a instalar la _library_ PeasyCam:

*Sketch -> Importar biblioteca -> Añadir biblioteca*. Ahí busca: *PeasyCam* y presiona en *Instalar*

## Consideraciones

Es importante agregar el *P3D renderer* en la declaración del tamaño del sketch (ya sea dentro de `size()` o `fullscreen()`).

La función `lights()` agrega una configuración básica de iluminación. Más adelante en el curso veremos cómo trabajar más deliberadamente con luces virtuales.

## Sketch plantilla

Este sketch nos puede servir de base para empezar a construir en 3D:

```java
// Importa PeasyCam y declara la cámara
import peasy.PeasyCam;
PeasyCam cam;

void setup() {
  // Determina el tamaño de la ventana
  // y que usaremos el renderer P3D
  size(800, 600, P3D);

  // Crea el objeto de la cámara
  // a 60 unidades de distancia del punto "lookAt"
  // (por defecto, en (0,0,0)
  cam = new PeasyCam(this, 60);
}

void draw() {
  // Dibuja un fondo para limpiar la ventana en cada frame
  background(255);
  // Establece "luces" por defecto para notar mejor el 3D
  lights();
  
  // Empieza a dibujar...
  // Por ejemplo, crea un cubo de lado 5:
  box(5);
}
```

### Ajuste de perspectiva

La siguiente expresión ajusta la cámara para que "vea" cualquier objeto que esté entre 1 y 100 unidades de distancia. Úsala cuando notes que los objetos que dibujes desaparezcan al hacer *zoom*

```java
// ajusta perspectiva: ve en un rango entre 1 a 100 unidades
perspective(PI/3, 1.0*width/height, 1, 100);
```

### Punto *lookAt*

Al crear la cámara podemos especificar el punto al que está viendo la cámara originalmente, además de la distancia a la que se encuentra:

```java
// mira hacia (10,10,0) desde una distancia de 50 unidades
cam = new PeasyCam(this, 10, 10, 0, 50);
```

## Sketch plantilla con ejes

Esta es otra plantilla. Incluye el ajuste de perspectiva, y utiliza una función propia `dibujaEjes( )` para dibujar los ejes coordenados:

```java
import peasy.*;
PeasyCam cam;

void setup() {
  size(800, 600, P3D);

  // cámara a 50 unidades de 0,0,0
  cam = new PeasyCam(this, 50);

  // ajusta perspectiva: ve en un rango entre 1 y 500 unidades
  perspective(PI/3, 1.0*width/height, 1, 500);
} // cierra setup()

void draw() {
  background(255);
  // Establece "luces" por defecto
  lights();
  
  // guía de ejes coordenados con largo de 10
  dibujaEjes(10);

  // dibuja aquí:

  

} // cierra draw()

void dibujaEjes(float d) {
  // esta función dibuja los ejes coordenados X, Y, Z
  // de colores R, G, B respectivamente
  // d: longitud de las líneas
  
  // eje X: rojo
  stroke(255, 0, 0);
  line(0, 0, 0, d, 0, 0);

  // eje Y: verde
  stroke(0, 255, 0);
  line(0, 0, 0, 0, d, 0);

  // eje Z: azul
  stroke(0, 0, 255);
  line(0, 0, 0, 0, 0, d);

  // regresa al color negro de línea
  stroke(0, 0, 0);
} // cierra función dibujaEjes( )
```
