diff --git a/doc/classes/Skeleton.xml b/doc/classes/Skeleton.xml index 7b19d523d..ba314258e 100644 --- a/doc/classes/Skeleton.xml +++ b/doc/classes/Skeleton.xml @@ -28,6 +28,16 @@ [i]Deprecated soon.[/i] + + + + + + + Takes the given bone pose/transform and converts it to a world transform, relative to the [Skeleton3D] node. + This is useful for using the bone transform in calculations with transforms from [Node3D]-based nodes. + + @@ -37,6 +47,7 @@ + Removes the global pose override on all bones in the skeleton. @@ -125,38 +136,56 @@ [i]Deprecated soon.[/i] + + + + + + + Returns whether the bone rest for the bone at [code]bone_idx[/code] is disabled. + + + Returns all bones in the skeleton to their rest poses. + Adds a collision exception to the physical bone. + Works just like the [RigidBody3D] node. + Removes a collision exception to the physical bone. + Works just like the [RigidBody3D] node. + Tells the [PhysicalBone3D] nodes in the Skeleton to start simulating and reacting to the physics world. + Optionally, a list of bone names can be passed-in, allowing only the passed-in bones to be simulated. + Tells the [PhysicalBone3D] nodes in the Skeleton to stop simulating. + Binds the given Skin to the Skeleton. @@ -172,6 +201,9 @@ + Sets the global pose transform, [code]pose[/code], for the bone at [code]bone_idx[/code]. + [code]amount[/code] is the interpolation strengh that will be used when applying the pose, and [code]persistent[/code] determines if the applied pose will remain. + [b]Note[/b]: The pose transform needs to be in bone space. Use [method world_transform_to_bone_transform] to convert a world transform, like one you can get from a [Node3D], to bone space. @@ -241,6 +273,17 @@ + Unparents the bone at [code]bone_idx[/code] and sets its rest position to that of it's parent prior to being reset. + + + + + + + + + Takes the given world transform, relative to the [Skeleton3D], and converts it to a bone pose/transform. + This is useful for using setting bone poses using transforms from [Node3D]-based nodes. diff --git a/editor/editor_properties.cpp b/editor/editor_properties.cpp index 6e06d085d..1fd3984ef 100644 --- a/editor/editor_properties.cpp +++ b/editor/editor_properties.cpp @@ -1878,13 +1878,25 @@ void EditorPropertyVector3::_value_changed(double val, const String &p_name) { } void EditorPropertyVector3::update_property() { - Vector3 val = get_edited_object()->get(get_edited_property()); + update_using_vector(get_edited_object()->get(get_edited_property())); +} + +void EditorPropertyVector3::update_using_vector(Vector3 p_vector) { setting = true; - spin[0]->set_value(val.x); - spin[1]->set_value(val.y); - spin[2]->set_value(val.z); + spin[0]->set_value(p_vector.x); + spin[1]->set_value(p_vector.y); + spin[2]->set_value(p_vector.z); setting = false; } + +Vector3 EditorPropertyVector3::get_vector() { + Vector3 v3; + v3.x = spin[0]->get_value(); + v3.y = spin[1]->get_value(); + v3.z = spin[2]->get_value(); + return v3; +} + void EditorPropertyVector3::_notification(int p_what) { if (p_what == NOTIFICATION_ENTER_TREE || p_what == NOTIFICATION_THEME_CHANGED) { Color base = get_color("accent_color", "Editor"); @@ -2441,23 +2453,27 @@ void EditorPropertyTransform::_value_changed(double val, const String &p_name) { } void EditorPropertyTransform::update_property() { - Transform val = get_edited_object()->get(get_edited_property()); + update_using_transform(get_edited_object()->get(get_edited_property())); +} + +void EditorPropertyTransform::update_using_transform(Transform p_transform) { setting = true; - spin[0]->set_value(val.basis[0][0]); - spin[1]->set_value(val.basis[1][0]); - spin[2]->set_value(val.basis[2][0]); - spin[3]->set_value(val.basis[0][1]); - spin[4]->set_value(val.basis[1][1]); - spin[5]->set_value(val.basis[2][1]); - spin[6]->set_value(val.basis[0][2]); - spin[7]->set_value(val.basis[1][2]); - spin[8]->set_value(val.basis[2][2]); - spin[9]->set_value(val.origin[0]); - spin[10]->set_value(val.origin[1]); - spin[11]->set_value(val.origin[2]); + spin[0]->set_value(p_transform.basis[0][0]); + spin[1]->set_value(p_transform.basis[1][0]); + spin[2]->set_value(p_transform.basis[2][0]); + spin[3]->set_value(p_transform.basis[0][1]); + spin[4]->set_value(p_transform.basis[1][1]); + spin[5]->set_value(p_transform.basis[2][1]); + spin[6]->set_value(p_transform.basis[0][2]); + spin[7]->set_value(p_transform.basis[1][2]); + spin[8]->set_value(p_transform.basis[2][2]); + spin[9]->set_value(p_transform.origin[0]); + spin[10]->set_value(p_transform.origin[1]); + spin[11]->set_value(p_transform.origin[2]); setting = false; } + void EditorPropertyTransform::_notification(int p_what) { if (p_what == NOTIFICATION_ENTER_TREE || p_what == NOTIFICATION_THEME_CHANGED) { Color base = get_color("accent_color", "Editor"); diff --git a/editor/editor_properties.h b/editor/editor_properties.h index b3ef30ed2..c1e69819d 100644 --- a/editor/editor_properties.h +++ b/editor/editor_properties.h @@ -494,6 +494,8 @@ protected: public: virtual void update_property(); + virtual void update_using_vector(Vector3 p_vector); + virtual Vector3 get_vector(); void setup(double p_min, double p_max, double p_step, bool p_no_slider); EditorPropertyVector3(); }; @@ -606,6 +608,7 @@ protected: public: virtual void update_property(); + virtual void update_using_transform(Transform p_transform); void setup(double p_min, double p_max, double p_step, bool p_no_slider); EditorPropertyTransform(); }; diff --git a/modules/skeleton_editor/skeleton_editor_plugin.cpp b/modules/skeleton_editor/skeleton_editor_plugin.cpp index 196a9ea7a..d0dd3099a 100644 --- a/modules/skeleton_editor/skeleton_editor_plugin.cpp +++ b/modules/skeleton_editor/skeleton_editor_plugin.cpp @@ -98,76 +98,46 @@ void ModuleBoneTransformEditor::create_editors() { enabled_checkbox->set_visible(toggle_enabled); section->get_vbox()->add_child(enabled_checkbox); - Label *l1 = memnew(Label(TTR("Translation"))); - section->get_vbox()->add_child(l1); + // 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); - translation_grid = memnew(GridContainer()); - translation_grid->set_columns(TRANSLATION_COMPONENTS); - section->get_vbox()->add_child(translation_grid); + // Rotation property + rotation_property = memnew(EditorPropertyVector3()); + 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"); + section->get_vbox()->add_child(rotation_property); - Label *l2 = memnew(Label(TTR("Rotation Degrees"))); - section->get_vbox()->add_child(l2); + // Scale property + scale_property = memnew(EditorPropertyVector3()); + scale_property->setup(-10000, 10000, 0.001f, true); + scale_property->set_label("Scale"); + scale_property->set_use_folding(true); + scale_property->set_read_only(false); + scale_property->connect("property_changed", this, "_value_changed_vector3"); + section->get_vbox()->add_child(scale_property); - rotation_grid = memnew(GridContainer()); - rotation_grid->set_columns(ROTATION_DEGREES_COMPONENTS); - section->get_vbox()->add_child(rotation_grid); + // 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); - Label *l3 = memnew(Label(TTR("Scale"))); - section->get_vbox()->add_child(l3); - - scale_grid = memnew(GridContainer()); - scale_grid->set_columns(SCALE_COMPONENTS); - section->get_vbox()->add_child(scale_grid); - - Label *l4 = memnew(Label(TTR("Transform"))); - section->get_vbox()->add_child(l4); - - transform_grid = memnew(GridContainer()); - transform_grid->set_columns(TRANSFORM_CONTROL_COMPONENTS); - section->get_vbox()->add_child(transform_grid); - - static const char *desc[TRANSFORM_COMPONENTS] = { "x", "y", "z", "x", "y", "z", "x", "y", "z", "x", "y", "z" }; - float snap = EDITOR_GET("interface/inspector/default_float_step"); - - for (int i = 0; i < TRANSFORM_CONTROL_COMPONENTS; ++i) { - translation_slider[i] = memnew(EditorSpinSlider()); - translation_slider[i]->set_label(desc[i]); - translation_slider[i]->set_step(snap); - setup_spinner(translation_slider[i], false); - translation_grid->add_child(translation_slider[i]); - - rotation_slider[i] = memnew(EditorSpinSlider()); - rotation_slider[i]->set_label(desc[i]); - rotation_slider[i]->set_step(snap); - setup_spinner(rotation_slider[i], false); - rotation_grid->add_child(rotation_slider[i]); - - scale_slider[i] = memnew(EditorSpinSlider()); - scale_slider[i]->set_label(desc[i]); - scale_slider[i]->set_step(snap); - setup_spinner(scale_slider[i], false); - scale_grid->add_child(scale_slider[i]); - } - - for (int i = 0; i < TRANSFORM_COMPONENTS; ++i) { - transform_slider[i] = memnew(EditorSpinSlider()); - transform_slider[i]->set_label(desc[i]); - transform_slider[i]->set_step(snap); - setup_spinner(transform_slider[i], true); - transform_grid->add_child(transform_slider[i]); - } -} - -void ModuleBoneTransformEditor::setup_spinner(EditorSpinSlider *spinner, const bool is_transform_spinner) { - spinner->set_flat(true); - spinner->set_min(-10000); - spinner->set_max(10000); - spinner->set_hide_slider(true); - spinner->set_allow_greater(true); - spinner->set_allow_lesser(true); - spinner->set_h_size_flags(SIZE_EXPAND_FILL); - - spinner->connect("value_changed", this, "_value_changed", varray(is_transform_spinner)); + // 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); } void ModuleBoneTransformEditor::_notification(int p_what) { @@ -178,49 +148,6 @@ void ModuleBoneTransformEditor::_notification(int p_what) { enabled_checkbox->connect("toggled", this, "_checkbox_toggled"); FALLTHROUGH; } - case NOTIFICATION_THEME_CHANGED: { - const Color base = get_color("accent_color", "Editor"); - const Color bg_color = get_color("property_color", "Editor"); - const Color bg_lbl_color(bg_color.r, bg_color.g, bg_color.b, 0.5); - - for (int i = 0; i < TRANSLATION_COMPONENTS; i++) { - Color c = base; - c.set_hsv(float(i % TRANSLATION_COMPONENTS) / TRANSLATION_COMPONENTS + 0.05, c.get_s() * 0.75, c.get_v()); - if (!translation_slider[i]) { - continue; - } - translation_slider[i]->set_custom_label_color(true, c); - } - - for (int i = 0; i < ROTATION_DEGREES_COMPONENTS; i++) { - Color c = base; - c.set_hsv(float(i % ROTATION_DEGREES_COMPONENTS) / ROTATION_DEGREES_COMPONENTS + 0.05, c.get_s() * 0.75, c.get_v()); - if (!rotation_slider[i]) { - continue; - } - rotation_slider[i]->set_custom_label_color(true, c); - } - - for (int i = 0; i < SCALE_COMPONENTS; i++) { - Color c = base; - c.set_hsv(float(i % SCALE_COMPONENTS) / SCALE_COMPONENTS + 0.05, c.get_s() * 0.75, c.get_v()); - if (!scale_slider[i]) { - continue; - } - scale_slider[i]->set_custom_label_color(true, c); - } - - for (int i = 0; i < TRANSFORM_COMPONENTS; i++) { - Color c = base; - c.set_hsv(float(i % TRANSFORM_COMPONENTS) / TRANSFORM_COMPONENTS + 0.05, c.get_s() * 0.75, c.get_v()); - if (!transform_slider[i]) { - continue; - } - transform_slider[i]->set_custom_label_color(true, c); - } - - break; - } case NOTIFICATION_SORT_CHILDREN: { const Ref font = get_font("font", "Tree"); @@ -229,12 +156,13 @@ void ModuleBoneTransformEditor::_notification(int p_what) { buffer.y += font->get_height(); buffer.y += get_constant("vseparation", "Tree"); - const float vector_height = translation_grid->get_size().y; - const float transform_height = transform_grid->get_size().y; + 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 { @@ -242,10 +170,10 @@ void ModuleBoneTransformEditor::_notification(int p_what) { } if (section->get_vbox()->is_visible()) { - input_rects.push_back(Rect2(translation_grid->get_position() + buffer, Size2(width, vector_height))); - input_rects.push_back(Rect2(rotation_grid->get_position() + buffer, Size2(width, vector_height))); - input_rects.push_back(Rect2(scale_grid->get_position() + buffer, Size2(width, vector_height))); - input_rects.push_back(Rect2(transform_grid->get_position() + buffer, Size2(width, transform_height))); + 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; @@ -274,47 +202,67 @@ void ModuleBoneTransformEditor::_notification(int p_what) { } } -void ModuleBoneTransformEditor::_value_changed(const double p_value, const bool p_from_transform) { +void ModuleBoneTransformEditor::_value_changed(const double p_value) { if (updating) return; - if (property.get_slicec('/', 0) == "bones" && property.get_slicec('/', 2) == "custom_pose") { - const Transform tform = compute_transform(p_from_transform); - - undo_redo->create_action(TTR("Set Custom Bone Pose Transform"), UndoRedo::MERGE_ENDS); - undo_redo->add_undo_method(skeleton, "set_bone_custom_pose", property.get_slicec('/', 1).to_int(), skeleton->get_bone_custom_pose(property.get_slicec('/', 1).to_int())); - undo_redo->add_do_method(skeleton, "set_bone_custom_pose", property.get_slicec('/', 1).to_int(), tform); - undo_redo->commit_action(); - } else if (property.get_slicec('/', 0) == "bones") { - const Transform tform = compute_transform(p_from_transform); - - undo_redo->create_action(TTR("Set Bone Transform"), UndoRedo::MERGE_ENDS); - undo_redo->add_undo_property(skeleton, property, skeleton->get(property)); - undo_redo->add_do_property(skeleton, property, tform); - undo_redo->commit_action(); - } + Transform tform = compute_transform_from_vector3s(); + _change_transform(tform); } -Transform ModuleBoneTransformEditor::compute_transform(const bool p_from_transform) const { - // Last modified was a raw transform column... - if (p_from_transform) { - Transform tform; - - for (int i = 0; i < BASIS_COMPONENTS; ++i) { - tform.basis[i / BASIS_SPLIT_COMPONENTS][i % BASIS_SPLIT_COMPONENTS] = transform_slider[i]->get_value(); - } - - for (int i = 0; i < TRANSLATION_COMPONENTS; ++i) { - tform.origin[i] = transform_slider[i + BASIS_COMPONENTS]->get_value(); - } - - return tform; +void ModuleBoneTransformEditor::_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 ModuleBoneTransformEditor::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(Vector3(Math::deg2rad(rotation_slider[0]->get_value()), Math::deg2rad(rotation_slider[1]->get_value()), Math::deg2rad(rotation_slider[2]->get_value())), - Vector3(scale_slider[0]->get_value(), scale_slider[1]->get_value(), scale_slider[2]->get_value())), - Vector3(translation_slider[0]->get_value(), translation_slider[1]->get_value(), translation_slider[2]->get_value())); + Basis(prop_rotation, scale_property->get_vector()), + translation_property->get_vector()); +} + +void ModuleBoneTransformEditor::_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 ModuleBoneTransformEditor::_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); + undo_redo->commit_action(); + } else if (s == "custom_pose") { + undo_redo->create_action(TTR("Set Custom Bone Pose Transform"), UndoRedo::MERGE_ENDS); + undo_redo->add_undo_method(skeleton, "set_bone_custom_pose", property.get_slicec('/', 1).to_int(), skeleton->get_bone_custom_pose(property.get_slicec('/', 1).to_int())); + undo_redo->add_do_method(skeleton, "set_bone_custom_pose", property.get_slicec('/', 1).to_int(), p_new_transform); + 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 ModuleBoneTransformEditor::update_enabled_checkbox() { @@ -330,9 +278,13 @@ void ModuleBoneTransformEditor::update_enabled_checkbox() { } void ModuleBoneTransformEditor::_bind_methods() { - ClassDB::bind_method(D_METHOD("_value_changed", "value"), &ModuleBoneTransformEditor::_value_changed); ClassDB::bind_method(D_METHOD("_key_button_pressed"), &ModuleBoneTransformEditor::_key_button_pressed); ClassDB::bind_method(D_METHOD("_checkbox_toggled", "toggled"), &ModuleBoneTransformEditor::_checkbox_toggled); + + ClassDB::bind_method(D_METHOD("_value_changed"), &ModuleBoneTransformEditor::_value_changed); + ClassDB::bind_method(D_METHOD("_value_changed_vector3"), &ModuleBoneTransformEditor::_value_changed_vector3); + ClassDB::bind_method(D_METHOD("_value_changed_transform"), &ModuleBoneTransformEditor::_value_changed_transform); + ClassDB::bind_method(D_METHOD("_change_transform"), &ModuleBoneTransformEditor::_change_transform); } void ModuleBoneTransformEditor::_update_properties() { @@ -368,47 +320,22 @@ void ModuleBoneTransformEditor::_update_custom_pose_properties() { } void ModuleBoneTransformEditor::_update_transform_properties(Transform tform) { - Quat rot = tform.get_basis().orthonormalized(); - Vector3 rot_rad = rot.get_euler(); - Vector3 rot_degrees = Vector3(Math::rad2deg(rot_rad.x), Math::rad2deg(rot_rad.y), Math::rad2deg(rot_rad.z)); - Vector3 tr = tform.get_origin(); + 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(); - for (int i = 0; i < TRANSLATION_COMPONENTS; i++) { - translation_slider[i]->set_value(tr[i]); - } - - for (int i = 0; i < ROTATION_DEGREES_COMPONENTS; i++) { - rotation_slider[i]->set_value(rot_degrees[i]); - } - - for (int i = 0; i < SCALE_COMPONENTS; i++) { - scale_slider[i]->set_value(scale[i]); - } - - transform_slider[0]->set_value(tform.get_basis()[Vector3::AXIS_X].x); - transform_slider[1]->set_value(tform.get_basis()[Vector3::AXIS_Y].x); - transform_slider[2]->set_value(tform.get_basis()[Vector3::AXIS_Z].x); - transform_slider[3]->set_value(tform.get_basis()[Vector3::AXIS_X].y); - transform_slider[4]->set_value(tform.get_basis()[Vector3::AXIS_Y].y); - transform_slider[5]->set_value(tform.get_basis()[Vector3::AXIS_Z].y); - transform_slider[6]->set_value(tform.get_basis()[Vector3::AXIS_X].z); - transform_slider[7]->set_value(tform.get_basis()[Vector3::AXIS_Y].z); - transform_slider[8]->set_value(tform.get_basis()[Vector3::AXIS_Z].z); - - for (int i = 0; i < TRANSLATION_COMPONENTS; i++) { - transform_slider[BASIS_COMPONENTS + i]->set_value(tform.get_origin()[i]); - } + 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; } ModuleBoneTransformEditor::ModuleBoneTransformEditor(Skeleton *p_skeleton) : - translation_slider(), - rotation_slider(), - scale_slider(), - transform_slider(), skeleton(p_skeleton), key_button(nullptr), enabled_checkbox(nullptr), @@ -447,7 +374,7 @@ void ModuleBoneTransformEditor::_key_button_pressed() { return; // Need to normalize the basis before you key it - Transform tform = compute_transform(true); + Transform tform = compute_transform_from_vector3s(); tform.orthonormalize(); AnimationPlayerEditor::singleton->get_track_editor()->insert_transform_key(skeleton, name, tform); } @@ -459,21 +386,6 @@ void ModuleBoneTransformEditor::_checkbox_toggled(const bool p_toggled) { } } -void ModuleBoneTransformEditor::set_read_only(const bool p_read_only) { - for (int i = 0; i < TRANSLATION_COMPONENTS; i++) { - translation_slider[i]->set_read_only(p_read_only); - } - for (int i = 0; i < ROTATION_DEGREES_COMPONENTS; i++) { - rotation_slider[i]->set_read_only(p_read_only); - } - for (int i = 0; i < SCALE_COMPONENTS; i++) { - scale_slider[i]->set_read_only(p_read_only); - } - for (int i = 0; i < TRANSFORM_COMPONENTS; i++) { - transform_slider[i]->set_read_only(p_read_only); - } -} - void ModuleSkeletonEditor::set_keyable(const bool p_keyable) { keyable = p_keyable; options->get_popup()->set_item_disabled(MENU_OPTION_INSERT_KEYS, !p_keyable); @@ -1067,12 +979,7 @@ void ModuleSkeletonEditor::set_rest_mode_toggled(const bool pressed) { for (int i = 0; i < bone_len; i++) { skeleton->set_bone_enabled(i, !rest_mode); } - if (pose_editor) { - pose_editor->set_read_only(rest_mode); - } - if (custom_pose_editor) { - custom_pose_editor->set_read_only(rest_mode); - } + set_keyable(AnimationPlayerEditor::singleton->get_track_editor()->has_keying() && !rest_mode); } diff --git a/modules/skeleton_editor/skeleton_editor_plugin.h b/modules/skeleton_editor/skeleton_editor_plugin.h index f101b4d87..4ff120eba 100644 --- a/modules/skeleton_editor/skeleton_editor_plugin.h +++ b/modules/skeleton_editor/skeleton_editor_plugin.h @@ -31,13 +31,13 @@ /*************************************************************************/ #include "core/os/input_event.h" +#include "editor/editor_inspector.h" #include "editor/editor_node.h" #include "editor/editor_plugin.h" #include "editor/plugins/spatial_editor_plugin.h" #include "scene/3d/camera.h" #include "scene/3d/mesh_instance.h" #include "scene/3d/skeleton.h" -#include "editor/editor_inspector.h" class ModuleEditorInspectorPluginSkeleton; class Joint; @@ -53,30 +53,19 @@ class Label; class PopupMenu; class CheckBox; class VSeparator; +class EditorPropertyTransform; +class EditorPropertyVector3; class ModuleBoneTransformEditor : public VBoxContainer { GDCLASS(ModuleBoneTransformEditor, VBoxContainer); - static const int32_t TRANSLATION_COMPONENTS = 3; - static const int32_t ROTATION_DEGREES_COMPONENTS = 3; - static const int32_t SCALE_COMPONENTS = 3; - static const int32_t BASIS_COMPONENTS = 9; - static const int32_t BASIS_SPLIT_COMPONENTS = 3; - static const int32_t TRANSFORM_COMPONENTS = 12; - static const int32_t TRANSFORM_SPLIT_COMPONENTS = 3; - static const int32_t TRANSFORM_CONTROL_COMPONENTS = 3; - EditorInspectorSection *section; - GridContainer *translation_grid; - GridContainer *rotation_grid; - GridContainer *scale_grid; - GridContainer *transform_grid; - - EditorSpinSlider *translation_slider[TRANSLATION_COMPONENTS]; - EditorSpinSlider *rotation_slider[ROTATION_DEGREES_COMPONENTS]; - EditorSpinSlider *scale_slider[SCALE_COMPONENTS]; - EditorSpinSlider *transform_slider[TRANSFORM_COMPONENTS]; + EditorPropertyVector3 *translation_property; + EditorPropertyVector3 *rotation_property; + EditorPropertyVector3 *scale_property; + EditorInspectorSection *transform_section; + EditorPropertyTransform *transform_property; Rect2 background_rects[5]; @@ -95,11 +84,17 @@ class ModuleBoneTransformEditor : public VBoxContainer { String label; void create_editors(); - void setup_spinner(EditorSpinSlider *spinner, const bool is_transform_spinner); - void _value_changed(const double p_value, const bool p_from_transform); - - Transform compute_transform(const bool p_from_transform) const; + // 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); + // Creates a Transform using the EditorPropertyVector3 properties. + Transform compute_transform_from_vector3s() const; void update_enabled_checkbox(); @@ -118,9 +113,6 @@ public: void _update_custom_pose_properties(); void _update_transform_properties(Transform p_transform); - // Can/cannot modify the spinner values for the Transform - void set_read_only(const bool p_read_only); - // Transform can be keyed, whether or not to show the button void set_keyable(const bool p_keyable); diff --git a/scene/3d/skeleton.cpp b/scene/3d/skeleton.cpp index 55235b9ee..908a3bfb7 100644 --- a/scene/3d/skeleton.cpp +++ b/scene/3d/skeleton.cpp @@ -92,6 +92,7 @@ bool Skeleton::_set(const StringName &p_path, const Variant &p_value) { set_bone_parent(which, p_value); } else if (what == "rest") { set_bone_rest(which, p_value); + } else if (what == "enabled") { set_bone_enabled(which, p_value); } else if (what == "position") { @@ -100,6 +101,8 @@ bool Skeleton::_set(const StringName &p_path, const Variant &p_value) { set_bone_pose_rotation(which, p_value); } else if (what == "scale") { set_bone_pose_scale(which, p_value); + } else if (what == "pose") { + set_bone_pose(which, p_value); } else if (what == "bound_children") { Array children = p_value; @@ -147,6 +150,8 @@ bool Skeleton::_get(const StringName &p_path, Variant &r_ret) const { r_ret = get_bone_pose_rotation(which); } else if (what == "scale") { r_ret = get_bone_pose_scale(which); + } else if (what == "pose") { + r_ret = get_bone_pose(which); } else if (what == "bound_children") { Array children;