Skip to content

Commit f019835

Browse files
TokageItLablyuma
andcommitted
Implemented SkeletonEditorGizmo
Co-authored-by: Lyuma <[email protected]>
1 parent ce0268a commit f019835

36 files changed

+1302
-416
lines changed

doc/classes/EditorPlugin.xml

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -96,22 +96,22 @@
9696
</description>
9797
</method>
9898
<method name="_forward_3d_gui_input" qualifiers="virtual">
99-
<return type="bool" />
99+
<return type="int" />
100100
<argument index="0" name="viewport_camera" type="Camera3D" />
101101
<argument index="1" name="event" type="InputEvent" />
102102
<description>
103103
Called when there is a root node in the current edited scene, [method _handles] is implemented and an [InputEvent] happens in the 3D viewport. Intercepts the [InputEvent], if [code]return true[/code] [EditorPlugin] consumes the [code]event[/code], otherwise forwards [code]event[/code] to other Editor classes. Example:
104104
[codeblocks]
105105
[gdscript]
106106
# Prevents the InputEvent to reach other Editor classes.
107-
func _forward_3d_gui_input(camera, event):
108-
return true
107+
func _forward_spatial_gui_input(camera, event):
108+
return EditorPlugin.AFTER_GUI_INPUT_STOP
109109
[/gdscript]
110110
[csharp]
111111
// Prevents the InputEvent to reach other Editor classes.
112112
public override bool _Forward3dGuiInput(Camera3D camera, InputEvent @event)
113113
{
114-
return true;
114+
return EditorPlugin.AFTER_GUI_INPUT_STOP;
115115
}
116116
[/csharp]
117117
[/codeblocks]
@@ -185,8 +185,8 @@
185185
Called when there is a root node in the current edited scene, [method _handles] is implemented and an [InputEvent] happens in the 2D viewport. Intercepts the [InputEvent], if [code]return true[/code] [EditorPlugin] consumes the [code]event[/code], otherwise forwards [code]event[/code] to other Editor classes. Example:
186186
[codeblocks]
187187
[gdscript]
188-
# Prevents the InputEvent to reach other Editor classes
189-
func _forward_canvas_gui_input(event):
188+
# Prevents the InputEvent to reach other Editor classes.
189+
func _forward_spatial_gui_input(camera, event):
190190
return true
191191
[/gdscript]
192192
[csharp]
@@ -202,13 +202,19 @@
202202
[gdscript]
203203
# Consumes InputEventMouseMotion and forwards other InputEvent types.
204204
func _forward_canvas_gui_input(event):
205-
return event is InputEventMouseMotion
205+
if (event is InputEventMouseMotion) {
206+
return true
207+
}
208+
return false
206209
[/gdscript]
207210
[csharp]
208211
// Consumes InputEventMouseMotion and forwards other InputEvent types.
209212
public override bool ForwardCanvasGuiInput(InputEvent @event)
210213
{
211-
return @event is InputEventMouseMotion;
214+
if (@event is InputEventMouseMotion) {
215+
return true;
216+
}
217+
return false
212218
}
213219
[/csharp]
214220
[/codeblocks]

doc/classes/Node3D.xml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,15 @@
212212
Sets whether the node notifies about its global and local transformation changes. [Node3D] will not propagate this by default, unless it is in the editor context and it has a valid gizmo.
213213
</description>
214214
</method>
215+
<method name="set_subgizmo_selection">
216+
<return type="void" />
217+
<argument index="0" name="gizmo" type="Node3DGizmo" />
218+
<argument index="1" name="id" type="int" />
219+
<argument index="2" name="transform" type="Transform3D" />
220+
<description>
221+
Set subgizmo selection for this node in the editor.
222+
</description>
223+
</method>
215224
<method name="show">
216225
<return type="void" />
217226
<description>

