summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--AUTHORS.md1
-rw-r--r--DONORS.md44
-rw-r--r--core/array.cpp18
-rw-r--r--core/bind/core_bind.cpp12
-rw-r--r--core/class_db.cpp4
-rw-r--r--core/color.cpp3
-rw-r--r--core/command_queue_mt.h2
-rw-r--r--core/engine.cpp6
-rw-r--r--core/hash_map.h11
-rw-r--r--core/image.cpp9
-rw-r--r--core/io/file_access_buffered.cpp64
-rw-r--r--core/io/file_access_buffered_fa.h5
-rw-r--r--core/io/http_client.cpp2
-rw-r--r--core/io/json.cpp2
-rw-r--r--core/io/pck_packer.cpp7
-rw-r--r--core/io/resource_importer.cpp5
-rw-r--r--core/io/resource_loader.cpp4
-rw-r--r--core/math/bsp_tree.cpp6
-rw-r--r--core/math/camera_matrix.cpp60
-rw-r--r--core/math/math_funcs.cpp2
-rw-r--r--core/math/random_number_generator.h2
-rw-r--r--core/object.cpp6
-rw-r--r--core/os/dir_access.cpp4
-rw-r--r--core/os/memory.h2
-rw-r--r--core/project_settings.cpp2
-rw-r--r--core/ustring.cpp6
-rw-r--r--core/variant.cpp20
-rw-r--r--core/variant_op.cpp3
-rw-r--r--core/variant_parser.cpp14
-rw-r--r--doc/classes/AudioServer.xml26
-rw-r--r--drivers/gles2/shaders/scene.glsl57
-rw-r--r--drivers/gles3/rasterizer_storage_gles3.cpp1
-rw-r--r--drivers/unix/net_socket_posix.cpp8
-rw-r--r--editor/animation_bezier_editor.cpp4
-rw-r--r--editor/animation_track_editor_plugins.cpp2
-rw-r--r--editor/create_dialog.cpp3
-rw-r--r--editor/editor_plugin.cpp2
-rw-r--r--editor/editor_properties_array_dict.cpp63
-rw-r--r--editor/editor_properties_array_dict.h1
-rw-r--r--editor/groups_editor.cpp2
-rw-r--r--editor/plugins/collision_shape_2d_editor_plugin.h2
-rw-r--r--editor/plugins/curve_editor_plugin.cpp2
-rw-r--r--editor/plugins/path_2d_editor_plugin.h2
-rw-r--r--editor/plugins/script_editor_plugin.cpp2
-rw-r--r--editor/plugins/script_text_editor.cpp59
-rw-r--r--editor/plugins/script_text_editor.h6
-rw-r--r--editor/plugins/shader_editor_plugin.cpp57
-rw-r--r--editor/plugins/shader_editor_plugin.h4
-rw-r--r--editor/plugins/text_editor.cpp58
-rw-r--r--editor/plugins/text_editor.h4
-rw-r--r--editor/plugins/texture_region_editor_plugin.cpp7
-rw-r--r--editor/project_settings_editor.cpp4
-rw-r--r--editor/scene_tree_dock.cpp95
-rw-r--r--editor/scene_tree_dock.h6
-rw-r--r--editor/script_create_dialog.cpp4
-rw-r--r--editor/script_editor_debugger.cpp3
-rw-r--r--editor/spatial_editor_gizmos.cpp4
-rw-r--r--main/main.cpp2
-rw-r--r--modules/bullet/rigid_body_bullet.cpp4
-rw-r--r--modules/gdscript/gdscript.cpp2
-rw-r--r--modules/gdscript/gdscript_compiler.cpp2
-rw-r--r--modules/gdscript/gdscript_function.cpp53
-rw-r--r--modules/mono/csharp_script.cpp2
-rw-r--r--modules/visual_script/visual_script_editor.cpp4
-rw-r--r--platform/android/export/export.cpp19
-rw-r--r--platform/android/java/AndroidManifest.xml9
-rw-r--r--platform/android/java/src/org/godotengine/godot/Godot.java10
-rw-r--r--platform/android/java/src/org/godotengine/godot/GodotView.java22
-rw-r--r--platform/android/java/src/org/godotengine/godot/xr/XRMode.java14
-rw-r--r--platform/android/java/src/org/godotengine/godot/xr/regular/RegularConfigChooser.java (renamed from platform/android/java/src/org/godotengine/godot/xr/pancake/PancakeConfigChooser.java)10
-rw-r--r--platform/android/java/src/org/godotengine/godot/xr/regular/RegularContextFactory.java (renamed from platform/android/java/src/org/godotengine/godot/xr/pancake/PancakeContextFactory.java)8
-rw-r--r--platform/android/java/src/org/godotengine/godot/xr/regular/RegularFallbackConfigChooser.java (renamed from platform/android/java/src/org/godotengine/godot/xr/pancake/PancakeFallbackConfigChooser.java)12
-rw-r--r--platform/javascript/detect.py6
-rw-r--r--scene/2d/canvas_item.cpp1
-rw-r--r--scene/2d/navigation_2d.cpp1
-rw-r--r--scene/3d/audio_stream_player_3d.h2
-rw-r--r--scene/3d/navigation.cpp1
-rw-r--r--scene/3d/spatial.cpp2
-rw-r--r--scene/3d/visual_instance.cpp2
-rw-r--r--scene/gui/option_button.cpp2
-rw-r--r--scene/gui/text_edit.cpp8
-rw-r--r--scene/main/node.cpp6
-rw-r--r--scene/main/viewport.cpp2
-rw-r--r--scene/resources/texture.cpp2
-rw-r--r--servers/audio/audio_stream.cpp3
-rw-r--r--servers/audio/effects/audio_effect_record.cpp3
-rw-r--r--servers/audio_server.cpp17
-rw-r--r--servers/audio_server.h5
-rw-r--r--servers/physics/collision_object_sw.cpp7
-rw-r--r--servers/physics/collision_object_sw.h7
-rw-r--r--servers/physics_2d/collision_object_2d_sw.cpp45
-rw-r--r--servers/physics_2d/collision_object_2d_sw.h2
-rw-r--r--servers/physics_2d/physics_2d_server_sw.cpp20
-rw-r--r--servers/physics_2d/physics_2d_server_sw.h3
94 files changed, 786 insertions, 348 deletions
diff --git a/AUTHORS.md b/AUTHORS.md
index ba563eb507..43b4917382 100644
--- a/AUTHORS.md
+++ b/AUTHORS.md
@@ -52,6 +52,7 @@ name is available.
Clay John (clayjohn)
Dana Olson (adolson)
Daniel J. Ramirez (djrm)
+ Daniel Rakos (aqnuep)
Dharkael (lupoDharkael)
Dmitry Koteroff (Krakean)
DualMatrix
diff --git a/DONORS.md b/DONORS.md
index 30eb5c220f..947c12923b 100644
--- a/DONORS.md
+++ b/DONORS.md
@@ -41,6 +41,7 @@ generous deed immortalized in the next stable release of Godot Engine.
Matthieu Huvé
Maxim Karsten
Mike King
+ Nathan Warden
Neal Gompa (Conan Kudo)
Patrick Aarstad
Slobodan Milnovic
@@ -49,13 +50,11 @@ generous deed immortalized in the next stable release of Godot Engine.
Steve
VilliHaukka
Xananax
- Y8.com
Zashi
## Gold donors
Andrei
- Brandon Waite
cheese65536
David Gehrig
Ed Morley
@@ -66,12 +65,12 @@ generous deed immortalized in the next stable release of Godot Engine.
Manuele Finocchiaro
Officine Pixel S.n.c.
Retro Village
+ Ronan Zeegers
Sofox
Zaven Muradyan
Alexander Trey Saunders
Allen Schade
- Andreas Schüle
Asher Glick
Austen McRae
Brian van der Stel
@@ -85,8 +84,6 @@ generous deed immortalized in the next stable release of Godot Engine.
Jay Horton
Jon Smith
Jon Woodward
- Jorge Bernal
- Joshua Lesperance
Justo Delgado Baudí
Karl Werf
Kommentgames
@@ -96,11 +93,13 @@ generous deed immortalized in the next stable release of Godot Engine.
Mored1984
paul gruenbacher
Paul LaMotte
+ Péter Magyar
Rob Messick
Ross Esmond
Ryan Badour
Scott Wadden
Sergey
+ Shawn Yu
Svenne Krap
Tom Langwaldt
William Wold
@@ -129,6 +128,7 @@ generous deed immortalized in the next stable release of Godot Engine.
Robin Arys
Ronnie Ashlock
ScottMakesGames
+ Tad C Johnson
Thomas Bjarnelöf
Vincent Henderson
Wojciech Chojnacki
@@ -149,24 +149,25 @@ generous deed immortalized in the next stable release of Godot Engine.
D
Daniel
Daniel Eichler
+ David White
Deadly Lampshade
Eric
Eric Monson
- Ethan Bennis
Eugenio Hugo Salgüero Jáñez
flesk
Francisco Javier Moreno Carracedo
gavlig
GGGames.org
Giles Montgomery
- Giovanni Solimeno
Guilherme Felipe de C. G. da Silva
Heath Hayes
Hysteria
Idzard Kwadijk
Jared White
+ Jesse Nave
Jose Malheiro
Joshua Flores
+ Joshua Lesperance
Juan T Chen
Juraj Móza
Kasper Jeppesen
@@ -174,13 +175,13 @@ generous deed immortalized in the next stable release of Godot Engine.
Klavdij Voncina
Leandro Voltolino
Maarten Elings
- Malcolm Peralty
Markus Fehr
Markus Wiesner
Martin Eigel
Marvin
Matt Eunson
Matthew Hillier
+ Max Bulai
Max R.R. Collada
M H
Nick Nikitin
@@ -219,14 +220,18 @@ generous deed immortalized in the next stable release of Godot Engine.
Alice Robinson
Andreas Evers
Andreas Krampitz
+ Andreas Schüle
Andrew Peart
Anthony Bongiovanni
Anthony Staunton
Antony K. Jones
Arda Erol
+ Artem Bashev
Arthur S. Muszynski
+ Artistofdeath
Aubrey Falconer
Avencherus
+ B A
Balázs Batári
Bastian Böhm
Beliar
@@ -242,6 +247,7 @@ generous deed immortalized in the next stable release of Godot Engine.
Boyquotes
Branwyn Tylwyth
Bryan Stevenson
+ Caleb Dumitry
Carwyn Edwards
Chris Brown
Chris Chapin
@@ -250,7 +256,6 @@ generous deed immortalized in the next stable release of Godot Engine.
Christian Winter
Christoffer Sundbom
Christopher Schmitt
- Chris Wilson
Clay Heaton
Cobaltum
Collin Shooltz
@@ -263,7 +268,9 @@ generous deed immortalized in the next stable release of Godot Engine.
David Cravens
David May
Dimitri Stanojevic
+ Dominic Cooney
Dominik Wetzel
+ DrevanTonder
Duobix
Edward Herbert
Egon Elbre
@@ -272,12 +279,12 @@ generous deed immortalized in the next stable release of Godot Engine.
Emanuel Kotzayan
Eric Ellingson
Eric Martini
- Eric McCarthy
Eric Williams
Evan Rose
Felix Kollmann
fengjiongmax
Flaredown
+ FuDiggity
G3Dev sàrl
Gary Hulst
Gerrit Großkopf
@@ -286,9 +293,9 @@ generous deed immortalized in the next stable release of Godot Engine.
Greg Olson
Greg P
Guldoman
+ Hal A
Heribert Hirth
Hiroshi Naruo
- HMan
Hunter Jones
Hylpher
ialex32x
@@ -310,6 +317,7 @@ generous deed immortalized in the next stable release of Godot Engine.
Joel Setterberg
Johannes Eichler
Johannes Wuensch
+ Jomei Jackson
Jonas Rudlang
Jonas Yamazaki
Jonathan G
@@ -318,21 +326,24 @@ generous deed immortalized in the next stable release of Godot Engine.
Jon Bonazza
Jon Sully
Jose Aleman
+ Joseph Catrambone
Josh 'Cheeseness' Bush
Juanfran
Juan Negrier
Judd
+ Jueast
Julian Murgia
Kasier Bald0
KC Chan
kickmaniac
Kiyohiro Kawamura (kyorohiro)
Klagsam
+ Klassix
KR McGinley
KsyTek Games
Kuan Cheang
kycho
- Lavik1988
+ Leviathan Hunter
Levi Lindsey
Linus Lind Lundgren
Lionel Gaillard
@@ -344,6 +355,7 @@ generous deed immortalized in the next stable release of Godot Engine.
Malcolm
Malik Ahmed
Malik Nejer
+ Marc Urlus
Marcus Richter
Markus Michael Egger
Martin Holas
@@ -357,6 +369,7 @@ generous deed immortalized in the next stable release of Godot Engine.
Mikael Olsson
Mikayla Hutchinson
Mike Cunningham
+ Mitchell J. Wagner
mlevin cantu
MoM
Moritz Laass
@@ -365,6 +378,7 @@ generous deed immortalized in the next stable release of Godot Engine.
nee
Neil Blakey-Milner
Nerdforge
+ Nicholas
Niclas Eriksen
Nicolás Montaña
Nicolas SAN AGUSTIN
@@ -372,6 +386,7 @@ generous deed immortalized in the next stable release of Godot Engine.
NZ
Omar Delarosa
Oscar Norlander
+ Pafka
Pan Ip
Patrick Forringer
Patrick Nafarrete
@@ -382,6 +397,7 @@ generous deed immortalized in the next stable release of Godot Engine.
Pierre-Igor Berthet
Pietro Vertechi
Pitsanu Tongprasin
+ Point08
Poryg
Rafa Laguna
Rafal Wyszomirski
@@ -408,7 +424,7 @@ generous deed immortalized in the next stable release of Godot Engine.
Simon Wenner
SK
Sootstone
- Theo Cranmore
+ Stonepyre
Thibault Barbaroux
thomas
Thomas Bell
@@ -434,7 +450,6 @@ generous deed immortalized in the next stable release of Godot Engine.
Veodok
Victor
Vigilant Watch
- Viktor Ferenczi
waka nya
Wayne Haak
werner mendizabal
@@ -442,6 +457,7 @@ generous deed immortalized in the next stable release of Godot Engine.
Will
William Hogben
Wout Standaert
+ Yeung Si Xiang
## Bronze donors
diff --git a/core/array.cpp b/core/array.cpp
index 65934d6ec9..a334af2c04 100644
--- a/core/array.cpp
+++ b/core/array.cpp
@@ -133,12 +133,18 @@ void Array::erase(const Variant &p_value) {
}
Variant Array::front() const {
- ERR_FAIL_COND_V(_p->array.size() == 0, Variant());
+ if (_p->array.size() == 0) {
+ ERR_EXPLAIN("Can't take value from empty array");
+ ERR_FAIL_V(Variant());
+ }
return operator[](0);
}
Variant Array::back() const {
- ERR_FAIL_COND_V(_p->array.size() == 0, Variant());
+ if (_p->array.size() == 0) {
+ ERR_EXPLAIN("Can't take value from empty array");
+ ERR_FAIL_V(Variant());
+ }
return operator[](_p->array.size() - 1);
}
@@ -165,8 +171,8 @@ int Array::rfind(const Variant &p_value, int p_from) const {
if (_p->array[i] == p_value) {
return i;
- };
- };
+ }
+ }
return -1;
}
@@ -186,8 +192,8 @@ int Array::count(const Variant &p_value) const {
if (_p->array[i] == p_value) {
amount++;
- };
- };
+ }
+ }
return amount;
}
diff --git a/core/bind/core_bind.cpp b/core/bind/core_bind.cpp
index 242c5b3bf1..ba9bd10bfd 100644
--- a/core/bind/core_bind.cpp
+++ b/core/bind/core_bind.cpp
@@ -149,8 +149,10 @@ _ResourceLoader::_ResourceLoader() {
}
Error _ResourceSaver::save(const String &p_path, const RES &p_resource, SaverFlags p_flags) {
-
- ERR_FAIL_COND_V(p_resource.is_null(), ERR_INVALID_PARAMETER);
+ if (p_resource.is_null()) {
+ ERR_EXPLAIN("Can't save empty resource to path: " + String(p_path))
+ ERR_FAIL_V(ERR_INVALID_PARAMETER);
+ }
return ResourceSaver::save(p_path, p_resource, p_flags);
}
@@ -246,11 +248,11 @@ PoolStringArray _OS::get_connected_midi_inputs() {
}
void _OS::open_midi_inputs() {
- return OS::get_singleton()->open_midi_inputs();
+ OS::get_singleton()->open_midi_inputs();
}
void _OS::close_midi_inputs() {
- return OS::get_singleton()->close_midi_inputs();
+ OS::get_singleton()->close_midi_inputs();
}
void _OS::set_video_mode(const Size2 &p_size, bool p_fullscreen, bool p_resizeable, int p_screen) {
@@ -2266,7 +2268,7 @@ bool _Directory::current_is_dir() const {
void _Directory::list_dir_end() {
ERR_FAIL_COND(!d);
- return d->list_dir_end();
+ d->list_dir_end();
}
int _Directory::get_drive_count() {
diff --git a/core/class_db.cpp b/core/class_db.cpp
index 9fe9b23c68..2cbf53ba0b 100644
--- a/core/class_db.cpp
+++ b/core/class_db.cpp
@@ -925,7 +925,7 @@ void ClassDB::add_property(StringName p_class, const PropertyInfo &p_pinfo, cons
#ifdef DEBUG_METHODS_ENABLED
if (!mb_set) {
ERR_EXPLAIN("Invalid Setter: " + p_class + "::" + p_setter + " for property: " + p_pinfo.name);
- ERR_FAIL_COND(!mb_set);
+ ERR_FAIL();
} else {
int exp_args = 1 + (p_index >= 0 ? 1 : 0);
if (mb_set->get_argument_count() != exp_args) {
@@ -944,7 +944,7 @@ void ClassDB::add_property(StringName p_class, const PropertyInfo &p_pinfo, cons
if (!mb_get) {
ERR_EXPLAIN("Invalid Getter: " + p_class + "::" + p_getter + " for property: " + p_pinfo.name);
- ERR_FAIL_COND(!mb_get);
+ ERR_FAIL();
} else {
int exp_args = 0 + (p_index >= 0 ? 1 : 0);
diff --git a/core/color.cpp b/core/color.cpp
index 8959fce4e3..1843532124 100644
--- a/core/color.cpp
+++ b/core/color.cpp
@@ -388,9 +388,8 @@ bool Color::html_is_valid(const String &p_color) {
return false;
}
- int a = 255;
if (alpha) {
- a = _parse_col(color, 0);
+ int a = _parse_col(color, 0);
if (a < 0) {
return false;
}
diff --git a/core/command_queue_mt.h b/core/command_queue_mt.h
index 798fa4394d..3789eda5db 100644
--- a/core/command_queue_mt.h
+++ b/core/command_queue_mt.h
@@ -346,7 +346,7 @@ class CommandQueueMT {
}
return NULL;
}
- } else if (write_ptr >= dealloc_ptr) {
+ } else {
// ahead of dealloc_ptr, check that there is room
if ((COMMAND_MEM_SIZE - write_ptr) < alloc_size + sizeof(uint32_t)) {
diff --git a/core/engine.cpp b/core/engine.cpp
index 50822244cf..2d8473fbd9 100644
--- a/core/engine.cpp
+++ b/core/engine.cpp
@@ -197,8 +197,10 @@ void Engine::add_singleton(const Singleton &p_singleton) {
Object *Engine::get_singleton_object(const String &p_name) const {
const Map<StringName, Object *>::Element *E = singleton_ptrs.find(p_name);
- ERR_EXPLAIN("Failed to retrieve non-existent singleton '" + p_name + "'");
- ERR_FAIL_COND_V(!E, NULL);
+ if (!E) {
+ ERR_EXPLAIN("Failed to retrieve non-existent singleton '" + p_name + "'");
+ ERR_FAIL_V(NULL);
+ }
return E->get();
};
diff --git a/core/hash_map.h b/core/hash_map.h
index 31332991de..1513d7a65b 100644
--- a/core/hash_map.h
+++ b/core/hash_map.h
@@ -208,7 +208,10 @@ private:
/* if element doesn't exist, create it */
Element *e = memnew(Element);
- ERR_FAIL_COND_V(!e, NULL); /* out of memory */
+ if (!e) {
+ ERR_EXPLAIN("Out of memory");
+ ERR_FAIL_V(NULL);
+ }
uint32_t hash = Hasher::hash(p_key);
uint32_t index = hash & ((1 << hash_table_power) - 1);
e->next = hash_table[index];
@@ -495,8 +498,10 @@ public:
} else { /* get the next key */
const Element *e = get_element(*p_key);
- ERR_FAIL_COND_V(!e, NULL); /* invalid key supplied */
-
+ if (!e) {
+ ERR_EXPLAIN("Invalid key supplied")
+ ERR_FAIL_V(NULL);
+ }
if (e->next) {
/* if there is a "next" in the list, return that */
return &e->next->pair.key;
diff --git a/core/image.cpp b/core/image.cpp
index dd8f2b9bac..18a3aae88f 100644
--- a/core/image.cpp
+++ b/core/image.cpp
@@ -1372,6 +1372,7 @@ void Image::shrink_x2() {
int new_size = data.size() - ofs;
new_img.resize(new_size);
+ ERR_FAIL_COND(new_img.size() == 0);
{
PoolVector<uint8_t>::Write w = new_img.write();
@@ -1391,6 +1392,7 @@ void Image::shrink_x2() {
ERR_FAIL_COND(!_can_modify(format));
int ps = get_format_pixel_size(format);
new_img.resize((width / 2) * (height / 2) * ps);
+ ERR_FAIL_COND(new_img.size() == 0);
{
PoolVector<uint8_t>::Write w = new_img.write();
@@ -1464,7 +1466,10 @@ Error Image::generate_mipmaps(bool p_renormalize) {
ERR_FAIL_V(ERR_UNAVAILABLE);
}
- ERR_FAIL_COND_V(width == 0 || height == 0, ERR_UNCONFIGURED);
+ if (width == 0 || height == 0) {
+ ERR_EXPLAIN("Cannot generate mipmaps with width or height equal to 0.");
+ ERR_FAIL_V(ERR_UNCONFIGURED);
+ }
int mmcount;
@@ -2532,7 +2537,7 @@ Color Image::get_pixel(int p_x, int p_y) const {
}
void Image::set_pixelv(const Point2 &p_dst, const Color &p_color) {
- return set_pixel(p_dst.x, p_dst.y, p_color);
+ set_pixel(p_dst.x, p_dst.y, p_color);
}
void Image::set_pixel(int p_x, int p_y, const Color &p_color) {
diff --git a/core/io/file_access_buffered.cpp b/core/io/file_access_buffered.cpp
index 93eaeb08c5..15523a49a9 100644
--- a/core/io/file_access_buffered.cpp
+++ b/core/io/file_access_buffered.cpp
@@ -35,79 +35,79 @@
Error FileAccessBuffered::set_error(Error p_error) const {
return (last_error = p_error);
-};
+}
void FileAccessBuffered::set_cache_size(int p_size) {
cache_size = p_size;
-};
+}
int FileAccessBuffered::get_cache_size() {
return cache_size;
-};
+}
int FileAccessBuffered::cache_data_left() const {
if (file.offset >= file.size) {
return 0;
- };
+ }
if (cache.offset == -1 || file.offset < cache.offset || file.offset >= cache.offset + cache.buffer.size()) {
return read_data_block(file.offset, cache_size);
+ }
- } else {
-
- return cache.buffer.size() - (file.offset - cache.offset);
- };
-
- return 0;
-};
+ return cache.buffer.size() - (file.offset - cache.offset);
+}
void FileAccessBuffered::seek(size_t p_position) {
file.offset = p_position;
-};
+}
void FileAccessBuffered::seek_end(int64_t p_position) {
file.offset = file.size + p_position;
-};
+}
size_t FileAccessBuffered::get_position() const {
return file.offset;
-};
+}
size_t FileAccessBuffered::get_len() const {
return file.size;
-};
+}
bool FileAccessBuffered::eof_reached() const {
return file.offset > file.size;
-};
+}
uint8_t FileAccessBuffered::get_8() const {
-
- ERR_FAIL_COND_V(!file.open, 0);
+ if (!file.open) {
+ ERR_EXPLAIN("Can't get data, when file is not opened.");
+ ERR_FAIL_V(0);
+ }
uint8_t byte = 0;
if (cache_data_left() >= 1) {
byte = cache.buffer[file.offset - cache.offset];
- };
+ }
++file.offset;
return byte;
-};
+}
int FileAccessBuffered::get_buffer(uint8_t *p_dest, int p_length) const {
-
- ERR_FAIL_COND_V(!file.open, -1);
+ if (!file.open) {
+ ERR_EXPLAIN("Can't get buffer, when file is not opened.");
+ ERR_FAIL_V(-1);
+ }
if (p_length > cache_size) {
@@ -124,16 +124,16 @@ int FileAccessBuffered::get_buffer(uint8_t *p_dest, int p_length) const {
p_length -= size;
file.offset += size;
total_read += size;
- };
+ }
int err = read_data_block(file.offset, p_length, p_dest);
if (err >= 0) {
total_read += err;
file.offset += err;
- };
+ }
return total_read;
- };
+ }
int to_read = p_length;
int total_read = 0;
@@ -143,10 +143,10 @@ int FileAccessBuffered::get_buffer(uint8_t *p_dest, int p_length) const {
if (left == 0) {
file.offset += to_read;
return total_read;
- };
+ }
if (left < 0) {
return left;
- };
+ }
int r = MIN(left, to_read);
//PoolVector<uint8_t>::Read read = cache.buffer.read();
@@ -156,25 +156,25 @@ int FileAccessBuffered::get_buffer(uint8_t *p_dest, int p_length) const {
file.offset += r;
total_read += r;
to_read -= r;
- };
+ }
return p_length;
-};
+}
bool FileAccessBuffered::is_open() const {
return file.open;
-};
+}
Error FileAccessBuffered::get_error() const {
return last_error;
-};
+}
FileAccessBuffered::FileAccessBuffered() {
cache_size = DEFAULT_CACHE_SIZE;
-};
+}
FileAccessBuffered::~FileAccessBuffered() {
}
diff --git a/core/io/file_access_buffered_fa.h b/core/io/file_access_buffered_fa.h
index 24b40cbce8..6e806e7b3f 100644
--- a/core/io/file_access_buffered_fa.h
+++ b/core/io/file_access_buffered_fa.h
@@ -40,7 +40,10 @@ class FileAccessBufferedFA : public FileAccessBuffered {
int read_data_block(int p_offset, int p_size, uint8_t *p_dest = 0) const {
- ERR_FAIL_COND_V(!f.is_open(), -1);
+ if (!f.is_open()) {
+ ERR_EXPLAIN("Can't read data block, when file is not opened.");
+ ERR_FAIL_V(-1);
+ }
((T *)&f)->seek(p_offset);
diff --git a/core/io/http_client.cpp b/core/io/http_client.cpp
index c3626bfe31..170bef4430 100644
--- a/core/io/http_client.cpp
+++ b/core/io/http_client.cpp
@@ -482,8 +482,6 @@ Error HTTPClient::poll() {
return OK;
}
}
- // Wait for response
- return OK;
} break;
case STATUS_DISCONNECTED: {
return ERR_UNCONFIGURED;
diff --git a/core/io/json.cpp b/core/io/json.cpp
index c211ca2ed4..4e729cb355 100644
--- a/core/io/json.cpp
+++ b/core/io/json.cpp
@@ -347,8 +347,6 @@ Error JSON::_parse_value(Variant &value, Token &token, const CharType *p_str, in
r_err_str = "Expected value, got " + String(tk_name[token.type]) + ".";
return ERR_PARSE_ERROR;
}
-
- return ERR_PARSE_ERROR;
}
Error JSON::_parse_array(Array &array, const CharType *p_str, int &index, int p_len, int &line, String &r_err_str) {
diff --git a/core/io/pck_packer.cpp b/core/io/pck_packer.cpp
index 55685a2d9a..c16d89d695 100644
--- a/core/io/pck_packer.cpp
+++ b/core/io/pck_packer.cpp
@@ -63,10 +63,11 @@ void PCKPacker::_bind_methods() {
Error PCKPacker::pck_start(const String &p_file, int p_alignment) {
file = FileAccess::open(p_file, FileAccess::WRITE);
- if (file == NULL) {
- return ERR_CANT_CREATE;
- };
+ if (!file) {
+ ERR_EXPLAIN("Can't open file to write: " + String(p_file));
+ ERR_FAIL_V(ERR_CANT_CREATE);
+ }
alignment = p_alignment;
diff --git a/core/io/resource_importer.cpp b/core/io/resource_importer.cpp
index 4a58d37ca5..63d7ba547c 100644
--- a/core/io/resource_importer.cpp
+++ b/core/io/resource_importer.cpp
@@ -161,7 +161,8 @@ void ResourceFormatImporter::get_recognized_extensions(List<String> *p_extension
void ResourceFormatImporter::get_recognized_extensions_for_type(const String &p_type, List<String> *p_extensions) const {
if (p_type == "") {
- return get_recognized_extensions(p_extensions);
+ get_recognized_extensions(p_extensions);
+ return;
}
Set<String> found;
@@ -347,7 +348,7 @@ void ResourceFormatImporter::get_dependencies(const String &p_path, List<String>
return;
}
- return ResourceLoader::get_dependencies(pat.path, p_dependencies, p_add_types);
+ ResourceLoader::get_dependencies(pat.path, p_dependencies, p_add_types);
}
Ref<ResourceImporter> ResourceFormatImporter::get_importer_by_name(const String &p_name) const {
diff --git a/core/io/resource_loader.cpp b/core/io/resource_loader.cpp
index 56d3b8b133..a29b9d1ddb 100644
--- a/core/io/resource_loader.cpp
+++ b/core/io/resource_loader.cpp
@@ -207,8 +207,6 @@ RES ResourceFormatLoader::load(const String &p_path, const String &p_original_pa
ERR_FAIL_COND_V(err != OK, RES());
}
-
- return RES();
}
void ResourceFormatLoader::get_dependencies(const String &p_path, List<String> *p_dependencies, bool p_add_types) {
@@ -283,7 +281,6 @@ RES ResourceLoader::_load(const String &p_path, const String &p_original_path, c
ERR_EXPLAIN("No loader found for resource: " + p_path);
}
ERR_FAIL_V(RES());
- return RES();
}
bool ResourceLoader::_add_to_loading_map(const String &p_path) {
@@ -543,7 +540,6 @@ Ref<ResourceInteractiveLoader> ResourceLoader::load_interactive(const String &p_
ERR_EXPLAIN("No loader found for resource: " + path);
}
ERR_FAIL_V(Ref<ResourceInteractiveLoader>());
- return Ref<ResourceInteractiveLoader>();
}
void ResourceLoader::add_resource_format_loader(Ref<ResourceFormatLoader> p_format_loader, bool p_at_front) {
diff --git a/core/math/bsp_tree.cpp b/core/math/bsp_tree.cpp
index d7e6e82cd9..a12f9fee2e 100644
--- a/core/math/bsp_tree.cpp
+++ b/core/math/bsp_tree.cpp
@@ -142,7 +142,7 @@ int BSP_Tree::_get_points_inside(int p_node, const Vector3 *p_points, int *p_ind
}
return _get_points_inside(node->over, p_points, p_indices, p_center, p_half_extents, p_indices_count);
- } else if (dist_min <= 0) { //all points behind plane
+ } else { //all points behind plane
if (node->under == UNDER_LEAF) {
@@ -150,8 +150,6 @@ int BSP_Tree::_get_points_inside(int p_node, const Vector3 *p_points, int *p_ind
}
return _get_points_inside(node->under, p_points, p_indices, p_center, p_half_extents, p_indices_count);
}
-
- return 0;
}
int BSP_Tree::get_points_inside(const Vector3 *p_points, int p_point_count) const {
@@ -271,8 +269,6 @@ bool BSP_Tree::point_is_inside(const Vector3 &p_point) const {
ERR_FAIL_COND_V(idx < MAX_NODES && idx >= node_count, false);
#endif
}
-
- return false;
}
static int _bsp_find_best_half_plane(const Face3 *p_faces, const Vector<int> &p_indices, real_t p_tolerance) {
diff --git a/core/math/camera_matrix.cpp b/core/math/camera_matrix.cpp
index f615cc8c65..8b3b6c82f3 100644
--- a/core/math/camera_matrix.cpp
+++ b/core/math/camera_matrix.cpp
@@ -507,21 +507,21 @@ void CameraMatrix::set_light_bias() {
real_t *m = &matrix[0][0];
- m[0] = 0.5,
- m[1] = 0.0,
- m[2] = 0.0,
- m[3] = 0.0,
- m[4] = 0.0,
- m[5] = 0.5,
- m[6] = 0.0,
- m[7] = 0.0,
- m[8] = 0.0,
- m[9] = 0.0,
- m[10] = 0.5,
- m[11] = 0.0,
- m[12] = 0.5,
- m[13] = 0.5,
- m[14] = 0.5,
+ m[0] = 0.5;
+ m[1] = 0.0;
+ m[2] = 0.0;
+ m[3] = 0.0;
+ m[4] = 0.0;
+ m[5] = 0.5;
+ m[6] = 0.0;
+ m[7] = 0.0;
+ m[8] = 0.0;
+ m[9] = 0.0;
+ m[10] = 0.5;
+ m[11] = 0.0;
+ m[12] = 0.5;
+ m[13] = 0.5;
+ m[14] = 0.5;
m[15] = 1.0;
}
@@ -529,21 +529,21 @@ void CameraMatrix::set_light_atlas_rect(const Rect2 &p_rect) {
real_t *m = &matrix[0][0];
- m[0] = p_rect.size.width,
- m[1] = 0.0,
- m[2] = 0.0,
- m[3] = 0.0,
- m[4] = 0.0,
- m[5] = p_rect.size.height,
- m[6] = 0.0,
- m[7] = 0.0,
- m[8] = 0.0,
- m[9] = 0.0,
- m[10] = 1.0,
- m[11] = 0.0,
- m[12] = p_rect.position.x,
- m[13] = p_rect.position.y,
- m[14] = 0.0,
+ m[0] = p_rect.size.width;
+ m[1] = 0.0;
+ m[2] = 0.0;
+ m[3] = 0.0;
+ m[4] = 0.0;
+ m[5] = p_rect.size.height;
+ m[6] = 0.0;
+ m[7] = 0.0;
+ m[8] = 0.0;
+ m[9] = 0.0;
+ m[10] = 1.0;
+ m[11] = 0.0;
+ m[12] = p_rect.position.x;
+ m[13] = p_rect.position.y;
+ m[14] = 0.0;
m[15] = 1.0;
}
diff --git a/core/math/math_funcs.cpp b/core/math/math_funcs.cpp
index 5b5fd8e283..7a2e74a413 100644
--- a/core/math/math_funcs.cpp
+++ b/core/math/math_funcs.cpp
@@ -161,8 +161,6 @@ uint32_t Math::larger_prime(uint32_t p_val) {
return primes[idx];
idx++;
}
-
- return 0;
}
double Math::random(double from, double to) {
diff --git a/core/math/random_number_generator.h b/core/math/random_number_generator.h
index a6182a4b33..9b54ea9b2e 100644
--- a/core/math/random_number_generator.h
+++ b/core/math/random_number_generator.h
@@ -47,7 +47,7 @@ public:
_FORCE_INLINE_ uint64_t get_seed() { return randbase.get_seed(); }
- _FORCE_INLINE_ void randomize() { return randbase.randomize(); }
+ _FORCE_INLINE_ void randomize() { randbase.randomize(); }
_FORCE_INLINE_ uint32_t randi() { return randbase.rand(); }
diff --git a/core/object.cpp b/core/object.cpp
index ee512ff23c..3367d6b6c3 100644
--- a/core/object.cpp
+++ b/core/object.cpp
@@ -742,13 +742,11 @@ void Object::call_multilevel(const StringName &p_method, const Variant **p_args,
if (Object::cast_to<Reference>(this)) {
ERR_EXPLAIN("Can't 'free' a reference.");
ERR_FAIL();
- return;
}
if (_lock_index.get() > 1) {
ERR_EXPLAIN("Object is locked and can't be freed.");
ERR_FAIL();
- return;
}
#endif
@@ -1467,7 +1465,7 @@ Error Object::connect(const StringName &p_signal, Object *p_to_object, const Str
if (!signal_is_valid) {
ERR_EXPLAIN("In Object of type '" + String(get_class()) + "': Attempt to connect nonexistent signal '" + p_signal + "' to method '" + p_to_object->get_class() + "." + p_to_method + "'");
- ERR_FAIL_COND_V(!signal_is_valid, ERR_INVALID_PARAMETER);
+ ERR_FAIL_V(ERR_INVALID_PARAMETER);
}
signal_map[p_signal] = Signal();
s = &signal_map[p_signal];
@@ -1517,7 +1515,7 @@ bool Object::is_connected(const StringName &p_signal, Object *p_to_object, const
return false;
ERR_EXPLAIN("Nonexistent signal: " + p_signal);
- ERR_FAIL_COND_V(!s, false);
+ ERR_FAIL_V(false);
}
Signal::Target target(p_to_object->get_instance_id(), p_to_method);
diff --git a/core/os/dir_access.cpp b/core/os/dir_access.cpp
index 9feca5c673..0cdb5b41b7 100644
--- a/core/os/dir_access.cpp
+++ b/core/os/dir_access.cpp
@@ -43,8 +43,6 @@ String DirAccess::_get_root_path() const {
case ACCESS_USERDATA: return OS::get_singleton()->get_user_data_dir();
default: return "";
}
-
- return "";
}
String DirAccess::_get_root_string() const {
@@ -54,8 +52,6 @@ String DirAccess::_get_root_string() const {
case ACCESS_USERDATA: return "user://";
default: return "";
}
-
- return "";
}
int DirAccess::get_current_drive() {
diff --git a/core/os/memory.h b/core/os/memory.h
index f3ca9fc614..e073b11e76 100644
--- a/core/os/memory.h
+++ b/core/os/memory.h
@@ -66,7 +66,7 @@ public:
class DefaultAllocator {
public:
_FORCE_INLINE_ static void *alloc(size_t p_memory) { return Memory::alloc_static(p_memory, false); }
- _FORCE_INLINE_ static void free(void *p_ptr) { return Memory::free_static(p_ptr, false); }
+ _FORCE_INLINE_ static void free(void *p_ptr) { Memory::free_static(p_ptr, false); }
};
void *operator new(size_t p_size, const char *p_description); ///< operator new that takes a description and uses MemoryStaticPool
diff --git a/core/project_settings.cpp b/core/project_settings.cpp
index 983b2a2576..fc1a74801d 100644
--- a/core/project_settings.cpp
+++ b/core/project_settings.cpp
@@ -863,8 +863,6 @@ Error ProjectSettings::save_custom(const String &p_path, const CustomMap &p_cust
ERR_EXPLAIN("Unknown config file format: " + p_path);
ERR_FAIL_V(ERR_FILE_UNRECOGNIZED);
}
-
- return OK;
}
Variant _GLOBAL_DEF(const String &p_var, const Variant &p_default, bool p_restart_if_changed) {
diff --git a/core/ustring.cpp b/core/ustring.cpp
index ff28fa420d..18c48b4dad 100644
--- a/core/ustring.cpp
+++ b/core/ustring.cpp
@@ -481,8 +481,6 @@ signed char String::nocasecmp_to(const String &p_str) const {
this_str++;
that_str++;
}
-
- return 0; //should never reach anyway
}
signed char String::casecmp_to(const String &p_str) const {
@@ -513,8 +511,6 @@ signed char String::casecmp_to(const String &p_str) const {
this_str++;
that_str++;
}
-
- return 0; //should never reach anyway
}
signed char String::naturalnocasecmp_to(const String &p_str) const {
@@ -731,8 +727,6 @@ String String::get_slicec(CharType p_splitter, int p_slice) const {
i++;
}
-
- return String(); //no find!
}
Vector<String> String::split_spaces() const {
diff --git a/core/variant.cpp b/core/variant.cpp
index 9306867ac7..5b51a4e513 100644
--- a/core/variant.cpp
+++ b/core/variant.cpp
@@ -1171,8 +1171,6 @@ Variant::operator signed int() const {
return 0;
}
}
-
- return 0;
}
Variant::operator unsigned int() const {
@@ -1188,8 +1186,6 @@ Variant::operator unsigned int() const {
return 0;
}
}
-
- return 0;
}
Variant::operator int64_t() const {
@@ -1206,8 +1202,6 @@ Variant::operator int64_t() const {
return 0;
}
}
-
- return 0;
}
/*
@@ -1244,8 +1238,6 @@ Variant::operator uint64_t() const {
return 0;
}
}
-
- return 0;
}
#ifdef NEED_LONG_INT
@@ -1300,8 +1292,6 @@ Variant::operator signed short() const {
return 0;
}
}
-
- return 0;
}
Variant::operator unsigned short() const {
@@ -1317,8 +1307,6 @@ Variant::operator unsigned short() const {
return 0;
}
}
-
- return 0;
}
Variant::operator signed char() const {
@@ -1334,8 +1322,6 @@ Variant::operator signed char() const {
return 0;
}
}
-
- return 0;
}
Variant::operator unsigned char() const {
@@ -1351,8 +1337,6 @@ Variant::operator unsigned char() const {
return 0;
}
}
-
- return 0;
}
Variant::operator CharType() const {
@@ -1374,8 +1358,6 @@ Variant::operator float() const {
return 0;
}
}
-
- return 0;
}
Variant::operator double() const {
@@ -1391,8 +1373,6 @@ Variant::operator double() const {
return 0;
}
}
-
- return true;
}
Variant::operator StringName() const {
diff --git a/core/variant_op.cpp b/core/variant_op.cpp
index f3c9bcaa7e..d677c7776a 100644
--- a/core/variant_op.cpp
+++ b/core/variant_op.cpp
@@ -2183,7 +2183,8 @@ void Variant::set(const Variant &p_index, const Variant &p_value, bool *r_valid)
return;
}
- return obj->set(p_index, p_value, r_valid);
+ obj->set(p_index, p_value, r_valid);
+ return;
}
} break;
case DICTIONARY: {
diff --git a/core/variant_parser.cpp b/core/variant_parser.cpp
index d7371b0434..d5513bc2d7 100644
--- a/core/variant_parser.cpp
+++ b/core/variant_parser.cpp
@@ -436,8 +436,6 @@ Error VariantParser::_parse_enginecfg(Stream *p_stream, Vector<String> &strings,
line++;
}
}
-
- return OK;
}
template <class T>
@@ -799,8 +797,6 @@ Error VariantParser::parse_value(Token &token, Variant &value, Stream *p_stream,
}
}
- return OK;
-
} else if (id == "Resource" || id == "SubResource" || id == "ExtResource") {
get_token(p_stream, token, line, r_err_str);
@@ -864,8 +860,6 @@ Error VariantParser::parse_value(Token &token, Variant &value, Stream *p_stream,
return ERR_PARSE_ERROR;
}
}
-
- return OK;
#ifndef DISABLE_DEPRECATED
} else if (id == "InputEvent") {
@@ -1256,8 +1250,6 @@ Error VariantParser::parse_value(Token &token, Variant &value, Stream *p_stream,
r_err_str = "Expected value, got " + String(tk_name[token.type]) + ".";
return ERR_PARSE_ERROR;
}
-
- return ERR_PARSE_ERROR;
}
Error VariantParser::_parse_array(Array &array, Stream *p_stream, int &line, String &r_err_str, ResourceParser *p_res_parser) {
@@ -1301,8 +1293,6 @@ Error VariantParser::_parse_array(Array &array, Stream *p_stream, int &line, Str
array.push_back(v);
need_comma = true;
}
-
- return OK;
}
Error VariantParser::_parse_dictionary(Dictionary &object, Stream *p_stream, int &line, String &r_err_str, ResourceParser *p_res_parser) {
@@ -1372,8 +1362,6 @@ Error VariantParser::_parse_dictionary(Dictionary &object, Stream *p_stream, int
at_key = true;
}
}
-
- return OK;
}
Error VariantParser::_parse_tag(Token &token, Stream *p_stream, int &line, String &r_err_str, Tag &r_tag, ResourceParser *p_res_parser, bool p_simple_tag) {
@@ -1557,8 +1545,6 @@ Error VariantParser::parse_tag_assign_eof(Stream *p_stream, int &line, String &r
line++;
}
}
-
- return OK;
}
Error VariantParser::parse(Stream *p_stream, Variant &r_ret, String &r_err_str, int &r_err_line, ResourceParser *p_res_parser) {
diff --git a/doc/classes/AudioServer.xml b/doc/classes/AudioServer.xml
index dec1de42bc..f063cfe5ce 100644
--- a/doc/classes/AudioServer.xml
+++ b/doc/classes/AudioServer.xml
@@ -177,6 +177,13 @@
<description>
</description>
</method>
+ <method name="get_global_rate_scale">
+ <return type="float">
+ </return>
+ <description>
+ Returns the global rate scale at which audio is being played.
+ </description>
+ </method>
<method name="get_mix_rate" qualifiers="const">
<return type="float">
</return>
@@ -390,6 +397,15 @@
<description>
</description>
</method>
+ <method name="set_global_rate_scale">
+ <return type="void">
+ </return>
+ <argument index="0" name="scale" type="float">
+ </argument>
+ <description>
+ Scales the rate at which audio is played (i.e. setting it to [code]0.5[/code] will make the audio be played twice as fast).
+ </description>
+ </method>
<method name="swap_bus_effects">
<return type="void">
</return>
@@ -411,6 +427,16 @@
</description>
</method>
</methods>
+ <members>
+ <member name="bus_count" type="int" setter="set_bus_count" getter="get_bus_count">
+ Adds and removes buses to make the number of buses match [code]amount[/code].
+ </member>
+ <member name="device" type="string" setter="set_device" getter="get_device">
+ </member>
+ <member name="global_rate_scale" type="float" setter="set_global_rate_scale" getter="get_global_rate_scale">
+ Scales the rate at which audio is played (i.e. setting it to [code]0.5[/code] will make the audio be played twice as fast).
+ </member>
+ </members>
<signals>
<signal name="bus_layout_changed">
<description>
diff --git a/drivers/gles2/shaders/scene.glsl b/drivers/gles2/shaders/scene.glsl
index 2aef913ae8..ca222362e7 100644
--- a/drivers/gles2/shaders/scene.glsl
+++ b/drivers/gles2/shaders/scene.glsl
@@ -262,7 +262,7 @@ void light_compute(
#endif
SRGB_APPROX(specular_brdf_NL)
- specular_interp += specular_brdf_NL * light_color * attenuation;
+ specular_interp += specular_brdf_NL * light_color * attenuation * (1.0 / M_PI);
}
}
@@ -1641,18 +1641,30 @@ FRAGMENT_SHADER_CODE
#endif // defined(USE_REFLECTION_PROBE1) || defined(USE_REFLECTION_PROBE2)
- // scales the specular reflections, needs to be be computed before lighting happens,
- // but after environment and reflection probes are added
- //TODO: this curve is not really designed for gammaspace, should be adjusted
- const vec4 c0 = vec4(-1.0, -0.0275, -0.572, 0.022);
- const vec4 c1 = vec4(1.0, 0.0425, 1.04, -0.04);
- vec4 r = roughness * c0 + c1;
- float ndotv = clamp(dot(normal, eye_position), 0.0, 1.0);
- float a004 = min(r.x * r.x, exp2(-9.28 * ndotv)) * r.x + r.y;
- vec2 env = vec2(-1.04, 1.04) * a004 + r.zw;
+ // environment BRDF approximation
- vec3 f0 = F0(metallic, specular, albedo);
- specular_light *= env.x * f0 + env.y;
+ {
+
+#if defined(DIFFUSE_TOON)
+ //simplify for toon, as
+ specular_light *= specular * metallic * albedo * 2.0;
+#else
+
+ // scales the specular reflections, needs to be be computed before lighting happens,
+ // but after environment and reflection probes are added
+ //TODO: this curve is not really designed for gammaspace, should be adjusted
+ const vec4 c0 = vec4(-1.0, -0.0275, -0.572, 0.022);
+ const vec4 c1 = vec4(1.0, 0.0425, 1.04, -0.04);
+ vec4 r = roughness * c0 + c1;
+ float ndotv = clamp(dot(normal, eye_position), 0.0, 1.0);
+ float a004 = min(r.x * r.x, exp2(-9.28 * ndotv)) * r.x + r.y;
+ vec2 env = vec2(-1.04, 1.04) * a004 + r.zw;
+
+ vec3 f0 = F0(metallic, specular, albedo);
+ specular_light *= env.x * f0 + env.y;
+
+#endif
+ }
#ifdef USE_LIGHTMAP
//ambient light will come entirely from lightmap is lightmap is used
@@ -2048,6 +2060,17 @@ FRAGMENT_SHADER_CODE
specular_light += specular_interp * specular_blob_intensity * light_att;
diffuse_light += diffuse_interp * albedo * light_att;
+ // Same as above, needed for VERTEX_LIGHTING or else lights are too bright
+ const vec4 c0 = vec4(-1.0, -0.0275, -0.572, 0.022);
+ const vec4 c1 = vec4(1.0, 0.0425, 1.04, -0.04);
+ vec4 r = roughness * c0 + c1;
+ float ndotv = clamp(dot(normal, eye_position), 0.0, 1.0);
+ float a004 = min(r.x * r.x, exp2(-9.28 * ndotv)) * r.x + r.y;
+ vec2 env = vec2(-1.04, 1.04) * a004 + r.zw;
+
+ vec3 f0 = F0(metallic, specular, albedo);
+ specular_light *= env.x * f0 + env.y;
+
#else
//fragment lighting
light_compute(
@@ -2115,16 +2138,6 @@ FRAGMENT_SHADER_CODE
diffuse_light *= 1.0 - metallic;
ambient_light *= 1.0 - metallic;
- // environment BRDF approximation
-
- {
-
-#if defined(DIFFUSE_TOON)
- //simplify for toon, as
- specular_light *= specular * metallic * albedo * 2.0;
-#endif
- }
-
gl_FragColor = vec4(ambient_light + diffuse_light + specular_light, alpha);
//add emission if in base pass
diff --git a/drivers/gles3/rasterizer_storage_gles3.cpp b/drivers/gles3/rasterizer_storage_gles3.cpp
index 0f6db2dfb8..b280898188 100644
--- a/drivers/gles3/rasterizer_storage_gles3.cpp
+++ b/drivers/gles3/rasterizer_storage_gles3.cpp
@@ -4644,7 +4644,6 @@ Transform2D RasterizerStorageGLES3::multimesh_instance_get_transform_2d(RID p_mu
}
Color RasterizerStorageGLES3::multimesh_instance_get_color(RID p_multimesh, int p_index) const {
-
MultiMesh *multimesh = multimesh_owner.getornull(p_multimesh);
ERR_FAIL_COND_V(!multimesh, Color());
ERR_FAIL_INDEX_V(p_index, multimesh->size, Color());
diff --git a/drivers/unix/net_socket_posix.cpp b/drivers/unix/net_socket_posix.cpp
index 16562e2c8f..f8e771aea0 100644
--- a/drivers/unix/net_socket_posix.cpp
+++ b/drivers/unix/net_socket_posix.cpp
@@ -684,10 +684,10 @@ Ref<NetSocket> NetSocketPosix::accept(IP_Address &r_ip, uint16_t &r_port) {
return Ref<NetSocket>(ns);
}
-Error NetSocketPosix::join_multicast_group(const IP_Address &p_ip, String p_if_name) {
- return _change_multicast_group(p_ip, p_if_name, true);
+Error NetSocketPosix::join_multicast_group(const IP_Address &p_multi_address, String p_if_name) {
+ return _change_multicast_group(p_multi_address, p_if_name, true);
}
-Error NetSocketPosix::leave_multicast_group(const IP_Address &p_ip, String p_if_name) {
- return _change_multicast_group(p_ip, p_if_name, false);
+Error NetSocketPosix::leave_multicast_group(const IP_Address &p_multi_address, String p_if_name) {
+ return _change_multicast_group(p_multi_address, p_if_name, false);
}
diff --git a/editor/animation_bezier_editor.cpp b/editor/animation_bezier_editor.cpp
index e524dffd43..14ea18f885 100644
--- a/editor/animation_bezier_editor.cpp
+++ b/editor/animation_bezier_editor.cpp
@@ -275,8 +275,6 @@ void AnimationBezierTrackEdit::_notification(int p_what) {
int margin = 0;
{
- int ofs = 0;
-
NodePath path = animation->track_get_path(track);
Node *node = NULL;
@@ -290,6 +288,8 @@ void AnimationBezierTrackEdit::_notification(int p_what) {
int h = font->get_height();
if (node) {
+ int ofs = 0;
+
Ref<Texture> icon = EditorNode::get_singleton()->get_object_icon(node, "Node");
h = MAX(h, icon->get_height());
diff --git a/editor/animation_track_editor_plugins.cpp b/editor/animation_track_editor_plugins.cpp
index 07dbc1fd81..226eef9c1e 100644
--- a/editor/animation_track_editor_plugins.cpp
+++ b/editor/animation_track_editor_plugins.cpp
@@ -1009,7 +1009,7 @@ void AnimationTrackEditTypeAudio::drop_data(const Point2 &p_point, const Variant
}
}
- return AnimationTrackEdit::drop_data(p_point, p_data);
+ AnimationTrackEdit::drop_data(p_point, p_data);
}
void AnimationTrackEditTypeAudio::_gui_input(const Ref<InputEvent> &p_event) {
diff --git a/editor/create_dialog.cpp b/editor/create_dialog.cpp
index 9a152d663a..547d627925 100644
--- a/editor/create_dialog.cpp
+++ b/editor/create_dialog.cpp
@@ -329,8 +329,9 @@ void CreateDialog::_update_search() {
if (cpp_type && !ClassDB::can_instance(type))
continue; // can't create what can't be instanced
- bool skip = false;
if (cpp_type) {
+ bool skip = false;
+
for (Set<StringName>::Element *E = type_blacklist.front(); E && !skip; E = E->next()) {
if (ClassDB::is_parent_class(type, E->get()))
skip = true;
diff --git a/editor/editor_plugin.cpp b/editor/editor_plugin.cpp
index 78c38af555..90d6c3a983 100644
--- a/editor/editor_plugin.cpp
+++ b/editor/editor_plugin.cpp
@@ -200,7 +200,7 @@ ScriptEditor *EditorInterface::get_script_editor() {
}
void EditorInterface::select_file(const String &p_file) {
- return EditorNode::get_singleton()->get_filesystem_dock()->select_file(p_file);
+ EditorNode::get_singleton()->get_filesystem_dock()->select_file(p_file);
}
String EditorInterface::get_selected_path() const {
diff --git a/editor/editor_properties_array_dict.cpp b/editor/editor_properties_array_dict.cpp
index a49f9489e1..347699c632 100644
--- a/editor/editor_properties_array_dict.cpp
+++ b/editor/editor_properties_array_dict.cpp
@@ -183,16 +183,20 @@ void EditorPropertyArray::_property_changed(const String &p_prop, Variant p_valu
void EditorPropertyArray::_change_type(Object *p_button, int p_index) {
Button *button = Object::cast_to<Button>(p_button);
-
+ changing_type_idx = p_index;
Rect2 rect = button->get_global_rect();
change_type->set_as_minsize();
change_type->set_global_position(rect.position + rect.size - Vector2(change_type->get_combined_minimum_size().x, 0));
change_type->popup();
- changing_type_idx = p_index;
}
void EditorPropertyArray::_change_type_menu(int p_index) {
+ if (p_index == Variant::VARIANT_MAX) {
+ _remove_pressed(changing_type_idx);
+ return;
+ }
+
Variant value;
Variant::CallError ce;
value = Variant::construct(Variant::Type(p_index), NULL, 0, ce);
@@ -204,6 +208,7 @@ void EditorPropertyArray::_change_type_menu(int p_index) {
if (array.get_type() == Variant::ARRAY) {
array = array.call("duplicate"); //dupe, so undo/redo works better
}
+
object->set_array(array);
update_property();
}
@@ -356,21 +361,27 @@ void EditorPropertyArray::update_property() {
prop->set_selectable(false);
prop->connect("property_changed", this, "_property_changed");
prop->connect("object_id_selected", this, "_object_id_selected");
- if (array.get_type() == Variant::ARRAY) {
- HBoxContainer *hb = memnew(HBoxContainer);
- vbox->add_child(hb);
- hb->add_child(prop);
- prop->set_h_size_flags(SIZE_EXPAND_FILL);
-
- if (subtype == Variant::NIL) {
- Button *edit = memnew(Button);
- edit->set_icon(get_icon("Edit", "EditorIcons"));
- hb->add_child(edit);
- edit->connect("pressed", this, "_change_type", varray(edit, i + offset));
- }
+ prop->set_h_size_flags(SIZE_EXPAND_FILL);
+
+ HBoxContainer *hb = memnew(HBoxContainer);
+
+ vbox->add_child(hb);
+ hb->add_child(prop);
+ bool is_untyped_array = array.get_type() == Variant::ARRAY && subtype == Variant::NIL;
+
+ if (is_untyped_array) {
+
+ Button *edit = memnew(Button);
+ edit->set_icon(get_icon("Edit", "EditorIcons"));
+ hb->add_child(edit);
+ edit->connect("pressed", this, "_change_type", varray(edit, i + offset));
} else {
- vbox->add_child(prop);
+
+ Button *remove = memnew(Button);
+ remove->set_icon(get_icon("Remove", "EditorIcons"));
+ remove->connect("pressed", this, "_remove_pressed", varray(i + offset));
+ hb->add_child(remove);
}
prop->update_property();
@@ -388,8 +399,21 @@ void EditorPropertyArray::update_property() {
#endif
}
-void EditorPropertyArray::_notification(int p_what) {
+void EditorPropertyArray::_remove_pressed(int p_index) {
+ Variant array = object->get_array();
+ array.call("remove", p_index);
+
+ if (array.get_type() == Variant::ARRAY) {
+ array = array.call("duplicate");
+ }
+
+ emit_changed(get_edited_property(), array, "", false);
+ object->set_array(array);
+ update_property();
+}
+
+void EditorPropertyArray::_notification(int p_what) {
if (p_what == NOTIFICATION_ENTER_TREE || p_what == NOTIFICATION_THEME_CHANGED) {
}
}
@@ -476,6 +500,7 @@ void EditorPropertyArray::_bind_methods() {
ClassDB::bind_method("_change_type", &EditorPropertyArray::_change_type);
ClassDB::bind_method("_change_type_menu", &EditorPropertyArray::_change_type_menu);
ClassDB::bind_method("_object_id_selected", &EditorPropertyArray::_object_id_selected);
+ ClassDB::bind_method("_remove_pressed", &EditorPropertyArray::_remove_pressed);
}
EditorPropertyArray::EditorPropertyArray() {
@@ -498,11 +523,13 @@ EditorPropertyArray::EditorPropertyArray() {
change_type = memnew(PopupMenu);
add_child(change_type);
change_type->connect("id_pressed", this, "_change_type_menu");
- changing_type_idx = -1;
+
for (int i = 0; i < Variant::VARIANT_MAX; i++) {
String type = Variant::get_type_name(Variant::Type(i));
change_type->add_item(type, i);
}
+ change_type->add_separator();
+ change_type->add_item(TTR("Remove Item"), Variant::VARIANT_MAX);
changing_type_idx = -1;
subtype = Variant::NIL;
@@ -995,7 +1022,7 @@ EditorPropertyDictionary::EditorPropertyDictionary() {
change_type = memnew(PopupMenu);
add_child(change_type);
change_type->connect("id_pressed", this, "_change_type_menu");
- changing_type_idx = -1;
+
for (int i = 0; i < Variant::VARIANT_MAX; i++) {
String type = Variant::get_type_name(Variant::Type(i));
change_type->add_item(type, i);
diff --git a/editor/editor_properties_array_dict.h b/editor/editor_properties_array_dict.h
index 18519c754a..2fe7c07d56 100644
--- a/editor/editor_properties_array_dict.h
+++ b/editor/editor_properties_array_dict.h
@@ -105,6 +105,7 @@ class EditorPropertyArray : public EditorProperty {
void _change_type_menu(int p_index);
void _object_id_selected(const String &p_property, ObjectID p_id);
+ void _remove_pressed(int p_index);
protected:
static void _bind_methods();
diff --git a/editor/groups_editor.cpp b/editor/groups_editor.cpp
index aeded90a6b..5a8dc205c2 100644
--- a/editor/groups_editor.cpp
+++ b/editor/groups_editor.cpp
@@ -69,7 +69,7 @@ void GroupDialog::_load_nodes(Node *p_current) {
keep = false;
}
- TreeItem *node;
+ TreeItem *node = NULL;
NodePath path = scene_tree->get_edited_scene_root()->get_path_to(p_current);
if (keep && p_current->is_in_group(selected_group)) {
if (remove_filter->get_text().is_subsequence_ofi(String(p_current->get_name()))) {
diff --git a/editor/plugins/collision_shape_2d_editor_plugin.h b/editor/plugins/collision_shape_2d_editor_plugin.h
index 965e6c8827..10a1a6bd98 100644
--- a/editor/plugins/collision_shape_2d_editor_plugin.h
+++ b/editor/plugins/collision_shape_2d_editor_plugin.h
@@ -89,7 +89,7 @@ class CollisionShape2DEditorPlugin : public EditorPlugin {
public:
virtual bool forward_canvas_gui_input(const Ref<InputEvent> &p_event) { return collision_shape_2d_editor->forward_canvas_gui_input(p_event); }
- virtual void forward_canvas_draw_over_viewport(Control *p_overlay) { return collision_shape_2d_editor->forward_canvas_draw_over_viewport(p_overlay); }
+ virtual void forward_canvas_draw_over_viewport(Control *p_overlay) { collision_shape_2d_editor->forward_canvas_draw_over_viewport(p_overlay); }
virtual String get_name() const { return "CollisionShape2D"; }
bool has_main_screen() const { return false; }
diff --git a/editor/plugins/curve_editor_plugin.cpp b/editor/plugins/curve_editor_plugin.cpp
index 3b1d728b8b..d2d2b8f130 100644
--- a/editor/plugins/curve_editor_plugin.cpp
+++ b/editor/plugins/curve_editor_plugin.cpp
@@ -156,9 +156,9 @@ void CurveEditor::on_gui_input(const Ref<InputEvent> &p_event) {
Vector2 mpos = mm.get_position();
if (_dragging && _curve_ref.is_valid()) {
- Curve &curve = **_curve_ref;
if (_selected_point != -1) {
+ Curve &curve = **_curve_ref;
if (!_has_undo_data) {
// Save full curve state before dragging points,
diff --git a/editor/plugins/path_2d_editor_plugin.h b/editor/plugins/path_2d_editor_plugin.h
index 4edd17d146..44472f7a81 100644
--- a/editor/plugins/path_2d_editor_plugin.h
+++ b/editor/plugins/path_2d_editor_plugin.h
@@ -123,7 +123,7 @@ class Path2DEditorPlugin : public EditorPlugin {
public:
virtual bool forward_canvas_gui_input(const Ref<InputEvent> &p_event) { return path2d_editor->forward_gui_input(p_event); }
- virtual void forward_canvas_draw_over_viewport(Control *p_overlay) { return path2d_editor->forward_canvas_draw_over_viewport(p_overlay); }
+ virtual void forward_canvas_draw_over_viewport(Control *p_overlay) { path2d_editor->forward_canvas_draw_over_viewport(p_overlay); }
virtual String get_name() const { return "Path2D"; }
bool has_main_screen() const { return false; }
diff --git a/editor/plugins/script_editor_plugin.cpp b/editor/plugins/script_editor_plugin.cpp
index 1b00889e9a..d999f3189e 100644
--- a/editor/plugins/script_editor_plugin.cpp
+++ b/editor/plugins/script_editor_plugin.cpp
@@ -3463,7 +3463,7 @@ void ScriptEditorPlugin::get_window_layout(Ref<ConfigFile> p_layout) {
void ScriptEditorPlugin::get_breakpoints(List<String> *p_breakpoints) {
- return script_editor->get_breakpoints(p_breakpoints);
+ script_editor->get_breakpoints(p_breakpoints);
}
void ScriptEditorPlugin::edited_scene_changed() {
diff --git a/editor/plugins/script_text_editor.cpp b/editor/plugins/script_text_editor.cpp
index 9c57dd53f1..f705970d79 100644
--- a/editor/plugins/script_text_editor.cpp
+++ b/editor/plugins/script_text_editor.cpp
@@ -644,6 +644,43 @@ void ScriptTextEditor::_validate_script() {
emit_signal("edited_script_changed");
}
+void ScriptTextEditor::_update_bookmark_list() {
+
+ bookmarks_menu->get_popup()->clear();
+
+ bookmarks_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/toggle_bookmark"), BOOKMARK_TOGGLE);
+ bookmarks_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/remove_all_bookmarks"), BOOKMARK_REMOVE_ALL);
+ bookmarks_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/goto_next_bookmark"), BOOKMARK_GOTO_NEXT);
+ bookmarks_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/goto_previous_bookmark"), BOOKMARK_GOTO_PREV);
+
+ Array bookmark_list = code_editor->get_text_edit()->get_bookmarks_array();
+ if (bookmark_list.size() == 0) {
+ return;
+ }
+
+ bookmarks_menu->get_popup()->add_separator();
+
+ for (int i = 0; i < bookmark_list.size(); i++) {
+ String line = code_editor->get_text_edit()->get_line(bookmark_list[i]).strip_edges();
+ // Limit the size of the line if too big.
+ if (line.length() > 50) {
+ line = line.substr(0, 50);
+ }
+
+ bookmarks_menu->get_popup()->add_item(String::num((int)bookmark_list[i] + 1) + " - \"" + line + "\"");
+ bookmarks_menu->get_popup()->set_item_metadata(bookmarks_menu->get_popup()->get_item_count() - 1, bookmark_list[i]);
+ }
+}
+
+void ScriptTextEditor::_bookmark_item_pressed(int p_idx) {
+
+ if (p_idx < 4) { // Any item before the separator.
+ _edit_option(bookmarks_menu->get_popup()->get_item_id(p_idx));
+ } else {
+ code_editor->goto_line(bookmarks_menu->get_popup()->get_item_metadata(p_idx));
+ }
+}
+
static Vector<Node *> _find_all_node_for_script(Node *p_base, Node *p_current, const Ref<Script> &p_script) {
Vector<Node *> nodes;
@@ -1092,7 +1129,7 @@ void ScriptTextEditor::_edit_option(int p_op) {
String selected_text = code_editor->get_text_edit()->get_selection_text();
// Yep, because it doesn't make sense to instance this dialog for every single script open...
- // So this will be delegated to the ScriptEditor
+ // So this will be delegated to the ScriptEditor.
emit_signal("search_in_files_requested", selected_text);
} break;
@@ -1258,6 +1295,8 @@ void ScriptTextEditor::_change_syntax_highlighter(int p_idx) {
void ScriptTextEditor::_bind_methods() {
ClassDB::bind_method("_validate_script", &ScriptTextEditor::_validate_script);
+ ClassDB::bind_method("_update_bookmark_list", &ScriptTextEditor::_update_bookmark_list);
+ ClassDB::bind_method("_bookmark_item_pressed", &ScriptTextEditor::_bookmark_item_pressed);
ClassDB::bind_method("_load_theme_settings", &ScriptTextEditor::_load_theme_settings);
ClassDB::bind_method("_breakpoint_toggled", &ScriptTextEditor::_breakpoint_toggled);
ClassDB::bind_method("_lookup_connections", &ScriptTextEditor::_lookup_connections);
@@ -1708,18 +1747,16 @@ ScriptTextEditor::ScriptTextEditor() {
search_menu->get_popup()->connect("id_pressed", this, "_edit_option");
- PopupMenu *bookmarks = memnew(PopupMenu);
- bookmarks->set_name("bookmarks");
- edit_menu->get_popup()->add_child(bookmarks);
- edit_menu->get_popup()->add_submenu_item(TTR("Bookmarks"), "bookmarks");
- bookmarks->add_shortcut(ED_GET_SHORTCUT("script_text_editor/toggle_bookmark"), BOOKMARK_TOGGLE);
- bookmarks->add_shortcut(ED_GET_SHORTCUT("script_text_editor/remove_all_bookmarks"), BOOKMARK_REMOVE_ALL);
- bookmarks->add_shortcut(ED_GET_SHORTCUT("script_text_editor/goto_next_bookmark"), BOOKMARK_GOTO_NEXT);
- bookmarks->add_shortcut(ED_GET_SHORTCUT("script_text_editor/goto_previous_bookmark"), BOOKMARK_GOTO_PREV);
- bookmarks->connect("id_pressed", this, "_edit_option");
-
edit_hb->add_child(edit_menu);
+ bookmarks_menu = memnew(MenuButton);
+ edit_hb->add_child(bookmarks_menu);
+ bookmarks_menu->set_text(TTR("Bookmarks"));
+ bookmarks_menu->set_switch_on_hover(true);
+ _update_bookmark_list();
+ bookmarks_menu->connect("about_to_show", this, "_update_bookmark_list");
+ bookmarks_menu->get_popup()->connect("index_pressed", this, "_bookmark_item_pressed");
+
quick_open = memnew(ScriptEditorQuickOpen);
add_child(quick_open);
quick_open->connect("goto_line", this, "_goto_line");
diff --git a/editor/plugins/script_text_editor.h b/editor/plugins/script_text_editor.h
index 89975e061e..f83f1ea759 100644
--- a/editor/plugins/script_text_editor.h
+++ b/editor/plugins/script_text_editor.h
@@ -70,6 +70,7 @@ class ScriptTextEditor : public ScriptEditorBase {
MenuButton *edit_menu;
MenuButton *search_menu;
+ MenuButton *bookmarks_menu;
PopupMenu *highlighter_menu;
PopupMenu *context_menu;
@@ -144,8 +145,9 @@ protected:
static void _code_complete_scripts(void *p_ud, const String &p_code, List<String> *r_options, bool &r_force);
void _breakpoint_toggled(int p_row);
- //no longer virtual
- void _validate_script();
+ void _validate_script(); // No longer virtual.
+ void _update_bookmark_list();
+ void _bookmark_item_pressed(int p_idx);
void _code_complete_script(const String &p_code, List<String> *r_options, bool &r_force);
void _load_theme_settings();
void _set_theme_for_script();
diff --git a/editor/plugins/shader_editor_plugin.cpp b/editor/plugins/shader_editor_plugin.cpp
index d02817f6e8..04d13f0027 100644
--- a/editor/plugins/shader_editor_plugin.cpp
+++ b/editor/plugins/shader_editor_plugin.cpp
@@ -386,6 +386,9 @@ void ShaderEditor::_bind_methods() {
ClassDB::bind_method("_editor_settings_changed", &ShaderEditor::_editor_settings_changed);
ClassDB::bind_method("_text_edit_gui_input", &ShaderEditor::_text_edit_gui_input);
+ ClassDB::bind_method("_update_bookmark_list", &ShaderEditor::_update_bookmark_list);
+ ClassDB::bind_method("_bookmark_item_pressed", &ShaderEditor::_bookmark_item_pressed);
+
ClassDB::bind_method("_menu_option", &ShaderEditor::_menu_option);
ClassDB::bind_method("_params_changed", &ShaderEditor::_params_changed);
ClassDB::bind_method("apply_shaders", &ShaderEditor::apply_shaders);
@@ -521,6 +524,43 @@ void ShaderEditor::_text_edit_gui_input(const Ref<InputEvent> &ev) {
}
}
+void ShaderEditor::_update_bookmark_list() {
+
+ bookmarks_menu->get_popup()->clear();
+
+ bookmarks_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/toggle_bookmark"), BOOKMARK_TOGGLE);
+ bookmarks_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/remove_all_bookmarks"), BOOKMARK_REMOVE_ALL);
+ bookmarks_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/goto_next_bookmark"), BOOKMARK_GOTO_NEXT);
+ bookmarks_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/goto_previous_bookmark"), BOOKMARK_GOTO_PREV);
+
+ Array bookmark_list = shader_editor->get_text_edit()->get_bookmarks_array();
+ if (bookmark_list.size() == 0) {
+ return;
+ }
+
+ bookmarks_menu->get_popup()->add_separator();
+
+ for (int i = 0; i < bookmark_list.size(); i++) {
+ String line = shader_editor->get_text_edit()->get_line(bookmark_list[i]).strip_edges();
+ // Limit the size of the line if too big.
+ if (line.length() > 50) {
+ line = line.substr(0, 50);
+ }
+
+ bookmarks_menu->get_popup()->add_item(String::num((int)bookmark_list[i] + 1) + " - \"" + line + "\"");
+ bookmarks_menu->get_popup()->set_item_metadata(bookmarks_menu->get_popup()->get_item_count() - 1, bookmark_list[i]);
+ }
+}
+
+void ShaderEditor::_bookmark_item_pressed(int p_idx) {
+
+ if (p_idx < 4) { // Any item before the separator.
+ _menu_option(bookmarks_menu->get_popup()->get_item_id(p_idx));
+ } else {
+ shader_editor->goto_line(bookmarks_menu->get_popup()->get_item_metadata(p_idx));
+ }
+}
+
void ShaderEditor::_make_context_menu(bool p_selection) {
context_menu->clear();
@@ -539,6 +579,7 @@ void ShaderEditor::_make_context_menu(bool p_selection) {
context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/indent_left"), EDIT_INDENT_LEFT);
context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/indent_right"), EDIT_INDENT_RIGHT);
context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/toggle_comment"), EDIT_TOGGLE_COMMENT);
+ context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/toggle_bookmark"), BOOKMARK_TOGGLE);
context_menu->set_position(get_global_transform().xform(get_local_mouse_position()));
context_menu->set_size(Vector2(1, 1));
@@ -609,20 +650,18 @@ ShaderEditor::ShaderEditor(EditorNode *p_node) {
search_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/goto_line"), SEARCH_GOTO_LINE);
search_menu->get_popup()->connect("id_pressed", this, "_menu_option");
- PopupMenu *bookmarks = memnew(PopupMenu);
- bookmarks->set_name("bookmarks");
- edit_menu->get_popup()->add_child(bookmarks);
- edit_menu->get_popup()->add_submenu_item(TTR("Bookmarks"), "bookmarks");
- bookmarks->add_shortcut(ED_GET_SHORTCUT("script_text_editor/toggle_bookmark"), BOOKMARK_TOGGLE);
- bookmarks->add_shortcut(ED_GET_SHORTCUT("script_text_editor/remove_all_bookmarks"), BOOKMARK_REMOVE_ALL);
- bookmarks->add_shortcut(ED_GET_SHORTCUT("script_text_editor/goto_next_bookmark"), BOOKMARK_GOTO_NEXT);
- bookmarks->add_shortcut(ED_GET_SHORTCUT("script_text_editor/goto_previous_bookmark"), BOOKMARK_GOTO_PREV);
- bookmarks->connect("id_pressed", this, "_edit_option");
+ bookmarks_menu = memnew(MenuButton);
+ bookmarks_menu->set_text(TTR("Bookmarks"));
+ bookmarks_menu->set_switch_on_hover(true);
+ _update_bookmark_list();
+ bookmarks_menu->connect("about_to_show", this, "_update_bookmark_list");
+ bookmarks_menu->get_popup()->connect("index_pressed", this, "_bookmark_item_pressed");
add_child(main_container);
main_container->add_child(hbc);
hbc->add_child(search_menu);
hbc->add_child(edit_menu);
+ hbc->add_child(bookmarks_menu);
hbc->add_style_override("panel", p_node->get_gui_base()->get_stylebox("ScriptEditorPanel", "EditorStyles"));
main_container->add_child(shader_editor);
diff --git a/editor/plugins/shader_editor_plugin.h b/editor/plugins/shader_editor_plugin.h
index b56c1451ad..f01e39189f 100644
--- a/editor/plugins/shader_editor_plugin.h
+++ b/editor/plugins/shader_editor_plugin.h
@@ -99,6 +99,7 @@ class ShaderEditor : public PanelContainer {
MenuButton *edit_menu;
MenuButton *search_menu;
+ MenuButton *bookmarks_menu;
MenuButton *settings_menu;
PopupMenu *context_menu;
uint64_t idle;
@@ -124,6 +125,9 @@ protected:
void _make_context_menu(bool p_selection);
void _text_edit_gui_input(const Ref<InputEvent> &ev);
+ void _update_bookmark_list();
+ void _bookmark_item_pressed(int p_idx);
+
public:
void apply_shaders();
diff --git a/editor/plugins/text_editor.cpp b/editor/plugins/text_editor.cpp
index 787813336d..fae88f4eb7 100644
--- a/editor/plugins/text_editor.cpp
+++ b/editor/plugins/text_editor.cpp
@@ -219,6 +219,43 @@ void TextEditor::_validate_script() {
emit_signal("edited_script_changed");
}
+void TextEditor::_update_bookmark_list() {
+
+ bookmarks_menu->get_popup()->clear();
+
+ bookmarks_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/toggle_bookmark"), BOOKMARK_TOGGLE);
+ bookmarks_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/remove_all_bookmarks"), BOOKMARK_REMOVE_ALL);
+ bookmarks_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/goto_next_bookmark"), BOOKMARK_GOTO_NEXT);
+ bookmarks_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/goto_previous_bookmark"), BOOKMARK_GOTO_PREV);
+
+ Array bookmark_list = code_editor->get_text_edit()->get_bookmarks_array();
+ if (bookmark_list.size() == 0) {
+ return;
+ }
+
+ bookmarks_menu->get_popup()->add_separator();
+
+ for (int i = 0; i < bookmark_list.size(); i++) {
+ String line = code_editor->get_text_edit()->get_line(bookmark_list[i]).strip_edges();
+ // Limit the size of the line if too big.
+ if (line.length() > 50) {
+ line = line.substr(0, 50);
+ }
+
+ bookmarks_menu->get_popup()->add_item(String::num((int)bookmark_list[i] + 1) + " - \"" + line + "\"");
+ bookmarks_menu->get_popup()->set_item_metadata(bookmarks_menu->get_popup()->get_item_count() - 1, bookmark_list[i]);
+ }
+}
+
+void TextEditor::_bookmark_item_pressed(int p_idx) {
+
+ if (p_idx < 4) { // Any item before the separator.
+ _edit_option(bookmarks_menu->get_popup()->get_item_id(p_idx));
+ } else {
+ code_editor->goto_line(bookmarks_menu->get_popup()->get_item_metadata(p_idx));
+ }
+}
+
void TextEditor::apply_code() {
text_file->set_text(code_editor->get_text_edit()->get_text());
}
@@ -471,6 +508,8 @@ void TextEditor::_convert_case(CodeTextEditor::CaseStyle p_case) {
void TextEditor::_bind_methods() {
ClassDB::bind_method("_validate_script", &TextEditor::_validate_script);
+ ClassDB::bind_method("_update_bookmark_list", &TextEditor::_update_bookmark_list);
+ ClassDB::bind_method("_bookmark_item_pressed", &TextEditor::_bookmark_item_pressed);
ClassDB::bind_method("_load_theme_settings", &TextEditor::_load_theme_settings);
ClassDB::bind_method("_edit_option", &TextEditor::_edit_option);
ClassDB::bind_method("_change_syntax_highlighter", &TextEditor::_change_syntax_highlighter);
@@ -547,6 +586,7 @@ void TextEditor::_make_context_menu(bool p_selection, bool p_can_fold, bool p_is
context_menu->add_separator();
context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/indent_left"), EDIT_INDENT_LEFT);
context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/indent_right"), EDIT_INDENT_RIGHT);
+ context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/toggle_bookmark"), BOOKMARK_TOGGLE);
if (p_selection) {
context_menu->add_separator();
@@ -584,6 +624,7 @@ TextEditor::TextEditor() {
search_menu = memnew(MenuButton);
edit_hb->add_child(search_menu);
search_menu->set_text(TTR("Search"));
+ search_menu->set_switch_on_hover(true);
search_menu->get_popup()->connect("id_pressed", this, "_edit_option");
search_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/find"), SEARCH_FIND);
@@ -598,6 +639,7 @@ TextEditor::TextEditor() {
edit_menu = memnew(MenuButton);
edit_menu->set_text(TTR("Edit"));
+ edit_menu->set_switch_on_hover(true);
edit_menu->get_popup()->connect("id_pressed", this, "_edit_option");
edit_hb->add_child(edit_menu);
@@ -642,15 +684,13 @@ TextEditor::TextEditor() {
highlighter_menu->add_radio_check_item(TTR("Standard"));
highlighter_menu->connect("id_pressed", this, "_change_syntax_highlighter");
- PopupMenu *bookmarks = memnew(PopupMenu);
- bookmarks->set_name("bookmarks");
- edit_menu->get_popup()->add_child(bookmarks);
- edit_menu->get_popup()->add_submenu_item(TTR("Bookmarks"), "bookmarks");
- bookmarks->add_shortcut(ED_GET_SHORTCUT("script_text_editor/toggle_bookmark"), BOOKMARK_TOGGLE);
- bookmarks->add_shortcut(ED_GET_SHORTCUT("script_text_editor/remove_all_bookmarks"), BOOKMARK_REMOVE_ALL);
- bookmarks->add_shortcut(ED_GET_SHORTCUT("script_text_editor/goto_next_bookmark"), BOOKMARK_GOTO_NEXT);
- bookmarks->add_shortcut(ED_GET_SHORTCUT("script_text_editor/goto_previous_bookmark"), BOOKMARK_GOTO_PREV);
- bookmarks->connect("id_pressed", this, "_edit_option");
+ bookmarks_menu = memnew(MenuButton);
+ edit_hb->add_child(bookmarks_menu);
+ bookmarks_menu->set_text(TTR("Bookmarks"));
+ bookmarks_menu->set_switch_on_hover(true);
+ _update_bookmark_list();
+ bookmarks_menu->connect("about_to_show", this, "_update_bookmark_list");
+ bookmarks_menu->get_popup()->connect("index_pressed", this, "_bookmark_item_pressed");
code_editor->get_text_edit()->set_drag_forwarding(this);
}
diff --git a/editor/plugins/text_editor.h b/editor/plugins/text_editor.h
index 277e93fd39..ae0c0bcf93 100644
--- a/editor/plugins/text_editor.h
+++ b/editor/plugins/text_editor.h
@@ -46,6 +46,7 @@ private:
MenuButton *edit_menu;
PopupMenu *highlighter_menu;
MenuButton *search_menu;
+ MenuButton *bookmarks_menu;
PopupMenu *context_menu;
GotoLineDialog *goto_line_dialog;
@@ -110,6 +111,9 @@ protected:
void _validate_script();
+ void _update_bookmark_list();
+ void _bookmark_item_pressed(int p_idx);
+
public:
virtual void add_syntax_highlighter(SyntaxHighlighter *p_highlighter);
virtual void set_syntax_highlighter(SyntaxHighlighter *p_highlighter);
diff --git a/editor/plugins/texture_region_editor_plugin.cpp b/editor/plugins/texture_region_editor_plugin.cpp
index 4e15bd5116..8f58fbd6ab 100644
--- a/editor/plugins/texture_region_editor_plugin.cpp
+++ b/editor/plugins/texture_region_editor_plugin.cpp
@@ -192,8 +192,8 @@ void TextureRegionEditor::_region_draw() {
}
updating_scroll = false;
- float margins[4];
if (node_ninepatch || obj_styleBox.is_valid()) {
+ float margins[4];
if (node_ninepatch) {
margins[0] = node_ninepatch->get_patch_margin(MARGIN_TOP);
margins[1] = node_ninepatch->get_patch_margin(MARGIN_BOTTOM);
@@ -204,6 +204,11 @@ void TextureRegionEditor::_region_draw() {
margins[1] = obj_styleBox->get_margin_size(MARGIN_BOTTOM);
margins[2] = obj_styleBox->get_margin_size(MARGIN_LEFT);
margins[3] = obj_styleBox->get_margin_size(MARGIN_RIGHT);
+ } else {
+ margins[0] = 0;
+ margins[1] = 0;
+ margins[2] = 0;
+ margins[3] = 0;
}
Vector2 pos[4] = {
mtx.basis_xform(Vector2(0, margins[0])) + Vector2(0, endpoints[0].y - draw_ofs.y * draw_zoom),
diff --git a/editor/project_settings_editor.cpp b/editor/project_settings_editor.cpp
index 3caa10b4e2..001846604c 100644
--- a/editor/project_settings_editor.cpp
+++ b/editor/project_settings_editor.cpp
@@ -257,7 +257,7 @@ void ProjectSettingsEditor::_device_input_add() {
Ref<InputEventJoypadMotion> jm;
jm.instance();
jm->set_axis(device_index->get_selected() >> 1);
- jm->set_axis_value(device_index->get_selected() & 1 ? 1 : -1);
+ jm->set_axis_value((device_index->get_selected() & 1) ? 1 : -1);
jm->set_device(_get_current_device());
for (int i = 0; i < events.size(); i++) {
@@ -483,7 +483,7 @@ void ProjectSettingsEditor::_add_item(int p_item, Ref<InputEvent> p_exiting_even
for (int i = 0; i < JOY_AXIS_MAX * 2; i++) {
String desc = _axis_names[i];
- device_index->add_item(TTR("Axis") + " " + itos(i / 2) + " " + (i & 1 ? "+" : "-") + desc);
+ device_index->add_item(TTR("Axis") + " " + itos(i / 2) + " " + ((i & 1) ? "+" : "-") + desc);
}
device_input->popup_centered_minsize(Size2(350, 95) * EDSCALE);
diff --git a/editor/scene_tree_dock.cpp b/editor/scene_tree_dock.cpp
index a15ae2efda..442de08ffa 100644
--- a/editor/scene_tree_dock.cpp
+++ b/editor/scene_tree_dock.cpp
@@ -89,6 +89,8 @@ void SceneTreeDock::_unhandled_key_input(Ref<InputEvent> p_event) {
_tool_selected(TOOL_NEW);
} else if (ED_IS_SHORTCUT("scene_tree/instance_scene", p_event)) {
_tool_selected(TOOL_INSTANCE);
+ } else if (ED_IS_SHORTCUT("scene_tree/expand_collapse_all", p_event)) {
+ _tool_selected(TOOL_EXPAND_COLLAPSE);
} else if (ED_IS_SHORTCUT("scene_tree/change_node_type", p_event)) {
_tool_selected(TOOL_REPLACE);
} else if (ED_IS_SHORTCUT("scene_tree/duplicate", p_event)) {
@@ -370,6 +372,23 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
quick_open->set_title(TTR("Instance Child Scene"));
} break;
+ case TOOL_EXPAND_COLLAPSE: {
+
+ if (!scene_tree->get_selected())
+ break;
+
+ Tree *tree = scene_tree->get_scene_tree();
+ TreeItem *selected_item = tree->get_selected();
+
+ if (!selected_item)
+ selected_item = tree->get_root();
+
+ bool collapsed = _is_collapsed_recursive(selected_item);
+ _set_collapsed_recursive(selected_item, !collapsed);
+
+ tree->ensure_cursor_is_visible();
+
+ } break;
case TOOL_REPLACE: {
if (!profile_allow_editing) {
@@ -418,6 +437,8 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
}
}
}
+ script_create_dialog->connect("script_created", this, "_script_created");
+ script_create_dialog->connect("popup_hide", this, "_script_creation_closed");
script_create_dialog->config(inherits, path);
script_create_dialog->popup_centered();
@@ -998,6 +1019,17 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
}
}
+void SceneTreeDock::_node_collapsed(Object *p_obj) {
+
+ TreeItem *ti = Object::cast_to<TreeItem>(p_obj);
+ if (!ti)
+ return;
+
+ if (Input::get_singleton()->is_key_pressed(KEY_SHIFT)) {
+ _set_collapsed_recursive(ti, ti->is_collapsed());
+ }
+}
+
void SceneTreeDock::_notification(int p_what) {
switch (p_what) {
@@ -1030,6 +1062,7 @@ void SceneTreeDock::_notification(int p_what) {
filter->set_clear_button_enabled(true);
EditorNode::get_singleton()->get_editor_selection()->connect("selection_changed", this, "_selection_changed");
+ scene_tree->get_scene_tree()->connect("item_collapsed", this, "_node_collapsed");
// create_root_dialog
HBoxContainer *top_row = memnew(HBoxContainer);
@@ -1493,7 +1526,6 @@ void SceneTreeDock::_do_reparent(Node *p_new_parent, int p_position_in_parent, V
if (p_nodes.find(validate) != -1) {
ERR_EXPLAIN("Selection changed at some point.. can't reparent");
ERR_FAIL();
- return;
}
validate = validate->get_parent();
}
@@ -1624,6 +1656,52 @@ void SceneTreeDock::_do_reparent(Node *p_new_parent, int p_position_in_parent, V
editor_data->get_undo_redo().commit_action();
}
+bool SceneTreeDock::_is_collapsed_recursive(TreeItem *p_item) const {
+
+ bool is_branch_collapsed = false;
+
+ List<TreeItem *> needs_check;
+ needs_check.push_back(p_item);
+
+ while (!needs_check.empty()) {
+
+ TreeItem *item = needs_check.back()->get();
+ needs_check.pop_back();
+
+ TreeItem *child = item->get_children();
+ is_branch_collapsed = item->is_collapsed() && child;
+
+ if (is_branch_collapsed) {
+ break;
+ }
+ while (child) {
+ needs_check.push_back(child);
+ child = child->get_next();
+ }
+ }
+ return is_branch_collapsed;
+}
+
+void SceneTreeDock::_set_collapsed_recursive(TreeItem *p_item, bool p_collapsed) {
+
+ List<TreeItem *> to_collapse;
+ to_collapse.push_back(p_item);
+
+ while (!to_collapse.empty()) {
+
+ TreeItem *item = to_collapse.back()->get();
+ to_collapse.pop_back();
+
+ item->set_collapsed(p_collapsed);
+
+ TreeItem *child = item->get_children();
+ while (child) {
+ to_collapse.push_back(child);
+ child = child->get_next();
+ }
+ }
+}
+
void SceneTreeDock::_script_created(Ref<Script> p_script) {
List<Node *> selected = editor_selection->get_selected_node_list();
@@ -1647,6 +1725,11 @@ void SceneTreeDock::_script_created(Ref<Script> p_script) {
_update_script_button();
}
+void SceneTreeDock::_script_creation_closed() {
+ script_create_dialog->disconnect("script_created", this, "_script_created");
+ script_create_dialog->disconnect("popup_hide", this, "_script_creation_closed");
+}
+
void SceneTreeDock::_toggle_editable_children_from_selection() {
List<Node *> selection = editor_selection->get_selected_node_list();
@@ -2238,8 +2321,10 @@ void SceneTreeDock::_tree_rmb(const Vector2 &p_menu_pos) {
menu->add_icon_shortcut(get_icon("Add", "EditorIcons"), ED_GET_SHORTCUT("scene_tree/add_child_node"), TOOL_NEW);
menu->add_icon_shortcut(get_icon("Instance", "EditorIcons"), ED_GET_SHORTCUT("scene_tree/instance_scene"), TOOL_INSTANCE);
- menu->add_separator();
}
+ menu->add_icon_shortcut(get_icon("Collapse", "EditorIcons"), ED_GET_SHORTCUT("scene_tree/expand_collapse_all"), TOOL_EXPAND_COLLAPSE);
+ menu->add_separator();
+
existing_script = selected->get_script();
}
@@ -2506,6 +2591,7 @@ void SceneTreeDock::_bind_methods() {
ClassDB::bind_method(D_METHOD("_node_selected"), &SceneTreeDock::_node_selected);
ClassDB::bind_method(D_METHOD("_node_renamed"), &SceneTreeDock::_node_renamed);
ClassDB::bind_method(D_METHOD("_script_created"), &SceneTreeDock::_script_created);
+ ClassDB::bind_method(D_METHOD("_script_creation_closed"), &SceneTreeDock::_script_creation_closed);
ClassDB::bind_method(D_METHOD("_load_request"), &SceneTreeDock::_load_request);
ClassDB::bind_method(D_METHOD("_script_open_request"), &SceneTreeDock::_script_open_request);
ClassDB::bind_method(D_METHOD("_unhandled_key_input"), &SceneTreeDock::_unhandled_key_input);
@@ -2516,6 +2602,7 @@ void SceneTreeDock::_bind_methods() {
ClassDB::bind_method(D_METHOD("_node_prerenamed"), &SceneTreeDock::_node_prerenamed);
ClassDB::bind_method(D_METHOD("_import_subscene"), &SceneTreeDock::_import_subscene);
ClassDB::bind_method(D_METHOD("_selection_changed"), &SceneTreeDock::_selection_changed);
+ ClassDB::bind_method(D_METHOD("_node_collapsed"), &SceneTreeDock::_node_collapsed);
ClassDB::bind_method(D_METHOD("_new_scene_from"), &SceneTreeDock::_new_scene_from);
ClassDB::bind_method(D_METHOD("_nodes_dragged"), &SceneTreeDock::_nodes_dragged);
ClassDB::bind_method(D_METHOD("_files_dropped"), &SceneTreeDock::_files_dropped);
@@ -2555,6 +2642,7 @@ SceneTreeDock::SceneTreeDock(EditorNode *p_editor, Node *p_scene_root, EditorSel
ED_SHORTCUT("scene_tree/batch_rename", TTR("Batch Rename"), KEY_MASK_CMD | KEY_F2);
ED_SHORTCUT("scene_tree/add_child_node", TTR("Add Child Node"), KEY_MASK_CMD | KEY_A);
ED_SHORTCUT("scene_tree/instance_scene", TTR("Instance Child Scene"));
+ ED_SHORTCUT("scene_tree/expand_collapse_all", TTR("Expand/Collapse All"));
ED_SHORTCUT("scene_tree/change_node_type", TTR("Change Type"));
ED_SHORTCUT("scene_tree/attach_script", TTR("Attach Script"));
ED_SHORTCUT("scene_tree/extend_script", TTR("Extend Script"));
@@ -2572,7 +2660,7 @@ SceneTreeDock::SceneTreeDock(EditorNode *p_editor, Node *p_scene_root, EditorSel
button_add = memnew(ToolButton);
button_add->connect("pressed", this, "_tool_selected", make_binds(TOOL_NEW, false));
- button_add->set_tooltip(TTR("Add/Create a New Node"));
+ button_add->set_tooltip(TTR("Add/Create a New Node."));
button_add->set_shortcut(ED_GET_SHORTCUT("scene_tree/add_child_node"));
filter_hbc->add_child(button_add);
@@ -2661,7 +2749,6 @@ SceneTreeDock::SceneTreeDock(EditorNode *p_editor, Node *p_scene_root, EditorSel
script_create_dialog = memnew(ScriptCreateDialog);
script_create_dialog->set_inheritance_base_type("Node");
add_child(script_create_dialog);
- script_create_dialog->connect("script_created", this, "_script_created");
reparent_dialog = memnew(ReparentDialog);
add_child(reparent_dialog);
diff --git a/editor/scene_tree_dock.h b/editor/scene_tree_dock.h
index b645c22295..3729e27ce6 100644
--- a/editor/scene_tree_dock.h
+++ b/editor/scene_tree_dock.h
@@ -60,6 +60,7 @@ class SceneTreeDock : public VBoxContainer {
TOOL_NEW,
TOOL_INSTANCE,
+ TOOL_EXPAND_COLLAPSE,
TOOL_RENAME,
TOOL_BATCH_RENAME,
TOOL_REPLACE,
@@ -116,6 +117,7 @@ class SceneTreeDock : public VBoxContainer {
HBoxContainer *tool_hbc;
void _tool_selected(int p_tool, bool p_confirm_override = false);
+ void _node_collapsed(Object *p_obj);
EditorData *editor_data;
EditorSelection *editor_selection;
@@ -152,6 +154,9 @@ class SceneTreeDock : public VBoxContainer {
void _node_reparent(NodePath p_path, bool p_keep_global_xform);
void _do_reparent(Node *p_new_parent, int p_position_in_parent, Vector<Node *> p_nodes, bool p_keep_global_xform);
+ bool _is_collapsed_recursive(TreeItem *p_item) const;
+ void _set_collapsed_recursive(TreeItem *p_item, bool p_collapsed);
+
void _set_owners(Node *p_owner, const Array &p_nodes);
enum ReplaceOwnerMode {
@@ -170,6 +175,7 @@ class SceneTreeDock : public VBoxContainer {
void _node_selected();
void _node_renamed();
void _script_created(Ref<Script> p_script);
+ void _script_creation_closed();
void _delete_confirm();
diff --git a/editor/script_create_dialog.cpp b/editor/script_create_dialog.cpp
index ffa221edaf..8916f4d8c4 100644
--- a/editor/script_create_dialog.cpp
+++ b/editor/script_create_dialog.cpp
@@ -286,8 +286,8 @@ void ScriptCreateDialog::_create_new() {
}
}
- hide();
emit_signal("script_created", scr);
+ hide();
}
void ScriptCreateDialog::_load_exist() {
@@ -300,8 +300,8 @@ void ScriptCreateDialog::_load_exist() {
return;
}
- hide();
emit_signal("script_created", p_script.get_ref_ptr());
+ hide();
}
void ScriptCreateDialog::_lang_changed(int l) {
diff --git a/editor/script_editor_debugger.cpp b/editor/script_editor_debugger.cpp
index 00c8ed6ad3..8fd1064427 100644
--- a/editor/script_editor_debugger.cpp
+++ b/editor/script_editor_debugger.cpp
@@ -626,8 +626,7 @@ void ScriptEditorDebugger::_parse_message(const String &p_msg, const Array &p_da
d["frame"] = i;
s->set_metadata(0, d);
- //String line = itos(i)+" - "+String(d["file"])+":"+itos(d["line"])+" - at func: "+d["function"];
- String line = itos(i) + " - " + String(d["file"]) + ":" + itos(d["line"]);
+ String line = itos(i) + " - " + String(d["file"]) + ":" + itos(d["line"]) + " - at function: " + d["function"];
s->set_text(0, line);
if (i == 0)
diff --git a/editor/spatial_editor_gizmos.cpp b/editor/spatial_editor_gizmos.cpp
index fc4ff2ecfc..fe6d9dd8c7 100644
--- a/editor/spatial_editor_gizmos.cpp
+++ b/editor/spatial_editor_gizmos.cpp
@@ -147,7 +147,7 @@ void EditorSpatialGizmo::set_handle(int p_idx, Camera *p_camera, const Point2 &p
}
ERR_FAIL_COND(!gizmo_plugin);
- return gizmo_plugin->set_handle(this, p_idx, p_camera, p_point);
+ gizmo_plugin->set_handle(this, p_idx, p_camera, p_point);
}
void EditorSpatialGizmo::commit_handle(int p_idx, const Variant &p_restore, bool p_cancel) {
@@ -158,7 +158,7 @@ void EditorSpatialGizmo::commit_handle(int p_idx, const Variant &p_restore, bool
}
ERR_FAIL_COND(!gizmo_plugin);
- return gizmo_plugin->commit_handle(this, p_idx, p_restore, p_cancel);
+ gizmo_plugin->commit_handle(this, p_idx, p_restore, p_cancel);
}
void EditorSpatialGizmo::set_spatial_node(Spatial *p_node) {
diff --git a/main/main.cpp b/main/main.cpp
index 16a0677bd0..3f84eca1d2 100644
--- a/main/main.cpp
+++ b/main/main.cpp
@@ -356,7 +356,7 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
ClassDB::register_class<Performance>();
engine->add_singleton(Engine::Singleton("Performance", performance));
- GLOBAL_DEF("debug/settings/crash_handler/message", "Godot version: " + get_full_version_string() + String("\nPlease include this when reporting the bug on https://github.com/godotengine/godot/issues"));
+ GLOBAL_DEF("debug/settings/crash_handler/message", String("Please include this when reporting the bug on https://github.com/godotengine/godot/issues"));
MAIN_PRINT("Main: Parse CMDLine");
diff --git a/modules/bullet/rigid_body_bullet.cpp b/modules/bullet/rigid_body_bullet.cpp
index 733a900396..085cce9733 100644
--- a/modules/bullet/rigid_body_bullet.cpp
+++ b/modules/bullet/rigid_body_bullet.cpp
@@ -866,7 +866,7 @@ void RigidBodyBullet::on_enter_area(AreaBullet *p_area) {
if (p_area->is_spOv_gravityPoint()) {
++countGravityPointSpaces;
- assert(0 < countGravityPointSpaces);
+ ERR_FAIL_COND(countGravityPointSpaces <= 0);
}
}
@@ -888,7 +888,7 @@ void RigidBodyBullet::on_exit_area(AreaBullet *p_area) {
if (wasTheAreaFound) {
if (p_area->is_spOv_gravityPoint()) {
--countGravityPointSpaces;
- assert(0 <= countGravityPointSpaces);
+ ERR_FAIL_COND(countGravityPointSpaces < 0);
}
--areaWhereIamCount;
diff --git a/modules/gdscript/gdscript.cpp b/modules/gdscript/gdscript.cpp
index 95f3c12806..bc28f7009e 100644
--- a/modules/gdscript/gdscript.cpp
+++ b/modules/gdscript/gdscript.cpp
@@ -332,7 +332,7 @@ ScriptInstance *GDScript::instance_create(Object *p_this) {
}
Variant::CallError unchecked_error;
- return _create_instance(NULL, 0, p_this, Object::cast_to<Reference>(p_this), unchecked_error);
+ return _create_instance(NULL, 0, p_this, Object::cast_to<Reference>(p_this) != NULL, unchecked_error);
}
PlaceHolderScriptInstance *GDScript::placeholder_instance_create(Object *p_this) {
diff --git a/modules/gdscript/gdscript_compiler.cpp b/modules/gdscript/gdscript_compiler.cpp
index caffe04700..4c976bd2e0 100644
--- a/modules/gdscript/gdscript_compiler.cpp
+++ b/modules/gdscript/gdscript_compiler.cpp
@@ -1259,8 +1259,6 @@ int GDScriptCompiler::_parse_expression(CodeGen &codegen, const GDScriptParser::
ERR_FAIL_V(-1); //unreachable code
} break;
}
-
- ERR_FAIL_V(-1); //unreachable code
}
Error GDScriptCompiler::_parse_block(CodeGen &codegen, const GDScriptParser::BlockNode *p_block, int p_stack_level, int p_break_addr, int p_continue_addr) {
diff --git a/modules/gdscript/gdscript_function.cpp b/modules/gdscript/gdscript_function.cpp
index bae5eca218..d5e74c07c9 100644
--- a/modules/gdscript/gdscript_function.cpp
+++ b/modules/gdscript/gdscript_function.cpp
@@ -1556,14 +1556,14 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
//error
// function, file, line, error, explanation
String err_file;
- if (p_instance)
+ if (p_instance && p_instance->script->is_valid() && p_instance->script->path != "")
err_file = p_instance->script->path;
else if (script)
err_file = script->path;
if (err_file == "")
err_file = "<built-in>";
String err_func = name;
- if (p_instance && p_instance->script->name != "")
+ if (p_instance && p_instance->script->is_valid() && p_instance->script->name != "")
err_func = p_instance->script->name + "." + err_func;
int err_line = line;
if (err_text == "") {
@@ -1591,15 +1591,26 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
GDScriptLanguage::get_singleton()->script_frame_time += time_taken - function_call_time;
}
- if (ScriptDebugger::get_singleton())
- GDScriptLanguage::get_singleton()->exit_function();
+ bool yielded = retvalue.is_ref() && Object::cast_to<GDScriptFunctionState>(retvalue);
+
+ // Check if this is the last time the function is resuming from yield
+ // Will be true if never yielded as well
+ // When it's the last resume it will postpone the exit from stack,
+ // so the debugger knows which function triggered the resume of the next function (if any)
+ if (!p_state || yielded) {
+ if (ScriptDebugger::get_singleton())
+ GDScriptLanguage::get_singleton()->exit_function();
#endif
- if (_stack_size) {
- //free stack
- for (int i = 0; i < _stack_size; i++)
- stack[i].~Variant();
+ if (_stack_size) {
+ //free stack
+ for (int i = 0; i < _stack_size; i++)
+ stack[i].~Variant();
+ }
+
+#ifdef DEBUG_ENABLED
}
+#endif
return retvalue;
}
@@ -1775,7 +1786,7 @@ Variant GDScriptFunctionState::_signal_callback(const Variant **p_args, int p_ar
if (state.instance_id && !ObjectDB::get_instance(state.instance_id)) {
#ifdef DEBUG_ENABLED
- ERR_EXPLAIN("Resumed after yield, but class instance is gone");
+ ERR_EXPLAIN("Resumed function '" + String(function->get_name()) + "()' after yield, but class instance is gone. At script: " + state.script->get_path() + ":" + itos(state.line));
ERR_FAIL_V(Variant());
#else
return Variant();
@@ -1838,6 +1849,17 @@ Variant GDScriptFunctionState::_signal_callback(const Variant **p_args, int p_ar
}
}
+#ifdef DEBUG_ENABLED
+ if (ScriptDebugger::get_singleton())
+ GDScriptLanguage::get_singleton()->exit_function();
+ if (state.stack_size) {
+ //free stack
+ Variant *stack = (Variant *)state.stack.ptr();
+ for (int i = 0; i < state.stack_size; i++)
+ stack[i].~Variant();
+ }
+#endif
+
return ret;
}
@@ -1860,7 +1882,7 @@ Variant GDScriptFunctionState::resume(const Variant &p_arg) {
ERR_FAIL_COND_V(!function, Variant());
if (state.instance_id && !ObjectDB::get_instance(state.instance_id)) {
#ifdef DEBUG_ENABLED
- ERR_EXPLAIN("Resumed after yield, but class instance is gone");
+ ERR_EXPLAIN("Resumed function '" + String(function->get_name()) + "()' after yield, but class instance is gone. At script: " + state.script->get_path() + ":" + itos(state.line));
ERR_FAIL_V(Variant());
#else
return Variant();
@@ -1892,6 +1914,17 @@ Variant GDScriptFunctionState::resume(const Variant &p_arg) {
} else {
emit_signal("completed", ret);
}
+
+#ifdef DEBUG_ENABLED
+ if (ScriptDebugger::get_singleton())
+ GDScriptLanguage::get_singleton()->exit_function();
+ if (state.stack_size) {
+ //free stack
+ Variant *stack = (Variant *)state.stack.ptr();
+ for (int i = 0; i < state.stack_size; i++)
+ stack[i].~Variant();
+ }
+#endif
}
return ret;
diff --git a/modules/mono/csharp_script.cpp b/modules/mono/csharp_script.cpp
index 20b227bda1..9522eaee77 100644
--- a/modules/mono/csharp_script.cpp
+++ b/modules/mono/csharp_script.cpp
@@ -2701,7 +2701,7 @@ ScriptInstance *CSharpScript::instance_create(Object *p_this) {
}
Variant::CallError unchecked_error;
- return _create_instance(NULL, 0, p_this, Object::cast_to<Reference>(p_this), unchecked_error);
+ return _create_instance(NULL, 0, p_this, Object::cast_to<Reference>(p_this) != NULL, unchecked_error);
}
PlaceHolderScriptInstance *CSharpScript::placeholder_instance_create(Object *p_this) {
diff --git a/modules/visual_script/visual_script_editor.cpp b/modules/visual_script/visual_script_editor.cpp
index 3ac170a935..4579644d49 100644
--- a/modules/visual_script/visual_script_editor.cpp
+++ b/modules/visual_script/visual_script_editor.cpp
@@ -1099,6 +1099,9 @@ void VisualScriptEditor::_expression_text_changed(const String &p_text, int p_id
void VisualScriptEditor::_available_node_doubleclicked() {
+ if (edited_func == String())
+ return;
+
TreeItem *item = nodes->get_selected();
if (!item)
@@ -1107,7 +1110,6 @@ void VisualScriptEditor::_available_node_doubleclicked() {
String which = item->get_metadata(0);
if (which == String())
return;
-
Vector2 ofs = graph->get_scroll_ofs() + graph->get_size() * 0.5;
if (graph->is_using_snap()) {
diff --git a/platform/android/export/export.cpp b/platform/android/export/export.cpp
index b37cf642db..08cbb176fe 100644
--- a/platform/android/export/export.cpp
+++ b/platform/android/export/export.cpp
@@ -665,6 +665,8 @@ class EditorExportPlatformAndroid : public EditorExportPlatform {
bool screen_support_large = p_preset->get("screen/support_large");
bool screen_support_xlarge = p_preset->get("screen/support_xlarge");
+ int xr_mode_index = p_preset->get("graphics/xr_mode");
+
Vector<String> perms;
const char **aperms = android_perms;
@@ -822,6 +824,14 @@ class EditorExportPlatformAndroid : public EditorExportPlatform {
encode_uint32(min_gles3 ? 0x00030000 : 0x00020000, &p_manifest.write[iofs + 16]);
}
+ if (tname == "meta-data" && attrname == "value") {
+ if (xr_mode_index == 1 /* XRMode.OVR */) {
+ string_table.write[attr_value] = "vr_only";
+ } else {
+ string_table.write[attr_value] = "";
+ }
+ }
+
iofs += 20;
}
@@ -1139,6 +1149,7 @@ public:
virtual void get_export_options(List<ExportOption> *r_options) {
+ r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "graphics/xr_mode", PROPERTY_HINT_ENUM, "Regular,Oculus Mobile VR"), 0));
r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "graphics/32_bits_framebuffer"), true));
r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "one_click_deploy/clear_previous_install"), true));
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "custom_package/debug", PROPERTY_HINT_GLOBAL_FILE, "*.apk"), ""));
@@ -2071,6 +2082,14 @@ public:
}
}
+ int xr_mode_index = p_preset->get("graphics/xr_mode");
+ if (xr_mode_index == 1 /* XRMode.OVR */) {
+ cl.push_back("--xr_mode_ovr");
+ } else {
+ // XRMode.REGULAR is the default.
+ cl.push_back("--xr_mode_regular");
+ }
+
if (use_32_fb)
cl.push_back("--use_depth_32");
diff --git a/platform/android/java/AndroidManifest.xml b/platform/android/java/AndroidManifest.xml
index 9997950137..a7e6db4059 100644
--- a/platform/android/java/AndroidManifest.xml
+++ b/platform/android/java/AndroidManifest.xml
@@ -13,7 +13,7 @@
<!--glEsVersion is modified by the exporter, changing this value here has no effect-->
<uses-feature android:glEsVersion="0x00020000" android:required="true" />
-<!--Adding custom text to manifest is fine, but do it outside the custom user and application BEGIN/ENDregions, as that gets rewritten-->
+<!--Adding custom text to manifest is fine, but do it outside the custom user and application BEGIN/END regions, as that gets rewritten-->
<!--Custom permissions XML added by add-ons. It's recommended to add them from the export preset, though-->
<!--CHUNK_USER_PERMISSIONS_BEGIN-->
@@ -25,12 +25,15 @@
<!--The following values are replaced when Godot exports, modifying them here has no effect. Do these changes in the-->
<!--export preset. Adding new ones is fine.-->
+<!-- Metadata for VR app detection on Oculus devices. This is modified by the exporter based on the selected xr mode. Changing this value here has no effect. -->
+ <meta-data android:name="com.samsung.android.vr.application.mode" android:value=""/>
+
<activity android:name="org.godotengine.godot.Godot"
android:label="@string/godot_project_name_string"
- android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
+ android:theme="@android:style/Theme.Black.NoTitleBar.Fullscreen"
android:launchMode="singleTask"
android:screenOrientation="landscape"
- android:configChanges="orientation|keyboardHidden|screenSize|smallestScreenSize"
+ android:configChanges="orientation|keyboardHidden|screenSize|smallestScreenSize|density|keyboard|navigation|screenLayout|uiMode"
android:resizeableActivity="false"
tools:ignore="UnusedAttribute">
diff --git a/platform/android/java/src/org/godotengine/godot/Godot.java b/platform/android/java/src/org/godotengine/godot/Godot.java
index 751e885118..6e1841fa8b 100644
--- a/platform/android/java/src/org/godotengine/godot/Godot.java
+++ b/platform/android/java/src/org/godotengine/godot/Godot.java
@@ -58,7 +58,6 @@ import android.os.Environment;
import android.os.Messenger;
import android.provider.Settings.Secure;
import android.support.v4.content.ContextCompat;
-import android.util.Log;
import android.view.Display;
import android.view.KeyEvent;
import android.view.MotionEvent;
@@ -115,6 +114,7 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC
private Button mPauseButton;
private Button mWiFiSettingsButton;
+ private XRMode xrMode = XRMode.REGULAR;
private boolean use_32_bits = false;
private boolean use_immersive = false;
private boolean use_debug_opengl = false;
@@ -282,7 +282,7 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC
// ...add to FrameLayout
layout.addView(edittext);
- mView = new GodotView(this, XRMode.PANCAKE, use_gl3, use_32_bits, use_debug_opengl);
+ mView = new GodotView(this, xrMode, use_gl3, use_32_bits, use_debug_opengl);
layout.addView(mView, new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
edittext.setView(mView);
io.setEdit(edittext);
@@ -488,7 +488,11 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC
for (int i = 0; i < command_line.length; i++) {
boolean has_extra = i < command_line.length - 1;
- if (command_line[i].equals("--use_depth_32")) {
+ if (command_line[i].equals(XRMode.REGULAR.cmdLineArg)) {
+ xrMode = XRMode.REGULAR;
+ } else if (command_line[i].equals(XRMode.OVR.cmdLineArg)) {
+ xrMode = XRMode.OVR;
+ } else if (command_line[i].equals("--use_depth_32")) {
use_32_bits = true;
} else if (command_line[i].equals("--debug_opengl")) {
use_debug_opengl = true;
diff --git a/platform/android/java/src/org/godotengine/godot/GodotView.java b/platform/android/java/src/org/godotengine/godot/GodotView.java
index 1c189a1579..fc3e47e69d 100644
--- a/platform/android/java/src/org/godotengine/godot/GodotView.java
+++ b/platform/android/java/src/org/godotengine/godot/GodotView.java
@@ -40,9 +40,9 @@ import org.godotengine.godot.xr.XRMode;
import org.godotengine.godot.xr.ovr.OvrConfigChooser;
import org.godotengine.godot.xr.ovr.OvrContextFactory;
import org.godotengine.godot.xr.ovr.OvrWindowSurfaceFactory;
-import org.godotengine.godot.xr.pancake.PancakeConfigChooser;
-import org.godotengine.godot.xr.pancake.PancakeContextFactory;
-import org.godotengine.godot.xr.pancake.PancakeFallbackConfigChooser;
+import org.godotengine.godot.xr.regular.RegularConfigChooser;
+import org.godotengine.godot.xr.regular.RegularContextFactory;
+import org.godotengine.godot.xr.regular.RegularFallbackConfigChooser;
/**
* A simple GLSurfaceView sub-class that demonstrate how to perform
@@ -123,7 +123,7 @@ public class GodotView extends GLSurfaceView {
setEGLWindowSurfaceFactory(new OvrWindowSurfaceFactory());
break;
- case PANCAKE:
+ case REGULAR:
default:
/* By default, GLSurfaceView() creates a RGB_565 opaque surface.
* If we want a translucent one, we should change the surface's
@@ -137,7 +137,7 @@ public class GodotView extends GLSurfaceView {
/* Setup the context factory for 2.0 rendering.
* See ContextFactory class definition below
*/
- setEGLContextFactory(new PancakeContextFactory());
+ setEGLContextFactory(new RegularContextFactory());
/* We need to choose an EGLConfig that matches the format of
* our surface exactly. This is going to be done in our
@@ -147,15 +147,15 @@ public class GodotView extends GLSurfaceView {
if (GLUtils.use_32) {
setEGLConfigChooser(translucent ?
- new PancakeFallbackConfigChooser(8, 8, 8, 8, 24, stencil,
- new PancakeConfigChooser(8, 8, 8, 8, 16, stencil)) :
- new PancakeFallbackConfigChooser(8, 8, 8, 8, 24, stencil,
- new PancakeConfigChooser(5, 6, 5, 0, 16, stencil)));
+ new RegularFallbackConfigChooser(8, 8, 8, 8, 24, stencil,
+ new RegularConfigChooser(8, 8, 8, 8, 16, stencil)) :
+ new RegularFallbackConfigChooser(8, 8, 8, 8, 24, stencil,
+ new RegularConfigChooser(5, 6, 5, 0, 16, stencil)));
} else {
setEGLConfigChooser(translucent ?
- new PancakeConfigChooser(8, 8, 8, 8, 16, stencil) :
- new PancakeConfigChooser(5, 6, 5, 0, 16, stencil));
+ new RegularConfigChooser(8, 8, 8, 8, 16, stencil) :
+ new RegularConfigChooser(5, 6, 5, 0, 16, stencil));
}
break;
}
diff --git a/platform/android/java/src/org/godotengine/godot/xr/XRMode.java b/platform/android/java/src/org/godotengine/godot/xr/XRMode.java
index cbc8a1e902..dd5701af7d 100644
--- a/platform/android/java/src/org/godotengine/godot/xr/XRMode.java
+++ b/platform/android/java/src/org/godotengine/godot/xr/XRMode.java
@@ -34,6 +34,16 @@ package org.godotengine.godot.xr;
* Godot available XR modes.
*/
public enum XRMode {
- PANCAKE, // Regular/flatscreen
- OVR, // Oculus mobile VR SDK
+ REGULAR(0, "Regular", "--xr_mode_regular"), // Regular/flatscreen
+ OVR(1, "Oculus Mobile VR", "--xr_mode_ovr");
+
+ final int index;
+ final String label;
+ public final String cmdLineArg;
+
+ XRMode(int index, String label, String cmdLineArg) {
+ this.index = index;
+ this.label = label;
+ this.cmdLineArg = cmdLineArg;
+ }
}
diff --git a/platform/android/java/src/org/godotengine/godot/xr/pancake/PancakeConfigChooser.java b/platform/android/java/src/org/godotengine/godot/xr/regular/RegularConfigChooser.java
index ac19a09e76..3836967f86 100644
--- a/platform/android/java/src/org/godotengine/godot/xr/pancake/PancakeConfigChooser.java
+++ b/platform/android/java/src/org/godotengine/godot/xr/regular/RegularConfigChooser.java
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* PancakeConfigChooser.java */
+/* RegularConfigChooser.java */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -28,7 +28,7 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-package org.godotengine.godot.xr.pancake;
+package org.godotengine.godot.xr.regular;
import android.opengl.GLSurfaceView;
import javax.microedition.khronos.egl.EGL10;
@@ -39,9 +39,9 @@ import org.godotengine.godot.utils.GLUtils;
/**
* Used to select the egl config for pancake games.
*/
-public class PancakeConfigChooser implements GLSurfaceView.EGLConfigChooser {
+public class RegularConfigChooser implements GLSurfaceView.EGLConfigChooser {
- private static final String TAG = PancakeConfigChooser.class.getSimpleName();
+ private static final String TAG = RegularConfigChooser.class.getSimpleName();
private int[] mValue = new int[1];
@@ -69,7 +69,7 @@ public class PancakeConfigChooser implements GLSurfaceView.EGLConfigChooser {
EGL10.EGL_NONE
};
- public PancakeConfigChooser(int r, int g, int b, int a, int depth, int stencil) {
+ public RegularConfigChooser(int r, int g, int b, int a, int depth, int stencil) {
mRedSize = r;
mGreenSize = g;
mBlueSize = b;
diff --git a/platform/android/java/src/org/godotengine/godot/xr/pancake/PancakeContextFactory.java b/platform/android/java/src/org/godotengine/godot/xr/regular/RegularContextFactory.java
index aca6ffdba6..4f1e9a696b 100644
--- a/platform/android/java/src/org/godotengine/godot/xr/pancake/PancakeContextFactory.java
+++ b/platform/android/java/src/org/godotengine/godot/xr/regular/RegularContextFactory.java
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* PancakeContextFactory.java */
+/* RegularContextFactory.java */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -28,7 +28,7 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-package org.godotengine.godot.xr.pancake;
+package org.godotengine.godot.xr.regular;
import android.opengl.GLSurfaceView;
import android.util.Log;
@@ -42,8 +42,8 @@ import org.godotengine.godot.utils.GLUtils;
/**
* Factory used to setup the opengl context for pancake games.
*/
-public class PancakeContextFactory implements GLSurfaceView.EGLContextFactory {
- private static final String TAG = PancakeContextFactory.class.getSimpleName();
+public class RegularContextFactory implements GLSurfaceView.EGLContextFactory {
+ private static final String TAG = RegularContextFactory.class.getSimpleName();
private static final int _EGL_CONTEXT_FLAGS_KHR = 0x30FC;
private static final int _EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR = 0x00000001;
diff --git a/platform/android/java/src/org/godotengine/godot/xr/pancake/PancakeFallbackConfigChooser.java b/platform/android/java/src/org/godotengine/godot/xr/regular/RegularFallbackConfigChooser.java
index e19f218916..f5718ef2b3 100644
--- a/platform/android/java/src/org/godotengine/godot/xr/pancake/PancakeFallbackConfigChooser.java
+++ b/platform/android/java/src/org/godotengine/godot/xr/regular/RegularFallbackConfigChooser.java
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* PancakeFallbackConfigChooser.java */
+/* RegularFallbackConfigChooser.java */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -28,7 +28,7 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-package org.godotengine.godot.xr.pancake;
+package org.godotengine.godot.xr.regular;
import android.util.Log;
import javax.microedition.khronos.egl.EGL10;
@@ -37,13 +37,13 @@ import javax.microedition.khronos.egl.EGLDisplay;
import org.godotengine.godot.utils.GLUtils;
/* Fallback if 32bit View is not supported*/
-public class PancakeFallbackConfigChooser extends PancakeConfigChooser {
+public class RegularFallbackConfigChooser extends RegularConfigChooser {
- private static final String TAG = PancakeFallbackConfigChooser.class.getSimpleName();
+ private static final String TAG = RegularFallbackConfigChooser.class.getSimpleName();
- private PancakeConfigChooser fallback;
+ private RegularConfigChooser fallback;
- public PancakeFallbackConfigChooser(int r, int g, int b, int a, int depth, int stencil, PancakeConfigChooser fallback) {
+ public RegularFallbackConfigChooser(int r, int g, int b, int a, int depth, int stencil, RegularConfigChooser fallback) {
super(r, g, b, a, depth, stencil);
this.fallback = fallback;
}
diff --git a/platform/javascript/detect.py b/platform/javascript/detect.py
index 145ac42863..c6afa02c6d 100644
--- a/platform/javascript/detect.py
+++ b/platform/javascript/detect.py
@@ -69,9 +69,9 @@ def configure(env):
exec(f.read(), em_config)
except StandardError as e:
raise RuntimeError("Emscripten configuration file '%s' is invalid:\n%s" % (em_config_file, e))
- if 'EMSCRIPTEN_ROOT' not in em_config:
- raise RuntimeError("'EMSCRIPTEN_ROOT' missing in Emscripten configuration file '%s'" % em_config_file)
- env.PrependENVPath('PATH', em_config['EMSCRIPTEN_ROOT'])
+ if 'BINARYEN_ROOT' not in em_config and 'EMSCRIPTEN_ROOT' not in em_config:
+ raise RuntimeError("'BINARYEN_ROOT' or 'EMSCRIPTEN_ROOT' missing in Emscripten configuration file '%s'" % em_config_file)
+ env.PrependENVPath('PATH', em_config.get('BINARYEN_ROOT', em_config.get('EMSCRIPTEN_ROOT')))
env['CC'] = 'emcc'
env['CXX'] = 'em++'
diff --git a/scene/2d/canvas_item.cpp b/scene/2d/canvas_item.cpp
index 78e98deb93..23f6404e3e 100644
--- a/scene/2d/canvas_item.cpp
+++ b/scene/2d/canvas_item.cpp
@@ -1074,6 +1074,7 @@ Vector2 CanvasItem::make_canvas_position_local(const Vector2 &screen_point) cons
Ref<InputEvent> CanvasItem::make_input_local(const Ref<InputEvent> &p_event) const {
+ ERR_FAIL_COND_V(p_event.is_null(), p_event);
ERR_FAIL_COND_V(!is_inside_tree(), p_event);
return p_event->xformed_by((get_canvas_transform() * get_global_transform()).affine_inverse());
diff --git a/scene/2d/navigation_2d.cpp b/scene/2d/navigation_2d.cpp
index 72b5f2fb12..f644db462b 100644
--- a/scene/2d/navigation_2d.cpp
+++ b/scene/2d/navigation_2d.cpp
@@ -92,7 +92,6 @@ void Navigation2D::_navpoly_link(int p_id) {
if (!valid) {
nm.polygons.pop_back();
ERR_CONTINUE(!valid);
- continue;
}
p.center = center / plen;
diff --git a/scene/3d/audio_stream_player_3d.h b/scene/3d/audio_stream_player_3d.h
index 7a652ed65f..93954e758a 100644
--- a/scene/3d/audio_stream_player_3d.h
+++ b/scene/3d/audio_stream_player_3d.h
@@ -71,7 +71,7 @@ private:
struct Output {
AudioFilterSW filter;
- AudioFilterSW::Processor filter_process[6];
+ AudioFilterSW::Processor filter_process[8];
AudioFrame vol[4];
float filter_gain;
float pitch_scale;
diff --git a/scene/3d/navigation.cpp b/scene/3d/navigation.cpp
index 612d91c6e1..12d562c0c6 100644
--- a/scene/3d/navigation.cpp
+++ b/scene/3d/navigation.cpp
@@ -90,7 +90,6 @@ void Navigation::_navmesh_link(int p_id) {
if (!valid) {
nm.polygons.pop_back();
ERR_CONTINUE(!valid);
- continue;
}
p.center = center;
diff --git a/scene/3d/spatial.cpp b/scene/3d/spatial.cpp
index efd418e3c7..1a41a31253 100644
--- a/scene/3d/spatial.cpp
+++ b/scene/3d/spatial.cpp
@@ -506,6 +506,8 @@ bool Spatial::is_set_as_toplevel() const {
Ref<World> Spatial::get_world() const {
ERR_FAIL_COND_V(!is_inside_world(), Ref<World>());
+ ERR_FAIL_COND_V(!data.viewport, Ref<World>());
+
return data.viewport->find_world();
}
diff --git a/scene/3d/visual_instance.cpp b/scene/3d/visual_instance.cpp
index 4bb4d18071..5141c84803 100644
--- a/scene/3d/visual_instance.cpp
+++ b/scene/3d/visual_instance.cpp
@@ -60,7 +60,7 @@ void VisualInstance::_notification(int p_what) {
if (skeleton)
VisualServer::get_singleton()->instance_attach_skeleton( instance, skeleton->get_skeleton() );
*/
-
+ ERR_FAIL_COND(get_world().is_null());
VisualServer::get_singleton()->instance_set_scenario(instance, get_world()->get_scenario());
_update_visibility();
diff --git a/scene/gui/option_button.cpp b/scene/gui/option_button.cpp
index 872402e9e1..58671655dc 100644
--- a/scene/gui/option_button.cpp
+++ b/scene/gui/option_button.cpp
@@ -282,7 +282,7 @@ void OptionButton::_set_items(const Array &p_items) {
void OptionButton::get_translatable_strings(List<String> *p_strings) const {
- return popup->get_translatable_strings(p_strings);
+ popup->get_translatable_strings(p_strings);
}
void OptionButton::_bind_methods() {
diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp
index f9bdce5fef..a6e3d644f6 100644
--- a/scene/gui/text_edit.cpp
+++ b/scene/gui/text_edit.cpp
@@ -4817,14 +4817,18 @@ void TextEdit::deselect() {
void TextEdit::select(int p_from_line, int p_from_column, int p_to_line, int p_to_column) {
- if (p_from_line >= text.size())
+ if (p_from_line < 0)
+ p_from_line = 0;
+ else if (p_from_line >= text.size())
p_from_line = text.size() - 1;
if (p_from_column >= text[p_from_line].length())
p_from_column = text[p_from_line].length();
if (p_from_column < 0)
p_from_column = 0;
- if (p_to_line >= text.size())
+ if (p_to_line < 0)
+ p_to_line = 0;
+ else if (p_to_line >= text.size())
p_to_line = text.size() - 1;
if (p_to_column >= text[p_to_line].length())
p_to_column = text[p_to_line].length();
diff --git a/scene/main/node.cpp b/scene/main/node.cpp
index a580a7f8ac..5888760973 100644
--- a/scene/main/node.cpp
+++ b/scene/main/node.cpp
@@ -71,6 +71,8 @@ void Node::_notification(int p_notification) {
} break;
case NOTIFICATION_ENTER_TREE: {
+ ERR_FAIL_COND(!get_viewport());
+ ERR_FAIL_COND(!get_tree());
if (data.pause_mode == PAUSE_MODE_INHERIT) {
@@ -94,6 +96,8 @@ void Node::_notification(int p_notification) {
} break;
case NOTIFICATION_EXIT_TREE: {
+ ERR_FAIL_COND(!get_viewport());
+ ERR_FAIL_COND(!get_tree());
get_tree()->node_count--;
orphan_node_count++;
@@ -840,6 +844,8 @@ bool Node::is_processing_internal() const {
void Node::set_process_priority(int p_priority) {
data.process_priority = p_priority;
+ ERR_FAIL_COND(!data.tree);
+
if (is_processing())
data.tree->make_group_changed("idle_process");
diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp
index dcd70a1844..8561d9aedb 100644
--- a/scene/main/viewport.cpp
+++ b/scene/main/viewport.cpp
@@ -1701,6 +1701,8 @@ bool Viewport::_gui_drop(Control *p_at_control, Point2 p_at_pos, bool p_just_che
void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
+ ERR_FAIL_COND(p_event.is_null())
+
//?
/*
if (!is_visible()) {
diff --git a/scene/resources/texture.cpp b/scene/resources/texture.cpp
index 3a0144849a..a5e9351753 100644
--- a/scene/resources/texture.cpp
+++ b/scene/resources/texture.cpp
@@ -1487,8 +1487,10 @@ uint32_t CubeMap::get_flags() const {
void CubeMap::set_side(Side p_side, const Ref<Image> &p_image) {
+ ERR_FAIL_COND(p_image.is_null());
ERR_FAIL_COND(p_image->empty());
ERR_FAIL_INDEX(p_side, 6);
+
if (!_is_valid()) {
format = p_image->get_format();
w = p_image->get_width();
diff --git a/servers/audio/audio_stream.cpp b/servers/audio/audio_stream.cpp
index 388346b67c..17f5e158a7 100644
--- a/servers/audio/audio_stream.cpp
+++ b/servers/audio/audio_stream.cpp
@@ -49,8 +49,9 @@ void AudioStreamPlaybackResampled::_begin_resample() {
void AudioStreamPlaybackResampled::mix(AudioFrame *p_buffer, float p_rate_scale, int p_frames) {
float target_rate = AudioServer::get_singleton()->get_mix_rate();
+ float global_rate_scale = AudioServer::get_singleton()->get_global_rate_scale();
- uint64_t mix_increment = uint64_t(((get_stream_sampling_rate() * p_rate_scale) / double(target_rate)) * double(FP_LEN));
+ uint64_t mix_increment = uint64_t(((get_stream_sampling_rate() * p_rate_scale) / double(target_rate * global_rate_scale)) * double(FP_LEN));
for (int i = 0; i < p_frames; i++) {
diff --git a/servers/audio/effects/audio_effect_record.cpp b/servers/audio/effects/audio_effect_record.cpp
index abf9d5593c..acf27d2bbf 100644
--- a/servers/audio/effects/audio_effect_record.cpp
+++ b/servers/audio/effects/audio_effect_record.cpp
@@ -216,6 +216,9 @@ Ref<AudioStreamSample> AudioEffectRecord::get_recording() const {
PoolVector<uint8_t> dst_data;
+ ERR_FAIL_COND_V(current_instance.is_null(), NULL);
+ ERR_FAIL_COND_V(current_instance->recording_data.size(), NULL);
+
if (dst_format == AudioStreamSample::FORMAT_8_BITS) {
int data_size = current_instance->recording_data.size();
dst_data.resize(data_size);
diff --git a/servers/audio_server.cpp b/servers/audio_server.cpp
index fc3ecedd03..a6473d69c0 100644
--- a/servers/audio_server.cpp
+++ b/servers/audio_server.cpp
@@ -944,6 +944,15 @@ bool AudioServer::is_bus_channel_active(int p_bus, int p_channel) const {
return buses[p_bus]->channels[p_channel].active;
}
+void AudioServer::set_global_rate_scale(float p_scale) {
+
+ global_rate_scale = p_scale;
+}
+float AudioServer::get_global_rate_scale() const {
+
+ return global_rate_scale;
+}
+
void AudioServer::init_channels_and_buffers() {
channel_count = get_channel_count();
temp_buffer.resize(channel_count);
@@ -1352,6 +1361,9 @@ void AudioServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_bus_peak_volume_left_db", "bus_idx", "channel"), &AudioServer::get_bus_peak_volume_left_db);
ClassDB::bind_method(D_METHOD("get_bus_peak_volume_right_db", "bus_idx", "channel"), &AudioServer::get_bus_peak_volume_right_db);
+ ClassDB::bind_method(D_METHOD("set_global_rate_scale", "scale"), &AudioServer::set_global_rate_scale);
+ ClassDB::bind_method(D_METHOD("get_global_rate_scale"), &AudioServer::get_global_rate_scale);
+
ClassDB::bind_method(D_METHOD("lock"), &AudioServer::lock);
ClassDB::bind_method(D_METHOD("unlock"), &AudioServer::unlock);
@@ -1372,6 +1384,10 @@ void AudioServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_bus_layout", "bus_layout"), &AudioServer::set_bus_layout);
ClassDB::bind_method(D_METHOD("generate_bus_layout"), &AudioServer::generate_bus_layout);
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "bus_count"), "set_bus_count", "get_bus_count");
+ ADD_PROPERTY(PropertyInfo(Variant::STRING, "device"), "set_device", "get_device");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "global_rate_scale"), "set_global_rate_scale", "get_global_rate_scale");
+
ADD_SIGNAL(MethodInfo("bus_layout_changed"));
BIND_ENUM_CONSTANT(SPEAKER_MODE_STEREO);
@@ -1396,6 +1412,7 @@ AudioServer::AudioServer() {
#endif
mix_time = 0;
mix_size = 0;
+ global_rate_scale = 1;
}
AudioServer::~AudioServer() {
diff --git a/servers/audio_server.h b/servers/audio_server.h
index 942fe7bc87..b0fff9d4b7 100644
--- a/servers/audio_server.h
+++ b/servers/audio_server.h
@@ -181,6 +181,8 @@ private:
int channel_count;
int to_mix;
+ float global_rate_scale;
+
struct Bus {
StringName name;
@@ -339,6 +341,9 @@ public:
bool is_bus_channel_active(int p_bus, int p_channel) const;
+ void set_global_rate_scale(float p_scale);
+ float get_global_rate_scale() const;
+
virtual void init();
virtual void finish();
virtual void update();
diff --git a/servers/physics/collision_object_sw.cpp b/servers/physics/collision_object_sw.cpp
index b1c21290ab..39de440da2 100644
--- a/servers/physics/collision_object_sw.cpp
+++ b/servers/physics/collision_object_sw.cpp
@@ -76,6 +76,13 @@ void CollisionObjectSW::set_shape_transform(int p_index, const Transform &p_tran
//_shapes_changed();
}
+void CollisionObjectSW::set_shape_as_disabled(int p_idx, bool p_enable) {
+ shapes.write[p_idx].disabled = p_enable;
+ if (!pending_shape_update_list.in_list()) {
+ PhysicsServerSW::singleton->pending_shape_update_list.add(&pending_shape_update_list);
+ }
+}
+
void CollisionObjectSW::remove_shape(ShapeSW *p_shape) {
//remove a shape, all the times it appears
diff --git a/servers/physics/collision_object_sw.h b/servers/physics/collision_object_sw.h
index c2c3fe0e5a..895eda8528 100644
--- a/servers/physics/collision_object_sw.h
+++ b/servers/physics/collision_object_sw.h
@@ -139,8 +139,11 @@ public:
_FORCE_INLINE_ void set_ray_pickable(bool p_enable) { ray_pickable = p_enable; }
_FORCE_INLINE_ bool is_ray_pickable() const { return ray_pickable; }
- _FORCE_INLINE_ void set_shape_as_disabled(int p_idx, bool p_enable) { shapes.write[p_idx].disabled = p_enable; }
- _FORCE_INLINE_ bool is_shape_set_as_disabled(int p_idx) const { return shapes[p_idx].disabled; }
+ void set_shape_as_disabled(int p_idx, bool p_enable);
+ _FORCE_INLINE_ bool is_shape_set_as_disabled(int p_idx) const {
+ CRASH_BAD_INDEX(p_idx, shapes.size());
+ return shapes[p_idx].disabled;
+ }
_FORCE_INLINE_ void set_collision_layer(uint32_t p_layer) { collision_layer = p_layer; }
_FORCE_INLINE_ uint32_t get_collision_layer() const { return collision_layer; }
diff --git a/servers/physics_2d/collision_object_2d_sw.cpp b/servers/physics_2d/collision_object_2d_sw.cpp
index 445a2e0613..f556638db1 100644
--- a/servers/physics_2d/collision_object_2d_sw.cpp
+++ b/servers/physics_2d/collision_object_2d_sw.cpp
@@ -29,6 +29,7 @@
/*************************************************************************/
#include "collision_object_2d_sw.h"
+#include "servers/physics_2d/physics_2d_server_sw.h"
#include "space_2d_sw.h"
void CollisionObject2DSW::add_shape(Shape2DSW *p_shape, const Transform2D &p_transform, bool p_disabled) {
@@ -43,8 +44,12 @@ void CollisionObject2DSW::add_shape(Shape2DSW *p_shape, const Transform2D &p_tra
s.one_way_collision_margin = 0;
shapes.push_back(s);
p_shape->add_owner(this);
- _update_shapes();
- _shapes_changed();
+
+ if (!pending_shape_update_list.in_list()) {
+ Physics2DServerSW::singletonsw->pending_shape_update_list.add(&pending_shape_update_list);
+ }
+ // _update_shapes();
+ // _shapes_changed();
}
void CollisionObject2DSW::set_shape(int p_index, Shape2DSW *p_shape) {
@@ -54,8 +59,12 @@ void CollisionObject2DSW::set_shape(int p_index, Shape2DSW *p_shape) {
shapes.write[p_index].shape = p_shape;
p_shape->add_owner(this);
- _update_shapes();
- _shapes_changed();
+
+ if (!pending_shape_update_list.in_list()) {
+ Physics2DServerSW::singletonsw->pending_shape_update_list.add(&pending_shape_update_list);
+ }
+ // _update_shapes();
+ // _shapes_changed();
}
void CollisionObject2DSW::set_shape_metadata(int p_index, const Variant &p_metadata) {
@@ -70,8 +79,12 @@ void CollisionObject2DSW::set_shape_transform(int p_index, const Transform2D &p_
shapes.write[p_index].xform = p_transform;
shapes.write[p_index].xform_inv = p_transform.affine_inverse();
- _update_shapes();
- _shapes_changed();
+
+ if (!pending_shape_update_list.in_list()) {
+ Physics2DServerSW::singletonsw->pending_shape_update_list.add(&pending_shape_update_list);
+ }
+ // _update_shapes();
+ // _shapes_changed();
}
void CollisionObject2DSW::set_shape_as_disabled(int p_idx, bool p_disabled) {
@@ -89,9 +102,15 @@ void CollisionObject2DSW::set_shape_as_disabled(int p_idx, bool p_disabled) {
if (p_disabled && shape.bpid != 0) {
space->get_broadphase()->remove(shape.bpid);
shape.bpid = 0;
- _update_shapes();
+ if (!pending_shape_update_list.in_list()) {
+ Physics2DServerSW::singletonsw->pending_shape_update_list.add(&pending_shape_update_list);
+ }
+ //_update_shapes();
} else if (!p_disabled && shape.bpid == 0) {
- _update_shapes(); // automatically adds shape with bpid == 0
+ if (!pending_shape_update_list.in_list()) {
+ Physics2DServerSW::singletonsw->pending_shape_update_list.add(&pending_shape_update_list);
+ }
+ //_update_shapes(); // automatically adds shape with bpid == 0
}
}
@@ -122,8 +141,11 @@ void CollisionObject2DSW::remove_shape(int p_index) {
shapes[p_index].shape->remove_owner(this);
shapes.remove(p_index);
- _update_shapes();
- _shapes_changed();
+ if (!pending_shape_update_list.in_list()) {
+ Physics2DServerSW::singletonsw->pending_shape_update_list.add(&pending_shape_update_list);
+ }
+ // _update_shapes();
+ // _shapes_changed();
}
void CollisionObject2DSW::_set_static(bool p_static) {
@@ -239,7 +261,8 @@ void CollisionObject2DSW::_shape_changed() {
_shapes_changed();
}
-CollisionObject2DSW::CollisionObject2DSW(Type p_type) {
+CollisionObject2DSW::CollisionObject2DSW(Type p_type) :
+ pending_shape_update_list(this) {
_static = true;
type = p_type;
diff --git a/servers/physics_2d/collision_object_2d_sw.h b/servers/physics_2d/collision_object_2d_sw.h
index fa18e61262..ed59469878 100644
--- a/servers/physics_2d/collision_object_2d_sw.h
+++ b/servers/physics_2d/collision_object_2d_sw.h
@@ -78,6 +78,8 @@ private:
uint32_t collision_layer;
bool _static;
+ SelfList<CollisionObject2DSW> pending_shape_update_list;
+
void _update_shapes();
protected:
diff --git a/servers/physics_2d/physics_2d_server_sw.cpp b/servers/physics_2d/physics_2d_server_sw.cpp
index 0efa15d43e..cc656d3b73 100644
--- a/servers/physics_2d/physics_2d_server_sw.cpp
+++ b/servers/physics_2d/physics_2d_server_sw.cpp
@@ -902,6 +902,8 @@ void Physics2DServerSW::body_apply_torque_impulse(RID p_body, real_t p_torque) {
Body2DSW *body = body_owner.get(p_body);
ERR_FAIL_COND(!body);
+ _update_shapes();
+
body->apply_torque_impulse(p_torque);
}
@@ -910,6 +912,8 @@ void Physics2DServerSW::body_apply_impulse(RID p_body, const Vector2 &p_pos, con
Body2DSW *body = body_owner.get(p_body);
ERR_FAIL_COND(!body);
+ _update_shapes();
+
body->apply_impulse(p_pos, p_impulse);
body->wakeup();
};
@@ -944,6 +948,8 @@ void Physics2DServerSW::body_set_axis_velocity(RID p_body, const Vector2 &p_axis
Body2DSW *body = body_owner.get(p_body);
ERR_FAIL_COND(!body);
+ _update_shapes();
+
Vector2 v = body->get_linear_velocity();
Vector2 axis = p_axis_velocity.normalized();
v -= axis * axis.dot(v);
@@ -1052,6 +1058,8 @@ bool Physics2DServerSW::body_test_motion(RID p_body, const Transform2D &p_from,
ERR_FAIL_COND_V(!body->get_space(), false);
ERR_FAIL_COND_V(body->get_space()->is_locked(), false);
+ _update_shapes();
+
return body->get_space()->test_body_motion(body, p_from, p_motion, p_infinite_inertia, p_margin, r_result, p_exclude_raycast_shapes);
}
@@ -1238,6 +1246,8 @@ Physics2DServer::JointType Physics2DServerSW::joint_get_type(RID p_joint) const
void Physics2DServerSW::free(RID p_rid) {
+ _update_shapes(); // just in case
+
if (shape_owner.owns(p_rid)) {
Shape2DSW *shape = shape_owner.get(p_rid);
@@ -1335,6 +1345,8 @@ void Physics2DServerSW::step(real_t p_step) {
if (!active)
return;
+ _update_shapes();
+
doing_sync = false;
last_step = p_step;
@@ -1418,6 +1430,14 @@ void Physics2DServerSW::finish() {
memdelete(direct_state);
};
+void Physics2DServerSW::_update_shapes() {
+
+ while (pending_shape_update_list.first()) {
+ pending_shape_update_list.first()->self()->_shape_changed();
+ pending_shape_update_list.remove(pending_shape_update_list.first());
+ }
+}
+
int Physics2DServerSW::get_process_info(ProcessInfo p_info) {
switch (p_info) {
diff --git a/servers/physics_2d/physics_2d_server_sw.h b/servers/physics_2d/physics_2d_server_sw.h
index adc011af40..72625c397c 100644
--- a/servers/physics_2d/physics_2d_server_sw.h
+++ b/servers/physics_2d/physics_2d_server_sw.h
@@ -70,6 +70,9 @@ class Physics2DServerSW : public Physics2DServer {
static Physics2DServerSW *singletonsw;
//void _clear_query(Query2DSW *p_query);
+ friend class CollisionObject2DSW;
+ SelfList<CollisionObject2DSW>::List pending_shape_update_list;
+ void _update_shapes();
RID _shape_create(ShapeType p_shape);