Pārlūkot izejas kodu

Merge pull request #45892 from akien-mga/3.2-cherrypicks

Cherry-picks for the 3.2 branch (future 3.2.4) - 22nd batch
Rémi Verschelde 4 gadi atpakaļ
vecāks
revīzija
9a89782996

+ 5 - 1
.mailmap

@@ -6,6 +6,7 @@ Anish Bhobe <[email protected]>
 Anutrix <[email protected]>
 Aren Villanueva <[email protected]> <[email protected]>
 Ariel Manzur <[email protected]>
+Ariel Manzur <[email protected]> <[email protected]>
 Ariel Manzur <[email protected]> <[email protected]>
 Ariel Manzur <[email protected]> <[email protected]>
 Ariel Manzur <[email protected]> <[email protected]>
@@ -25,6 +26,7 @@ Daniel J. Ramirez <[email protected]>
 Dominik 'dreamsComeTrue' Jasiński <[email protected]>
 Emmanuel Barroga <[email protected]>
 Eric M <[email protected]>
+Eric Rybicki <[email protected]> <[email protected]>
 Erik Selecký <[email protected]>
 Erik Selecký <[email protected]> <[email protected]>
 Fabian <[email protected]>
@@ -84,6 +86,7 @@ Mateo Kuruk Miccino <[email protected]>
 Max Hilbrunner <[email protected]>
 Max Hilbrunner <[email protected]> <[email protected]>
 Michael Alexsander <[email protected]>
+Nathan Franke <[email protected]> <[email protected]>
 Nathan Lovato <[email protected]>
 Nathan Warden <[email protected]> <[email protected]>
 Nils ANDRÉ-CHANG <[email protected]>
@@ -97,7 +100,7 @@ Pieter-Jan Briers <[email protected]>
 Pieter-Jan Briers <[email protected]> <[email protected]>
 Poommetee Ketson <[email protected]>
 Przemysław Gołąb (n-pigeon) <[email protected]>
-Rafał Mikrut <[email protected]>
+Rafał Mikrut <mikrutrafal@protonmail.com> <mikrutrafal[email protected]>
 Ralf Hölzemer <[email protected]> <[email protected]>
 Ralf Hölzemer <[email protected]> <[email protected]>
 Ramesh Ravone <[email protected]>
@@ -123,5 +126,6 @@ Wilhem Barbier <[email protected]> <[email protected]>
 Wilhem Barbier <[email protected]> <[email protected]>
 Will Nations <[email protected]>
 yg2f <[email protected]>
+Yuri Sizov <[email protected]> <[email protected]>
 Zak Stam <[email protected]>
 Zher Huei Lee <[email protected]>

+ 3 - 0
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

+ 12 - 8
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; }

+ 26 - 17
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())
+	int l = p_string.length();
+	if (l > length()) {
 		return false;
+	}
 
-	int l = p_string.length();
-	if (l == 0)
+	if (l == 0) {
 		return true;
+	}
 
-	const CharType *src = &p_string[0];
-	const CharType *str = &operator[](0);
-
-	int i = 0;
-	for (; i < l; i++) {
+	const CharType *p = &p_string[0];
+	const CharType *s = &operator[](0);
 
-		if (src[i] != str[i])
+	for (int i = 0; i < l; i++) {
+		if (p[i] != s[i]) {
 			return false;
+		}
 	}
 
-	// only if i == l the p_string matches the beginning
-	return i == l;
+	return true;
 }
+
 bool String::begins_with(const char *p_string) const {
 
 	int l = length();

+ 3 - 4
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]
 	</description>
 	<tutorials>
@@ -143,7 +142,7 @@
 			<return type="String">
 			</return>
 			<description>
-				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".
 			</description>
 		</method>
 		<method name="import" qualifiers="virtual">

+ 7 - 0
doc/classes/GraphNode.xml

@@ -226,6 +226,13 @@
 				Emitted when the GraphNode is moved.
 			</description>
 		</signal>
+		<signal name="slot_updated">
+			<argument index="0" name="idx" type="int">
+			</argument>
+			<description>
+				Emitted when any GraphNode's slot is updated.
+			</description>
+		</signal>
 		<signal name="raise_request">
 			<description>
 				Emitted when the GraphNode is requested to be displayed over other ones. Happens on focusing (clicking into) the GraphNode.

+ 15 - 3
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);
 	}
 }

+ 6 - 4
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');

+ 20 - 8
modules/gdscript/doc_classes/@GDScript.xml

@@ -320,7 +320,7 @@
 			</argument>
 			<description>
 				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 @@
 			</argument>
 			<description>
 				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.
 			</description>
 		</method>
 		<method name="is_inf">
@@ -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].
 			</description>
 		</method>
 		<method name="max">
@@ -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]
 			</description>
 		</method>
@@ -693,12 +698,17 @@
 			<argument index="0" name="value" type="int">
 			</argument>
 			<description>
-				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 &lt;= 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).
 			</description>
 		</method>
 		<method name="ord">
@@ -1078,15 +1088,17 @@
 			</argument>
 			<argument index="1" name="to" type="float">
 			</argument>
-			<argument index="2" name="weight" type="float">
+			<argument index="2" name="s" type="float">
 			</argument>
 			<description>
-				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 &lt;= from[/code], and [code]1[/code] if [code]s &gt;= 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]
 			</description>
 		</method>
@@ -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#.
 			</description>
 		</method>
 		<method name="step_decimals">

+ 1 - 1
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;

+ 12 - 0
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<GraphNode>(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<GraphNode>(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);

+ 1 - 0
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);

+ 3 - 0
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"));

+ 6 - 0
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")) {