2016-02-08 23:45:57 +01:00
|
|
|
.. _doc_viewport_and_canvas_transforms:
|
2016-02-08 22:07:55 +01:00
|
|
|
|
2016-02-06 01:54:33 +01:00
|
|
|
Viewport & Canvas Transforms
|
|
|
|
============================
|
|
|
|
|
|
|
|
Introduction
|
|
|
|
------------
|
|
|
|
|
|
|
|
This tutorial is created after a topic that is a little dark for most
|
|
|
|
users, and explains all the 2D transforms going on for nodes from the
|
|
|
|
moment they draw their content locally to the time they are drawn into
|
|
|
|
the screen.
|
|
|
|
|
|
|
|
Canvas Transform
|
|
|
|
----------------
|
|
|
|
|
2016-02-08 23:45:57 +01:00
|
|
|
As mentioned in the previous tutorial :ref:`doc_canvas_layers`, every
|
2016-02-06 01:54:33 +01:00
|
|
|
CanvasItem node (remember that Node2D and Control based nodes use
|
|
|
|
CanvasItem as their common root) will reside in a *Canvas Layer*. Every
|
|
|
|
canvas layer has a transform (translation, rotation, scale, etc) that
|
|
|
|
can be accessed as a
|
|
|
|
`Matrix32 <https://github.com/okamstudio/godot/wiki/class_matrix32>`__.
|
|
|
|
|
|
|
|
By default, nodes are drawn in Layer 0, in the built-in canvas. To put
|
|
|
|
nodes in a different layer, a
|
|
|
|
`CanvasLayer <https://github.com/okamstudio/godot/wiki/class_canvaslayer>`__
|
|
|
|
node can be used. This was covered in the previous tutorial anyway, just
|
|
|
|
refreshing.
|
|
|
|
|
|
|
|
Global Canvas Transform
|
|
|
|
-----------------------
|
|
|
|
|
|
|
|
Viewports also have a Global Canvas transform (also a
|
|
|
|
`Matrix32 <https://github.com/okamstudio/godot/wiki/class_matrix32>`__
|
|
|
|
). This is the master transform and affects all individual *Canvas
|
|
|
|
Layer* transforms. Generally this transform is not of much use, but is
|
|
|
|
used in the CanvasItem Editor in Godot's editor.
|
|
|
|
|
|
|
|
Stretch Transform
|
|
|
|
-----------------
|
|
|
|
|
|
|
|
Finally, viewports have a *Stretch Transform*, which is used when
|
|
|
|
resizing or stretching the screen. This transform is used internally by
|
2016-02-08 23:45:57 +01:00
|
|
|
the :ref:`doc_multiple_resolutions`, but can also be requested to the viewport.
|
2016-02-06 01:54:33 +01:00
|
|
|
|
|
|
|
Input events received in the
|
|
|
|
`Node.\_input\_event(ev) <https://github.com/okamstudio/godot/wiki/class_node#_input_event>`__
|
|
|
|
callback are multiplied by this transform, but lack the ones above. To
|
|
|
|
convert InputEvent coordinates to local CanvasItem coordinates, the
|
|
|
|
`CanvasItem.make\_input\_local(ev) <https://github.com/okamstudio/godot/wiki/class_canvasitem#make_input_local>`__
|
|
|
|
function was added for convenience.
|
|
|
|
|
|
|
|
Transform Order
|
|
|
|
---------------
|
|
|
|
|
|
|
|
For a coordinate in CanvasItem local properties to become an actual
|
|
|
|
screen coordinate, the following chain of transforms must be applied:
|
|
|
|
|
|
|
|
.. image:: /img/viewport_transforms2.png
|
|
|
|
|
|
|
|
Transform Functions
|
|
|
|
-------------------
|
|
|
|
|
|
|
|
Obtaining each transform can be achieved with the following functions:
|
|
|
|
|
|
|
|
| \|Type: \| Transform\|
|
|
|
|
| \|CanvasItem \|
|
|
|
|
`CanvasItem.get\_global\_transform() <https://github.com/okamstudio/godot/wiki/class_canvasitem#get_global_transform>`__
|
|
|
|
\|
|
|
|
|
| \|CanvasLayer\|
|
|
|
|
`CanvasItem.get\_canvas\_transform() <https://github.com/okamstudio/godot/wiki/class_canvasitem#get_canvas_transform>`__
|
|
|
|
\|
|
|
|
|
| \|CanvasLayer+GlobalCanvas+Stretch \|
|
|
|
|
`CanvasItem.get\_viewport\_transform() <https://github.com/okamstudio/godot/wiki/class_canvasitem#get_viewport_transform>`__
|
|
|
|
\|
|
|
|
|
|
|
|
|
Finally then, to convert a CanvasItem local coordinates to screen
|
|
|
|
coordinates, just multiply in the following order:
|
|
|
|
|
|
|
|
::
|
|
|
|
|
|
|
|
var screen_coord = get_viewport_transform() + ( get_global_transform() + local_pos )
|
|
|
|
|
|
|
|
Keep in mind, however, that it is generally not desired to work with
|
|
|
|
screen coordinates. The recommended approach is to simply work in Canvas
|
|
|
|
coordinates (CanvasItem.get\_global\_transform()), to allow automatic
|
|
|
|
screen resolution resizing to work properly.
|
|
|
|
|
|
|
|
Feeding Custom Input Events
|
|
|
|
---------------------------
|
|
|
|
|
|
|
|
It is often desired to feed custom input events to the scene tree. With
|
|
|
|
the above knowledge, to correctly do this, it must be done the following
|
|
|
|
way:
|
|
|
|
|
|
|
|
::
|
|
|
|
|
|
|
|
var local_pos = Vector2(10,20) # local to Control/Node2D
|
|
|
|
var ie = InputEvent()
|
|
|
|
ie.type=InputEvent.MOUSE_BUTTON
|
|
|
|
ie.button_index=1 #left click
|
|
|
|
ie.pos = get_viewport_transform() + ( get_global_transform() + local_pos )
|
|
|
|
get_tree().input_event(ie)
|
|
|
|
|
|
|
|
|
|
|
|
|