Skip to content

Commit

Permalink
Implemented SkeletonEditorGizmo
Browse files Browse the repository at this point in the history
Co-authored-by: Lyuma <xn.lyuma@gmail.com>
  • Loading branch information
TokageItLab and lyuma committed Sep 13, 2021
1 parent e6106ed commit ba49f3e
Show file tree
Hide file tree
Showing 36 changed files with 1,298 additions and 416 deletions.
22 changes: 14 additions & 8 deletions doc/classes/EditorPlugin.xml
Original file line number Diff line number Diff line change
Expand Up @@ -96,22 +96,22 @@
</description>
</method>
<method name="_forward_3d_gui_input" qualifiers="virtual">
<return type="bool" />
<return type="int" />
<argument index="0" name="viewport_camera" type="Camera3D" />
<argument index="1" name="event" type="InputEvent" />
<description>
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:
[codeblocks]
[gdscript]
# Prevents the InputEvent to reach other Editor classes.
func _forward_3d_gui_input(camera, event):
return true
func _forward_spatial_gui_input(camera, event):
return EditorPlugin.AFTER_GUI_INPUT_STOP
[/gdscript]
[csharp]
// Prevents the InputEvent to reach other Editor classes.
public override bool _Forward3dGuiInput(Camera3D camera, InputEvent @event)
{
return true;
return EditorPlugin.AFTER_GUI_INPUT_STOP;
}
[/csharp]
[/codeblocks]
Expand Down Expand Up @@ -185,8 +185,8 @@
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:
[codeblocks]
[gdscript]
# Prevents the InputEvent to reach other Editor classes
func _forward_canvas_gui_input(event):
# Prevents the InputEvent to reach other Editor classes.
func _forward_spatial_gui_input(camera, event):
return true
[/gdscript]
[csharp]
Expand All @@ -202,13 +202,19 @@
[gdscript]
# Consumes InputEventMouseMotion and forwards other InputEvent types.
func _forward_canvas_gui_input(event):
return event is InputEventMouseMotion
if (event is InputEventMouseMotion) {
return true
}
return false
[/gdscript]
[csharp]
// Consumes InputEventMouseMotion and forwards other InputEvent types.
public override bool ForwardCanvasGuiInput(InputEvent @event)
{
return @event is InputEventMouseMotion;
if (@event is InputEventMouseMotion) {
return true;
}
return false
}
[/csharp]
[/codeblocks]
Expand Down
9 changes: 9 additions & 0 deletions doc/classes/Node3D.xml
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,15 @@
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.
</description>
</method>
<method name="set_subgizmo_selection">
<return type="void" />
<argument index="0" name="gizmo" type="Node3DGizmo" />
<argument index="1" name="id" type="int" />
<argument index="2" name="transform" type="Transform3D" />
<description>
Set subgizmo selection for this node in the editor.
</description>
</method>
<method name="show">
<return type="void" />
<description>
Expand Down
26 changes: 26 additions & 0 deletions doc/classes/Skeleton3D.xml
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,13 @@
This is helper function to make using [method Transform3D.looking_at] easier with bone poses.
</description>
</method>
<method name="is_bone_enabled" qualifiers="const">
<return type="bool" />
<argument index="0" name="bone_idx" type="int" />
<description>
Returns whether the bone pose for the bone at [code]bone_idx[/code] is enabled.
</description>
</method>
<method name="is_bone_rest_disabled" qualifiers="const">
<return type="bool" />
<argument index="0" name="bone_idx" type="int" />
Expand Down Expand Up @@ -282,6 +289,14 @@
Disables the rest pose for the bone at [code]bone_idx[/code] if [code]true[/code], enables the bone rest if [code]false[/code].
</description>
</method>
<method name="set_bone_enabled">
<return type="void" />
<argument index="0" name="bone_idx" type="int" />
<argument index="1" name="enabled" type="bool" default="true" />
<description>
Disables the pose for the bone at [code]bone_idx[/code] if [code]false[/code], enables the bone pose if [code]true[/code].
</description>
</method>
<method name="set_bone_global_pose_override">
<return type="void" />
<argument index="0" name="bone_idx" type="int" />
Expand Down Expand Up @@ -365,8 +380,15 @@
<members>
<member name="animate_physical_bones" type="bool" setter="set_animate_physical_bones" getter="get_animate_physical_bones" default="true">
</member>
<member name="show_rest_only" type="bool" setter="set_show_rest_only" getter="is_show_rest_only" default="false">
</member>
</members>
<signals>
<signal name="bone_enabled_changed">
<argument index="0" name="bone_idx" type="int" />
<description>
</description>
</signal>
<signal name="bone_pose_changed">
<argument index="0" name="bone_idx" type="int" />
<description>
Expand All @@ -377,6 +399,10 @@
<description>
</description>
</signal>
<signal name="show_rest_only_changed">
<description>
</description>
</signal>
</signals>
<constants>
<constant name="NOTIFICATION_UPDATE_SKELETON" value="50">
Expand Down
47 changes: 36 additions & 11 deletions editor/animation_track_editor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3362,7 +3362,7 @@ void AnimationTrackEditor::_query_insert(const InsertData &p_id) {
insert_data.push_back(p_id);

bool reset_allowed = true;
AnimationPlayer *player = AnimationPlayerEditor::singleton->get_player();
AnimationPlayer *player = AnimationPlayerEditor::get_singleton()->get_player();
if (player->has_animation("RESET") && player->get_animation("RESET") == animation) {
// Avoid messing with the reset animation itself
reset_allowed = false;
Expand Down Expand Up @@ -3531,6 +3531,31 @@ void AnimationTrackEditor::insert_transform_key(Node3D *p_node, const String &p_
_query_insert(id);
}

bool AnimationTrackEditor::has_transform_track(Node3D *p_node, const String &p_sub) {
if (!keying) {
return false;
}
if (!animation.is_valid()) {
return false;
}
if (!root) {
return false;
}

//let's build a node path
String path = root->get_path_to(p_node);
if (p_sub != "") {
path += ":" + p_sub;
}
int track_id = animation->find_track(path);
if (track_id >= 0) {
if (animation->track_get_type(track_id) == Animation::TYPE_TRANSFORM3D) {
return true;
}
}
return false;
}

void AnimationTrackEditor::_insert_animation_key(NodePath p_path, const Variant &p_value) {
String path = p_path;

Expand Down Expand Up @@ -3574,7 +3599,7 @@ void AnimationTrackEditor::insert_node_value_key(Node *p_node, const String &p_p
String path = root->get_path_to(node);

if (Object::cast_to<AnimationPlayer>(node) && p_property == "current_animation") {
if (node == AnimationPlayerEditor::singleton->get_player()) {
if (node == AnimationPlayerEditor::get_singleton()->get_player()) {
EditorNode::get_singleton()->show_warning(TTR("AnimationPlayer can't animate itself, only other players."));
return;
}
Expand Down Expand Up @@ -3675,7 +3700,7 @@ void AnimationTrackEditor::insert_value_key(const String &p_property, const Vari
String path = root->get_path_to(node);

if (Object::cast_to<AnimationPlayer>(node) && p_property == "current_animation") {
if (node == AnimationPlayerEditor::singleton->get_player()) {
if (node == AnimationPlayerEditor::get_singleton()->get_player()) {
EditorNode::get_singleton()->show_warning(TTR("AnimationPlayer can't animate itself, only other players."));
return;
}
Expand Down Expand Up @@ -3755,17 +3780,17 @@ void AnimationTrackEditor::insert_value_key(const String &p_property, const Vari
}

Ref<Animation> AnimationTrackEditor::_create_and_get_reset_animation() {
AnimationPlayer *player = AnimationPlayerEditor::singleton->get_player();
AnimationPlayer *player = AnimationPlayerEditor::get_singleton()->get_player();
if (player->has_animation("RESET")) {
return player->get_animation("RESET");
} else {
Ref<Animation> reset_anim;
reset_anim.instantiate();
reset_anim->set_length(ANIM_MIN_LENGTH);
undo_redo->add_do_method(player, "add_animation", "RESET", reset_anim);
undo_redo->add_do_method(AnimationPlayerEditor::singleton, "_animation_player_changed", player);
undo_redo->add_do_method(AnimationPlayerEditor::get_singleton(), "_animation_player_changed", player);
undo_redo->add_undo_method(player, "remove_animation", "RESET");
undo_redo->add_undo_method(AnimationPlayerEditor::singleton, "_animation_player_changed", player);
undo_redo->add_undo_method(AnimationPlayerEditor::get_singleton(), "_animation_player_changed", player);
return reset_anim;
}
}
Expand Down Expand Up @@ -4449,7 +4474,7 @@ void AnimationTrackEditor::_new_track_node_selected(NodePath p_path) {
return;
}

if (node == AnimationPlayerEditor::singleton->get_player()) {
if (node == AnimationPlayerEditor::get_singleton()->get_player()) {
EditorNode::get_singleton()->show_warning(TTR("AnimationPlayer can't animate itself, only other players."));
return;
}
Expand Down Expand Up @@ -5176,7 +5201,7 @@ void AnimationTrackEditor::_anim_duplicate_keys(bool transpose) {
}

void AnimationTrackEditor::_edit_menu_about_to_popup() {
AnimationPlayer *player = AnimationPlayerEditor::singleton->get_player();
AnimationPlayer *player = AnimationPlayerEditor::get_singleton()->get_player();
edit->get_popup()->set_item_disabled(edit->get_popup()->get_item_index(EDIT_APPLY_RESET), !player->can_apply_reset());
}

Expand Down Expand Up @@ -5520,7 +5545,7 @@ void AnimationTrackEditor::_edit_menu_pressed(int p_option) {
goto_prev_step(false);
} break;
case EDIT_APPLY_RESET: {
AnimationPlayerEditor::singleton->get_player()->apply_reset(true);
AnimationPlayerEditor::get_singleton()->get_player()->apply_reset(true);

} break;
case EDIT_OPTIMIZE_ANIMATION: {
Expand All @@ -5540,9 +5565,9 @@ void AnimationTrackEditor::_edit_menu_pressed(int p_option) {
case EDIT_CLEAN_UP_ANIMATION_CONFIRM: {
if (cleanup_all->is_pressed()) {
List<StringName> names;
AnimationPlayerEditor::singleton->get_player()->get_animation_list(&names);
AnimationPlayerEditor::get_singleton()->get_player()->get_animation_list(&names);
for (const StringName &E : names) {
_cleanup_animation(AnimationPlayerEditor::singleton->get_player()->get_animation(E));
_cleanup_animation(AnimationPlayerEditor::get_singleton()->get_player()->get_animation(E));
}
} else {
_cleanup_animation(animation);
Expand Down
1 change: 1 addition & 0 deletions editor/animation_track_editor.h
Original file line number Diff line number Diff line change
Expand Up @@ -531,6 +531,7 @@ class AnimationTrackEditor : public VBoxContainer {
void insert_node_value_key(Node *p_node, const String &p_property, const Variant &p_value, bool p_only_if_exists = false);
void insert_value_key(const String &p_property, const Variant &p_value, bool p_advance);
void insert_transform_key(Node3D *p_node, const String &p_sub, const Transform3D &p_xform);
bool has_transform_track(Node3D *p_node, const String &p_sub);

void show_select_node_warning(bool p_show);

Expand Down
16 changes: 10 additions & 6 deletions editor/editor_node.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6885,7 +6885,7 @@ EditorNode::EditorNode() {
add_child(editor_interface);

//more visually meaningful to have this later
raise_bottom_panel_item(AnimationPlayerEditor::singleton);
raise_bottom_panel_item(AnimationPlayerEditor::get_singleton());

add_editor_plugin(VersionControlEditorPlugin::get_singleton());
add_editor_plugin(memnew(ShaderEditorPlugin(this)));
Expand Down Expand Up @@ -7160,20 +7160,24 @@ bool EditorPluginList::forward_gui_input(const Ref<InputEvent> &p_event) {
return discard;
}

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

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

if (plugins_list[i]->forward_spatial_gui_input(p_camera, p_event)) {
discard = true;
EditorPlugin::AfterGUIInput current_after = plugins_list[i]->forward_spatial_gui_input(p_camera, p_event);
if (current_after == EditorPlugin::AFTER_GUI_INPUT_STOP) {
after = EditorPlugin::AFTER_GUI_INPUT_STOP;
}
if (after != EditorPlugin::AFTER_GUI_INPUT_STOP && current_after == EditorPlugin::AFTER_GUI_INPUT_DESELECT) {
after = EditorPlugin::AFTER_GUI_INPUT_DESELECT;
}
}

return discard;
return after;
}

void EditorPluginList::forward_canvas_draw_over_viewport(Control *p_overlay) {
Expand Down
2 changes: 1 addition & 1 deletion editor/editor_node.h
Original file line number Diff line number Diff line change
Expand Up @@ -937,7 +937,7 @@ class EditorPluginList : public Object {
bool forward_gui_input(const Ref<InputEvent> &p_event);
void forward_canvas_draw_over_viewport(Control *p_overlay);
void forward_canvas_force_draw_over_viewport(Control *p_overlay);
bool forward_spatial_gui_input(Camera3D *p_camera, const Ref<InputEvent> &p_event, bool serve_when_force_input_enabled);
EditorPlugin::AfterGUIInput forward_spatial_gui_input(Camera3D *p_camera, const Ref<InputEvent> &p_event, bool serve_when_force_input_enabled);
void forward_spatial_draw_over_viewport(Control *p_overlay);
void forward_spatial_force_draw_over_viewport(Control *p_overlay);
void add_plugin(EditorPlugin *p_plugin);
Expand Down
8 changes: 4 additions & 4 deletions editor/editor_plugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -592,14 +592,14 @@ int EditorPlugin::update_overlays() const {
}
}

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

if (GDVIRTUAL_CALL(_forward_3d_gui_input, p_camera, p_event, success)) {
return success;
return static_cast<EditorPlugin::AfterGUIInput>(success);
}

return false;
return EditorPlugin::AFTER_GUI_INPUT_PASS;
}

void EditorPlugin::forward_spatial_draw_over_viewport(Control *p_overlay) {
Expand Down
10 changes: 8 additions & 2 deletions editor/editor_plugin.h
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ class EditorPlugin : public Node {
GDVIRTUAL1R(bool, _forward_canvas_gui_input, Ref<InputEvent>)
GDVIRTUAL1(_forward_canvas_draw_over_viewport, Control *)
GDVIRTUAL1(_forward_canvas_force_draw_over_viewport, Control *)
GDVIRTUAL2R(bool, _forward_3d_gui_input, Camera3D *, Ref<InputEvent>)
GDVIRTUAL2R(int, _forward_3d_gui_input, Camera3D *, Ref<InputEvent>)
GDVIRTUAL1(_forward_3d_draw_over_viewport, Control *)
GDVIRTUAL1(_forward_3d_force_draw_over_viewport, Control *)
GDVIRTUAL0RC(String, _get_plugin_name)
Expand Down Expand Up @@ -200,6 +200,12 @@ class EditorPlugin : public Node {
DOCK_SLOT_MAX
};

enum AfterGUIInput {
AFTER_GUI_INPUT_PASS,
AFTER_GUI_INPUT_STOP,
AFTER_GUI_INPUT_DESELECT
};

//TODO: send a resource for editing to the editor node?

void add_control_to_container(CustomControlContainer p_location, Control *p_control);
Expand Down Expand Up @@ -228,7 +234,7 @@ class EditorPlugin : public Node {
virtual void forward_canvas_draw_over_viewport(Control *p_overlay);
virtual void forward_canvas_force_draw_over_viewport(Control *p_overlay);

virtual bool forward_spatial_gui_input(Camera3D *p_camera, const Ref<InputEvent> &p_event);
virtual EditorPlugin::AfterGUIInput forward_spatial_gui_input(Camera3D *p_camera, const Ref<InputEvent> &p_event);
virtual void forward_spatial_draw_over_viewport(Control *p_overlay);
virtual void forward_spatial_force_draw_over_viewport(Control *p_overlay);

Expand Down
1 change: 1 addition & 0 deletions editor/editor_themes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,7 @@ void editor_register_and_generate_icons(Ref<Theme> p_theme, bool p_dark_theme =
exceptions.insert("EditorPivot");
exceptions.insert("EditorHandle");
exceptions.insert("Editor3DHandle");
exceptions.insert("EditorBoneHandle");
exceptions.insert("Godot");
exceptions.insert("Sky");
exceptions.insert("EditorControlAnchor");
Expand Down
1 change: 1 addition & 0 deletions editor/icons/EditorBoneHandle.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions editor/icons/ToolBoneSelect.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 3 additions & 3 deletions editor/inspector_dock.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -317,15 +317,15 @@ void InspectorDock::_menu_expandall() {
}

void InspectorDock::_property_keyed(const String &p_keyed, const Variant &p_value, bool p_advance) {
AnimationPlayerEditor::singleton->get_track_editor()->insert_value_key(p_keyed, p_value, p_advance);
AnimationPlayerEditor::get_singleton()->get_track_editor()->insert_value_key(p_keyed, p_value, p_advance);
}

void InspectorDock::_transform_keyed(Object *sp, const String &p_sub, const Transform3D &p_key) {
Node3D *s = Object::cast_to<Node3D>(sp);
if (!s) {
return;
}
AnimationPlayerEditor::singleton->get_track_editor()->insert_transform_key(s, p_sub, p_key);
AnimationPlayerEditor::get_singleton()->get_track_editor()->insert_transform_key(s, p_sub, p_key);
}

void InspectorDock::_warning_pressed() {
Expand Down Expand Up @@ -478,7 +478,7 @@ void InspectorDock::go_back() {
void InspectorDock::update_keying() {
bool valid = false;

if (AnimationPlayerEditor::singleton->get_track_editor()->has_keying()) {
if (AnimationPlayerEditor::get_singleton()->get_track_editor()->has_keying()) {
EditorHistory *editor_history = EditorNode::get_singleton()->get_editor_history();
if (editor_history->get_path_size() >= 1) {
Object *obj = ObjectDB::get_instance(editor_history->get_path_object(0));
Expand Down
Loading

0 comments on commit ba49f3e

Please sign in to comment.