doc/classes/Skeleton3D.xml

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,13 @@
189189
This is helper function to make using [method Transform3D.looking_at] easier with bone poses.
190190
</description>
191191
</method>
192+
<method name="is_bone_enabled" qualifiers="const">
193+
<return type="bool" />
194+
<argument index="0" name="bone_idx" type="int" />
195+
<description>
196+
Returns whether the bone pose for the bone at [code]bone_idx[/code] is enabled.
197+
</description>
198+
</method>
192199
<method name="is_bone_rest_disabled" qualifiers="const">
193200
<return type="bool" />
194201
<argument index="0" name="bone_idx" type="int" />
@@ -282,6 +289,14 @@
282289
Disables the rest pose for the bone at [code]bone_idx[/code] if [code]true[/code], enables the bone rest if [code]false[/code].
283290
</description>
284291
</method>
292+
<method name="set_bone_enabled">
293+
<return type="void" />
294+
<argument index="0" name="bone_idx" type="int" />
295+
<argument index="1" name="enabled" type="bool" default="true" />
296+
<description>
297+
Disables the pose for the bone at [code]bone_idx[/code] if [code]false[/code], enables the bone pose if [code]true[/code].
298+
</description>
299+
</method>
285300
<method name="set_bone_global_pose_override">
286301
<return type="void" />
287302
<argument index="0" name="bone_idx" type="int" />
@@ -365,8 +380,15 @@
365380
<members>
366381
<member name="animate_physical_bones" type="bool" setter="set_animate_physical_bones" getter="get_animate_physical_bones" default="true">
367382
</member>
383+
<member name="show_rest_only" type="bool" setter="set_show_rest_only" getter="is_show_rest_only" default="false">
384+
</member>
368385
</members>
369386
<signals>
387+
<signal name="bone_enabled_changed">
388+
<argument index="0" name="bone_idx" type="int" />
389+
<description>
390+
</description>
391+
</signal>
370392
<signal name="bone_pose_changed">
371393
<argument index="0" name="bone_idx" type="int" />
372394
<description>
@@ -377,6 +399,10 @@
377399
<description>
378400
</description>
379401
</signal>
402+
<signal name="show_rest_only_changed">
403+
<description>
404+
</description>
405+
</signal>
380406
</signals>
381407
<constants>
382408
<constant name="NOTIFICATION_UPDATE_SKELETON" value="50">

editor/animation_track_editor.cpp

