2d_transforms.rst 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. .. _doc_viewport_and_canvas_transforms:
  2. Viewport and canvas transforms
  3. ==============================
  4. Introduction
  5. ------------
  6. This is an overview of the 2D transforms going on for nodes from the
  7. moment they draw their content locally to the time they are drawn onto
  8. the screen. This overview discusses very low level details of the engine.
  9. Canvas transform
  10. ----------------
  11. As mentioned in the previous tutorial, :ref:`doc_canvas_layers`, every
  12. CanvasItem node (remember that Node2D and Control based nodes use
  13. CanvasItem as their common root) will reside in a *Canvas Layer*. Every
  14. canvas layer has a transform (translation, rotation, scale, etc.) that
  15. can be accessed as a :ref:`Transform2D <class_Transform2D>`.
  16. Also covered in the previous tutorial, nodes are drawn by default in Layer 0,
  17. in the built-in canvas. To put nodes in a different layer, a :ref:`CanvasLayer
  18. <class_CanvasLayer>` node can be used.
  19. Global canvas transform
  20. -----------------------
  21. Viewports also have a Global Canvas transform (also a
  22. :ref:`Transform2D <class_Transform2D>`). This is the master transform and
  23. affects all individual *Canvas Layer* transforms. Generally, this
  24. transform is not of much use, but is used in the CanvasItem Editor
  25. in Godot's editor.
  26. Stretch transform
  27. -----------------
  28. Finally, viewports have a *Stretch Transform*, which is used when
  29. resizing or stretching the screen. This transform is used internally (as
  30. described in :ref:`doc_multiple_resolutions`), but can also be manually set
  31. on each viewport.
  32. Input events received in the :ref:`MainLoop._input_event() <class_MainLoop_method__input_event>`
  33. callback are multiplied by this transform but lack the ones above. To
  34. convert InputEvent coordinates to local CanvasItem coordinates, the
  35. :ref:`CanvasItem.make_input_local() <class_CanvasItem_method_make_input_local>`
  36. function was added for convenience.
  37. Transform order
  38. ---------------
  39. For a coordinate in CanvasItem local properties to become an actual
  40. screen coordinate, the following chain of transforms must be applied:
  41. .. image:: img/viewport_transforms2.png
  42. Transform functions
  43. -------------------
  44. Obtaining each transform can be achieved with the following functions:
  45. +----------------------------------+---------------------------------------------------------------------------------------------+
  46. | Type | Transform |
  47. +==================================+=============================================================================================+
  48. | CanvasItem | :ref:`CanvasItem.get_global_transform() <class_CanvasItem_method_get_global_transform>` |
  49. +----------------------------------+---------------------------------------------------------------------------------------------+
  50. | CanvasLayer | :ref:`CanvasItem.get_canvas_transform() <class_CanvasItem_method_get_canvas_transform>` |
  51. +----------------------------------+---------------------------------------------------------------------------------------------+
  52. | CanvasLayer+GlobalCanvas+Stretch | :ref:`CanvasItem.get_viewport_transform() <class_CanvasItem_method_get_viewport_transform>` |
  53. +----------------------------------+---------------------------------------------------------------------------------------------+
  54. Finally, then, to convert a CanvasItem local coordinates to screen
  55. coordinates, just multiply in the following order:
  56. .. tabs::
  57. .. code-tab:: gdscript GDScript
  58. var screen_coord = get_viewport_transform() * (get_global_transform() * local_pos)
  59. .. code-tab:: csharp
  60. var screenCord = (GetViewportTransform() * GetGlobalTransform()).Xform(localPos);
  61. Keep in mind, however, that it is generally not desired to work with
  62. screen coordinates. The recommended approach is to simply work in Canvas
  63. coordinates (``CanvasItem.get_global_transform()``), to allow automatic
  64. screen resolution resizing to work properly.
  65. Feeding custom input events
  66. ---------------------------
  67. It is often desired to feed custom input events to the scene tree. With
  68. the above knowledge, to correctly do this, it must be done the following
  69. way:
  70. .. tabs::
  71. .. code-tab:: gdscript GDScript
  72. var local_pos = Vector2(10, 20) # local to Control/Node2D
  73. var ie = InputEventMouseButton.new()
  74. ie.button_index = BUTTON_LEFT
  75. ie.position = get_viewport_transform() * (get_global_transform() * local_pos)
  76. get_tree().input_event(ie)
  77. .. code-tab:: csharp
  78. var localPos = new Vector2(10,20); // local to Control/Node2D
  79. var ie = new InputEventMouseButton();
  80. ie.ButtonIndex = (int)ButtonList.Left;
  81. ie.Position = (GetViewportTransform() * GetGlobalTransform()).Xform(localPos);
  82. GetTree().InputEvent(ie);