Skip to content

Add BlendSpace BlendPoint weight transitions by velocity limiting #105923

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 39 additions & 0 deletions doc/classes/AnimationNodeBlendSpace1D.xml
Original file line number Diff line number Diff line change
Expand Up @@ -34,13 +34,27 @@
Returns the [AnimationNode] referenced by the point at index [param point].
</description>
</method>
<method name="get_blend_point_ovl" qualifiers="const">
<return type="bool" />
<param index="0" name="point" type="int" />
<description>
Returns the velocity limit override of the point at index [param point].
</description>
</method>
<method name="get_blend_point_position" qualifiers="const">
<return type="float" />
<param index="0" name="point" type="int" />
<description>
Returns the position of the point at index [param point].
</description>
</method>
<method name="get_blend_point_vl" qualifiers="const">
<return type="float" />
<param index="0" name="point" type="int" />
<description>
Returns the velocity limit of the point at index [param point].
</description>
</method>
<method name="remove_blend_point">
<return type="void" />
<param index="0" name="point" type="int" />
Expand All @@ -56,6 +70,14 @@
Changes the [AnimationNode] referenced by the point at index [param point].
</description>
</method>
<method name="set_blend_point_ovl">
<return type="void" />
<param index="0" name="point" type="int" />
<param index="1" name="override_velocity_limit" type="bool" />
<description>
Updates the velocity limit override of the point at index [param point] in the blend space.
</description>
</method>
<method name="set_blend_point_position">
<return type="void" />
<param index="0" name="point" type="int" />
Expand All @@ -64,6 +86,14 @@
Updates the position of the point at index [param point] on the blend axis.
</description>
</method>
<method name="set_blend_point_vl">
<return type="void" />
<param index="0" name="point" type="int" />
<param index="1" name="velocity_limit" type="float" />
<description>
Updates the velocity limit of the point at index [param point] in the blend space.
</description>
</method>
</methods>
<members>
<member name="blend_mode" type="int" setter="set_blend_mode" getter="get_blend_mode" enum="AnimationNodeBlendSpace1D.BlendMode" default="0">
Expand All @@ -82,9 +112,18 @@
If [code]false[/code], the blended animations' frame are stopped when the blend value is [code]0[/code].
If [code]true[/code], forcing the blended animations to advance frame.
</member>
<member name="use_velocity_limit" type="bool" setter="set_use_velocity_limit" getter="get_use_velocity_limit" default="false">
If [code]true[/code], while [member sync] is [code]true[/code] a blend point's weight is applied over time using [member velocity_limit] with [member velocity_limit_ease].
</member>
<member name="value_label" type="String" setter="set_value_label" getter="get_value_label" default="&quot;value&quot;">
Label of the virtual axis of the blend space.
</member>
<member name="velocity_limit" type="float" setter="set_velocity_limit" getter="get_velocity_limit" default="0.0">
Controls the blend point velocity limit speed.
</member>
<member name="velocity_limit_ease" type="float" setter="set_velocity_limit_ease" getter="get_velocity_limit_ease" default="1.0">
Controls the easing of the velocity limit speed.
</member>
</members>
<constants>
<constant name="BLEND_MODE_INTERPOLATED" value="0" enum="BlendMode">
Expand Down
39 changes: 39 additions & 0 deletions doc/classes/AnimationNodeBlendSpace2D.xml
Original file line number Diff line number Diff line change
Expand Up @@ -45,13 +45,27 @@
Returns the [AnimationRootNode] referenced by the point at index [param point].
</description>
</method>
<method name="get_blend_point_ovl" qualifiers="const">
<return type="bool" />
<param index="0" name="point" type="int" />
<description>
Returns the velocity limit override of the point at index [param point].
</description>
</method>
<method name="get_blend_point_position" qualifiers="const">
<return type="Vector2" />
<param index="0" name="point" type="int" />
<description>
Returns the position of the point at index [param point].
</description>
</method>
<method name="get_blend_point_vl" qualifiers="const">
<return type="float" />
<param index="0" name="point" type="int" />
<description>
Returns the velocity limit of the point at index [param point].
</description>
</method>
<method name="get_triangle_count" qualifiers="const">
<return type="int" />
<description>
Expand Down Expand Up @@ -88,6 +102,14 @@
Changes the [AnimationNode] referenced by the point at index [param point].
</description>
</method>
<method name="set_blend_point_ovl">
<return type="void" />
<param index="0" name="point" type="int" />
<param index="1" name="override_velocity_limit" type="bool" />
<description>
Updates the velocity limit override of the point at index [param point] in the blend space.
</description>
</method>
<method name="set_blend_point_position">
<return type="void" />
<param index="0" name="point" type="int" />
Expand All @@ -96,6 +118,14 @@
Updates the position of the point at index [param point] in the blend space.
</description>
</method>
<method name="set_blend_point_vl">
<return type="void" />
<param index="0" name="point" type="int" />
<param index="1" name="velocity_limit" type="float" />
<description>
Updates the velocity limit of the point at index [param point] in the blend space.
</description>
</method>
</methods>
<members>
<member name="auto_triangles" type="bool" setter="set_auto_triangles" getter="get_auto_triangles" default="true">
Expand All @@ -117,6 +147,15 @@
If [code]false[/code], the blended animations' frame are stopped when the blend value is [code]0[/code].
If [code]true[/code], forcing the blended animations to advance frame.
</member>
<member name="use_velocity_limit" type="bool" setter="set_use_velocity_limit" getter="get_use_velocity_limit" default="false">
If [code]true[/code], while [member sync] is [code]true[/code] a blend point's weight is applied over time using [member velocity_limit] with [member velocity_limit_ease].
</member>
<member name="velocity_limit" type="float" setter="set_velocity_limit" getter="get_velocity_limit" default="0.0">
Controls the blend point velocity limit speed.
</member>
<member name="velocity_limit_ease" type="float" setter="set_velocity_limit_ease" getter="get_velocity_limit_ease" default="1.0">
Controls the easing of the velocity limit speed.
</member>
<member name="x_label" type="String" setter="set_x_label" getter="get_x_label" default="&quot;x&quot;">
Name of the blend space's X axis.
</member>
Expand Down
116 changes: 114 additions & 2 deletions editor/animation/animation_blend_space_1d_editor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
#include "animation_blend_space_1d_editor.h"

