Skip to content

Commit

Permalink
implement add_directry to animation tree node add2 and add3
Browse files Browse the repository at this point in the history
  • Loading branch information
TokageItLab authored and rafallus committed Oct 16, 2021
1 parent fddbbf4 commit a163d7e
Show file tree
Hide file tree
Showing 10 changed files with 99 additions and 16 deletions.
1 change: 1 addition & 0 deletions doc/classes/AnimationNode.xml
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
<argument index="3" name="blend" type="float" />
<argument index="4" name="filter" type="int" enum="AnimationNode.FilterAction" default="0" />
<argument index="5" name="optimize" type="bool" default="true" />
<argument index="6" name="add_directly" type="bool" default="false" />
<description>
Blend an input. This is only useful for nodes created for an [AnimationNodeBlendTree]. The [code]time[/code] parameter is a relative delta, unless [code]seek[/code] is [code]true[/code], in which case it is absolute. A filter mode may be optionally passed (see [enum FilterAction] for options).
</description>
Expand Down
3 changes: 3 additions & 0 deletions doc/classes/AnimationNodeAdd2.xml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@
<methods>
</methods>
<members>
<member name="add_directly" type="bool" setter="set_add_directly" getter="get_add_directly" default="true">
If [code]false[/code], adds the blended transformation after the subtraction of the difference. If [code]true[/code], adds the second transformation to first it directly.
</member>
<member name="sync" type="bool" setter="set_use_sync" getter="is_using_sync" default="false">
If [code]true[/code], sets the [code]optimization[/code] to [code]false[/code] when calling [method AnimationNode.blend_input], forcing the blended animations to update every frame.
</member>
Expand Down
3 changes: 3 additions & 0 deletions doc/classes/AnimationNodeAdd3.xml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@
<methods>
</methods>
<members>
<member name="add_directly" type="bool" setter="set_add_directly" getter="get_add_directly" default="true">
If [code]false[/code], adds the blended transformation after the subtraction of the difference. If [code]true[/code], adds the first or third transformation to second it directly.
</member>
<member name="sync" type="bool" setter="set_use_sync" getter="is_using_sync" default="false">
If [code]true[/code], sets the [code]optimization[/code] to [code]false[/code] when calling [method AnimationNode.blend_input], forcing the blended animations to update every frame.
</member>
Expand Down
2 changes: 2 additions & 0 deletions scene/animation/animation_blend_space_1d.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,8 @@ float AnimationNodeBlendSpace1D::process(float p_time, bool p_seek) {
return 0.0;
}

blend_points[blend_points_used - 1].node->add_directly = add_directly;

if (blend_points_used == 1) {
// only one point available, just play that animation
return blend_node(blend_points[0].name, blend_points[0].node, p_time, p_seek, 1.0, FILTER_IGNORE, false);
Expand Down
5 changes: 5 additions & 0 deletions scene/animation/animation_blend_space_2d.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -436,6 +436,8 @@ float AnimationNodeBlendSpace2D::process(float p_time, bool p_seek) {
int blend_triangle = -1;
float blend_weights[3] = { 0, 0, 0 };

blend_points[blend_points_used - 1].node->add_directly = add_directly;

for (int i = 0; i < triangles.size(); i++) {
Vector2 points[3];
for (int j = 0; j < 3; j++) {
Expand Down Expand Up @@ -513,6 +515,7 @@ float AnimationNodeBlendSpace2D::process(float p_time, bool p_seek) {
new_closest = i;
new_closest_dist = d;
}
blend_points[i].node->add_directly = false;
}

if (new_closest != closest && new_closest != -1) {
Expand All @@ -522,12 +525,14 @@ float AnimationNodeBlendSpace2D::process(float p_time, bool p_seek) {
from = length_internal - blend_node(blend_points[closest].name, blend_points[closest].node, p_time, false, 0.0, FILTER_IGNORE, false);
}

blend_points[new_closest].node->add_directly = add_directly;
mind = blend_node(blend_points[new_closest].name, blend_points[new_closest].node, from, true, 1.0, FILTER_IGNORE, false);
length_internal = from + mind;

closest = new_closest;

} else {
blend_points[closest].node->add_directly = add_directly;
mind = blend_node(blend_points[closest].name, blend_points[closest].node, p_time, p_seek, 1.0, FILTER_IGNORE, false);
}
}
Expand Down
37 changes: 34 additions & 3 deletions scene/animation/animation_blend_tree.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -375,14 +375,22 @@ bool AnimationNodeAdd2::is_using_sync() const {
return sync;
}

void AnimationNodeAdd2::set_add_directly(bool p_add_directly) {
add_directly = p_add_directly;
}

bool AnimationNodeAdd2::get_add_directly() const {
return add_directly;
}

bool AnimationNodeAdd2::has_filter() const {
return true;
}

float AnimationNodeAdd2::process(float p_time, bool p_seek) {
float amount = get_parameter(add_amount);
float rem0 = blend_input(0, p_time, p_seek, 1.0, FILTER_IGNORE, !sync);
blend_input(1, p_time, p_seek, amount, FILTER_PASS, !sync);
blend_input(1, p_time, p_seek, amount, FILTER_PASS, !sync, add_directly);

return rem0;
}
Expand All @@ -391,14 +399,19 @@ void AnimationNodeAdd2::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_use_sync", "enable"), &AnimationNodeAdd2::set_use_sync);
ClassDB::bind_method(D_METHOD("is_using_sync"), &AnimationNodeAdd2::is_using_sync);

ClassDB::bind_method(D_METHOD("set_add_directly", "enable"), &AnimationNodeAdd2::set_add_directly);
ClassDB::bind_method(D_METHOD("get_add_directly"), &AnimationNodeAdd2::get_add_directly);

ADD_PROPERTY(PropertyInfo(Variant::BOOL, "sync"), "set_use_sync", "is_using_sync");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "add_directly"), "set_add_directly", "get_add_directly");
}

