Hasta ahora creamos transformaciones (translate, rotateX/Y/Z, scale) que se aplican a todos los objetos que se crean después de ella. 
  Pero para éste caso requerimos que los objetos se muevan de forma independiente, si movemos el punto de origen 300 unidades en X, Y o Z o rotamos el objeto, queremos que todo vuelva a cero luego de creado el/los objeto/s nuevos.

    Antes que nada, descargamos el proyecto y lo descomprimimos: 

Transformaciones

   Para empezar, les recuerdo a los alumnos las transformaciones que hemos estado usando en WebGL, y que al poner una de ellas, afecta a todos los objetos que estan a continuacion:


   En clases anteriores hemos concatenado rotaciones y objetos obteniendo efectos de "tentaculos"(Como vimos en una clase anterior), pero tenemos la posibilidad de aislar las transformaciones de distintos objetos con push() y pop().
  Por ejemplo, si ponemos un rotateX (1) y un scale(2)  podemos esperar que todo lo que pongamos debajo tenga ese tamaño y rotación, pero dentro de una estructura push/pop las transformaciones vuelven a cero.


En los ejemplos de arriba tenemos el mismo código, con las mismas transformaciones antes de cada torus().
   En el primer ejemplo (imagen de arriba), el translate lleva el cero a -300 (hacia la izquierda de la pantalla) donde pone el primer toro, y el rotate(1) gira un radian hacia la derecha de la pantalla lo que lo orienta a este y a todos los todos en esa dirección.

  Luego el scale(2) pide que todos los objetos tengan EL DOBLE DEL TAMAÑO, translada 200 unidades y crea un toro, luego un scale(1/5) hace que el tercer toro tenga 1/5 del tamaño que ya era del doble. Como vemos las transformaciones afectan a todos los objetos 

  En el segundo ejemplo, cada transformación(rotateX/Y/Z, scale o translate) y toro es AISLADO por push() y un pop() por lo tanto el primer toro está efectivamente a la izquierda, pero al llegar el primer pop() hace que el punto de origen (el cero) vuelva al centro de la pantalla, los translates solo traen los objetos mas cerca de la cámara. Como estan aislados entre sí el tercer scale actúa sin importarle el scale(2) del segundo toro.

Mover el objeto con el Mouse


  Para el ejemplo, usamos un translate(mouseX, mouseY , 400), que hará que el objeto 3D siga el mouse en X e Y, y traiga el objeto 400 unidades mas cerca de la camara. El problema es que mouseX y mouseY comienzan a contar desde la margen superior izquierda, pero los objetos webGL aparecen en el punto de origen inicial 0,0,0 o sea el centro de la ventana, por lo tanto la diferencia entre mouseX y la posición horizontal de la nave es la mitad del tamaño del canvas (windowWidth/2) , y la diferencia entre mouseY y la nave en el sentido vertical es la mitad del tamaño vetical del canvas (windowHeight/2).





   Luego restamos esos valores para que la posición de X e Y del translate coincidan con la posición de mouseX y mouseY.






   Ahora agregaremos un translate(0,0, -1000) que moverá el punto de origen para el próximo objeto lejos de la cámara, unas 1000 unidades y pondremos un toro como se ve en la imagen.
  Pero como vemos, el movimiento de ambos objetos está ligado al primer translate, si se mueve la nave todo el resto de los objetos nuevos también lo hará.



















Aislando Ambos Objetos


  En el siguiente ejemplo, separamos el modelo de la nave y sus transformaciones (lineas 21 a 24) por las del toro (lineas 28 y 29), usando 2 estructuras push() y pop(), lo que permitira que tengan movimientos independientes.



    El movimiento del toro, está controlado por la variable a declarada en la línea 4 con el valor -1500, lo que pone al toro lejos de la cámara (recordemos que la nave está 400 unidades más cerca de la cámara por el tercer valor de la línea 20), pero en la línea 30 usamos un incrementador para que venga avanzando hacia nosotros cada vez (de 30 en 30, aunque cambiamos el valor). 

    Tal y como vimos en la clase de incrementadores, cuando el objeto llega a cierto valor podemos volver a ponerlo en el valor inicial. en nuestro caso, en la línea 31 indicamos que si el valor de a es mayor a 900 que vuelva a ser -1500, en otras palabras, si el objeto pasó detrás de nosotros que vuelva a aparecer allá a lo lejos (es el mismo código que usamos con las chicas superpoderosas en 2D).  



var objeto;
var imagen1;
var imagen2;
var a= -1500; 
var x=0;
var y=0;
function setup(){
  createCanvas(windowWidth,windowHeight,WEBGL);
  objeto = loadModel("xwing.obj");
  imagen1 = loadImage("xwing.png");
  imagen2 = loadImage("espacio.jpg");
}
 function draw(){
 background(0);
     push() 
  translate(mouseX-windowWidth/2 , mouseY-windowHeight/2 , 400)
    scale( 1/2 )
    rotateZ(PI/2 *2)
  texture(imagen1)
  model(objeto)
     pop()
     push() 
   translate(0,0, a)
     texture(imagen1)

   torus(100) 
         a=a+30
   if (a>900) { a= -1500 }
     pop() 
}