Skip to content

Commit 4cc14d6

Browse files
committed
Add BlendSpace BlendPoint weight smoothing
1 parent ce94b26 commit 4cc14d6

10 files changed

+363
-22
lines changed

doc/classes/AnimationNodeBlendSpace1D.xml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,12 @@
7575
<member name="min_space" type="float" setter="set_min_space" getter="get_min_space" default="-1.0">
7676
The blend space's axis's lower limit for the points' position. See [method add_blend_point].
7777
</member>
78+
<member name="smooth" type="bool" setter="set_use_smooth" getter="is_using_smooth" default="false">
79+
If [code]true[/code], while [member sync] is [code]true[/code] a blend point's weight is applied over time using [member smooth_speed].
80+
</member>
81+
<member name="smooth_speed" type="float" setter="set_smooth_speed" getter="get_smooth_speed" default="1.0">
82+
Controls the blend point smoothing speed.
83+
</member>
7884
<member name="snap" type="float" setter="set_snap" getter="get_snap" default="0.1">
7985
Position increment to snap to when moving a point on the axis.
8086
</member>

doc/classes/AnimationNodeBlendSpace2D.xml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,12 @@
110110
<member name="min_space" type="Vector2" setter="set_min_space" getter="get_min_space" default="Vector2(-1, -1)">
111111
The blend space's X and Y axes' lower limit for the points' position. See [method add_blend_point].
112112
</member>
113+
<member name="smooth" type="bool" setter="set_use_smooth" getter="is_using_smooth" default="false">
114+
If [code]true[/code], while [member sync] is [code]true[/code] a blend point's weight is applied over time using [member smooth_speed].
115+
</member>
116+
<member name="smooth_speed" type="float" setter="set_smooth_speed" getter="get_smooth_speed" default="1.0">
117+
Controls the blend point smoothing speed.
118+
</member>
113119
<member name="snap" type="Vector2" setter="set_snap" getter="get_snap" default="Vector2(0.1, 0.1)">
114120
Position increment to snap to when moving a point.
115121
</member>