AnimationNodeAdd2::AnimationNodeAdd2() {
add_amount = "add_amount";
add_input("in");
add_input("add");
sync = false;
add_directly = true;
}

////////////////////////////////////////////////
Expand All @@ -421,15 +434,28 @@ bool AnimationNodeAdd3::is_using_sync() const {
return sync;
}

void AnimationNodeAdd3::set_add_directly(bool p_add_directly) {
add_directly = p_add_directly;
}

bool AnimationNodeAdd3::get_add_directly() const {
return add_directly;
}

bool AnimationNodeAdd3::has_filter() const {
return true;
}

float AnimationNodeAdd3::process(float p_time, bool p_seek) {
float amount = get_parameter(add_amount);
blend_input(0, p_time, p_seek, MAX(0, -amount), FILTER_PASS, !sync);
float rem0 = blend_input(1, p_time, p_seek, 1.0, FILTER_IGNORE, !sync);
blend_input(2, p_time, p_seek, MAX(0, amount), FILTER_PASS, !sync);
if (amount < 0) {
blend_input(0, p_time, p_seek, -amount, FILTER_PASS, !sync, add_directly);
blend_input(2, p_time, p_seek, 0, FILTER_PASS, !sync);
} else {
blend_input(2, p_time, p_seek, amount, FILTER_PASS, !sync, add_directly);
blend_input(0, p_time, p_seek, 0, FILTER_PASS, !sync);
}

return rem0;
}
Expand All @@ -438,7 +464,11 @@ void AnimationNodeAdd3::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_use_sync", "enable"), &AnimationNodeAdd3::set_use_sync);
ClassDB::bind_method(D_METHOD("is_using_sync"), &AnimationNodeAdd3::is_using_sync);

ClassDB::bind_method(D_METHOD("set_add_directly", "enable"), &AnimationNodeAdd3::set_add_directly);
ClassDB::bind_method(D_METHOD("get_add_directly"), &AnimationNodeAdd3::get_add_directly);

ADD_PROPERTY(PropertyInfo(Variant::BOOL, "sync"), "set_use_sync", "is_using_sync");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "add_directly"), "set_add_directly", "get_add_directly");
}