#include "core/os/keyboard.h"
#include "editor/docks/inspector_dock.h"
#include "editor/editor_node.h"
#include "editor/editor_string_names.h"
#include "editor/editor_undo_redo_manager.h"
Expand Down Expand Up @@ -133,9 +134,9 @@ void AnimationNodeBlendSpace1DEditor::_blend_space_gui_input(const Ref<InputEven
for (int i = 0; i < points.size(); i++) {
if (Math::abs(float(points[i] - mb->get_position().x)) < 10 * EDSCALE) {
selected_point = i;

Ref<AnimationNode> node = blend_space->get_blend_point_node(i);
EditorNode::get_singleton()->push_item(node.ptr(), "", true);
current_blend_point_editor->setup(blend_space, selected_point, node);
InspectorDock::get_inspector_singleton()->edit(current_blend_point_editor.ptr());
dragging_selected_attempt = true;
drag_from = mb->get_position();
_update_tool_erase();
Expand Down Expand Up @@ -336,6 +337,8 @@ void AnimationNodeBlendSpace1DEditor::_update_space() {

sync->set_pressed(blend_space->is_using_sync());
interpolation->select(blend_space->get_blend_mode());
use_velocity_limit->set_pressed(blend_space->get_use_velocity_limit());
default_velocity_limit->set_value(blend_space->get_velocity_limit());

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

Expand Down Expand Up @@ -364,6 +367,11 @@ void AnimationNodeBlendSpace1DEditor::_config_changed(double) {
undo_redo->add_undo_method(blend_space.ptr(), "set_use_sync", blend_space->is_using_sync());
undo_redo->add_do_method(blend_space.ptr(), "set_blend_mode", interpolation->get_selected());
undo_redo->add_undo_method(blend_space.ptr(), "set_blend_mode", blend_space->get_blend_mode());
blending_hb->set_visible(sync->is_pressed());
undo_redo->add_do_method(blend_space.ptr(), "set_use_velocity_limit", use_velocity_limit->is_pressed());
undo_redo->add_undo_method(blend_space.ptr(), "set_use_velocity_limit", blend_space->get_use_velocity_limit());
undo_redo->add_do_method(blend_space.ptr(), "set_velocity_limit", default_velocity_limit->get_value());
undo_redo->add_undo_method(blend_space.ptr(), "set_velocity_limit", blend_space->get_velocity_limit());
undo_redo->add_do_method(this, "_update_space");
undo_redo->add_undo_method(this, "_update_space");
undo_redo->commit_action();
Expand Down Expand Up @@ -571,6 +579,7 @@ void AnimationNodeBlendSpace1DEditor::_open_editor() {

void AnimationNodeBlendSpace1DEditor::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_ENTER_TREE:
case NOTIFICATION_THEME_CHANGED: {
error_panel->add_theme_style_override(SceneStringName(panel), get_theme_stylebox(SceneStringName(panel), SNAME("Tree")));
error_label->add_theme_color_override(SceneStringName(font_color), get_theme_color(SNAME("error_color"), EditorStringName(Editor)));
Expand Down Expand Up @@ -616,6 +625,82 @@ void AnimationNodeBlendSpace1DEditor::_notification(int p_what) {
} break;
}
}
void BlendPointEditor1D::setup(Ref<AnimationNodeBlendSpace1D> p_blend_space, int p_idx, Ref<AnimationNode> p_anim_node) {
blend_space = p_blend_space;
selected_point = p_idx;
anim_node = p_anim_node;
}

void BlendPointEditor1D::set_velocity_limit(float p_value) {
if (blend_space.is_valid()) {
if (updating) {
return;
}
updating = true;
EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton();
undo_redo->create_action(TTR("Change Node Velocity Limit"));
undo_redo->add_do_method(blend_space.ptr(), "set_blend_point_vl", selected_point, p_value);
undo_redo->add_undo_method(blend_space.ptr(), "set_blend_point_vl", selected_point, blend_space->get_blend_point_vl(selected_point));
undo_redo->commit_action();
updating = false;
}
}
double BlendPointEditor1D::get_velocity_limit() const {
return (blend_space.is_valid()) ? blend_space->get_blend_point_vl(selected_point) : 0.0;
}

Ref<AnimationNode> BlendPointEditor1D::get_anim_node() const {
return anim_node;
}
void BlendPointEditor1D::set_velocity_limit_ease(float const p_ease) {
if (blend_space.is_valid()) {
updating = true;
EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton();
undo_redo->create_action(TTR("Change Blendspace Velocity Limit Ease"));
undo_redo->add_do_method(blend_space.ptr(), "set_velocity_limit_ease", p_ease);
undo_redo->add_undo_method(blend_space.ptr(), "set_velocity_limit_ease", blend_space->get_velocity_limit_ease());
undo_redo->commit_action();
updating = false;
}
}
float BlendPointEditor1D::get_velocity_limit_ease() const {
return (blend_space.is_valid()) ? blend_space->get_velocity_limit_ease() : 1.0;
}

void BlendPointEditor1D::set_override_velocity_limit(bool const p_ovl) {
if (blend_space.is_valid()) {
updating = true;
EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton();
undo_redo->create_action(TTR("Change Node Override Velocity Limit"));
undo_redo->add_do_method(blend_space.ptr(), "set_blend_point_ovl", selected_point, p_ovl);
undo_redo->add_undo_method(blend_space.ptr(), "set_blend_point_ovl", selected_point, blend_space->get_blend_point_ovl(selected_point));
undo_redo->commit_action();
updating = false;
}
}
bool BlendPointEditor1D::get_override_velocity_limit() const {
return (blend_space.is_valid()) ? blend_space->get_blend_point_ovl(selected_point) : false;
}

void BlendPointEditor1D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_velocity_limit", "value"), &BlendPointEditor1D::set_velocity_limit);
ClassDB::bind_method(D_METHOD("get_velocity_limit"), &BlendPointEditor1D::get_velocity_limit);
ClassDB::bind_method(D_METHOD("_dont_undo_redo"), &BlendPointEditor1D::_dont_undo_redo);
ClassDB::bind_method(D_METHOD("_hide_script_from_inspector"), &BlendPointEditor1D::_hide_script_from_inspector);
ClassDB::bind_method(D_METHOD("_hide_metadata_from_inspector"), &BlendPointEditor1D::_hide_metadata_from_inspector);

ClassDB::bind_method(D_METHOD("get_velocity_limit_ease"), &BlendPointEditor1D::get_velocity_limit_ease);
ClassDB::bind_method(D_METHOD("set_velocity_limit_ease"), &BlendPointEditor1D::set_velocity_limit_ease);

ClassDB::bind_method(D_METHOD("set_override_velocity_limit"), &BlendPointEditor1D::set_override_velocity_limit);
ClassDB::bind_method(D_METHOD("get_override_velocity_limit"), &BlendPointEditor1D::get_override_velocity_limit);

ClassDB::bind_method(D_METHOD("get_anim_node"), &BlendPointEditor1D::get_anim_node);
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "velocity_limit_ease", PROPERTY_HINT_EXP_EASING), "set_velocity_limit_ease", "get_velocity_limit_ease");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "override_velocity_limit", PROPERTY_HINT_NONE), "set_override_velocity_limit", "get_override_velocity_limit");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "velocity_limit", PROPERTY_HINT_NONE, "0,60,0.01,or_greater,suffix:/s"), "set_velocity_limit", "get_velocity_limit");
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "animation_node", PROPERTY_HINT_RESOURCE_TYPE, "AnimationNode"), "", "get_anim_node");
}