editor/plugins/animation_blend_space_1d_editor.cpp

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -336,6 +336,8 @@ void AnimationNodeBlendSpace1DEditor::_update_space() {
336336

337337
sync->set_pressed(blend_space->is_using_sync());
338338
interpolation->select(blend_space->get_blend_mode());
339+
smooth->set_pressed(blend_space->is_using_smooth());
340+
smooth_speed->set_value(blend_space->get_smooth_speed());
339341

340342
label_value->set_text(blend_space->get_value_label());
341343

@@ -364,6 +366,11 @@ void AnimationNodeBlendSpace1DEditor::_config_changed(double) {
364366
undo_redo->add_undo_method(blend_space.ptr(), "set_use_sync", blend_space->is_using_sync());
365367
undo_redo->add_do_method(blend_space.ptr(), "set_blend_mode", interpolation->get_selected());
366368
undo_redo->add_undo_method(blend_space.ptr(), "set_blend_mode", blend_space->get_blend_mode());
369+
undo_redo->add_do_method(blend_space.ptr(), "set_use_smooth", smooth->is_pressed());
370+
undo_redo->add_undo_method(blend_space.ptr(), "set_use_smooth", blend_space->is_using_smooth());
371+
smooth_hb->set_visible((sync->is_pressed() && interpolation->get_selected() == AnimationNodeBlendSpace1D::BLEND_MODE_INTERPOLATED));
372+
undo_redo->add_do_method(blend_space.ptr(), "set_smooth_speed", smooth_speed->get_value());
373+
undo_redo->add_undo_method(blend_space.ptr(), "set_use_smooth", blend_space->get_smooth_speed());
367374
undo_redo->add_do_method(this, "_update_space");
368375
undo_redo->add_undo_method(this, "_update_space");
369376
undo_redo->commit_action();
@@ -646,6 +653,8 @@ void AnimationNodeBlendSpace1DEditor::edit(const Ref<AnimationNode> &p_node) {
646653
min_value->set_editable(!read_only);
647654
max_value->set_editable(!read_only);
648655
sync->set_disabled(read_only);
656+
smooth->set_disabled(read_only);
657+
smooth_speed->set_editable(!read_only);
649658
interpolation->set_disabled(read_only);
650659
}
651660

@@ -728,6 +737,24 @@ AnimationNodeBlendSpace1DEditor::AnimationNodeBlendSpace1DEditor() {
728737
top_hb->add_child(interpolation);
729738
interpolation->connect(SceneStringName(item_selected), callable_mp(this, &AnimationNodeBlendSpace1DEditor::_config_changed));
730739

740+
smooth_hb = memnew(HBoxContainer);
741+
top_hb->add_child(smooth_hb);
742+
smooth_hb->add_child(memnew(VSeparator));
743+
744+
smooth_hb->add_child(memnew(Label(TTR("Smooth:"))));
745+
smooth = memnew(CheckBox);
746+
smooth_hb->add_child(smooth);
747+
smooth->connect(SceneStringName(toggled), callable_mp(this, &AnimationNodeBlendSpace1DEditor::_config_changed));
748+
749+
smooth_hb->add_child(memnew(Label(TTR("Speed:"))));
750+
751+
smooth_speed = memnew(SpinBox);
752+
smooth_hb->add_child(smooth_speed);
753+
smooth_speed->set_min(0.01);
754+
smooth_speed->set_step(0.01);
755+
smooth_speed->set_max(1000);
756+
smooth_speed->connect(SceneStringName(value_changed), callable_mp(this, &AnimationNodeBlendSpace1DEditor::_config_changed));
757+
731758
edit_hb = memnew(HBoxContainer);
732759
top_hb->add_child(edit_hb);
733760
edit_hb->add_child(memnew(VSeparator));

editor/plugins/animation_blend_space_1d_editor.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,10 @@ class AnimationNodeBlendSpace1DEditor : public AnimationTreeNodeEditorPlugin {
6868
CheckBox *sync = nullptr;
6969
OptionButton *interpolation = nullptr;
7070

71+
HBoxContainer *smooth_hb = nullptr;
72+
CheckBox *smooth = nullptr;
73+
SpinBox *smooth_speed = nullptr;
74+
7175
HBoxContainer *edit_hb = nullptr;
7276
SpinBox *edit_value = nullptr;
7377
Button *open_editor = nullptr;

editor/plugins/animation_blend_space_2d_editor.cpp

Lines changed: 117 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
#include "editor/editor_string_names.h"
3939
#include "editor/editor_undo_redo_manager.h"
4040
#include "editor/gui/editor_file_dialog.h"
41+
#include "editor/inspector_dock.h"
4142
#include "editor/themes/editor_scale.h"
4243
#include "scene/animation/animation_blend_tree.h"
4344
#include "scene/animation/animation_player.h"
@@ -53,6 +54,21 @@
5354
#include "scene/gui/spin_box.h"
5455
#include "scene/main/window.h"
5556

57+
//void BlendPointEditor::_bind_methods() {
58+
// ClassDB::bind_method(D_METHOD("set_fade_in", "value"), &BlendPointEditor::set_fade_in);
59+
// ClassDB::bind_method(D_METHOD("get_fade_in"), &BlendPointEditor::get_fade_in);
60+
// ClassDB::bind_method(D_METHOD("set_fade_out", "value"), &BlendPointEditor::set_fade_out);
61+
// ClassDB::bind_method(D_METHOD("get_fade_out"), &BlendPointEditor::get_fade_out);
62+
// //ClassDB::bind_method(D_METHOD("_dont_undo_redo"), &BlendPointEditor::_dont_undo_redo);
63+
// //ClassDB::bind_method(D_METHOD("_hide_script_from_inspector"), &BlendPointEditor::_hide_script_from_inspector);
64+
// //ClassDB::bind_method(D_METHOD("_hide_metadata_from_inspector"), &BlendPointEditor::_hide_metadata_from_inspector);
65+
// ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "fade_in", PROPERTY_HINT_NONE, "0,60,0.01,or_greater,suffix:s"), "set_fade_in", "get_fade_in");
66+
// ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "fade_out", PROPERTY_HINT_NONE, "0,60,0.01,or_greater,suffix:s"), "set_fade_out", "get_fade_out");
67+
// ClassDB::bind_method(D_METHOD("get_anim_node"), &BlendPointEditor::get_anim_node);
68+
//
69+
// ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "animation_node", PROPERTY_HINT_RESOURCE_TYPE, "AnimationNode"), "", "get_anim_node");
70+
//}
71+
5672
bool AnimationNodeBlendSpace2DEditor::can_edit(const Ref<AnimationNode> &p_node) {
5773
Ref<AnimationNodeBlendSpace2D> bs2d = p_node;
5874
return bs2d.is_valid();
@@ -88,6 +104,8 @@ void AnimationNodeBlendSpace2DEditor::edit(const Ref<AnimationNode> &p_node) {
88104
tool_triangle->set_disabled(read_only);
89105
auto_triangles->set_disabled(read_only);
90106
sync->set_disabled(read_only);
107+
default_blend_time->set_editable(!read_only);
108+
override_delta->set_disabled(read_only);
91109
interpolation->set_disabled(read_only);
92110
}
93111

@@ -176,15 +194,16 @@ void AnimationNodeBlendSpace2DEditor::_blend_space_gui_input(const Ref<InputEven
176194
if (points[i].distance_to(mb->get_position()) < 10 * EDSCALE) {
177195
selected_point = i;
178196
Ref<AnimationNode> node = blend_space->get_blend_point_node(i);
179-
EditorNode::get_singleton()->push_item(node.ptr(), "", true);
197+
current_blend_point_editor->setup(blend_space, selected_point, node);
198+
//EditorNode::get_singleton()->push_item(current_blend_point_editor.ptr(), "", true);
199+
InspectorDock::get_inspector_singleton()->edit(current_blend_point_editor.ptr());
180200
dragging_selected_attempt = true;
181201
drag_from = mb->get_position();
182202
_update_tool_erase();
183203
_update_edited_point_pos();
184204
return;
185205
}
186206
}
187-
188207
//then try to see if a triangle can be selected
189208
if (!blend_space->get_auto_triangles()) { //if autotriangles use, disable this
190209
for (int i = 0; i < blend_space->get_triangle_count(); i++) {
@@ -650,6 +669,9 @@ void AnimationNodeBlendSpace2DEditor::_update_space() {
650669

651670
sync->set_pressed(blend_space->is_using_sync());
652671
interpolation->select(blend_space->get_blend_mode());
672+
default_blend_time->set_value(blend_space->get_default_blend_time());
673+
override_delta->set_pressed(blend_space->get_override_delta());
674+
//smooth_speed->set_value(blend_space->get_smooth_speed());
653675

654676
max_x_value->set_value(blend_space->get_max_space().x);
655677
max_y_value->set_value(blend_space->get_max_space().y);
@@ -686,6 +708,13 @@ void AnimationNodeBlendSpace2DEditor::_config_changed(double) {
686708
undo_redo->add_undo_method(blend_space.ptr(), "set_use_sync", blend_space->is_using_sync());
687709
undo_redo->add_do_method(blend_space.ptr(), "set_blend_mode", interpolation->get_selected());
688710
undo_redo->add_undo_method(blend_space.ptr(), "set_blend_mode", blend_space->get_blend_mode());
711+
undo_redo->add_do_method(blend_space.ptr(), "set_default_blend_time", default_blend_time->get_value());
712+
undo_redo->add_undo_method(blend_space.ptr(), "set_default_blend_time", blend_space->get_default_blend_time());
713+
undo_redo->add_do_method(blend_space.ptr(), "set_override_delta", override_delta->is_pressed());
714+
undo_redo->add_undo_method(blend_space.ptr(), "set_override_delta", blend_space->get_override_delta());
715+
blending_hb->set_visible(sync->is_pressed());
716+
//edit_fade_hb->set_visible(sync->is_pressed() && !Math::is_zero_approx(default_blend_time->get_value()));
717+
689718
undo_redo->add_do_method(this, "_update_space");
690719
undo_redo->add_undo_method(this, "_update_space");
691720
undo_redo->commit_action();
@@ -790,6 +819,10 @@ void AnimationNodeBlendSpace2DEditor::_edit_point_pos(double) {
790819
blend_space_draw->queue_redraw();
791820
}
792821

822+
Vector2 AnimationNodeBlendSpace2DEditor::get_point_fade() {
823+
return (selected_point != -1 && blend_space != nullptr) ? blend_space->get_blend_point_fade(selected_point) : Vector2();
824+
}
825+
793826
void AnimationNodeBlendSpace2DEditor::_notification(int p_what) {
794827
switch (p_what) {
795828
case NOTIFICATION_ENTER_TREE:
@@ -861,6 +894,64 @@ void AnimationNodeBlendSpace2DEditor::_auto_triangles_toggled() {
861894
undo_redo->commit_action();
862895
}
863896

897+
void BlendPointEditor::_edit_point_fade() {
898+
if (updating) {
899+
return;
900+
}
901+
updating = true;
902+
EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton();
903+
undo_redo->create_action(TTR("Change Node Fade"));
904+
undo_redo->add_do_method(blend_space.ptr(), "set_blend_point_fade", selected_point, fades);
905+
undo_redo->add_undo_method(blend_space.ptr(), "set_blend_point_fade", selected_point, blend_space->get_blend_point_fade(selected_point));
906+
undo_redo->commit_action();
907+
updating = false;
908+
}
909+
void BlendPointEditor::setup(Ref<AnimationNodeBlendSpace2D> p_blend_space, int p_idx, Ref<AnimationNode> p_anim_node) {
910+
blend_space = p_blend_space;
911+
selected_point = p_idx;
912+
anim_node = p_anim_node;
913+
}
914+
915+
void BlendPointEditor::set_fade_in(float p_value) {
916+
if (blend_space.is_valid()) {
917+
fades = blend_space->get_blend_point_fade(selected_point);
918+
fades.x = p_value;
919+
_edit_point_fade();
920+
}
921+
}
922+
double BlendPointEditor::get_fade_in() const {
923+
return (blend_space.is_valid()) ? blend_space->get_blend_point_fade(selected_point).x : 0;
924+
}
925+
926+
void BlendPointEditor::set_fade_out(float p_value) {
927+
if (blend_space.is_valid()) {
928+
fades = blend_space->get_blend_point_fade(selected_point);
929+
fades.y = p_value;
930+
_edit_point_fade();
931+
}
932+
}
933+
double BlendPointEditor::get_fade_out() const {
934+
return (blend_space.is_valid()) ? blend_space->get_blend_point_fade(selected_point).y : 0;
935+
}
936+
937+
Ref<AnimationNode> BlendPointEditor::get_anim_node() const {
938+
return anim_node;
939+
}
940+
941+
void BlendPointEditor::_bind_methods() {
942+
ClassDB::bind_method(D_METHOD("set_fade_in", "value"), &BlendPointEditor::set_fade_in);
943+
ClassDB::bind_method(D_METHOD("get_fade_in"), &BlendPointEditor::get_fade_in);
944+
ClassDB::bind_method(D_METHOD("set_fade_out", "value"), &BlendPointEditor::set_fade_out);
945+
ClassDB::bind_method(D_METHOD("get_fade_out"), &BlendPointEditor::get_fade_out);
946+
ClassDB::bind_method(D_METHOD("_dont_undo_redo"), &BlendPointEditor::_dont_undo_redo);
947+
ClassDB::bind_method(D_METHOD("_hide_script_from_inspector"), &BlendPointEditor::_hide_script_from_inspector);
948+
ClassDB::bind_method(D_METHOD("_hide_metadata_from_inspector"), &BlendPointEditor::_hide_metadata_from_inspector);
949+
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "fade_in", PROPERTY_HINT_NONE, "0,60,0.01,or_greater,suffix:s"), "set_fade_in", "get_fade_in");
950+
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "fade_out", PROPERTY_HINT_NONE, "0,60,0.01,or_greater,suffix:s"), "set_fade_out", "get_fade_out");
951+
ClassDB::bind_method(D_METHOD("get_anim_node"), &BlendPointEditor::get_anim_node);
952+
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "animation_node", PROPERTY_HINT_RESOURCE_TYPE, "AnimationNode"), "", "get_anim_node");
953+
}
954+
864955
void AnimationNodeBlendSpace2DEditor::_bind_methods() {
865956
ClassDB::bind_method("_update_space", &AnimationNodeBlendSpace2DEditor::_update_space);
866957
ClassDB::bind_method("_update_tool_erase", &AnimationNodeBlendSpace2DEditor::_update_tool_erase);
@@ -978,6 +1069,26 @@ AnimationNodeBlendSpace2DEditor::AnimationNodeBlendSpace2DEditor() {
9781069
top_hb->add_child(interpolation);
9791070
interpolation->connect(SceneStringName(item_selected), callable_mp(this, &AnimationNodeBlendSpace2DEditor::_config_changed));
9801071

1072+
blending_hb = memnew(HBoxContainer);
1073+
top_hb->add_child(blending_hb);
1074+
blending_hb->add_child(memnew(VSeparator));
1075+
1076+
blending_hb->add_child(memnew(Label(TTR("Default Blend Time:"))));
1077+
default_blend_time = memnew(SpinBox);
1078+
blending_hb->add_child(default_blend_time);
1079+
default_blend_time->set_min(0.0);
1080+
default_blend_time->set_step(0.01);
1081+
default_blend_time->set_max(60.0);
1082+
default_blend_time->set_suffix("s");
1083+
default_blend_time->connect(SceneStringName(value_changed), callable_mp(this, &AnimationNodeBlendSpace2DEditor::_config_changed));
1084+
1085+
blending_hb->add_child(memnew(Label(TTR("Override delta:"))));
1086+
override_delta = memnew(CheckBox);
1087+
blending_hb->add_child(override_delta);
1088+
override_delta->connect(SceneStringName(toggled), callable_mp(this, &AnimationNodeBlendSpace2DEditor::_config_changed));
1089+
1090+
current_blend_point_editor.instantiate();
1091+
9811092
edit_hb = memnew(HBoxContainer);
9821093
top_hb->add_child(edit_hb);
9831094
edit_hb->add_child(memnew(VSeparator));
@@ -996,6 +1107,7 @@ AnimationNodeBlendSpace2DEditor::AnimationNodeBlendSpace2DEditor() {
9961107
edit_y->set_max(1000);
9971108
edit_y->set_accessibility_name(TTRC("Blend X Value"));
9981109
edit_y->connect(SceneStringName(value_changed), callable_mp(this, &AnimationNodeBlendSpace2DEditor::_edit_point_pos));
1110+
9991111
open_editor = memnew(Button);
10001112
edit_hb->add_child(open_editor);
10011113
open_editor->set_text(TTR("Open Editor"));
@@ -1114,3 +1226,6 @@ AnimationNodeBlendSpace2DEditor::AnimationNodeBlendSpace2DEditor() {
11141226
dragging_selected = false;
11151227
dragging_selected_attempt = false;
11161228
}
1229+
AnimationNodeBlendSpace2DEditor::~AnimationNodeBlendSpace2DEditor() {
1230+
SceneTree::get_singleton()->queue_delete(current_blend_point_editor.ptr());
1231+
}

editor/plugins/animation_blend_space_2d_editor.h

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,9 @@
3333
#include "editor/plugins/animation_tree_editor_plugin.h"
3434
#include "editor/plugins/editor_plugin.h"
3535
#include "scene/animation/animation_blend_space_2d.h"
36+
#include "scene/gui/dialogs.h"
3637
#include "scene/gui/graph_edit.h"
38+
#include "scene/gui/tree.h"
3739

3840
class Button;
3941
class CheckBox;
@@ -43,8 +45,10 @@ class PanelContainer;
4345
class SpinBox;
4446
class VSeparator;
4547

48+
class BlendPointEditor;
4649
class AnimationNodeBlendSpace2DEditor : public AnimationTreeNodeEditorPlugin {
4750
GDCLASS(AnimationNodeBlendSpace2DEditor, AnimationTreeNodeEditorPlugin);
51+
friend BlendPointEditor;
4852

4953
Ref<AnimationNodeBlendSpace2D> blend_space;
5054
bool read_only = false;
@@ -60,8 +64,18 @@ class AnimationNodeBlendSpace2DEditor : public AnimationTreeNodeEditorPlugin {
6064
SpinBox *snap_x = nullptr;
6165
SpinBox *snap_y = nullptr;
6266
CheckBox *sync = nullptr;
67+
6368
OptionButton *interpolation = nullptr;
6469

70+
HBoxContainer *blending_hb = nullptr;
71+
SpinBox *default_blend_time = nullptr;
72+
CheckBox *override_delta = nullptr;
73+
Ref<BlendPointEditor> current_blend_point_editor;
74+
75+
HBoxContainer *edit_fade_hb = nullptr;
76+
SpinBox *edit_fade_in = nullptr;
77+
SpinBox *edit_fade_out = nullptr;
78+
6579
Button *auto_triangles = nullptr;
6680

6781
LineEdit *label_x = nullptr;
@@ -118,6 +132,7 @@ class AnimationNodeBlendSpace2DEditor : public AnimationTreeNodeEditorPlugin {
118132
void _update_tool_erase();
119133
void _erase_selected();
120134
void _edit_point_pos(double);
135+
Vector2 get_point_fade();
121136
void _open_editor();
122137

123138
void _auto_triangles_toggled();
@@ -145,4 +160,32 @@ class AnimationNodeBlendSpace2DEditor : public AnimationTreeNodeEditorPlugin {
145160
virtual bool can_edit(const Ref<AnimationNode> &p_node) override;
146161
virtual void edit(const Ref<AnimationNode> &p_node) override;
147162
AnimationNodeBlendSpace2DEditor();
163+
~AnimationNodeBlendSpace2DEditor();
164+
};
165+
166+
class BlendPointEditor : public RefCounted {
167+
GDCLASS(BlendPointEditor, RefCounted);
168+
169+
private:
170+
Ref<AnimationNodeBlendSpace2D> blend_space;
171+
Ref<AnimationNode> anim_node;
172+
int selected_point = -1;
173+
Vector2 fades;
174+
bool updating = false;
175+
176+
public:
177+
void setup(Ref<AnimationNodeBlendSpace2D> p_blend_space, int idx, Ref<AnimationNode> p_anim_node);
178+
179+
void set_fade_in(float p_value);
180+
double get_fade_in() const;
181+
182+
void set_fade_out(float p_value);
183+
double get_fade_out() const;
184+
void _edit_point_fade();
185+
Ref<AnimationNode> get_anim_node() const;
186+
bool _hide_script_from_inspector() { return true; }
187+
bool _hide_metadata_from_inspector() { return true; }
188+
bool _dont_undo_redo() { return true; }
189+
190+
static void _bind_methods();
148191
};

0 commit comments

Comments
 (0)