AnimationNodeAdd3::AnimationNodeAdd3() {
Expand All @@ -447,6 +477,7 @@ AnimationNodeAdd3::AnimationNodeAdd3() {
add_input("in");
add_input("+add");
sync = false;
add_directly = true;
}
/////////////////////////////////////////////

Expand Down
8 changes: 8 additions & 0 deletions scene/animation/animation_blend_tree.h
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,7 @@ class AnimationNodeAdd2 : public AnimationNode {

StringName add_amount;
bool sync;
bool add_directly;

protected:
static void _bind_methods();
Expand All @@ -147,6 +148,9 @@ class AnimationNodeAdd2 : public AnimationNode {
void set_use_sync(bool p_sync);
bool is_using_sync() const;

void set_add_directly(bool p_add_directly);
bool get_add_directly() const;

virtual bool has_filter() const;
virtual float process(float p_time, bool p_seek);

Expand All @@ -158,6 +162,7 @@ class AnimationNodeAdd3 : public AnimationNode {

StringName add_amount;
bool sync;
bool add_directly;

protected:
static void _bind_methods();
Expand All @@ -171,6 +176,9 @@ class AnimationNodeAdd3 : public AnimationNode {
void set_use_sync(bool p_sync);
bool is_using_sync() const;

void set_add_directly(bool p_add_directly);
bool get_add_directly() const;

virtual bool has_filter() const;
virtual float process(float p_time, bool p_seek);

Expand Down
9 changes: 9 additions & 0 deletions scene/animation/animation_node_state_machine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -309,6 +309,7 @@ float AnimationNodeStateMachinePlayback::process(AnimationNodeStateMachine *p_st
// can restart, just postpone traveling
path.clear();
current = p_state_machine->start_node;
p_state_machine->states[current].node->add_directly = p_state_machine->add_directly;
playing = true;
play_start = true;
} else {
Expand All @@ -322,6 +323,7 @@ float AnimationNodeStateMachinePlayback::process(AnimationNodeStateMachine *p_st
// can't travel, then teleport
path.clear();
current = start_request;
p_state_machine->states[current].node->add_directly = p_state_machine->add_directly;
}
start_request = StringName(); //clear start request
}
Expand All @@ -330,6 +332,7 @@ float AnimationNodeStateMachinePlayback::process(AnimationNodeStateMachine *p_st
if (p_state_machine->states.has(start_request)) {
path.clear();
current = start_request;
p_state_machine->states[current].node->add_directly = p_state_machine->add_directly;
playing = true;
play_start = true;
start_request = StringName(); //clear start request
Expand All @@ -345,7 +348,11 @@ float AnimationNodeStateMachinePlayback::process(AnimationNodeStateMachine *p_st

if (do_start) {
if (p_state_machine->start_node != StringName() && p_seek && p_time == 0) {
if (current != StringName()) {
p_state_machine->states[current].node->add_directly = false;
}
current = p_state_machine->start_node;
p_state_machine->states[current].node->add_directly = p_state_machine->add_directly;
}

len_current = p_state_machine->blend_node(current, p_state_machine->states[current].node, 0, true, 1.0, AnimationNode::FILTER_IGNORE, false);
Expand Down Expand Up @@ -464,7 +471,9 @@ float AnimationNodeStateMachinePlayback::process(AnimationNodeStateMachine *p_st
if (path.size()) { //if it came from path, remove path
path.remove(0);
}
p_state_machine->states[current].node->add_directly = false;
current = next;
p_state_machine->states[current].node->add_directly = p_state_machine->add_directly;
if (switch_mode == AnimationNodeStateMachineTransition::SWITCH_MODE_SYNC) {
len_current = p_state_machine->blend_node(current, p_state_machine->states[current].node, 0, true, 0, AnimationNode::FILTER_IGNORE, false);
pos_current = MIN(pos_current, len_current);
Expand Down
43 changes: 31 additions & 12 deletions scene/animation/animation_tree.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@ void AnimationNode::blend_animation(const StringName &p_animation, float p_time,
anim_state.time = p_time;
anim_state.animation = animation;
anim_state.seeked = p_seeked;
anim_state.add_directly = add_directly;

state->animation_states.push_back(anim_state);
}
Expand Down Expand Up @@ -141,7 +142,7 @@ void AnimationNode::make_invalid(const String &p_reason) {
state->invalid_reasons += String::utf8("") + p_reason;
}

float AnimationNode::blend_input(int p_input, float p_time, bool p_seek, float p_blend, FilterAction p_filter, bool p_optimize) {
float AnimationNode::blend_input(int p_input, float p_time, bool p_seek, float p_blend, FilterAction p_filter, bool p_optimize, bool p_add_directly) {
ERR_FAIL_INDEX_V(p_input, inputs.size(), 0);
ERR_FAIL_COND_V(!state, 0);

Expand All @@ -154,6 +155,9 @@ float AnimationNode::blend_input(int p_input, float p_time, bool p_seek, float p
String name = blend_tree->get_node_name(Ref<AnimationNode>(this));
make_invalid(vformat(RTR("Nothing connected to input '%s' of node '%s'."), get_input_name(p_input), name));
return 0;
} else {
Ref<AnimationNode> node = blend_tree->get_node(node_name);
node->add_directly = p_add_directly;
}

Ref<AnimationNode> node = blend_tree->get_node(node_name);
Expand Down Expand Up @@ -409,7 +413,7 @@ void AnimationNode::_bind_methods() {

ClassDB::bind_method(D_METHOD("blend_animation", "animation", "time", "delta", "seeked", "blend"), &AnimationNode::blend_animation);
ClassDB::bind_method(D_METHOD("blend_node", "name", "node", "time", "seek", "blend", "filter", "optimize"), &AnimationNode::blend_node, DEFVAL(FILTER_IGNORE), DEFVAL(true));
ClassDB::bind_method(D_METHOD("blend_input", "input_index", "time", "seek", "blend", "filter", "optimize"), &AnimationNode::blend_input, DEFVAL(FILTER_IGNORE), DEFVAL(true));
ClassDB::bind_method(D_METHOD("blend_input", "input_index", "time", "seek", "blend", "filter", "optimize", "add_directly"), &AnimationNode::blend_input, DEFVAL(FILTER_IGNORE), DEFVAL(true), DEFVAL(false));

ClassDB::bind_method(D_METHOD("set_parameter", "name", "value"), &AnimationNode::set_parameter);
ClassDB::bind_method(D_METHOD("get_parameter", "name"), &AnimationNode::get_parameter);
Expand Down Expand Up @@ -921,16 +925,23 @@ void AnimationTree::_process_graph(float p_delta) {
continue;
}

t->loc = t->loc.linear_interpolate(loc, blend);
if (t->rot_blend_accum == 0) {
t->rot = rot;
t->rot_blend_accum = blend;
if (!as.add_directly) {
t->loc = t->loc.linear_interpolate(loc, blend);
if (t->rot_blend_accum == 0) {
t->rot = rot;
t->rot_blend_accum = blend;
} else {
float rot_total = t->rot_blend_accum + blend;
t->rot = rot.slerp(t->rot, t->rot_blend_accum / rot_total).normalized();
t->rot_blend_accum = rot_total;
}
t->scale = t->scale.linear_interpolate(scale, blend);
} else {
float rot_total = t->rot_blend_accum + blend;
t->rot = rot.slerp(t->rot, t->rot_blend_accum / rot_total).normalized();
t->rot_blend_accum = rot_total;
t->loc += loc * blend;
t->scale = t->scale.linear_interpolate(scale, blend);
Quat q = Quat().slerp(rot.normalized(), blend).normalized();
t->rot = (t->rot * q).normalized();
}
t->scale = t->scale.linear_interpolate(scale, blend);
}

} break;
Expand All @@ -952,7 +963,11 @@ void AnimationTree::_process_graph(float p_delta) {
t->process_pass = process_pass;
}

Variant::interpolate(t->value, value, blend, t->value);
if (as.add_directly) {
Variant::blend(t->value, value, blend, t->value);
} else {
Variant::interpolate(t->value, value, blend, t->value);
}

} else {
List<int> indices;
Expand Down Expand Up @@ -1004,7 +1019,11 @@ void AnimationTree::_process_graph(float p_delta) {
t->process_pass = process_pass;
}

t->value = Math::lerp(t->value, bezier, blend);
if (as.add_directly) {
t->value += bezier * blend;
} else {
t->value = Math::lerp(t->value, bezier, blend);
}

} break;
case Animation::TYPE_AUDIO: {
Expand Down
4 changes: 3 additions & 1 deletion scene/animation/animation_tree.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ class AnimationNode : public Resource {
const Vector<float> *track_blends;
float blend;
bool seeked;
bool add_directly;
};

struct State {
Expand All @@ -94,6 +95,7 @@ class AnimationNode : public Resource {

HashMap<NodePath, bool> filter;
bool filter_enabled;
bool add_directly;

Array _get_filters() const;
void _set_filters(const Array &p_filters);
Expand All @@ -103,7 +105,7 @@ class AnimationNode : public Resource {
protected:
void blend_animation(const StringName &p_animation, float p_time, float p_delta, bool p_seeked, float p_blend);
float blend_node(const StringName &p_sub_path, Ref<AnimationNode> p_node, float p_time, bool p_seek, float p_blend, FilterAction p_filter = FILTER_IGNORE, bool p_optimize = true);
float blend_input(int p_input, float p_time, bool p_seek, float p_blend, FilterAction p_filter = FILTER_IGNORE, bool p_optimize = true);
float blend_input(int p_input, float p_time, bool p_seek, float p_blend, FilterAction p_filter = FILTER_IGNORE, bool p_optimize = true, bool p_add_directly = false);
void make_invalid(const String &p_reason);

static void _bind_methods();
Expand Down

0 comments on commit a163d7e

Please sign in to comment.