diff --git a/modules/skeleton_editor/skeleton_editor_plugin.cpp b/modules/skeleton_editor/skeleton_editor_plugin.cpp index ec47200a6..a71080a17 100644 --- a/modules/skeleton_editor/skeleton_editor_plugin.cpp +++ b/modules/skeleton_editor/skeleton_editor_plugin.cpp @@ -53,9 +53,9 @@ #include "scene/gui/tree.h" #include "scene/main/viewport.h" #include "scene/resources/capsule_shape.h" +#include "scene/resources/skin.h" #include "scene/resources/sphere_shape.h" #include "scene/resources/surface_tool.h" -#include "scene/resources/skin.h" #define DISTANCE_DEFAULT 4 @@ -89,36 +89,26 @@ void BoneTransformEditor::create_editors() { section = memnew(EditorInspectorSection); section->setup("trf_properties", label, this, section_color, true); + section->unfold(); add_child(section); - key_button = memnew(Button); - key_button->set_text(TTR("Key Transform")); - key_button->set_visible(keyable); - key_button->set_icon(get_icon("Key", "EditorIcons")); - key_button->set_flat(true); - section->get_vbox()->add_child(key_button); - - enabled_checkbox = memnew(CheckBox(TTR("Pose Enabled"))); - enabled_checkbox->set_flat(true); - enabled_checkbox->set_visible(toggle_enabled); + enabled_checkbox = memnew(EditorPropertyCheck()); + enabled_checkbox->set_label("Pose Enabled"); + enabled_checkbox->connect("property_changed", this, "_value_changed"); section->get_vbox()->add_child(enabled_checkbox); - // Translation property - translation_property = memnew(EditorPropertyVector3()); - translation_property->setup(-10000, 10000, 0.001f, true); - translation_property->set_label("Translation"); - translation_property->set_use_folding(true); - translation_property->set_read_only(false); - translation_property->connect("property_changed", this, "_value_changed_vector3"); - section->get_vbox()->add_child(translation_property); + // Position property. + position_property = memnew(EditorPropertyVector3()); + position_property->setup(-10000, 10000, 0.001f, true); + position_property->set_label("Position"); + position_property->connect("property_changed", this, "_value_changed"); + section->get_vbox()->add_child(position_property); // Rotation property - rotation_property = memnew(EditorPropertyVector3()); + rotation_property = memnew(EditorPropertyQuat()); rotation_property->setup(-10000, 10000, 0.001f, true); - rotation_property->set_label("Rotation Degrees"); - rotation_property->set_use_folding(true); - rotation_property->set_read_only(false); - rotation_property->connect("property_changed", this, "_value_changed_vector3"); + rotation_property->set_label("Rotation"); + rotation_property->connect("property_changed", this, "_value_changed"); section->get_vbox()->add_child(rotation_property); // Scale property @@ -131,199 +121,45 @@ void BoneTransformEditor::create_editors() { section->get_vbox()->add_child(scale_property); // Transform/Matrix section - transform_section = memnew(EditorInspectorSection); - transform_section->setup("trf_properties_transform", "Matrix", this, section_color, true); - section->get_vbox()->add_child(transform_section); + rest_section = memnew(EditorInspectorSection); + rest_section->setup("trf_properties_transform", "Rest", this, section_color, true); + section->get_vbox()->add_child(rest_section); // Transform/Matrix property - transform_property = memnew(EditorPropertyTransform()); - transform_property->setup(-10000, 10000, 0.001f, true); - transform_property->set_label("Transform"); - transform_property->set_use_folding(true); - transform_property->set_read_only(false); - transform_property->connect("property_changed", this, "_value_changed_transform"); - transform_section->get_vbox()->add_child(transform_property); + rest_matrix = memnew(EditorPropertyTransform()); + rest_matrix->setup(-10000, 10000, 0.001f, true); + rest_matrix->set_label("Transform"); + rest_section->get_vbox()->add_child(rest_matrix); } void BoneTransformEditor::_notification(int p_what) { switch (p_what) { case NOTIFICATION_ENTER_TREE: { create_editors(); - key_button->connect("pressed", this, "_key_button_pressed"); - enabled_checkbox->connect("toggled", this, "_checkbox_toggled"); - FALLTHROUGH; - } - case NOTIFICATION_SORT_CHILDREN: { - const Ref font = get_font("font", "Tree"); - - Point2 buffer; - buffer.x += get_constant("inspector_margin", "Editor"); - buffer.y += font->get_height(); - buffer.y += get_constant("vseparation", "Tree"); - - const float vector_height = translation_property->get_size().y; - const float transform_height = transform_property->get_size().y; - const float button_height = key_button->get_size().y; - - const float width = get_size().x - get_constant("inspector_margin", "Editor"); - Vector input_rects; - - if (keyable && section->get_vbox()->is_visible()) { - input_rects.push_back(Rect2(key_button->get_position() + buffer, Size2(width, button_height))); - } else { - input_rects.push_back(Rect2(0, 0, 0, 0)); - } - - if (section->get_vbox()->is_visible()) { - input_rects.push_back(Rect2(translation_property->get_position() + buffer, Size2(width, vector_height))); - input_rects.push_back(Rect2(rotation_property->get_position() + buffer, Size2(width, vector_height))); - input_rects.push_back(Rect2(scale_property->get_position() + buffer, Size2(width, vector_height))); - input_rects.push_back(Rect2(transform_property->get_position() + buffer, Size2(width, transform_height))); - } else { - const int32_t start = input_rects.size(); - const int32_t empty_input_rect_elements = 4; - const int32_t end = start + empty_input_rect_elements; - for (int i = start; i < end; ++i) { - input_rects.push_back(Rect2(0, 0, 0, 0)); - } - } - - for (int32_t i = 0; i < input_rects.size(); i++) { - background_rects[i] = input_rects[i]; - } - - update(); - break; - } - case NOTIFICATION_DRAW: { - const Color dark_color = get_color("dark_color_2", "Editor"); - - for (int i = 0; i < 5; ++i) { - draw_rect(background_rects[i], dark_color); - } - - break; } } } -void BoneTransformEditor::_value_changed(const double p_value) { +void BoneTransformEditor::_value_changed(const String &p_path, const Variant &p_value, const String &p_name, bool changing) { if (updating) { return; } - Transform tform = compute_transform_from_vector3s(); - _change_transform(tform); -} - -void BoneTransformEditor::_value_changed_vector3(const String &p_property, const Variant &p_value, const String &p_field, bool p_changing) { - if (updating) { - return; - } - - Transform tform = compute_transform_from_vector3s(); - _change_transform(tform); -} - -Transform BoneTransformEditor::compute_transform_from_vector3s() const { - // Convert rotation from degrees to radians. - Vector3 prop_rotation = rotation_property->get_vector(); - prop_rotation.x = Math::deg2rad(prop_rotation.x); - prop_rotation.y = Math::deg2rad(prop_rotation.y); - prop_rotation.z = Math::deg2rad(prop_rotation.z); - - return Transform( - Basis(prop_rotation, scale_property->get_vector()), - translation_property->get_vector()); -} - -void BoneTransformEditor::_value_changed_transform(const String &p_property, const Variant &p_value, const String &p_field, bool p_changing) { - if (updating) { - return; - } - - Transform transform = p_value; - - _change_transform(transform); -} - -void BoneTransformEditor::_change_transform(Transform p_new_transform) { - if (property.get_slicec('/', 0) != "bones") { - return; - } - - String s = property.get_slicec('/', 2); - - if (s == "pose") { - undo_redo->create_action(TTR("Set Pose Transform"), UndoRedo::MERGE_ENDS); - undo_redo->add_undo_method(skeleton, "set_bone_pose", property.get_slicec('/', 1).to_int(), skeleton->get_bone_pose(property.get_slicec('/', 1).to_int())); - undo_redo->add_do_method(skeleton, "set_bone_pose", property.get_slicec('/', 1).to_int(), p_new_transform); + if (skeleton) { + undo_redo->create_action(TTR("Set Bone Transform"), UndoRedo::MERGE_ENDS); + undo_redo->add_undo_property(skeleton, p_path, skeleton->get(p_path)); + undo_redo->add_do_property(skeleton, p_path, p_value); undo_redo->commit_action(); - } else if (s == "rest") { - undo_redo->create_action(TTR("Set Bone Rest Transform"), UndoRedo::MERGE_ENDS); - undo_redo->add_undo_property(skeleton, property, skeleton->get(property)); - undo_redo->add_do_property(skeleton, property, p_new_transform); - } -} - -void BoneTransformEditor::update_enabled_checkbox() { - if (property.empty()) { - return; - } - - if (enabled_checkbox) { - const String path = "bones/" + property.get_slicec('/', 1) + "/enabled"; - const bool is_enabled = skeleton->get(path); - enabled_checkbox->set_pressed(is_enabled); } } void BoneTransformEditor::_bind_methods() { - ClassDB::bind_method(D_METHOD("_key_button_pressed"), &BoneTransformEditor::_key_button_pressed); - ClassDB::bind_method(D_METHOD("_checkbox_toggled", "toggled"), &BoneTransformEditor::_checkbox_toggled); - ClassDB::bind_method(D_METHOD("_value_changed"), &BoneTransformEditor::_value_changed); - ClassDB::bind_method(D_METHOD("_value_changed_vector3"), &BoneTransformEditor::_value_changed_vector3); - ClassDB::bind_method(D_METHOD("_value_changed_transform"), &BoneTransformEditor::_value_changed_transform); - ClassDB::bind_method(D_METHOD("_change_transform"), &BoneTransformEditor::_change_transform); - //ClassDB::bind_method(D_METHOD("update_joint_tree"), &BoneTransformEditor::update_joint_tree); } -void BoneTransformEditor::_update_properties() { - if (updating) { - return; - } - - if (skeleton == nullptr) { - return; - } - - updating = true; - - Transform tform = skeleton->get(property); - _update_transform_properties(tform); -} - -void BoneTransformEditor::_update_transform_properties(Transform tform) { - Basis rotation_basis = tform.get_basis(); - Vector3 rotation_radians = rotation_basis.get_rotation_euler(); - Vector3 rotation_degrees = Vector3(Math::rad2deg(rotation_radians.x), Math::rad2deg(rotation_radians.y), Math::rad2deg(rotation_radians.z)); - Vector3 translation = tform.get_origin(); - Vector3 scale = tform.basis.get_scale(); - - translation_property->update_using_vector(translation); - rotation_property->update_using_vector(rotation_degrees); - scale_property->update_using_vector(scale); - transform_property->update_using_transform(tform); - - update_enabled_checkbox(); - updating = false; -} - BoneTransformEditor::BoneTransformEditor(Skeleton *p_skeleton) { skeleton = p_skeleton; - key_button = nullptr; enabled_checkbox = nullptr; keyable = false; toggle_enabled = false; @@ -332,82 +168,65 @@ BoneTransformEditor::BoneTransformEditor(Skeleton *p_skeleton) { } void BoneTransformEditor::set_target(const String &p_prop) { - property = p_prop; + enabled_checkbox->set_object_and_property(skeleton, p_prop + "enabled"); + enabled_checkbox->update_property(); + + position_property->set_object_and_property(skeleton, p_prop + "position"); + position_property->update_property(); + + rotation_property->set_object_and_property(skeleton, p_prop + "rotation"); + rotation_property->update_property(); + + scale_property->set_object_and_property(skeleton, p_prop + "scale"); + scale_property->update_property(); + + rest_matrix->set_object_and_property(skeleton, p_prop + "rest"); + rest_matrix->update_property(); } -void BoneTransformEditor::set_keyable(const bool p_keyable) { - keyable = p_keyable; - - if (key_button) { - key_button->set_visible(p_keyable); - } -} - -void BoneTransformEditor::_update_key_button(const bool p_keyable) { - bool is_keyable = keyable && p_keyable; - - if (key_button) { - key_button->set_visible(is_keyable); - } -} - -void BoneTransformEditor::set_properties_read_only(const bool p_readonly) { - enabled_checkbox->set_disabled(p_readonly); - enabled_checkbox->update(); -} - -void BoneTransformEditor::set_transform_read_only(const bool p_readonly) { - translation_property->set_read_only(p_readonly); - rotation_property->set_read_only(p_readonly); - scale_property->set_read_only(p_readonly); - transform_property->set_read_only(p_readonly); - translation_property->update(); - rotation_property->update(); - scale_property->update(); - transform_property->update(); - - _update_key_button(!p_readonly); -} - -void BoneTransformEditor::set_toggle_enabled(const bool p_enabled) { - toggle_enabled = p_enabled; - - if (enabled_checkbox) { - enabled_checkbox->set_visible(p_enabled); - } -} - -void BoneTransformEditor::_key_button_pressed() { - if (skeleton == nullptr) { - return; - } - - const BoneId bone_id = property.get_slicec('/', 1).to_int(); - const String name = skeleton->get_bone_name(bone_id); - - if (name.empty()) { - return; - } - - // Need to normalize the basis before you key it - Transform tform = compute_transform_from_vector3s(); - tform.orthonormalize(); - AnimationPlayerEditor::get_singleton()->get_track_editor()->insert_transform_key(skeleton, name, tform); -} - -void BoneTransformEditor::_checkbox_toggled(const bool p_toggled) { +void BoneTransformEditor::_update_properties() { + /* if (!skeleton) { return; } - if (enabled_checkbox) { - const BoneId bone_id = property.get_slicec('/', 1).to_int(); - undo_redo->create_action(TTR("Set Pose Enabled")); - bool enabled = skeleton->is_bone_enabled(bone_id); - undo_redo->add_do_method(skeleton, "set_bone_enabled", bone_id, !enabled); - undo_redo->add_undo_method(skeleton, "set_bone_enabled", bone_id, enabled); - undo_redo->commit_action(); + int selected = SkeletonEditor::get_singleton()->get_selected_bone(); + + List props; + skeleton->get_property_list(&props); + for (const PropertyInfo &E : props) { + PackedStringArray spr = E.name.split("/"); + if (spr.size() == 3 && spr[0] == "bones") { + if (spr[1].to_int() == selected) { + if (spr[2] == "enabled") { + enabled_checkbox->set_read_only(E.usage & PROPERTY_USAGE_READ_ONLY); + enabled_checkbox->update_property(); + enabled_checkbox->update(); + } + if (spr[2] == "position") { + position_property->set_read_only(E.usage & PROPERTY_USAGE_READ_ONLY); + position_property->update_property(); + position_property->update(); + } + if (spr[2] == "rotation") { + rotation_property->set_read_only(E.usage & PROPERTY_USAGE_READ_ONLY); + rotation_property->update_property(); + rotation_property->update(); + } + if (spr[2] == "scale") { + scale_property->set_read_only(E.usage & PROPERTY_USAGE_READ_ONLY); + scale_property->update_property(); + scale_property->update(); + } + if (spr[2] == "rest") { + rest_matrix->set_read_only(E.usage & PROPERTY_USAGE_READ_ONLY); + rest_matrix->update_property(); + rest_matrix->update(); + } + } + } } + */ } SkeletonEditor *SkeletonEditor::singleton = nullptr; @@ -422,24 +241,6 @@ void SkeletonEditor::set_rest_options_enabled(const bool p_rest_options_enabled) rest_options->get_popup()->set_item_disabled(REST_OPTION_POSE_TO_REST, !p_rest_options_enabled); }; -void SkeletonEditor::_update_show_rest_only() { - _update_pose_enabled(-1); -} - -void SkeletonEditor::_update_pose_enabled(int p_bone) { - if (!skeleton) { - return; - } - if (pose_editor) { - pose_editor->set_properties_read_only(skeleton->is_show_rest_only()); - - if (selected_bone > 0) { - pose_editor->set_transform_read_only(skeleton->is_show_rest_only() || !(skeleton->is_bone_enabled(selected_bone))); - } - } - _update_gizmo_visible(); -} - void SkeletonEditor::_on_click_skeleton_option(int p_skeleton_option) { if (!skeleton) { return; @@ -495,8 +296,13 @@ void SkeletonEditor::init_pose() { UndoRedo *ur = EditorNode::get_singleton()->get_undo_redo(); ur->create_action(TTR("Set Bone Transform"), UndoRedo::MERGE_ENDS); for (int i = 0; i < bone_len; i++) { - ur->add_do_method(skeleton, "set_bone_pose", i, Transform()); - ur->add_undo_method(skeleton, "set_bone_pose", i, skeleton->get_bone_pose(i)); + Transform rest = skeleton->get_bone_rest(i); + ur->add_do_method(skeleton, "set_bone_pose_position", i, rest.origin); + ur->add_do_method(skeleton, "set_bone_pose_rotation", i, rest.basis.get_rotation_quat()); + ur->add_do_method(skeleton, "set_bone_pose_scale", i, rest.basis.get_scale()); + ur->add_undo_method(skeleton, "set_bone_pose_position", i, skeleton->get_bone_pose_position(i)); + ur->add_undo_method(skeleton, "set_bone_pose_rotation", i, skeleton->get_bone_pose_rotation(i)); + ur->add_undo_method(skeleton, "set_bone_pose_scale", i, skeleton->get_bone_pose_scale(i)); } ur->commit_action(); } @@ -536,11 +342,9 @@ void SkeletonEditor::pose_to_rest() { // Todo: Do method with multiple bone selection. UndoRedo *ur = EditorNode::get_singleton()->get_undo_redo(); - ur->create_action(TTR("Set Bone Transform"), UndoRedo::MERGE_ENDS); - ur->add_do_method(skeleton, "set_bone_pose", selected_bone, Transform()); - ur->add_undo_method(skeleton, "set_bone_pose", selected_bone, skeleton->get_bone_pose(selected_bone)); - ur->add_do_method(skeleton, "set_bone_rest", selected_bone, skeleton->get_bone_rest(selected_bone) * skeleton->get_bone_pose(selected_bone)); + ur->create_action(TTR("Set Bone Rest"), UndoRedo::MERGE_ENDS); + ur->add_do_method(skeleton, "set_bone_rest", selected_bone, skeleton->get_bone_pose(selected_bone)); ur->add_undo_method(skeleton, "set_bone_rest", selected_bone, skeleton->get_bone_rest(selected_bone)); ur->commit_action(); @@ -754,19 +558,17 @@ void SkeletonEditor::_joint_tree_selection_changed() { const int b_idx = path.get_slicec('/', 1).to_int(); const String bone_path = "bones/" + itos(b_idx) + "/"; - pose_editor->set_target(bone_path + "pose"); - rest_editor->set_target(bone_path + "rest"); - - pose_editor->set_visible(true); - rest_editor->set_visible(true); + pose_editor->set_target(bone_path); selected_bone = b_idx; } } + pose_editor->set_visible(selected); + set_rest_options_enabled(selected); _update_properties(); - _update_pose_enabled(); + _update_gizmo_visible(); } void SkeletonEditor::_joint_tree_rmb_select(const Vector2 &p_pos) { @@ -775,15 +577,11 @@ void SkeletonEditor::_joint_tree_rmb_select(const Vector2 &p_pos) { } void SkeletonEditor::_update_properties() { - if (rest_editor) { - rest_editor->_update_properties(); - } - if (pose_editor) { pose_editor->_update_properties(); } - _update_gizmo_transform(); + SpatialEditor::get_singleton()->update_transform_gizmo(); } void SkeletonEditor::update_joint_tree() { @@ -955,17 +753,9 @@ void SkeletonEditor::create_editors() { s_con->add_child(joint_tree); pose_editor = memnew(BoneTransformEditor(skeleton)); - pose_editor->set_label(TTR("Bone Pose")); - pose_editor->set_toggle_enabled(true); - pose_editor->set_keyable(te->has_keying()); + pose_editor->set_label(TTR("Bone Transform")); pose_editor->set_visible(false); add_child(pose_editor); - - rest_editor = memnew(BoneTransformEditor(skeleton)); - rest_editor->set_label(TTR("Bone Rest")); - rest_editor->set_visible(false); - add_child(rest_editor); - rest_editor->set_transform_read_only(true); } void SkeletonEditor::_notification(int p_what) { @@ -985,8 +775,8 @@ void SkeletonEditor::_notification(int p_what) { #ifdef TOOLS_ENABLED skeleton->connect("pose_updated", this, "_draw_gizmo"); skeleton->connect("pose_updated", this, "_update_properties"); - skeleton->connect("bone_enabled_changed", this, "_update_pose_enabled"); - skeleton->connect("show_rest_only_changed", this, "_update_show_rest_only"); + skeleton->connect("bone_enabled_changed", this, "_bone_enabled_changed"); + skeleton->connect("show_rest_only_changed", this, "_update_gizmo_visible"); #endif break; } @@ -1019,8 +809,6 @@ void SkeletonEditor::_bind_methods() { ClassDB::bind_method(D_METHOD("_draw_handles"), &SkeletonEditor::_draw_handles); ClassDB::bind_method(D_METHOD("_draw_gizmo"), &SkeletonEditor::_draw_gizmo); - ClassDB::bind_method(D_METHOD("_update_pose_enabled"), &SkeletonEditor::_update_pose_enabled); - ClassDB::bind_method(D_METHOD("_update_show_rest_only"), &SkeletonEditor::_update_show_rest_only); _bind_tool_popup_methods(); } @@ -1136,8 +924,8 @@ SkeletonEditor::SkeletonEditor(EditorInspectorPluginSkeleton *e_plugin, EditorNo SkeletonEditor::~SkeletonEditor() { if (skeleton) { #ifdef TOOLS_ENABLED - skeleton->disconnect("show_rest_only_changed", this, "_update_show_rest_only"); - skeleton->disconnect("bone_enabled_changed", this, "_update_pose_enabled"); + skeleton->disconnect("show_rest_only_changed", this, "_update_gizmo_visible"); + skeleton->disconnect("bone_enabled_changed", this, "_bone_enabled_changed"); skeleton->disconnect("pose_updated", this, "_draw_gizmo"); skeleton->disconnect("pose_updated", this, "_update_properties"); skeleton->set_transform_gizmo_visible(true); @@ -1179,7 +967,9 @@ void SkeletonEditor::update_bone_original() { return; } - bone_original = skeleton->get_bone_pose(selected_bone); + bone_original_position = skeleton->get_bone_pose_position(selected_bone); + bone_original_rotation = skeleton->get_bone_pose_rotation(selected_bone); + bone_original_scale = skeleton->get_bone_pose_scale(selected_bone); } void SkeletonEditor::_hide_handles() { @@ -1439,10 +1229,9 @@ bool SkeletonEditorPlugin::handles(Object *p_object) const { return p_object->is_class("Skeleton"); } - -void SkeletonEditor::_update_gizmo_transform() { - SpatialEditor::get_singleton()->update_transform_gizmo(); -}; +void SkeletonEditor::_bone_enabled_changed(const int p_bone_id) { + _update_gizmo_visible(); +} void SkeletonEditorPlugin::_notification(int p_what) { if (p_what == NOTIFICATION_ENTER_TREE) { @@ -1602,7 +1391,9 @@ void SkeletonGizmoPlugin::set_subgizmo_transform(const EditorSpatialGizmo *p_giz t.origin = orig + to_local.xform(sub); // Apply transform. - skeleton->set_bone_pose(p_id, t); + skeleton->set_bone_pose_position(p_id, t.origin); + skeleton->set_bone_pose_rotation(p_id, t.basis.get_rotation_quat()); + skeleton->set_bone_pose_scale(p_id, t.basis.get_scale()); } void SkeletonGizmoPlugin::commit_subgizmos(const EditorSpatialGizmo *p_gizmo, const Vector &p_ids, const Vector &p_restore, bool p_cancel) { @@ -1610,12 +1401,31 @@ void SkeletonGizmoPlugin::commit_subgizmos(const EditorSpatialGizmo *p_gizmo, co ERR_FAIL_COND(!skeleton); SkeletonEditor *se = SkeletonEditor::get_singleton(); + SpatialEditor *ne = SpatialEditor::get_singleton(); UndoRedo *ur = EditorNode::get_singleton()->get_undo_redo(); - for (int i = 0; i < p_ids.size(); i++) { - ur->create_action(TTR("Set Bone Transform")); - ur->add_do_method(skeleton, "set_bone_pose", p_ids[i], skeleton->get_bone_pose(p_ids[i])); - ur->add_undo_method(skeleton, "set_bone_pose", p_ids[i], se->get_bone_original()); + + ur->create_action(TTR("Set Bone Transform")); + if (ne->get_tool_mode() == SpatialEditor::TOOL_MODE_SELECT || ne->get_tool_mode() == SpatialEditor::TOOL_MODE_MOVE) { + for (int i = 0; i < p_ids.size(); i++) { + ur->add_do_method(skeleton, "set_bone_pose_position", p_ids[i], skeleton->get_bone_pose_position(p_ids[i])); + ur->add_undo_method(skeleton, "set_bone_pose_position", p_ids[i], se->get_bone_original_position()); + } + } + if (ne->get_tool_mode() == SpatialEditor::TOOL_MODE_SELECT || ne->get_tool_mode() == SpatialEditor::TOOL_MODE_ROTATE) { + for (int i = 0; i < p_ids.size(); i++) { + ur->add_do_method(skeleton, "set_bone_pose_rotation", p_ids[i], skeleton->get_bone_pose_rotation(p_ids[i])); + ur->add_undo_method(skeleton, "set_bone_pose_rotation", p_ids[i], se->get_bone_original_rotation()); + } + } + if (ne->get_tool_mode() == SpatialEditor::TOOL_MODE_SCALE) { + for (int i = 0; i < p_ids.size(); i++) { + // If the axis is swapped by scaling, the rotation can be changed. + ur->add_do_method(skeleton, "set_bone_pose_rotation", p_ids[i], skeleton->get_bone_pose_rotation(p_ids[i])); + ur->add_undo_method(skeleton, "set_bone_pose_rotation", p_ids[i], se->get_bone_original_rotation()); + ur->add_do_method(skeleton, "set_bone_pose_scale", p_ids[i], skeleton->get_bone_pose_scale(p_ids[i])); + ur->add_undo_method(skeleton, "set_bone_pose_scale", p_ids[i], se->get_bone_original_scale()); + } } ur->commit_action(); } diff --git a/modules/skeleton_editor/skeleton_editor_plugin.h b/modules/skeleton_editor/skeleton_editor_plugin.h index 351c01748..6d4203665 100644 --- a/modules/skeleton_editor/skeleton_editor_plugin.h +++ b/modules/skeleton_editor/skeleton_editor_plugin.h @@ -56,28 +56,29 @@ class CheckBox; class VSeparator; class EditorPropertyTransform; class EditorPropertyVector3; +class EditorPropertyCheck; +class EditorPropertyQuat; class BoneTransformEditor : public VBoxContainer { GDCLASS(BoneTransformEditor, VBoxContainer); EditorInspectorSection *section; - EditorPropertyVector3 *translation_property; - EditorPropertyVector3 *rotation_property; + EditorPropertyCheck *enabled_checkbox = nullptr; + EditorPropertyVector3 *position_property = nullptr; + EditorPropertyQuat *rotation_property = nullptr; EditorPropertyVector3 *scale_property; - EditorInspectorSection *transform_section; - EditorPropertyTransform *transform_property; + + EditorInspectorSection *rest_section = nullptr; + EditorPropertyTransform *rest_matrix = nullptr; Rect2 background_rects[5]; Skeleton *skeleton; - String property; + //String property; UndoRedo *undo_redo; - Button *key_button; - CheckBox *enabled_checkbox; - bool keyable; bool toggle_enabled; bool updating; @@ -86,20 +87,7 @@ class BoneTransformEditor : public VBoxContainer { void create_editors(); - // Called when one of the EditorSpinSliders are changed. - void _value_changed(const double p_value); - // Called when the one of the EditorPropertyVector3 are updated. - void _value_changed_vector3(const String &p_path, const Variant &p_value, const String &p_name = "", bool changing = false); - // Called when the transform_property is updated. - void _value_changed_transform(const String &p_path, const Variant &p_value, const String &p_name = "", bool changing = false); - // Changes the transform to the given transform and updates the UI accordingly. - void _change_transform(Transform p_new_transform); - // Update it is truely keyable then. - void _update_key_button(const bool p_keyable); - // Creates a Transform using the EditorPropertyVector3 properties. - Transform compute_transform_from_vector3s() const; - - void update_enabled_checkbox(); + void _value_changed(const String &p_path, const Variant &p_value, const String &p_name = "", bool changing = false); protected: void _notification(int p_what); @@ -113,23 +101,6 @@ public: void set_label(const String &p_label) { label = p_label; } void _update_properties(); - void _update_transform_properties(Transform p_transform); - - // Transform can be keyed, whether or not to show the button - void set_keyable(const bool p_keyable); - - // When rest mode, pose and custom_pose editor are diasbled. - void set_properties_read_only(const bool p_readonly); - void set_transform_read_only(const bool p_readonly); - - // Bone can be toggled enabled or disabled, whether or not to show the checkbox - void set_toggle_enabled(const bool p_enabled); - - // Key Transform Button pressed - void _key_button_pressed(); - - // Bone Enabled Checkbox toggled - void _checkbox_toggled(const bool p_toggled); }; class SkeletonEditor : public VBoxContainer { @@ -214,13 +185,12 @@ class SkeletonEditor : public VBoxContainer { Ref handle_material; Ref handle_shader; - Transform bone_original; + Vector3 bone_original_position; + Quat bone_original_rotation; + Vector3 bone_original_scale; - void _update_pose_enabled(int p_bone = -1); - void _update_show_rest_only(); - - void _update_gizmo_transform(); void _update_gizmo_visible(); + void _bone_enabled_changed(const int p_bone_id); void _hide_handles(); @@ -254,7 +224,9 @@ public: bool is_edit_mode() const { return edit_mode; } void update_bone_original(); - Transform get_bone_original() { return bone_original; }; + Vector3 get_bone_original_position() const { return bone_original_position; }; + Quat get_bone_original_rotation() const { return bone_original_rotation; }; + Vector3 get_bone_original_scale() const { return bone_original_scale; }; SkeletonEditor(EditorInspectorPluginSkeleton *e_plugin, EditorNode *p_editor, Skeleton *skeleton); ~SkeletonEditor(); diff --git a/scene/3d/skeleton.cpp b/scene/3d/skeleton.cpp index 4cb7ff903..67c958fc0 100644 --- a/scene/3d/skeleton.cpp +++ b/scene/3d/skeleton.cpp @@ -178,6 +178,41 @@ void Skeleton::_get_property_list(List *p_list) const { #endif //_3D_DISABLED } +/* +void Skeleton::_validate_property(PropertyInfo &property) const { + Vector spr = property.name.split("/"); + if (spr.size() == 3 && spr[0] == "bones") { + if (spr[2] == "rest") { + property.usage |= PROPERTY_USAGE_KEYING_INCREMENTS; + } + if (is_show_rest_only()) { + if (spr[2] == "enabled") { + property.usage |= PROPERTY_USAGE_READ_ONLY; + } + if (spr[2] == "position") { + property.usage |= PROPERTY_USAGE_READ_ONLY; + } + if (spr[2] == "rotation") { + property.usage |= PROPERTY_USAGE_READ_ONLY; + } + if (spr[2] == "scale") { + property.usage |= PROPERTY_USAGE_READ_ONLY; + } + } else if (!is_bone_enabled(spr[1].to_int())) { + if (spr[2] == "position") { + property.usage |= PROPERTY_USAGE_READ_ONLY; + } + if (spr[2] == "rotation") { + property.usage |= PROPERTY_USAGE_READ_ONLY; + } + if (spr[2] == "scale") { + property.usage |= PROPERTY_USAGE_READ_ONLY; + } + } + } +} +*/ + void Skeleton::_update_process_order() { if (!process_order_dirty) { return; diff --git a/scene/3d/skeleton.h b/scene/3d/skeleton.h index b7b190c37..2bf4fed5e 100644 --- a/scene/3d/skeleton.h +++ b/scene/3d/skeleton.h @@ -162,7 +162,10 @@ protected: bool _get(const StringName &p_path, Variant &r_ret) const; bool _set(const StringName &p_path, const Variant &p_value); void _get_property_list(List *p_list) const; + //void _validate_property(PropertyInfo &property) const; + void _notification(int p_what); + static void _bind_methods(); #ifndef _3D_DISABLED