void AnimationNodeBlendSpace1DEditor::_bind_methods() {
ClassDB::bind_method("_update_space", &AnimationNodeBlendSpace1DEditor::_update_space);
Expand Down Expand Up @@ -645,6 +730,8 @@ void AnimationNodeBlendSpace1DEditor::edit(const Ref<AnimationNode> &p_node) {
min_value->set_editable(!read_only);
max_value->set_editable(!read_only);
sync->set_disabled(read_only);
default_velocity_limit->set_editable(!read_only);
use_velocity_limit->set_disabled(read_only);
interpolation->set_disabled(read_only);
}

Expand All @@ -666,6 +753,7 @@ AnimationNodeBlendSpace1DEditor::AnimationNodeBlendSpace1DEditor() {
top_hb->add_child(tool_blend);
tool_blend->set_pressed(true);
tool_blend->set_tooltip_text(TTR("Set the blending position within the space"));
tool_blend->set_accessibility_name(TTRC("Set Blending Position"));
tool_blend->connect(SceneStringName(pressed), callable_mp(this, &AnimationNodeBlendSpace1DEditor::_tool_switch).bind(3));

tool_select = memnew(Button);
Expand All @@ -674,6 +762,7 @@ AnimationNodeBlendSpace1DEditor::AnimationNodeBlendSpace1DEditor() {
tool_select->set_button_group(bg);
top_hb->add_child(tool_select);
tool_select->set_tooltip_text(TTR("Select and move points, create points with RMB."));
tool_select->set_accessibility_name(TTRC("Edit Points"));
tool_select->connect(SceneStringName(pressed), callable_mp(this, &AnimationNodeBlendSpace1DEditor::_tool_switch).bind(0));

tool_create = memnew(Button);
Expand All @@ -682,6 +771,7 @@ AnimationNodeBlendSpace1DEditor::AnimationNodeBlendSpace1DEditor() {
tool_create->set_button_group(bg);
top_hb->add_child(tool_create);
tool_create->set_tooltip_text(TTR("Create points."));
tool_create->set_accessibility_name(TTRC("Create Points"));
tool_create->connect(SceneStringName(pressed), callable_mp(this, &AnimationNodeBlendSpace1DEditor::_tool_switch).bind(1));

tool_erase_sep = memnew(VSeparator);
Expand All @@ -690,6 +780,7 @@ AnimationNodeBlendSpace1DEditor::AnimationNodeBlendSpace1DEditor() {
tool_erase->set_theme_type_variation(SceneStringName(FlatButton));
top_hb->add_child(tool_erase);
tool_erase->set_tooltip_text(TTR("Erase points."));
tool_erase->set_accessibility_name(TTRC("Erase Points"));
tool_erase->connect(SceneStringName(pressed), callable_mp(this, &AnimationNodeBlendSpace1DEditor::_erase_selected));

top_hb->add_child(memnew(VSeparator));
Expand All @@ -700,6 +791,7 @@ AnimationNodeBlendSpace1DEditor::AnimationNodeBlendSpace1DEditor() {
top_hb->add_child(snap);
snap->set_pressed(true);
snap->set_tooltip_text(TTR("Enable snap and show grid."));
snap->set_accessibility_name(TTRC("Snap to Grid"));
snap->connect(SceneStringName(pressed), callable_mp(this, &AnimationNodeBlendSpace1DEditor::_snap_toggled));

snap_value = memnew(SpinBox);
Expand All @@ -722,6 +814,26 @@ AnimationNodeBlendSpace1DEditor::AnimationNodeBlendSpace1DEditor() {
top_hb->add_child(interpolation);
interpolation->connect(SceneStringName(item_selected), callable_mp(this, &AnimationNodeBlendSpace1DEditor::_config_changed));

blending_hb = memnew(HBoxContainer);
top_hb->add_child(blending_hb);
blending_hb->add_child(memnew(VSeparator));

blending_hb->add_child(memnew(Label(TTR("Use Velocity Limit:"))));
use_velocity_limit = memnew(CheckBox);
blending_hb->add_child(use_velocity_limit);
use_velocity_limit->connect(SceneStringName(toggled), callable_mp(this, &AnimationNodeBlendSpace1DEditor::_config_changed));

blending_hb->add_child(memnew(Label(TTR("Default Velocity limit:"))));
default_velocity_limit = memnew(SpinBox);
blending_hb->add_child(default_velocity_limit);
default_velocity_limit->set_min(0.0);
default_velocity_limit->set_step(0.01);
default_velocity_limit->set_max(60.0);
default_velocity_limit->set_suffix("/s");
default_velocity_limit->connect(SceneStringName(value_changed), callable_mp(this, &AnimationNodeBlendSpace1DEditor::_config_changed));

current_blend_point_editor.instantiate();

edit_hb = memnew(HBoxContainer);
top_hb->add_child(edit_hb);
edit_hb->add_child(memnew(VSeparator));
Expand Down
Loading