From 4cfe174263699762a2f72aa8ea5e27261239defd Mon Sep 17 00:00:00 2001 From: Mario Liebisch Date: Sun, 23 May 2021 09:37:53 +0200 Subject: [PATCH 01/38] Increase line counter when parsing comments (cherry picked from commit bf708e72dc5b6de7f2b0e8f433f17ba2e3064179) --- core/variant_parser.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/core/variant_parser.cpp b/core/variant_parser.cpp index 4c5a1f93053..51810cc2aef 100644 --- a/core/variant_parser.cpp +++ b/core/variant_parser.cpp @@ -157,6 +157,7 @@ Error VariantParser::get_token(Stream *p_stream, Token &r_token, int &line, Stri return OK; } if (ch == '\n') { + line++; break; } } @@ -1457,6 +1458,7 @@ Error VariantParser::parse_tag_assign_eof(Stream *p_stream, int &line, String &r return ERR_FILE_EOF; } if (ch == '\n') { + line++; break; } } From 93482809e5eaf458865b87b78dc46ff55e321160 Mon Sep 17 00:00:00 2001 From: kobewi Date: Thu, 5 May 2022 17:57:25 +0200 Subject: [PATCH 02/38] Fix error spam when tweened node leaves tree (cherry picked from commit 45e4cb2bbf70a4f26c28045abbb60d9ad180abe1) --- scene/animation/scene_tree_tween.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scene/animation/scene_tree_tween.cpp b/scene/animation/scene_tree_tween.cpp index 7d849353ba8..d15e3299ba3 100644 --- a/scene/animation/scene_tree_tween.cpp +++ b/scene/animation/scene_tree_tween.cpp @@ -332,7 +332,7 @@ bool SceneTreeTween::can_process(bool p_tree_paused) const { if (is_bound && pause_mode == TWEEN_PAUSE_BOUND) { Node *bound_node = get_bound_node(); if (bound_node) { - return bound_node->can_process(); + return bound_node->is_inside_tree() && bound_node->can_process(); } } From 5cedb395dc49b143ebe7a2f2e4eb7fef92325b2a Mon Sep 17 00:00:00 2001 From: Nicholas Huelin <62965063+SirQuartz@users.noreply.github.com> Date: Fri, 15 Apr 2022 01:09:07 -0400 Subject: [PATCH 03/38] Fix inconsistent naming in Time (cherry picked from commit 8409d92282e71f8ad479f48d6b1f6d52eb73ae39) --- core/os/time.cpp | 8 ++++---- core/os/time.h | 4 ++-- doc/classes/Time.xml | 4 ++-- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/core/os/time.cpp b/core/os/time.cpp index 4461a752e8e..c7d4b73c1c7 100644 --- a/core/os/time.cpp +++ b/core/os/time.cpp @@ -261,7 +261,7 @@ String Time::get_time_string_from_unix_time(int64_t p_unix_time_val) const { return vformat("%02d:%02d:%02d", hour, minute, second); } -Dictionary Time::get_datetime_dict_from_string(String p_datetime, bool p_weekday) const { +Dictionary Time::get_datetime_dict_from_datetime_string(String p_datetime, bool p_weekday) const { PARSE_ISO8601_STRING(Dictionary()) Dictionary dict; dict[YEAR_KEY] = year; @@ -279,7 +279,7 @@ Dictionary Time::get_datetime_dict_from_string(String p_datetime, bool p_weekday return dict; } -String Time::get_datetime_string_from_dict(const Dictionary p_datetime, bool p_use_space) const { +String Time::get_datetime_string_from_datetime_dict(const Dictionary p_datetime, bool p_use_space) const { ERR_FAIL_COND_V_MSG(p_datetime.empty(), "", "Invalid datetime Dictionary: Dictionary is empty."); EXTRACT_FROM_DICTIONARY VALIDATE_YMDHMS("") @@ -410,8 +410,8 @@ void Time::_bind_methods() { ClassDB::bind_method(D_METHOD("get_datetime_string_from_unix_time", "unix_time_val", "use_space"), &Time::get_datetime_string_from_unix_time, DEFVAL(false)); ClassDB::bind_method(D_METHOD("get_date_string_from_unix_time", "unix_time_val"), &Time::get_date_string_from_unix_time); ClassDB::bind_method(D_METHOD("get_time_string_from_unix_time", "unix_time_val"), &Time::get_time_string_from_unix_time); - ClassDB::bind_method(D_METHOD("get_datetime_dict_from_string", "datetime", "weekday"), &Time::get_datetime_dict_from_string); - ClassDB::bind_method(D_METHOD("get_datetime_string_from_dict", "datetime", "use_space"), &Time::get_datetime_string_from_dict); + ClassDB::bind_method(D_METHOD("get_datetime_dict_from_datetime_string", "datetime", "weekday"), &Time::get_datetime_dict_from_datetime_string); + ClassDB::bind_method(D_METHOD("get_datetime_string_from_datetime_dict", "datetime", "use_space"), &Time::get_datetime_string_from_datetime_dict); ClassDB::bind_method(D_METHOD("get_unix_time_from_datetime_dict", "datetime"), &Time::get_unix_time_from_datetime_dict); ClassDB::bind_method(D_METHOD("get_unix_time_from_datetime_string", "datetime"), &Time::get_unix_time_from_datetime_string); ClassDB::bind_method(D_METHOD("get_offset_string_from_offset_minutes", "offset_minutes"), &Time::get_offset_string_from_offset_minutes); diff --git a/core/os/time.h b/core/os/time.h index b786e1d018d..a7c31a4b968 100644 --- a/core/os/time.h +++ b/core/os/time.h @@ -85,8 +85,8 @@ public: String get_datetime_string_from_unix_time(int64_t p_unix_time_val, bool p_use_space = false) const; String get_date_string_from_unix_time(int64_t p_unix_time_val) const; String get_time_string_from_unix_time(int64_t p_unix_time_val) const; - Dictionary get_datetime_dict_from_string(String p_datetime, bool p_weekday = true) const; - String get_datetime_string_from_dict(const Dictionary p_datetime, bool p_use_space = false) const; + Dictionary get_datetime_dict_from_datetime_string(String p_datetime, bool p_weekday = true) const; + String get_datetime_string_from_datetime_dict(const Dictionary p_datetime, bool p_use_space = false) const; int64_t get_unix_time_from_datetime_dict(const Dictionary p_datetime) const; int64_t get_unix_time_from_datetime_string(String p_datetime) const; String get_offset_string_from_offset_minutes(int64_t p_offset_minutes) const; diff --git a/doc/classes/Time.xml b/doc/classes/Time.xml index bfd1f41e3e8..c3e4a4e3915 100644 --- a/doc/classes/Time.xml +++ b/doc/classes/Time.xml @@ -43,7 +43,7 @@ Converts the given Unix timestamp to an ISO 8601 date string (YYYY-MM-DD). - + @@ -68,7 +68,7 @@ The returned Dictionary's values will be the same as the [method get_datetime_dict_from_system] if the Unix timestamp is the current time, with the exception of Daylight Savings Time as it cannot be determined from the epoch. - + From 6b7815ea74e14d8c0b339d2e39c5d28e00b0f847 Mon Sep 17 00:00:00 2001 From: Hugo Locurcio Date: Thu, 5 May 2022 19:29:46 +0200 Subject: [PATCH 04/38] Add French translation for Linux desktop file (cherry picked from commit 2212afd7947cc15847388ff09411c13ad6d62310) --- misc/dist/linux/org.godotengine.Godot.desktop | 2 ++ 1 file changed, 2 insertions(+) diff --git a/misc/dist/linux/org.godotengine.Godot.desktop b/misc/dist/linux/org.godotengine.Godot.desktop index 98c7ada4308..79d3d89f418 100644 --- a/misc/dist/linux/org.godotengine.Godot.desktop +++ b/misc/dist/linux/org.godotengine.Godot.desktop @@ -1,8 +1,10 @@ [Desktop Entry] Name=Godot Engine GenericName=Libre game engine +GenericName[fr]=Moteur de jeu libre GenericName[zh_CN]=自由的游戏引擎 Comment=Multi-platform 2D and 3D game engine with a feature-rich editor +Comment[fr]=Moteur de jeu 2D et 3D multiplateforme avec un éditeur riche en fonctionnalités Comment[zh_CN]=多平台 2D 和 3D 游戏引擎,带有功能丰富的编辑器 Exec=godot %f Icon=godot From 9350256eff28733bb8978ed233daf2ff9e6f6e59 Mon Sep 17 00:00:00 2001 From: Emmanouil Papadeas <35376950+OverloadedOrama@users.noreply.github.com> Date: Fri, 6 May 2022 18:55:46 +0300 Subject: [PATCH 05/38] Add Greek translation for Linux desktop file Follow-up to #60777 and #60800. (cherry picked from commit ab444469f0f22e516d12f9f29d5dff229bd85885) --- misc/dist/linux/org.godotengine.Godot.desktop | 2 ++ 1 file changed, 2 insertions(+) diff --git a/misc/dist/linux/org.godotengine.Godot.desktop b/misc/dist/linux/org.godotengine.Godot.desktop index 79d3d89f418..db0c80e4f11 100644 --- a/misc/dist/linux/org.godotengine.Godot.desktop +++ b/misc/dist/linux/org.godotengine.Godot.desktop @@ -1,9 +1,11 @@ [Desktop Entry] Name=Godot Engine GenericName=Libre game engine +GenericName[el]=Ελεύθερη μηχανή παιχνιδιού GenericName[fr]=Moteur de jeu libre GenericName[zh_CN]=自由的游戏引擎 Comment=Multi-platform 2D and 3D game engine with a feature-rich editor +Comment[el]=2D και 3D μηχανή παιχνιδιού πολλαπλών πλατφορμών με επεξεργαστή πλούσιο σε χαρακτηριστικά Comment[fr]=Moteur de jeu 2D et 3D multiplateforme avec un éditeur riche en fonctionnalités Comment[zh_CN]=多平台 2D 和 3D 游戏引擎,带有功能丰富的编辑器 Exec=godot %f From 5fa7ed768668956a6ad097608d51105c9ec70950 Mon Sep 17 00:00:00 2001 From: kobewi Date: Mon, 9 May 2022 01:22:31 +0200 Subject: [PATCH 06/38] Rescue orphan nodes in inherited scenes (cherry picked from commit 2b53826ee6872d48acafb9ece1b9027467d2611d) --- scene/resources/packed_scene.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/scene/resources/packed_scene.cpp b/scene/resources/packed_scene.cpp index 1f780b24526..aee5b2ed6cd 100644 --- a/scene/resources/packed_scene.cpp +++ b/scene/resources/packed_scene.cpp @@ -114,6 +114,7 @@ Node *SceneState::instance(GenEditState p_edit_state) const { const NodeData &n = nd[i]; Node *parent = nullptr; + String old_parent_path; if (i > 0) { ERR_FAIL_COND_V_MSG(n.parent == -1, nullptr, vformat("Invalid scene: node %s does not specify its parent node.", snames[n.name])); @@ -121,6 +122,8 @@ Node *SceneState::instance(GenEditState p_edit_state) const { #ifdef DEBUG_ENABLED if (!nparent && (n.parent & FLAG_ID_IS_PATH)) { WARN_PRINT(String("Parent path '" + String(node_paths[n.parent & FLAG_MASK]) + "' for node '" + String(snames[n.name]) + "' has vanished when instancing: '" + get_path() + "'.").ascii().get_data()); + old_parent_path = String(node_paths[n.parent & FLAG_MASK]).trim_prefix("./").replace("/", "@"); + nparent = ret_nodes[0]; } #endif parent = nparent; @@ -305,6 +308,10 @@ Node *SceneState::instance(GenEditState p_edit_state) const { } } + if (!old_parent_path.empty()) { + node->_set_name_nocheck(old_parent_path + "@" + node->get_name()); + } + if (n.owner >= 0) { NODE_FROM_ID(owner, n.owner); if (owner) { From 06b7f218c6d35dadbfac254486438237325ebe86 Mon Sep 17 00:00:00 2001 From: kleonc <9283098+kleonc@users.noreply.github.com> Date: Sun, 3 Oct 2021 14:49:18 +0200 Subject: [PATCH 07/38] AnimationTrackEditor Fix signal connection on root exiting the tree (cherry picked from commit 2ede2bac0bb14b96b0d6f65e99d4eeccdc00702b) --- editor/animation_track_editor.cpp | 2 +- editor/animation_track_editor.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/editor/animation_track_editor.cpp b/editor/animation_track_editor.cpp index f19f44b6aa8..847d9497306 100644 --- a/editor/animation_track_editor.cpp +++ b/editor/animation_track_editor.cpp @@ -3228,7 +3228,7 @@ Ref AnimationTrackEditor::get_current_animation() const { return animation; } -void AnimationTrackEditor::_root_removed(Node *p_root) { +void AnimationTrackEditor::_root_removed() { root = nullptr; } diff --git a/editor/animation_track_editor.h b/editor/animation_track_editor.h index 0229f59dacc..865c6ac2caa 100644 --- a/editor/animation_track_editor.h +++ b/editor/animation_track_editor.h @@ -376,7 +376,7 @@ class AnimationTrackEditor : public VBoxContainer { TrackIndices _confirm_insert(InsertData p_id, TrackIndices p_next_tracks, bool p_create_reset, Ref p_reset_anim, bool p_create_beziers); void _insert_delay(bool p_create_reset, bool p_create_beziers); - void _root_removed(Node *p_root); + void _root_removed(); PropertyInfo _find_hint_for_track(int p_idx, NodePath &r_base_path, Variant *r_current_val = nullptr); From bdbbc78da4f1df10e38b32c05d89efd0c213a431 Mon Sep 17 00:00:00 2001 From: kobewi Date: Sun, 8 May 2022 00:31:40 +0200 Subject: [PATCH 08/38] Mention that Area2D doesn't support one_way_collision (cherry picked from commit c836bdf5b117c0262ca0794443da80fc3aba7ed3) --- doc/classes/CollisionPolygon2D.xml | 1 + doc/classes/CollisionShape2D.xml | 1 + scene/2d/collision_polygon_2d.cpp | 5 +++++ scene/2d/collision_shape_2d.cpp | 5 +++++ 4 files changed, 12 insertions(+) diff --git a/doc/classes/CollisionPolygon2D.xml b/doc/classes/CollisionPolygon2D.xml index 2f42aff7fa5..4b28480ceba 100644 --- a/doc/classes/CollisionPolygon2D.xml +++ b/doc/classes/CollisionPolygon2D.xml @@ -19,6 +19,7 @@ If [code]true[/code], only edges that face up, relative to [CollisionPolygon2D]'s rotation, will collide with other objects. + [b]Note:[/b] This property has no effect if this [CollisionPolygon2D] is a child of an [Area2D] node. The margin used for one-way collision (in pixels). Higher values will make the shape thicker, and work better for colliders that enter the polygon at a high velocity. diff --git a/doc/classes/CollisionShape2D.xml b/doc/classes/CollisionShape2D.xml index 19d93f6452b..ca12e0fc318 100644 --- a/doc/classes/CollisionShape2D.xml +++ b/doc/classes/CollisionShape2D.xml @@ -20,6 +20,7 @@ Sets whether this collision shape should only detect collision on one side (top or bottom). + [b]Note:[/b] This property has no effect if this [CollisionShape2D] is a child of an [Area2D] node. The margin used for one-way collision (in pixels). Higher values will make the shape thicker, and work better for colliders that enter the shape at a high velocity. diff --git a/scene/2d/collision_polygon_2d.cpp b/scene/2d/collision_polygon_2d.cpp index ab1cfedc535..23ff5074a95 100644 --- a/scene/2d/collision_polygon_2d.cpp +++ b/scene/2d/collision_polygon_2d.cpp @@ -32,6 +32,7 @@ #include "collision_object_2d.h" #include "core/engine.h" +#include "scene/2d/area_2d.h" #include "scene/resources/concave_polygon_shape_2d.h" #include "scene/resources/convex_polygon_shape_2d.h" @@ -273,6 +274,9 @@ String CollisionPolygon2D::get_configuration_warning() const { warning += TTR("Invalid polygon. At least 2 points are needed in 'Segments' build mode."); } } + if (one_way_collision && Object::cast_to(get_parent())) { + warning += TTR("The One Way Collision property will be ignored when the parent is an Area2D."); + } return warning; } @@ -295,6 +299,7 @@ void CollisionPolygon2D::set_one_way_collision(bool p_enable) { if (parent) { parent->shape_owner_set_one_way_collision(owner_id, p_enable); } + update_configuration_warning(); } bool CollisionPolygon2D::is_one_way_collision_enabled() const { diff --git a/scene/2d/collision_shape_2d.cpp b/scene/2d/collision_shape_2d.cpp index ef867ff9f07..5bd8e3db952 100644 --- a/scene/2d/collision_shape_2d.cpp +++ b/scene/2d/collision_shape_2d.cpp @@ -32,6 +32,7 @@ #include "collision_object_2d.h" #include "core/engine.h" +#include "scene/2d/area_2d.h" #include "scene/resources/capsule_shape_2d.h" #include "scene/resources/circle_shape_2d.h" #include "scene/resources/concave_polygon_shape_2d.h" @@ -204,6 +205,9 @@ String CollisionShape2D::get_configuration_warning() const { warning += TTR("Polygon-based shapes are not meant be used nor edited directly through the CollisionShape2D node. Please use the CollisionPolygon2D node instead."); } } + if (one_way_collision && Object::cast_to(get_parent())) { + warning += TTR("The One Way Collision property will be ignored when the parent is an Area2D."); + } return warning; } @@ -226,6 +230,7 @@ void CollisionShape2D::set_one_way_collision(bool p_enable) { if (parent) { parent->shape_owner_set_one_way_collision(owner_id, p_enable); } + update_configuration_warning(); } bool CollisionShape2D::is_one_way_collision_enabled() const { From 5e693b6d84e62b352690a203cc3e46d481b18083 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20Verschelde?= Date: Tue, 10 May 2022 12:05:52 +0200 Subject: [PATCH 09/38] Fix warnings found by Emscripten 3.1.10 Fix `-Wunused-but-set-variable`, `-Wunqualified-std-cast-call`, and `-Wliteral-range` warnings. (cherry picked from commit d8935b27a9af8a6484d271a5b4ebc967a9d0a36f) --- core/math/bsp_tree.cpp | 4 ++-- core/math/quick_hull.cpp | 2 -- modules/csg/csg.cpp | 7 +++---- modules/gdscript/gdscript_compiler.cpp | 4 ---- scene/3d/voxel_light_baker.cpp | 3 --- scene/resources/polygon_path_finder.cpp | 8 ++++---- servers/visual/portals/portal_rooms_bsp.cpp | 3 --- servers/visual/visual_server_scene.cpp | 12 ------------ servers/visual/visual_server_viewport.cpp | 7 ------- thirdparty/bullet/BulletSoftBody/btSparseSDF.h | 6 +++--- .../patches/fix-unused-but-set-warning.patch | 17 +++++++++++++++++ 11 files changed, 29 insertions(+), 44 deletions(-) create mode 100644 thirdparty/bullet/patches/fix-unused-but-set-warning.patch diff --git a/core/math/bsp_tree.cpp b/core/math/bsp_tree.cpp index ff3eaea667d..9a60a0805fc 100644 --- a/core/math/bsp_tree.cpp +++ b/core/math/bsp_tree.cpp @@ -271,7 +271,7 @@ static int _bsp_find_best_half_plane(const Face3 *p_faces, const Vector &p_ const Face3 &f = p_faces[indices[i]]; Plane p = f.get_plane(); - int num_over = 0, num_under = 0, num_spanning = 0; + int num_over = 0, num_under = 0; //num_spanning = 0; for (int j = 0; j < ic; j++) { if (i == j) { @@ -294,7 +294,7 @@ static int _bsp_find_best_half_plane(const Face3 *p_faces, const Vector &p_ } if (over && under) { - num_spanning++; + //num_spanning++; } else if (over) { num_over++; } else { diff --git a/core/math/quick_hull.cpp b/core/math/quick_hull.cpp index 17e43abcebc..8bbba3262b3 100644 --- a/core/math/quick_hull.cpp +++ b/core/math/quick_hull.cpp @@ -394,7 +394,6 @@ Error QuickHull::build(const Vector &p_points, Geometry::MeshData &r_me if (O->get().plane.is_equal_approx(f.plane)) { //merge and delete edge and contiguous face, while repointing edges (uuugh!) int ois = O->get().indices.size(); - int merged = 0; for (int j = 0; j < ois; j++) { //search a @@ -409,7 +408,6 @@ Error QuickHull::build(const Vector &p_points, Geometry::MeshData &r_me if (idx != a) { f.indices.insert(i + 1, idx); i++; - merged++; } Edge e2(idx, idxn); diff --git a/modules/csg/csg.cpp b/modules/csg/csg.cpp index 25ae92eb045..16fa0ac3794 100644 --- a/modules/csg/csg.cpp +++ b/modules/csg/csg.cpp @@ -1387,13 +1387,13 @@ void CSGBrushOperation::update_faces(const CSGBrush &p_brush_a, const int p_face } // Ensure B has points either side of or in the plane of A. - int in_plane_count = 0, over_count = 0, under_count = 0; + int over_count = 0, under_count = 0; Plane plane_a(vertices_a[0], vertices_a[1], vertices_a[2]); ERR_FAIL_COND_MSG(plane_a.normal == Vector3(), "Couldn't form plane from Brush A face."); for (int i = 0; i < 3; i++) { if (plane_a.has_point(vertices_b[i])) { - in_plane_count++; + // In plane. } else if (plane_a.is_point_over(vertices_b[i])) { over_count++; } else { @@ -1406,7 +1406,6 @@ void CSGBrushOperation::update_faces(const CSGBrush &p_brush_a, const int p_face } // Ensure A has points either side of or in the plane of B. - in_plane_count = 0; over_count = 0; under_count = 0; Plane plane_b(vertices_b[0], vertices_b[1], vertices_b[2]); @@ -1414,7 +1413,7 @@ void CSGBrushOperation::update_faces(const CSGBrush &p_brush_a, const int p_face for (int i = 0; i < 3; i++) { if (plane_b.has_point(vertices_a[i])) { - in_plane_count++; + // In plane. } else if (plane_b.is_point_over(vertices_a[i])) { over_count++; } else { diff --git a/modules/gdscript/gdscript_compiler.cpp b/modules/gdscript/gdscript_compiler.cpp index fe2ea5478de..8b152699b36 100644 --- a/modules/gdscript/gdscript_compiler.cpp +++ b/modules/gdscript/gdscript_compiler.cpp @@ -1316,7 +1316,6 @@ int GDScriptCompiler::_parse_expression(CodeGen &codegen, const GDScriptParser:: Error GDScriptCompiler::_parse_block(CodeGen &codegen, const GDScriptParser::BlockNode *p_block, int p_stack_level, int p_break_addr, int p_continue_addr) { codegen.push_stack_identifiers(); - int new_identifiers = 0; codegen.current_line = p_block->line; for (int i = 0; i < p_block->statements.size(); i++) { @@ -1347,7 +1346,6 @@ Error GDScriptCompiler::_parse_block(CodeGen &codegen, const GDScriptParser::Blo // copied because there is no _parse_statement :( codegen.add_stack_identifier(id->name, p_stack_level++); codegen.alloc_stack(p_stack_level); - new_identifiers++; GDScriptParser::OperatorNode *op = memnew(GDScriptParser::OperatorNode); op->op = GDScriptParser::OperatorNode::OP_ASSIGN; @@ -1605,8 +1603,6 @@ Error GDScriptCompiler::_parse_block(CodeGen &codegen, const GDScriptParser::Blo codegen.add_stack_identifier(lv->name, p_stack_level++); codegen.alloc_stack(p_stack_level); - new_identifiers++; - } break; default: { //expression diff --git a/scene/3d/voxel_light_baker.cpp b/scene/3d/voxel_light_baker.cpp index 676ca5d9bb3..35510da99ca 100644 --- a/scene/3d/voxel_light_baker.cpp +++ b/scene/3d/voxel_light_baker.cpp @@ -854,8 +854,6 @@ void VoxelLightBaker::plot_light_directional(const Vector3 &p_direction, const C float distance_adv = _get_normal_advance(light_axis); - int success_count = 0; - Vector3 light_energy = Vector3(p_color.r, p_color.g, p_color.b) * p_energy * p_indirect_energy; int idx = first_leaf; @@ -916,7 +914,6 @@ void VoxelLightBaker::plot_light_directional(const Vector3 &p_direction, const C light->direct_accum[i][2] += light_energy.z * s; } } - success_count++; } idx = light_data[idx].next_leaf; diff --git a/scene/resources/polygon_path_finder.cpp b/scene/resources/polygon_path_finder.cpp index 435a19b5d53..f714a5f46e8 100644 --- a/scene/resources/polygon_path_finder.cpp +++ b/scene/resources/polygon_path_finder.cpp @@ -137,7 +137,7 @@ Vector PolygonPathFinder::find_path(const Vector2 &p_from, const Vector Edge ignore_to_edge(-1, -1); if (!_is_point_inside(from)) { - float closest_dist = 1e20; + float closest_dist = 1e20f; Vector2 closest_point; for (Set::Element *E = edges.front(); E; E = E->next()) { @@ -161,7 +161,7 @@ Vector PolygonPathFinder::find_path(const Vector2 &p_from, const Vector }; if (!_is_point_inside(to)) { - float closest_dist = 1e20; + float closest_dist = 1e20f; Vector2 closest_point; for (Set::Element *E = edges.front(); E; E = E->next()) { @@ -489,7 +489,7 @@ bool PolygonPathFinder::is_point_inside(const Vector2 &p_point) const { } Vector2 PolygonPathFinder::get_closest_point(const Vector2 &p_point) const { - float closest_dist = 1e20; + float closest_dist = 1e20f; Vector2 closest_point; for (Set::Element *E = edges.front(); E; E = E->next()) { @@ -508,7 +508,7 @@ Vector2 PolygonPathFinder::get_closest_point(const Vector2 &p_point) const { } } - ERR_FAIL_COND_V(closest_dist == 1e20, Vector2()); + ERR_FAIL_COND_V(Math::is_equal_approx(closest_dist, 1e20f), Vector2()); return closest_point; } diff --git a/servers/visual/portals/portal_rooms_bsp.cpp b/servers/visual/portals/portal_rooms_bsp.cpp index 3746980a75e..3966d9729e9 100644 --- a/servers/visual/portals/portal_rooms_bsp.cpp +++ b/servers/visual/portals/portal_rooms_bsp.cpp @@ -526,7 +526,6 @@ int PortalRoomsBSP::evaluate_room_split_plane(int p_room_a_id, int p_room_b_id, int PortalRoomsBSP::evaluate_plane(const VSPortal *p_portal, const Plane &p_plane, const LocalVector &p_room_ids, LocalVector *r_room_ids_back, LocalVector *r_room_ids_front) { int rooms_front = 0; int rooms_back = 0; - int rooms_split = 0; if (r_room_ids_back) { DEV_ASSERT(!r_room_ids_back->size()); @@ -622,8 +621,6 @@ int PortalRoomsBSP::evaluate_plane(const VSPortal *p_portal, const Plane &p_plan if (r_room_ids_back) { r_room_ids_back->push_back(rid); } - - rooms_split++; } #undef GODOT_BSP_PUSH_BACK diff --git a/servers/visual/visual_server_scene.cpp b/servers/visual/visual_server_scene.cpp index 810d5a709a5..969b2fa81ea 100644 --- a/servers/visual/visual_server_scene.cpp +++ b/servers/visual/visual_server_scene.cpp @@ -3750,10 +3750,6 @@ void VisualServerScene::_bake_gi_probe_light(const GIProbeDataHeader *header, co float distance_adv = _get_normal_advance(light_axis); - int success_count = 0; - - // uint64_t us = OS::get_singleton()->get_ticks_usec(); - for (int i = 0; i < p_leaf_count; i++) { uint32_t idx = leaves[i]; @@ -3802,18 +3798,11 @@ void VisualServerScene::_bake_gi_probe_light(const GIProbeDataHeader *header, co light->energy[0] += int32_t(light_r * att * ((cell->albedo >> 16) & 0xFF) / 255.0); light->energy[1] += int32_t(light_g * att * ((cell->albedo >> 8) & 0xFF) / 255.0); light->energy[2] += int32_t(light_b * att * ((cell->albedo) & 0xFF) / 255.0); - success_count++; } } - - // print_line("BAKE TIME: " + rtos((OS::get_singleton()->get_ticks_usec() - us) / 1000000.0)); - // print_line("valid cells: " + itos(success_count)); - } break; case VS::LIGHT_OMNI: case VS::LIGHT_SPOT: { - // uint64_t us = OS::get_singleton()->get_ticks_usec(); - Vector3 light_pos = light_cache.transform.origin; Vector3 spot_axis = -light_cache.transform.basis.get_axis(2).normalized(); @@ -3911,7 +3900,6 @@ void VisualServerScene::_bake_gi_probe_light(const GIProbeDataHeader *header, co light->energy[2] += int32_t(light_b * att * ((cell->albedo) & 0xFF) / 255.0); } } - //print_line("BAKE TIME: " + rtos((OS::get_singleton()->get_ticks_usec() - us) / 1000000.0)); } break; } } diff --git a/servers/visual/visual_server_viewport.cpp b/servers/visual/visual_server_viewport.cpp index 02cd4488976..2474fdbdfad 100644 --- a/servers/visual/visual_server_viewport.cpp +++ b/servers/visual/visual_server_viewport.cpp @@ -107,8 +107,6 @@ void VisualServerViewport::_draw_viewport(Viewport *p_viewport, ARVRInterface::E } if (!p_viewport->hide_canvas) { - int i = 0; - Map canvas_map; Rect2 clip_rect(0, 0, p_viewport->size.x, p_viewport->size.y); @@ -117,8 +115,6 @@ void VisualServerViewport::_draw_viewport(Viewport *p_viewport, ARVRInterface::E RasterizerCanvas::Light *lights_with_mask = nullptr; Rect2 shadow_rect; - int light_count = 0; - for (Map::Element *E = p_viewport->canvas_map.front(); E; E = E->next()) { VisualServerCanvas::Canvas *canvas = static_cast(E->get().canvas); @@ -164,8 +160,6 @@ void VisualServerViewport::_draw_viewport(Viewport *p_viewport, ARVRInterface::E cl->mask_next_ptr = lights_with_mask; lights_with_mask = cl; } - - light_count++; } VSG::canvas_render->light_internal_update(cl->light_internal, cl); @@ -235,7 +229,6 @@ void VisualServerViewport::_draw_viewport(Viewport *p_viewport, ARVRInterface::E } VSG::canvas->render_canvas(canvas, xform, canvas_lights, lights_with_mask, clip_rect, canvas_layer_id); - i++; if (scenario_draw_canvas_bg && E->key().get_layer() >= scenario_canvas_max_layer) { if (!can_draw_3d) { diff --git a/thirdparty/bullet/BulletSoftBody/btSparseSDF.h b/thirdparty/bullet/BulletSoftBody/btSparseSDF.h index ae1288d9e6d..243b80f8ae5 100644 --- a/thirdparty/bullet/BulletSoftBody/btSparseSDF.h +++ b/thirdparty/bullet/BulletSoftBody/btSparseSDF.h @@ -233,9 +233,9 @@ struct btSparseSdf //int sz = sizeof(Cell); if (ncells > m_clampCells) { - static int numResets = 0; - numResets++; - // printf("numResets=%d\n",numResets); + //static int numResets = 0; + //numResets++; + //printf("numResets=%d\n",numResets); Reset(); } diff --git a/thirdparty/bullet/patches/fix-unused-but-set-warning.patch b/thirdparty/bullet/patches/fix-unused-but-set-warning.patch new file mode 100644 index 00000000000..b0b38676f33 --- /dev/null +++ b/thirdparty/bullet/patches/fix-unused-but-set-warning.patch @@ -0,0 +1,17 @@ +diff --git a/thirdparty/bullet/BulletSoftBody/btSparseSDF.h b/thirdparty/bullet/BulletSoftBody/btSparseSDF.h +index ae1288d9e6..243b80f8ae 100644 +--- a/thirdparty/bullet/BulletSoftBody/btSparseSDF.h ++++ b/thirdparty/bullet/BulletSoftBody/btSparseSDF.h +@@ -233,9 +233,9 @@ struct btSparseSdf + //int sz = sizeof(Cell); + if (ncells > m_clampCells) + { +- static int numResets = 0; +- numResets++; +- // printf("numResets=%d\n",numResets); ++ //static int numResets = 0; ++ //numResets++; ++ //printf("numResets=%d\n",numResets); + Reset(); + } + From b66f94d2ff9c5b764a06dd8f62d240fb711d54cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20Verschelde?= Date: Tue, 10 May 2022 12:06:09 +0200 Subject: [PATCH 10/38] CI: Update Emscripten to 3.1.10 That's the version that we'll (tentatively) use for future 3.x and 4.0 builds. (cherry picked from commit f07021fbeb7d91011c1534702042697d246551ac) --- .github/workflows/javascript_builds.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/javascript_builds.yml b/.github/workflows/javascript_builds.yml index df26cdd2abb..4f6da710708 100644 --- a/.github/workflows/javascript_builds.yml +++ b/.github/workflows/javascript_builds.yml @@ -5,7 +5,7 @@ on: [push, pull_request] env: GODOT_BASE_BRANCH: 3.x SCONSFLAGS: verbose=yes warnings=all werror=yes debug_symbols=no - EM_VERSION: 2.0.25 + EM_VERSION: 3.1.10 EM_CACHE_FOLDER: "emsdk-cache" concurrency: From 2d3f5855c62588c6bd5145aa3b53c3902dbe499f Mon Sep 17 00:00:00 2001 From: bruvzg <7645683+bruvzg@users.noreply.github.com> Date: Tue, 10 May 2022 11:12:04 +0300 Subject: [PATCH 11/38] [Windows] Save and re-apply window icon when changing window style. (cherry picked from commit b268c4b4bc8a1c246984249b2ce88277df47fe78) --- platform/windows/os_windows.cpp | 13 ++++++++++--- platform/windows/os_windows.h | 2 ++ 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/platform/windows/os_windows.cpp b/platform/windows/os_windows.cpp index 64cc9cc4848..e6ab0fb07f5 100644 --- a/platform/windows/os_windows.cpp +++ b/platform/windows/os_windows.cpp @@ -2312,6 +2312,10 @@ void OS_Windows::_update_window_style(bool p_repaint, bool p_maximized) { } } + if (icon.is_valid()) { + set_icon(icon); + } + SetWindowPos(hWnd, video_mode.always_on_top ? HWND_TOPMOST : HWND_NOTOPMOST, 0, 0, 0, 0, SWP_FRAMECHANGED | SWP_NOMOVE | SWP_NOSIZE); if (p_repaint) { @@ -3040,9 +3044,12 @@ void OS_Windows::set_native_icon(const String &p_filename) { void OS_Windows::set_icon(const Ref &p_icon) { ERR_FAIL_COND(!p_icon.is_valid()); - Ref icon = p_icon->duplicate(); - if (icon->get_format() != Image::FORMAT_RGBA8) - icon->convert(Image::FORMAT_RGBA8); + if (icon != p_icon) { + icon = p_icon->duplicate(); + if (icon->get_format() != Image::FORMAT_RGBA8) { + icon->convert(Image::FORMAT_RGBA8); + } + } int w = icon->get_width(); int h = icon->get_height(); diff --git a/platform/windows/os_windows.h b/platform/windows/os_windows.h index 7472e47b52c..549b9f0e1f9 100644 --- a/platform/windows/os_windows.h +++ b/platform/windows/os_windows.h @@ -318,6 +318,8 @@ class OS_Windows : public OS { uint32_t move_timer_id; + Ref icon; + HCURSOR hCursor; Size2 min_size; From ddb77740992e62adc1b0667b549b5daaf3d4c870 Mon Sep 17 00:00:00 2001 From: Haoyu Qiu Date: Tue, 10 May 2022 18:27:45 +0800 Subject: [PATCH 12/38] Try to convert OS::execute() output to Unicode on Windows (cherry picked from commit a71e8081124eaf4eac6059bfeb3550a400bc2002) --- platform/windows/os_windows.cpp | 66 ++++++++++++++++++++++++++++----- 1 file changed, 57 insertions(+), 9 deletions(-) diff --git a/platform/windows/os_windows.cpp b/platform/windows/os_windows.cpp index e6ab0fb07f5..7a56eb9be8a 100644 --- a/platform/windows/os_windows.cpp +++ b/platform/windows/os_windows.cpp @@ -2803,6 +2803,31 @@ String OS_Windows::_quote_command_line_argument(const String &p_text) const { return p_text; } +static void _append_to_pipe(char *p_bytes, int p_size, String *r_pipe, Mutex *p_pipe_mutex) { + // Try to convert from default ANSI code page to Unicode. + LocalVector wchars; + int total_wchars = MultiByteToWideChar(CP_ACP, 0, p_bytes, p_size, nullptr, 0); + if (total_wchars > 0) { + wchars.resize(total_wchars); + if (MultiByteToWideChar(CP_ACP, 0, p_bytes, p_size, wchars.ptr(), total_wchars) == 0) { + wchars.clear(); + } + } + + if (p_pipe_mutex) { + p_pipe_mutex->lock(); + } + if (wchars.empty()) { + // Let's hope it's compatible with UTF-8. + (*r_pipe) += String::utf8(p_bytes, p_size); + } else { + (*r_pipe) += String(wchars.ptr(), total_wchars); + } + if (p_pipe_mutex) { + p_pipe_mutex->unlock(); + } +} + Error OS_Windows::execute(const String &p_path, const List &p_arguments, bool p_blocking, ProcessID *r_child_id, String *r_pipe, int *r_exitcode, bool read_stderr, Mutex *p_pipe_mutex, bool p_open_console) { String path = p_path.replace("/", "\\"); @@ -2861,21 +2886,44 @@ Error OS_Windows::execute(const String &p_path, const List &p_arguments, if (p_blocking) { if (r_pipe) { CloseHandle(pipe[1]); // Close pipe write handle (only child process is writing). - char buf[4096]; + + LocalVector bytes; + int bytes_in_buffer = 0; + + const int CHUNK_SIZE = 4096; DWORD read = 0; for (;;) { // Read StdOut and StdErr from pipe. - bool success = ReadFile(pipe[0], buf, 4096, &read, NULL); + bytes.resize(bytes_in_buffer + CHUNK_SIZE); + const bool success = ReadFile(pipe[0], bytes.ptr() + bytes_in_buffer, CHUNK_SIZE, &read, NULL); if (!success || read == 0) { break; } - if (p_pipe_mutex) { - p_pipe_mutex->lock(); + // Assume that all possible encodings are ASCII-compatible. + // Break at newline to allow receiving long output in portions. + int newline_index = -1; + for (int i = read - 1; i >= 0; i--) { + if (bytes[bytes_in_buffer + i] == '\n') { + newline_index = i; + break; + } } - (*r_pipe) += String::utf8(buf, read); - if (p_pipe_mutex) { - p_pipe_mutex->unlock(); + + if (newline_index == -1) { + bytes_in_buffer += read; + continue; } - }; + + const int bytes_to_convert = bytes_in_buffer + (newline_index + 1); + _append_to_pipe(bytes.ptr(), bytes_to_convert, r_pipe, p_pipe_mutex); + + bytes_in_buffer = read - (newline_index + 1); + memmove(bytes.ptr(), bytes.ptr() + bytes_to_convert, bytes_in_buffer); + } + + if (bytes_in_buffer > 0) { + _append_to_pipe(bytes.ptr(), bytes_in_buffer, r_pipe, p_pipe_mutex); + } + CloseHandle(pipe[0]); // Close pipe read handle. } else { WaitForSingleObject(pi.pi.hProcess, INFINITE); @@ -2897,7 +2945,7 @@ Error OS_Windows::execute(const String &p_path, const List &p_arguments, process_map->insert(pid, pi); } return OK; -}; +} Error OS_Windows::kill(const ProcessID &p_pid) { ERR_FAIL_COND_V(!process_map->has(p_pid), FAILED); From 7a4187495db5af8cf46ce03292c2ae707d54f4e4 Mon Sep 17 00:00:00 2001 From: Hendrik Brucker Date: Tue, 10 May 2022 22:27:48 +0200 Subject: [PATCH 13/38] Fix button icon expansion calculation with empty text (cherry picked from commit c09a5e277410761733a59a2b207d7320131b2511) --- scene/gui/button.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/scene/gui/button.cpp b/scene/gui/button.cpp index d8aad4b7d2f..d8f8dfc7af5 100644 --- a/scene/gui/button.cpp +++ b/scene/gui/button.cpp @@ -199,7 +199,8 @@ void Button::_notification(int p_what) { if (expand_icon) { Size2 _size = get_size() - style->get_offset() * 2; - _size.width -= get_constant("hseparation") + icon_ofs_region; + int icon_text_separation = text.empty() ? 0 : get_constant("h_separation"); + _size.width -= icon_text_separation + icon_ofs_region; if (!clip_text && icon_align != ALIGN_CENTER) { _size.width -= get_font("font")->get_string_size(xl_text).width; } From b40dff698cab8eff07c237f49d8c9127b6f45eae Mon Sep 17 00:00:00 2001 From: Haoyu Qiu Date: Wed, 11 May 2022 16:12:31 +0800 Subject: [PATCH 14/38] Fix invalid memory usage when using Image.convert (cherry picked from commit 34c1a2beaa8ae92a445b85458d3681f60cd5216f) --- core/image.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/image.cpp b/core/image.cpp index 7da60c00380..00e6db691c8 100644 --- a/core/image.cpp +++ b/core/image.cpp @@ -370,7 +370,7 @@ static void _convert(int p_width, int p_height, const uint8_t *p_src, uint8_t *p const uint8_t *rofs = &p_src[((y * p_width) + x) * (read_bytes + (read_alpha ? 1 : 0))]; uint8_t *wofs = &p_dst[((y * p_width) + x) * (write_bytes + (write_alpha ? 1 : 0))]; - uint8_t rgba[4]; + uint8_t rgba[4] = { 0, 0, 0, 255 }; if (read_gray) { rgba[0] = rofs[0]; @@ -388,7 +388,7 @@ static void _convert(int p_width, int p_height, const uint8_t *p_src, uint8_t *p if (write_gray) { //TODO: not correct grayscale, should use fixed point version of actual weights - wofs[0] = uint8_t((uint16_t(rofs[0]) + uint16_t(rofs[1]) + uint16_t(rofs[2])) / 3); + wofs[0] = uint8_t((uint16_t(rgba[0]) + uint16_t(rgba[1]) + uint16_t(rgba[2])) / 3); } else { for (uint32_t i = 0; i < write_bytes; i++) { wofs[i] = rgba[i]; From 689179036b8a7a58907b20d751b9aec35e41e7b0 Mon Sep 17 00:00:00 2001 From: smix8 <52464204+smix8@users.noreply.github.com> Date: Wed, 11 May 2022 15:36:50 +0200 Subject: [PATCH 15/38] Add Warning to NavigationMesh bake when source geometry is suspiciously big Adds Warning when users try to bake a NavigationMesh with suspiciously big source geometry and small cellsizes as this baking process will likely fail or result in a NavigationMesh that will create serious pathfinding performance issues. (cherry picked from commit 79511af7c94b447409d10194239069facef9c4a0) --- modules/navigation/navigation_mesh_generator.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/modules/navigation/navigation_mesh_generator.cpp b/modules/navigation/navigation_mesh_generator.cpp index 62ec65bf89a..911c23ed657 100644 --- a/modules/navigation/navigation_mesh_generator.cpp +++ b/modules/navigation/navigation_mesh_generator.cpp @@ -463,6 +463,14 @@ void NavigationMeshGenerator::_build_recast_navigation_mesh( #endif rcCalcGridSize(cfg.bmin, cfg.bmax, cfg.cs, &cfg.width, &cfg.height); + // ~30000000 seems to be around sweetspot where Editor baking breaks + if ((cfg.width * cfg.height) > 30000000) { + WARN_PRINT("NavigationMesh baking process will likely fail." + "\nSource geometry is suspiciously big for the current Cell Size and Cell Height in the NavMesh Resource bake settings." + "\nIf baking does not fail, the resulting NavigationMesh will create serious pathfinding performance issues." + "\nIt is advised to increase Cell Size and/or Cell Height in the NavMesh Resource bake settings or reduce the size / scale of the source geometry."); + } + #ifdef TOOLS_ENABLED if (ep) ep->step(TTR("Creating heightfield..."), 3); From 2398db0f3488ec7a5c969211c7cdcd6cdd4f31e7 Mon Sep 17 00:00:00 2001 From: Eduardo Rodrigues Date: Thu, 14 Apr 2022 00:07:29 -0300 Subject: [PATCH 16/38] Improve description for GDScript built-in range Rewrites the definition of how the function works. Reworks the style of the examples and adds a negative range example. Changes the while loop to a range loop in the array backwards example. (cherry picked from commit b2841ce19494d8b34ef2fc13dd92c827fc1d2cc6) --- modules/gdscript/doc_classes/@GDScript.xml | 28 ++++++++++------------ 1 file changed, 13 insertions(+), 15 deletions(-) diff --git a/modules/gdscript/doc_classes/@GDScript.xml b/modules/gdscript/doc_classes/@GDScript.xml index 506a71d4463..07a39a18e6b 100644 --- a/modules/gdscript/doc_classes/@GDScript.xml +++ b/modules/gdscript/doc_classes/@GDScript.xml @@ -852,26 +852,24 @@ - Returns an array with the given range. Range can be 1 argument [code]N[/code] (0 to [code]N[/code] - 1), two arguments ([code]initial[/code], [code]final - 1[/code]) or three arguments ([code]initial[/code], [code]final - 1[/code], [code]increment[/code]). Returns an empty array if the range isn't valid (e.g. [code]range(2, 5, -1)[/code] or [code]range(5, 5, 1)[/code]). - Returns an array with the given range. [code]range()[/code] can have 1 argument N ([code]0[/code] to [code]N - 1[/code]), two arguments ([code]initial[/code], [code]final - 1[/code]) or three arguments ([code]initial[/code], [code]final - 1[/code], [code]increment[/code]). [code]increment[/code] can be negative. If [code]increment[/code] is negative, [code]final - 1[/code] will become [code]final + 1[/code]. Also, the initial value must be greater than the final value for the loop to run. + Returns an array with the given range. [method range] can be called in three ways: + [code]range(n: int)[/code]: Starts from 0, increases by steps of 1, and stops [i]before[/i] [code]n[/code]. The argument [code]n[/code] is [b]exclusive[/b]. + [code]range(b: int, n: int)[/code]: Starts from [code]b[/code], increases by steps of 1, and stops [i]before[/i] [code]n[/code]. The arguments [code]b[/code] and [code]n[/code] are [b]inclusive[/b] and [b]exclusive[/b], respectively. + [code]range(b: int, n: int, s: int)[/code]: Starts from [code]b[/code], increases/decreases by steps of [code]s[/code], and stops [i]before[/i] [code]n[/code]. The arguments [code]b[/code] and [code]n[/code] are [b]inclusive[/b] and [b]exclusive[/b], respectively. The argument [code]s[/code] [b]can[/b] be negative, but not [code]0[/code]. If [code]s[/code] is [code]0[/code], an error message is printed. + [method range] converts all arguments to [int] before processing. + [b]Note:[/b] Returns an empty array if no value meets the value constraint (e.g. [code]range(2, 5, -1)[/code] or [code]range(5, 5, 1)[/code]). + Examples: [codeblock] - print(range(4)) - print(range(2, 5)) - print(range(0, 6, 2)) - [/codeblock] - Output: - [codeblock] - [0, 1, 2, 3] - [2, 3, 4] - [0, 2, 4] + print(range(4)) # Prints [0, 1, 2, 3] + print(range(2, 5)) # Prints [2, 3, 4] + print(range(0, 6, 2)) # Prints [0, 2, 4] + print(range(4, 1, -1)) # Prints [4, 3, 2] [/codeblock] To iterate over an [Array] backwards, use: [codeblock] var array = [3, 6, 9] - var i := array.size() - 1 - while i >= 0: - print(array[i]) - i -= 1 + for i in range(array.size(), 0, -1): + print(array[i - 1]) [/codeblock] Output: [codeblock] From 621cb8c52f0eb8e70fc8230eec1cc516955e8b78 Mon Sep 17 00:00:00 2001 From: kobewi Date: Thu, 12 May 2022 16:38:59 +0200 Subject: [PATCH 17/38] Move Display settings higher in the list (cherry picked from commit 739242dd04d16f85d542bcf9a29aa44402410481) --- core/project_settings.cpp | 14 ++++++++++++++ main/main.cpp | 13 ------------- 2 files changed, 14 insertions(+), 13 deletions(-) diff --git a/core/project_settings.cpp b/core/project_settings.cpp index 13c5a605f0b..43ef3291194 100644 --- a/core/project_settings.cpp +++ b/core/project_settings.cpp @@ -1069,6 +1069,20 @@ ProjectSettings::ProjectSettings() { GLOBAL_DEF("application/config/use_custom_user_dir", false); GLOBAL_DEF("application/config/custom_user_dir_name", ""); GLOBAL_DEF("application/config/project_settings_override", ""); + + GLOBAL_DEF("display/window/size/width", 1024); + ProjectSettings::get_singleton()->set_custom_property_info("display/window/size/width", PropertyInfo(Variant::INT, "display/window/size/width", PROPERTY_HINT_RANGE, "0,7680,1,or_greater")); // 8K resolution + GLOBAL_DEF("display/window/size/height", 600); + ProjectSettings::get_singleton()->set_custom_property_info("display/window/size/height", PropertyInfo(Variant::INT, "display/window/size/height", PROPERTY_HINT_RANGE, "0,4320,1,or_greater")); // 8K resolution + GLOBAL_DEF("display/window/size/resizable", true); + GLOBAL_DEF("display/window/size/borderless", false); + GLOBAL_DEF("display/window/size/fullscreen", false); + GLOBAL_DEF("display/window/size/always_on_top", false); + GLOBAL_DEF("display/window/size/test_width", 0); + ProjectSettings::get_singleton()->set_custom_property_info("display/window/size/test_width", PropertyInfo(Variant::INT, "display/window/size/test_width", PROPERTY_HINT_RANGE, "0,7680,1,or_greater")); // 8K resolution + GLOBAL_DEF("display/window/size/test_height", 0); + ProjectSettings::get_singleton()->set_custom_property_info("display/window/size/test_height", PropertyInfo(Variant::INT, "display/window/size/test_height", PROPERTY_HINT_RANGE, "0,4320,1,or_greater")); // 8K resolution + GLOBAL_DEF("audio/default_bus_layout", "res://default_bus_layout.tres"); custom_prop_info["audio/default_bus_layout"] = PropertyInfo(Variant::STRING, "audio/default_bus_layout", PROPERTY_HINT_FILE, "*.tres"); diff --git a/main/main.cpp b/main/main.cpp index 3d4ef1f3240..42061a62733 100644 --- a/main/main.cpp +++ b/main/main.cpp @@ -1082,19 +1082,6 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph // Assigning here, to be sure that it appears in docs GLOBAL_DEF("rendering/2d/options/use_nvidia_rect_flicker_workaround", false); - GLOBAL_DEF("display/window/size/width", 1024); - ProjectSettings::get_singleton()->set_custom_property_info("display/window/size/width", PropertyInfo(Variant::INT, "display/window/size/width", PROPERTY_HINT_RANGE, "0,7680,1,or_greater")); // 8K resolution - GLOBAL_DEF("display/window/size/height", 600); - ProjectSettings::get_singleton()->set_custom_property_info("display/window/size/height", PropertyInfo(Variant::INT, "display/window/size/height", PROPERTY_HINT_RANGE, "0,4320,1,or_greater")); // 8K resolution - GLOBAL_DEF("display/window/size/resizable", true); - GLOBAL_DEF("display/window/size/borderless", false); - GLOBAL_DEF("display/window/size/fullscreen", false); - GLOBAL_DEF("display/window/size/always_on_top", false); - GLOBAL_DEF("display/window/size/test_width", 0); - ProjectSettings::get_singleton()->set_custom_property_info("display/window/size/test_width", PropertyInfo(Variant::INT, "display/window/size/test_width", PROPERTY_HINT_RANGE, "0,7680,1,or_greater")); // 8K resolution - GLOBAL_DEF("display/window/size/test_height", 0); - ProjectSettings::get_singleton()->set_custom_property_info("display/window/size/test_height", PropertyInfo(Variant::INT, "display/window/size/test_height", PROPERTY_HINT_RANGE, "0,4320,1,or_greater")); // 8K resolution - if (use_custom_res) { if (!force_res) { video_mode.width = GLOBAL_GET("display/window/size/width"); From 99e509a5d227a575e80670bb61cd517386e9d7ae Mon Sep 17 00:00:00 2001 From: Julian Mills Date: Thu, 12 May 2022 01:40:34 +0200 Subject: [PATCH 18/38] Fix blank command prompts spawning prevent certain mono actions from displaying empty command prompts. (cherry picked from commit d606a8ededaa9cf8edfa09b4aeaeb92167a48207) --- modules/mono/editor/GodotTools/GodotTools/Build/BuildSystem.cs | 1 + modules/mono/editor/GodotTools/GodotTools/Utils/OS.cs | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/modules/mono/editor/GodotTools/GodotTools/Build/BuildSystem.cs b/modules/mono/editor/GodotTools/GodotTools/Build/BuildSystem.cs index bac7a2e6db2..02e9d98647d 100644 --- a/modules/mono/editor/GodotTools/GodotTools/Build/BuildSystem.cs +++ b/modules/mono/editor/GodotTools/GodotTools/Build/BuildSystem.cs @@ -63,6 +63,7 @@ namespace GodotTools.Build startInfo.RedirectStandardOutput = true; startInfo.RedirectStandardError = true; startInfo.UseShellExecute = false; + startInfo.CreateNoWindow = true; if (UsingMonoMsBuildOnWindows) { diff --git a/modules/mono/editor/GodotTools/GodotTools/Utils/OS.cs b/modules/mono/editor/GodotTools/GodotTools/Utils/OS.cs index 86342c9bdf7..54f19173465 100644 --- a/modules/mono/editor/GodotTools/GodotTools/Utils/OS.cs +++ b/modules/mono/editor/GodotTools/GodotTools/Utils/OS.cs @@ -174,7 +174,8 @@ namespace GodotTools.Utils { RedirectStandardOutput = true, RedirectStandardError = true, - UseShellExecute = false + UseShellExecute = false, + CreateNoWindow = true }; using (Process process = Process.Start(startInfo)) From c8b85c1b54467aaf0a4fb1a2df6eb916ce1475a6 Mon Sep 17 00:00:00 2001 From: SnailRhymer Date: Wed, 4 May 2022 21:27:09 +0100 Subject: [PATCH 19/38] Indent bullet points in enum descriptions When converting doc xml files to rst, add an indenation level to bullet points in the text description of enum values. Also add check to avoid out of bounds error in rstize_text. (cherry picked from commit 38cf07b768074b9f9fd5e9081cce9af2dc8b089f) --- doc/tools/make_rst.py | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/doc/tools/make_rst.py b/doc/tools/make_rst.py index 34f478797c0..bc772c45a44 100755 --- a/doc/tools/make_rst.py +++ b/doc/tools/make_rst.py @@ -592,7 +592,8 @@ def make_rst_class(class_def, state, dry_run, output_dir): # type: (ClassDef, S for value in e.values.values(): f.write("- **{}** = **{}**".format(value.name, value.value)) if value.text is not None and value.text.strip() != "": - f.write(" --- " + rstize_text(value.text.strip(), state)) + # If value.text contains a bullet point list, each entry needs additional indentation + f.write(" --- " + indent_bullets(rstize_text(value.text.strip(), state))) f.write("\n\n") @@ -738,7 +739,7 @@ def rstize_text(text, state): # type: (str, State) -> str pre_text = text[:pos] indent_level = 0 - while text[pos + 1] == "\t": + while pos + 1 < len(text) and text[pos + 1] == "\t": pos += 1 indent_level += 1 post_text = text[pos + 1 :] @@ -1190,5 +1191,24 @@ def make_link(url, title): # type: (str, str) -> str return "`" + url + " <" + url + ">`__" +def indent_bullets(text): # type: (str) -> str + # Take the text and check each line for a bullet point represented by "-". + # Where found, indent the given line by a further "\t". + # Used to properly indent bullet points contained in the description for enum values. + # Ignore the first line - text will be prepended to it so bullet points wouldn't work anyway. + bullet_points = "-" + + lines = text.splitlines(keepends=True) + for line_index, line in enumerate(lines[1:], start=1): + pos = 0 + while pos < len(line) and line[pos] == "\t": + pos += 1 + + if pos < len(line) and line[pos] in bullet_points: + lines[line_index] = line[:pos] + "\t" + line[pos:] + + return "".join(lines) + + if __name__ == "__main__": main() From 559c20aa2f2fa3f0213c4703f5f1664c2c5b6788 Mon Sep 17 00:00:00 2001 From: Megamega53 <60354907+Megamega53@users.noreply.github.com> Date: Sat, 9 May 2020 16:31:18 -0400 Subject: [PATCH 20/38] Improve AnimatedSprite2D description in the class reference (cherry picked from commit de968baca9064c8e20011758b8c85b2a0acfc6ba) --- doc/classes/AnimatedSprite.xml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/doc/classes/AnimatedSprite.xml b/doc/classes/AnimatedSprite.xml index aa55c9bba64..e2837386df9 100644 --- a/doc/classes/AnimatedSprite.xml +++ b/doc/classes/AnimatedSprite.xml @@ -1,11 +1,11 @@ - Sprite node that can use multiple textures for animation. + Sprite node that contains multiple textures as frames to play for animation. - Animations are created using a [SpriteFrames] resource, which can be configured in the editor via the SpriteFrames panel. - [b]Note:[/b] You can associate a set of normal maps by creating additional [SpriteFrames] resources with a [code]_normal[/code] suffix. For example, having 2 [SpriteFrames] resources [code]run[/code] and [code]run_normal[/code] will make it so the [code]run[/code] animation uses the normal map. + [AnimatedSprite] is similar to the [Sprite] node, except it carries multiple textures as animation frames. Animations are created using a [SpriteFrames] resource, which allows you to import image files (or a folder containing said files) to provide the animation frames for the sprite. The [SpriteFrames] resource can be configured in the editor via the SpriteFrames bottom panel. + [b]Note:[/b] You can associate a set of normal or specular maps by creating additional [SpriteFrames] resources with a [code]_normal[/code] or [code]_specular[/code] suffix. For example, having 3 [SpriteFrames] resources [code]run[/code], [code]run_normal[/code], and [code]run_specular[/code] will make it so the [code]run[/code] animation uses normal and specular maps. $DOCS_URL/tutorials/2d/2d_sprite_animation.html @@ -29,7 +29,7 @@ - The current animation from the [code]frames[/code] resource. If this value changes, the [code]frame[/code] counter is reset. + The current animation from the [member frames] resource. If this value changes, the [code]frame[/code] counter is reset. If [code]true[/code], texture will be centered. @@ -44,7 +44,7 @@ The displayed animation frame's index. - The [SpriteFrames] resource containing the animation(s). + The [SpriteFrames] resource containing the animation(s). Allows you the option to load, edit, clear, make unique and save the states of the [SpriteFrames] resource. The texture's drawing offset. From 0df7aa1e2c7d365bac06bb0d7c116cf211ad91d9 Mon Sep 17 00:00:00 2001 From: Hugo Locurcio Date: Mon, 18 Apr 2022 21:04:24 +0200 Subject: [PATCH 21/38] Increase compiler optimization when using `target=release` on iOS/Android (cherry picked from commit 78b4ec2d4d0d6233ca0f4d8cfeb74640063e970f) --- platform/android/detect.py | 7 +++++-- platform/iphone/detect.py | 7 +++++-- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/platform/android/detect.py b/platform/android/detect.py index 49b66b12420..9b654d64ef7 100644 --- a/platform/android/detect.py +++ b/platform/android/detect.py @@ -193,8 +193,11 @@ def configure(env): if env["target"].startswith("release"): if env["optimize"] == "speed": # optimize for speed (default) - env.Append(LINKFLAGS=["-O2"]) - env.Append(CCFLAGS=["-O2", "-fomit-frame-pointer"]) + # `-O2` is more friendly to debuggers than `-O3`, leading to better crash backtraces + # when using `target=release_debug`. + opt = "-O3" if env["target"] == "release" else "-O2" + env.Append(LINKFLAGS=[opt]) + env.Append(CCFLAGS=[opt, "-fomit-frame-pointer"]) elif env["optimize"] == "size": # optimize for size env.Append(CCFLAGS=["-Os"]) env.Append(LINKFLAGS=["-Os"]) diff --git a/platform/iphone/detect.py b/platform/iphone/detect.py index e292d6a514f..1dd6eab223a 100644 --- a/platform/iphone/detect.py +++ b/platform/iphone/detect.py @@ -51,8 +51,11 @@ def configure(env): if env["target"].startswith("release"): env.Append(CPPDEFINES=["NDEBUG", ("NS_BLOCK_ASSERTIONS", 1)]) if env["optimize"] == "speed": # optimize for speed (default) - env.Append(CCFLAGS=["-O2", "-ftree-vectorize", "-fomit-frame-pointer"]) - env.Append(LINKFLAGS=["-O2"]) + # `-O2` is more friendly to debuggers than `-O3`, leading to better crash backtraces + # when using `target=release_debug`. + opt = "-O3" if env["target"] == "release" else "-O2" + env.Append(CCFLAGS=[opt, "-ftree-vectorize", "-fomit-frame-pointer"]) + env.Append(LINKFLAGS=[opt]) elif env["optimize"] == "size": # optimize for size env.Append(CCFLAGS=["-Os", "-ftree-vectorize"]) env.Append(LINKFLAGS=["-Os"]) From a656243a4e4354593bae7cb554b200af13c6093d Mon Sep 17 00:00:00 2001 From: SnailRhymer Date: Fri, 13 May 2022 15:06:46 +0100 Subject: [PATCH 22/38] Document Shape2D's collide_and_get_contacts() and collide_with_motion_and_get_contacts() Expand on the format of the output array for collide_and_get_contacts and collide_with_motion_and_get_contacts, and describe how the contact point pairs can be used to calculate collision normals and depths. (cherry picked from commit bdf086c781f2f5d1bf5f4f11f0b29a94a629a0ec) --- doc/classes/Shape2D.xml | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/doc/classes/Shape2D.xml b/doc/classes/Shape2D.xml index 8fd3c907a3b..edac424f7c2 100644 --- a/doc/classes/Shape2D.xml +++ b/doc/classes/Shape2D.xml @@ -26,7 +26,9 @@ - Returns a list of the points where this shape touches another. If there are no collisions the list is empty. + Returns a list of contact point pairs where this shape touches another. + If there are no collisions, the returned list is empty. Otherwise, the returned list contains contact points arranged in pairs, with entries alternating between points on the boundary of this shape and points on the boundary of [code]with_shape[/code]. + A collision pair A, B can be used to calculate the collision normal with [code](B - A).normalized()[/code], and the collision depth with [code](B - A).length()[/code]. This information is typically used to separate shapes, particularly in collision solvers. This method needs the transformation matrix for this shape ([code]local_xform[/code]), the shape to check collisions with ([code]with_shape[/code]), and the transformation matrix of that shape ([code]shape_xform[/code]). @@ -50,7 +52,9 @@ - Returns a list of the points where this shape would touch another, if a given movement was applied. If there are no collisions the list is empty. + Returns a list of contact point pairs where this shape would touch another, if a given movement was applied. + If there would be no collisions, the returned list is empty. Otherwise, the returned list contains contact points arranged in pairs, with entries alternating between points on the boundary of this shape and points on the boundary of [code]with_shape[/code]. + A collision pair A, B can be used to calculate the collision normal with [code](B - A).normalized()[/code], and the collision depth with [code](B - A).length()[/code]. This information is typically used to separate shapes, particularly in collision solvers. This method needs the transformation matrix for this shape ([code]local_xform[/code]), the movement to test on this shape ([code]local_motion[/code]), the shape to check collisions with ([code]with_shape[/code]), the transformation matrix of that shape ([code]shape_xform[/code]), and the movement to test onto the other object ([code]shape_motion[/code]). From 847fab627240f2b62c0e7ea29a959811fac2befd Mon Sep 17 00:00:00 2001 From: smix8 <52464204+smix8@users.noreply.github.com> Date: Sun, 15 May 2022 20:29:23 +0200 Subject: [PATCH 23/38] Fix NavigationObstacle2D/3D get_global_transform() error Fixes NavigationObstacle2D/3D reporting a 'get_global_transform: Condition "!is_inside_tree()" error when estimating the agent radius. The collisionshapes that are lower in the SceneTree order than the obstacle node are not loaded in the SceneTree yet so the global_transform function fails. Also adds warning message when this happens. (cherry picked from commit cc707412e909f117ad53ebe53e19bad43acf086a) --- scene/2d/navigation_obstacle_2d.cpp | 9 ++++++--- scene/3d/navigation_obstacle.cpp | 9 ++++++--- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/scene/2d/navigation_obstacle_2d.cpp b/scene/2d/navigation_obstacle_2d.cpp index d829c73b1f8..f89ee8756bc 100644 --- a/scene/2d/navigation_obstacle_2d.cpp +++ b/scene/2d/navigation_obstacle_2d.cpp @@ -92,7 +92,7 @@ void NavigationObstacle2D::_notification(int p_what) { parent_node2d = nullptr; } break; case NOTIFICATION_INTERNAL_PHYSICS_PROCESS: { - if (parent_node2d) { + if (parent_node2d && parent_node2d->is_inside_tree()) { Navigation2DServer::get_singleton()->agent_set_position(agent, parent_node2d->get_global_transform().get_origin()); } @@ -155,13 +155,13 @@ void NavigationObstacle2D::reevaluate_agent_radius() { } real_t NavigationObstacle2D::estimate_agent_radius() const { - if (parent_node2d) { + if (parent_node2d && parent_node2d->is_inside_tree()) { // Estimate the radius of this physics body real_t radius = 0.0; for (int i(0); i < parent_node2d->get_child_count(); i++) { // For each collision shape CollisionShape2D *cs = Object::cast_to(parent_node2d->get_child(i)); - if (cs) { + if (cs && cs->is_inside_tree()) { // Take the distance between the Body center to the shape center real_t r = cs->get_transform().get_origin().length(); if (cs->get_shape().is_valid()) { @@ -172,6 +172,9 @@ real_t NavigationObstacle2D::estimate_agent_radius() const { r *= MAX(s.x, s.y); // Takes the biggest radius radius = MAX(radius, r); + } else if (cs && !cs->is_inside_tree()) { + WARN_PRINT("A CollisionShape2D of the NavigationObstacle2D parent node was not inside the SceneTree when estimating the obstacle radius." + "\nMove the NavigationObstacle2D to a child position below any CollisionShape2D node of the parent node so the CollisionShape2D is already inside the SceneTree."); } } Vector2 s = parent_node2d->get_global_transform().get_scale(); diff --git a/scene/3d/navigation_obstacle.cpp b/scene/3d/navigation_obstacle.cpp index c8160061188..e1cadfb0346 100644 --- a/scene/3d/navigation_obstacle.cpp +++ b/scene/3d/navigation_obstacle.cpp @@ -92,7 +92,7 @@ void NavigationObstacle::_notification(int p_what) { parent_spatial = nullptr; } break; case NOTIFICATION_INTERNAL_PHYSICS_PROCESS: { - if (parent_spatial) { + if (parent_spatial && parent_spatial->is_inside_tree()) { NavigationServer::get_singleton()->agent_set_position(agent, parent_spatial->get_global_transform().origin); } @@ -162,13 +162,13 @@ void NavigationObstacle::reevaluate_agent_radius() { } real_t NavigationObstacle::estimate_agent_radius() const { - if (parent_spatial) { + if (parent_spatial && parent_spatial->is_inside_tree()) { // Estimate the radius of this physics body real_t radius = 0.0; for (int i(0); i < parent_spatial->get_child_count(); i++) { // For each collision shape CollisionShape *cs = Object::cast_to(parent_spatial->get_child(i)); - if (cs) { + if (cs && cs->is_inside_tree()) { // Take the distance between the Body center to the shape center real_t r = cs->get_transform().origin.length(); if (cs->get_shape().is_valid()) { @@ -179,6 +179,9 @@ real_t NavigationObstacle::estimate_agent_radius() const { r *= MAX(s.x, MAX(s.y, s.z)); // Takes the biggest radius radius = MAX(radius, r); + } else if (cs && !cs->is_inside_tree()) { + WARN_PRINT("A CollisionShape of the NavigationObstacle parent node was not inside the SceneTree when estimating the obstacle radius." + "\nMove the NavigationObstacle to a child position below any CollisionShape node of the parent node so the CollisionShape is already inside the SceneTree."); } } Vector3 s = parent_spatial->get_global_transform().basis.get_scale(); From b11708c50df4e465777e64a47b63be16b10fa565 Mon Sep 17 00:00:00 2001 From: smix8 <52464204+smix8@users.noreply.github.com> Date: Sat, 14 May 2022 23:33:09 +0200 Subject: [PATCH 24/38] Expose NavigationObstacle2D/3D get_rid() and add config warning Exposes get_rid() function for scripting. Adds configuration warning when obstacle is used with not intended static body parent. (cherry picked from commit 001d89223f1377717d2b3d5ec453ff8dd3604182) --- doc/classes/NavigationObstacle.xml | 6 ++++++ doc/classes/NavigationObstacle2D.xml | 6 ++++++ scene/2d/navigation_obstacle_2d.cpp | 8 ++++++++ scene/3d/navigation_obstacle.cpp | 9 ++++++++- 4 files changed, 28 insertions(+), 1 deletion(-) diff --git a/doc/classes/NavigationObstacle.xml b/doc/classes/NavigationObstacle.xml index f58e9e6d47f..9480f6f5182 100644 --- a/doc/classes/NavigationObstacle.xml +++ b/doc/classes/NavigationObstacle.xml @@ -15,6 +15,12 @@ Returns the [Navigation] node that the obstacle is using for its navigation system. + + + + Returns the [RID] of this obstacle on the [NavigationServer]. + + diff --git a/doc/classes/NavigationObstacle2D.xml b/doc/classes/NavigationObstacle2D.xml index 0f75132c083..54913d59f4c 100644 --- a/doc/classes/NavigationObstacle2D.xml +++ b/doc/classes/NavigationObstacle2D.xml @@ -15,6 +15,12 @@ Returns the [Navigation2D] node that the obstacle is using for its navigation system. + + + + Returns the [RID] of this obstacle on the [Navigation2DServer]. + + diff --git a/scene/2d/navigation_obstacle_2d.cpp b/scene/2d/navigation_obstacle_2d.cpp index f89ee8756bc..2d7e331227d 100644 --- a/scene/2d/navigation_obstacle_2d.cpp +++ b/scene/2d/navigation_obstacle_2d.cpp @@ -36,8 +36,11 @@ #include "servers/navigation_2d_server.h" void NavigationObstacle2D::_bind_methods() { + ClassDB::bind_method(D_METHOD("get_rid"), &NavigationObstacle2D::get_rid); + ClassDB::bind_method(D_METHOD("set_navigation", "navigation"), &NavigationObstacle2D::set_navigation_node); ClassDB::bind_method(D_METHOD("get_navigation"), &NavigationObstacle2D::get_navigation_node); + ClassDB::bind_method(D_METHOD("set_estimate_radius", "estimate_radius"), &NavigationObstacle2D::set_estimate_radius); ClassDB::bind_method(D_METHOD("is_radius_estimated"), &NavigationObstacle2D::is_radius_estimated); ClassDB::bind_method(D_METHOD("set_radius", "radius"), &NavigationObstacle2D::set_radius); @@ -136,6 +139,11 @@ String NavigationObstacle2D::get_configuration_warning() const { return TTR("The NavigationObstacle2D only serves to provide collision avoidance to a Node2D object."); } + if (Object::cast_to(get_parent())) { + return TTR("The NavigationObstacle2D is intended for constantly moving bodies like KinematicBody2D or RigidBody2D as it creates only an RVO avoidance radius and does not follow scene geometry exactly." + "\nNot constantly moving or complete static objects should be captured with a refreshed NavigationPolygon so agents can not only avoid them but also move along those objects outline at high detail"); + } + return String(); } diff --git a/scene/3d/navigation_obstacle.cpp b/scene/3d/navigation_obstacle.cpp index e1cadfb0346..29cc16f357e 100644 --- a/scene/3d/navigation_obstacle.cpp +++ b/scene/3d/navigation_obstacle.cpp @@ -36,6 +36,8 @@ #include "servers/navigation_server.h" void NavigationObstacle::_bind_methods() { + ClassDB::bind_method(D_METHOD("get_rid"), &NavigationObstacle::get_rid); + ClassDB::bind_method(D_METHOD("set_navigation", "navigation"), &NavigationObstacle::set_navigation_node); ClassDB::bind_method(D_METHOD("get_navigation"), &NavigationObstacle::get_navigation_node); ClassDB::bind_method(D_METHOD("is_radius_estimated"), &NavigationObstacle::is_radius_estimated); @@ -140,7 +142,12 @@ Node *NavigationObstacle::get_navigation_node() const { String NavigationObstacle::get_configuration_warning() const { if (!Object::cast_to(get_parent())) { - return TTR("The NavigationObstacle only serves to provide collision avoidance to a spatial object."); + return TTR("The NavigationObstacle only serves to provide collision avoidance to a Spatial inheriting parent object."); + } + + if (Object::cast_to(get_parent())) { + return TTR("The NavigationObstacle is intended for constantly moving bodies like KinematicBody3D or RigidBody3D as it creates only an RVO avoidance radius and does not follow scene geometry exactly." + "\nNot constantly moving or complete static objects should be (re)baked to a NavigationMesh so agents can not only avoid them but also move along those objects outline at high detail"); } return String(); From c3b39ca1e9836a3accfec674a286c2a2fcfe42ed Mon Sep 17 00:00:00 2001 From: smix8 <52464204+smix8@users.noreply.github.com> Date: Sat, 14 May 2022 18:25:45 +0200 Subject: [PATCH 25/38] Disable threaded NavigationMesh bake on unsupported OS Automatically disables threaded NavigationMesh bake when OS does not support threads. (cherry picked from commit 49c603e1276b84f9b80414946429372f173bcbeb) --- doc/classes/NavigationMeshInstance.xml | 2 +- scene/3d/navigation_mesh_instance.cpp | 8 +++++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/doc/classes/NavigationMeshInstance.xml b/doc/classes/NavigationMeshInstance.xml index e55e3b9d312..b74ea4b4852 100644 --- a/doc/classes/NavigationMeshInstance.xml +++ b/doc/classes/NavigationMeshInstance.xml @@ -13,7 +13,7 @@ - Bakes the [NavigationMesh]. If [code]on_thread[/code] is set to [code]true[/code] (default), the baking is done on a separate thread. Baking on separate thread is useful because navigation baking is not a cheap operation. When it is completed, it automatically sets the new [NavigationMesh]. Please note that baking on separate thread may be very slow if geometry is parsed from meshes as async access to each mesh involves heavy synchronization. + Bakes the [NavigationMesh]. If [code]on_thread[/code] is set to [code]true[/code] (default), the baking is done on a separate thread. Baking on separate thread is useful because navigation baking is not a cheap operation. When it is completed, it automatically sets the new [NavigationMesh]. Please note that baking on separate thread may be very slow if geometry is parsed from meshes as async access to each mesh involves heavy synchronization. Also, please note that baking on a separate thread is automatically disabled on operating systems that cannot use threads (such as HTML5 with threads disabled). diff --git a/scene/3d/navigation_mesh_instance.cpp b/scene/3d/navigation_mesh_instance.cpp index df27c51110e..0092aa4d530 100644 --- a/scene/3d/navigation_mesh_instance.cpp +++ b/scene/3d/navigation_mesh_instance.cpp @@ -30,6 +30,7 @@ #include "navigation_mesh_instance.h" +#include "core/os/os.h" #include "core/os/thread.h" #include "mesh_instance.h" #include "navigation.h" @@ -178,7 +179,12 @@ void NavigationMeshInstance::bake_navigation_mesh(bool p_on_thread) { BakeThreadsArgs *args = memnew(BakeThreadsArgs); args->nav_region = this; - if (p_on_thread) { + if (p_on_thread && !OS::get_singleton()->can_use_threads()) { + WARN_PRINT("NavigationMesh bake 'on_thread' will be disabled as the current OS does not support multiple threads." + "\nAs a fallback the navigation mesh will bake on the main thread which can cause framerate issues."); + } + + if (p_on_thread && OS::get_singleton()->can_use_threads()) { bake_thread.start(_bake_navigation_mesh, args); } else { _bake_navigation_mesh(args); From 3977eb9107e869ab1b38323978d203910d6efb1a Mon Sep 17 00:00:00 2001 From: smix8 <52464204+smix8@users.noreply.github.com> Date: Thu, 12 May 2022 02:52:48 +0200 Subject: [PATCH 26/38] Add NavigationServer2D/3D API functions to find missing RID info Utility functions for NavigationServer2D/3D to find missing RID information when working with Server API directly. e.g. from map to regions and agents, from agent or region to map, from region to map and agents and so on .... Requirement to work with NavigationServer API exklusive without SceneTree nodes and when juggling agents and regions between multiple navigation maps. (cherry picked from commit 371054e3e5a20325200cc7ba7bbbce6b6a4588c3) --- doc/classes/Navigation2DServer.xml | 28 ++++++++++++++++ doc/classes/NavigationServer.xml | 28 ++++++++++++++++ .../navigation/godot_navigation_server.cpp | 32 +++++++++++++++++++ modules/navigation/godot_navigation_server.h | 5 +++ servers/navigation_2d_server.cpp | 13 ++++++++ servers/navigation_2d_server.h | 5 +++ servers/navigation_server.cpp | 5 +++ servers/navigation_server.h | 5 +++ 8 files changed, 121 insertions(+) diff --git a/doc/classes/Navigation2DServer.xml b/doc/classes/Navigation2DServer.xml index 5afaa3e7283..25946c0a3da 100644 --- a/doc/classes/Navigation2DServer.xml +++ b/doc/classes/Navigation2DServer.xml @@ -20,6 +20,13 @@ Creates the agent. + + + + + Returns the navigation map [RID] the requested [code]agent[/code] is currently assigned to. + + @@ -122,6 +129,13 @@ Create a new map. + + + + + Returns all navigation agents [RID]s that are currently assigned to the requested navigation [code]map[/code]. + + @@ -162,6 +176,13 @@ Returns the navigation path to reach the destination from the origin. + + + + + Returns all navigation regions [RID]s that are currently assigned to the requested navigation [code]map[/code]. + + @@ -199,6 +220,13 @@ Creates a new region. + + + + + Returns the navigation map [RID] the requested [code]region[/code] is currently assigned to. + + diff --git a/doc/classes/NavigationServer.xml b/doc/classes/NavigationServer.xml index 465f5cb4f3a..e6bd9a7e780 100644 --- a/doc/classes/NavigationServer.xml +++ b/doc/classes/NavigationServer.xml @@ -20,6 +20,13 @@ Creates the agent. + + + + + Returns the navigation map [RID] the requested [code]agent[/code] is currently assigned to. + + @@ -122,6 +129,13 @@ Create a new map. + + + + + Returns all navigation agents [RID]s that are currently assigned to the requested navigation [code]map[/code]. + + @@ -187,6 +201,13 @@ Returns the navigation path to reach the destination from the origin. + + + + + Returns all navigation regions [RID]s that are currently assigned to the requested navigation [code]map[/code]. + + @@ -264,6 +285,13 @@ Creates a new region. + + + + + Returns the navigation map [RID] the requested [code]region[/code] is currently assigned to. + + diff --git a/modules/navigation/godot_navigation_server.cpp b/modules/navigation/godot_navigation_server.cpp index 38ed94c6029..326df34b13f 100644 --- a/modules/navigation/godot_navigation_server.cpp +++ b/modules/navigation/godot_navigation_server.cpp @@ -250,6 +250,38 @@ RID GodotNavigationServer::map_get_closest_point_owner(RID p_map, const Vector3 return map->get_closest_point_owner(p_point); } +Array GodotNavigationServer::map_get_regions(RID p_map) const { + Array regions_rids; + const NavMap *map = map_owner.getornull(p_map); + ERR_FAIL_COND_V(map == nullptr, regions_rids); + for (NavRegion *region : map->get_regions()) { + regions_rids.push_back(region->get_self()); + } + return regions_rids; +} + +Array GodotNavigationServer::map_get_agents(RID p_map) const { + Array agents_rids; + const NavMap *map = map_owner.getornull(p_map); + ERR_FAIL_COND_V(map == nullptr, agents_rids); + for (RvoAgent *agent : map->get_agents()) { + agents_rids.push_back(agent->get_self()); + } + return agents_rids; +} + +RID GodotNavigationServer::region_get_map(RID p_region) const { + NavRegion *region = region_owner.getornull(p_region); + ERR_FAIL_COND_V(region == nullptr, RID()); + return region->get_map()->get_self(); +} + +RID GodotNavigationServer::agent_get_map(RID p_agent) const { + RvoAgent *agent = agent_owner.getornull(p_agent); + ERR_FAIL_COND_V(agent == nullptr, RID()); + return agent->get_map()->get_self(); +} + RID GodotNavigationServer::region_create() const { auto mut_this = const_cast(this); MutexLock lock(mut_this->operations_mutex); diff --git a/modules/navigation/godot_navigation_server.h b/modules/navigation/godot_navigation_server.h index 115676afdd5..64af7fdb7d4 100644 --- a/modules/navigation/godot_navigation_server.h +++ b/modules/navigation/godot_navigation_server.h @@ -108,14 +108,19 @@ public: virtual Vector3 map_get_closest_point_normal(RID p_map, const Vector3 &p_point) const; virtual RID map_get_closest_point_owner(RID p_map, const Vector3 &p_point) const; + virtual Array map_get_regions(RID p_map) const; + virtual Array map_get_agents(RID p_map) const; + virtual RID region_create() const; COMMAND_2(region_set_map, RID, p_region, RID, p_map); + virtual RID region_get_map(RID p_region) const; COMMAND_2(region_set_transform, RID, p_region, Transform, p_transform); COMMAND_2(region_set_navmesh, RID, p_region, Ref, p_nav_mesh); virtual void region_bake_navmesh(Ref r_mesh, Node *p_node) const; virtual RID agent_create() const; COMMAND_2(agent_set_map, RID, p_agent, RID, p_map); + virtual RID agent_get_map(RID p_agent) const; COMMAND_2(agent_set_neighbor_dist, RID, p_agent, real_t, p_dist); COMMAND_2(agent_set_max_neighbors, RID, p_agent, int, p_count); COMMAND_2(agent_set_time_horizon, RID, p_agent, real_t, p_time); diff --git a/servers/navigation_2d_server.cpp b/servers/navigation_2d_server.cpp index 5b41bd7541c..326738f2a89 100644 --- a/servers/navigation_2d_server.cpp +++ b/servers/navigation_2d_server.cpp @@ -142,13 +142,18 @@ void Navigation2DServer::_bind_methods() { ClassDB::bind_method(D_METHOD("map_get_closest_point", "map", "to_point"), &Navigation2DServer::map_get_closest_point); ClassDB::bind_method(D_METHOD("map_get_closest_point_owner", "map", "to_point"), &Navigation2DServer::map_get_closest_point_owner); + ClassDB::bind_method(D_METHOD("map_get_regions", "map"), &Navigation2DServer::map_get_regions); + ClassDB::bind_method(D_METHOD("map_get_agents", "map"), &Navigation2DServer::map_get_agents); + ClassDB::bind_method(D_METHOD("region_create"), &Navigation2DServer::region_create); ClassDB::bind_method(D_METHOD("region_set_map", "region", "map"), &Navigation2DServer::region_set_map); + ClassDB::bind_method(D_METHOD("region_get_map", "region"), &Navigation2DServer::region_get_map); ClassDB::bind_method(D_METHOD("region_set_transform", "region", "transform"), &Navigation2DServer::region_set_transform); ClassDB::bind_method(D_METHOD("region_set_navpoly", "region", "nav_poly"), &Navigation2DServer::region_set_navpoly); ClassDB::bind_method(D_METHOD("agent_create"), &Navigation2DServer::agent_create); ClassDB::bind_method(D_METHOD("agent_set_map", "agent", "map"), &Navigation2DServer::agent_set_map); + ClassDB::bind_method(D_METHOD("agent_get_map", "agent"), &Navigation2DServer::agent_get_map); ClassDB::bind_method(D_METHOD("agent_set_neighbor_dist", "agent", "dist"), &Navigation2DServer::agent_set_neighbor_dist); ClassDB::bind_method(D_METHOD("agent_set_max_neighbors", "agent", "count"), &Navigation2DServer::agent_set_max_neighbors); ClassDB::bind_method(D_METHOD("agent_set_time_horizon", "agent", "time"), &Navigation2DServer::agent_set_time_horizon); @@ -171,6 +176,14 @@ Navigation2DServer::~Navigation2DServer() { singleton = nullptr; } +Array FORWARD_1_C(map_get_regions, RID, p_map, rid_to_rid); + +Array FORWARD_1_C(map_get_agents, RID, p_map, rid_to_rid); + +RID FORWARD_1_C(region_get_map, RID, p_region, rid_to_rid); + +RID FORWARD_1_C(agent_get_map, RID, p_agent, rid_to_rid); + RID FORWARD_0_C(map_create); void FORWARD_2_C(map_set_active, RID, p_map, bool, p_active, rid_to_rid, bool_to_bool); diff --git a/servers/navigation_2d_server.h b/servers/navigation_2d_server.h index d629496dbfe..ad1015b3c7e 100644 --- a/servers/navigation_2d_server.h +++ b/servers/navigation_2d_server.h @@ -82,11 +82,15 @@ public: virtual Vector2 map_get_closest_point(RID p_map, const Vector2 &p_point) const; virtual RID map_get_closest_point_owner(RID p_map, const Vector2 &p_point) const; + virtual Array map_get_regions(RID p_map) const; + virtual Array map_get_agents(RID p_map) const; + /// Creates a new region. virtual RID region_create() const; /// Set the map of this region. virtual void region_set_map(RID p_region, RID p_map) const; + virtual RID region_get_map(RID p_region) const; /// Set the global transformation of this region. virtual void region_set_transform(RID p_region, Transform2D p_transform) const; @@ -99,6 +103,7 @@ public: /// Put the agent in the map. virtual void agent_set_map(RID p_agent, RID p_map) const; + virtual RID agent_get_map(RID p_agent) const; /// The maximum distance (center point to /// center point) to other agents this agent diff --git a/servers/navigation_server.cpp b/servers/navigation_server.cpp index 5cc55ccda50..3adda285c58 100644 --- a/servers/navigation_server.cpp +++ b/servers/navigation_server.cpp @@ -54,14 +54,19 @@ void NavigationServer::_bind_methods() { ClassDB::bind_method(D_METHOD("map_get_closest_point_normal", "map", "to_point"), &NavigationServer::map_get_closest_point_normal); ClassDB::bind_method(D_METHOD("map_get_closest_point_owner", "map", "to_point"), &NavigationServer::map_get_closest_point_owner); + ClassDB::bind_method(D_METHOD("map_get_regions", "map"), &NavigationServer::map_get_regions); + ClassDB::bind_method(D_METHOD("map_get_agents", "map"), &NavigationServer::map_get_agents); + ClassDB::bind_method(D_METHOD("region_create"), &NavigationServer::region_create); ClassDB::bind_method(D_METHOD("region_set_map", "region", "map"), &NavigationServer::region_set_map); + ClassDB::bind_method(D_METHOD("region_get_map", "region"), &NavigationServer::region_get_map); ClassDB::bind_method(D_METHOD("region_set_transform", "region", "transform"), &NavigationServer::region_set_transform); ClassDB::bind_method(D_METHOD("region_set_navmesh", "region", "nav_mesh"), &NavigationServer::region_set_navmesh); ClassDB::bind_method(D_METHOD("region_bake_navmesh", "mesh", "node"), &NavigationServer::region_bake_navmesh); ClassDB::bind_method(D_METHOD("agent_create"), &NavigationServer::agent_create); ClassDB::bind_method(D_METHOD("agent_set_map", "agent", "map"), &NavigationServer::agent_set_map); + ClassDB::bind_method(D_METHOD("agent_get_map", "agent"), &NavigationServer::agent_get_map); ClassDB::bind_method(D_METHOD("agent_set_neighbor_dist", "agent", "dist"), &NavigationServer::agent_set_neighbor_dist); ClassDB::bind_method(D_METHOD("agent_set_max_neighbors", "agent", "count"), &NavigationServer::agent_set_max_neighbors); ClassDB::bind_method(D_METHOD("agent_set_time_horizon", "agent", "time"), &NavigationServer::agent_set_time_horizon); diff --git a/servers/navigation_server.h b/servers/navigation_server.h index 78de6c4a8da..d99bba7a88d 100644 --- a/servers/navigation_server.h +++ b/servers/navigation_server.h @@ -101,11 +101,15 @@ public: virtual Vector3 map_get_closest_point_normal(RID p_map, const Vector3 &p_point) const = 0; virtual RID map_get_closest_point_owner(RID p_map, const Vector3 &p_point) const = 0; + virtual Array map_get_regions(RID p_map) const = 0; + virtual Array map_get_agents(RID p_map) const = 0; + /// Creates a new region. virtual RID region_create() const = 0; /// Set the map of this region. virtual void region_set_map(RID p_region, RID p_map) const = 0; + virtual RID region_get_map(RID p_region) const = 0; /// Set the global transformation of this region. virtual void region_set_transform(RID p_region, Transform p_transform) const = 0; @@ -121,6 +125,7 @@ public: /// Put the agent in the map. virtual void agent_set_map(RID p_agent, RID p_map) const = 0; + virtual RID agent_get_map(RID p_agent) const = 0; /// The maximum distance (center point to /// center point) to other agents this agent From 3e01d32b4cdd49cf99ba3fbc94190df40b911e80 Mon Sep 17 00:00:00 2001 From: smix8 <52464204+smix8@users.noreply.github.com> Date: Sun, 15 May 2022 21:52:02 +0200 Subject: [PATCH 27/38] Clamp NavigationMesh sample_distance above zero While default ReCast library has support for 0.0 'sample_distance' the Godot implementation does not an crashes. Previously Godot would set all sample_distance values below 0.9 to 0 which causes the crashes. This limits the sample_distance range selection to 0.1 - 16.0 and also clamps sample_distance that are below 0.1 before ReCast receives them. (cherry picked from commit e33fa9d8331f38c8c404b9d6ea286eacb503d3bb) --- modules/navigation/navigation_mesh_generator.cpp | 2 +- scene/resources/navigation_mesh.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/navigation/navigation_mesh_generator.cpp b/modules/navigation/navigation_mesh_generator.cpp index 911c23ed657..275cf6da95b 100644 --- a/modules/navigation/navigation_mesh_generator.cpp +++ b/modules/navigation/navigation_mesh_generator.cpp @@ -447,7 +447,7 @@ void NavigationMeshGenerator::_build_recast_navigation_mesh( cfg.minRegionArea = (int)(p_nav_mesh->get_region_min_size() * p_nav_mesh->get_region_min_size()); cfg.mergeRegionArea = (int)(p_nav_mesh->get_region_merge_size() * p_nav_mesh->get_region_merge_size()); cfg.maxVertsPerPoly = (int)p_nav_mesh->get_verts_per_poly(); - cfg.detailSampleDist = p_nav_mesh->get_detail_sample_distance() < 0.9f ? 0 : p_nav_mesh->get_cell_size() * p_nav_mesh->get_detail_sample_distance(); + cfg.detailSampleDist = MAX(p_nav_mesh->get_cell_size() * p_nav_mesh->get_detail_sample_distance(), 0.1f); cfg.detailSampleMaxError = p_nav_mesh->get_cell_height() * p_nav_mesh->get_detail_sample_max_error(); cfg.bmin[0] = bmin[0]; diff --git a/scene/resources/navigation_mesh.cpp b/scene/resources/navigation_mesh.cpp index f304c11ebb8..e4ee26ee8c9 100644 --- a/scene/resources/navigation_mesh.cpp +++ b/scene/resources/navigation_mesh.cpp @@ -223,7 +223,7 @@ float NavigationMesh::get_verts_per_poly() const { } void NavigationMesh::set_detail_sample_distance(float p_value) { - ERR_FAIL_COND(p_value < 0); + ERR_FAIL_COND(p_value < 0.1); detail_sample_distance = p_value; } @@ -494,7 +494,7 @@ void NavigationMesh::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::REAL, "edge/max_length", PROPERTY_HINT_RANGE, "0.0,50.0,0.01,or_greater"), "set_edge_max_length", "get_edge_max_length"); ADD_PROPERTY(PropertyInfo(Variant::REAL, "edge/max_error", PROPERTY_HINT_RANGE, "0.1,3.0,0.01,or_greater"), "set_edge_max_error", "get_edge_max_error"); ADD_PROPERTY(PropertyInfo(Variant::REAL, "polygon/verts_per_poly", PROPERTY_HINT_RANGE, "3.0,12.0,1.0,or_greater"), "set_verts_per_poly", "get_verts_per_poly"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "detail/sample_distance", PROPERTY_HINT_RANGE, "0.0,16.0,0.01,or_greater"), "set_detail_sample_distance", "get_detail_sample_distance"); + ADD_PROPERTY(PropertyInfo(Variant::REAL, "detail/sample_distance", PROPERTY_HINT_RANGE, "0.1,16.0,0.01,or_greater"), "set_detail_sample_distance", "get_detail_sample_distance"); ADD_PROPERTY(PropertyInfo(Variant::REAL, "detail/sample_max_error", PROPERTY_HINT_RANGE, "0.0,16.0,0.01,or_greater"), "set_detail_sample_max_error", "get_detail_sample_max_error"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "filter/low_hanging_obstacles"), "set_filter_low_hanging_obstacles", "get_filter_low_hanging_obstacles"); From 214a00ca2e86d8c459a399dd471deae0b47cb928 Mon Sep 17 00:00:00 2001 From: smix8 <52464204+smix8@users.noreply.github.com> Date: Sat, 14 May 2022 19:11:08 +0200 Subject: [PATCH 28/38] Add missing class doc to NavigationMeshGenerator Adds missing class documentation for NavigationMeshGenerator bake() and clear() functions. (cherry picked from commit 375c4ef3120f63f5cf5b78bc3f412412f46c6c9a) --- doc/classes/NavigationMeshGenerator.xml | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/doc/classes/NavigationMeshGenerator.xml b/doc/classes/NavigationMeshGenerator.xml index 79aa1b36da8..d57b44791ef 100644 --- a/doc/classes/NavigationMeshGenerator.xml +++ b/doc/classes/NavigationMeshGenerator.xml @@ -1,10 +1,13 @@ - This class is responsible for creating and clearing navigation meshes. + Helper class for creating and clearing navigation meshes. - This class is responsible for creating and clearing navigation meshes. + This class is responsible for creating and clearing 3D navigation meshes used as [NavigationMesh] resources inside [NavigationMeshInstance]. The [NavigationMeshGenerator] has very limited to no use for 2D as the navigation mesh baking process expects 3D node types and 3D source geometry to parse. + The entire navigation mesh baking is best done in a separate thread as the voxelization, collision tests and mesh optimization steps involved are very performance and time hungry operations. + Navigation mesh baking happens in multiple steps and the result depends on 3D source geometry and properties of the [NavigationMesh] resource. In the first step, starting from a root node and depending on [NavigationMesh] properties all valid 3D source geometry nodes are collected from the [SceneTree]. Second, all collected nodes are parsed for their relevant 3D geometry data and a combined 3D mesh is build. Due to the many different types of parsable objects, from normal [MeshInstance]s to [CSGShape]s or various [CollisionObject]s, some operations to collect geometry data can trigger [VisualServer] and [PhysicsServer] synchronizations. Server synchronization can have a negative effect on baking time or framerate as it often involves [Mutex] locking for thread security. Many parsable objects and the continuous synchronization with other threaded Servers can increase the baking time significantly. On the other hand only a few but very large and complex objects will take some time to prepare for the Servers which can noticeably stall the next frame render. As a general rule the total amount of parsable objects and their individual size and complexity should be balanced to avoid framerate issues or very long baking times. The combined mesh is then passed to the Recast Navigation Object to test the source geometry for walkable terrain suitable to [NavigationMesh] agent properties by creating a voxel world around the meshes bounding area. + The finalized navigation mesh is then returned and stored inside the [NavigationMesh] for use as a resource inside [NavigationMeshInstance] nodes. @@ -14,14 +17,14 @@ - Bakes the navigation mesh. This will allow you to use pathfinding with the navigation system. + Bakes navigation data to the provided [code]nav_mesh[/code] by parsing child nodes under the provided [code]root_node[/code] or a specific group of nodes for potential source geometry. The parse behavior can be controlled with the [member NavigationMesh.geometry/parsed_geometry_type] and [member NavigationMesh.geometry/source_geometry_mode] properties on the [NavigationMesh] resource. - Clears the navigation mesh. + Removes all polygons and vertices from the provided [code]nav_mesh[/code] resource. From 59151db99e36352bbfe6706e21e6e86f255d3422 Mon Sep 17 00:00:00 2001 From: Haoyu Qiu Date: Mon, 16 May 2022 09:38:48 +0800 Subject: [PATCH 29/38] Fix crash when editing pinned StyleBox (cherry picked from commit 4b013a9c967ecc063801b3d4a0e833dcbc865f83) --- editor/plugins/theme_editor_plugin.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/editor/plugins/theme_editor_plugin.cpp b/editor/plugins/theme_editor_plugin.cpp index 26054a8dfe2..c336afb5f18 100644 --- a/editor/plugins/theme_editor_plugin.cpp +++ b/editor/plugins/theme_editor_plugin.cpp @@ -2852,11 +2852,13 @@ void ThemeTypeEditor::_update_stylebox_from_leading() { edited_theme->get_stylebox_list(edited_type, &names); List> styleboxes; for (List::Element *E = names.front(); E; E = E->next()) { - if (E->get() == leading_stylebox.item_name) { + Ref sb = edited_theme->get_stylebox(E->get(), edited_type); + + // Avoid itself, stylebox can be shared between items. + if (sb == leading_stylebox.stylebox) { continue; } - Ref sb = edited_theme->get_stylebox(E->get(), edited_type); if (sb->get_class() == leading_stylebox.stylebox->get_class()) { styleboxes.push_back(sb); } From 67e6fc8e43e033a0a06d64d466c74ca3cd84fb59 Mon Sep 17 00:00:00 2001 From: FireForge <67974470+fire-forge@users.noreply.github.com> Date: Sun, 10 Apr 2022 22:18:21 -0500 Subject: [PATCH 30/38] Fix Theme type group naming in the inspector (cherry picked from commit 197be78bc558aa90413bd0420c24736a989e5f0e) --- scene/resources/theme.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/scene/resources/theme.cpp b/scene/resources/theme.cpp index 9c47543c180..e4f2b8c637c 100644 --- a/scene/resources/theme.cpp +++ b/scene/resources/theme.cpp @@ -179,7 +179,15 @@ void Theme::_get_property_list(List *p_list) const { } list.sort(); + String prev_type; for (List::Element *E = list.front(); E; E = E->next()) { + // Add groups for types so that their names are left unchanged in the inspector. + String current_type = E->get().name.get_slice("/", 0); + if (prev_type != current_type) { + p_list->push_back(PropertyInfo(Variant::NIL, current_type, PROPERTY_HINT_NONE, current_type + "/", PROPERTY_USAGE_GROUP)); + prev_type = current_type; + } + p_list->push_back(E->get()); } } From e19f8fcbdca488a54f166342076744eeb74369d0 Mon Sep 17 00:00:00 2001 From: Hugo Locurcio Date: Mon, 11 Apr 2022 01:11:00 +0200 Subject: [PATCH 31/38] Improve error messages when creating Images from code The rationale behind the expected number of bytes is now displayed in clear (width, height, format, number of mipmaps expected if any). (cherry picked from commit 18e9e6a81a0aef27bbb78d3e52d52a4b009457bf) --- core/image.cpp | 40 +++++++++++++++++++++++++++++----------- 1 file changed, 29 insertions(+), 11 deletions(-) diff --git a/core/image.cpp b/core/image.cpp index 00e6db691c8..a1e7485e18a 100644 --- a/core/image.cpp +++ b/core/image.cpp @@ -1733,12 +1733,14 @@ PoolVector Image::get_data() const { } void Image::create(int p_width, int p_height, bool p_use_mipmaps, Format p_format) { - ERR_FAIL_COND_MSG(p_width <= 0, "Image width must be greater than 0."); - ERR_FAIL_COND_MSG(p_height <= 0, "Image height must be greater than 0."); - ERR_FAIL_COND_MSG(p_width > MAX_WIDTH, "Image width cannot be greater than " + itos(MAX_WIDTH) + "."); - ERR_FAIL_COND_MSG(p_height > MAX_HEIGHT, "Image height cannot be greater than " + itos(MAX_HEIGHT) + "."); + ERR_FAIL_COND_MSG(p_width <= 0, "The Image width specified (" + itos(p_width) + " pixels) must be greater than 0 pixels."); + ERR_FAIL_COND_MSG(p_height <= 0, "The Image height specified (" + itos(p_height) + " pixels) must be greater than 0 pixels."); + ERR_FAIL_COND_MSG(p_width > MAX_WIDTH, + "The Image width specified (" + itos(p_width) + " pixels) cannot be greater than " + itos(MAX_WIDTH) + "pixels."); + ERR_FAIL_COND_MSG(p_height > MAX_HEIGHT, + "The Image height specified (" + itos(p_height) + " pixels) cannot be greater than " + itos(MAX_HEIGHT) + "pixels."); ERR_FAIL_COND_MSG(write_lock.ptr(), "Cannot create image when it is locked."); - ERR_FAIL_INDEX_MSG(p_format, FORMAT_MAX, "Image format out of range, please see Image's Format enum."); + ERR_FAIL_INDEX_MSG(p_format, FORMAT_MAX, "The Image format specified (" + itos(p_format) + ") is out of range. See Image's Format enum."); int mm = 0; int size = _get_dst_image_size(p_width, p_height, p_format, mm, p_use_mipmaps ? -1 : 0); @@ -1755,16 +1757,32 @@ void Image::create(int p_width, int p_height, bool p_use_mipmaps, Format p_forma } void Image::create(int p_width, int p_height, bool p_use_mipmaps, Format p_format, const PoolVector &p_data) { - ERR_FAIL_COND_MSG(p_width <= 0, "Image width must be greater than 0."); - ERR_FAIL_COND_MSG(p_height <= 0, "Image height must be greater than 0."); - ERR_FAIL_COND_MSG(p_width > MAX_WIDTH, "Image width cannot be greater than " + itos(MAX_WIDTH) + "."); - ERR_FAIL_COND_MSG(p_height > MAX_HEIGHT, "Image height cannot be greater than " + itos(MAX_HEIGHT) + "."); - ERR_FAIL_INDEX_MSG(p_format, FORMAT_MAX, "Image format out of range, please see Image's Format enum."); + ERR_FAIL_COND_MSG(p_width <= 0, "The Image width specified (" + itos(p_width) + " pixels) must be greater than 0 pixels."); + ERR_FAIL_COND_MSG(p_height <= 0, "The Image height specified (" + itos(p_height) + " pixels) must be greater than 0 pixels."); + ERR_FAIL_COND_MSG(p_width > MAX_WIDTH, + "The Image width specified (" + itos(p_width) + " pixels) cannot be greater than " + itos(MAX_WIDTH) + " pixels."); + ERR_FAIL_COND_MSG(p_height > MAX_HEIGHT, + "The Image height specified (" + itos(p_height) + " pixels) cannot be greater than " + itos(MAX_HEIGHT) + " pixels."); + ERR_FAIL_INDEX_MSG(p_format, FORMAT_MAX, "The Image format specified (" + itos(p_format) + ") is out of range. See Image's Format enum."); int mm; int size = _get_dst_image_size(p_width, p_height, p_format, mm, p_use_mipmaps ? -1 : 0); - ERR_FAIL_COND_MSG(p_data.size() != size, "Expected data size of " + itos(size) + " bytes in Image::create(), got instead " + itos(p_data.size()) + " bytes."); + if (unlikely(p_data.size() != size)) { + String description_mipmaps; + if (p_use_mipmaps) { + const int num_mipmaps = get_image_required_mipmaps(p_width, p_height, p_format); + if (num_mipmaps != 1) { + description_mipmaps = vformat("with %d mipmaps", num_mipmaps); + } else { + description_mipmaps = "with 1 mipmap"; + } + } else { + description_mipmaps = "without mipmaps"; + } + const String description = vformat("%dx%dx%d (%s)", p_width, p_height, get_format_pixel_size(p_format), description_mipmaps); + ERR_FAIL_MSG(vformat("Expected Image data size of %s = %d bytes, got %d bytes instead.", description, size, p_data.size())); + } height = p_height; width = p_width; From 5968dbd7471a41f40859311d6def7d6a1c16baf6 Mon Sep 17 00:00:00 2001 From: FireForge <67974470+fire-forge@users.noreply.github.com> Date: Sat, 9 Apr 2022 16:31:22 -0500 Subject: [PATCH 32/38] Expose EditorSpinSlider.hide_slider (cherry picked from commit 8e752b06e8a0f116991a0e618cc47e4fe2f3d270) --- doc/classes/EditorSpinSlider.xml | 3 +++ editor/editor_spin_slider.cpp | 4 ++++ 2 files changed, 7 insertions(+) diff --git a/doc/classes/EditorSpinSlider.xml b/doc/classes/EditorSpinSlider.xml index 93794e9f4b0..668adc6f389 100644 --- a/doc/classes/EditorSpinSlider.xml +++ b/doc/classes/EditorSpinSlider.xml @@ -14,6 +14,9 @@ + + If [code]true[/code], the slider is hidden. + diff --git a/editor/editor_spin_slider.cpp b/editor/editor_spin_slider.cpp index ff8efc245c5..5193c9604d7 100644 --- a/editor/editor_spin_slider.cpp +++ b/editor/editor_spin_slider.cpp @@ -562,6 +562,9 @@ void EditorSpinSlider::_bind_methods() { ClassDB::bind_method(D_METHOD("set_flat", "flat"), &EditorSpinSlider::set_flat); ClassDB::bind_method(D_METHOD("is_flat"), &EditorSpinSlider::is_flat); + ClassDB::bind_method(D_METHOD("set_hide_slider", "hide_slider"), &EditorSpinSlider::set_hide_slider); + ClassDB::bind_method(D_METHOD("is_hiding_slider"), &EditorSpinSlider::is_hiding_slider); + ClassDB::bind_method(D_METHOD("_gui_input"), &EditorSpinSlider::_gui_input); ClassDB::bind_method(D_METHOD("_value_input_gui_input", "event"), &EditorSpinSlider::_value_input_gui_input); ClassDB::bind_method(D_METHOD("_grabber_mouse_entered"), &EditorSpinSlider::_grabber_mouse_entered); @@ -574,6 +577,7 @@ void EditorSpinSlider::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::STRING, "label"), "set_label", "get_label"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "read_only"), "set_read_only", "is_read_only"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "flat"), "set_flat", "is_flat"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "hide_slider"), "set_hide_slider", "is_hiding_slider"); } EditorSpinSlider::EditorSpinSlider() { From 5b19a5d4a8b76f667c92b79b68b735442a69478b Mon Sep 17 00:00:00 2001 From: Hugo Locurcio Date: Sun, 27 Mar 2022 20:31:18 +0200 Subject: [PATCH 33/38] Improve documentation for `Camera3D.project_ray_{normal,origin}` This mentions that internally, the inverse camera projection is used to perform projections. (cherry picked from commit fbec10179ad2a058a5f6d2689dba9db813bdc83f) --- doc/classes/Camera.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/classes/Camera.xml b/doc/classes/Camera.xml index eb0c4527576..cc2d7233603 100644 --- a/doc/classes/Camera.xml +++ b/doc/classes/Camera.xml @@ -75,14 +75,14 @@ - Returns a normal vector in world space, that is the result of projecting a point on the [Viewport] rectangle by the camera projection. This is useful for casting rays in the form of (origin, normal) for object intersection or picking. + Returns a normal vector in world space, that is the result of projecting a point on the [Viewport] rectangle by the inverse camera projection. This is useful for casting rays in the form of (origin, normal) for object intersection or picking. - Returns a 3D position in world space, that is the result of projecting a point on the [Viewport] rectangle by the camera projection. This is useful for casting rays in the form of (origin, normal) for object intersection or picking. + Returns a 3D position in world space, that is the result of projecting a point on the [Viewport] rectangle by the inverse camera projection. This is useful for casting rays in the form of (origin, normal) for object intersection or picking. From ff52becb474aa74dec2826b7c0356f0427cf6393 Mon Sep 17 00:00:00 2001 From: Markus Sauermann <6299227+Sauermann@users.noreply.github.com> Date: Fri, 1 Apr 2022 18:46:52 +0200 Subject: [PATCH 34/38] Distribute remaining pixel to expanding childs of GridContainer (cherry picked from commit 6b3207644b8d2338a9a55f8cfeb0ec65f1cea207) --- scene/gui/grid_container.cpp | 53 +++++++++++++++++++++++++++++++++--- 1 file changed, 49 insertions(+), 4 deletions(-) diff --git a/scene/gui/grid_container.cpp b/scene/gui/grid_container.cpp index e1ed8d6d942..ab00055bd08 100644 --- a/scene/gui/grid_container.cpp +++ b/scene/gui/grid_container.cpp @@ -142,12 +142,45 @@ void GridContainer::_notification(int p_what) { } // Finally, fit the nodes. - int col_expand = col_expanded.size() > 0 ? remaining_space.width / col_expanded.size() : 0; - int row_expand = row_expanded.size() > 0 ? remaining_space.height / row_expanded.size() : 0; + int col_remaining_pixel = 0; + int col_expand = 0; + if (col_expanded.size() > 0) { + col_expand = remaining_space.width / col_expanded.size(); + col_remaining_pixel = remaining_space.width - col_expanded.size() * col_expand; + } + + int row_remaining_pixel = 0; + int row_expand = 0; + if (row_expanded.size() > 0) { + row_expand = remaining_space.height / row_expanded.size(); + row_remaining_pixel = remaining_space.height - row_expanded.size() * row_expand; + } int col_ofs = 0; int row_ofs = 0; + // Calculate the index of rows and columns that receive the remaining pixel. + int col_remaining_pixel_index = 0; + for (int i = 0; i < max_col; i++) { + if (col_remaining_pixel == 0) { + break; + } + if (col_expanded.has(i)) { + col_remaining_pixel_index = i + 1; + col_remaining_pixel--; + } + } + int row_remaining_pixel_index = 0; + for (int i = 0; i < max_row; i++) { + if (row_remaining_pixel == 0) { + break; + } + if (row_expanded.has(i)) { + row_remaining_pixel_index = i + 1; + row_remaining_pixel--; + } + } + valid_controls_index = 0; for (int i = 0; i < get_child_count(); i++) { Control *c = Object::cast_to(get_child(i)); @@ -162,14 +195,26 @@ void GridContainer::_notification(int p_what) { col_ofs = 0; if (row > 0) { row_ofs += (row_expanded.has(row - 1) ? row_expand : row_minh[row - 1]) + vsep; + + if (row_expanded.has(row - 1) && row - 1 < row_remaining_pixel_index) { + // Apply the remaining pixel of the previous row. + row_ofs++; + } } } - Point2 p(col_ofs, row_ofs); Size2 s(col_expanded.has(col) ? col_expand : col_minw[col], row_expanded.has(row) ? row_expand : row_minh[row]); - fit_child_in_rect(c, Rect2(p, s)); + // Add the remaining pixel to the expanding columns and rows, starting from left and top. + if (col_expanded.has(col) && col < col_remaining_pixel_index) { + s.x++; + } + if (row_expanded.has(row) && row < row_remaining_pixel_index) { + s.y++; + } + Point2 p(col_ofs, row_ofs); + fit_child_in_rect(c, Rect2(p, s)); col_ofs += s.width + hsep; } From ddd392a93ff626f416e289906ceabcea9388873a Mon Sep 17 00:00:00 2001 From: dzil123 <5725958+dzil123@users.noreply.github.com> Date: Sat, 2 Apr 2022 01:53:36 -0700 Subject: [PATCH 35/38] fix gridmap cursor showing the wrong mesh (cherry picked from commit 726614ff4b0018379ed8fe1ea0461ba9403b671b) --- modules/gridmap/grid_map_editor_plugin.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/gridmap/grid_map_editor_plugin.cpp b/modules/gridmap/grid_map_editor_plugin.cpp index c92d731e264..77818d737d4 100644 --- a/modules/gridmap/grid_map_editor_plugin.cpp +++ b/modules/gridmap/grid_map_editor_plugin.cpp @@ -938,6 +938,7 @@ void GridMapEditor::edit(GridMap *p_gridmap) { } update_palette(); + _update_cursor_instance(); set_process(true); From d9acd21b46352a0c6fe09b42d03bbdb6a749687d Mon Sep 17 00:00:00 2001 From: Hugo Locurcio Date: Thu, 20 Jan 2022 17:56:51 +0100 Subject: [PATCH 36/38] Display a modal dialog if threads are unavailable in the web editor Threads are required for the web editor to function. If the web server is not correctly configured, threads won't be available. This makes troubleshooting easier for people looking to self-host the web editor. (cherry picked from commit 304a2865020c842a1affad86ecf4986af13c79fa) --- misc/dist/html/editor.html | 53 ++++++++++++++++++++++++++++++++++---- 1 file changed, 48 insertions(+), 5 deletions(-) diff --git a/misc/dist/html/editor.html b/misc/dist/html/editor.html index bba8763efd3..f8b6fb065dd 100644 --- a/misc/dist/html/editor.html +++ b/misc/dist/html/editor.html @@ -68,6 +68,11 @@ height: 100%; overflow: auto; background-color: hsla(0, 0%, 0%, 0.5); + text-align: left; + } + + .welcome-modal-title { + text-align: center; } .welcome-modal-content { @@ -238,7 +243,7 @@ onclick="if (event.target === this) closeWelcomeModal(false)" >
-

Important - Please read before continuing

+

Important - Please read before continuing

The Godot Web Editor has some limitations compared to the native version. @@ -254,9 +259,38 @@ >Web editor documentation for usage instructions and limitations.

- + +
+ +
@@ -361,7 +395,16 @@ }); } - if (localStorage.getItem("welcomeModalDismissed") !== 'true') { + if (!crossOriginIsolated) { + // Display error dialog as threading support is required for the editor. + setButtonEnabled('startButton', false); + document.getElementById("welcome-modal-description").style.display = "none"; + document.getElementById("welcome-modal-description-no-cross-origin-isolation").style.display = "block"; + document.getElementById("welcome-modal-dismiss").style.display = "none"; + document.getElementById("welcome-modal-reason-not-secure").style.display = window.isSecureContext ? "none" : "list-item"; + } + + if (!crossOriginIsolated || localStorage.getItem("welcomeModalDismissed") !== 'true') { document.getElementById("welcome-modal").style.display = "block"; document.getElementById("welcome-modal-dismiss").focus(); } From 96b1b1991ba91ed8d47cc8c71452256e06cf1301 Mon Sep 17 00:00:00 2001 From: Haoyu Qiu Date: Mon, 16 May 2022 21:03:22 +0800 Subject: [PATCH 37/38] Fix AnimatedSprite doesn't emit animation_finished when changing playback direction (cherry picked from commit d5f5e96e118d6904aaa071fcb8e8f08fa2d4eae5) --- scene/2d/animated_sprite.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/scene/2d/animated_sprite.cpp b/scene/2d/animated_sprite.cpp index 4891823e318..5a618f8760e 100644 --- a/scene/2d/animated_sprite.cpp +++ b/scene/2d/animated_sprite.cpp @@ -599,6 +599,7 @@ void AnimatedSprite::play(const StringName &p_animation, const bool p_backwards) } } + is_over = false; set_playing(true); } From 16fb7888530b3750c746b756a02cbd549324eef0 Mon Sep 17 00:00:00 2001 From: kobewi Date: Mon, 16 May 2022 20:04:38 +0200 Subject: [PATCH 38/38] Clarify seek() in relation to animation_finished (cherry picked from commit 74e135c90bad1dcaacc3b718deb8ec39318760ee) --- doc/classes/AnimationPlayer.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/classes/AnimationPlayer.xml b/doc/classes/AnimationPlayer.xml index 8e7070e78de..ea404209012 100644 --- a/doc/classes/AnimationPlayer.xml +++ b/doc/classes/AnimationPlayer.xml @@ -159,6 +159,7 @@ Seeks the animation to the [code]seconds[/code] point in time (in seconds). If [code]update[/code] is [code]true[/code], the animation updates too, otherwise it updates at process time. Events between the current frame and [code]seconds[/code] are skipped. + [b]Note:[/b] Seeking to the end of the animation doesn't emit [signal animation_finished]. If you want to skip animation and emit the signal, use [method advance].