|
@@ -49,276 +49,128 @@ void BoneTransformEditor::create_editors() {
|
|
|
|
|
|
section = memnew(EditorInspectorSection);
|
|
|
section->setup("trf_properties", label, this, section_color, true);
|
|
|
+ section->unfold();
|
|
|
add_child(section);
|
|
|
|
|
|
- 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", callable_mp(this, &BoneTransformEditor::_value_changed));
|
|
|
section->get_vbox()->add_child(enabled_checkbox);
|
|
|
|
|
|
- key_button = memnew(Button);
|
|
|
- key_button->set_text(TTR("Key Transform"));
|
|
|
- key_button->set_visible(keyable);
|
|
|
- key_button->set_icon(get_theme_icon(SNAME("Key"), SNAME("EditorIcons")));
|
|
|
- key_button->set_flat(true);
|
|
|
- section->get_vbox()->add_child(key_button);
|
|
|
-
|
|
|
- // 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->connect("property_changed", callable_mp(this, &BoneTransformEditor::_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", callable_mp(this, &BoneTransformEditor::_value_changed));
|
|
|
+ section->get_vbox()->add_child(position_property);
|
|
|
|
|
|
// Rotation property.
|
|
|
- rotation_property = memnew(EditorPropertyVector3());
|
|
|
+ rotation_property = memnew(EditorPropertyQuaternion());
|
|
|
rotation_property->setup(-10000, 10000, 0.001f, true);
|
|
|
- rotation_property->set_label("Rotation Degrees");
|
|
|
- rotation_property->set_use_folding(true);
|
|
|
- rotation_property->connect("property_changed", callable_mp(this, &BoneTransformEditor::_value_changed_vector3));
|
|
|
+ rotation_property->set_label("Rotation");
|
|
|
+ rotation_property->connect("property_changed", callable_mp(this, &BoneTransformEditor::_value_changed));
|
|
|
section->get_vbox()->add_child(rotation_property);
|
|
|
|
|
|
// 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->connect("property_changed", callable_mp(this, &BoneTransformEditor::_value_changed_vector3));
|
|
|
+ scale_property->connect("property_changed", callable_mp(this, &BoneTransformEditor::_value_changed));
|
|
|
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(EditorPropertyTransform3D());
|
|
|
- transform_property->setup(-10000, 10000, 0.001f, true);
|
|
|
- transform_property->set_label("Transform");
|
|
|
- transform_property->set_use_folding(true);
|
|
|
- transform_property->connect("property_changed", callable_mp(this, &BoneTransformEditor::_value_changed_transform));
|
|
|
- transform_section->get_vbox()->add_child(transform_property);
|
|
|
+ rest_matrix = memnew(EditorPropertyTransform3D());
|
|
|
+ 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", callable_mp(this, &BoneTransformEditor::_key_button_pressed));
|
|
|
- enabled_checkbox->connect("pressed", callable_mp(this, &BoneTransformEditor::_checkbox_pressed));
|
|
|
- [[fallthrough]];
|
|
|
- }
|
|
|
- case NOTIFICATION_SORT_CHILDREN: {
|
|
|
- const Ref<Font> font = get_theme_font(SNAME("font"), SNAME("Tree"));
|
|
|
- int font_size = get_theme_font_size(SNAME("font_size"), SNAME("Tree"));
|
|
|
-
|
|
|
- Point2 buffer;
|
|
|
- buffer.x += get_theme_constant(SNAME("inspector_margin"), SNAME("Editor"));
|
|
|
- buffer.y += font->get_height(font_size);
|
|
|
- buffer.y += get_theme_constant(SNAME("vseparation"), SNAME("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_theme_constant(SNAME("inspector_margin"), SNAME("Editor"));
|
|
|
- Vector<Rect2> 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_theme_color(SNAME("dark_color_2"), SNAME("Editor"));
|
|
|
-
|
|
|
- for (int i = 0; i < 5; ++i) {
|
|
|
- draw_rect(background_rects[i], dark_color);
|
|
|
- }
|
|
|
-
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-void BoneTransformEditor::_value_changed(const double p_value) {
|
|
|
- if (updating) {
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- Transform3D tform = compute_transform_from_vector3s();
|
|
|
- _change_transform(tform);
|
|
|
-}
|
|
|
-
|
|
|
-void BoneTransformEditor::_value_changed_vector3(const String p_property_name, const Vector3 p_vector, const StringName p_edited_property_name, const bool p_boolean) {
|
|
|
- if (updating) {
|
|
|
- return;
|
|
|
- }
|
|
|
- Transform3D tform = compute_transform_from_vector3s();
|
|
|
- _change_transform(tform);
|
|
|
-}
|
|
|
-
|
|
|
-Transform3D 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 Transform3D(
|
|
|
- Basis(prop_rotation, scale_property->get_vector()),
|
|
|
- translation_property->get_vector());
|
|
|
-}
|
|
|
-
|
|
|
-void BoneTransformEditor::_value_changed_transform(const String p_property_name, const Transform3D p_transform, const StringName p_edited_property_name, const bool p_boolean) {
|
|
|
+void BoneTransformEditor::_value_changed(const String &p_property, Variant p_value, const String &p_name, bool p_changing) {
|
|
|
if (updating) {
|
|
|
return;
|
|
|
}
|
|
|
- _change_transform(p_transform);
|
|
|
-}
|
|
|
-
|
|
|
-void BoneTransformEditor::_change_transform(Transform3D p_new_transform) {
|
|
|
- if (property.get_slicec('/', 0) == "bones") {
|
|
|
+ if (skeleton) {
|
|
|
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, p_new_transform);
|
|
|
+ undo_redo->add_undo_property(skeleton, p_property, skeleton->get(p_property));
|
|
|
+ undo_redo->add_do_property(skeleton, p_property, p_value);
|
|
|
undo_redo->commit_action();
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-void BoneTransformEditor::update_enabled_checkbox() {
|
|
|
- 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::_update_properties() {
|
|
|
- if (updating) {
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- if (!skeleton) {
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- updating = true;
|
|
|
-
|
|
|
- Transform3D tform = skeleton->get(property);
|
|
|
- _update_transform_properties(tform);
|
|
|
-}
|
|
|
-
|
|
|
-void BoneTransformEditor::_update_transform_properties(Transform3D 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(Skeleton3D *p_skeleton) :
|
|
|
skeleton(p_skeleton) {
|
|
|
undo_redo = EditorNode::get_undo_redo();
|
|
|
}
|
|
|
|
|
|
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();
|
|
|
|
|
|
-void BoneTransformEditor::set_keyable(const bool p_keyable) {
|
|
|
- keyable = p_keyable;
|
|
|
-}
|
|
|
+ position_property->set_object_and_property(skeleton, p_prop + "position");
|
|
|
+ position_property->update_property();
|
|
|
|
|
|
-void BoneTransformEditor::_update_key_button(const bool p_keyable) {
|
|
|
- bool is_keyable = keyable && p_keyable;
|
|
|
- if (key_button) {
|
|
|
- key_button->set_visible(is_keyable);
|
|
|
- }
|
|
|
-}
|
|
|
+ rotation_property->set_object_and_property(skeleton, p_prop + "rotation");
|
|
|
+ rotation_property->update_property();
|
|
|
|
|
|
-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) {
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- const BoneId bone_id = property.get_slicec('/', 1).to_int();
|
|
|
- const String name = skeleton->get_bone_name(bone_id);
|
|
|
-
|
|
|
- if (name.is_empty()) {
|
|
|
- return;
|
|
|
- }
|
|
|
+ scale_property->set_object_and_property(skeleton, p_prop + "scale");
|
|
|
+ scale_property->update_property();
|
|
|
|
|
|
- Transform3D tform = compute_transform_from_vector3s();
|
|
|
- AnimationPlayerEditor::get_singleton()->get_track_editor()->insert_transform_key(skeleton, name, tform);
|
|
|
+ rest_matrix->set_object_and_property(skeleton, p_prop + "rest");
|
|
|
+ rest_matrix->update_property();
|
|
|
}
|
|
|
|
|
|
-void BoneTransformEditor::_checkbox_pressed() {
|
|
|
+void BoneTransformEditor::_update_properties() {
|
|
|
if (!skeleton) {
|
|
|
return;
|
|
|
}
|
|
|
-
|
|
|
- const BoneId bone_id = property.get_slicec('/', 1).to_int();
|
|
|
- if (enabled_checkbox) {
|
|
|
- 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 = Skeleton3DEditor::get_singleton()->get_selected_bone();
|
|
|
+ List<PropertyInfo> 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();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -334,24 +186,6 @@ void Skeleton3DEditor::set_rest_options_enabled(const bool p_rest_options_enable
|
|
|
rest_options->get_popup()->set_item_disabled(REST_OPTION_POSE_TO_REST, !p_rest_options_enabled);
|
|
|
};
|
|
|
|
|
|
-void Skeleton3DEditor::_update_show_rest_only() {
|
|
|
- _update_pose_enabled(-1);
|
|
|
-}
|
|
|
-
|
|
|
-void Skeleton3DEditor::_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 Skeleton3DEditor::_on_click_skeleton_option(int p_skeleton_option) {
|
|
|
if (!skeleton) {
|
|
|
return;
|
|
@@ -398,8 +232,13 @@ void Skeleton3DEditor::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, Transform3D());
|
|
|
- ur->add_undo_method(skeleton, "set_bone_pose", i, skeleton->get_bone_pose(i));
|
|
|
+ Transform3D 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_quaternion());
|
|
|
+ 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();
|
|
|
}
|
|
@@ -439,13 +278,9 @@ void Skeleton3DEditor::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, Transform3D());
|
|
|
- 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();
|
|
|
}
|
|
|
|
|
@@ -630,18 +465,14 @@ void Skeleton3DEditor::_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();
|
|
|
}
|
|
|
|
|
|
// May be not used with single select mode.
|
|
@@ -649,13 +480,10 @@ void Skeleton3DEditor::_joint_tree_rmb_select(const Vector2 &p_pos) {
|
|
|
}
|
|
|
|
|
|
void Skeleton3DEditor::_update_properties() {
|
|
|
- if (rest_editor) {
|
|
|
- rest_editor->_update_properties();
|
|
|
- }
|
|
|
if (pose_editor) {
|
|
|
pose_editor->_update_properties();
|
|
|
}
|
|
|
- _update_gizmo_transform();
|
|
|
+ Node3DEditor::get_singleton()->update_transform_gizmo();
|
|
|
}
|
|
|
|
|
|
void Skeleton3DEditor::update_joint_tree() {
|
|
@@ -782,17 +610,9 @@ void Skeleton3DEditor::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 Skeleton3DEditor::_notification(int p_what) {
|
|
@@ -811,8 +631,8 @@ void Skeleton3DEditor::_notification(int p_what) {
|
|
|
#ifdef TOOLS_ENABLED
|
|
|
skeleton->connect("pose_updated", callable_mp(this, &Skeleton3DEditor::_draw_gizmo));
|
|
|
skeleton->connect("pose_updated", callable_mp(this, &Skeleton3DEditor::_update_properties));
|
|
|
- skeleton->connect("bone_enabled_changed", callable_mp(this, &Skeleton3DEditor::_update_pose_enabled));
|
|
|
- skeleton->connect("show_rest_only_changed", callable_mp(this, &Skeleton3DEditor::_update_show_rest_only));
|
|
|
+ skeleton->connect("bone_enabled_changed", callable_mp(this, &Skeleton3DEditor::_bone_enabled_changed));
|
|
|
+ skeleton->connect("show_rest_only_changed", callable_mp(this, &Skeleton3DEditor::_update_gizmo_visible));
|
|
|
#endif
|
|
|
break;
|
|
|
}
|
|
@@ -833,8 +653,6 @@ void Skeleton3DEditor::_bind_methods() {
|
|
|
ClassDB::bind_method(D_METHOD("_node_removed"), &Skeleton3DEditor::_node_removed);
|
|
|
ClassDB::bind_method(D_METHOD("_joint_tree_selection_changed"), &Skeleton3DEditor::_joint_tree_selection_changed);
|
|
|
ClassDB::bind_method(D_METHOD("_joint_tree_rmb_select"), &Skeleton3DEditor::_joint_tree_rmb_select);
|
|
|
- ClassDB::bind_method(D_METHOD("_update_show_rest_only"), &Skeleton3DEditor::_update_show_rest_only);
|
|
|
- ClassDB::bind_method(D_METHOD("_update_pose_enabled"), &Skeleton3DEditor::_update_pose_enabled);
|
|
|
ClassDB::bind_method(D_METHOD("_update_properties"), &Skeleton3DEditor::_update_properties);
|
|
|
ClassDB::bind_method(D_METHOD("_on_click_skeleton_option"), &Skeleton3DEditor::_on_click_skeleton_option);
|
|
|
ClassDB::bind_method(D_METHOD("_on_click_rest_option"), &Skeleton3DEditor::_on_click_rest_option);
|
|
@@ -905,7 +723,9 @@ void Skeleton3DEditor::update_bone_original() {
|
|
|
if (skeleton->get_bone_count() == 0 || selected_bone == -1) {
|
|
|
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 Skeleton3DEditor::_hide_handles() {
|
|
@@ -1033,8 +853,8 @@ void Skeleton3DEditor::select_bone(int p_idx) {
|
|
|
Skeleton3DEditor::~Skeleton3DEditor() {
|
|
|
if (skeleton) {
|
|
|
#ifdef TOOLS_ENABLED
|
|
|
- skeleton->disconnect("show_rest_only_changed", callable_mp(this, &Skeleton3DEditor::_update_show_rest_only));
|
|
|
- skeleton->disconnect("bone_enabled_changed", callable_mp(this, &Skeleton3DEditor::_update_pose_enabled));
|
|
|
+ skeleton->disconnect("show_rest_only_changed", callable_mp(this, &Skeleton3DEditor::_update_gizmo_visible));
|
|
|
+ skeleton->disconnect("bone_enabled_changed", callable_mp(this, &Skeleton3DEditor::_bone_enabled_changed));
|
|
|
skeleton->disconnect("pose_updated", callable_mp(this, &Skeleton3DEditor::_draw_gizmo));
|
|
|
skeleton->disconnect("pose_updated", callable_mp(this, &Skeleton3DEditor::_update_properties));
|
|
|
skeleton->set_transform_gizmo_visible(true);
|
|
@@ -1115,9 +935,9 @@ bool Skeleton3DEditorPlugin::handles(Object *p_object) const {
|
|
|
return p_object->is_class("Skeleton3D");
|
|
|
}
|
|
|
|
|
|
-void Skeleton3DEditor::_update_gizmo_transform() {
|
|
|
- Node3DEditor::get_singleton()->update_transform_gizmo();
|
|
|
-};
|
|
|
+void Skeleton3DEditor::_bone_enabled_changed(const int p_bone_id) {
|
|
|
+ _update_gizmo_visible();
|
|
|
+}
|
|
|
|
|
|
void Skeleton3DEditor::_update_gizmo_visible() {
|
|
|
_subgizmo_selection_change();
|
|
@@ -1272,7 +1092,7 @@ void Skeleton3DGizmoPlugin::set_subgizmo_transform(const EditorNode3DGizmo *p_gi
|
|
|
|
|
|
// Apply transform.
|
|
|
skeleton->set_bone_pose_position(p_id, t.origin);
|
|
|
- skeleton->set_bone_pose_rotation(p_id, t.basis.operator Quaternion());
|
|
|
+ skeleton->set_bone_pose_rotation(p_id, t.basis.get_rotation_quaternion());
|
|
|
skeleton->set_bone_pose_scale(p_id, t.basis.get_scale());
|
|
|
}
|
|
|
|
|
@@ -1281,12 +1101,30 @@ void Skeleton3DGizmoPlugin::commit_subgizmos(const EditorNode3DGizmo *p_gizmo, c
|
|
|
ERR_FAIL_COND(!skeleton);
|
|
|
|
|
|
Skeleton3DEditor *se = Skeleton3DEditor::get_singleton();
|
|
|
+ Node3DEditor *ne = Node3DEditor::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() == Node3DEditor::TOOL_MODE_SELECT || ne->get_tool_mode() == Node3DEditor::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() == Node3DEditor::TOOL_MODE_SELECT || ne->get_tool_mode() == Node3DEditor::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() == Node3DEditor::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();
|
|
|
}
|