Browse Source

Fixed SoftBody3D handles not being clickable in 3D Editor Viewport

Fix erratic behaviour when modifying pinned_points via inspector
Joel Fortier 1 year ago
parent
commit
a58ae8e1c6

+ 1 - 0
doc/classes/SoftBody3D.xml

@@ -87,6 +87,7 @@
 			<param index="0" name="point_index" type="int" />
 			<param index="1" name="pinned" type="bool" />
 			<param index="2" name="attachment_path" type="NodePath" default="NodePath(&quot;&quot;)" />
+			<param index="3" name="insert_at" type="int" default="-1" />
 			<description>
 				Sets the pinned state of a surface vertex. When set to [code]true[/code], the optional [param attachment_path] can define a [Node3D] the pinned vertex will be attached to.
 			</description>

+ 2 - 3
editor/plugins/node_3d_editor_plugin.cpp

@@ -1951,9 +1951,8 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
 					surface->queue_redraw();
 				} else {
 					if (_edit.gizmo.is_valid()) {
-						if (_edit.original_mouse_pos != _edit.mouse_pos) {
-							_edit.gizmo->commit_handle(_edit.gizmo_handle, _edit.gizmo_handle_secondary, _edit.gizmo_initial_value, false);
-						}
+						_edit.gizmo->commit_handle(_edit.gizmo_handle, _edit.gizmo_handle_secondary, _edit.gizmo_initial_value, false);
+						spatial_editor->get_single_selected_node()->update_gizmos();
 						_edit.gizmo = Ref<EditorNode3DGizmo>();
 						break;
 					}

+ 7 - 0
misc/extension_api_validation/4.3-stable.expected

@@ -80,3 +80,10 @@ GH-94434
 Validate extension JSON: Error: Field 'classes/OS/methods/execute_with_pipe/arguments': size changed value in new API, from 2 to 3.
 
 Optional argument added. Compatibility method registered.
+
+
+GH-94684
+--------
+Validate extension JSON: Error: Field 'classes/SoftBody3D/methods/set_point_pinned/arguments': size changed value in new API, from 3 to 4.
+
+Optional argument added to allow for adding pin point at specific index. Compatibility method registered.

+ 41 - 0
scene/3d/soft_body_3d.compat.inc

@@ -0,0 +1,41 @@
+/**************************************************************************/
+/*  soft_body_3d.compat.inc                                               */
+/**************************************************************************/
+/*                         This file is part of:                          */
+/*                             GODOT ENGINE                               */
+/*                        https://godotengine.org                         */
+/**************************************************************************/
+/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
+/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur.                  */
+/*                                                                        */
+/* Permission is hereby granted, free of charge, to any person obtaining  */
+/* a copy of this software and associated documentation files (the        */
+/* "Software"), to deal in the Software without restriction, including    */
+/* without limitation the rights to use, copy, modify, merge, publish,    */
+/* distribute, sublicense, and/or sell copies of the Software, and to     */
+/* permit persons to whom the Software is furnished to do so, subject to  */
+/* the following conditions:                                              */
+/*                                                                        */
+/* The above copyright notice and this permission notice shall be         */
+/* included in all copies or substantial portions of the Software.        */
+/*                                                                        */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,        */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF     */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY   */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,   */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE      */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                 */
+/**************************************************************************/
+
+#ifndef DISABLE_DEPRECATED
+
+void SoftBody3D::_pin_point_bind_compat_94684(int p_point_index, bool pin, const NodePath &p_spatial_attachment_path) {
+	pin_point(p_point_index, pin, p_spatial_attachment_path, -1);
+}
+
+void SoftBody3D::_bind_compatibility_methods() {
+	ClassDB::bind_compatibility_method(D_METHOD("set_point_pinned", "point_index", "pinned", "attachment_path"), &SoftBody3D::_pin_point_bind_compat_94684, DEFVAL(NodePath()));
+}
+
+#endif // DISABLE_DEPRECATED

+ 20 - 8
scene/3d/soft_body_3d.cpp

@@ -29,6 +29,7 @@
 /**************************************************************************/
 
 #include "soft_body_3d.h"
+#include "soft_body_3d.compat.inc"
 
 #include "scene/3d/physics/physics_body_3d.h"
 
@@ -200,12 +201,18 @@ bool SoftBody3D::_set_property_pinned_points_indices(const Array &p_indices) {
 	int point_index;
 	for (int i = 0; i < p_indices_size; ++i) {
 		point_index = p_indices.get(i);
-		if (w[i].point_index != point_index) {
-			if (-1 != w[i].point_index) {
+		if (w[i].point_index != point_index || pinned_points.size() < p_indices_size) {
+			bool insert = false;
+			if (w[i].point_index != -1 && p_indices.find(w[i].point_index) == -1) {
 				pin_point(w[i].point_index, false);
+				insert = true;
 			}
 			w[i].point_index = point_index;
-			pin_point(w[i].point_index, true);
+			if (insert) {
+				pin_point(w[i].point_index, true, NodePath(), i);
+			} else {
+				pin_point(w[i].point_index, true);
+			}
 		}
 	}
 	return true;
@@ -356,7 +363,7 @@ void SoftBody3D::_bind_methods() {
 
 	ClassDB::bind_method(D_METHOD("get_point_transform", "point_index"), &SoftBody3D::get_point_transform);
 
-	ClassDB::bind_method(D_METHOD("set_point_pinned", "point_index", "pinned", "attachment_path"), &SoftBody3D::pin_point, DEFVAL(NodePath()));
+	ClassDB::bind_method(D_METHOD("set_point_pinned", "point_index", "pinned", "attachment_path", "insert_at"), &SoftBody3D::pin_point, DEFVAL(NodePath()), DEFVAL(-1));
 	ClassDB::bind_method(D_METHOD("is_point_pinned", "point_index"), &SoftBody3D::is_point_pinned);
 
 	ClassDB::bind_method(D_METHOD("set_ray_pickable", "ray_pickable"), &SoftBody3D::set_ray_pickable);
@@ -668,10 +675,11 @@ void SoftBody3D::pin_point_toggle(int p_point_index) {
 	pin_point(p_point_index, !(-1 != _has_pinned_point(p_point_index)));
 }
 
-void SoftBody3D::pin_point(int p_point_index, bool pin, const NodePath &p_spatial_attachment_path) {
+void SoftBody3D::pin_point(int p_point_index, bool pin, const NodePath &p_spatial_attachment_path, int p_insert_at) {
+	ERR_FAIL_COND_MSG(p_insert_at < -1 || p_insert_at >= pinned_points.size(), "Invalid index for pin point insertion position.");
 	_pin_point_on_physics_server(p_point_index, pin);
 	if (pin) {
-		_add_pinned_point(p_point_index, p_spatial_attachment_path);
+		_add_pinned_point(p_point_index, p_spatial_attachment_path, p_insert_at);
 	} else {
 		_remove_pinned_point(p_point_index);
 	}
@@ -730,7 +738,7 @@ void SoftBody3D::_pin_point_on_physics_server(int p_point_index, bool pin) {
 	PhysicsServer3D::get_singleton()->soft_body_pin_point(physics_rid, p_point_index, pin);
 }
 
-void SoftBody3D::_add_pinned_point(int p_point_index, const NodePath &p_spatial_attachment_path) {
+void SoftBody3D::_add_pinned_point(int p_point_index, const NodePath &p_spatial_attachment_path, int p_insert_at) {
 	SoftBody3D::PinnedPoint *pinned_point;
 	if (-1 == _get_pinned_point(p_point_index, pinned_point)) {
 		// Create new
@@ -743,7 +751,11 @@ void SoftBody3D::_add_pinned_point(int p_point_index, const NodePath &p_spatial_
 			pp.offset = (pp.spatial_attachment->get_global_transform().affine_inverse() * get_global_transform()).xform(PhysicsServer3D::get_singleton()->soft_body_get_point_global_position(physics_rid, pp.point_index));
 		}
 
-		pinned_points.push_back(pp);
+		if (p_insert_at != -1) {
+			pinned_points.insert(p_insert_at, pp);
+		} else {
+			pinned_points.push_back(pp);
+		}
 
 	} else {
 		pinned_point->point_index = p_point_index;

+ 7 - 2
scene/3d/soft_body_3d.h

@@ -126,6 +126,11 @@ protected:
 	void _notification(int p_what);
 	static void _bind_methods();
 
+#ifndef DISABLE_DEPRECATED
+	void _pin_point_bind_compat_94684(int p_point_index, bool pin, const NodePath &p_spatial_attachment_path = NodePath());
+	static void _bind_compatibility_methods();
+#endif
+
 	PackedStringArray get_configuration_warnings() const override;
 
 public:
@@ -177,7 +182,7 @@ public:
 	Vector3 get_point_transform(int p_point_index);
 
 	void pin_point_toggle(int p_point_index);
-	void pin_point(int p_point_index, bool pin, const NodePath &p_spatial_attachment_path = NodePath());
+	void pin_point(int p_point_index, bool pin, const NodePath &p_spatial_attachment_path = NodePath(), int p_insert_at = -1);
 	bool is_point_pinned(int p_point_index) const;
 
 	void _pin_point_deferred(int p_point_index, bool pin, const NodePath p_spatial_attachment_path);
@@ -193,7 +198,7 @@ private:
 	void _update_cache_pin_points_datas();
 
 	void _pin_point_on_physics_server(int p_point_index, bool pin);
-	void _add_pinned_point(int p_point_index, const NodePath &p_spatial_attachment_path);
+	void _add_pinned_point(int p_point_index, const NodePath &p_spatial_attachment_path, int p_insert_at = -1);
 	void _reset_points_offsets();
 
 	void _remove_pinned_point(int p_point_index);