summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--AUTHORS.md1
-rw-r--r--DONORS.md87
-rw-r--r--SConstruct15
-rw-r--r--core/os/os.cpp6
-rw-r--r--core/variant_call.cpp6
-rw-r--r--doc/classes/AnimationTree.xml4
-rw-r--r--doc/classes/DirectionalLight3D.xml8
-rw-r--r--doc/classes/DynamicFontData.xml2
-rw-r--r--doc/classes/EditorInterface.xml12
-rw-r--r--doc/classes/Image.xml6
-rw-r--r--doc/classes/Rect2i.xml122
-rw-r--r--doc/classes/RichTextLabel.xml4
-rw-r--r--doc/classes/Skeleton3D.xml12
-rw-r--r--doc/classes/Vector2i.xml29
-rw-r--r--doc/classes/Vector3i.xml32
-rw-r--r--drivers/gles2/shader_compiler_gles2.cpp12
-rw-r--r--drivers/gles2/shader_compiler_gles2.h2
-rw-r--r--drivers/vulkan/rendering_device_vulkan.cpp13
-rw-r--r--drivers/vulkan/rendering_device_vulkan.h167
-rw-r--r--drivers/vulkan/vulkan_context.h30
-rw-r--r--editor/code_editor.cpp2
-rw-r--r--editor/editor_autoload_settings.cpp8
-rw-r--r--editor/editor_node.cpp2
-rw-r--r--editor/editor_node.h2
-rw-r--r--editor/editor_plugin.cpp7
-rw-r--r--editor/editor_plugin.h1
-rw-r--r--editor/import/resource_importer_texture_atlas.cpp3
-rw-r--r--editor/plugins/canvas_item_editor_plugin.cpp1
-rw-r--r--editor/plugins/collision_shape_2d_editor_plugin.cpp1
-rw-r--r--editor/plugins/script_text_editor.cpp23
-rw-r--r--editor/plugins/tile_map_editor_plugin.cpp16
-rw-r--r--editor/plugins/tile_map_editor_plugin.h1
-rw-r--r--editor/plugins/tile_set_editor_plugin.cpp33
-rw-r--r--editor/plugins/tile_set_editor_plugin.h1
-rw-r--r--editor/project_manager.cpp6
-rw-r--r--editor/scene_tree_dock.cpp5
-rw-r--r--editor/script_create_dialog.cpp7
-rw-r--r--methods.py24
-rw-r--r--modules/opus/config.py2
-rw-r--r--modules/theora/config.py2
-rw-r--r--modules/vorbis/config.py2
-rw-r--r--modules/webm/config.py5
-rw-r--r--platform/android/export/export.cpp17
-rw-r--r--platform/osx/joypad_osx.cpp9
-rw-r--r--scene/3d/light_3d.cpp2
-rw-r--r--scene/gui/rich_text_label.cpp307
-rw-r--r--scene/gui/rich_text_label.h5
-rw-r--r--scene/gui/scroll_bar.cpp21
-rw-r--r--scene/gui/scroll_bar.h22
-rw-r--r--scene/register_scene_types.cpp1
-rw-r--r--scene/resources/dynamic_font.cpp2
-rw-r--r--scene/resources/primitive_meshes.cpp2
-rw-r--r--scene/resources/ray_shape_2d.cpp105
-rw-r--r--scene/resources/ray_shape_2d.h61
-rw-r--r--scene/resources/segment_shape_2d.cpp74
-rw-r--r--scene/resources/segment_shape_2d.h25
-rw-r--r--servers/rendering/rasterizer.h2
-rw-r--r--servers/rendering/rasterizer_rd/shader_compiler_rd.cpp12
-rw-r--r--servers/rendering/rasterizer_rd/shader_compiler_rd.h2
59 files changed, 876 insertions, 517 deletions
diff --git a/AUTHORS.md b/AUTHORS.md
index 0f002cfaed..e8bb91d4bb 100644
--- a/AUTHORS.md
+++ b/AUTHORS.md
@@ -95,6 +95,7 @@ name is available.
Indah Sylvia (ISylvox)
J08nY
Jakub Grzesik (kubecz3k)
+ James Buck (jbuck3)
Jérôme Gully (Nutriz)
Joan Fons Sanchez (JFonS)
Johan Manuel (29jm)
diff --git a/DONORS.md b/DONORS.md
index 134dc0484b..2988cc94f4 100644
--- a/DONORS.md
+++ b/DONORS.md
@@ -24,11 +24,12 @@ generous deed immortalized in the next stable release of Godot Engine.
AD Ford
Alan Beauchamp
- Anand Mallik
+ albinaask
Andrew Dunai
Brandon Lamb
Christian Baune
Christopher Montesano
+ Darius Pranskus
Darkhan Baimyrza
Darrin Massena
Dov Zimring
@@ -41,15 +42,18 @@ generous deed immortalized in the next stable release of Godot Engine.
Jasper Brooks
Javary Co.
Jeffery Chiu
+ John Benard (Linuxydable)
Justin Arnold
Justo Delgado Baudí
Kyle Szklenski
+ Marcel Kräml
Matthieu Huvé
Maxim Karsten
Mike King
Nathan Warden
Neal Gompa (Conan Kudo)
Péter Magyar
+ Ronnie Cheng
Slobodan Milnovic
Stephan Lanfermann
Steve
@@ -58,12 +62,14 @@ generous deed immortalized in the next stable release of Godot Engine.
## Gold donors
+ Bjarke
David Gehrig
David Graham
David Snopek
Ed Morley
Florian Rämisch
Jakub Grzesik
+ HardRound
Manuele Finocchiaro
Officine Pixel S.n.c.
Ronan Zeegers
@@ -92,10 +98,10 @@ generous deed immortalized in the next stable release of Godot Engine.
Maciej Pendolski
Matthew Hillier
Mohamed Ikbel Boulabiar
- Mored4u
Rene
Retro Village
Rob Messick
+ Roland Fredenhagen
Ryan Badour
Sandro Jenny
Scott Wadden
@@ -108,16 +114,19 @@ generous deed immortalized in the next stable release of Godot Engine.
Alex Khayrullin
alice gambrell
+ Barugon
Chris Goddard
Chris Serino
Christian Padilla
Conrad Curry
Craig Smith
Darrian Little
+ Hoai Nam Tran
Horváth Péter
- Ivan Trombley
+ Jamal Aboudrar
Joan Fons
Joshua Flores
+ Leo Fidel R Liban
Petr Malac
Rami
Rob
@@ -149,20 +158,20 @@ generous deed immortalized in the next stable release of Godot Engine.
Christoph Schröder
Codee Leaf
Cody Parker
- Coldragon
Craig Ostrin
+ curtis Kramer
D
Easypete
+ Edgar Sun
Eric Monson
Eugenio Hugo Salgüero Jáñez
- Fain
flesk
Gary Hulst
gavlig
GGGames.org
Guilherme Felipe de C. G. da Silva
- Halom Vered
Heath Hayes
+ Hu Hund
Isaac Clausman
Jared White
Jeff Nyte
@@ -171,18 +180,21 @@ generous deed immortalized in the next stable release of Godot Engine.
Jose Malheiro
Joshua Lesperance
Juan Velandia
+ Julian Todd
Juraj Móza
Kelteseth
kickmaniac
kinfox
Lain Ballard
Marcelo Dornbusch Lopes
+ Marcelo Henrique Gonçalves
Markus Fehr
Markus Wiesner
Martin Eigel
Matt Eunson
m kaersten
MuffinManKen
+ Nick Abousselam
Oliver Dick
Oscar Campos
Patrick Ting
@@ -197,14 +209,16 @@ generous deed immortalized in the next stable release of Godot Engine.
Samuel Judd
Scott Pilet
Sean Morgan
+ Sean Robertson
+ Sébastien
Serban Serafimescu
- Sindre Sømme
SleepCircle
spilldata
Stoned Xander
TheLevelOfDetail .
Thomas Kurz
Tobias Bocanegra
+ Trent Fehl
Urho
William Foster
Zhou Tuizhi
@@ -214,6 +228,7 @@ generous deed immortalized in the next stable release of Godot Engine.
## Silver donors
1D_Inc
+ Aaron Winter
Abraham Haskins
Acheron
Adam
@@ -229,7 +244,6 @@ generous deed immortalized in the next stable release of Godot Engine.
Agustinus Arya
Aidan O'Flannagain
Aki Mimoto
- Alan Mervitz
Alan Stice
Albin Jonasson Svärdsby
Alder Stefano
@@ -237,14 +251,17 @@ generous deed immortalized in the next stable release of Godot Engine.
Alessandro Senese
Alexander Erlemann
alex clavelle
+ Alfred Reinold Baudisch
Allan Davis
Allen Schade
- Andreas Evers
Andreas Krampitz
+ Andres Hernandez
André Simões
+ andrew james morris
+ Andrew Mansuetti
Andrew Thomas
+ Ano Nim
Anthony Avina
- Anthony Staunton
AP Condomines
Arda Erol
Armin Preiml
@@ -252,10 +269,11 @@ generous deed immortalized in the next stable release of Godot Engine.
Arthur S. Muszynski
Asger
Ashley Claymore
+ Ashton Scott Snapp
Aubrey Falconer
- Avencherus
B A
Balázs Batári
+ Bartosz Bielecki
Benedikt
Ben Vercammen
Bernd Jänichen
@@ -265,10 +283,8 @@ generous deed immortalized in the next stable release of Godot Engine.
Bobby CC Wong
Bram
brian
- bugcaptor
Burney Waring
Cameron Meyer
- Carlo Sitaro
Carl van der Geest
Carwyn Edwards
Cas Brugman
@@ -289,7 +305,7 @@ generous deed immortalized in the next stable release of Godot Engine.
Daniel Tebbutt
David May
David Woodard
- DiCola Jamn
+ Dimitri Stanojevic
Dominic Cooney
Dominik Wetzel
Donn Eddy
@@ -301,24 +317,25 @@ generous deed immortalized in the next stable release of Godot Engine.
Eduardo Teixeira
Edward Herbert
Edward Swartz
+ Eelco F Hillenius
Egon Elbre
Elgenzay
Elias Nykrem
- Elmeri '- Duy Kevin Nguyen
Ephemeral
Eric Ellingson
- Eric Rogers
Eric Williams
Erkki Seppälä
Evan Rose
+ Fain
+ Faisal Alkubaisi
Fancy Ants Studios
Fekinox
Felix Bohmann
Felix Kollmann
Flaredown
Forty Doubleu
- fox
FuDiggity
+ Frank
Gadzhi Kharkharov
gamedev by Celio
Gary Thomas
@@ -328,16 +345,17 @@ generous deed immortalized in the next stable release of Godot Engine.
Greyson Richey
Grid
Guillaume Audirac
+ Guillaume Pham Ngoc
Guldoman
Hal A
Heribert Hirth
Hunter Jones
Hylpher
- Ichiro Dohi
Iiari
iKlem
IndustrialRobot
Ivan Nikolaev
+ Jackson Harmer
Jacob
Jaiden Gerig
Jaime Ruiz-Borau Vizárraga
@@ -346,9 +364,11 @@ generous deed immortalized in the next stable release of Godot Engine.
Janders
Jannik Gröger
JARKKO PARVIAINEN
+ Jean-Baptiste LEPESME
Jeff Hungerford
Jennifer Graves
Jesse Dubay
+ Joe Alden
Joel Fivat
Joel Höglund
Joel Setterberg
@@ -363,14 +383,18 @@ generous deed immortalized in the next stable release of Godot Engine.
Jonathan G
Jon Bonazza
Jon Sully
+ Jordy Goodridge
+ Jorge Antunes
Jorge Caballero
Jose Aleman
Jose C. Rubio
Joseph Catrambone
Josh Mitchell
+ Joshua Southerland
Juanfran
Judd
Julian Murgia
+ June Little
JungleRobba
Justin Hamilton
Justin Spedding
@@ -382,7 +406,6 @@ generous deed immortalized in the next stable release of Godot Engine.
Kent Jofur
Kevin McPhillips
Kiri Jolly
- Kiyohiro Kawamura (kyorohiro)
Kjetil Haugland
Klagsam
KsyTek Games
@@ -390,26 +413,24 @@ generous deed immortalized in the next stable release of Godot Engine.
kycho
Kyle Appelgate
Laurent Tréguier
+ Leonard Meagher
Leonardo Dimano
Levi Lindsey
Lin Chear
Linus Lind Lundgren
Lionel Gaillard
- Lukáš Rendvanský
Luigi Renna
LunaticInAHat
Lurkars
Major Haul
Malcolm
- Malik Ahmed
- Malik Nejer
+ Marco Lardelli
Markus Michael Egger
Martin Holas
Martin Liška
Marvin
- Mathieu Rimelen
+ Mathieu
Matt Edwards
- Matthew Little
Mauro Pellegrini
Max Fiedler
Maxime Blade
@@ -426,7 +447,7 @@ generous deed immortalized in the next stable release of Godot Engine.
Mikayla
Mike Birkhead
Mike Cunningham
- Mitchell J. Wagner
+ Molinghu
MoM
Mored4u
Nathan Fish
@@ -435,8 +456,10 @@ generous deed immortalized in the next stable release of Godot Engine.
Neil Blakey-Milner
Neil Wang
Nerdforge
+ Nerdyninja
Nicholas
Nicholas Girga
+ Nick Allen
Nick Macholl
Niclas Eriksen
Nicolás Montaña
@@ -453,11 +476,12 @@ generous deed immortalized in the next stable release of Godot Engine.
Paweł Kowal
Pedro Assuncao
Penguin
+ Peter
Philip Cohoe
Point08
+ pwab
Rad Cat
Rafa Laguna
- rainerLinux
Remi Rampin
Rémi Verschelde
Ricardo Alcantara
@@ -470,6 +494,7 @@ generous deed immortalized in the next stable release of Godot Engine.
Roman Tinkov
Ronald Ho Hip (CrimsonZA)
Ronan
+ Ronny Mühle
Ryan Groom
Ryan Hentz
Sam Edson
@@ -483,6 +508,7 @@ generous deed immortalized in the next stable release of Godot Engine.
Shane
Shane Sicienski
Shane Spoor
+ Shiomi '- Duy Kevin Nguyen
Siim Raidma
Simon Jonas Larsen
Simon Wenner
@@ -490,17 +516,21 @@ generous deed immortalized in the next stable release of Godot Engine.
SK
smbe19
smo1704
+ soft circles
+ Squirrel
Stefano Caronia
Steve Cloete
Svenne Krap
Taylor Fahlman
Terry
tezuvholovdr
+ TheVoiceInMyHead
thomas
Thomas Bechtold
Thomas Detoy
Thomas Kelly
Tim Drumheller
+ Tim Erskine
Timothy B. MacDonald
Title Plinsut
Tobbun
@@ -516,6 +546,7 @@ generous deed immortalized in the next stable release of Godot Engine.
Tyler Compton
Tyler Stafos
UltyX
+ Valentí Gàmez
Vaughan Ling
Victor
Vigilant Watch
@@ -525,10 +556,12 @@ generous deed immortalized in the next stable release of Godot Engine.
werner mendizabal
Wiley Thompson
Will
- William Hogben
Wyatt Goodin
Yegor
+ Yuri LaPointe
Yuri Sizov
+ Zgegnesh Hemomancer
+ 郝晨煜
## Bronze donors
diff --git a/SConstruct b/SConstruct
index 27e6c5f2d3..b424363dc8 100644
--- a/SConstruct
+++ b/SConstruct
@@ -86,6 +86,7 @@ env_base.__class__.add_library = methods.add_library
env_base.__class__.add_program = methods.add_program
env_base.__class__.CommandNoCache = methods.CommandNoCache
env_base.__class__.disable_warnings = methods.disable_warnings
+env_base.__class__.module_check_dependencies = methods.module_check_dependencies
env_base["x86_libtheora_opt_gcc"] = False
env_base["x86_libtheora_opt_vc"] = False
@@ -607,14 +608,12 @@ if selected_platform in platform_list:
env.Append(CPPDEFINES=["MINIZIP_ENABLED"])
editor_module_list = ["regex"]
- for x in editor_module_list:
- if not env["module_" + x + "_enabled"]:
- if env["tools"]:
- print(
- "Build option 'module_" + x + "_enabled=no' cannot be used with 'tools=yes' (editor), "
- "only with 'tools=no' (export template)."
- )
- Exit(255)
+ if env["tools"] and not env.module_check_dependencies("tools", editor_module_list):
+ print(
+ "Build option 'module_" + x + "_enabled=no' cannot be used with 'tools=yes' (editor), "
+ "only with 'tools=no' (export template)."
+ )
+ Exit(255)
if not env["verbose"]:
methods.no_verbose(sys, env)
diff --git a/core/os/os.cpp b/core/os/os.cpp
index c29930e485..56755bcf51 100644
--- a/core/os/os.cpp
+++ b/core/os/os.cpp
@@ -457,18 +457,22 @@ PackedStringArray OS::get_connected_midi_inputs() {
}
PackedStringArray list;
- return list;
+ ERR_FAIL_V_MSG(list, vformat("MIDI input isn't supported on %s.", OS::get_singleton()->get_name()));
}
void OS::open_midi_inputs() {
if (MIDIDriver::get_singleton()) {
MIDIDriver::get_singleton()->open();
+ } else {
+ ERR_PRINT(vformat("MIDI input isn't supported on %s.", OS::get_singleton()->get_name()));
}
}
void OS::close_midi_inputs() {
if (MIDIDriver::get_singleton()) {
MIDIDriver::get_singleton()->close();
+ } else {
+ ERR_PRINT(vformat("MIDI input isn't supported on %s.", OS::get_singleton()->get_name()));
}
}
diff --git a/core/variant_call.cpp b/core/variant_call.cpp
index 404468a7b4..f1b2a1547d 100644
--- a/core/variant_call.cpp
+++ b/core/variant_call.cpp
@@ -1296,10 +1296,16 @@ Variant Variant::construct(const Variant::Type p_type, const Variant **p_args, i
// math types
case VECTOR2:
return Vector2();
+ case VECTOR2I:
+ return Vector2i();
case RECT2:
return Rect2();
+ case RECT2I:
+ return Rect2i();
case VECTOR3:
return Vector3();
+ case VECTOR3I:
+ return Vector3i();
case TRANSFORM2D:
return Transform2D();
case PLANE:
diff --git a/doc/classes/AnimationTree.xml b/doc/classes/AnimationTree.xml
index 9642dd1c70..dd04f4ce3f 100644
--- a/doc/classes/AnimationTree.xml
+++ b/doc/classes/AnimationTree.xml
@@ -4,6 +4,7 @@
A node to be used for advanced animation transitions in an [AnimationPlayer].
</brief_description>
<description>
+ Note: When linked with an [AnimationPlayer], several properties and methods of the corresponding [AnimationPlayer] will not function as expected. Playback and transitions should be handled using only the [AnimationTree] and its constituent [AnimationNode](s). The [AnimationPlayer] node should be used solely for adding, deleting, and editing animations.
</description>
<tutorials>
<link>https://docs.godotengine.org/en/latest/tutorials/animation/animation_tree.html</link>
@@ -23,6 +24,7 @@
<return type="Transform">
</return>
<description>
+ Retrieve the motion of the [member root_motion_track] as a [Transform] that can be used elsewhere. If [member root_motion_track] is not a path to a track of type [constant Animation.TYPE_TRANSFORM], returns an identity transformation.
</description>
</method>
<method name="rename_parameter">
@@ -47,6 +49,8 @@
The process mode of this [AnimationTree]. See [enum AnimationProcessMode] for available modes.
</member>
<member name="root_motion_track" type="NodePath" setter="set_root_motion_track" getter="get_root_motion_track" default="NodePath(&quot;&quot;)">
+ The path to the Animation track used for root motion. Paths must be valid scene-tree paths to a node, and must be specified starting from the parent node of the node that will reproduce the animation. To specify a track that controls properties or bones, append its name after the path, separated by [code]":"[/code]. For example, [code]"character/skeleton:ankle"[/code] or [code]"character/mesh:transform/local"[/code].
+ If the track has type [constant Animation.TYPE_TRANSFORM], the transformation will be cancelled visually, and the animation will appear to stay in place.
</member>
<member name="tree_root" type="AnimationNode" setter="set_tree_root" getter="get_tree_root">
The root animation node of this [AnimationTree]. See [AnimationNode].
diff --git a/doc/classes/DirectionalLight3D.xml b/doc/classes/DirectionalLight3D.xml
index 6c88dcf42e..f66be6ddde 100644
--- a/doc/classes/DirectionalLight3D.xml
+++ b/doc/classes/DirectionalLight3D.xml
@@ -42,19 +42,19 @@
</members>
<constants>
<constant name="SHADOW_ORTHOGONAL" value="0" enum="ShadowMode">
- Renders the entire scene's shadow map from an orthogonal point of view. May result in blockier shadows on close objects.
+ Renders the entire scene's shadow map from an orthogonal point of view. This is the fastest directional shadow mode. May result in blurrier shadows on close objects.
</constant>
<constant name="SHADOW_PARALLEL_2_SPLITS" value="1" enum="ShadowMode">
- Splits the view frustum in 2 areas, each with its own shadow map.
+ Splits the view frustum in 2 areas, each with its own shadow map. This shadow mode is a compromise between [constant SHADOW_ORTHOGONAL] and [constant SHADOW_PARALLEL_4_SPLITS] in terms of performance.
</constant>
<constant name="SHADOW_PARALLEL_4_SPLITS" value="2" enum="ShadowMode">
- Splits the view frustum in 4 areas, each with its own shadow map.
+ Splits the view frustum in 4 areas, each with its own shadow map. This is the slowest directional shadow mode.
</constant>
<constant name="SHADOW_DEPTH_RANGE_STABLE" value="0" enum="ShadowDepthRange">
Keeps the shadow stable when the camera moves, at the cost of lower effective shadow resolution.
</constant>
<constant name="SHADOW_DEPTH_RANGE_OPTIMIZED" value="1" enum="ShadowDepthRange">
- Tries to achieve maximum shadow resolution. May result in saw effect on shadow edges.
+ Tries to achieve maximum shadow resolution. May result in saw effect on shadow edges. This mode typically works best in games where the camera will often move at high speeds, such as most racing games.
</constant>
</constants>
</class>
diff --git a/doc/classes/DynamicFontData.xml b/doc/classes/DynamicFontData.xml
index 2b4ec17bf1..483da96f3f 100644
--- a/doc/classes/DynamicFontData.xml
+++ b/doc/classes/DynamicFontData.xml
@@ -12,7 +12,7 @@
</methods>
<members>
<member name="antialiased" type="bool" setter="set_antialiased" getter="is_antialiased" default="true">
- If [code]true[/code], the font is rendered with anti-aliasing.
+ If [code]true[/code], the font is rendered with anti-aliasing. This property applies both to the main font and its outline (if it has one).
</member>
<member name="font_path" type="String" setter="set_font_path" getter="get_font_path" default="&quot;&quot;">
The path to the vector font file.
diff --git a/doc/classes/EditorInterface.xml b/doc/classes/EditorInterface.xml
index 499c3b8271..dbe725f08b 100644
--- a/doc/classes/EditorInterface.xml
+++ b/doc/classes/EditorInterface.xml
@@ -182,14 +182,6 @@
Selects the file, with the path provided by [code]file[/code], in the FileSystem dock.
</description>
</method>
- <method name="set_distraction_free_mode">
- <return type="void">
- </return>
- <argument index="0" name="enter" type="bool">
- </argument>
- <description>
- </description>
- </method>
<method name="set_main_screen_editor">
<return type="void">
</return>
@@ -210,6 +202,10 @@
</description>
</method>
</methods>
+ <members>
+ <member name="distraction_free_mode" type="bool" setter="set_distraction_free_mode" getter="is_distraction_free_mode_enabled">
+ </member>
+ </members>
<constants>
</constants>
</class>
diff --git a/doc/classes/Image.xml b/doc/classes/Image.xml
index 55d2275194..aa8c8d2443 100644
--- a/doc/classes/Image.xml
+++ b/doc/classes/Image.xml
@@ -436,6 +436,12 @@
Saves the image as a PNG file to [code]path[/code].
</description>
</method>
+ <method name="save_png_to_buffer" qualifiers="const">
+ <return type="PackedByteArray">
+ </return>
+ <description>
+ </description>
+ </method>
<method name="set_pixel">
<return type="void">
</return>
diff --git a/doc/classes/Rect2i.xml b/doc/classes/Rect2i.xml
index 2e8be384c1..f3a7ba0476 100644
--- a/doc/classes/Rect2i.xml
+++ b/doc/classes/Rect2i.xml
@@ -46,7 +46,129 @@
Constructs a new [Rect2i] from [Rect2]. The floating point coordinates will be truncated.
</description>
</method>
+ <method name="abs">
+ <return type="Rect2i">
+ </return>
+ <description>
+ Returns a [Rect2i] with equivalent position and area, modified so that the top-left corner is the origin and [code]width[/code] and [code]height[/code] are positive.
+ </description>
+ </method>
+ <method name="clip">
+ <return type="Rect2i">
+ </return>
+ <argument index="0" name="b" type="Rect2i">
+ </argument>
+ <description>
+ Returns the intersection of this [Rect2i] and b.
+ </description>
+ </method>
+ <method name="encloses">
+ <return type="bool">
+ </return>
+ <argument index="0" name="b" type="Rect2i">
+ </argument>
+ <description>
+ Returns [code]true[/code] if this [Rect2i] completely encloses another one.
+ </description>
+ </method>
+ <method name="expand">
+ <return type="Rect2i">
+ </return>
+ <argument index="0" name="to" type="Vector2i">
+ </argument>
+ <description>
+ Returns this [Rect2i] expanded to include a given point.
+ </description>
+ </method>
+ <method name="get_area">
+ <return type="int">
+ </return>
+ <description>
+ Returns the area of the [Rect2i].
+ </description>
+ </method>
+ <method name="grow">
+ <return type="Rect2i">
+ </return>
+ <argument index="0" name="by" type="int">
+ </argument>
+ <description>
+ Returns a copy of the [Rect2i] grown a given amount of units towards all the sides.
+ </description>
+ </method>
+ <method name="grow_individual">
+ <return type="Rect2i">
+ </return>
+ <argument index="0" name="left" type="int">
+ </argument>
+ <argument index="1" name="top" type="int">
+ </argument>
+ <argument index="2" name="right" type="int">
+ </argument>
+ <argument index="3" name=" bottom" type="int">
+ </argument>
+ <description>
+ Returns a copy of the [Rect2i] grown a given amount of units towards each direction individually.
+ </description>
+ </method>
+ <method name="grow_margin">
+ <return type="Rect2i">
+ </return>
+ <argument index="0" name="margin" type="int">
+ </argument>
+ <argument index="1" name="by" type="int">
+ </argument>
+ <description>
+ Returns a copy of the [Rect2i] grown a given amount of units towards the [enum Margin] direction.
+ </description>
+ </method>
+ <method name="has_no_area">
+ <return type="bool">
+ </return>
+ <description>
+ Returns [code]true[/code] if the [Rect2i] is flat or empty.
+ </description>
+ </method>
+ <method name="has_point">
+ <return type="bool">
+ </return>
+ <argument index="0" name="point" type="Vector2i">
+ </argument>
+ <description>
+ Returns [code]true[/code] if the [Rect2i] contains a point.
+ </description>
+ </method>
+ <method name="intersects">
+ <return type="bool">
+ </return>
+ <argument index="0" name="b" type="Rect2i">
+ </argument>
+ <description>
+ Returns [code]true[/code] if the [Rect2i] overlaps with [code]b[/code] (i.e. they have at least one point in common).
+ If [code]include_borders[/code] is [code]true[/code], they will also be considered overlapping if their borders touch, even without intersection.
+ </description>
+ </method>
+ <method name="merge">
+ <return type="Rect2i">
+ </return>
+ <argument index="0" name="b" type="Rect2i">
+ </argument>
+ <description>
+ Returns a larger [Rect2i] that contains this [Rect2i] and [code]b[/code].
+ </description>
+ </method>
</methods>
+ <members>
+ <member name="end" type="Vector2i" setter="" getter="" default="Vector2i( 0, 0 )">
+ Ending corner.
+ </member>
+ <member name="position" type="Vector2i" setter="" getter="" default="Vector2i( 0, 0 )">
+ Position (starting corner).
+ </member>
+ <member name="size" type="Vector2i" setter="" getter="" default="Vector2i( 0, 0 )">
+ Size from position to end.
+ </member>
+ </members>
<constants>
</constants>
</class>
diff --git a/doc/classes/RichTextLabel.xml b/doc/classes/RichTextLabel.xml
index efc0c9d600..db036d7d88 100644
--- a/doc/classes/RichTextLabel.xml
+++ b/doc/classes/RichTextLabel.xml
@@ -20,8 +20,10 @@
</argument>
<argument index="2" name="height" type="int" default="0">
</argument>
+ <argument index="3" name="color" type="Color" default="Color( 1, 1, 1, 1 )">
+ </argument>
<description>
- Adds an image's opening and closing tags to the tag stack, optionally providing a [code]width[/code] and [code]height[/code] to resize the image.
+ Adds an image's opening and closing tags to the tag stack, optionally providing a [code]width[/code] and [code]height[/code] to resize the image and a [code]color[/code] to tint the image.
If [code]width[/code] or [code]height[/code] is set to 0, the image size will be adjusted in order to keep the original aspect ratio.
</description>
</method>
diff --git a/doc/classes/Skeleton3D.xml b/doc/classes/Skeleton3D.xml
index 4460b519fc..640cbe84f5 100644
--- a/doc/classes/Skeleton3D.xml
+++ b/doc/classes/Skeleton3D.xml
@@ -106,6 +106,12 @@
Returns the pose transform of the specified bone. Pose is applied on top of the custom pose, which is applied on top the rest pose.
</description>
</method>
+ <method name="get_bone_process_orders">
+ <return type="PackedInt32Array">
+ </return>
+ <description>
+ </description>
+ </method>
<method name="get_bone_rest" qualifiers="const">
<return type="Transform">
</return>
@@ -268,6 +274,12 @@
<member name="animate_physical_bones" type="bool" setter="set_animate_physical_bones" getter="get_animate_physical_bones" default="true">
</member>
</members>
+ <signals>
+ <signal name="pose_updated">
+ <description>
+ </description>
+ </signal>
+ </signals>
<constants>
<constant name="NOTIFICATION_UPDATE_SKELETON" value="50">
</constant>
diff --git a/doc/classes/Vector2i.xml b/doc/classes/Vector2i.xml
index a516eb01dd..71c7aaa4e5 100644
--- a/doc/classes/Vector2i.xml
+++ b/doc/classes/Vector2i.xml
@@ -31,7 +31,36 @@
Constructs a new [Vector2i] from [Vector2]. The floating point coordinates will be truncated.
</description>
</method>
+ <method name="abs">
+ <return type="Vector2i">
+ </return>
+ <description>
+ Returns a new vector with all components in absolute values (i.e. positive).
+ </description>
+ </method>
+ <method name="aspect">
+ <return type="float">
+ </return>
+ <description>
+ Returns the ratio of [member x] to [member y].
+ </description>
+ </method>
+ <method name="sign">
+ <return type="Vector2i">
+ </return>
+ <description>
+ Returns the vector with each component set to one or negative one, depending on the signs of the components.
+ </description>
+ </method>
</methods>
+ <members>
+ <member name="x" type="int" setter="" getter="" default="0">
+ The vector's X component. Also accessible by using the index position [code][0][/code].
+ </member>
+ <member name="y" type="int" setter="" getter="" default="0">
+ The vector's Y component. Also accessible by using the index position [code][1][/code].
+ </member>
+ </members>
<constants>
<constant name="AXIS_X" value="0">
Enumerated value for the X axis.
diff --git a/doc/classes/Vector3i.xml b/doc/classes/Vector3i.xml
index 4f5a658b89..c5aa3d0347 100644
--- a/doc/classes/Vector3i.xml
+++ b/doc/classes/Vector3i.xml
@@ -33,7 +33,39 @@
Constructs a new [Vector3i] from [Vector3]. The floating point coordinates will be truncated.
</description>
</method>
+ <method name="max_axis">
+ <return type="int">
+ </return>
+ <description>
+ Returns the axis of the vector's largest value. See [code]AXIS_*[/code] constants.
+ </description>
+ </method>
+ <method name="min_axis">
+ <return type="int">
+ </return>
+ <description>
+ Returns the axis of the vector's smallest value. See [code]AXIS_*[/code] constants.
+ </description>
+ </method>
+ <method name="sign">
+ <return type="Vector3i">
+ </return>
+ <description>
+ Returns the vector with each component set to one or negative one, depending on the signs of the components.
+ </description>
+ </method>
</methods>
+ <members>
+ <member name="x" type="int" setter="" getter="" default="0">
+ The vector's X component. Also accessible by using the index position [code][0][/code].
+ </member>
+ <member name="y" type="int" setter="" getter="" default="0">
+ The vector's Y component. Also accessible by using the index position [code][1][/code].
+ </member>
+ <member name="z" type="int" setter="" getter="" default="0">
+ The vector's Z component. Also accessible by using the index position [code][2][/code].
+ </member>
+ </members>
<constants>
<constant name="AXIS_X" value="0">
Enumerated value for the X axis.
diff --git a/drivers/gles2/shader_compiler_gles2.cpp b/drivers/gles2/shader_compiler_gles2.cpp
index 9b57f417cb..2e36de5c79 100644
--- a/drivers/gles2/shader_compiler_gles2.cpp
+++ b/drivers/gles2/shader_compiler_gles2.cpp
@@ -262,7 +262,7 @@ void ShaderCompilerGLES2::_dump_function_deps(SL::ShaderNode *p_node, const Stri
}
}
-String ShaderCompilerGLES2::_dump_node_code(SL::Node *p_node, int p_level, GeneratedCode &r_gen_code, IdentifierActions &p_actions, const DefaultIdentifierActions &p_default_actions, bool p_assigning) {
+String ShaderCompilerGLES2::_dump_node_code(SL::Node *p_node, int p_level, GeneratedCode &r_gen_code, IdentifierActions &p_actions, const DefaultIdentifierActions &p_default_actions, bool p_assigning, bool p_use_scope) {
StringBuilder code;
switch (p_node->type) {
@@ -626,7 +626,7 @@ String ShaderCompilerGLES2::_dump_node_code(SL::Node *p_node, int p_level, Gener
if (arr_node->call_expression != nullptr) {
code += ".";
- code += _dump_node_code(arr_node->call_expression, p_level, r_gen_code, p_actions, p_default_actions, p_assigning);
+ code += _dump_node_code(arr_node->call_expression, p_level, r_gen_code, p_actions, p_default_actions, p_assigning, false);
}
if (arr_node->index_expression != nullptr) {
@@ -822,13 +822,17 @@ String ShaderCompilerGLES2::_dump_node_code(SL::Node *p_node, int p_level, Gener
} break;
default: {
- code += "(";
+ if (p_use_scope) {
+ code += "(";
+ }
code += _dump_node_code(op_node->arguments[0], p_level, r_gen_code, p_actions, p_default_actions, p_assigning);
code += " ";
code += _opstr(op_node->op);
code += " ";
code += _dump_node_code(op_node->arguments[1], p_level, r_gen_code, p_actions, p_default_actions, p_assigning);
- code += ")";
+ if (p_use_scope) {
+ code += ")";
+ }
} break;
}
} break;
diff --git a/drivers/gles2/shader_compiler_gles2.h b/drivers/gles2/shader_compiler_gles2.h
index 369bf7877b..66a3af0739 100644
--- a/drivers/gles2/shader_compiler_gles2.h
+++ b/drivers/gles2/shader_compiler_gles2.h
@@ -75,7 +75,7 @@ private:
};
void _dump_function_deps(ShaderLanguage::ShaderNode *p_node, const StringName &p_for_func, const Map<StringName, String> &p_func_code, StringBuilder &r_to_add, Set<StringName> &r_added);
- String _dump_node_code(ShaderLanguage::Node *p_node, int p_level, GeneratedCode &r_gen_code, IdentifierActions &p_actions, const DefaultIdentifierActions &p_default_actions, bool p_assigning);
+ String _dump_node_code(ShaderLanguage::Node *p_node, int p_level, GeneratedCode &r_gen_code, IdentifierActions &p_actions, const DefaultIdentifierActions &p_default_actions, bool p_assigning, bool p_use_scope = true);
StringName current_func_name;
StringName vertex_name;
diff --git a/drivers/vulkan/rendering_device_vulkan.cpp b/drivers/vulkan/rendering_device_vulkan.cpp
index efd4f057fd..c9e78678a8 100644
--- a/drivers/vulkan/rendering_device_vulkan.cpp
+++ b/drivers/vulkan/rendering_device_vulkan.cpp
@@ -35,6 +35,7 @@
#include "core/os/os.h"
#include "core/project_settings.h"
#include "drivers/vulkan/vulkan_context.h"
+
#include "thirdparty/spirv-reflect/spirv_reflect.h"
//#define FORCE_FULL_BARRIER
@@ -5905,7 +5906,7 @@ void RenderingDeviceVulkan::draw_list_bind_render_pipeline(DrawListID p_list, RI
if (pipeline->push_constant_size) {
dl->state.pipeline_push_constant_stages = pipeline->push_constant_stages;
#ifdef DEBUG_ENABLED
- dl->validation.pipeline_push_constant_suppplied = false;
+ dl->validation.pipeline_push_constant_supplied = false;
#endif
}
@@ -6036,7 +6037,7 @@ void RenderingDeviceVulkan::draw_list_set_push_constant(DrawListID p_list, const
#endif
vkCmdPushConstants(dl->command_buffer, dl->state.pipeline_layout, dl->state.pipeline_push_constant_stages, 0, p_data_size, p_data);
#ifdef DEBUG_ENABLED
- dl->validation.pipeline_push_constant_suppplied = true;
+ dl->validation.pipeline_push_constant_supplied = true;
#endif
}
@@ -6064,7 +6065,7 @@ void RenderingDeviceVulkan::draw_list_draw(DrawListID p_list, bool p_use_indices
if (dl->validation.pipeline_push_constant_size > 0) {
//using push constants, check that they were supplied
- ERR_FAIL_COND_MSG(!dl->validation.pipeline_push_constant_suppplied,
+ ERR_FAIL_COND_MSG(!dl->validation.pipeline_push_constant_supplied,
"The shader in this pipeline requires a push constant to be set before drawing, but it's not present.");
}
@@ -6300,7 +6301,7 @@ void RenderingDeviceVulkan::compute_list_bind_compute_pipeline(ComputeListID p_l
if (pipeline->push_constant_size) {
cl->state.pipeline_push_constant_stages = pipeline->push_constant_stages;
#ifdef DEBUG_ENABLED
- cl->validation.pipeline_push_constant_suppplied = false;
+ cl->validation.pipeline_push_constant_supplied = false;
#endif
}
@@ -6433,7 +6434,7 @@ void RenderingDeviceVulkan::compute_list_set_push_constant(ComputeListID p_list,
#endif
vkCmdPushConstants(cl->command_buffer, cl->state.pipeline_layout, cl->state.pipeline_push_constant_stages, 0, p_data_size, p_data);
#ifdef DEBUG_ENABLED
- cl->validation.pipeline_push_constant_suppplied = true;
+ cl->validation.pipeline_push_constant_supplied = true;
#endif
}
@@ -6460,7 +6461,7 @@ void RenderingDeviceVulkan::compute_list_dispatch(ComputeListID p_list, uint32_t
if (cl->validation.pipeline_push_constant_size > 0) {
//using push constants, check that they were supplied
- ERR_FAIL_COND_MSG(!cl->validation.pipeline_push_constant_suppplied,
+ ERR_FAIL_COND_MSG(!cl->validation.pipeline_push_constant_supplied,
"The shader in this pipeline requires a push constant to be set before drawing, but it's not present.");
}
diff --git a/drivers/vulkan/rendering_device_vulkan.h b/drivers/vulkan/rendering_device_vulkan.h
index 6b75154a8d..eac3250bf7 100644
--- a/drivers/vulkan/rendering_device_vulkan.h
+++ b/drivers/vulkan/rendering_device_vulkan.h
@@ -42,7 +42,9 @@
#endif
#endif
#include "vk_mem_alloc.h"
+
#include <vulkan/vulkan.h>
+
//todo:
//compute
//push constants
@@ -202,15 +204,10 @@ class RenderingDeviceVulkan : public RenderingDevice {
Error _insert_staging_block();
struct Buffer {
- uint32_t size;
- VkBuffer buffer;
- VmaAllocation allocation;
+ uint32_t size = 0;
+ VkBuffer buffer = VK_NULL_HANDLE;
+ VmaAllocation allocation = nullptr;
VkDescriptorBufferInfo buffer_info; //used for binding
- Buffer() {
- size = 0;
- buffer = VK_NULL_HANDLE;
- allocation = nullptr;
- }
};
Error _buffer_allocate(Buffer *p_buffer, uint32_t p_size, uint32_t p_usage, VmaMemoryUsage p_mapping);
@@ -570,7 +567,7 @@ class RenderingDeviceVulkan : public RenderingDevice {
struct DescriptorPoolKey {
union {
struct {
- uint16_t uniform_type[UNIFORM_TYPE_MAX]; //using 16 bits because, for sending arrays, each element is a pool set.
+ uint16_t uniform_type[UNIFORM_TYPE_MAX]; // Using 16 bits because, for sending arrays, each element is a pool set.
};
struct {
uint64_t key1;
@@ -712,106 +709,67 @@ class RenderingDeviceVulkan : public RenderingDevice {
Vector<SplitDrawListAllocator> split_draw_list_allocators;
struct DrawList {
- VkCommandBuffer command_buffer; //if persistent, this is owned, otherwise it's shared with the ringbuffer
+ VkCommandBuffer command_buffer; // If persistent, this is owned, otherwise it's shared with the ringbuffer.
Rect2i viewport;
struct SetState {
- uint32_t pipeline_expected_format;
- uint32_t uniform_set_format;
- VkDescriptorSet descriptor_set;
+ uint32_t pipeline_expected_format = 0;
+ uint32_t uniform_set_format = 0;
+ VkDescriptorSet descriptor_set = VK_NULL_HANDLE;
RID uniform_set;
- bool bound;
- SetState() {
- bound = false;
- pipeline_expected_format = 0;
- uniform_set_format = 0;
- descriptor_set = VK_NULL_HANDLE;
- }
+ bool bound = false;
};
struct State {
SetState sets[MAX_UNIFORM_SETS];
- uint32_t set_count;
+ uint32_t set_count = 0;
RID pipeline;
RID pipeline_shader;
- VkPipelineLayout pipeline_layout;
+ VkPipelineLayout pipeline_layout = VK_NULL_HANDLE;
RID vertex_array;
RID index_array;
- uint32_t pipeline_push_constant_stages;
-
- State() {
- set_count = 0;
- pipeline_layout = VK_NULL_HANDLE;
- pipeline_push_constant_stages = 0;
- }
+ uint32_t pipeline_push_constant_stages = 0;
} state;
-#ifdef DEBUG_ENABLED
+#ifdef DEBUG_ENABLED
struct Validation {
- bool active; //means command buffer was not closes, so you can keep adding things
- FramebufferFormatID framebuffer_format;
- //actual render pass values
- uint32_t dynamic_state;
- VertexFormatID vertex_format; //INVALID_ID if not set
- uint32_t vertex_array_size; //0 if not set
- uint32_t vertex_max_instances_allowed;
- bool index_buffer_uses_restart_indices;
- uint32_t index_array_size; //0 if index buffer not set
- uint32_t index_array_max_index;
+ bool active = true; // Means command buffer was not closed, so you can keep adding things.
+ FramebufferFormatID framebuffer_format = INVALID_ID;
+ // Actual render pass values.
+ uint32_t dynamic_state = 0;
+ VertexFormatID vertex_format = INVALID_ID;
+ uint32_t vertex_array_size = 0;
+ uint32_t vertex_max_instances_allowed = 0xFFFFFFFF;
+ bool index_buffer_uses_restart_indices = false;
+ uint32_t index_array_size = 0;
+ uint32_t index_array_max_index = 0;
uint32_t index_array_offset;
Vector<uint32_t> set_formats;
Vector<bool> set_bound;
Vector<RID> set_rids;
- //last pipeline set values
- bool pipeline_active;
- uint32_t pipeline_dynamic_state;
- VertexFormatID pipeline_vertex_format;
+ // Last pipeline set values.
+ bool pipeline_active = false;
+ uint32_t pipeline_dynamic_state = 0;
+ VertexFormatID pipeline_vertex_format = INVALID_ID;
RID pipeline_shader;
- uint32_t invalid_set_from;
- bool pipeline_uses_restart_indices;
+ uint32_t invalid_set_from = 0;
+ bool pipeline_uses_restart_indices = false;
uint32_t pipeline_primitive_divisor;
uint32_t pipeline_primitive_minimum;
Vector<uint32_t> pipeline_set_formats;
- uint32_t pipeline_push_constant_size;
- bool pipeline_push_constant_suppplied;
-
- Validation() {
- active = true;
- dynamic_state = 0;
- vertex_format = INVALID_ID;
- vertex_array_size = 0;
- vertex_max_instances_allowed = 0xFFFFFFFF;
- framebuffer_format = INVALID_ID;
- index_array_size = 0; //not sent
- index_array_max_index = 0; //not set
- index_buffer_uses_restart_indices = false;
- invalid_set_from = 0;
-
- //pipeline state initalize
- pipeline_active = false;
- pipeline_dynamic_state = 0;
- pipeline_vertex_format = INVALID_ID;
- pipeline_uses_restart_indices = false;
- pipeline_push_constant_size = 0;
- pipeline_push_constant_suppplied = false;
- }
+ uint32_t pipeline_push_constant_size = 0;
+ bool pipeline_push_constant_supplied = false;
} validation;
#else
struct Validation {
- uint32_t vertex_array_size; //0 if not set
- uint32_t index_array_size; //0 if index buffer not set
+ uint32_t vertex_array_size = 0;
+ uint32_t index_array_size = 0;
uint32_t index_array_offset;
-
- Validation() {
- vertex_array_size = 0;
- index_array_size = 0; //not sent
- }
} validation;
-
#endif
};
- DrawList *draw_list; //one for regular draw lists, multiple for split.
+ DrawList *draw_list; // One for regular draw lists, multiple for split.
uint32_t draw_list_count;
bool draw_list_split;
Vector<RID> draw_list_bound_textures;
@@ -828,62 +786,39 @@ class RenderingDeviceVulkan : public RenderingDevice {
/**********************/
struct ComputeList {
- VkCommandBuffer command_buffer; //if persistent, this is owned, otherwise it's shared with the ringbuffer
+ VkCommandBuffer command_buffer; // If persistent, this is owned, otherwise it's shared with the ringbuffer.
struct SetState {
- uint32_t pipeline_expected_format;
- uint32_t uniform_set_format;
- VkDescriptorSet descriptor_set;
+ uint32_t pipeline_expected_format = 0;
+ uint32_t uniform_set_format = 0;
+ VkDescriptorSet descriptor_set = VK_NULL_HANDLE;
RID uniform_set;
- bool bound;
- SetState() {
- bound = false;
- pipeline_expected_format = 0;
- uniform_set_format = 0;
- descriptor_set = VK_NULL_HANDLE;
- }
+ bool bound = false;
};
struct State {
Set<Texture *> textures_to_sampled_layout;
-
SetState sets[MAX_UNIFORM_SETS];
- uint32_t set_count;
+ uint32_t set_count = 0;
RID pipeline;
RID pipeline_shader;
- VkPipelineLayout pipeline_layout;
- uint32_t pipeline_push_constant_stages;
-
- State() {
- set_count = 0;
- pipeline_layout = VK_NULL_HANDLE;
- pipeline_push_constant_stages = 0;
- }
+ VkPipelineLayout pipeline_layout = VK_NULL_HANDLE;
+ uint32_t pipeline_push_constant_stages = 0;
} state;
-#ifdef DEBUG_ENABLED
+#ifdef DEBUG_ENABLED
struct Validation {
- bool active; //means command buffer was not closes, so you can keep adding things
+ bool active = true; // Means command buffer was not closed, so you can keep adding things.
Vector<uint32_t> set_formats;
Vector<bool> set_bound;
Vector<RID> set_rids;
- //last pipeline set values
- bool pipeline_active;
+ // Last pipeline set values.
+ bool pipeline_active = false;
RID pipeline_shader;
- uint32_t invalid_set_from;
+ uint32_t invalid_set_from = 0;
Vector<uint32_t> pipeline_set_formats;
- uint32_t pipeline_push_constant_size;
- bool pipeline_push_constant_suppplied;
-
- Validation() {
- active = true;
- invalid_set_from = 0;
-
- //pipeline state initalize
- pipeline_active = false;
- pipeline_push_constant_size = 0;
- pipeline_push_constant_suppplied = false;
- }
+ uint32_t pipeline_push_constant_size = 0;
+ bool pipeline_push_constant_supplied = false;
} validation;
#endif
};
diff --git a/drivers/vulkan/vulkan_context.h b/drivers/vulkan/vulkan_context.h
index ff1215ff5d..3f4cfac123 100644
--- a/drivers/vulkan/vulkan_context.h
+++ b/drivers/vulkan/vulkan_context.h
@@ -80,29 +80,15 @@ class VulkanContext {
} SwapchainImageResources;
struct Window {
- bool is_minimzed;
- VkSurfaceKHR surface;
- VkSwapchainKHR swapchain;
- SwapchainImageResources *swapchain_image_resources;
- VkPresentModeKHR presentMode;
- uint32_t current_buffer;
- int width;
- int height;
+ VkSurfaceKHR surface = VK_NULL_HANDLE;
+ VkSwapchainKHR swapchain = VK_NULL_HANDLE;
+ SwapchainImageResources *swapchain_image_resources = VK_NULL_HANDLE;
+ VkPresentModeKHR presentMode = VK_PRESENT_MODE_FIFO_KHR;
+ uint32_t current_buffer = 0;
+ int width = 0;
+ int height = 0;
VkCommandPool present_cmd_pool; //for separate present queue
-
- VkRenderPass render_pass;
-
- Window() {
- width = 0;
- height = 0;
- render_pass = VK_NULL_HANDLE;
- current_buffer = 0;
- surface = VK_NULL_HANDLE;
- swapchain_image_resources = VK_NULL_HANDLE;
- swapchain = VK_NULL_HANDLE;
- is_minimzed = false;
- presentMode = VK_PRESENT_MODE_FIFO_KHR;
- }
+ VkRenderPass render_pass = VK_NULL_HANDLE;
};
struct LocalDevice {
diff --git a/editor/code_editor.cpp b/editor/code_editor.cpp
index 3ea970a0f0..9888013ce6 100644
--- a/editor/code_editor.cpp
+++ b/editor/code_editor.cpp
@@ -657,7 +657,7 @@ FindReplaceBar::FindReplaceBar() {
// be handled too late if they weren't handled here.
void CodeTextEditor::_input(const Ref<InputEvent> &event) {
const Ref<InputEventKey> key_event = event;
- if (!key_event.is_valid() || !key_event->is_pressed()) {
+ if (!key_event.is_valid() || !key_event->is_pressed() || !text_editor->has_focus()) {
return;
}
diff --git a/editor/editor_autoload_settings.cpp b/editor/editor_autoload_settings.cpp
index 200ae7045f..da0ff9f18f 100644
--- a/editor/editor_autoload_settings.cpp
+++ b/editor/editor_autoload_settings.cpp
@@ -674,18 +674,18 @@ bool EditorAutoloadSettings::autoload_add(const String &p_name, const String &p_
String error;
if (!_autoload_name_is_valid(name, &error)) {
- EditorNode::get_singleton()->show_warning(error);
+ EditorNode::get_singleton()->show_warning(TTR("Can't add autoload:") + "\n" + error);
return false;
}
const String &path = p_path;
if (!FileAccess::exists(path)) {
- EditorNode::get_singleton()->show_warning(TTR("Invalid path.") + "\n" + TTR("File does not exist."));
+ EditorNode::get_singleton()->show_warning(TTR("Can't add autoload:") + "\n" + TTR(vformat("%s is an invalid path. File does not exist.", path)));
return false;
}
if (!path.begins_with("res://")) {
- EditorNode::get_singleton()->show_warning(TTR("Invalid path.") + "\n" + TTR("Not in resource path."));
+ EditorNode::get_singleton()->show_warning(TTR("Can't add autoload:") + "\n" + TTR(vformat("%s is an invalid path. Not in resource path (res://).", path)));
return false;
}
@@ -912,4 +912,4 @@ void EditorAutoloadSettings::_set_autoload_add_path(const String &p_text) {
void EditorAutoloadSettings::_browse_autoload_add_path() {
file_dialog->popup_centered_ratio();
-} \ No newline at end of file
+}
diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp
index 8b7014fabe..4d69b3f0d6 100644
--- a/editor/editor_node.cpp
+++ b/editor/editor_node.cpp
@@ -4782,7 +4782,7 @@ void EditorNode::set_distraction_free_mode(bool p_enter) {
}
}
-bool EditorNode::get_distraction_free_mode() const {
+bool EditorNode::is_distraction_free_mode_enabled() const {
return distraction_free->is_pressed();
}
diff --git a/editor/editor_node.h b/editor/editor_node.h
index dfe3d91c07..7c9cf44d6c 100644
--- a/editor/editor_node.h
+++ b/editor/editor_node.h
@@ -693,7 +693,7 @@ public:
bool get_docks_visible() const;
void set_distraction_free_mode(bool p_enter);
- bool get_distraction_free_mode() const;
+ bool is_distraction_free_mode_enabled() const;
void add_control_to_dock(DockSlot p_slot, Control *p_control);
void remove_control_from_dock(Control *p_control);
diff --git a/editor/editor_plugin.cpp b/editor/editor_plugin.cpp
index 2365090f03..6d93e92555 100644
--- a/editor/editor_plugin.cpp
+++ b/editor/editor_plugin.cpp
@@ -270,6 +270,10 @@ void EditorInterface::set_distraction_free_mode(bool p_enter) {
EditorNode::get_singleton()->set_distraction_free_mode(p_enter);
}
+bool EditorInterface::is_distraction_free_mode_enabled() const {
+ return EditorNode::get_singleton()->is_distraction_free_mode_enabled();
+}
+
EditorInterface *EditorInterface::singleton = nullptr;
void EditorInterface::_bind_methods() {
@@ -302,6 +306,9 @@ void EditorInterface::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_main_screen_editor", "name"), &EditorInterface::set_main_screen_editor);
ClassDB::bind_method(D_METHOD("set_distraction_free_mode", "enter"), &EditorInterface::set_distraction_free_mode);
+ ClassDB::bind_method(D_METHOD("is_distraction_free_mode_enabled"), &EditorInterface::is_distraction_free_mode_enabled);
+
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "distraction_free_mode"), "set_distraction_free_mode", "is_distraction_free_mode_enabled");
}
EditorInterface::EditorInterface() {
diff --git a/editor/editor_plugin.h b/editor/editor_plugin.h
index 2792c8bf19..aac36bfdfd 100644
--- a/editor/editor_plugin.h
+++ b/editor/editor_plugin.h
@@ -105,6 +105,7 @@ public:
void set_main_screen_editor(const String &p_name);
void set_distraction_free_mode(bool p_enter);
+ bool is_distraction_free_mode_enabled() const;
EditorInterface();
};
diff --git a/editor/import/resource_importer_texture_atlas.cpp b/editor/import/resource_importer_texture_atlas.cpp
index 2848d13160..2423553d22 100644
--- a/editor/import/resource_importer_texture_atlas.cpp
+++ b/editor/import/resource_importer_texture_atlas.cpp
@@ -130,7 +130,8 @@ static void _plot_triangle(Vector2 *vertices, const Vector2 &p_offset, bool p_tr
double dx_low = double(x[2] - x[1]) / (y[2] - y[1] + 1);
double xf = x[0];
double xt = x[0] + dx_upper; // if y[0] == y[1], special case
- for (int yi = y[0]; yi <= (y[2] > height - 1 ? height - 1 : y[2]); yi++) {
+ int max_y = MIN(y[2], height - p_offset.y - 1);
+ for (int yi = y[0]; yi <= max_y; yi++) {
if (yi >= 0) {
for (int xi = (xf > 0 ? int(xf) : 0); xi <= (xt < width ? xt : width - 1); xi++) {
int px = xi, py = yi;
diff --git a/editor/plugins/canvas_item_editor_plugin.cpp b/editor/plugins/canvas_item_editor_plugin.cpp
index 573876c488..59366a239f 100644
--- a/editor/plugins/canvas_item_editor_plugin.cpp
+++ b/editor/plugins/canvas_item_editor_plugin.cpp
@@ -87,7 +87,6 @@ public:
GridContainer *child_container;
set_title(TTR("Configure Snap"));
- get_ok()->set_text(TTR("Close"));
container = memnew(VBoxContainer);
add_child(container);
diff --git a/editor/plugins/collision_shape_2d_editor_plugin.cpp b/editor/plugins/collision_shape_2d_editor_plugin.cpp
index 0f381c06b4..596629f8e8 100644
--- a/editor/plugins/collision_shape_2d_editor_plugin.cpp
+++ b/editor/plugins/collision_shape_2d_editor_plugin.cpp
@@ -36,6 +36,7 @@
#include "scene/resources/concave_polygon_shape_2d.h"
#include "scene/resources/convex_polygon_shape_2d.h"
#include "scene/resources/line_shape_2d.h"
+#include "scene/resources/ray_shape_2d.h"
#include "scene/resources/rectangle_shape_2d.h"
#include "scene/resources/segment_shape_2d.h"
diff --git a/editor/plugins/script_text_editor.cpp b/editor/plugins/script_text_editor.cpp
index e7f8a56e5e..4b79d8c344 100644
--- a/editor/plugins/script_text_editor.cpp
+++ b/editor/plugins/script_text_editor.cpp
@@ -609,6 +609,18 @@ void ScriptTextEditor::_validate_script() {
for (List<ScriptLanguage::Warning>::Element *E = warnings.front(); E; E = E->next()) {
ScriptLanguage::Warning w = E->get();
+ Dictionary ignore_meta;
+ ignore_meta["line"] = w.line;
+ ignore_meta["code"] = w.string_code.to_lower();
+ warnings_panel->push_cell();
+ warnings_panel->push_meta(ignore_meta);
+ warnings_panel->push_color(
+ warnings_panel->get_theme_color("accent_color", "Editor").lerp(warnings_panel->get_theme_color("mono_color", "Editor"), 0.5));
+ warnings_panel->add_text(TTR("[Ignore]"));
+ warnings_panel->pop(); // Color.
+ warnings_panel->pop(); // Meta ignore.
+ warnings_panel->pop(); // Cell.
+
warnings_panel->push_cell();
warnings_panel->push_meta(w.line - 1);
warnings_panel->push_color(warnings_panel->get_theme_color("warning_color", "Editor"));
@@ -621,15 +633,6 @@ void ScriptTextEditor::_validate_script() {
warnings_panel->push_cell();
warnings_panel->add_text(w.message);
warnings_panel->pop(); // Cell.
-
- Dictionary ignore_meta;
- ignore_meta["line"] = w.line;
- ignore_meta["code"] = w.string_code.to_lower();
- warnings_panel->push_cell();
- warnings_panel->push_meta(ignore_meta);
- warnings_panel->add_text(TTR("(ignore)"));
- warnings_panel->pop(); // Meta ignore.
- warnings_panel->pop(); // Cell.
}
warnings_panel->pop(); // Table.
@@ -1747,6 +1750,8 @@ ScriptTextEditor::ScriptTextEditor() {
warnings_panel = memnew(RichTextLabel);
editor_box->add_child(warnings_panel);
+ warnings_panel->add_theme_font_override(
+ "normal_font", EditorNode::get_singleton()->get_gui_base()->get_theme_font("main", "EditorFonts"));
warnings_panel->set_custom_minimum_size(Size2(0, 100 * EDSCALE));
warnings_panel->set_h_size_flags(SIZE_EXPAND_FILL);
warnings_panel->set_meta_underline(true);
diff --git a/editor/plugins/tile_map_editor_plugin.cpp b/editor/plugins/tile_map_editor_plugin.cpp
index 6c037f94a0..3281a59c1c 100644
--- a/editor/plugins/tile_map_editor_plugin.cpp
+++ b/editor/plugins/tile_map_editor_plugin.cpp
@@ -194,6 +194,21 @@ void TileMapEditor::_palette_multi_selected(int index, bool selected) {
_update_palette();
}
+void TileMapEditor::_palette_input(const Ref<InputEvent> &p_event) {
+ const Ref<InputEventMouseButton> mb = p_event;
+
+ // Zoom in/out using Ctrl + mouse wheel.
+ if (mb.is_valid() && mb->is_pressed() && mb->get_command()) {
+ if (mb->is_pressed() && mb->get_button_index() == BUTTON_WHEEL_UP) {
+ size_slider->set_value(size_slider->get_value() + 0.2);
+ }
+
+ if (mb->is_pressed() && mb->get_button_index() == BUTTON_WHEEL_DOWN) {
+ size_slider->set_value(size_slider->get_value() - 0.2);
+ }
+ }
+}
+
void TileMapEditor::_canvas_mouse_enter() {
mouse_over = true;
CanvasItemEditor::get_singleton()->update_viewport();
@@ -1913,6 +1928,7 @@ TileMapEditor::TileMapEditor(EditorNode *p_editor) {
palette->add_theme_constant_override("vseparation", 8 * EDSCALE);
palette->connect("item_selected", callable_mp(this, &TileMapEditor::_palette_selected));
palette->connect("multi_selected", callable_mp(this, &TileMapEditor::_palette_multi_selected));
+ palette->connect("gui_input", callable_mp(this, &TileMapEditor::_palette_input));
palette_container->add_child(palette);
// Add message for when no texture is selected.
diff --git a/editor/plugins/tile_map_editor_plugin.h b/editor/plugins/tile_map_editor_plugin.h
index 5f82d7bfb8..e25e2d2add 100644
--- a/editor/plugins/tile_map_editor_plugin.h
+++ b/editor/plugins/tile_map_editor_plugin.h
@@ -182,6 +182,7 @@ class TileMapEditor : public VBoxContainer {
void _menu_option(int p_option);
void _palette_selected(int index);
void _palette_multi_selected(int index, bool selected);
+ void _palette_input(const Ref<InputEvent> &p_event);
Dictionary _create_cell_dictionary(int tile, bool flip_x, bool flip_y, bool transpose, Vector2 autotile_coord);
void _start_undo(const String &p_action);
diff --git a/editor/plugins/tile_set_editor_plugin.cpp b/editor/plugins/tile_set_editor_plugin.cpp
index 644facd5bd..b3d4b391d3 100644
--- a/editor/plugins/tile_set_editor_plugin.cpp
+++ b/editor/plugins/tile_set_editor_plugin.cpp
@@ -569,6 +569,7 @@ TileSetEditor::TileSetEditor(EditorNode *p_editor) {
scroll = memnew(ScrollContainer);
main_vb->add_child(scroll);
scroll->set_v_size_flags(SIZE_EXPAND_FILL);
+ scroll->connect("gui_input", callable_mp(this, &TileSetEditor::_on_scroll_container_input));
scroll->set_clip_contents(true);
empty_message = memnew(Label);
@@ -1198,6 +1199,27 @@ bool TileSetEditor::is_within_grabbing_distance_of_first_point(const Vector2 &p_
return distance < p_grab_threshold;
}
+void TileSetEditor::_on_scroll_container_input(const Ref<InputEvent> &p_event) {
+ const Ref<InputEventMouseButton> mb = p_event;
+
+ if (mb.is_valid()) {
+ // Zoom in/out using Ctrl + mouse wheel. This is done on the ScrollContainer
+ // to allow performing this action anywhere, even if the cursor isn't
+ // hovering the texture in the workspace.
+ if (mb->get_button_index() == BUTTON_WHEEL_UP && mb->is_pressed() && mb->get_control()) {
+ print_line("zooming in");
+ _zoom_in();
+ // Don't scroll up after zooming in.
+ accept_event();
+ } else if (mb->get_button_index() == BUTTON_WHEEL_DOWN && mb->is_pressed() && mb->get_control()) {
+ print_line("zooming out");
+ _zoom_out();
+ // Don't scroll down after zooming out.
+ accept_event();
+ }
+ }
+}
+
void TileSetEditor::_on_workspace_input(const Ref<InputEvent> &p_ie) {
if (tileset.is_null() || !get_current_texture().is_valid()) {
return;
@@ -1214,8 +1236,8 @@ void TileSetEditor::_on_workspace_input(const Ref<InputEvent> &p_ie) {
}
current_tile_region.position += WORKSPACE_MARGIN;
- Ref<InputEventMouseButton> mb = p_ie;
- Ref<InputEventMouseMotion> mm = p_ie;
+ const Ref<InputEventMouseButton> mb = p_ie;
+ const Ref<InputEventMouseMotion> mm = p_ie;
if (mb.is_valid()) {
if (mb->is_pressed() && mb->get_button_index() == BUTTON_LEFT && !creating_shape) {
@@ -1239,13 +1261,6 @@ void TileSetEditor::_on_workspace_input(const Ref<InputEvent> &p_ie) {
delete tiles;
}
}
-
- // Mouse Wheel Event
- if (mb->get_button_index() == BUTTON_WHEEL_UP && mb->is_pressed() && mb->get_control()) {
- _zoom_in();
- } else if (mb->get_button_index() == BUTTON_WHEEL_DOWN && mb->is_pressed() && mb->get_control()) {
- _zoom_out();
- }
}
// Drag Middle Mouse
if (mm.is_valid()) {
diff --git a/editor/plugins/tile_set_editor_plugin.h b/editor/plugins/tile_set_editor_plugin.h
index 827325cfd7..2955dda244 100644
--- a/editor/plugins/tile_set_editor_plugin.h
+++ b/editor/plugins/tile_set_editor_plugin.h
@@ -200,6 +200,7 @@ private:
void _on_workspace_overlay_draw();
void _on_workspace_draw();
void _on_workspace_process();
+ void _on_scroll_container_input(const Ref<InputEvent> &p_event);
void _on_workspace_input(const Ref<InputEvent> &p_ie);
void _on_tool_clicked(int p_tool);
void _on_priority_changed(float val);
diff --git a/editor/project_manager.cpp b/editor/project_manager.cpp
index dc5ff6a5eb..499f7d4017 100644
--- a/editor/project_manager.cpp
+++ b/editor/project_manager.cpp
@@ -916,6 +916,8 @@ public:
icon = nullptr;
icon_needs_reload = true;
hover = false;
+
+ set_focus_mode(FocusMode::FOCUS_ALL);
}
void set_is_favorite(bool fav) {
@@ -1739,6 +1741,10 @@ void ProjectList::_panel_input(const Ref<InputEvent> &p_ev, Node *p_hb) {
select_project(clicked_index);
}
+ if (_selected_project_keys.has(clicked_project.project_key)) {
+ clicked_project.control->grab_focus();
+ }
+
emit_signal(SIGNAL_SELECTION_CHANGED);
if (!mb->get_control() && mb->is_doubleclick()) {
diff --git a/editor/scene_tree_dock.cpp b/editor/scene_tree_dock.cpp
index a81a2ff4e9..c37d32b26b 100644
--- a/editor/scene_tree_dock.cpp
+++ b/editor/scene_tree_dock.cpp
@@ -2557,6 +2557,11 @@ void SceneTreeDock::_focus_node() {
}
void SceneTreeDock::attach_script_to_selected(bool p_extend) {
+ if (ScriptServer::get_language_count() == 0) {
+ EditorNode::get_singleton()->show_warning(TTR("Cannot attach a script: there are no languages registered.\nThis is probably because this editor was built with all language modules disabled."));
+ return;
+ }
+
if (!profile_allow_script_editing) {
return;
}
diff --git a/editor/script_create_dialog.cpp b/editor/script_create_dialog.cpp
index 04fbfdff9d..ae5229b628 100644
--- a/editor/script_create_dialog.cpp
+++ b/editor/script_create_dialog.cpp
@@ -783,7 +783,7 @@ ScriptCreateDialog::ScriptCreateDialog() {
gc->add_child(memnew(Label(TTR("Language:"))));
gc->add_child(language_menu);
- default_language = 0;
+ default_language = -1;
for (int i = 0; i < ScriptServer::get_language_count(); i++) {
String lang = ScriptServer::get_language(i)->get_name();
language_menu->add_item(lang);
@@ -791,8 +791,9 @@ ScriptCreateDialog::ScriptCreateDialog() {
default_language = i;
}
}
-
- language_menu->select(default_language);
+ if (default_language >= 0) {
+ language_menu->select(default_language);
+ }
current_language = default_language;
language_menu->connect("item_selected", callable_mp(this, &ScriptCreateDialog::_lang_changed));
diff --git a/methods.py b/methods.py
index c1245cd95a..756db19e9a 100644
--- a/methods.py
+++ b/methods.py
@@ -231,6 +231,30 @@ def disable_module(self):
self.disabled_modules.append(self.current_module)
+def module_check_dependencies(self, module, dependencies):
+ """
+ Checks if module dependencies are enabled for a given module,
+ and prints a warning if they aren't.
+ Meant to be used in module `can_build` methods.
+ Returns a boolean (True if dependencies are satisfied).
+ """
+ missing_deps = []
+ for dep in dependencies:
+ opt = "module_{}_enabled".format(dep)
+ if not opt in self or not self[opt]:
+ missing_deps.append(dep)
+
+ if missing_deps != []:
+ print(
+ "Disabling '{}' module as the following dependencies are not satisfied: {}".format(
+ module, ", ".join(missing_deps)
+ )
+ )
+ return False
+ else:
+ return True
+
+
def use_windows_spawn_fix(self, platform=None):
if os.name != "nt":
diff --git a/modules/opus/config.py b/modules/opus/config.py
index d22f9454ed..9ff7b2dece 100644
--- a/modules/opus/config.py
+++ b/modules/opus/config.py
@@ -1,5 +1,5 @@
def can_build(env, platform):
- return True
+ return env.module_check_dependencies("opus", ["ogg"])
def configure(env):
diff --git a/modules/theora/config.py b/modules/theora/config.py
index 413acce2df..b063ed51f9 100644
--- a/modules/theora/config.py
+++ b/modules/theora/config.py
@@ -1,5 +1,5 @@
def can_build(env, platform):
- return True
+ return env.module_check_dependencies("theora", ["ogg", "vorbis"])
def configure(env):
diff --git a/modules/vorbis/config.py b/modules/vorbis/config.py
index d22f9454ed..8a384e3066 100644
--- a/modules/vorbis/config.py
+++ b/modules/vorbis/config.py
@@ -1,5 +1,5 @@
def can_build(env, platform):
- return True
+ return env.module_check_dependencies("vorbis", ["ogg"])
def configure(env):
diff --git a/modules/webm/config.py b/modules/webm/config.py
index 93b49d177a..99f8ace114 100644
--- a/modules/webm/config.py
+++ b/modules/webm/config.py
@@ -1,5 +1,8 @@
def can_build(env, platform):
- return platform not in ["iphone"]
+ if platform in ["iphone"]:
+ return False
+
+ return env.module_check_dependencies("webm", ["ogg", "opus", "vorbis"])
def configure(env):
diff --git a/platform/android/export/export.cpp b/platform/android/export/export.cpp
index b678bbb886..3579b5a112 100644
--- a/platform/android/export/export.cpp
+++ b/platform/android/export/export.cpp
@@ -1729,23 +1729,32 @@ public:
// Look for export templates (first official, and if defined custom templates).
if (!bool(p_preset->get("custom_template/use_custom_build"))) {
- bool dvalid = exists_export_template("android_debug.apk", &err);
- bool rvalid = exists_export_template("android_release.apk", &err);
+ String template_err;
+ bool dvalid = false;
+ bool rvalid = false;
if (p_preset->get("custom_template/debug") != "") {
dvalid = FileAccess::exists(p_preset->get("custom_template/debug"));
if (!dvalid) {
- err += TTR("Custom debug template not found.") + "\n";
+ template_err += TTR("Custom debug template not found.") + "\n";
}
+ } else {
+ dvalid = exists_export_template("android_debug.apk", &template_err);
}
+
if (p_preset->get("custom_template/release") != "") {
rvalid = FileAccess::exists(p_preset->get("custom_template/release"));
if (!rvalid) {
- err += TTR("Custom release template not found.") + "\n";
+ template_err += TTR("Custom release template not found.") + "\n";
}
+ } else {
+ rvalid = exists_export_template("android_release.apk", &template_err);
}
valid = dvalid || rvalid;
+ if (!valid) {
+ err += template_err;
+ }
} else {
valid = exists_export_template("android_source.zip", &err);
}
diff --git a/platform/osx/joypad_osx.cpp b/platform/osx/joypad_osx.cpp
index d342d30097..cfc371710b 100644
--- a/platform/osx/joypad_osx.cpp
+++ b/platform/osx/joypad_osx.cpp
@@ -311,9 +311,16 @@ bool JoypadOSX::configure_joypad(IOHIDDeviceRef p_device_ref, joypad *p_joy) {
if (refCF) {
CFNumberGetValue((CFNumberRef)refCF, kCFNumberSInt32Type, &product_id);
}
+
+ int version = 0;
+ refCF = IOHIDDeviceGetProperty(p_device_ref, CFSTR(kIOHIDVersionNumberKey));
+ if (refCF) {
+ CFNumberGetValue((CFNumberRef)refCF, kCFNumberSInt32Type, &version);
+ }
+
if (vendor && product_id) {
char uid[128];
- sprintf(uid, "%04x%08x%04x%08x", OSSwapHostToBigInt32(vendor), 0, OSSwapHostToBigInt32(product_id), 0);
+ sprintf(uid, "%08x%08x%08x%08x", OSSwapHostToBigInt32(3), OSSwapHostToBigInt32(vendor), OSSwapHostToBigInt32(product_id), OSSwapHostToBigInt32(version));
input->joy_connection_changed(id, true, name, uid);
} else {
//bluetooth device
diff --git a/scene/3d/light_3d.cpp b/scene/3d/light_3d.cpp
index 814e911372..ef24676d69 100644
--- a/scene/3d/light_3d.cpp
+++ b/scene/3d/light_3d.cpp
@@ -402,7 +402,7 @@ void DirectionalLight3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("is_blend_splits_enabled"), &DirectionalLight3D::is_blend_splits_enabled);
ADD_GROUP("Directional Shadow", "directional_shadow_");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "directional_shadow_mode", PROPERTY_HINT_ENUM, "Orthogonal,PSSM 2 Splits,PSSM 4 Splits"), "set_shadow_mode", "get_shadow_mode");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "directional_shadow_mode", PROPERTY_HINT_ENUM, "Orthogonal (Fast),PSSM 2 Splits (Average),PSSM 4 Splits (Slow)"), "set_shadow_mode", "get_shadow_mode");
ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "directional_shadow_split_1", PROPERTY_HINT_RANGE, "0,1,0.001"), "set_param", "get_param", PARAM_SHADOW_SPLIT_1_OFFSET);
ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "directional_shadow_split_2", PROPERTY_HINT_RANGE, "0,1,0.001"), "set_param", "get_param", PARAM_SHADOW_SPLIT_2_OFFSET);
ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "directional_shadow_split_3", PROPERTY_HINT_RANGE, "0,1,0.001"), "set_param", "get_param", PARAM_SHADOW_SPLIT_3_OFFSET);
diff --git a/scene/gui/rich_text_label.cpp b/scene/gui/rich_text_label.cpp
index a57408b83b..2f5af0eda0 100644
--- a/scene/gui/rich_text_label.cpp
+++ b/scene/gui/rich_text_label.cpp
@@ -256,6 +256,11 @@ int RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int &
lh = line < l.height_caches.size() ? l.height_caches[line] : 1; \
line_ascent = line < l.ascent_caches.size() ? l.ascent_caches[line] : 1; \
line_descent = line < l.descent_caches.size() ? l.descent_caches[line] : 1; \
+ if (p_mode == PROCESS_DRAW) { \
+ if (line < l.offset_caches.size()) { \
+ wofs = l.offset_caches[line]; \
+ } \
+ } \
} \
if (p_mode == PROCESS_POINTER && r_click_item && p_click_pos.y >= p_ofs.y + y && p_click_pos.y <= p_ofs.y + y + lh && p_click_pos.x < p_ofs.x + wofs) { \
if (r_outside) \
@@ -646,7 +651,7 @@ int RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int &
}
if (p_mode == PROCESS_DRAW && visible) {
- img->image->draw_rect(ci, Rect2(p_ofs + Point2(align_ofs + wofs, y + lh - font->get_descent() - img->size.height), img->size));
+ img->image->draw_rect(ci, Rect2(p_ofs + Point2(align_ofs + wofs, y + lh - font->get_descent() - img->size.height), img->size), false, img->color);
}
p_char_count++;
@@ -873,7 +878,7 @@ int RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int &
}
void RichTextLabel::_scroll_changed(double) {
- if (updating_scroll || !scroll_active) {
+ if (updating_scroll) {
return;
}
@@ -1443,6 +1448,46 @@ void RichTextLabel::_fetch_item_fx_stack(Item *p_item, Vector<ItemFX *> &r_stack
}
}
+Color RichTextLabel::_get_color_from_string(const String &p_color_str, const Color &p_default_color) {
+ if (p_color_str.begins_with("#")) {
+ return Color::html(p_color_str);
+ } else if (p_color_str == "aqua") {
+ return Color(0, 1, 1);
+ } else if (p_color_str == "black") {
+ return Color(0, 0, 0);
+ } else if (p_color_str == "blue") {
+ return Color(0, 0, 1);
+ } else if (p_color_str == "fuchsia") {
+ return Color(1, 0, 1);
+ } else if (p_color_str == "gray" || p_color_str == "grey") {
+ return Color(0.5, 0.5, 0.5);
+ } else if (p_color_str == "green") {
+ return Color(0, 0.5, 0);
+ } else if (p_color_str == "lime") {
+ return Color(0, 1, 0);
+ } else if (p_color_str == "maroon") {
+ return Color(0.5, 0, 0);
+ } else if (p_color_str == "navy") {
+ return Color(0, 0, 0.5);
+ } else if (p_color_str == "olive") {
+ return Color(0.5, 0.5, 0);
+ } else if (p_color_str == "purple") {
+ return Color(0.5, 0, 0.5);
+ } else if (p_color_str == "red") {
+ return Color(1, 0, 0);
+ } else if (p_color_str == "silver") {
+ return Color(0.75, 0.75, 0.75);
+ } else if (p_color_str == "teal") {
+ return Color(0, 0.5, 0.5);
+ } else if (p_color_str == "white") {
+ return Color(1, 1, 1);
+ } else if (p_color_str == "yellow") {
+ return Color(1, 1, 0);
+ } else {
+ return p_default_color;
+ }
+}
+
bool RichTextLabel::_find_meta(Item *p_item, Variant *r_meta, ItemMeta **r_item) {
Item *item = p_item;
@@ -1636,7 +1681,7 @@ void RichTextLabel::_remove_item(Item *p_item, const int p_line, const int p_sub
}
}
-void RichTextLabel::add_image(const Ref<Texture2D> &p_image, const int p_width, const int p_height) {
+void RichTextLabel::add_image(const Ref<Texture2D> &p_image, const int p_width, const int p_height, const Color &p_color) {
if (current->type == ITEM_TABLE) {
return;
}
@@ -1645,6 +1690,7 @@ void RichTextLabel::add_image(const Ref<Texture2D> &p_image, const int p_width,
ItemImage *item = memnew(ItemImage);
item->image = p_image;
+ item->color = p_color;
if (p_width > 0) {
// custom width
@@ -1967,6 +2013,7 @@ void RichTextLabel::set_scroll_active(bool p_active) {
}
scroll_active = p_active;
+ vscroll->set_drag_node_enabled(p_active);
update();
}
@@ -2034,7 +2081,32 @@ Error RichTextLabel::append_bbcode(const String &p_bbcode) {
String tag = p_bbcode.substr(brk_pos + 1, brk_end - brk_pos - 1);
Vector<String> split_tag_block = tag.split(" ", false);
- String bbcode = !split_tag_block.empty() ? split_tag_block[0] : "";
+
+ // Find optional parameters.
+ String bbcode_name;
+ typedef Map<String, String> OptionMap;
+ OptionMap bbcode_options;
+ if (!split_tag_block.empty()) {
+ bbcode_name = split_tag_block[0];
+ for (int i = 1; i < split_tag_block.size(); i++) {
+ const String &expr = split_tag_block[i];
+ int value_pos = expr.find("=");
+ if (value_pos > -1) {
+ bbcode_options[expr.substr(0, value_pos)] = expr.substr(value_pos + 1);
+ }
+ }
+ } else {
+ bbcode_name = tag;
+ }
+
+ // Find main parameter.
+ String bbcode_value;
+ int main_value_pos = bbcode_name.find("=");
+ if (main_value_pos > -1) {
+ bbcode_value = bbcode_name.substr(main_value_pos + 1);
+ bbcode_name = bbcode_name.substr(0, main_value_pos);
+ }
+
if (tag.begins_with("/") && tag_stack.size()) {
bool tag_ok = tag_stack.size() && tag_stack.front()->get() == tag.substr(1, tag.length());
@@ -2160,7 +2232,7 @@ Error RichTextLabel::append_bbcode(const String &p_bbcode) {
push_meta(url);
pos = brk_end + 1;
tag_stack.push_front("url");
- } else if (tag == "img") {
+ } else if (bbcode_name == "img") {
int end = p_bbcode.find("[", brk_end);
if (end == -1) {
end = p_bbcode.length();
@@ -2170,80 +2242,42 @@ Error RichTextLabel::append_bbcode(const String &p_bbcode) {
Ref<Texture2D> texture = ResourceLoader::load(image, "Texture2D");
if (texture.is_valid()) {
- add_image(texture);
- }
-
- pos = end;
- tag_stack.push_front(tag);
- } else if (tag.begins_with("img=")) {
- int width = 0;
- int height = 0;
-
- String params = tag.substr(4, tag.length());
- int sep = params.find("x");
- if (sep == -1) {
- width = params.to_int();
- } else {
- width = params.substr(0, sep).to_int();
- height = params.substr(sep + 1, params.length()).to_int();
- }
+ Color color = Color(1.0, 1.0, 1.0);
+ OptionMap::Element *color_option = bbcode_options.find("color");
+ if (color_option) {
+ color = _get_color_from_string(color_option->value(), color);
+ }
- int end = p_bbcode.find("[", brk_end);
- if (end == -1) {
- end = p_bbcode.length();
- }
+ int width = 0;
+ int height = 0;
+ if (!bbcode_value.empty()) {
+ int sep = bbcode_value.find("x");
+ if (sep == -1) {
+ width = bbcode_value.to_int();
+ } else {
+ width = bbcode_value.substr(0, sep).to_int();
+ height = bbcode_value.substr(sep + 1).to_int();
+ }
+ } else {
+ OptionMap::Element *width_option = bbcode_options.find("width");
+ if (width_option) {
+ width = width_option->value().to_int();
+ }
- String image = p_bbcode.substr(brk_end + 1, end - brk_end - 1);
+ OptionMap::Element *height_option = bbcode_options.find("height");
+ if (height_option) {
+ height = height_option->value().to_int();
+ }
+ }
- Ref<Texture2D> texture = ResourceLoader::load(image, "Texture");
- if (texture.is_valid()) {
- add_image(texture, width, height);
+ add_image(texture, width, height, color);
}
pos = end;
- tag_stack.push_front("img");
+ tag_stack.push_front(bbcode_name);
} else if (tag.begins_with("color=")) {
- String col = tag.substr(6, tag.length());
- Color color;
-
- if (col.begins_with("#")) {
- color = Color::html(col);
- } else if (col == "aqua") {
- color = Color(0, 1, 1);
- } else if (col == "black") {
- color = Color(0, 0, 0);
- } else if (col == "blue") {
- color = Color(0, 0, 1);
- } else if (col == "fuchsia") {
- color = Color(1, 0, 1);
- } else if (col == "gray" || col == "grey") {
- color = Color(0.5, 0.5, 0.5);
- } else if (col == "green") {
- color = Color(0, 0.5, 0);
- } else if (col == "lime") {
- color = Color(0, 1, 0);
- } else if (col == "maroon") {
- color = Color(0.5, 0, 0);
- } else if (col == "navy") {
- color = Color(0, 0, 0.5);
- } else if (col == "olive") {
- color = Color(0.5, 0.5, 0);
- } else if (col == "purple") {
- color = Color(0.5, 0, 0.5);
- } else if (col == "red") {
- color = Color(1, 0, 0);
- } else if (col == "silver") {
- color = Color(0.75, 0.75, 0.75);
- } else if (col == "teal") {
- color = Color(0, 0.5, 0.5);
- } else if (col == "white") {
- color = Color(1, 1, 1);
- } else if (col == "yellow") {
- color = Color(1, 1, 0);
- } else {
- color = base_color;
- }
-
+ String color_str = tag.substr(6, tag.length());
+ Color color = _get_color_from_string(color_str, base_color);
push_color(color);
pos = brk_end + 1;
tag_stack.push_front("color");
@@ -2261,113 +2295,90 @@ Error RichTextLabel::append_bbcode(const String &p_bbcode) {
pos = brk_end + 1;
tag_stack.push_front("font");
- } else if (bbcode == "fade") {
- int startIndex = 0;
- int length = 10;
+ } else if (bbcode_name == "fade") {
+ int start_index = 0;
+ OptionMap::Element *start_option = bbcode_options.find("start");
+ if (start_option) {
+ start_index = start_option->value().to_int();
+ }
- if (split_tag_block.size() > 1) {
- split_tag_block.remove(0);
- for (int i = 0; i < split_tag_block.size(); i++) {
- String expr = split_tag_block[i];
- if (expr.begins_with("start=")) {
- String start_str = expr.substr(6, expr.length());
- startIndex = start_str.to_int();
- } else if (expr.begins_with("length=")) {
- String end_str = expr.substr(7, expr.length());
- length = end_str.to_int();
- }
- }
+ int length = 10;
+ OptionMap::Element *length_option = bbcode_options.find("length");
+ if (length_option) {
+ length = length_option->value().to_int();
}
- push_fade(startIndex, length);
+ push_fade(start_index, length);
pos = brk_end + 1;
tag_stack.push_front("fade");
- } else if (bbcode == "shake") {
+ } else if (bbcode_name == "shake") {
int strength = 5;
- float rate = 20.0f;
+ OptionMap::Element *strength_option = bbcode_options.find("level");
+ if (strength_option) {
+ strength = strength_option->value().to_int();
+ }
- if (split_tag_block.size() > 1) {
- split_tag_block.remove(0);
- for (int i = 0; i < split_tag_block.size(); i++) {
- String expr = split_tag_block[i];
- if (expr.begins_with("level=")) {
- String str_str = expr.substr(6, expr.length());
- strength = str_str.to_int();
- } else if (expr.begins_with("rate=")) {
- String rate_str = expr.substr(5, expr.length());
- rate = rate_str.to_float();
- }
- }
+ float rate = 20.0f;
+ OptionMap::Element *rate_option = bbcode_options.find("rate");
+ if (rate_option) {
+ rate = rate_option->value().to_float();
}
push_shake(strength, rate);
pos = brk_end + 1;
tag_stack.push_front("shake");
set_process_internal(true);
- } else if (bbcode == "wave") {
+ } else if (bbcode_name == "wave") {
float amplitude = 20.0f;
- float period = 5.0f;
+ OptionMap::Element *amplitude_option = bbcode_options.find("amp");
+ if (amplitude_option) {
+ amplitude = amplitude_option->value().to_float();
+ }
- if (split_tag_block.size() > 1) {
- split_tag_block.remove(0);
- for (int i = 0; i < split_tag_block.size(); i++) {
- String expr = split_tag_block[i];
- if (expr.begins_with("amp=")) {
- String amp_str = expr.substr(4, expr.length());
- amplitude = amp_str.to_float();
- } else if (expr.begins_with("freq=")) {
- String period_str = expr.substr(5, expr.length());
- period = period_str.to_float();
- }
- }
+ float period = 5.0f;
+ OptionMap::Element *period_option = bbcode_options.find("freq");
+ if (period_option) {
+ period = period_option->value().to_float();
}
push_wave(period, amplitude);
pos = brk_end + 1;
tag_stack.push_front("wave");
set_process_internal(true);
- } else if (bbcode == "tornado") {
+ } else if (bbcode_name == "tornado") {
float radius = 10.0f;
- float frequency = 1.0f;
+ OptionMap::Element *radius_option = bbcode_options.find("radius");
+ if (radius_option) {
+ radius = radius_option->value().to_float();
+ }
- if (split_tag_block.size() > 1) {
- split_tag_block.remove(0);
- for (int i = 0; i < split_tag_block.size(); i++) {
- String expr = split_tag_block[i];
- if (expr.begins_with("radius=")) {
- String amp_str = expr.substr(7, expr.length());
- radius = amp_str.to_float();
- } else if (expr.begins_with("freq=")) {
- String period_str = expr.substr(5, expr.length());
- frequency = period_str.to_float();
- }
- }
+ float frequency = 1.0f;
+ OptionMap::Element *frequency_option = bbcode_options.find("freq");
+ if (frequency_option) {
+ frequency = frequency_option->value().to_float();
}
push_tornado(frequency, radius);
pos = brk_end + 1;
tag_stack.push_front("tornado");
set_process_internal(true);
- } else if (bbcode == "rainbow") {
+ } else if (bbcode_name == "rainbow") {
float saturation = 0.8f;
+ OptionMap::Element *saturation_option = bbcode_options.find("sat");
+ if (saturation_option) {
+ saturation = saturation_option->value().to_float();
+ }
+
float value = 0.8f;
- float frequency = 1.0f;
+ OptionMap::Element *value_option = bbcode_options.find("val");
+ if (value_option) {
+ value = value_option->value().to_float();
+ }
- if (split_tag_block.size() > 1) {
- split_tag_block.remove(0);
- for (int i = 0; i < split_tag_block.size(); i++) {
- String expr = split_tag_block[i];
- if (expr.begins_with("sat=")) {
- String sat_str = expr.substr(4, expr.length());
- saturation = sat_str.to_float();
- } else if (expr.begins_with("val=")) {
- String val_str = expr.substr(4, expr.length());
- value = val_str.to_float();
- } else if (expr.begins_with("freq=")) {
- String freq_str = expr.substr(5, expr.length());
- frequency = freq_str.to_float();
- }
- }
+ float frequency = 1.0f;
+ OptionMap::Element *frequency_option = bbcode_options.find("freq");
+ if (frequency_option) {
+ frequency = frequency_option->value().to_float();
}
push_rainbow(saturation, value, frequency);
@@ -2634,7 +2645,7 @@ void RichTextLabel::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_text"), &RichTextLabel::get_text);
ClassDB::bind_method(D_METHOD("add_text", "text"), &RichTextLabel::add_text);
ClassDB::bind_method(D_METHOD("set_text", "text"), &RichTextLabel::set_text);
- ClassDB::bind_method(D_METHOD("add_image", "image", "width", "height"), &RichTextLabel::add_image, DEFVAL(0), DEFVAL(0));
+ ClassDB::bind_method(D_METHOD("add_image", "image", "width", "height", "color"), &RichTextLabel::add_image, DEFVAL(0), DEFVAL(0), DEFVAL(Color(1.0, 1.0, 1.0)));
ClassDB::bind_method(D_METHOD("newline"), &RichTextLabel::add_newline);
ClassDB::bind_method(D_METHOD("remove_line", "line"), &RichTextLabel::remove_line);
ClassDB::bind_method(D_METHOD("push_font", "font"), &RichTextLabel::push_font);
diff --git a/scene/gui/rich_text_label.h b/scene/gui/rich_text_label.h
index 019edf5d45..4cec435568 100644
--- a/scene/gui/rich_text_label.h
+++ b/scene/gui/rich_text_label.h
@@ -149,6 +149,7 @@ private:
struct ItemImage : public Item {
Ref<Texture2D> image;
Size2 size;
+ Color color;
ItemImage() { type = ITEM_IMAGE; }
};
@@ -381,6 +382,8 @@ private:
bool _find_by_type(Item *p_item, ItemType p_type);
void _fetch_item_fx_stack(Item *p_item, Vector<ItemFX *> &r_stack);
+ static Color _get_color_from_string(const String &p_color_str, const Color &p_default_color);
+
void _update_scroll();
void _update_fx(ItemFrame *p_frame, float p_delta_time);
void _scroll_changed(double);
@@ -406,7 +409,7 @@ protected:
public:
String get_text();
void add_text(const String &p_text);
- void add_image(const Ref<Texture2D> &p_image, const int p_width = 0, const int p_height = 0);
+ void add_image(const Ref<Texture2D> &p_image, const int p_width = 0, const int p_height = 0, const Color &p_color = Color(1.0, 1.0, 1.0));
void add_newline();
bool remove_line(const int p_line);
void push_font(const Ref<Font> &p_font);
diff --git a/scene/gui/scroll_bar.cpp b/scene/gui/scroll_bar.cpp
index e7950bec98..4db6ca2949 100644
--- a/scene/gui/scroll_bar.cpp
+++ b/scene/gui/scroll_bar.cpp
@@ -506,6 +506,10 @@ void ScrollBar::_drag_node_exit() {
}
void ScrollBar::_drag_node_input(const Ref<InputEvent> &p_input) {
+ if (!drag_node_enabled) {
+ return;
+ }
+
Ref<InputEventMouseButton> mb = p_input;
if (mb.is_valid()) {
@@ -590,6 +594,10 @@ NodePath ScrollBar::get_drag_node() const {
return drag_node_path;
}
+void ScrollBar::set_drag_node_enabled(bool p_enable) {
+ drag_node_enabled = p_enable;
+}
+
void ScrollBar::set_smooth_scroll_enabled(bool p_enable) {
smooth_scroll_enabled = p_enable;
}
@@ -610,19 +618,6 @@ void ScrollBar::_bind_methods() {
ScrollBar::ScrollBar(Orientation p_orientation) {
orientation = p_orientation;
- highlight = HIGHLIGHT_NONE;
- custom_step = -1;
- drag_node = nullptr;
-
- drag.active = false;
-
- drag_node_speed = Vector2();
- drag_node_touching = false;
- drag_node_touching_deaccel = false;
-
- scrolling = false;
- target_scroll = 0;
- smooth_scroll_enabled = false;
if (focus_by_default) {
set_focus_mode(FOCUS_ALL);
diff --git a/scene/gui/scroll_bar.h b/scene/gui/scroll_bar.h
index d2641b14f3..23ee61d9e1 100644
--- a/scene/gui/scroll_bar.h
+++ b/scene/gui/scroll_bar.h
@@ -47,12 +47,12 @@ class ScrollBar : public Range {
Orientation orientation;
Size2 size;
- float custom_step;
+ float custom_step = -1;
- HighlightStatus highlight;
+ HighlightStatus highlight = HIGHLIGHT_NONE;
struct Drag {
- bool active;
+ bool active = false;
float pos_at_click;
float value_at_click;
} drag;
@@ -66,22 +66,23 @@ class ScrollBar : public Range {
static void set_can_focus_by_default(bool p_can_focus);
- Node *drag_node;
+ Node *drag_node = nullptr;
NodePath drag_node_path;
+ bool drag_node_enabled = true;
- Vector2 drag_node_speed;
+ Vector2 drag_node_speed = Vector2();
Vector2 drag_node_accum;
Vector2 drag_node_from;
Vector2 last_drag_node_accum;
float last_drag_node_time;
float time_since_motion;
- bool drag_node_touching;
- bool drag_node_touching_deaccel;
+ bool drag_node_touching = false;
+ bool drag_node_touching_deaccel = false;
bool click_handled;
- bool scrolling;
- double target_scroll;
- bool smooth_scroll_enabled;
+ bool scrolling = false;
+ double target_scroll = 0;
+ bool smooth_scroll_enabled = false;
void _drag_node_exit();
void _drag_node_input(const Ref<InputEvent> &p_input);
@@ -99,6 +100,7 @@ public:
void set_drag_node(const NodePath &p_path);
NodePath get_drag_node() const;
+ void set_drag_node_enabled(bool p_enable);
void set_smooth_scroll_enabled(bool p_enable);
bool is_smooth_scroll_enabled() const;
diff --git a/scene/register_scene_types.cpp b/scene/register_scene_types.cpp
index 5588d1bd97..2d0e2daf41 100644
--- a/scene/register_scene_types.cpp
+++ b/scene/register_scene_types.cpp
@@ -154,6 +154,7 @@
#include "scene/resources/physics_material.h"
#include "scene/resources/polygon_path_finder.h"
#include "scene/resources/primitive_meshes.h"
+#include "scene/resources/ray_shape_2d.h"
#include "scene/resources/ray_shape_3d.h"
#include "scene/resources/rectangle_shape_2d.h"
#include "scene/resources/resource_format_text.h"
diff --git a/scene/resources/dynamic_font.cpp b/scene/resources/dynamic_font.cpp
index 3b4e4b73f8..3d99556a10 100644
--- a/scene/resources/dynamic_font.cpp
+++ b/scene/resources/dynamic_font.cpp
@@ -567,7 +567,7 @@ DynamicFontAtSize::Character DynamicFontAtSize::_make_outline_char(CharType p_ch
if (FT_Glyph_Stroke(&glyph, stroker, 1) != 0) {
goto cleanup_glyph;
}
- if (FT_Glyph_To_Bitmap(&glyph, FT_RENDER_MODE_NORMAL, nullptr, 1) != 0) {
+ if (FT_Glyph_To_Bitmap(&glyph, font->antialiased ? FT_RENDER_MODE_NORMAL : FT_RENDER_MODE_MONO, nullptr, 1) != 0) {
goto cleanup_glyph;
}
diff --git a/scene/resources/primitive_meshes.cpp b/scene/resources/primitive_meshes.cpp
index 99edf26dc1..8d9c5f07b2 100644
--- a/scene/resources/primitive_meshes.cpp
+++ b/scene/resources/primitive_meshes.cpp
@@ -204,7 +204,7 @@ void PrimitiveMesh::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_flip_faces", "flip_faces"), &PrimitiveMesh::set_flip_faces);
ClassDB::bind_method(D_METHOD("get_flip_faces"), &PrimitiveMesh::get_flip_faces);
- ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "material", PROPERTY_HINT_RESOURCE_TYPE, "StandardMaterial3D,ShaderMaterial"), "set_material", "get_material");
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "material", PROPERTY_HINT_RESOURCE_TYPE, "ShaderMaterial,StandardMaterial3D"), "set_material", "get_material");
ADD_PROPERTY(PropertyInfo(Variant::AABB, "custom_aabb", PROPERTY_HINT_NONE, ""), "set_custom_aabb", "get_custom_aabb");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "flip_faces"), "set_flip_faces", "get_flip_faces");
}
diff --git a/scene/resources/ray_shape_2d.cpp b/scene/resources/ray_shape_2d.cpp
new file mode 100644
index 0000000000..67c4f84749
--- /dev/null
+++ b/scene/resources/ray_shape_2d.cpp
@@ -0,0 +1,105 @@
+/*************************************************************************/
+/* ray_shape_2d.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#include "ray_shape_2d.h"
+
+#include "servers/physics_server_2d.h"
+#include "servers/rendering_server.h"
+
+void RayShape2D::_update_shape() {
+ Dictionary d;
+ d["length"] = length;
+ d["slips_on_slope"] = slips_on_slope;
+ PhysicsServer2D::get_singleton()->shape_set_data(get_rid(), d);
+ emit_changed();
+}
+
+void RayShape2D::draw(const RID &p_to_rid, const Color &p_color) {
+ Vector2 tip = Vector2(0, get_length());
+ RS::get_singleton()->canvas_item_add_line(p_to_rid, Vector2(), tip, p_color, 3);
+ Vector<Vector2> pts;
+ float tsize = 4;
+ pts.push_back(tip + Vector2(0, tsize));
+ pts.push_back(tip + Vector2(Math_SQRT12 * tsize, 0));
+ pts.push_back(tip + Vector2(-Math_SQRT12 * tsize, 0));
+ Vector<Color> cols;
+ for (int i = 0; i < 3; i++) {
+ cols.push_back(p_color);
+ }
+ RS::get_singleton()->canvas_item_add_primitive(p_to_rid, pts, cols, Vector<Point2>(), RID());
+}
+
+Rect2 RayShape2D::get_rect() const {
+ Rect2 rect;
+ rect.position = Vector2();
+ rect.expand_to(Vector2(0, length));
+ rect = rect.grow(Math_SQRT12 * 4);
+ return rect;
+}
+
+real_t RayShape2D::get_enclosing_radius() const {
+ return length;
+}
+
+void RayShape2D::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("set_length", "length"), &RayShape2D::set_length);
+ ClassDB::bind_method(D_METHOD("get_length"), &RayShape2D::get_length);
+
+ ClassDB::bind_method(D_METHOD("set_slips_on_slope", "active"), &RayShape2D::set_slips_on_slope);
+ ClassDB::bind_method(D_METHOD("get_slips_on_slope"), &RayShape2D::get_slips_on_slope);
+
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "length"), "set_length", "get_length");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "slips_on_slope"), "set_slips_on_slope", "get_slips_on_slope");
+}
+
+void RayShape2D::set_length(real_t p_length) {
+ length = p_length;
+ _update_shape();
+}
+
+real_t RayShape2D::get_length() const {
+ return length;
+}
+
+void RayShape2D::set_slips_on_slope(bool p_active) {
+ slips_on_slope = p_active;
+ _update_shape();
+}
+
+bool RayShape2D::get_slips_on_slope() const {
+ return slips_on_slope;
+}
+
+RayShape2D::RayShape2D() :
+ Shape2D(PhysicsServer2D::get_singleton()->ray_shape_create()) {
+ length = 20;
+ slips_on_slope = false;
+ _update_shape();
+}
diff --git a/scene/resources/ray_shape_2d.h b/scene/resources/ray_shape_2d.h
new file mode 100644
index 0000000000..9a209d2907
--- /dev/null
+++ b/scene/resources/ray_shape_2d.h
@@ -0,0 +1,61 @@
+/*************************************************************************/
+/* ray_shape_2d.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#ifndef RAY_SHAPE_2D_H
+#define RAY_SHAPE_2D_H
+
+#include "scene/resources/shape_2d.h"
+
+class RayShape2D : public Shape2D {
+ GDCLASS(RayShape2D, Shape2D);
+
+ real_t length;
+ bool slips_on_slope;
+
+ void _update_shape();
+
+protected:
+ static void _bind_methods();
+
+public:
+ void set_length(real_t p_length);
+ real_t get_length() const;
+
+ void set_slips_on_slope(bool p_active);
+ bool get_slips_on_slope() const;
+
+ virtual void draw(const RID &p_to_rid, const Color &p_color);
+ virtual Rect2 get_rect() const;
+ virtual real_t get_enclosing_radius() const;
+
+ RayShape2D();
+};
+
+#endif // RAY_SHAPE_2D_H
diff --git a/scene/resources/segment_shape_2d.cpp b/scene/resources/segment_shape_2d.cpp
index e13c4c67c4..b1001203a1 100644
--- a/scene/resources/segment_shape_2d.cpp
+++ b/scene/resources/segment_shape_2d.cpp
@@ -98,77 +98,3 @@ SegmentShape2D::SegmentShape2D() :
b = Vector2(0, 10);
_update_shape();
}
-
-////////////////////////////////////////////////////////////
-
-void RayShape2D::_update_shape() {
- Dictionary d;
- d["length"] = length;
- d["slips_on_slope"] = slips_on_slope;
- PhysicsServer2D::get_singleton()->shape_set_data(get_rid(), d);
- emit_changed();
-}
-
-void RayShape2D::draw(const RID &p_to_rid, const Color &p_color) {
- Vector2 tip = Vector2(0, get_length());
- RS::get_singleton()->canvas_item_add_line(p_to_rid, Vector2(), tip, p_color, 3);
- Vector<Vector2> pts;
- float tsize = 4;
- pts.push_back(tip + Vector2(0, tsize));
- pts.push_back(tip + Vector2(Math_SQRT12 * tsize, 0));
- pts.push_back(tip + Vector2(-Math_SQRT12 * tsize, 0));
- Vector<Color> cols;
- for (int i = 0; i < 3; i++) {
- cols.push_back(p_color);
- }
-
- RS::get_singleton()->canvas_item_add_primitive(p_to_rid, pts, cols, Vector<Point2>(), RID());
-}
-
-Rect2 RayShape2D::get_rect() const {
- Rect2 rect;
- rect.position = Vector2();
- rect.expand_to(Vector2(0, length));
- rect = rect.grow(Math_SQRT12 * 4);
- return rect;
-}
-
-real_t RayShape2D::get_enclosing_radius() const {
- return length;
-}
-
-void RayShape2D::_bind_methods() {
- ClassDB::bind_method(D_METHOD("set_length", "length"), &RayShape2D::set_length);
- ClassDB::bind_method(D_METHOD("get_length"), &RayShape2D::get_length);
-
- ClassDB::bind_method(D_METHOD("set_slips_on_slope", "active"), &RayShape2D::set_slips_on_slope);
- ClassDB::bind_method(D_METHOD("get_slips_on_slope"), &RayShape2D::get_slips_on_slope);
-
- ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "length"), "set_length", "get_length");
- ADD_PROPERTY(PropertyInfo(Variant::BOOL, "slips_on_slope"), "set_slips_on_slope", "get_slips_on_slope");
-}
-
-void RayShape2D::set_length(real_t p_length) {
- length = p_length;
- _update_shape();
-}
-
-real_t RayShape2D::get_length() const {
- return length;
-}
-
-void RayShape2D::set_slips_on_slope(bool p_active) {
- slips_on_slope = p_active;
- _update_shape();
-}
-
-bool RayShape2D::get_slips_on_slope() const {
- return slips_on_slope;
-}
-
-RayShape2D::RayShape2D() :
- Shape2D(PhysicsServer2D::get_singleton()->ray_shape_create()) {
- length = 20;
- slips_on_slope = false;
- _update_shape();
-}
diff --git a/scene/resources/segment_shape_2d.h b/scene/resources/segment_shape_2d.h
index ca10c24f07..39c297b040 100644
--- a/scene/resources/segment_shape_2d.h
+++ b/scene/resources/segment_shape_2d.h
@@ -60,29 +60,4 @@ public:
SegmentShape2D();
};
-class RayShape2D : public Shape2D {
- GDCLASS(RayShape2D, Shape2D);
-
- real_t length;
- bool slips_on_slope;
-
- void _update_shape();
-
-protected:
- static void _bind_methods();
-
-public:
- void set_length(real_t p_length);
- real_t get_length() const;
-
- void set_slips_on_slope(bool p_active);
- bool get_slips_on_slope() const;
-
- virtual void draw(const RID &p_to_rid, const Color &p_color);
- virtual Rect2 get_rect() const;
- virtual real_t get_enclosing_radius() const;
-
- RayShape2D();
-};
-
#endif // SEGMENT_SHAPE_2D_H
diff --git a/servers/rendering/rasterizer.h b/servers/rendering/rasterizer.h
index e0d4432fd5..026725bf01 100644
--- a/servers/rendering/rasterizer.h
+++ b/servers/rendering/rasterizer.h
@@ -814,7 +814,7 @@ public:
item_mask = 1;
scale = 1.0;
energy = 1.0;
- item_shadow_mask = -1;
+ item_shadow_mask = 1;
mode = RS::CANVAS_LIGHT_MODE_ADD;
// texture_cache = nullptr;
next_ptr = nullptr;
diff --git a/servers/rendering/rasterizer_rd/shader_compiler_rd.cpp b/servers/rendering/rasterizer_rd/shader_compiler_rd.cpp
index d0b91df470..32321164a1 100644
--- a/servers/rendering/rasterizer_rd/shader_compiler_rd.cpp
+++ b/servers/rendering/rasterizer_rd/shader_compiler_rd.cpp
@@ -479,7 +479,7 @@ static String _get_global_variable_from_type_and_index(const String &p_buffer, c
}
}
-String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, GeneratedCode &r_gen_code, IdentifierActions &p_actions, const DefaultIdentifierActions &p_default_actions, bool p_assigning) {
+String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, GeneratedCode &r_gen_code, IdentifierActions &p_actions, const DefaultIdentifierActions &p_default_actions, bool p_assigning, bool p_use_scope) {
String code;
switch (p_node->type) {
@@ -967,7 +967,7 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge
if (anode->call_expression != nullptr) {
code += ".";
- code += _dump_node_code(anode->call_expression, p_level, r_gen_code, p_actions, p_default_actions, p_assigning);
+ code += _dump_node_code(anode->call_expression, p_level, r_gen_code, p_actions, p_default_actions, p_assigning, false);
}
if (anode->index_expression != nullptr) {
@@ -1113,7 +1113,13 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge
} break;
default: {
- code = "(" + _dump_node_code(onode->arguments[0], p_level, r_gen_code, p_actions, p_default_actions, p_assigning) + _opstr(onode->op) + _dump_node_code(onode->arguments[1], p_level, r_gen_code, p_actions, p_default_actions, p_assigning) + ")";
+ if (p_use_scope) {
+ code += "(";
+ }
+ code += _dump_node_code(onode->arguments[0], p_level, r_gen_code, p_actions, p_default_actions, p_assigning) + _opstr(onode->op) + _dump_node_code(onode->arguments[1], p_level, r_gen_code, p_actions, p_default_actions, p_assigning);
+ if (p_use_scope) {
+ code += ")";
+ }
break;
}
}
diff --git a/servers/rendering/rasterizer_rd/shader_compiler_rd.h b/servers/rendering/rasterizer_rd/shader_compiler_rd.h
index eaad34b8cd..ce94fb743f 100644
--- a/servers/rendering/rasterizer_rd/shader_compiler_rd.h
+++ b/servers/rendering/rasterizer_rd/shader_compiler_rd.h
@@ -96,7 +96,7 @@ private:
String _get_sampler_name(ShaderLanguage::TextureFilter p_filter, ShaderLanguage::TextureRepeat p_repeat);
void _dump_function_deps(const ShaderLanguage::ShaderNode *p_node, const StringName &p_for_func, const Map<StringName, String> &p_func_code, String &r_to_add, Set<StringName> &added);
- String _dump_node_code(const ShaderLanguage::Node *p_node, int p_level, GeneratedCode &r_gen_code, IdentifierActions &p_actions, const DefaultIdentifierActions &p_default_actions, bool p_assigning);
+ String _dump_node_code(const ShaderLanguage::Node *p_node, int p_level, GeneratedCode &r_gen_code, IdentifierActions &p_actions, const DefaultIdentifierActions &p_default_actions, bool p_assigning, bool p_scope = true);
const ShaderLanguage::ShaderNode *shader;
const ShaderLanguage::FunctionNode *function;