Transformación de Viewport y Canvas

Introducción

Esto es un resumen de lo que sucede con las matrices de transformación 2D en los nodos desde el momento en que dibujan su contenido localmente hasta el momento en que se muestran en pantalla. Aquí se mostrarán detalles de muy bajo nivel de el motor.

Transformación del canvas

Como se mencionó en el tutorial anterior, Canvas layers, cada nodo CanvasItem (recuerda que los nodos basados en Node2D y Control usan CanvasItem como su raíz común) residirá en una Canvas Layer. Cada canvas layer tiene una transformación (translation, rotation, scale, etc.) a la que se puede acceder mediante Transform2D.

Esto también está cubierto por el tutorial anterior, los nodos son dibujados por defecto en Layer (capa) 0, en el «built-in canvas» (el canvas por defecto del viewport). Para colocar nodos en una capa distinta, se debe utilizar una CanvasLayer.

Transformación global del canvas

Los Viewports también tienen una transformación Global Canvas (también un Transform2D). Esta es la transformación principal y afecta a todas las transformaciones individuales de Canvas Layer. Generalmente esta transformación no es de mucha utilidad, pero se usa en el Editor de CanvasItem del editor de Godot.

Stretch transform

Por último, los Viewports tienen un Stretch Transform, que se utiliza al cambiar de tamaño o estirar la pantalla. Esta transformación se utiliza internamente (como se describe en Multiple resolutions) pero también se puede configurar manualmente en cada Viewport.

Eventos de entrada (Input events) recibidos en el callback de MainLoop._input_event() son multiplicados por este transform, pero carecen de los presentados anteriormente. Para convertir fácilmente coordenadas de InputEvent a coordenadas locales de CanvasItem, se agregó la función CanvasItem.make_input_local().

Orden de Transform

Para que un sistema de coordenadas locales en CanvasItem se convierta en coordenadas de pantalla, se debe aplicar la siguiente secuencia de transforms:

../../_images/viewport_transforms2.png

Funciones de Transform

Cada transform se puede obtener con las siguientes funciones:

Tipo Transformar
CanvasItem CanvasItem.get_global_transform()
CanvasLayer CanvasItem.get_canvas_transform()
CanvasLayer+GlobalCanvas+Stretch CanvasItem.get_viewport_transform()

Finalmente, para convertir un CanvasItem de coordenadas locales a coordenadas de pantalla, utilizar el siguiente orden:

var screen_coord = get_viewport_transform() * (get_global_transform() * local_pos)
var screenCord = (GetViewportTransform() * GetGlobalTransform()).Xform(localPos);

Tener en cuenta que esto no es aconsejable para trabajar en coordenadas de pantalla. Lo recomendable es simplemente trabajar en coordenadas de Canvas (CanvasItem.get_global_transform()), para permitir que el cambio de tamaño/ajuste de resolución funcione de la manera adecuada.

Generando eventos de entrada personalizados

Usualmente es deseable crear eventos de entradas personalizados para enviar al árbol de escenas. Para hacer esto correctamente, se debe hacer de la siguiente manera:

var local_pos = Vector2(10, 20) # local to Control/Node2D
var ie = InputEventMouseButton.new()
ie.button_index = BUTTON_LEFT
ie.position = get_viewport_transform() * (get_global_transform() * local_pos)
get_tree().input_event(ie)
var localPos = new Vector2(10,20); // local to Control/Node2D
var ie = new InputEventMouseButton();
ie.ButtonIndex = (int)ButtonList.Left;
ie.Position = (GetViewportTransform() * GetGlobalTransform()).Xform(localPos);
GetTree().InputEvent(ie);