Lines changed: 36 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3359,7 +3359,7 @@ void AnimationTrackEditor::_query_insert(const InsertData &p_id) {
33593359
insert_data.push_back(p_id);
33603360

33613361
bool reset_allowed = true;
3362-
AnimationPlayer *player = AnimationPlayerEditor::singleton->get_player();
3362+
AnimationPlayer *player = AnimationPlayerEditor::get_singleton()->get_player();
33633363
if (player->has_animation("RESET") && player->get_animation("RESET") == animation) {
33643364
// Avoid messing with the reset animation itself
33653365
reset_allowed = false;
@@ -3528,6 +3528,31 @@ void AnimationTrackEditor::insert_transform_key(Node3D *p_node, const String &p_
35283528
_query_insert(id);
35293529
}
35303530

3531+
bool AnimationTrackEditor::has_transform_track(Node3D *p_node, const String &p_sub) {
3532+
if (!keying) {
3533+
return false;
3534+
}
3535+
if (!animation.is_valid()) {
3536+
return false;
3537+
}
3538+
if (!root) {
3539+
return false;
3540+
}
3541+
3542+
//let's build a node path
3543+
String path = root->get_path_to(p_node);
3544+
if (p_sub != "") {
3545+
path += ":" + p_sub;
3546+
}
3547+
int track_id = animation->find_track(path);
3548+
if (track_id >= 0) {
3549+
if (animation->track_get_type(track_id) == Animation::TYPE_TRANSFORM3D) {
3550+
return true;
3551+
}
3552+
}
3553+
return false;
3554+
}
3555+
35313556
void AnimationTrackEditor::_insert_animation_key(NodePath p_path, const Variant &p_value) {
35323557
String path = p_path;
35333558

@@ -3571,7 +3596,7 @@ void AnimationTrackEditor::insert_node_value_key(Node *p_node, const String &p_p
35713596
String path = root->get_path_to(node);
35723597

35733598
if (Object::cast_to<AnimationPlayer>(node) && p_property == "current_animation") {
3574-
if (node == AnimationPlayerEditor::singleton->get_player()) {
3599+
if (node == AnimationPlayerEditor::get_singleton()->get_player()) {
35753600
EditorNode::get_singleton()->show_warning(TTR("AnimationPlayer can't animate itself, only other players."));
35763601
return;
35773602
}
@@ -3672,7 +3697,7 @@ void AnimationTrackEditor::insert_value_key(const String &p_property, const Vari
36723697
String path = root->get_path_to(node);
36733698

36743699
if (Object::cast_to<AnimationPlayer>(node) && p_property == "current_animation") {
3675-
if (node == AnimationPlayerEditor::singleton->get_player()) {
3700+
if (node == AnimationPlayerEditor::get_singleton()->get_player()) {
36763701
EditorNode::get_singleton()->show_warning(TTR("AnimationPlayer can't animate itself, only other players."));
36773702
return;
36783703
}
@@ -3752,17 +3777,17 @@ void AnimationTrackEditor::insert_value_key(const String &p_property, const Vari
37523777
}
37533778

37543779
Ref<Animation> AnimationTrackEditor::_create_and_get_reset_animation() {
3755-
AnimationPlayer *player = AnimationPlayerEditor::singleton->get_player();
3780+
AnimationPlayer *player = AnimationPlayerEditor::get_singleton()->get_player();
37563781
if (player->has_animation("RESET")) {
37573782
return player->get_animation("RESET");
37583783
} else {
37593784
Ref<Animation> reset_anim;
37603785
reset_anim.instantiate();
37613786
reset_anim->set_length(ANIM_MIN_LENGTH);
37623787
undo_redo->add_do_method(player, "add_animation", "RESET", reset_anim);
3763-
undo_redo->add_do_method(AnimationPlayerEditor::singleton, "_animation_player_changed", player);
3788+
undo_redo->add_do_method(AnimationPlayerEditor::get_singleton(), "_animation_player_changed", player);
37643789
undo_redo->add_undo_method(player, "remove_animation", "RESET");
3765-
undo_redo->add_undo_method(AnimationPlayerEditor::singleton, "_animation_player_changed", player);
3790+
undo_redo->add_undo_method(AnimationPlayerEditor::get_singleton(), "_animation_player_changed", player);
37663791
return reset_anim;
37673792
}
37683793
}
@@ -4446,7 +4471,7 @@ void AnimationTrackEditor::_new_track_node_selected(NodePath p_path) {
44464471
return;
44474472
}
44484473

4449-
if (node == AnimationPlayerEditor::singleton->get_player()) {
4474+
if (node == AnimationPlayerEditor::get_singleton()->get_player()) {
44504475
EditorNode::get_singleton()->show_warning(TTR("AnimationPlayer can't animate itself, only other players."));
44514476
return;
44524477
}
@@ -5173,7 +5198,7 @@ void AnimationTrackEditor::_anim_duplicate_keys(bool transpose) {
51735198
}
51745199

51755200
void AnimationTrackEditor::_edit_menu_about_to_popup() {
5176-
AnimationPlayer *player = AnimationPlayerEditor::singleton->get_player();
5201+
AnimationPlayer *player = AnimationPlayerEditor::get_singleton()->get_player();
51775202
edit->get_popup()->set_item_disabled(edit->get_popup()->get_item_index(EDIT_APPLY_RESET), !player->can_apply_reset());
51785203
}
51795204

@@ -5517,7 +5542,7 @@ void AnimationTrackEditor::_edit_menu_pressed(int p_option) {
55175542
goto_prev_step(false);
55185543
} break;
55195544
case EDIT_APPLY_RESET: {
5520-
AnimationPlayerEditor::singleton->get_player()->apply_reset(true);
5545+
AnimationPlayerEditor::get_singleton()->get_player()->apply_reset(true);
55215546

55225547
} break;
55235548
case EDIT_OPTIMIZE_ANIMATION: {
@@ -5537,9 +5562,9 @@ void AnimationTrackEditor::_edit_menu_pressed(int p_option) {
55375562
case EDIT_CLEAN_UP_ANIMATION_CONFIRM: {
55385563
if (cleanup_all->is_pressed()) {
55395564
List<StringName> names;
5540-
AnimationPlayerEditor::singleton->get_player()->get_animation_list(&names);
5565+
AnimationPlayerEditor::get_singleton()->get_player()->get_animation_list(&names);
55415566
for (const StringName &E : names) {
5542-
_cleanup_animation(AnimationPlayerEditor::singleton->get_player()->get_animation(E));
5567+
_cleanup_animation(AnimationPlayerEditor::get_singleton()->get_player()->get_animation(E));
55435568
}
55445569
} else {
55455570
_cleanup_animation(animation);

editor/animation_track_editor.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -531,6 +531,7 @@ class AnimationTrackEditor : public VBoxContainer {
531531
void insert_node_value_key(Node *p_node, const String &p_property, const Variant &p_value, bool p_only_if_exists = false);
532532
void insert_value_key(const String &p_property, const Variant &p_value, bool p_advance);
533533
void insert_transform_key(Node3D *p_node, const String &p_sub, const Transform3D &p_xform);
534+
bool has_transform_track(Node3D *p_node, const String &p_sub);
534535

535536
void show_select_node_warning(bool p_show);
536537

editor/editor_node.cpp

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6930,7 +6930,7 @@ EditorNode::EditorNode() {
69306930
add_child(editor_interface);
69316931

69326932
//more visually meaningful to have this later
6933-
raise_bottom_panel_item(AnimationPlayerEditor::singleton);
6933+
raise_bottom_panel_item(AnimationPlayerEditor::get_singleton());
69346934

69356935
add_editor_plugin(VersionControlEditorPlugin::get_singleton());
69366936
add_editor_plugin(memnew(ShaderEditorPlugin(this)));
@@ -7204,20 +7204,24 @@ bool EditorPluginList::forward_gui_input(const Ref<InputEvent> &p_event) {
72047204
return discard;
72057205
}
72067206

7207-
bool EditorPluginList::forward_spatial_gui_input(Camera3D *p_camera, const Ref<InputEvent> &p_event, bool serve_when_force_input_enabled) {
7208-
bool discard = false;
7207+
EditorPlugin::AfterGUIInput EditorPluginList::forward_spatial_gui_input(Camera3D *p_camera, const Ref<InputEvent> &p_event, bool serve_when_force_input_enabled) {
7208+
EditorPlugin::AfterGUIInput after = EditorPlugin::AFTER_GUI_INPUT_PASS;
72097209

72107210
for (int i = 0; i < plugins_list.size(); i++) {
72117211
if ((!serve_when_force_input_enabled) && plugins_list[i]->is_input_event_forwarding_always_enabled()) {
72127212
continue;
72137213
}
72147214

7215-
if (plugins_list[i]->forward_spatial_gui_input(p_camera, p_event)) {
7216-
discard = true;
7215+
EditorPlugin::AfterGUIInput current_after = plugins_list[i]->forward_spatial_gui_input(p_camera, p_event);
7216+
if (current_after == EditorPlugin::AFTER_GUI_INPUT_STOP) {
7217+
after = EditorPlugin::AFTER_GUI_INPUT_STOP;
7218+
}
7219+
if (after != EditorPlugin::AFTER_GUI_INPUT_STOP && current_after == EditorPlugin::AFTER_GUI_INPUT_DESELECT) {
7220+
after = EditorPlugin::AFTER_GUI_INPUT_DESELECT;
72177221
}
72187222
}
72197223

7220-
return discard;
7224+
return after;
72217225
}
72227226

72237227
void EditorPluginList::forward_canvas_draw_over_viewport(Control *p_overlay) {

editor/editor_node.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -942,7 +942,7 @@ class EditorPluginList : public Object {
942942
bool forward_gui_input(const Ref<InputEvent> &p_event);
943943
void forward_canvas_draw_over_viewport(Control *p_overlay);
944944
void forward_canvas_force_draw_over_viewport(Control *p_overlay);
945-
bool forward_spatial_gui_input(Camera3D *p_camera, const Ref<InputEvent> &p_event, bool serve_when_force_input_enabled);
945+
EditorPlugin::AfterGUIInput forward_spatial_gui_input(Camera3D *p_camera, const Ref<InputEvent> &p_event, bool serve_when_force_input_enabled);
946946
void forward_spatial_draw_over_viewport(Control *p_overlay);
947947
void forward_spatial_force_draw_over_viewport(Control *p_overlay);
948948
void add_plugin(EditorPlugin *p_plugin);

editor/editor_plugin.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -593,14 +593,14 @@ int EditorPlugin::update_overlays() const {
593593
}
594594
}
595595

596-
bool EditorPlugin::forward_spatial_gui_input(Camera3D *p_camera, const Ref<InputEvent> &p_event) {
597-
bool success;
596+
EditorPlugin::AfterGUIInput EditorPlugin::forward_spatial_gui_input(Camera3D *p_camera, const Ref<InputEvent> &p_event) {
597+
int success;
598598

599599
if (GDVIRTUAL_CALL(_forward_3d_gui_input, p_camera, p_event, success)) {
600-
return success;
600+
return static_cast<EditorPlugin::AfterGUIInput>(success);
601601
}
602602

603-
return false;
603+
return EditorPlugin::AFTER_GUI_INPUT_PASS;
604604
}
605605

606606
void EditorPlugin::forward_spatial_draw_over_viewport(Control *p_overlay) {

editor/editor_plugin.h

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@ class EditorPlugin : public Node {
151151
GDVIRTUAL1R(bool, _forward_canvas_gui_input, Ref<InputEvent>)
152152
GDVIRTUAL1(_forward_canvas_draw_over_viewport, Control *)
153153
GDVIRTUAL1(_forward_canvas_force_draw_over_viewport, Control *)
154-
GDVIRTUAL2R(bool, _forward_3d_gui_input, Camera3D *, Ref<InputEvent>)
154+
GDVIRTUAL2R(int, _forward_3d_gui_input, Camera3D *, Ref<InputEvent>)
155155
GDVIRTUAL1(_forward_3d_draw_over_viewport, Control *)
156156
GDVIRTUAL1(_forward_3d_force_draw_over_viewport, Control *)
157157
GDVIRTUAL0RC(String, _get_plugin_name)
@@ -200,6 +200,12 @@ class EditorPlugin : public Node {
200200
DOCK_SLOT_MAX
201201
};
202202

203+
enum AfterGUIInput {
204+
AFTER_GUI_INPUT_PASS,
205+
AFTER_GUI_INPUT_STOP,
206+
AFTER_GUI_INPUT_DESELECT
207+
};
208+
203209
//TODO: send a resource for editing to the editor node?
204210

205211
void add_control_to_container(CustomControlContainer p_location, Control *p_control);
@@ -228,7 +234,7 @@ class EditorPlugin : public Node {
228234
virtual void forward_canvas_draw_over_viewport(Control *p_overlay);
229235
virtual void forward_canvas_force_draw_over_viewport(Control *p_overlay);
230236

231-
virtual bool forward_spatial_gui_input(Camera3D *p_camera, const Ref<InputEvent> &p_event);
237+
virtual EditorPlugin::AfterGUIInput forward_spatial_gui_input(Camera3D *p_camera, const Ref<InputEvent> &p_event);
232238
virtual void forward_spatial_draw_over_viewport(Control *p_overlay);
233239
virtual void forward_spatial_force_draw_over_viewport(Control *p_overlay);
234240

editor/editor_themes.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,7 @@ void editor_register_and_generate_icons(Ref<Theme> p_theme, bool p_dark_theme =
213213
exceptions.insert("EditorPivot");
214214
exceptions.insert("EditorHandle");
215215
exceptions.insert("Editor3DHandle");
216+
exceptions.insert("EditorBoneHandle");
216217
exceptions.insert("Godot");
217218
exceptions.insert("Sky");
218219
exceptions.insert("EditorControlAnchor");

0 commit comments

Comments
 (0)