diff options
author | Juan Linietsky <reduzio@gmail.com> | 2018-05-04 16:46:32 -0300 |
---|---|---|
committer | Juan Linietsky <reduzio@gmail.com> | 2018-05-04 16:46:32 -0300 |
commit | bf561c49468c9a4d5c47ba7bc53204a51270855f (patch) | |
tree | a389de4158322cb6a20fab46ab9147bb20a062d3 | |
parent | e68cbec1fa76ea082671682dcc309d47cf812e7a (diff) |
Made bone handling for actual Bone2D a special case. Make custom bones appear like a custom (less important) option now.
-rw-r--r-- | editor/icons/icon_bone_2_d.svg | 61 | ||||
-rw-r--r-- | editor/plugins/canvas_item_editor_plugin.cpp | 122 | ||||
-rw-r--r-- | editor/plugins/canvas_item_editor_plugin.h | 20 | ||||
-rw-r--r-- | scene/2d/skeleton_2d.cpp | 15 | ||||
-rw-r--r-- | scene/2d/skeleton_2d.h | 4 |
5 files changed, 186 insertions, 36 deletions
diff --git a/editor/icons/icon_bone_2_d.svg b/editor/icons/icon_bone_2_d.svg new file mode 100644 index 0000000000..efcbc17e13 --- /dev/null +++ b/editor/icons/icon_bone_2_d.svg @@ -0,0 +1,61 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + width="16" + height="16" + version="1.1" + viewBox="0 0 16 16" + id="svg6" + sodipodi:docname="icon_bone_2d.svg" + inkscape:version="0.92.3 (2405546, 2018-03-11)"> + <metadata + id="metadata12"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + <dc:title></dc:title> + </cc:Work> + </rdf:RDF> + </metadata> + <defs + id="defs10" /> + <sodipodi:namedview + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1" + objecttolerance="10" + gridtolerance="10" + guidetolerance="10" + inkscape:pageopacity="0" + inkscape:pageshadow="2" + inkscape:window-width="836" + inkscape:window-height="480" + id="namedview8" + showgrid="false" + inkscape:zoom="14.75" + inkscape:cx="8" + inkscape:cy="8" + inkscape:window-x="67" + inkscape:window-y="27" + inkscape:window-maximized="0" + inkscape:current-layer="svg6" /> + <g + transform="translate(0 -1036.4)" + id="g4" + style="fill:#a5b7f3;fill-opacity:1"> + <path + d="m10.478 1037.4a2.4664 2.4663 0 0 0 -1.7804 0.7205 2.4664 2.4663 0 0 0 -0.31408 3.1041l-3.559 3.5608a2.4664 2.4663 0 0 0 -3.1023 0.3121 2.4664 2.4663 0 0 0 0 3.4876 2.4664 2.4663 0 0 0 1.397 0.6955 2.4664 2.4663 0 0 0 0.69561 1.397 2.4664 2.4663 0 0 0 3.4877 0 2.4664 2.4663 0 0 0 0.31408 -3.1041l3.5609-3.5608a2.4664 2.4663 0 0 0 3.1004 -0.3102 2.4664 2.4663 0 0 0 0 -3.4875 2.4664 2.4663 0 0 0 -1.397 -0.6974 2.4664 2.4663 0 0 0 -0.69561 -1.3971 2.4664 2.4663 0 0 0 -1.7072 -0.7205z" + fill="#fc9c9c" + id="path2" + style="fill:#a5b7f3;fill-opacity:1" /> + </g> +</svg> diff --git a/editor/plugins/canvas_item_editor_plugin.cpp b/editor/plugins/canvas_item_editor_plugin.cpp index 58398c9515..8bbedfbc1e 100644 --- a/editor/plugins/canvas_item_editor_plugin.cpp +++ b/editor/plugins/canvas_item_editor_plugin.cpp @@ -44,6 +44,7 @@ #include "scene/2d/particles_2d.h" #include "scene/2d/polygon_2d.h" #include "scene/2d/screen_button.h" +#include "scene/2d/skeleton_2d.h" #include "scene/2d/sprite.h" #include "scene/gui/grid_container.h" #include "scene/gui/nine_patch_rect.h" @@ -2590,27 +2591,27 @@ void CanvasItemEditor::_draw_bones() { Color bone_selected_color = EditorSettings::get_singleton()->get("editors/2d/bone_selected_color"); int bone_outline_size = EditorSettings::get_singleton()->get("editors/2d/bone_outline_size"); - for (Map<ObjectID, BoneList>::Element *E = bone_list.front(); E; E = E->next()) { + for (Map<BoneKey, BoneList>::Element *E = bone_list.front(); E; E = E->next()) { E->get().from = Vector2(); E->get().to = Vector2(); - Node2D *n2d = Object::cast_to<Node2D>(ObjectDB::get_instance(E->key())); - if (!n2d) - continue; + Node2D *from_node = Object::cast_to<Node2D>(ObjectDB::get_instance(E->key().from)); + Node2D *to_node = Object::cast_to<Node2D>(ObjectDB::get_instance(E->key().to)); - if (!n2d->get_parent()) + if (!from_node) continue; - CanvasItem *pi = n2d->get_parent_item(); - - Node2D *pn2d = Object::cast_to<Node2D>(n2d->get_parent()); - - if (!pn2d) + if (!to_node && E->get().length == 0) continue; - Vector2 from = transform.xform(pn2d->get_global_position()); - Vector2 to = transform.xform(n2d->get_global_position()); + Vector2 from = transform.xform(from_node->get_global_position()); + Vector2 to; + + if (to_node) + to = transform.xform(to_node->get_global_position()); + else + to = transform.xform(from_node->get_global_transform().xform(Vector2(E->get().length, 0))); E->get().from = from; E->get().to = to; @@ -2635,7 +2636,7 @@ void CanvasItemEditor::_draw_bones() { bone_shape_outline.push_back(from + rel * 0.2 - relt - reltn * bone_outline_size); Vector<Color> colors; - if (pi->has_meta("_edit_ik_")) { + if (from_node->has_meta("_edit_ik_")) { colors.push_back(bone_ik_color); colors.push_back(bone_ik_color); @@ -2649,7 +2650,8 @@ void CanvasItemEditor::_draw_bones() { } Vector<Color> outline_colors; - if (editor_selection->is_selected(pi)) { + + if (editor_selection->is_selected(from_node)) { outline_colors.push_back(bone_selected_color); outline_colors.push_back(bone_selected_color); outline_colors.push_back(bone_selected_color); @@ -2790,26 +2792,71 @@ void CanvasItemEditor::_draw_locks_and_groups(Node *p_node, const Transform2D &p } } -void CanvasItemEditor::_build_bones_list(Node *p_node) { - ERR_FAIL_COND(!p_node); +bool CanvasItemEditor::_build_bones_list(Node *p_node) { + ERR_FAIL_COND_V(!p_node, false); + + bool has_child_bones = false; for (int i = 0; i < p_node->get_child_count(); i++) { - _build_bones_list(p_node->get_child(i)); + if (_build_bones_list(p_node->get_child(i))) { + has_child_bones = true; + } } CanvasItem *c = Object::cast_to<CanvasItem>(p_node); - if (c && c->is_visible_in_tree()) { - if (c->has_meta("_edit_bone_")) { + if (!c) + return false; + + CanvasItem *p = c->get_parent_item(); + if (!p) + return false; + + if (!p->is_visible()) + return false; + + if (Object::cast_to<Bone2D>(c)) { + + if (Object::cast_to<Bone2D>(p)) { + BoneKey bk; + bk.from = p->get_instance_id(); + bk.to = c->get_instance_id(); + if (!bone_list.has(bk)) { + BoneList b; + b.length = 0; + bone_list[bk] = b; + } + + bone_list[bk].last_pass = bone_last_frame; + } - ObjectID id = c->get_instance_id(); - if (!bone_list.has(id)) { - BoneList bone; - bone_list[id] = bone; + if (!has_child_bones) { + BoneKey bk; + bk.from = c->get_instance_id(); + bk.to = 0; + if (!bone_list.has(bk)) { + BoneList b; + b.length = 0; + bone_list[bk] = b; } + bone_list[bk].last_pass = bone_last_frame; + } - bone_list[id].last_pass = bone_last_frame; + return true; + } + if (c->has_meta("_edit_bone_")) { + + BoneKey bk; + bk.from = c->get_parent()->get_instance_id(); + bk.to = c->get_instance_id(); + if (!bone_list.has(bk)) { + BoneList b; + b.length = 0; + bone_list[bk] = b; } + bone_list[bk].last_pass = bone_last_frame; } + + return false; } void CanvasItemEditor::_draw_viewport() { @@ -2936,9 +2983,9 @@ void CanvasItemEditor::_notification(int p_what) { // Show / Hide the layout button presets_menu->set_visible(nb_control > 0 && nb_control == selection.size()); - for (Map<ObjectID, BoneList>::Element *E = bone_list.front(); E; E = E->next()) { + for (Map<BoneKey, BoneList>::Element *E = bone_list.front(); E; E = E->next()) { - Object *b = ObjectDB::get_instance(E->key()); + Object *b = ObjectDB::get_instance(E->key().from); if (!b) { viewport->update(); @@ -2950,9 +2997,18 @@ void CanvasItemEditor::_notification(int p_what) { continue; } - if (b2->get_global_transform() != E->get().xform) { + Transform2D global_xform = b2->get_global_transform(); + + if (global_xform != E->get().xform) { + + E->get().xform = global_xform; + viewport->update(); + } + + Bone2D *bone = Object::cast_to<Bone2D>(b); + if (bone && bone->get_default_length() != E->get().length) { - E->get().xform = b2->get_global_transform(); + E->get().length = bone->get_default_length(); viewport->update(); } } @@ -3088,8 +3144,8 @@ void CanvasItemEditor::_update_scrollbars() { _build_bones_list(editor->get_edited_scene()); } - List<Map<ObjectID, BoneList>::Element *> bone_to_erase; - for (Map<ObjectID, BoneList>::Element *E = bone_list.front(); E; E = E->next()) { + List<Map<BoneKey, BoneList>::Element *> bone_to_erase; + for (Map<BoneKey, BoneList>::Element *E = bone_list.front(); E; E = E->next()) { if (E->get().last_pass != bone_last_frame) { bone_to_erase.push_back(E); } @@ -4248,13 +4304,13 @@ CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) { p = skeleton_menu->get_popup(); p->set_hide_on_checkable_item_selection(false); - p->add_shortcut(ED_SHORTCUT("canvas_item_editor/skeleton_make_bones", TTR("Make Bones"), KEY_MASK_CMD | KEY_MASK_SHIFT | KEY_B), SKELETON_MAKE_BONES); - p->add_shortcut(ED_SHORTCUT("canvas_item_editor/skeleton_clear_bones", TTR("Clear Bones")), SKELETON_CLEAR_BONES); - p->add_separator(); p->add_check_shortcut(ED_SHORTCUT("canvas_item_editor/skeleton_show_bones", TTR("Show Bones")), SKELETON_SHOW_BONES); p->add_separator(); p->add_shortcut(ED_SHORTCUT("canvas_item_editor/skeleton_set_ik_chain", TTR("Make IK Chain")), SKELETON_SET_IK_CHAIN); p->add_shortcut(ED_SHORTCUT("canvas_item_editor/skeleton_clear_ik_chain", TTR("Clear IK Chain")), SKELETON_CLEAR_IK_CHAIN); + p->add_separator(); + p->add_shortcut(ED_SHORTCUT("canvas_item_editor/skeleton_make_bones", TTR("Make Custom Bone(s) from Node(s)"), KEY_MASK_CMD | KEY_MASK_SHIFT | KEY_B), SKELETON_MAKE_BONES); + p->add_shortcut(ED_SHORTCUT("canvas_item_editor/skeleton_clear_bones", TTR("Clear Custom Bones")), SKELETON_CLEAR_BONES); p->connect("id_pressed", this, "_popup_callback"); hb->add_child(memnew(VSeparator)); diff --git a/editor/plugins/canvas_item_editor_plugin.h b/editor/plugins/canvas_item_editor_plugin.h index 373a4b799e..a1ffdd1fbd 100644 --- a/editor/plugins/canvas_item_editor_plugin.h +++ b/editor/plugins/canvas_item_editor_plugin.h @@ -264,12 +264,26 @@ class CanvasItemEditor : public VBoxContainer { struct BoneList { Transform2D xform; + float length; + uint64_t last_pass; Vector2 from; Vector2 to; - uint64_t last_pass; }; + uint64_t bone_last_frame; - Map<ObjectID, BoneList> bone_list; + + struct BoneKey { + ObjectID from; + ObjectID to; + _FORCE_INLINE_ bool operator<(const BoneKey &p_key) const { + if (from == p_key.from) + return to < p_key.to; + else + return from < p_key.from; + } + }; + + Map<BoneKey, BoneList> bone_list; struct PoseClipboard { Vector2 pos; @@ -366,7 +380,7 @@ class CanvasItemEditor : public VBoxContainer { void _selection_menu_hide(); UndoRedo *undo_redo; - void _build_bones_list(Node *p_node); + bool _build_bones_list(Node *p_node); List<CanvasItem *> _get_edited_canvas_items(bool retreive_locked = false, bool remove_canvas_item_if_parent_in_selection = true); Rect2 _get_encompassing_rect_from_list(List<CanvasItem *> p_list); diff --git a/scene/2d/skeleton_2d.cpp b/scene/2d/skeleton_2d.cpp index 9197127235..2363c791fa 100644 --- a/scene/2d/skeleton_2d.cpp +++ b/scene/2d/skeleton_2d.cpp @@ -56,7 +56,11 @@ void Bone2D::_bind_methods() { ClassDB::bind_method(D_METHOD("get_skeleton_rest"), &Bone2D::get_skeleton_rest); ClassDB::bind_method(D_METHOD("get_index_in_skeleton"), &Bone2D::get_index_in_skeleton); + ClassDB::bind_method(D_METHOD("set_default_length", "default_length"), &Bone2D::set_default_length); + ClassDB::bind_method(D_METHOD("get_default_length"), &Bone2D::get_default_length); + ADD_PROPERTY(PropertyInfo(Variant::TRANSFORM2D,"rest"),"set_rest","get_rest"); + ADD_PROPERTY(PropertyInfo(Variant::REAL,"default_length",PROPERTY_HINT_RANGE,"1,1024,1"),"set_default_length","get_default_length"); } void Bone2D::set_rest(const Transform2D &p_rest) { @@ -84,6 +88,16 @@ void Bone2D::apply_rest() { set_transform(rest); } +void Bone2D::set_default_length(float p_length) { + + default_length=p_length; + +} + +float Bone2D::get_default_length() const { + return default_length; +} + int Bone2D::get_index_in_skeleton() const { ERR_FAIL_COND_V(!skeleton,-1); skeleton->_update_bone_setup(); @@ -118,6 +132,7 @@ Bone2D::Bone2D() { skeleton = NULL; parent_bone = NULL; skeleton_index=-1; + default_length=16; set_notify_local_transform(true); //this is a clever hack so the bone knows no rest has been set yet, allowing to show an error. for(int i=0;i<3;i++) { diff --git a/scene/2d/skeleton_2d.h b/scene/2d/skeleton_2d.h index 9ae74b56d3..cd270dac85 100644 --- a/scene/2d/skeleton_2d.h +++ b/scene/2d/skeleton_2d.h @@ -11,6 +11,7 @@ class Bone2D : public Node2D { Bone2D *parent_bone; Skeleton2D *skeleton; Transform2D rest; + float default_length; friend class Skeleton2D; int skeleton_index; @@ -27,6 +28,9 @@ public: String get_configuration_warning() const; + void set_default_length(float p_length); + float get_default_length() const; + int get_index_in_skeleton() const; Bone2D(); |