From 56bca6b04fb660b5949cfd15ff8c018fe62e3d30 Mon Sep 17 00:00:00 2001 From: TwistedTwigleg Date: Wed, 22 Jul 2020 17:47:12 -0400 Subject: [PATCH] Changes: * Rewriting the Bone2D CanvasItemEditor gizmo thing: Now the Bone2D node handles drawing its own gizmo! * This change was needed so the gizmo is in the correct position when modifications are executing. This would be theoretically doable via the CanvasItemEditor, but the code would be messy and despite my best efforts (even with messy code), I couldn't get it working and it would have had to be more a workaround than a proper solution. * Now the Bone2D gizmo correctly positions itself, even when IK modifications are enabled. * The Bone2D gizmo changes to the Bone2D IK color in the editor settings when modifications are enabled. * The Bone2D gizmo now rotates to align with the custom bone angles, removing the need for using a Bone2D node just to have the Bone2D gizmo looking correct when the Polygon2D doesn't line up with a rotation of 0. * The shape is exactly the same as the previous gizmo and renders exactly the same. It stays the same size regardless of the scale and rotation of the Bone2D node. * The only loss of functionality is that the Bone2D gizmo no longer resizes as the editor is zoomed in and out, and it is no longer drawn with anti-alising. * This code is only executed in the editor, leading to no performance loss in exported games. * The Bone2D editor setting colors have been made slightly more transparent, so they are easier to work with. * The CanvasItemEditor now exposes the editor_selection variable, as otherwise there is no good way for the Bone2D to know if its been selected. * The code for drawing the Bone2D gizmo has been disabled in CanvasItemEditor, but not removed. * I plan to remove the Bone2D gizmo code (and the IK code) from the CanvasItemEditor in a future commit. * Fixed clang format issues --- editor/editor_settings.cpp | 10 +- editor/plugins/canvas_item_editor_plugin.cpp | 6 +- editor/plugins/canvas_item_editor_plugin.h | 4 +- scene/2d/skeleton_2d.cpp | 171 +++++++++++++++++++ scene/2d/skeleton_2d.h | 5 + scene/resources/skeleton_modification_2d.cpp | 2 +- 6 files changed, 188 insertions(+), 10 deletions(-) diff --git a/editor/editor_settings.cpp b/editor/editor_settings.cpp index 5f293f1fb3d3..c599dc45ca32 100644 --- a/editor/editor_settings.cpp +++ b/editor/editor_settings.cpp @@ -588,11 +588,11 @@ void EditorSettings::_load_defaults(Ref p_extra_config) { _initial_set("editors/2d/guides_color", Color(0.6, 0.0, 0.8)); _initial_set("editors/2d/smart_snapping_line_color", Color(0.9, 0.1, 0.1)); _initial_set("editors/2d/bone_width", 5); - _initial_set("editors/2d/bone_color1", Color(1.0, 1.0, 1.0, 0.9)); - _initial_set("editors/2d/bone_color2", Color(0.6, 0.6, 0.6, 0.9)); - _initial_set("editors/2d/bone_selected_color", Color(0.9, 0.45, 0.45, 0.9)); - _initial_set("editors/2d/bone_ik_color", Color(0.9, 0.9, 0.45, 0.9)); - _initial_set("editors/2d/bone_outline_color", Color(0.35, 0.35, 0.35)); + _initial_set("editors/2d/bone_color1", Color(1.0, 1.0, 1.0, 0.7)); + _initial_set("editors/2d/bone_color2", Color(0.6, 0.6, 0.6, 0.7)); + _initial_set("editors/2d/bone_selected_color", Color(0.9, 0.45, 0.45, 0.7)); + _initial_set("editors/2d/bone_ik_color", Color(0.9, 0.9, 0.45, 0.7)); + _initial_set("editors/2d/bone_outline_color", Color(0.35, 0.35, 0.35, 0.5)); _initial_set("editors/2d/bone_outline_size", 2); _initial_set("editors/2d/viewport_border_color", Color(0.4, 0.4, 1.0, 0.4)); _initial_set("editors/2d/constrain_editor_view", true); diff --git a/editor/plugins/canvas_item_editor_plugin.cpp b/editor/plugins/canvas_item_editor_plugin.cpp index 058f29a780ad..bd60d4fb1611 100644 --- a/editor/plugins/canvas_item_editor_plugin.cpp +++ b/editor/plugins/canvas_item_editor_plugin.cpp @@ -3511,7 +3511,7 @@ void CanvasItemEditor::_draw_axis() { } void CanvasItemEditor::_draw_bones() { - RID ci = viewport->get_canvas_item(); + //RID ci = viewport->get_canvas_item(); if (skeleton_show_bones) { Color bone_color1 = EditorSettings::get_singleton()->get("editors/2d/bone_color1"); @@ -3568,8 +3568,8 @@ void CanvasItemEditor::_draw_bones() { outline_colors.push_back(bone_outline_color); } - RenderingServer::get_singleton()->canvas_item_add_polygon(ci, bone_shape_outline, outline_colors); - RenderingServer::get_singleton()->canvas_item_add_primitive(ci, bone_shape, colors, Vector(), RID()); + //RenderingServer::get_singleton()->canvas_item_add_polygon(ci, bone_shape_outline, outline_colors); + //RenderingServer::get_singleton()->canvas_item_add_primitive(ci, bone_shape, colors, Vector(), RID()); } } } diff --git a/editor/plugins/canvas_item_editor_plugin.h b/editor/plugins/canvas_item_editor_plugin.h index c5d74c6fc915..458cb54a5e48 100644 --- a/editor/plugins/canvas_item_editor_plugin.h +++ b/editor/plugins/canvas_item_editor_plugin.h @@ -79,6 +79,8 @@ class CanvasItemEditor : public VBoxContainer { TOOL_MAX }; + EditorSelection *editor_selection; + private: EditorNode *editor; @@ -217,7 +219,7 @@ class CanvasItemEditor : public VBoxContainer { DRAG_KEY_MOVE }; - EditorSelection *editor_selection; + //EditorSelection *editor_selection; bool selection_menu_additive_selection; Tool tool; diff --git a/scene/2d/skeleton_2d.cpp b/scene/2d/skeleton_2d.cpp index 95379cb633a2..64e2daf350df 100644 --- a/scene/2d/skeleton_2d.cpp +++ b/scene/2d/skeleton_2d.cpp @@ -31,6 +31,11 @@ #include "skeleton_2d.h" #include "scene/resources/skeleton_modification_2d.h" +#ifdef TOOLS_ENABLED +#include "editor/editor_settings.h" +#include "editor/plugins/canvas_item_editor_plugin.h" +#endif //TOOLS_ENABLED + bool Bone2D::_set(const StringName &p_path, const Variant &p_value) { String path = p_path; @@ -88,10 +93,18 @@ void Bone2D::_notification(int p_what) { skeleton->bones.push_back(bone); skeleton->_make_bone_setup_dirty(); } + +#ifdef TOOLS_ENABLED + update(); +#endif // TOOLS_ENABLED } if (p_what == NOTIFICATION_LOCAL_TRANSFORM_CHANGED) { if (skeleton) { skeleton->_make_transform_dirty(); + +#ifdef TOOLS_ENABLED + update(); +#endif // TOOLS_ENABLED } } if (p_what == NOTIFICATION_MOVED_IN_PARENT) { @@ -119,7 +132,165 @@ void Bone2D::_notification(int p_what) { calculate_length_and_rotation(); } } + +#ifdef TOOLS_ENABLED + // Bone2D Editor gizmo drawing: + if (p_what == NOTIFICATION_DRAW) { + if (editor_gizmo_rid.is_null()) { + editor_gizmo_rid = RenderingServer::get_singleton()->canvas_item_create(); + RenderingServer::get_singleton()->canvas_item_set_parent(editor_gizmo_rid, get_canvas_item()); + RenderingServer::get_singleton()->canvas_item_set_z_as_relative_to_parent(editor_gizmo_rid, true); + RenderingServer::get_singleton()->canvas_item_set_z_index(editor_gizmo_rid, 10); + } + RenderingServer::get_singleton()->canvas_item_clear(editor_gizmo_rid); + // Undo scaling + Transform2D editor_gizmo_trans = Transform2D(); + editor_gizmo_trans.set_scale(Vector2(1, 1) / get_global_scale()); + RenderingServer::get_singleton()->canvas_item_set_transform(editor_gizmo_rid, editor_gizmo_trans); + + Color bone_color1 = EditorSettings::get_singleton()->get("editors/2d/bone_color1"); + Color bone_color2 = EditorSettings::get_singleton()->get("editors/2d/bone_color2"); + Color bone_ik_color = EditorSettings::get_singleton()->get("editors/2d/bone_ik_color"); + Color bone_outline_color = EditorSettings::get_singleton()->get("editors/2d/bone_outline_color"); + Color bone_selected_color = EditorSettings::get_singleton()->get("editors/2d/bone_selected_color"); + + bool Bone2D_found = false; + for (int i = 0; i < get_child_count(); i++) { + Bone2D *child_node = nullptr; + child_node = Object::cast_to(get_child(i)); + if (!child_node) { + continue; + } + Bone2D_found = true; + + Vector bone_shape; + Vector bone_shape_outline; + + _editor_get_bone_shape(&bone_shape, &bone_shape_outline, child_node); + + Vector colors; + if (has_meta("_local_pose_override_enabled_")) { + colors.push_back(bone_ik_color); + colors.push_back(bone_ik_color); + colors.push_back(bone_ik_color); + colors.push_back(bone_ik_color); + } else { + colors.push_back(bone_color1); + colors.push_back(bone_color2); + colors.push_back(bone_color1); + colors.push_back(bone_color2); + } + + Vector outline_colors; + if (CanvasItemEditor::get_singleton()->editor_selection->is_selected(this)) { + outline_colors.push_back(bone_selected_color); + outline_colors.push_back(bone_selected_color); + outline_colors.push_back(bone_selected_color); + outline_colors.push_back(bone_selected_color); + outline_colors.push_back(bone_selected_color); + outline_colors.push_back(bone_selected_color); + } else { + outline_colors.push_back(bone_outline_color); + outline_colors.push_back(bone_outline_color); + outline_colors.push_back(bone_outline_color); + outline_colors.push_back(bone_outline_color); + outline_colors.push_back(bone_outline_color); + outline_colors.push_back(bone_outline_color); + } + + RenderingServer::get_singleton()->canvas_item_add_polygon(editor_gizmo_rid, bone_shape_outline, outline_colors); + RenderingServer::get_singleton()->canvas_item_add_polygon(editor_gizmo_rid, bone_shape, colors); + } + + if (!Bone2D_found) { + Vector bone_shape; + Vector bone_shape_outline; + + _editor_get_bone_shape(&bone_shape, &bone_shape_outline, nullptr); + + Vector colors; + if (has_meta("_local_pose_override_enabled_")) { + colors.push_back(bone_ik_color); + colors.push_back(bone_ik_color); + colors.push_back(bone_ik_color); + colors.push_back(bone_ik_color); + } else { + colors.push_back(bone_color1); + colors.push_back(bone_color2); + colors.push_back(bone_color1); + colors.push_back(bone_color2); + } + + Vector outline_colors; + if (CanvasItemEditor::get_singleton()->editor_selection->is_selected(this)) { + outline_colors.push_back(bone_selected_color); + outline_colors.push_back(bone_selected_color); + outline_colors.push_back(bone_selected_color); + outline_colors.push_back(bone_selected_color); + outline_colors.push_back(bone_selected_color); + outline_colors.push_back(bone_selected_color); + } else { + outline_colors.push_back(bone_outline_color); + outline_colors.push_back(bone_outline_color); + outline_colors.push_back(bone_outline_color); + outline_colors.push_back(bone_outline_color); + outline_colors.push_back(bone_outline_color); + outline_colors.push_back(bone_outline_color); + } + + RenderingServer::get_singleton()->canvas_item_add_polygon(editor_gizmo_rid, bone_shape_outline, outline_colors); + RenderingServer::get_singleton()->canvas_item_add_polygon(editor_gizmo_rid, bone_shape, colors); + } + } +#endif // TOOLS_ENALBED +} + +#ifdef TOOLS_ENABLED +bool Bone2D::_editor_get_bone_shape(Vector *shape, Vector *outline_shape, Bone2D *other_bone) { + int bone_width = EditorSettings::get_singleton()->get("editors/2d/bone_width"); + int bone_outline_width = EditorSettings::get_singleton()->get("editors/2d/bone_outline_size"); + + if (!is_inside_tree()) { + return false; //may have been removed + } + if (!other_bone && length <= 0) { + return false; + } + + Vector2 rel; + if (other_bone) { + rel = (other_bone->get_global_transform().get_origin() - get_global_transform().get_origin()); + } else { + float angle_to_use = get_rotation() + bone_angle; + rel = Vector2(cos(angle_to_use), sin(angle_to_use)) * length; + } + + rel = rel.rotated(-get_rotation()); + + Vector2 relt = rel.tangent().normalized() * bone_width; + Vector2 reln = rel.normalized(); + Vector2 reltn = relt.normalized(); + + if (shape) { + shape->clear(); + shape->push_back(Vector2(0, 0)); + shape->push_back(rel * 0.2 + relt); + shape->push_back(rel); + shape->push_back(rel * 0.2 - relt); + } + + if (outline_shape) { + outline_shape->clear(); + outline_shape->push_back((-reln - reltn) * bone_outline_width); + outline_shape->push_back((-reln + reltn) * bone_outline_width); + outline_shape->push_back(rel * 0.2 + relt + reltn * bone_outline_width); + outline_shape->push_back(rel + (reln + reltn) * bone_outline_width); + outline_shape->push_back(rel + (reln - reltn) * bone_outline_width); + outline_shape->push_back(rel * 0.2 - relt - reltn * bone_outline_width); + } + return true; } +#endif // TOOLS_ENABLED void Bone2D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_rest", "rest"), &Bone2D::set_rest); diff --git a/scene/2d/skeleton_2d.h b/scene/2d/skeleton_2d.h index fe00bb692639..d7deb617ef73 100644 --- a/scene/2d/skeleton_2d.h +++ b/scene/2d/skeleton_2d.h @@ -56,6 +56,11 @@ class Bone2D : public Node2D { void calculate_length_and_rotation(); +#ifdef TOOLS_ENABLED + RID editor_gizmo_rid; + bool _editor_get_bone_shape(Vector *shape, Vector *outline_shape, Bone2D *other_bone); +#endif // TOOLS_ENABLED + protected: void _notification(int p_what); static void _bind_methods(); diff --git a/scene/resources/skeleton_modification_2d.cpp b/scene/resources/skeleton_modification_2d.cpp index f4ee6b173ffe..20829c5e9f92 100644 --- a/scene/resources/skeleton_modification_2d.cpp +++ b/scene/resources/skeleton_modification_2d.cpp @@ -2203,7 +2203,7 @@ void SkeletonModification2DTwoBoneIK::execute(float delta) { if (!override_angles_due_to_out_of_range) { float angle_0 = Math::acos(((joint_one_to_target * joint_one_to_target) + (bone_one_length * bone_one_length) - (bone_two_length * bone_two_length)) / (2.0 * joint_one_to_target * bone_one_length)); float angle_1 = Math::acos(((bone_two_length * bone_two_length) + (bone_one_length * bone_one_length) - (joint_one_to_target * joint_one_to_target)) / (2.0 * bone_two_length * bone_one_length)); - + if (flip_bend_direction) { angle_0 = -angle_0; angle_1 = -angle_1;