From be3aee23cd7659efde4651d4a7ef4f97a296909f Mon Sep 17 00:00:00 2001 From: PrestonKnopp Date: Mon, 17 Jun 2019 20:20:41 -0700 Subject: [PATCH 01/10] moved to bone_gizmo folder --- addons/{ => bone_gizmo}/bone_gizmo.gd | 0 addons/{ => bone_gizmo}/bone_gizmo.png | Bin addons/{ => bone_gizmo}/bone_gizmo_node.gd | 0 addons/{ => bone_gizmo}/dock.gd | 0 addons/{ => bone_gizmo}/dock.tscn | 0 addons/{ => bone_gizmo}/icon.png | Bin addons/{ => bone_gizmo}/icon.png.import | 0 addons/{ => bone_gizmo}/plugin.cfg | 0 addons/{ => bone_gizmo}/plugin.gd | 0 9 files changed, 0 insertions(+), 0 deletions(-) rename addons/{ => bone_gizmo}/bone_gizmo.gd (100%) rename addons/{ => bone_gizmo}/bone_gizmo.png (100%) rename addons/{ => bone_gizmo}/bone_gizmo_node.gd (100%) rename addons/{ => bone_gizmo}/dock.gd (100%) rename addons/{ => bone_gizmo}/dock.tscn (100%) rename addons/{ => bone_gizmo}/icon.png (100%) rename addons/{ => bone_gizmo}/icon.png.import (100%) rename addons/{ => bone_gizmo}/plugin.cfg (100%) rename addons/{ => bone_gizmo}/plugin.gd (100%) diff --git a/addons/bone_gizmo.gd b/addons/bone_gizmo/bone_gizmo.gd similarity index 100% rename from addons/bone_gizmo.gd rename to addons/bone_gizmo/bone_gizmo.gd diff --git a/addons/bone_gizmo.png b/addons/bone_gizmo/bone_gizmo.png similarity index 100% rename from addons/bone_gizmo.png rename to addons/bone_gizmo/bone_gizmo.png diff --git a/addons/bone_gizmo_node.gd b/addons/bone_gizmo/bone_gizmo_node.gd similarity index 100% rename from addons/bone_gizmo_node.gd rename to addons/bone_gizmo/bone_gizmo_node.gd diff --git a/addons/dock.gd b/addons/bone_gizmo/dock.gd similarity index 100% rename from addons/dock.gd rename to addons/bone_gizmo/dock.gd diff --git a/addons/dock.tscn b/addons/bone_gizmo/dock.tscn similarity index 100% rename from addons/dock.tscn rename to addons/bone_gizmo/dock.tscn diff --git a/addons/icon.png b/addons/bone_gizmo/icon.png similarity index 100% rename from addons/icon.png rename to addons/bone_gizmo/icon.png diff --git a/addons/icon.png.import b/addons/bone_gizmo/icon.png.import similarity index 100% rename from addons/icon.png.import rename to addons/bone_gizmo/icon.png.import diff --git a/addons/plugin.cfg b/addons/bone_gizmo/plugin.cfg similarity index 100% rename from addons/plugin.cfg rename to addons/bone_gizmo/plugin.cfg diff --git a/addons/plugin.gd b/addons/bone_gizmo/plugin.gd similarity index 100% rename from addons/plugin.gd rename to addons/bone_gizmo/plugin.gd From 10ac897ade6edcae004684cc52da404999577a3e Mon Sep 17 00:00:00 2001 From: PrestonKnopp Date: Mon, 17 Jun 2019 20:23:00 -0700 Subject: [PATCH 02/10] rm unused bone_gizmo.gd --- addons/bone_gizmo/bone_gizmo.gd | 8 -------- 1 file changed, 8 deletions(-) delete mode 100644 addons/bone_gizmo/bone_gizmo.gd diff --git a/addons/bone_gizmo/bone_gizmo.gd b/addons/bone_gizmo/bone_gizmo.gd deleted file mode 100644 index 5318843..0000000 --- a/addons/bone_gizmo/bone_gizmo.gd +++ /dev/null @@ -1,8 +0,0 @@ -tool -extends EditorPlugin - -func _enter_tree(): - add_custom_type("BoneGizmo", "Spatial", preload("bone_gizmo_node.gd"), preload("bone_gizmo.png")) - -func _exit_tree(): - remove_custom_type("BoneGizmo") From dec26056fd66b287650a073cd76716b765c0599a Mon Sep 17 00:00:00 2001 From: PrestonKnopp Date: Mon, 17 Jun 2019 20:41:49 -0700 Subject: [PATCH 03/10] rename bone_gizmo_node to bone_gizmo --- addons/bone_gizmo/{bone_gizmo_node.gd => bone_gizmo.gd} | 0 addons/bone_gizmo/icon.png.import | 8 +++++--- addons/bone_gizmo/plugin.gd | 4 ++-- 3 files changed, 7 insertions(+), 5 deletions(-) rename addons/bone_gizmo/{bone_gizmo_node.gd => bone_gizmo.gd} (100%) diff --git a/addons/bone_gizmo/bone_gizmo_node.gd b/addons/bone_gizmo/bone_gizmo.gd similarity index 100% rename from addons/bone_gizmo/bone_gizmo_node.gd rename to addons/bone_gizmo/bone_gizmo.gd diff --git a/addons/bone_gizmo/icon.png.import b/addons/bone_gizmo/icon.png.import index dcabc97..9a7b3bb 100644 --- a/addons/bone_gizmo/icon.png.import +++ b/addons/bone_gizmo/icon.png.import @@ -3,20 +3,21 @@ importer="texture" type="StreamTexture" path="res://.import/icon.png-2a5a7f799fe1a3f1156b96d53d16544c.stex" +metadata={ +"vram_texture": false +} [deps] source_file="res://addons/bone_gizmo/icon.png" -source_md5="bd3fb020e2be509090f4517ccc956938" - dest_files=[ "res://.import/icon.png-2a5a7f799fe1a3f1156b96d53d16544c.stex" ] -dest_md5="6eca8843e06a1dde23ea895bea3f938b" [params] compress/mode=0 compress/lossy_quality=0.7 compress/hdr_mode=0 +compress/bptc_ldr=0 compress/normal_map=0 flags/repeat=0 flags/filter=true @@ -26,6 +27,7 @@ flags/srgb=2 process/fix_alpha_border=true process/premult_alpha=false process/HDR_as_SRGB=false +process/invert_color=false stream=false size_limit=0 detect_3d=true diff --git a/addons/bone_gizmo/plugin.gd b/addons/bone_gizmo/plugin.gd index 8980c77..ddb2700 100644 --- a/addons/bone_gizmo/plugin.gd +++ b/addons/bone_gizmo/plugin.gd @@ -4,11 +4,11 @@ extends EditorPlugin var dock func _enter_tree(): - add_custom_type("BoneGizmo", "Spatial", preload("bone_gizmo_node.gd"), preload("icon.png")) + add_custom_type("BoneGizmo", "Spatial", preload("bone_gizmo.gd"), preload("icon.png")) dock = preload("res://addons/bone_gizmo/dock.tscn").instance() add_control_to_dock( DOCK_SLOT_LEFT_UL, dock) func _exit_tree(): remove_custom_type("BoneGizmo") remove_control_from_docks( dock ) # Remove the dock - dock.free() # Erase the control from the memory \ No newline at end of file + dock.free() # Erase the control from the memory From 639c1d81744798a95f9f11f7f922faab69e3a86c Mon Sep 17 00:00:00 2001 From: PrestonKnopp Date: Mon, 17 Jun 2019 20:43:18 -0700 Subject: [PATCH 04/10] load resources only after plugin has entered tree --- addons/bone_gizmo/plugin.gd | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/addons/bone_gizmo/plugin.gd b/addons/bone_gizmo/plugin.gd index ddb2700..0a683be 100644 --- a/addons/bone_gizmo/plugin.gd +++ b/addons/bone_gizmo/plugin.gd @@ -4,11 +4,22 @@ extends EditorPlugin var dock func _enter_tree(): - add_custom_type("BoneGizmo", "Spatial", preload("bone_gizmo.gd"), preload("icon.png")) - dock = preload("res://addons/bone_gizmo/dock.tscn").instance() + + # Load resources only when entering tree. + # Has the additional effect of being reloadable after script changes. + # You do not not need to restart editor. + var base_dir = get_script().get_path().get_base_dir() + var bone_gizmo = load(base_dir.plus_file("bone_gizmo.gd")) + var dock_scene = load(base_dir.plus_file("dock.tscn")) + var icon = load(base_dir.plus_file("icon.png")) + + dock = dock_scene.instance() + add_control_to_dock( DOCK_SLOT_LEFT_UL, dock) + add_custom_type("BoneGizmo", "Spatial", bone_gizmo, icon) func _exit_tree(): remove_custom_type("BoneGizmo") remove_control_from_docks( dock ) # Remove the dock dock.free() # Erase the control from the memory + From 9bd76e37872054b8282335b55fe5662c73ae3a2c Mon Sep 17 00:00:00 2001 From: PrestonKnopp Date: Tue, 18 Jun 2019 00:22:06 -0700 Subject: [PATCH 05/10] fixed bug where track `i` was used for bone at index `i` --- addons/bone_gizmo/bone_gizmo.gd | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/addons/bone_gizmo/bone_gizmo.gd b/addons/bone_gizmo/bone_gizmo.gd index 2617a62..b5f4295 100644 --- a/addons/bone_gizmo/bone_gizmo.gd +++ b/addons/bone_gizmo/bone_gizmo.gd @@ -29,12 +29,19 @@ func create_tracks(): animation.add_track(Animation.TYPE_TRANSFORM,i) animation.track_set_path(i,skeleton_path + ":" + skeleton_node.get_bone_name(i)) - -func insert_key(): #This will override all the bone poses in the track with the current ones - var skeleton_node = get_node(skeleton_path) - var animation_node = get_node(animation_path) +# This will override all the bone poses in the track with the current ones +func insert_key(): + var skeleton_node = get_node(skeleton_path) as Skeleton + var animation_node = get_node(animation_path) as AnimationPlayer var animation = animation_node.get_animation(animation_node.assigned_animation) - for i in range(skeleton_node.get_bone_count()): - var bone_tr = skeleton_node.get_bone_pose(i) - var rot = Quat(bone_tr.basis) - animation.transform_track_insert_key(i,animation_node.current_animation_position,bone_tr.origin,rot,bone_tr.basis.get_scale()) \ No newline at end of file + for i in skeleton_node.get_bone_count(): + var bone_name = skeleton_node.get_bone_name(i) + var bone_pose = skeleton_node.get_bone_pose(i) + var bone_track = animation.find_track(NodePath(skeleton_node.name + ':' + bone_name)) + animation.transform_track_insert_key( + bone_track, + animation_node.current_animation_position, + bone_pose.origin, + Quat(bone_pose.basis), + bone_pose.basis.get_scale() + ) From 48bbfa62b5e95772aad40a3a42ab486a3d070b07 Mon Sep 17 00:00:00 2001 From: PrestonKnopp Date: Tue, 18 Jun 2019 00:26:24 -0700 Subject: [PATCH 06/10] add and integrate bone finder --- addons/bone_gizmo/bone_finder.gd | 36 +++ addons/bone_gizmo/bone_finder.tscn | 37 ++++ addons/bone_gizmo/bone_gizmo.gd | 11 +- addons/bone_gizmo/dock.gd | 54 ++--- addons/bone_gizmo/dock.tscn | 340 ++++++----------------------- 5 files changed, 182 insertions(+), 296 deletions(-) create mode 100644 addons/bone_gizmo/bone_finder.gd create mode 100644 addons/bone_gizmo/bone_finder.tscn diff --git a/addons/bone_gizmo/bone_finder.gd b/addons/bone_gizmo/bone_finder.gd new file mode 100644 index 0000000..325fb5d --- /dev/null +++ b/addons/bone_gizmo/bone_finder.gd @@ -0,0 +1,36 @@ +tool +extends VBoxContainer + +signal bone_selected(this, name, id) + +onready var _bone_list: ItemList = $bone_list as ItemList + +var _skel: Skeleton +var _filter := '' + +func set_skeleton(skeleton: Skeleton): + if skeleton == null: + _bone_list.clear() + _skel = null + return + if _skel != skeleton: + _skel = skeleton + refresh_bone_list() + +func refresh_bone_list(): + if _skel == null: + return + _bone_list.clear() + for id in _skel.get_bone_count(): + var name = _skel.get_bone_name(id) + if name.findn(_filter) > -1: + _bone_list.add_item(name) + _bone_list.set_item_metadata(_bone_list.get_item_count() - 1, {name = name, id = id}) + +func _on_filter_text_changed(new_text: String) -> void: + _filter = new_text + refresh_bone_list() + +func _on_bone_list_item_activated(index: int) -> void: + var meta = _bone_list.get_item_metadata(index) + emit_signal("bone_selected", self, meta.name, meta.id) diff --git a/addons/bone_gizmo/bone_finder.tscn b/addons/bone_gizmo/bone_finder.tscn new file mode 100644 index 0000000..ffc9046 --- /dev/null +++ b/addons/bone_gizmo/bone_finder.tscn @@ -0,0 +1,37 @@ +[gd_scene load_steps=2 format=2] + +[ext_resource path="res://addons/bone_gizmo/bone_finder.gd" type="Script" id=1] + +[node name="bone_finder" type="VBoxContainer"] +anchor_right = 1.0 +anchor_bottom = 1.0 +size_flags_horizontal = 3 +size_flags_vertical = 3 +script = ExtResource( 1 ) + +[node name="HBoxContainer" type="HBoxContainer" parent="."] +margin_right = 1024.0 +margin_bottom = 24.0 +size_flags_horizontal = 3 + +[node name="Label" type="Label" parent="HBoxContainer"] +margin_top = 5.0 +margin_right = 37.0 +margin_bottom = 19.0 +text = "Filter:" + +[node name="filter" type="LineEdit" parent="HBoxContainer"] +margin_left = 41.0 +margin_right = 1024.0 +margin_bottom = 24.0 +size_flags_horizontal = 3 +caret_blink = true + +[node name="bone_list" type="ItemList" parent="."] +margin_top = 28.0 +margin_right = 1024.0 +margin_bottom = 600.0 +size_flags_horizontal = 3 +size_flags_vertical = 3 +[connection signal="text_changed" from="HBoxContainer/filter" to="." method="_on_filter_text_changed"] +[connection signal="item_activated" from="bone_list" to="." method="_on_bone_list_item_activated"] diff --git a/addons/bone_gizmo/bone_gizmo.gd b/addons/bone_gizmo/bone_gizmo.gd index b5f4295..0eb4e48 100644 --- a/addons/bone_gizmo/bone_gizmo.gd +++ b/addons/bone_gizmo/bone_gizmo.gd @@ -11,12 +11,19 @@ export(String) var animation_path = "../AnimationPlayer" var skeleton var bone_index +var initialized = false + func _process(delta): if run: if not edit_bone == "" and not skeleton_path == "": - skeleton = get_node(skeleton_path) + skeleton = get_node(skeleton_path) as Skeleton bone_index = skeleton.find_bone(edit_bone) - skeleton.set_bone_pose(bone_index,transform) + if not initialized: + global_transform = skeleton.get_bone_global_pose(bone_index) + initialized = true + skeleton.set_bone_global_pose(bone_index, global_transform) + else: + initialized = false diff --git a/addons/bone_gizmo/dock.gd b/addons/bone_gizmo/dock.gd index 02f6ef7..678e0c3 100644 --- a/addons/bone_gizmo/dock.gd +++ b/addons/bone_gizmo/dock.gd @@ -2,63 +2,62 @@ tool extends Control var gizmo_node = null +onready var bone_finder = find_node('bone_finder') func _on_FindGizmo_pressed(): if not get_tree().get_edited_scene_root().find_node("BoneGizmo",true,false): - $"Output".set_text("BoneGizmo node not found!") + print("BoneGizmo node not found!") gizmo_node = null else: - $"Output".set_text("BoneGizmo node found!") + print("BoneGizmo node found!") gizmo_node = get_tree().get_edited_scene_root().find_node("BoneGizmo",true,false) + bone_finder.set_skeleton(gizmo_node.get_node(gizmo_node.skeleton_path)) func _on_ResetGizmo_pressed(): if not gizmo_node == null: gizmo_node.translation = Vector3(0,0,0) gizmo_node.rotation = Vector3(0,0,0) gizmo_node.scale = Vector3(1,1,1) - $"Output".set_text("BoneGizmo reset transform") - + print("BoneGizmo reset transform") func _on_RunGizmo_toggled(button_pressed): if not gizmo_node == null: gizmo_node.run = button_pressed -func _on_SkeletonPath_text_entered(new_text): - if not gizmo_node == null: - gizmo_node.skeleton_path = new_text - if not gizmo_node.has_node(gizmo_node.skeleton_path): - $"Output".set_text("Invalid skeleton path") - return - $"Output".set_text("Set skeleton path") +#func _on_SkeletonPath_text_entered(new_text): +# if not gizmo_node == null: +# gizmo_node.skeleton_path = new_text +# if not gizmo_node.has_node(gizmo_node.skeleton_path): +# print("BoneGizmo Invalid skeleton path") +# return +# print("BoneGizmo Set skeleton path") func _on_Bone_text_entered(new_text): if not gizmo_node == null: gizmo_node.edit_bone = new_text if gizmo_node.has_node(gizmo_node.skeleton_path): if gizmo_node.get_node(gizmo_node.skeleton_path).find_bone(new_text) == -1: - $"Output".set_text("Invalid bone") + print("BoneGizmo Invalid bone") return - $"Output".set_text("Set bone") - + print("BoneGizmo Set bone") - -func _on_AnimationPath_text_entered(new_text): - if not gizmo_node == null: - gizmo_node.animation_path = new_text - if not gizmo_node.has_node(gizmo_node.animation_path): - $"Output".set_text("Invalid animation path") - return - $"Output".set_text("Set animation player path") +#func _on_AnimationPath_text_entered(new_text): +# if not gizmo_node == null: +# gizmo_node.animation_path = new_text +# if not gizmo_node.has_node(gizmo_node.animation_path): +# print("BoneGizmo Invalid animation path") +# return +# print("BoneGizmo Set animation player path") func _on_CreateTracks_pressed(): if not gizmo_node == null: if not gizmo_node.has_node(gizmo_node.skeleton_path): - $"Output".set_text("Invalid skeleton path") + print("BoneGizmo Invalid skeleton path") return if not gizmo_node.has_node(gizmo_node.animation_path): - $"Output".set_text("Invalid animation path") + print("BoneGizmo Invalid animation path") return gizmo_node.create_tracks() @@ -66,9 +65,12 @@ func _on_CreateTracks_pressed(): func _on_InsertKey_pressed(): if not gizmo_node == null: if not gizmo_node.has_node(gizmo_node.skeleton_path): - $"Output".set_text("Invalid skeleton path") + print("BoneGizmo Invalid skeleton path") return if not gizmo_node.has_node(gizmo_node.animation_path): - $"Output".set_text("Invalid animation path") + print("BoneGizmo Invalid animation path") return gizmo_node.insert_key() + +func _on_bone_finder_bone_selected(this, name, id) -> void: + _on_Bone_text_entered(name) \ No newline at end of file diff --git a/addons/bone_gizmo/dock.tscn b/addons/bone_gizmo/dock.tscn index 2e9d3a8..4f69fcd 100644 --- a/addons/bone_gizmo/dock.tscn +++ b/addons/bone_gizmo/dock.tscn @@ -1,311 +1,115 @@ -[gd_scene load_steps=3 format=2] +[gd_scene load_steps=4 format=2] [ext_resource path="res://addons/bone_gizmo/dock.gd" type="Script" id=1] [ext_resource path="res://addons/bone_gizmo/icon.png" type="Texture" id=2] +[ext_resource path="res://addons/bone_gizmo/bone_finder.tscn" type="PackedScene" id=3] -[node name="BoneGizmo" type="Control" index="0"] - -anchor_left = 0.0 -anchor_top = 0.0 -anchor_right = 0.0 -anchor_bottom = 0.0 -margin_right = 64.0 -margin_bottom = 64.0 -rect_pivot_offset = Vector2( 0, 0 ) +[node name="BoneGizmo" type="Control"] +anchor_bottom = 1.0 +margin_right = 206.0 mouse_filter = 1 -mouse_default_cursor_shape = 0 -size_flags_horizontal = 1 -size_flags_vertical = 1 script = ExtResource( 1 ) -_sections_unfolded = [ "Rect" ] - -[node name="VBox" type="VBoxContainer" parent="." index="0"] -anchor_left = 0.0 -anchor_top = 0.0 -anchor_right = 0.0 -anchor_bottom = 0.0 -margin_left = 20.0 -margin_top = 40.0 -margin_right = 174.0 -margin_bottom = 230.0 -rect_pivot_offset = Vector2( 0, 0 ) -mouse_filter = 1 -mouse_default_cursor_shape = 0 -size_flags_horizontal = 1 -size_flags_vertical = 1 +[node name="VBox" type="VBoxContainer" parent="."] +anchor_right = 1.0 +anchor_bottom = 1.0 custom_constants/separation = 10 -alignment = 0 -_sections_unfolded = [ "Rect", "custom_constants" ] -[node name="FindGizmo" type="Button" parent="VBox" index="0"] +[node name="HBoxContainer" type="HBoxContainer" parent="VBox"] +margin_right = 206.0 +margin_bottom = 16.0 +size_flags_horizontal = 3 +size_flags_vertical = 0 +alignment = 1 + +[node name="Info" type="Label" parent="VBox/HBoxContainer"] +margin_left = 30.0 +margin_top = 1.0 +margin_right = 155.0 +margin_bottom = 15.0 +text = "@thimenesup V 0.1" -anchor_left = 0.0 -anchor_top = 0.0 -anchor_right = 0.0 -anchor_bottom = 0.0 -margin_right = 154.0 -margin_bottom = 20.0 -rect_pivot_offset = Vector2( 0, 0 ) -focus_mode = 2 -mouse_filter = 0 -mouse_default_cursor_shape = 0 -size_flags_horizontal = 1 -size_flags_vertical = 1 -toggle_mode = false -enabled_focus_mode = 2 -shortcut = null -group = null -text = "Find Gizmo" -flat = false -align = 1 +[node name="Icon" type="TextureRect" parent="VBox/HBoxContainer"] +margin_left = 159.0 +margin_right = 175.0 +margin_bottom = 16.0 +texture = ExtResource( 2 ) -[node name="ResetGizmo" type="Button" parent="VBox" index="1"] +[node name="FindGizmo" type="Button" parent="VBox"] +margin_top = 26.0 +margin_right = 206.0 +margin_bottom = 46.0 +text = "Find Gizmo" -anchor_left = 0.0 -anchor_top = 0.0 -anchor_right = 0.0 -anchor_bottom = 0.0 -margin_top = 30.0 -margin_right = 154.0 -margin_bottom = 50.0 -rect_pivot_offset = Vector2( 0, 0 ) -focus_mode = 2 -mouse_filter = 0 -mouse_default_cursor_shape = 0 -size_flags_horizontal = 1 -size_flags_vertical = 1 -toggle_mode = false -enabled_focus_mode = 2 -shortcut = null -group = null +[node name="ResetGizmo" type="Button" parent="VBox"] +margin_top = 56.0 +margin_right = 206.0 +margin_bottom = 76.0 text = "Reset Gizmo Matrix" -flat = false -align = 1 - -[node name="RunGizmo" type="CheckButton" parent="VBox" index="2"] -anchor_left = 0.0 -anchor_top = 0.0 -anchor_right = 0.0 -anchor_bottom = 0.0 -margin_top = 60.0 -margin_right = 154.0 -margin_bottom = 100.0 -rect_pivot_offset = Vector2( 0, 0 ) -focus_mode = 2 -mouse_filter = 0 -mouse_default_cursor_shape = 0 -size_flags_horizontal = 1 -size_flags_vertical = 1 -toggle_mode = true -enabled_focus_mode = 2 -shortcut = null -group = null +[node name="RunGizmo" type="CheckButton" parent="VBox"] +margin_top = 86.0 +margin_right = 206.0 +margin_bottom = 126.0 text = "Run Gizmo" -flat = false -align = 0 -[node name="SkeletonPath" type="LineEdit" parent="VBox" index="3"] - -anchor_left = 0.0 -anchor_top = 0.0 -anchor_right = 0.0 -anchor_bottom = 0.0 -margin_top = 110.0 -margin_right = 154.0 -margin_bottom = 134.0 -rect_pivot_offset = Vector2( 0, 0 ) -focus_mode = 2 -mouse_filter = 0 -mouse_default_cursor_shape = 1 -size_flags_horizontal = 1 -size_flags_vertical = 1 -focus_mode = 2 -context_menu_enabled = true +[node name="SkeletonPath" type="LineEdit" parent="VBox"] +visible = false +margin_top = 136.0 +margin_right = 206.0 +margin_bottom = 160.0 placeholder_text = "Skeleton Path" placeholder_alpha = 0.3 caret_blink = true -caret_blink_speed = 0.65 -caret_position = 0 -_sections_unfolded = [ "Placeholder" ] -[node name="Bone" type="LineEdit" parent="VBox" index="4"] - -anchor_left = 0.0 -anchor_top = 0.0 -anchor_right = 0.0 -anchor_bottom = 0.0 -margin_top = 144.0 -margin_right = 154.0 -margin_bottom = 168.0 -rect_pivot_offset = Vector2( 0, 0 ) -focus_mode = 2 -mouse_filter = 0 -mouse_default_cursor_shape = 1 -size_flags_horizontal = 1 -size_flags_vertical = 1 -focus_mode = 2 -context_menu_enabled = true +[node name="Bone" type="LineEdit" parent="VBox"] +visible = false +margin_top = 170.0 +margin_right = 206.0 +margin_bottom = 194.0 placeholder_text = "Skeleton Bone" placeholder_alpha = 0.3 caret_blink = true -caret_blink_speed = 0.65 -caret_position = 0 -_sections_unfolded = [ "Placeholder" ] -[node name="AnimationPath" type="LineEdit" parent="VBox" index="5"] - -anchor_left = 0.0 -anchor_top = 0.0 -anchor_right = 0.0 -anchor_bottom = 0.0 -margin_top = 178.0 -margin_right = 154.0 -margin_bottom = 202.0 -rect_pivot_offset = Vector2( 0, 0 ) -focus_mode = 2 -mouse_filter = 0 -mouse_default_cursor_shape = 1 -size_flags_horizontal = 1 -size_flags_vertical = 1 -focus_mode = 2 -context_menu_enabled = true +[node name="AnimationPath" type="LineEdit" parent="VBox"] +visible = false +margin_top = 136.0 +margin_right = 206.0 +margin_bottom = 160.0 placeholder_text = "AnimPlayer Path" placeholder_alpha = 0.3 caret_blink = true -caret_blink_speed = 0.65 -caret_position = 0 -_sections_unfolded = [ "Placeholder" ] -[node name="CreateTracks" type="Button" parent="VBox" index="6"] - -anchor_left = 0.0 -anchor_top = 0.0 -anchor_right = 0.0 -anchor_bottom = 0.0 -margin_top = 212.0 -margin_right = 154.0 -margin_bottom = 232.0 -rect_pivot_offset = Vector2( 0, 0 ) -focus_mode = 2 -mouse_filter = 0 -mouse_default_cursor_shape = 0 -size_flags_horizontal = 1 -size_flags_vertical = 1 -toggle_mode = false -enabled_focus_mode = 2 -shortcut = null -group = null +[node name="CreateTracks" type="Button" parent="VBox"] +margin_top = 136.0 +margin_right = 206.0 +margin_bottom = 156.0 text = "Create Tracks" -flat = false -align = 1 - -[node name="InsertKey" type="Button" parent="VBox" index="7"] -anchor_left = 0.0 -anchor_top = 0.0 -anchor_right = 0.0 -anchor_bottom = 0.0 -margin_top = 242.0 -margin_right = 154.0 -margin_bottom = 262.0 -rect_pivot_offset = Vector2( 0, 0 ) -focus_mode = 2 -mouse_filter = 0 -mouse_default_cursor_shape = 0 -size_flags_horizontal = 1 -size_flags_vertical = 1 -toggle_mode = false -enabled_focus_mode = 2 -shortcut = null -group = null +[node name="InsertKey" type="Button" parent="VBox"] +margin_top = 166.0 +margin_right = 206.0 +margin_bottom = 186.0 text = "Insert Key" -flat = false -align = 1 - -[node name="Info" type="Label" parent="." index="1"] -anchor_left = 0.0 -anchor_top = 0.0 -anchor_right = 0.0 -anchor_bottom = 0.0 -margin_left = 23.0 -margin_top = 3.0 -margin_right = 148.0 -margin_bottom = 17.0 -rect_pivot_offset = Vector2( 0, 0 ) -mouse_filter = 2 -mouse_default_cursor_shape = 0 -size_flags_horizontal = 1 -size_flags_vertical = 4 -text = "@thimenesup V 0.1" -percent_visible = 1.0 -lines_skipped = 0 -max_lines_visible = -1 - -[node name="Icon" type="TextureRect" parent="." index="2"] +[node name="FIND BONES" type="Label" parent="VBox"] +margin_top = 196.0 +margin_right = 206.0 +margin_bottom = 210.0 +text = "FIND BONE:" -anchor_left = 0.0 -anchor_top = 0.0 +[node name="bone_finder" parent="VBox" instance=ExtResource( 3 )] anchor_right = 0.0 anchor_bottom = 0.0 -margin_left = 158.0 -margin_top = 8.0 -margin_right = 174.0 -margin_bottom = 24.0 -rect_pivot_offset = Vector2( 0, 0 ) -mouse_filter = 1 -mouse_default_cursor_shape = 0 -size_flags_horizontal = 1 -size_flags_vertical = 1 -texture = ExtResource( 2 ) -stretch_mode = 0 -_sections_unfolded = [ "Rect" ] - -[node name="Output" type="RichTextLabel" parent="." index="3"] - -anchor_left = 0.0 -anchor_top = 0.0 -anchor_right = 0.0 -anchor_bottom = 0.0 -margin_left = 6.0 -margin_top = 500.0 -margin_right = 211.0 -margin_bottom = 703.0 -rect_pivot_offset = Vector2( 0, 0 ) -rect_clip_content = true -mouse_filter = 0 -mouse_default_cursor_shape = 0 -size_flags_horizontal = 1 -size_flags_vertical = 1 -bbcode_enabled = true -bbcode_text = "Output" -visible_characters = -1 -percent_visible = 1.0 -meta_underlined = true -tab_size = 4 -text = "Output" -scroll_active = true -scroll_following = false -selection_enabled = false -override_selected_font_color = false -_sections_unfolded = [ "BBCode", "Rect" ] - +margin_top = 220.0 +margin_right = 206.0 +margin_bottom = 600.0 [connection signal="pressed" from="VBox/FindGizmo" to="." method="_on_FindGizmo_pressed"] - [connection signal="pressed" from="VBox/ResetGizmo" to="." method="_on_ResetGizmo_pressed"] - [connection signal="toggled" from="VBox/RunGizmo" to="." method="_on_RunGizmo_toggled"] - [connection signal="text_entered" from="VBox/SkeletonPath" to="." method="_on_SkeletonPath_text_entered"] - [connection signal="text_entered" from="VBox/Bone" to="." method="_on_Bone_text_entered"] - [connection signal="text_entered" from="VBox/AnimationPath" to="." method="_on_AnimationPath_text_entered"] - [connection signal="pressed" from="VBox/CreateTracks" to="." method="_on_CreateTracks_pressed"] - [connection signal="pressed" from="VBox/InsertKey" to="." method="_on_InsertKey_pressed"] - - +[connection signal="bone_selected" from="VBox/bone_finder" to="." method="_on_bone_finder_bone_selected"] From 11c18762d788d2216c24071c06283d1af455f78e Mon Sep 17 00:00:00 2001 From: PrestonKnopp Date: Tue, 18 Jun 2019 21:59:09 -0700 Subject: [PATCH 07/10] remove unused callbacks from dock --- addons/bone_gizmo/dock.gd | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/addons/bone_gizmo/dock.gd b/addons/bone_gizmo/dock.gd index 678e0c3..d807718 100644 --- a/addons/bone_gizmo/dock.gd +++ b/addons/bone_gizmo/dock.gd @@ -4,7 +4,6 @@ extends Control var gizmo_node = null onready var bone_finder = find_node('bone_finder') - func _on_FindGizmo_pressed(): if not get_tree().get_edited_scene_root().find_node("BoneGizmo",true,false): print("BoneGizmo node not found!") @@ -25,14 +24,6 @@ func _on_RunGizmo_toggled(button_pressed): if not gizmo_node == null: gizmo_node.run = button_pressed -#func _on_SkeletonPath_text_entered(new_text): -# if not gizmo_node == null: -# gizmo_node.skeleton_path = new_text -# if not gizmo_node.has_node(gizmo_node.skeleton_path): -# print("BoneGizmo Invalid skeleton path") -# return -# print("BoneGizmo Set skeleton path") - func _on_Bone_text_entered(new_text): if not gizmo_node == null: gizmo_node.edit_bone = new_text @@ -42,15 +33,6 @@ func _on_Bone_text_entered(new_text): return print("BoneGizmo Set bone") -#func _on_AnimationPath_text_entered(new_text): -# if not gizmo_node == null: -# gizmo_node.animation_path = new_text -# if not gizmo_node.has_node(gizmo_node.animation_path): -# print("BoneGizmo Invalid animation path") -# return -# print("BoneGizmo Set animation player path") - - func _on_CreateTracks_pressed(): if not gizmo_node == null: if not gizmo_node.has_node(gizmo_node.skeleton_path): @@ -61,7 +43,6 @@ func _on_CreateTracks_pressed(): return gizmo_node.create_tracks() - func _on_InsertKey_pressed(): if not gizmo_node == null: if not gizmo_node.has_node(gizmo_node.skeleton_path): From f791203475c380ccca41e0ec4a8b87847bfe8338 Mon Sep 17 00:00:00 2001 From: PrestonKnopp Date: Wed, 19 Jun 2019 00:18:57 -0700 Subject: [PATCH 08/10] refactor: proxy obj, bone_gizmo api, use EditorPlugin signals to autofind gizmo --- addons/bone_gizmo/bone_gizmo.gd | 82 ++++++++++++---------- addons/bone_gizmo/dock.gd | 119 +++++++++++++++++++++----------- addons/bone_gizmo/dock.tscn | 28 ++++---- addons/bone_gizmo/plugin.gd | 15 +++- 4 files changed, 156 insertions(+), 88 deletions(-) diff --git a/addons/bone_gizmo/bone_gizmo.gd b/addons/bone_gizmo/bone_gizmo.gd index 0eb4e48..f40f77c 100644 --- a/addons/bone_gizmo/bone_gizmo.gd +++ b/addons/bone_gizmo/bone_gizmo.gd @@ -1,54 +1,66 @@ tool extends Spatial -var run = false +# All paths are must be relative to the node (BoneGizmo) +export(NodePath) var skeleton_path = @"../Skeleton" +export(NodePath) var animation_path = @"../AnimationPlayer" -#All paths are must be relative to the node (BoneGizmo) -export(String) var skeleton_path = "../Armature" -export(String) var edit_bone = "" -export(String) var animation_path = "../AnimationPlayer" +var edit_bone = "" -var skeleton -var bone_index +var running: bool setget set_running,get_running +func get_running() -> bool: return running +func set_running(new_val: bool) -> void: + if new_val and not running: + global_transform = get_skeleton().get_bone_global_pose(get_edit_bone_index()) + set_process(true) + elif not new_val: + set_process(false) + running = new_val -var initialized = false +func _ready(): + set_running(false) func _process(delta): - if run: - if not edit_bone == "" and not skeleton_path == "": - skeleton = get_node(skeleton_path) as Skeleton - bone_index = skeleton.find_bone(edit_bone) - if not initialized: - global_transform = skeleton.get_bone_global_pose(bone_index) - initialized = true - skeleton.set_bone_global_pose(bone_index, global_transform) - else: - initialized = false + var skeleton = get_skeleton() + var bone_index = get_edit_bone_index() + skeleton.set_bone_global_pose(bone_index, global_transform) +func reset() -> void: + transform = Transform() +func can_run() -> bool: + return (get_skeleton() != null) and (get_edit_bone_index() != -1) + +func get_animation_player() -> AnimationPlayer: + return get_node(animation_path) as AnimationPlayer + +func get_skeleton() -> Skeleton: + return get_node(skeleton_path) as Skeleton + +func get_edit_bone_index() -> int: + return get_skeleton().find_bone(edit_bone) func create_tracks(): - var skeleton_node = get_node(skeleton_path) - var animation_node = get_node(animation_path) - var animation = animation_node.get_animation(animation_node.assigned_animation) - print(animation_node.current_animation) - for i in range(skeleton_node.get_bone_count()): - animation.add_track(Animation.TYPE_TRANSFORM,i) - animation.track_set_path(i,skeleton_path + ":" + skeleton_node.get_bone_name(i)) + var skel = get_skeleton() + var anim_player = get_animation_player() + var anim = anim_player.get_animation(anim_player.assigned_animation) + for i in skel.get_bone_count(): + anim.add_track(Animation.TYPE_TRANSFORM,i) + anim.track_set_path(i,skeleton_path + ":" + skel.get_bone_name(i)) # This will override all the bone poses in the track with the current ones func insert_key(): - var skeleton_node = get_node(skeleton_path) as Skeleton - var animation_node = get_node(animation_path) as AnimationPlayer - var animation = animation_node.get_animation(animation_node.assigned_animation) - for i in skeleton_node.get_bone_count(): - var bone_name = skeleton_node.get_bone_name(i) - var bone_pose = skeleton_node.get_bone_pose(i) - var bone_track = animation.find_track(NodePath(skeleton_node.name + ':' + bone_name)) - animation.transform_track_insert_key( + var skel = get_skeleton() + var anim_player = get_animation_player() + var anim = anim_player.get_animation(anim_player.assigned_animation) + for i in skel.get_bone_count(): + var bone_name = skel.get_bone_name(i) + var bone_pose = skel.get_bone_pose(i) + var bone_track = anim.find_track(NodePath(skel.name + ':' + bone_name)) + anim.transform_track_insert_key( bone_track, - animation_node.current_animation_position, + anim_player.current_animation_position, bone_pose.origin, Quat(bone_pose.basis), bone_pose.basis.get_scale() - ) + ) \ No newline at end of file diff --git a/addons/bone_gizmo/dock.gd b/addons/bone_gizmo/dock.gd index d807718..35121dc 100644 --- a/addons/bone_gizmo/dock.gd +++ b/addons/bone_gizmo/dock.gd @@ -1,57 +1,98 @@ tool extends Control -var gizmo_node = null +class BoneGizmoProxy: + static func make_proxy(node: Node) -> BoneGizmoProxy: + if node == null: + return NullBoneGizmoProxy.new() + return BoneGizmoProxy.new(node) + + var _node: Node + + func _init(node: Node) -> void: + _node = node + + var edit_bone: String setget set_eb,get_eb + var running: bool setget set_running,get_running + func set_eb(eb): _node.edit_bone = eb + func get_eb(): return _node.edit_bone + func set_running(new_val: bool) -> void: _node.set_running(new_val) + func get_running() -> bool: return _node.running + func can_run() -> bool: return _node.can_run() + func get_animation_player() -> AnimationPlayer: return _node.get_animation_player() + func get_skeleton() -> Skeleton: return _node.get_skeleton() + func get_edit_bone_index() -> int: return _node.get_edit_bone_index() + func create_tracks(): _node.create_tracks() + func insert_key(): _node.insert_key() + func reset(): _node.reset() + func on_tree_exit_sig(target, callback): + if not _node.is_connected("tree_exited", target, callback): + _node.connect("tree_exited", target, callback) + func off_tree_exit_sig(target, callback): _node.disconnect("tree_exited", target, callback) + +class NullBoneGizmoProxy extends BoneGizmoProxy: + func _init().(null): pass + func set_eb(eb): pass + func get_eb(): return '' + func set_running(new_val: bool) -> void: pass + func get_running() -> bool: return false + func can_run() -> bool: return false + func get_animation_player() -> AnimationPlayer: return null + func get_skeleton() -> Skeleton: return null + func get_edit_bone_index() -> int: return -1 + func create_tracks(): pass + func insert_key(): pass + func reset(): pass + func on_tree_exit_sig(target, callback): pass + func off_tree_exit_sig(target, callback): pass + +var proxy: BoneGizmoProxy = NullBoneGizmoProxy.new() onready var bone_finder = find_node('bone_finder') -func _on_FindGizmo_pressed(): - if not get_tree().get_edited_scene_root().find_node("BoneGizmo",true,false): +func find_gizmo(): + proxy = NullBoneGizmoProxy.new() + + var scene_root = get_tree().get_edited_scene_root() + if scene_root != null: + proxy = BoneGizmoProxy.make_proxy(scene_root.find_node("BoneGizmo", true, false)) + + if proxy is NullBoneGizmoProxy: print("BoneGizmo node not found!") - gizmo_node = null else: print("BoneGizmo node found!") - gizmo_node = get_tree().get_edited_scene_root().find_node("BoneGizmo",true,false) - bone_finder.set_skeleton(gizmo_node.get_node(gizmo_node.skeleton_path)) + + proxy.on_tree_exit_sig(self, '_on_bone_gizmo_exited_tree') + bone_finder.set_skeleton(proxy.get_skeleton()) + +func _on_bone_gizmo_exited_tree(): + proxy.off_tree_exit_sig(self, '_on_bone_gizmo_exited_tree') + find_gizmo() func _on_ResetGizmo_pressed(): - if not gizmo_node == null: - gizmo_node.translation = Vector3(0,0,0) - gizmo_node.rotation = Vector3(0,0,0) - gizmo_node.scale = Vector3(1,1,1) - print("BoneGizmo reset transform") + proxy.reset() + print("BoneGizmo reset transform") func _on_RunGizmo_toggled(button_pressed): - if not gizmo_node == null: - gizmo_node.run = button_pressed - -func _on_Bone_text_entered(new_text): - if not gizmo_node == null: - gizmo_node.edit_bone = new_text - if gizmo_node.has_node(gizmo_node.skeleton_path): - if gizmo_node.get_node(gizmo_node.skeleton_path).find_bone(new_text) == -1: - print("BoneGizmo Invalid bone") - return - print("BoneGizmo Set bone") + proxy.running = button_pressed + print("BoneGizmo running: ", proxy.running) func _on_CreateTracks_pressed(): - if not gizmo_node == null: - if not gizmo_node.has_node(gizmo_node.skeleton_path): - print("BoneGizmo Invalid skeleton path") - return - if not gizmo_node.has_node(gizmo_node.animation_path): - print("BoneGizmo Invalid animation path") - return - gizmo_node.create_tracks() + if check_anim_track_operation(): + proxy.create_tracks() func _on_InsertKey_pressed(): - if not gizmo_node == null: - if not gizmo_node.has_node(gizmo_node.skeleton_path): - print("BoneGizmo Invalid skeleton path") - return - if not gizmo_node.has_node(gizmo_node.animation_path): - print("BoneGizmo Invalid animation path") - return - gizmo_node.insert_key() + if check_anim_track_operation(): + proxy.insert_key() + +func check_anim_track_operation() -> bool: + var passed = true + if proxy.get_skeleton() == null: + print("BoneGizmo Invalid skeleton path") + passed = false + if proxy.get_animation_player() == null: + print("BoneGizmo Invalid animation path") + passed = false + return passed func _on_bone_finder_bone_selected(this, name, id) -> void: - _on_Bone_text_entered(name) \ No newline at end of file + proxy.edit_bone = name diff --git a/addons/bone_gizmo/dock.tscn b/addons/bone_gizmo/dock.tscn index 4f69fcd..27b3aef 100644 --- a/addons/bone_gizmo/dock.tscn +++ b/addons/bone_gizmo/dock.tscn @@ -36,21 +36,23 @@ margin_bottom = 16.0 texture = ExtResource( 2 ) [node name="FindGizmo" type="Button" parent="VBox"] +visible = false margin_top = 26.0 margin_right = 206.0 margin_bottom = 46.0 text = "Find Gizmo" [node name="ResetGizmo" type="Button" parent="VBox"] -margin_top = 56.0 +visible = false +margin_top = 26.0 margin_right = 206.0 -margin_bottom = 76.0 +margin_bottom = 46.0 text = "Reset Gizmo Matrix" [node name="RunGizmo" type="CheckButton" parent="VBox"] -margin_top = 86.0 +margin_top = 26.0 margin_right = 206.0 -margin_bottom = 126.0 +margin_bottom = 66.0 text = "Run Gizmo" [node name="SkeletonPath" type="LineEdit" parent="VBox"] @@ -81,27 +83,27 @@ placeholder_alpha = 0.3 caret_blink = true [node name="CreateTracks" type="Button" parent="VBox"] -margin_top = 136.0 +margin_top = 76.0 margin_right = 206.0 -margin_bottom = 156.0 +margin_bottom = 96.0 text = "Create Tracks" [node name="InsertKey" type="Button" parent="VBox"] -margin_top = 166.0 +margin_top = 106.0 margin_right = 206.0 -margin_bottom = 186.0 +margin_bottom = 126.0 text = "Insert Key" -[node name="FIND BONES" type="Label" parent="VBox"] -margin_top = 196.0 +[node name="FindBone" type="Label" parent="VBox"] +margin_top = 136.0 margin_right = 206.0 -margin_bottom = 210.0 -text = "FIND BONE:" +margin_bottom = 150.0 +text = "Find Bone:" [node name="bone_finder" parent="VBox" instance=ExtResource( 3 )] anchor_right = 0.0 anchor_bottom = 0.0 -margin_top = 220.0 +margin_top = 160.0 margin_right = 206.0 margin_bottom = 600.0 [connection signal="pressed" from="VBox/FindGizmo" to="." method="_on_FindGizmo_pressed"] diff --git a/addons/bone_gizmo/plugin.gd b/addons/bone_gizmo/plugin.gd index 0a683be..917206c 100644 --- a/addons/bone_gizmo/plugin.gd +++ b/addons/bone_gizmo/plugin.gd @@ -2,6 +2,7 @@ tool extends EditorPlugin var dock +var bone_gizmo func _enter_tree(): @@ -9,17 +10,29 @@ func _enter_tree(): # Has the additional effect of being reloadable after script changes. # You do not not need to restart editor. var base_dir = get_script().get_path().get_base_dir() - var bone_gizmo = load(base_dir.plus_file("bone_gizmo.gd")) var dock_scene = load(base_dir.plus_file("dock.tscn")) var icon = load(base_dir.plus_file("icon.png")) + bone_gizmo = load(base_dir.plus_file("bone_gizmo.gd")) dock = dock_scene.instance() add_control_to_dock( DOCK_SLOT_LEFT_UL, dock) add_custom_type("BoneGizmo", "Spatial", bone_gizmo, icon) + connect("scene_changed", self, "_on_scene_changed") + func _exit_tree(): remove_custom_type("BoneGizmo") remove_control_from_docks( dock ) # Remove the dock dock.free() # Erase the control from the memory + bone_gizmo = null + + disconnect("scene_changed", self, "_on_scene_changed") + +func _on_scene_changed(scene: Node) -> void: + dock.find_gizmo() +func handles(object: Object) -> bool: + if object is bone_gizmo: + dock.find_gizmo() + return false \ No newline at end of file From de8a9f6d5265530dddfc48fec2febc178c7c0348 Mon Sep 17 00:00:00 2001 From: PrestonKnopp Date: Wed, 19 Jun 2019 02:31:27 -0700 Subject: [PATCH 09/10] independent bone gizmo and dock workflow BoneGizmo nodes can be selected in scene tree inspector which activates the bone gizmo dock. The dock provides an interface to run gizmo tracking, create and insert animation tracks/keys, and finding bones by name. Additionally, bone filters are persisted via scene metadata. --- addons/bone_gizmo/bone_finder.gd | 15 +++-- addons/bone_gizmo/bone_finder.tscn | 2 +- addons/bone_gizmo/bone_gizmo.gd | 28 ++++++-- addons/bone_gizmo/dock.gd | 104 ++++++++++------------------- addons/bone_gizmo/dock.tscn | 13 ++++ addons/bone_gizmo/plugin.gd | 27 ++++++-- 6 files changed, 104 insertions(+), 85 deletions(-) diff --git a/addons/bone_gizmo/bone_finder.gd b/addons/bone_gizmo/bone_finder.gd index 325fb5d..abae82a 100644 --- a/addons/bone_gizmo/bone_finder.gd +++ b/addons/bone_gizmo/bone_finder.gd @@ -4,9 +4,16 @@ extends VBoxContainer signal bone_selected(this, name, id) onready var _bone_list: ItemList = $bone_list as ItemList +onready var _filter_edit: LineEdit = find_node('filter') as LineEdit var _skel: Skeleton -var _filter := '' + +var filter := '' setget set_filter,get_filter +func get_filter() -> String: return filter +func set_filter(new_val: String): + filter = new_val + _filter_edit.text = filter + refresh_bone_list() func set_skeleton(skeleton: Skeleton): if skeleton == null: @@ -23,14 +30,14 @@ func refresh_bone_list(): _bone_list.clear() for id in _skel.get_bone_count(): var name = _skel.get_bone_name(id) - if name.findn(_filter) > -1: + if filter == "" or name.findn(filter) > -1: _bone_list.add_item(name) _bone_list.set_item_metadata(_bone_list.get_item_count() - 1, {name = name, id = id}) func _on_filter_text_changed(new_text: String) -> void: - _filter = new_text + filter = new_text refresh_bone_list() -func _on_bone_list_item_activated(index: int) -> void: +func _on_bone_list_item_selected(index: int) -> void: var meta = _bone_list.get_item_metadata(index) emit_signal("bone_selected", self, meta.name, meta.id) diff --git a/addons/bone_gizmo/bone_finder.tscn b/addons/bone_gizmo/bone_finder.tscn index ffc9046..708a92f 100644 --- a/addons/bone_gizmo/bone_finder.tscn +++ b/addons/bone_gizmo/bone_finder.tscn @@ -34,4 +34,4 @@ margin_bottom = 600.0 size_flags_horizontal = 3 size_flags_vertical = 3 [connection signal="text_changed" from="HBoxContainer/filter" to="." method="_on_filter_text_changed"] -[connection signal="item_activated" from="bone_list" to="." method="_on_bone_list_item_activated"] +[connection signal="item_selected" from="bone_list" to="." method="_on_bone_list_item_selected"] diff --git a/addons/bone_gizmo/bone_gizmo.gd b/addons/bone_gizmo/bone_gizmo.gd index f40f77c..5eab8ad 100644 --- a/addons/bone_gizmo/bone_gizmo.gd +++ b/addons/bone_gizmo/bone_gizmo.gd @@ -1,11 +1,22 @@ tool extends Spatial +signal path_changed(what) + # All paths are must be relative to the node (BoneGizmo) -export(NodePath) var skeleton_path = @"../Skeleton" -export(NodePath) var animation_path = @"../AnimationPlayer" +export(NodePath) var skeleton_path = @"../Skeleton" setget set_skeleton_path +func set_skeleton_path(new_val): + if new_val == skeleton_path: + return + skeleton_path = new_val + emit_signal("path_changed", "skeleton") -var edit_bone = "" +export(NodePath) var animation_path = @"../AnimationPlayer" setget set_animation_path +func set_animation_path(new_val): + if new_val == animation_path: + return + animation_path = new_val + emit_signal("path_changed", "animation") var running: bool setget set_running,get_running func get_running() -> bool: return running @@ -17,6 +28,15 @@ func set_running(new_val: bool) -> void: set_process(false) running = new_val +var edit_bone_filter setget set_edit_bone_filter,get_edit_bone_filter +func get_edit_bone_filter(): + return get_meta("edit_bone_filter") if has_meta("edit_bone_filter") else "" +func set_edit_bone_filter(new_val): + set_meta("edit_bone_filter", new_val) + +var edit_bone = "" +var allowed_to_run = false + func _ready(): set_running(false) @@ -29,7 +49,7 @@ func reset() -> void: transform = Transform() func can_run() -> bool: - return (get_skeleton() != null) and (get_edit_bone_index() != -1) + return allowed_to_run and (get_skeleton() != null) and (get_edit_bone_index() != -1) func get_animation_player() -> AnimationPlayer: return get_node(animation_path) as AnimationPlayer diff --git a/addons/bone_gizmo/dock.gd b/addons/bone_gizmo/dock.gd index 35121dc..64d7a71 100644 --- a/addons/bone_gizmo/dock.gd +++ b/addons/bone_gizmo/dock.gd @@ -1,98 +1,64 @@ tool extends Control -class BoneGizmoProxy: - static func make_proxy(node: Node) -> BoneGizmoProxy: - if node == null: - return NullBoneGizmoProxy.new() - return BoneGizmoProxy.new(node) - - var _node: Node - - func _init(node: Node) -> void: - _node = node - - var edit_bone: String setget set_eb,get_eb - var running: bool setget set_running,get_running - func set_eb(eb): _node.edit_bone = eb - func get_eb(): return _node.edit_bone - func set_running(new_val: bool) -> void: _node.set_running(new_val) - func get_running() -> bool: return _node.running - func can_run() -> bool: return _node.can_run() - func get_animation_player() -> AnimationPlayer: return _node.get_animation_player() - func get_skeleton() -> Skeleton: return _node.get_skeleton() - func get_edit_bone_index() -> int: return _node.get_edit_bone_index() - func create_tracks(): _node.create_tracks() - func insert_key(): _node.insert_key() - func reset(): _node.reset() - func on_tree_exit_sig(target, callback): - if not _node.is_connected("tree_exited", target, callback): - _node.connect("tree_exited", target, callback) - func off_tree_exit_sig(target, callback): _node.disconnect("tree_exited", target, callback) - -class NullBoneGizmoProxy extends BoneGizmoProxy: - func _init().(null): pass - func set_eb(eb): pass - func get_eb(): return '' - func set_running(new_val: bool) -> void: pass - func get_running() -> bool: return false - func can_run() -> bool: return false - func get_animation_player() -> AnimationPlayer: return null - func get_skeleton() -> Skeleton: return null - func get_edit_bone_index() -> int: return -1 - func create_tracks(): pass - func insert_key(): pass - func reset(): pass - func on_tree_exit_sig(target, callback): pass - func off_tree_exit_sig(target, callback): pass - -var proxy: BoneGizmoProxy = NullBoneGizmoProxy.new() onready var bone_finder = find_node('bone_finder') +onready var run_gizmo_button = find_node('RunGizmo') -func find_gizmo(): - proxy = NullBoneGizmoProxy.new() - - var scene_root = get_tree().get_edited_scene_root() - if scene_root != null: - proxy = BoneGizmoProxy.make_proxy(scene_root.find_node("BoneGizmo", true, false)) +var gizmo setget set_gizmo,get_gizmo +func get_gizmo(): return gizmo +func set_gizmo(new_val): + if is_instance_valid(gizmo): + gizmo.running = false + gizmo.disconnect("path_changed", self, "_on_gizmo_path_changed") - if proxy is NullBoneGizmoProxy: - print("BoneGizmo node not found!") + gizmo = new_val + if gizmo == null: + $Disabled.visible = true + run_gizmo_button.pressed = false + bone_finder.set_skeleton(null) + bone_finder.set_filter('') else: - print("BoneGizmo node found!") - - proxy.on_tree_exit_sig(self, '_on_bone_gizmo_exited_tree') - bone_finder.set_skeleton(proxy.get_skeleton()) + $Disabled.visible = false + bone_finder.set_skeleton(gizmo.get_skeleton()) + bone_finder.set_filter(gizmo.edit_bone_filter) + run_gizmo_button.pressed = gizmo.can_run() + gizmo.running = gizmo.can_run() + gizmo.connect("path_changed", self, "_on_gizmo_path_changed") -func _on_bone_gizmo_exited_tree(): - proxy.off_tree_exit_sig(self, '_on_bone_gizmo_exited_tree') - find_gizmo() +func _on_gizmo_path_changed(what): + if what == "skeleton": + bone_finder.set_skeleton(gizmo.get_skeleton()) + gizmo.running = gizmo.can_run() func _on_ResetGizmo_pressed(): - proxy.reset() + gizmo.reset() print("BoneGizmo reset transform") func _on_RunGizmo_toggled(button_pressed): - proxy.running = button_pressed - print("BoneGizmo running: ", proxy.running) + gizmo.allowed_to_run = button_pressed + gizmo.running = gizmo.can_run() + print("BoneGizmo running: ", gizmo.running) func _on_CreateTracks_pressed(): if check_anim_track_operation(): - proxy.create_tracks() + gizmo.create_tracks() func _on_InsertKey_pressed(): if check_anim_track_operation(): - proxy.insert_key() + gizmo.insert_key() func check_anim_track_operation() -> bool: var passed = true - if proxy.get_skeleton() == null: + if gizmo.get_skeleton() == null: print("BoneGizmo Invalid skeleton path") passed = false - if proxy.get_animation_player() == null: + if gizmo.get_animation_player() == null: print("BoneGizmo Invalid animation path") passed = false return passed func _on_bone_finder_bone_selected(this, name, id) -> void: - proxy.edit_bone = name + gizmo.running = false + gizmo.edit_bone = name + gizmo.edit_bone_filter = this.filter + gizmo.running = gizmo.can_run() diff --git a/addons/bone_gizmo/dock.tscn b/addons/bone_gizmo/dock.tscn index 27b3aef..e298442 100644 --- a/addons/bone_gizmo/dock.tscn +++ b/addons/bone_gizmo/dock.tscn @@ -106,6 +106,19 @@ anchor_bottom = 0.0 margin_top = 160.0 margin_right = 206.0 margin_bottom = 600.0 + +[node name="Disabled" type="Panel" parent="."] +self_modulate = Color( 0.290196, 0.290196, 0.290196, 0.564706 ) +anchor_right = 1.0 +anchor_bottom = 1.0 + +[node name="Label" type="Label" parent="Disabled"] +anchor_right = 1.0 +anchor_bottom = 1.0 +text = "Select a BoneGizmo node" +align = 1 +valign = 1 +autowrap = true [connection signal="pressed" from="VBox/FindGizmo" to="." method="_on_FindGizmo_pressed"] [connection signal="pressed" from="VBox/ResetGizmo" to="." method="_on_ResetGizmo_pressed"] [connection signal="toggled" from="VBox/RunGizmo" to="." method="_on_RunGizmo_toggled"] diff --git a/addons/bone_gizmo/plugin.gd b/addons/bone_gizmo/plugin.gd index 917206c..b1dbfcc 100644 --- a/addons/bone_gizmo/plugin.gd +++ b/addons/bone_gizmo/plugin.gd @@ -1,3 +1,13 @@ +# New Workflow Idea +# ----------------- +# Only enable bone gizmo dock when +# - bone has been chosen +# - BoneGizmo node is selected +# - BoneGizmo AnimationPlayer is not playing/stop when selected +# Auto "Run Gizmo" when dock is enabled +# Use edit_bone associated with BoneGizmo node. +# - You can have multiple BoneGizmos +# - Selecting a BoneGizmo activates it. tool extends EditorPlugin @@ -18,21 +28,24 @@ func _enter_tree(): add_control_to_dock( DOCK_SLOT_LEFT_UL, dock) add_custom_type("BoneGizmo", "Spatial", bone_gizmo, icon) - + connect("scene_changed", self, "_on_scene_changed") func _exit_tree(): + disconnect("scene_changed", self, "_on_scene_changed") remove_custom_type("BoneGizmo") remove_control_from_docks( dock ) # Remove the dock dock.free() # Erase the control from the memory bone_gizmo = null - disconnect("scene_changed", self, "_on_scene_changed") - -func _on_scene_changed(scene: Node) -> void: - dock.find_gizmo() +func _on_scene_changed(scene): + if scene == null: + dock.gizmo = null func handles(object: Object) -> bool: if object is bone_gizmo: - dock.find_gizmo() - return false \ No newline at end of file + dock.gizmo = object + return true + else: + dock.gizmo = null + return false \ No newline at end of file From d31d831f2bd92f1de9bc6865bd78f46ebeef6cf3 Mon Sep 17 00:00:00 2001 From: PrestonKnopp Date: Wed, 19 Jun 2019 02:54:36 -0700 Subject: [PATCH 10/10] update readme --- README.md | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index e55828d..d043e5a 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,24 @@ -# BoneEditor +# BoneGizmo + Plugin for Godot Engine Simple Gizmo so you can edit bone transforms easily. -# How to use: -Append the node "BoneGizmo" to your scene -Select the node and change the exposed variables "Skeleton Path" as a string path to the Skeleton Node. -Change the exposed variable "Edit Bone" as a string name of the bone you want to edit. (Listed in the Skeleton node) +## How to use: + +1. Enable plugin. +2. Add a BoneGizmo node to your scene. +3. Select BoneGizmo in scene tree and ensure it's properties points to a valid + Skeleton node and an optional AnimationPlayer node. +4. When you select a BoneGizmo node + - The BoneGizmo dock enables and loads up the selected BoneGizmo. + - You can then search for a bone. A highlighted bone is a selected bone. + - Bone filters are persisted via metadata for you to continue your work at + another time. +5. Hit *Run Gizmo* in the BoneGizmo dock. +6. Translate, rotate, and scale your selected bone. + +## Caveats + +You should disable *Run Gizmo* when an animation is playing. + +BoneGizmo nodes will remain in your scene tree.