From a58ae8e1c61f590e28a9ff9e8e9a66a80f242fa8 Mon Sep 17 00:00:00 2001 From: Joel Fortier Date: Fri, 19 Jul 2024 14:20:31 +0930 Subject: [PATCH] Fixed SoftBody3D handles not being clickable in 3D Editor Viewport Fix erratic behaviour when modifying pinned_points via inspector --- doc/classes/SoftBody3D.xml | 1 + editor/plugins/node_3d_editor_plugin.cpp | 5 +-- .../4.3-stable.expected | 7 ++++ scene/3d/soft_body_3d.compat.inc | 41 +++++++++++++++++++ scene/3d/soft_body_3d.cpp | 28 +++++++++---- scene/3d/soft_body_3d.h | 9 +++- 6 files changed, 78 insertions(+), 13 deletions(-) create mode 100644 scene/3d/soft_body_3d.compat.inc diff --git a/doc/classes/SoftBody3D.xml b/doc/classes/SoftBody3D.xml index 195196b78ca1..4d8791d8c1f7 100644 --- a/doc/classes/SoftBody3D.xml +++ b/doc/classes/SoftBody3D.xml @@ -87,6 +87,7 @@ + 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. diff --git a/editor/plugins/node_3d_editor_plugin.cpp b/editor/plugins/node_3d_editor_plugin.cpp index d0d4f6098c88..55649a31dc83 100644 --- a/editor/plugins/node_3d_editor_plugin.cpp +++ b/editor/plugins/node_3d_editor_plugin.cpp @@ -1951,9 +1951,8 @@ void Node3DEditorViewport::_sinput(const Ref &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(); break; } diff --git a/misc/extension_api_validation/4.3-stable.expected b/misc/extension_api_validation/4.3-stable.expected index ad77e30e11cc..06933b584126 100644 --- a/misc/extension_api_validation/4.3-stable.expected +++ b/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. diff --git a/scene/3d/soft_body_3d.compat.inc b/scene/3d/soft_body_3d.compat.inc new file mode 100644 index 000000000000..0b01bfeb1f3c --- /dev/null +++ b/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 diff --git a/scene/3d/soft_body_3d.cpp b/scene/3d/soft_body_3d.cpp index 7f67bde0cf8b..b0fc94d75f8a 100644 --- a/scene/3d/soft_body_3d.cpp +++ b/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; diff --git a/scene/3d/soft_body_3d.h b/scene/3d/soft_body_3d.h index ab30f7e654ff..b01d462d9f1c 100644 --- a/scene/3d/soft_body_3d.h +++ b/scene/3d/soft_body_3d.h @@ -126,6 +126,11 @@ class SoftBody3D : public MeshInstance3D { 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 @@ class SoftBody3D : public MeshInstance3D { 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 @@ class SoftBody3D : public MeshInstance3D { 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);