Transformaciones

Las transformaciones te permiten cambiar el lugar donde las cosas son dibujadas en el mundo. Por ejemplo, la función para dibujar bloques sólo puede dibujar bloques paralelos de eje. Por primera opción una transformación de rotación puedes crear bloques girados. También los sprites siempre son dibujados paralelos al plano-xy. Estableciendo una transformación puedes cambiar esto. Hay dos tipos de funciones: las funciones que ponen la transformación y las funciones que añaden transformaciones.

d3d_transform_set_identity () Pone la transformación a la identidad (ninguna transformación).

d3d_transform_set_translation(xt,yt,zt) Pone la transformación a una conversión sobre el vector indicado.

d3d_transform_set_scaling(xs,ys,zs) Pone la transformación a un escalamiento con las cantidades indicadas.

d3d_transform_set_rotation_x(ángulo) Pone la transformación a una rotación alrededor del eje-x con la cantidad indicada.

d3d_transform_set_rotation_y(ángulo) Pone la transformación a una rotación alrededor del eje-y con la cantidad indicada.

d3d_transform_set_rotation_z(ángulo) Pone la transformación a una rotación alrededor del eje-z con la cantidad indicada.

d3d_transform_set_rotation_axis(xa,ya,za,ángulo) Pone la transformación a una rotación alrededor del eje indicado por el vector con la cantidad indicada.

d3d_transform_add_translation(xt,yt,zt) Añade una transformación sobre vector indicado.

d3d_transform_add_scaling(xs,ys,zs) Añade un escalamiento con las cantidades indicadas.

d3d_transform_add_rotation_x(ángulo) Añade una rotación alrededor del eje-x con la cantidad indicada.

d3d_transform_add_rotation_y(ángulo) Añade una rotación alrededor del eje-y con la cantidad indicada.

d3d_transform_add_rotation_z(ángulo) Añade una rotación alrededor del eje-z con la cantidad indicada.

d3d_transform_add_rotation_axis(xa,ya,za,ángulo) Añade una rotación alrededor del eje indicado por el vector con la cantidad indicada.

Comprende que la rotación y el escalamiento son con respecto al origen del mundo, no al respecto al objeto que debe ser dibujado. Si el objeto no está en el origen este también se moverá a un lugar diferente, que no es lo que queremos. Así para p.ej. hacer girar un objeto sobre su propio eje-x, primero debemos trasladar al origen, después hacerlo girar, y finalmente trasladarlo de regreso a su posición. Esto es para qué son las funciones de añadir transformaciones.

Los ejemplos siguientes podrían explicar esto mejor. Asumiendo que tenemos un sprite spr que queremos dibujar en la posición (100,100,10). Podemos usar el código siguiente para hacer esto

 

{
  d3d_transform_set_translation(100,100,10);
  draw_sprite(spr,0,0,0);
  d3d_transform_set_identity();
}

 

Nota que porque usamos una transformación ahora deberíamos dibujar el sprite en la posición (0,0). (¡Esto asume que la instancia actual tiene una profundidad de 0! Si no estas seguro, primero pon la profundidad.) Si usáramos esto en nuestro tirador en primera persona no veríamos el sprite. La razón es que es todavía paralelo al plano-xy. Queremos hacerlo girar más de 90 grados a lo largo del eje-x (o el eje-y). Entonces tenemos que añadir una rotación. Recuerda el orden: primero debemos hacer girar el sprite y luego transformarlo. Entonces podemos usar el código siguiente.

 

{
  d3d_transform_set_identity();
  d3d_transform_add_rotation_x(90);
  d3d_transform_add_translation(100,100,10);
  draw_sprite(spr,0,0,0);
  d3d_transform_set_identity();
}

 

En ocasiones quieres guardar temporalmente la transformación actual, por ejemplo para añadir una transformación adicional y luego restaurar a la anterior (esto a menudo pasa dibujando modelos jerárquicos). Para este fin puedes empujar la transformación actual sobre un montón y luego sacarlo del montón para hacerlo la transformación actual de nuevo. Las funciones siguientes existen para esto:

 

d3d_transform_stack_clear() Limpia el montón de transformaciones.

d3d_transform_stack_empty() Devuelve si el montón de transformación está vacío.

d3d_transform_stack_push() Empuja la transformación actual sobre el montón. Devuelve si hay espacio sobre el montón para empujarlo allí (si olvidas sacar la transformación en algún momento te quedarás sin espacio en el montón).

d3d_transform_stack_pop() Saca la transformación superior del montón y la hace la actual. Devuelve si había una transformación sobre el montón.

d3d_transform_stack_top() Hace a la transformación superior la actual, pero no lo quita del montón. Devuelve si había tras una transformación sobre el montón.

d3d_transform_stack_discard() Quita la transformación superior del montón, pero no lo hace la actual. Vueltas si había tras una transformación en el montón.

 

La utilización de la transformación es un mecanismo poderoso. Pero sé cuidadoso y siempre restaura la transformación a la identidad una vez que terminaste.