Skip to content

Commit ad0edb8

Browse files
committed
Merge pull request godotengine#96196 from SaracenOne/bone_editor_revert
Add Revert support to SkeletonEditor.
2 parents 9725c03 + e32856b commit ad0edb8

File tree

3 files changed

+190
-8
lines changed

3 files changed

+190
-8
lines changed

editor/editor_properties_vector.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -130,9 +130,11 @@ void EditorPropertyVectorN::_notification(int p_what) {
130130
switch (p_what) {
131131
case NOTIFICATION_READY: {
132132
if (linked->is_visible()) {
133-
const String key = vformat("%s:%s", get_edited_object()->get_class(), get_edited_property());
134-
linked->set_pressed_no_signal(EditorSettings::get_singleton()->get_project_metadata("linked_properties", key, true));
135-
_update_ratio();
133+
if (get_edited_object()) {
134+
const String key = vformat("%s:%s", get_edited_object()->get_class(), get_edited_property());
135+
linked->set_pressed_no_signal(EditorSettings::get_singleton()->get_project_metadata("linked_properties", key, true));
136+
_update_ratio();
137+
}
136138
}
137139
} break;
138140

editor/plugins/skeleton_3d_editor_plugin.cpp

Lines changed: 177 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747
#include "scene/3d/physics/physics_body_3d.h"
4848
#include "scene/gui/separator.h"
4949
#include "scene/gui/texture_rect.h"
50+
#include "scene/property_utils.h"
5051
#include "scene/resources/3d/capsule_shape_3d.h"
5152
#include "scene/resources/skeleton_profile.h"
5253
#include "scene/resources/surface_tool.h"
@@ -65,7 +66,7 @@ void BoneTransformEditor::create_editors() {
6566

6667
// Position property.
6768
position_property = memnew(EditorPropertyVector3());
68-
position_property->setup(-10000, 10000, 0.001f, true);
69+
position_property->setup(-10000, 10000, 0.001, true);
6970
position_property->set_label("Position");
7071
position_property->set_selectable(false);
7172
position_property->connect("property_changed", callable_mp(this, &BoneTransformEditor::_value_changed));
@@ -74,7 +75,7 @@ void BoneTransformEditor::create_editors() {
7475

7576
// Rotation property.
7677
rotation_property = memnew(EditorPropertyQuaternion());
77-
rotation_property->setup(-10000, 10000, 0.001f, true);
78+
rotation_property->setup(-10000, 10000, 0.001, true);
7879
rotation_property->set_label("Rotation");
7980
rotation_property->set_selectable(false);
8081
rotation_property->connect("property_changed", callable_mp(this, &BoneTransformEditor::_value_changed));
@@ -83,7 +84,7 @@ void BoneTransformEditor::create_editors() {
8384

8485
// Scale property.
8586
scale_property = memnew(EditorPropertyVector3());
86-
scale_property->setup(-10000, 10000, 0.001f, true);
87+
scale_property->setup(-10000, 10000, 0.001, true, true);
8788
scale_property->set_label("Scale");
8889
scale_property->set_selectable(false);
8990
scale_property->connect("property_changed", callable_mp(this, &BoneTransformEditor::_value_changed));
@@ -97,7 +98,7 @@ void BoneTransformEditor::create_editors() {
9798

9899
// Transform/Matrix property.
99100
rest_matrix = memnew(EditorPropertyTransform3D());
100-
rest_matrix->setup(-10000, 10000, 0.001f, true);
101+
rest_matrix->setup(-10000, 10000, 0.001, true);
101102
rest_matrix->set_label("Transform");
102103
rest_matrix->set_selectable(false);
103104
rest_section->get_vbox()->add_child(rest_matrix);
@@ -122,6 +123,13 @@ void BoneTransformEditor::_value_changed(const String &p_property, const Variant
122123
undo_redo->create_action(TTR("Set Bone Transform"), UndoRedo::MERGE_ENDS);
123124
undo_redo->add_undo_property(skeleton, p_property, skeleton->get(p_property));
124125
undo_redo->add_do_property(skeleton, p_property, p_value);
126+
127+
Skeleton3DEditor *se = Skeleton3DEditor::get_singleton();
128+
if (se) {
129+
undo_redo->add_do_method(se, "update_joint_tree");
130+
undo_redo->add_undo_method(se, "update_joint_tree");
131+
}
132+
125133
undo_redo->commit_action();
126134
}
127135
}
@@ -189,26 +197,31 @@ void BoneTransformEditor::_update_properties() {
189197
if (split[2] == "enabled") {
190198
enabled_checkbox->set_read_only(E.usage & PROPERTY_USAGE_READ_ONLY);
191199
enabled_checkbox->update_property();
200+
enabled_checkbox->update_editor_property_status();
192201
enabled_checkbox->queue_redraw();
193202
}
194203
if (split[2] == "position") {
195204
position_property->set_read_only(E.usage & PROPERTY_USAGE_READ_ONLY);
196205
position_property->update_property();
206+
position_property->update_editor_property_status();
197207
position_property->queue_redraw();
198208
}
199209
if (split[2] == "rotation") {
200210
rotation_property->set_read_only(E.usage & PROPERTY_USAGE_READ_ONLY);
201211
rotation_property->update_property();
212+
rotation_property->update_editor_property_status();
202213
rotation_property->queue_redraw();
203214
}
204215
if (split[2] == "scale") {
205216
scale_property->set_read_only(E.usage & PROPERTY_USAGE_READ_ONLY);
206217
scale_property->update_property();
218+
scale_property->update_editor_property_status();
207219
scale_property->queue_redraw();
208220
}
209221
if (split[2] == "rest") {
210222
rest_matrix->set_read_only(E.usage & PROPERTY_USAGE_READ_ONLY);
211223
rest_matrix->update_property();
224+
rest_matrix->update_editor_property_status();
212225
rest_matrix->queue_redraw();
213226
}
214227
}
@@ -232,6 +245,11 @@ void Skeleton3DEditor::set_bone_options_enabled(const bool p_bone_options_enable
232245
skeleton_options->get_popup()->set_item_disabled(SKELETON_OPTION_SELECTED_POSES_TO_RESTS, !p_bone_options_enabled);
233246
};
234247

248+
void Skeleton3DEditor::_bind_methods() {
249+
ClassDB::bind_method(D_METHOD("update_all"), &Skeleton3DEditor::update_all);
250+
ClassDB::bind_method(D_METHOD("update_joint_tree"), &Skeleton3DEditor::update_joint_tree);
251+
}
252+
235253
void Skeleton3DEditor::_on_click_skeleton_option(int p_skeleton_option) {
236254
if (!skeleton) {
237255
return;
@@ -294,6 +312,10 @@ void Skeleton3DEditor::reset_pose(const bool p_all_bones) {
294312
ur->add_undo_method(skeleton, "set_bone_pose_scale", selected_bone, skeleton->get_bone_pose_scale(selected_bone));
295313
ur->add_do_method(skeleton, "reset_bone_pose", selected_bone);
296314
}
315+
316+
ur->add_undo_method(this, "update_joint_tree");
317+
ur->add_do_method(this, "update_joint_tree");
318+
297319
ur->commit_action();
298320
}
299321

@@ -357,6 +379,10 @@ void Skeleton3DEditor::pose_to_rest(const bool p_all_bones) {
357379
ur->add_do_method(skeleton, "set_bone_rest", selected_bone, skeleton->get_bone_pose(selected_bone));
358380
ur->add_undo_method(skeleton, "set_bone_rest", selected_bone, skeleton->get_bone_rest(selected_bone));
359381
}
382+
383+
ur->add_undo_method(this, "update_joint_tree");
384+
ur->add_do_method(this, "update_joint_tree");
385+
360386
ur->commit_action();
361387
}
362388

@@ -620,9 +646,12 @@ void Skeleton3DEditor::move_skeleton_bone(NodePath p_skeleton_path, int32_t p_se
620646
}
621647
ur->add_undo_method(skeleton_node, "set_bone_parent", p_selected_boneidx, skeleton_node->get_bone_parent(p_selected_boneidx));
622648
ur->add_do_method(skeleton_node, "set_bone_parent", p_selected_boneidx, p_target_boneidx);
649+
650+
ur->add_undo_method(this, "update_joint_tree");
651+
ur->add_do_method(this, "update_joint_tree");
652+
623653
skeleton_node->set_bone_parent(p_selected_boneidx, p_target_boneidx);
624654

625-
update_joint_tree();
626655
ur->commit_action();
627656
}
628657

@@ -655,6 +684,107 @@ void Skeleton3DEditor::_joint_tree_selection_changed() {
655684
void Skeleton3DEditor::_joint_tree_rmb_select(const Vector2 &p_pos, MouseButton p_button) {
656685
}
657686

687+
void Skeleton3DEditor::_joint_tree_button_clicked(Object *p_item, int p_column, int p_id, MouseButton p_button) {
688+
if (!skeleton) {
689+
return;
690+
}
691+
692+
TreeItem *tree_item = Object::cast_to<TreeItem>(p_item);
693+
if (tree_item) {
694+
String tree_item_metadata = tree_item->get_metadata(0);
695+
696+
String bone_enabled_property = tree_item_metadata + "/enabled";
697+
String bone_parent_property = tree_item_metadata + "/parent";
698+
String bone_name_property = tree_item_metadata + "/name";
699+
String bone_position_property = tree_item_metadata + "/position";
700+
String bone_rotation_property = tree_item_metadata + "/rotation";
701+
String bone_scale_property = tree_item_metadata + "/scale";
702+
String bone_rest_property = tree_item_metadata + "/rest";
703+
704+
Variant current_enabled = skeleton->get(bone_enabled_property);
705+
Variant current_parent = skeleton->get(bone_parent_property);
706+
Variant current_name = skeleton->get(bone_name_property);
707+
Variant current_position = skeleton->get(bone_position_property);
708+
Variant current_rotation = skeleton->get(bone_rotation_property);
709+
Variant current_scale = skeleton->get(bone_scale_property);
710+
Variant current_rest = skeleton->get(bone_rest_property);
711+
712+
EditorUndoRedoManager *ur = EditorUndoRedoManager::get_singleton();
713+
ur->create_action(TTR("Revert Bone"));
714+
715+
bool can_revert_enabled = EditorPropertyRevert::can_property_revert(skeleton, bone_enabled_property, &current_enabled);
716+
if (can_revert_enabled) {
717+
bool is_valid = false;
718+
Variant new_enabled = EditorPropertyRevert::get_property_revert_value(skeleton, bone_enabled_property, &is_valid);
719+
if (is_valid) {
720+
ur->add_undo_method(skeleton, "set", bone_enabled_property, current_enabled);
721+
ur->add_do_method(skeleton, "set", bone_enabled_property, new_enabled);
722+
}
723+
}
724+
725+
bool can_revert_parent = EditorPropertyRevert::can_property_revert(skeleton, bone_parent_property, &current_parent);
726+
if (can_revert_parent) {
727+
bool is_valid = false;
728+
Variant new_parent = EditorPropertyRevert::get_property_revert_value(skeleton, bone_parent_property, &is_valid);
729+
if (is_valid) {
730+
ur->add_undo_method(skeleton, "set", bone_parent_property, current_parent);
731+
ur->add_do_method(skeleton, "set", bone_parent_property, new_parent);
732+
}
733+
}
734+
bool can_revert_name = EditorPropertyRevert::can_property_revert(skeleton, bone_name_property, &current_name);
735+
if (can_revert_name) {
736+
bool is_valid = false;
737+
Variant new_name = EditorPropertyRevert::get_property_revert_value(skeleton, bone_name_property, &is_valid);
738+
if (is_valid) {
739+
ur->add_undo_method(skeleton, "set", bone_name_property, current_name);
740+
ur->add_do_method(skeleton, "set", bone_name_property, new_name);
741+
}
742+
}
743+
bool can_revert_position = EditorPropertyRevert::can_property_revert(skeleton, bone_position_property, &current_position);
744+
if (can_revert_position) {
745+
bool is_valid = false;
746+
Variant new_position = EditorPropertyRevert::get_property_revert_value(skeleton, bone_position_property, &is_valid);
747+
if (is_valid) {
748+
ur->add_undo_method(skeleton, "set", bone_position_property, current_position);
749+
ur->add_do_method(skeleton, "set", bone_position_property, new_position);
750+
}
751+
}
752+
bool can_revert_rotation = EditorPropertyRevert::can_property_revert(skeleton, bone_rotation_property, &current_rotation);
753+
if (can_revert_rotation) {
754+
bool is_valid = false;
755+
Variant new_rotation = EditorPropertyRevert::get_property_revert_value(skeleton, bone_rotation_property, &is_valid);
756+
if (is_valid) {
757+
ur->add_undo_method(skeleton, "set", bone_rotation_property, current_rotation);
758+
ur->add_do_method(skeleton, "set", bone_rotation_property, new_rotation);
759+
}
760+
}
761+
bool can_revert_scale = EditorPropertyRevert::can_property_revert(skeleton, bone_scale_property, &current_scale);
762+
if (can_revert_scale) {
763+
bool is_valid = false;
764+
Variant new_scale = EditorPropertyRevert::get_property_revert_value(skeleton, bone_scale_property, &is_valid);
765+
if (is_valid) {
766+
ur->add_undo_method(skeleton, "set", bone_scale_property, current_scale);
767+
ur->add_do_method(skeleton, "set", bone_scale_property, new_scale);
768+
}
769+
}
770+
bool can_revert_rest = EditorPropertyRevert::can_property_revert(skeleton, bone_rest_property, &current_rest);
771+
if (can_revert_rest) {
772+
bool is_valid = false;
773+
Variant new_rest = EditorPropertyRevert::get_property_revert_value(skeleton, bone_rest_property, &is_valid);
774+
if (is_valid) {
775+
ur->add_undo_method(skeleton, "set", bone_rest_property, current_rest);
776+
ur->add_do_method(skeleton, "set", bone_rest_property, new_rest);
777+
}
778+
}
779+
780+
ur->add_undo_method(this, "update_all");
781+
ur->add_do_method(this, "update_all");
782+
783+
ur->commit_action();
784+
}
785+
return;
786+
}
787+
658788
void Skeleton3DEditor::_update_properties() {
659789
if (pose_editor) {
660790
pose_editor->_update_properties();
@@ -693,15 +823,52 @@ void Skeleton3DEditor::update_joint_tree() {
693823
joint_item->set_selectable(0, true);
694824
joint_item->set_metadata(0, "bones/" + itos(current_bone_idx));
695825

826+
String bone_enabled_property = "bones/" + itos(current_bone_idx) + "/enabled";
827+
String bone_parent_property = "bones/" + itos(current_bone_idx) + "/parent";
828+
String bone_name_property = "bones/" + itos(current_bone_idx) + "/name";
829+
String bone_position_property = "bones/" + itos(current_bone_idx) + "/position";
830+
String bone_rotation_property = "bones/" + itos(current_bone_idx) + "/rotation";
831+
String bone_scale_property = "bones/" + itos(current_bone_idx) + "/scale";
832+
String bone_rest_property = "bones/" + itos(current_bone_idx) + "/rest";
833+
834+
Variant current_enabled = skeleton->get(bone_enabled_property);
835+
Variant current_parent = skeleton->get(bone_parent_property);
836+
Variant current_name = skeleton->get(bone_name_property);
837+
Variant current_position = skeleton->get(bone_position_property);
838+
Variant current_rotation = skeleton->get(bone_rotation_property);
839+
Variant current_scale = skeleton->get(bone_scale_property);
840+
Variant current_rest = skeleton->get(bone_rest_property);
841+
842+
bool can_revert_enabled = EditorPropertyRevert::can_property_revert(skeleton, bone_enabled_property, &current_enabled);
843+
bool can_revert_parent = EditorPropertyRevert::can_property_revert(skeleton, bone_parent_property, &current_parent);
844+
bool can_revert_name = EditorPropertyRevert::can_property_revert(skeleton, bone_name_property, &current_name);
845+
bool can_revert_position = EditorPropertyRevert::can_property_revert(skeleton, bone_position_property, &current_position);
846+
bool can_revert_rotation = EditorPropertyRevert::can_property_revert(skeleton, bone_rotation_property, &current_rotation);
847+
bool can_revert_scale = EditorPropertyRevert::can_property_revert(skeleton, bone_scale_property, &current_scale);
848+
bool can_revert_rest = EditorPropertyRevert::can_property_revert(skeleton, bone_rest_property, &current_rest);
849+
850+
if (can_revert_enabled || can_revert_parent || can_revert_name || can_revert_position || can_revert_rotation || can_revert_scale || can_revert_rest) {
851+
joint_item->add_button(0, get_editor_theme_icon(SNAME("ReloadSmall")), JOINT_BUTTON_REVERT, false, TTR("Revert"));
852+
}
853+
696854
// Add the bone's children to the list of bones to be processed.
697855
Vector<int> current_bone_child_bones = skeleton->get_bone_children(current_bone_idx);
698856
int child_bone_size = current_bone_child_bones.size();
699857
for (int i = 0; i < child_bone_size; i++) {
700858
bones_to_process.push_back(current_bone_child_bones[i]);
701859
}
860+
861+
if (current_bone_idx == selected_bone) {
862+
joint_item->select(0);
863+
}
702864
}
703865
}
704866

867+
void Skeleton3DEditor::update_all() {
868+
_update_properties();
869+
update_joint_tree();
870+
}
871+
705872
void Skeleton3DEditor::create_editors() {
706873
set_h_size_flags(SIZE_EXPAND_FILL);
707874
set_focus_mode(FOCUS_ALL);
@@ -840,6 +1007,7 @@ void Skeleton3DEditor::_notification(int p_what) {
8401007

8411008
joint_tree->connect(SceneStringName(item_selected), callable_mp(this, &Skeleton3DEditor::_joint_tree_selection_changed));
8421009
joint_tree->connect("item_mouse_selected", callable_mp(this, &Skeleton3DEditor::_joint_tree_rmb_select));
1010+
joint_tree->connect("button_clicked", callable_mp(this, &Skeleton3DEditor::_joint_tree_button_clicked));
8431011
#ifdef TOOLS_ENABLED
8441012
skeleton->connect(SceneStringName(pose_updated), callable_mp(this, &Skeleton3DEditor::_draw_gizmo));
8451013
skeleton->connect(SceneStringName(pose_updated), callable_mp(this, &Skeleton3DEditor::_update_properties));
@@ -1337,6 +1505,10 @@ void Skeleton3DGizmoPlugin::commit_subgizmos(const EditorNode3DGizmo *p_gizmo, c
13371505
ur->add_undo_method(skeleton, "set_bone_pose_scale", p_ids[i], se->get_bone_original_scale());
13381506
}
13391507
}
1508+
1509+
ur->add_do_method(se, "update_joint_tree");
1510+
ur->add_undo_method(se, "update_joint_tree");
1511+
13401512
ur->commit_action();
13411513
}
13421514

editor/plugins/skeleton_3d_editor_plugin.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,8 @@ class BoneTransformEditor : public VBoxContainer {
9696
class Skeleton3DEditor : public VBoxContainer {
9797
GDCLASS(Skeleton3DEditor, VBoxContainer);
9898

99+
static void _bind_methods();
100+
99101
friend class Skeleton3DEditorPlugin;
100102

101103
enum SkeletonOption {
@@ -116,6 +118,10 @@ class Skeleton3DEditor : public VBoxContainer {
116118

117119
Skeleton3D *skeleton = nullptr;
118120

121+
enum {
122+
JOINT_BUTTON_REVERT = 0,
123+
};
124+
119125
Tree *joint_tree = nullptr;
120126
BoneTransformEditor *rest_editor = nullptr;
121127
BoneTransformEditor *pose_editor = nullptr;
@@ -149,6 +155,7 @@ class Skeleton3DEditor : public VBoxContainer {
149155
EditorFileDialog *file_export_lib = nullptr;
150156

151157
void update_joint_tree();
158+
void update_all();
152159

153160
void create_editors();
154161

@@ -189,6 +196,7 @@ class Skeleton3DEditor : public VBoxContainer {
189196

190197
void _joint_tree_selection_changed();
191198
void _joint_tree_rmb_select(const Vector2 &p_pos, MouseButton p_button);
199+
void _joint_tree_button_clicked(Object *p_item, int p_column, int p_id, MouseButton p_button);
192200
void _update_properties();
193201

194202
void _subgizmo_selection_change();

0 commit comments

Comments
 (0)