diff --git a/.mailmap b/.mailmap index 73128d27dbb..72670d011f3 100644 --- a/.mailmap +++ b/.mailmap @@ -6,6 +6,7 @@ Anish Bhobe Anutrix Aren Villanueva Ariel Manzur +Ariel Manzur Ariel Manzur Ariel Manzur Ariel Manzur @@ -25,6 +26,7 @@ Daniel J. Ramirez Dominik 'dreamsComeTrue' Jasiński Emmanuel Barroga Eric M +Eric Rybicki Erik Selecký <35656626+rxlecky@users.noreply.github.com> Erik Selecký <35656626+rxlecky@users.noreply.github.com> <35656626+SeleckyErik@users.noreply.github.com> Fabian @@ -84,6 +86,7 @@ Mateo Kuruk Miccino Max Hilbrunner Max Hilbrunner Michael Alexsander +Nathan Franke Nathan Lovato Nathan Warden Nils ANDRÉ-CHANG @@ -97,7 +100,7 @@ Pieter-Jan Briers Pieter-Jan Briers Poommetee Ketson Przemysław Gołąb (n-pigeon) -Rafał Mikrut +Rafał Mikrut Ralf Hölzemer Ralf Hölzemer Ramesh Ravone @@ -123,5 +126,6 @@ Wilhem Barbier Wilhem Barbier Will Nations yg2f +Yuri Sizov Zak Stam Zher Huei Lee diff --git a/AUTHORS.md b/AUTHORS.md index 1ebef775096..2faaf2d2c0a 100644 --- a/AUTHORS.md +++ b/AUTHORS.md @@ -114,6 +114,7 @@ name is available. Leon Krause (leonkrause) Liz Haas (27thLiz) Lucien Menassol (Kanabenki) + Lyuma m4nu3lf Maganty Rushyendra (mrushyendra) Marcel Admiraal (madmiraal) @@ -138,6 +139,7 @@ name is available. MichiRecRoom (LikeLakers2) mrezai muiroc + Nathan Franke (nathanfranke) Nathan Lovato (NathanLovato) Nathan Warden (NathanWarden) Nils André-Chang (NilsIrl) @@ -191,6 +193,7 @@ name is available. Xavier Cho (mysticfall) yg2f (SuperUserNameMan) Yuri Roubinsky (Chaosus) + Yuri Sizov (pycbouh) Zak Stam (zaksnet) Zher Huei Lee (leezh) ZuBsPaCe diff --git a/core/math/math_funcs.h b/core/math/math_funcs.h index 6cd6c39b0e9..f4259e80908 100644 --- a/core/math/math_funcs.h +++ b/core/math/math_funcs.h @@ -233,15 +233,19 @@ public: static _ALWAYS_INLINE_ double range_lerp(double p_value, double p_istart, double p_istop, double p_ostart, double p_ostop) { return Math::lerp(p_ostart, p_ostop, Math::inverse_lerp(p_istart, p_istop, p_value)); } static _ALWAYS_INLINE_ float range_lerp(float p_value, float p_istart, float p_istop, float p_ostart, float p_ostop) { return Math::lerp(p_ostart, p_ostop, Math::inverse_lerp(p_istart, p_istop, p_value)); } - static _ALWAYS_INLINE_ double smoothstep(double p_from, double p_to, double p_weight) { - if (is_equal_approx(p_from, p_to)) return p_from; - double x = CLAMP((p_weight - p_from) / (p_to - p_from), 0.0, 1.0); - return x * x * (3.0 - 2.0 * x); + static _ALWAYS_INLINE_ double smoothstep(double p_from, double p_to, double p_s) { + if (is_equal_approx(p_from, p_to)) { + return p_from; + } + double s = CLAMP((p_s - p_from) / (p_to - p_from), 0.0, 1.0); + return s * s * (3.0 - 2.0 * s); } - static _ALWAYS_INLINE_ float smoothstep(float p_from, float p_to, float p_weight) { - if (is_equal_approx(p_from, p_to)) return p_from; - float x = CLAMP((p_weight - p_from) / (p_to - p_from), 0.0f, 1.0f); - return x * x * (3.0f - 2.0f * x); + static _ALWAYS_INLINE_ float smoothstep(float p_from, float p_to, float p_s) { + if (is_equal_approx(p_from, p_to)) { + return p_from; + } + float s = CLAMP((p_s - p_from) / (p_to - p_from), 0.0f, 1.0f); + return s * s * (3.0f - 2.0f * s); } static _ALWAYS_INLINE_ double move_toward(double p_from, double p_to, double p_delta) { return abs(p_to - p_from) <= p_delta ? p_to : p_from + SGN(p_to - p_from) * p_delta; } static _ALWAYS_INLINE_ float move_toward(float p_from, float p_to, float p_delta) { return abs(p_to - p_from) <= p_delta ? p_to : p_from + SGN(p_to - p_from) * p_delta; } diff --git a/core/ustring.cpp b/core/ustring.cpp index 5dc72219764..c3676e9c68c 100644 --- a/core/ustring.cpp +++ b/core/ustring.cpp @@ -2710,40 +2710,49 @@ int String::rfindn(const String &p_str, int p_from) const { } bool String::ends_with(const String &p_string) const { - int l = p_string.length(); + if (l > length()) { + return false; + } + if (l == 0) { return true; } - int pos = find_last(p_string); - if (pos == -1) - return false; - return pos + l == length(); + const CharType *p = &p_string[0]; + const CharType *s = &operator[](length() - l); + + for (int i = 0; i < l; i++) { + if (p[i] != s[i]) { + return false; + } + } + + return true; } bool String::begins_with(const String &p_string) const { - - if (p_string.length() > length()) - return false; - int l = p_string.length(); - if (l == 0) - return true; - - const CharType *src = &p_string[0]; - const CharType *str = &operator[](0); - - int i = 0; - for (; i < l; i++) { - - if (src[i] != str[i]) - return false; + if (l > length()) { + return false; } - // only if i == l the p_string matches the beginning - return i == l; + if (l == 0) { + return true; + } + + const CharType *p = &p_string[0]; + const CharType *s = &operator[](0); + + for (int i = 0; i < l; i++) { + if (p[i] != s[i]) { + return false; + } + } + + return true; } + bool String::begins_with(const char *p_string) const { int l = length(); diff --git a/doc/classes/EditorImportPlugin.xml b/doc/classes/EditorImportPlugin.xml index 471652df370..d3418cc6455 100644 --- a/doc/classes/EditorImportPlugin.xml +++ b/doc/classes/EditorImportPlugin.xml @@ -15,7 +15,7 @@ return "my.special.plugin" func get_visible_name(): - return "Special Mesh Importer" + return "Special Mesh" func get_recognized_extensions(): return ["special", "spec"] @@ -44,8 +44,7 @@ # Fill the Mesh with data read in "file", left as an exercise to the reader var filename = save_path + "." + get_save_extension() - ResourceSaver.save(filename, mesh) - return OK + return ResourceSaver.save(filename, mesh) [/codeblock] @@ -143,7 +142,7 @@ - Gets the name to display in the import window. + Gets the name to display in the import window. You should choose this name as a continuation to "Import as", e.g. "Import as Special Mesh". diff --git a/doc/classes/GraphNode.xml b/doc/classes/GraphNode.xml index f4ffe3872d9..878b903af03 100644 --- a/doc/classes/GraphNode.xml +++ b/doc/classes/GraphNode.xml @@ -226,6 +226,13 @@ Emitted when the GraphNode is moved. + + + + + Emitted when any GraphNode's slot is updated. + + Emitted when the GraphNode is requested to be displayed over other ones. Happens on focusing (clicking into) the GraphNode. diff --git a/editor/filesystem_dock.cpp b/editor/filesystem_dock.cpp index cff659e56bd..5566f152d1c 100644 --- a/editor/filesystem_dock.cpp +++ b/editor/filesystem_dock.cpp @@ -1294,14 +1294,26 @@ void FileSystemDock::_make_scene_confirm() { void FileSystemDock::_file_removed(String p_file) { emit_signal("file_removed", p_file); - path = "res://"; + // Find the closest parent directory available, in case multiple items were deleted along the same path. + path = p_file.get_base_dir(); + DirAccessRef da = DirAccess::create(DirAccess::ACCESS_RESOURCES); + while (!da->dir_exists(path)) { + path = path.get_base_dir(); + } + current_path->set_text(path); } void FileSystemDock::_folder_removed(String p_folder) { emit_signal("folder_removed", p_folder); - path = "res://"; + // Find the closest parent directory available, in case multiple items were deleted along the same path. + path = p_folder.get_base_dir(); + DirAccessRef da = DirAccess::create(DirAccess::ACCESS_RESOURCES); + while (!da->dir_exists(path)) { + path = path.get_base_dir(); + } + current_path->set_text(path); } @@ -1469,7 +1481,7 @@ void FileSystemDock::_move_operation_confirm(const String &p_to_path, bool overw print_verbose("FileSystem: saving moved scenes."); _save_scenes_after_move(file_renames); - path = "res://"; + path = p_to_path; current_path->set_text(path); } } diff --git a/misc/dist/html/editor.html b/misc/dist/html/editor.html index f51aba2cad3..881f7cd6e64 100644 --- a/misc/dist/html/editor.html +++ b/misc/dist/html/editor.html @@ -262,9 +262,7 @@ return; } Promise.all([ - deleteDB("/home/web_user/projects"), - deleteDB("/home/web_user/.config"), - deleteDB("/home/web_user/.cache"), + deleteDB("/home/web_user"), ]).then(function(results) { alert("Done."); }).catch(function (err) { @@ -286,6 +284,10 @@ tabs.forEach(function (elem) { if (elem.id == 'tab-' + name) { elem.style.display = 'block'; + if (name == 'editor' || name == 'game') { + const canvas = document.getElementById(name + '-canvas'); + canvas.focus(); + } } else { elem.style.display = 'none'; } @@ -327,7 +329,7 @@ function startEditor(zip) { const INDETERMINATE_STATUS_STEP_MS = 100; - const persistentPaths = ['/home/web_user/']; + const persistentPaths = ['/home/web_user']; var editorCanvas = document.getElementById('editor-canvas'); var gameCanvas = document.getElementById('game-canvas'); diff --git a/modules/gdscript/doc_classes/@GDScript.xml b/modules/gdscript/doc_classes/@GDScript.xml index 3b3ab3b8418..c2c13cdd48c 100644 --- a/modules/gdscript/doc_classes/@GDScript.xml +++ b/modules/gdscript/doc_classes/@GDScript.xml @@ -320,7 +320,7 @@ The natural exponential function. It raises the mathematical constant [b]e[/b] to the power of [code]s[/code] and returns it. - [b]e[/b] has an approximate value of 2.71828. + [b]e[/b] has an approximate value of 2.71828, and can be obtained with [code]exp(1)[/code]. For exponents to other bases use the method [method pow]. [codeblock] a = exp(2) # Approximately 7.39 @@ -501,6 +501,8 @@ Returns [code]true[/code] if [code]a[/code] and [code]b[/code] are approximately equal to each other. + Here, approximately equal means that [code]a[/code] and [code]b[/code] are within a small internal epsilon of each other, which scales with the magnitude of the numbers. + Infinity values of the same sign are considered equal. @@ -638,6 +640,7 @@ [codeblock] log(10) # Returns 2.302585 [/codeblock] + [b]Note:[/b] The logarithm of [code]0[/code] returns [code]-inf[/code], while negative values return [code]-nan[/code]. @@ -683,7 +686,9 @@ Moves [code]from[/code] toward [code]to[/code] by the [code]delta[/code] value. Use a negative [code]delta[/code] value to move away. [codeblock] + move_toward(5, 10, 4) # Returns 9 move_toward(10, 5, 4) # Returns 6 + move_toward(10, 5, -1.5) # Returns 11.5 [/codeblock] @@ -693,12 +698,17 @@ - Returns the nearest larger power of 2 for integer [code]value[/code]. + Returns the nearest equal or larger power of 2 for integer [code]value[/code]. + In other words, returns the smallest value [code]a[/code] where [code]a = pow(2, n)[/code] such that [code]value <= a[/code] for some non-negative integer [code]n[/code]. [codeblock] nearest_po2(3) # Returns 4 nearest_po2(4) # Returns 4 nearest_po2(5) # Returns 8 + + nearest_po2(0) # Returns 0 (this may not be what you expect) + nearest_po2(-1) # Returns 0 (this may not be what you expect) [/codeblock] + [b]WARNING:[/b] Due to the way it is implemented, this function returns [code]0[/code] rather than [code]1[/code] for non-positive values of [code]value[/code] (in reality, 1 is the smallest integer power of 2). @@ -1078,15 +1088,17 @@ - + - Returns a number smoothly interpolated between the [code]from[/code] and [code]to[/code], based on the [code]weight[/code]. Similar to [method lerp], but interpolates faster at the beginning and slower at the end. + Returns the result of smoothly interpolating the value of [code]s[/code] between [code]0[/code] and [code]1[/code], based on the where [code]s[/code] lies with respect to the edges [code]from[/code] and [code]to[/code]. + The return value is [code]0[/code] if [code]s <= from[/code], and [code]1[/code] if [code]s >= to[/code]. If [code]s[/code] lies between [code]from[/code] and [code]to[/code], the returned value follows an S-shaped curve that maps [code]s[/code] between [code]0[/code] and [code]1[/code]. + This S-shaped curve is the cubic Hermite interpolator, given by [code]f(s) = 3*s^2 - 2*s^3[/code]. [codeblock] smoothstep(0, 2, -5.0) # Returns 0.0 - smoothstep(0, 2, 0.5) # Returns 0.15625 - smoothstep(0, 2, 1.0) # Returns 0.5 - smoothstep(0, 2, 2.0) # Returns 1.0 + smoothstep(0, 2, 0.5) # Returns 0.15625 + smoothstep(0, 2, 1.0) # Returns 0.5 + smoothstep(0, 2, 2.0) # Returns 1.0 [/codeblock] @@ -1100,7 +1112,7 @@ [codeblock] sqrt(9) # Returns 3 [/codeblock] - If you need negative inputs, use [code]System.Numerics.Complex[/code] in C#. + [b]Note:[/b]Negative values of [code]s[/code] return NaN. If you need negative inputs, use [code]System.Numerics.Complex[/code] in C#. diff --git a/modules/gdscript/gdscript_functions.cpp b/modules/gdscript/gdscript_functions.cpp index 057eb2814d9..50a4ecea1bd 100644 --- a/modules/gdscript/gdscript_functions.cpp +++ b/modules/gdscript/gdscript_functions.cpp @@ -1715,7 +1715,7 @@ MethodInfo GDScriptFunctions::get_info(Function p_func) { return mi; } break; case MATH_SMOOTHSTEP: { - MethodInfo mi("smoothstep", PropertyInfo(Variant::REAL, "from"), PropertyInfo(Variant::REAL, "to"), PropertyInfo(Variant::REAL, "weight")); + MethodInfo mi("smoothstep", PropertyInfo(Variant::REAL, "from"), PropertyInfo(Variant::REAL, "to"), PropertyInfo(Variant::REAL, "s")); mi.return_val.type = Variant::REAL; return mi; } break; diff --git a/scene/gui/graph_edit.cpp b/scene/gui/graph_edit.cpp index 4ea0c22ddb9..96b93337ded 100644 --- a/scene/gui/graph_edit.cpp +++ b/scene/gui/graph_edit.cpp @@ -396,6 +396,15 @@ void GraphEdit::_graph_node_moved(Node *p_gn) { connections_layer->update(); } +void GraphEdit::_graph_node_slot_updated(int p_index, Node *p_gn) { + GraphNode *gn = Object::cast_to(p_gn); + ERR_FAIL_COND(!gn); + top_layer->update(); + minimap->update(); + update(); + connections_layer->update(); +} + void GraphEdit::add_child_notify(Node *p_child) { Control::add_child_notify(p_child); @@ -406,6 +415,7 @@ void GraphEdit::add_child_notify(Node *p_child) { if (gn) { gn->set_scale(Vector2(zoom, zoom)); gn->connect("offset_changed", this, "_graph_node_moved", varray(gn)); + gn->connect("slot_updated", this, "_graph_node_slot_updated", varray(gn)); gn->connect("raise_request", this, "_graph_node_raised", varray(gn)); gn->connect("item_rect_changed", connections_layer, "update"); gn->connect("item_rect_changed", minimap, "update"); @@ -432,6 +442,7 @@ void GraphEdit::remove_child_notify(Node *p_child) { GraphNode *gn = Object::cast_to(p_child); if (gn) { gn->disconnect("offset_changed", this, "_graph_node_moved"); + gn->disconnect("slot_updated", this, "_graph_node_slot_updated"); gn->disconnect("raise_request", this, "_graph_node_raised"); // In case of the whole GraphEdit being destroyed these references can already be freed. @@ -1659,6 +1670,7 @@ void GraphEdit::_bind_methods() { ClassDB::bind_method(D_METHOD("_graph_node_moved"), &GraphEdit::_graph_node_moved); ClassDB::bind_method(D_METHOD("_graph_node_raised"), &GraphEdit::_graph_node_raised); + ClassDB::bind_method(D_METHOD("_graph_node_slot_updated"), &GraphEdit::_graph_node_slot_updated); ClassDB::bind_method(D_METHOD("_top_layer_input"), &GraphEdit::_top_layer_input); ClassDB::bind_method(D_METHOD("_top_layer_draw"), &GraphEdit::_top_layer_draw); diff --git a/scene/gui/graph_edit.h b/scene/gui/graph_edit.h index a16c4232a72..155e390fb37 100644 --- a/scene/gui/graph_edit.h +++ b/scene/gui/graph_edit.h @@ -164,6 +164,7 @@ private: void _graph_node_raised(Node *p_gn); void _graph_node_moved(Node *p_gn); + void _graph_node_slot_updated(int p_index, Node *p_gn); void _update_scroll(); void _scroll_moved(double); diff --git a/scene/gui/graph_node.cpp b/scene/gui/graph_node.cpp index e97ef1c8bb4..274568141b6 100644 --- a/scene/gui/graph_node.cpp +++ b/scene/gui/graph_node.cpp @@ -312,6 +312,8 @@ void GraphNode::set_slot(int p_idx, bool p_enable_left, int p_type_left, const C slot_info[p_idx] = s; update(); connpos_dirty = true; + + emit_signal("slot_updated", p_idx); } void GraphNode::clear_slot(int p_idx) { @@ -720,6 +722,7 @@ void GraphNode::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::INT, "overlay", PROPERTY_HINT_ENUM, "Disabled,Breakpoint,Position"), "set_overlay", "get_overlay"); ADD_SIGNAL(MethodInfo("offset_changed")); + ADD_SIGNAL(MethodInfo("slot_updated", PropertyInfo(Variant::INT, "idx"))); ADD_SIGNAL(MethodInfo("dragged", PropertyInfo(Variant::VECTOR2, "from"), PropertyInfo(Variant::VECTOR2, "to"))); ADD_SIGNAL(MethodInfo("raise_request")); ADD_SIGNAL(MethodInfo("close_request")); diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp index 07efa4973d6..84e7e0a3579 100644 --- a/scene/main/viewport.cpp +++ b/scene/main/viewport.cpp @@ -416,6 +416,12 @@ void Viewport::_notification(int p_what) { int point_count = PhysicsServer::get_singleton()->space_get_contact_count(find_world()->get_space()); VS::get_singleton()->multimesh_set_visible_instances(contact_3d_debug_multimesh, point_count); + + for (int i = 0; i < point_count; i++) { + Transform point_transform; + point_transform.origin = points[i]; + VS::get_singleton()->multimesh_instance_set_transform(contact_3d_debug_multimesh, i, point_transform); + } } if (!GLOBAL_GET("physics/common/enable_pause_aware_picking")) {