Skip to content

Commit

Permalink
implement reverse play back for animtree
Browse files Browse the repository at this point in the history
  • Loading branch information
TokageItLab committed May 1, 2021
1 parent dea84c9 commit 4113abd
Show file tree
Hide file tree
Showing 4 changed files with 191 additions and 78 deletions.
10 changes: 7 additions & 3 deletions scene/animation/animation_blend_tree.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -87,10 +87,10 @@ float AnimationNodeAnimation::process(float p_time, bool p_seek) {
float step;

if (p_seek) {
step = p_time - time;
time = p_time;
step = 0;
} else {
time = MAX(0, time + p_time);
time = time + p_time;
step = p_time;
}

Expand All @@ -103,6 +103,10 @@ float AnimationNodeAnimation::process(float p_time, bool p_seek) {

} else if (time > anim_size) {
time = anim_size;
step = 0;
} else if (time < 0) {
time = 0;
step = 0;
}

blend_animation(animation, time, step, p_seek, 1.0);
Expand Down Expand Up @@ -534,7 +538,7 @@ AnimationNodeBlend3::AnimationNodeBlend3() {
/////////////////////////////////

void AnimationNodeTimeScale::get_parameter_list(List<PropertyInfo> *r_list) const {
r_list->push_back(PropertyInfo(Variant::FLOAT, scale, PROPERTY_HINT_RANGE, "0,32,0.01,or_greater"));
r_list->push_back(PropertyInfo(Variant::FLOAT, scale, PROPERTY_HINT_RANGE, "-32,32,0.01,or_greater"));
}

Variant AnimationNodeTimeScale::get_parameter_default_value(const StringName &p_parameter) const {
Expand Down
84 changes: 61 additions & 23 deletions scene/animation/animation_tree.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -819,6 +819,7 @@ void AnimationTree::_process_graph(float p_delta) {
float delta = as.delta;
float weight = as.blend;
bool seeked = as.seeked;
bool reverse = delta < 0;

for (int i = 0; i < a->get_track_count(); i++) {
NodePath path = a->track_get_path(i);
Expand Down Expand Up @@ -857,54 +858,81 @@ void AnimationTree::_process_graph(float p_delta) {
}

float prev_time = time - delta;
if (prev_time < 0) {
if (!a->has_loop()) {
prev_time = 0;
} else {
prev_time = a->get_length() + prev_time;
if (!reverse) {
if (prev_time < 0) {
if (!a->has_loop()) {
prev_time = 0;
} else {
prev_time = Math::fposmod(prev_time, a->get_length());
}
}
} else {
if (prev_time > a->get_length()) {
if (!a->has_loop()) {
prev_time = a->get_length();
} else {
prev_time = Math::fposmod(prev_time, a->get_length());
}
}
}

Vector3 loc[2];
Quat rot[2];
Vector3 scale[2];

if (prev_time > time) {
Error err = a->transform_track_interpolate(i, prev_time, &loc[0], &rot[0], &scale[0]);
if (err != OK) {
continue;
if (!reverse) {
if (prev_time > time) {
Error err = a->transform_track_interpolate(i, prev_time, &loc[0], &rot[0], &scale[0], reverse);
if (err != OK) {
continue;
}

a->transform_track_interpolate(i, a->get_length(), &loc[1], &rot[1], &scale[1], reverse);

t->loc += (loc[1] - loc[0]) * blend;
t->scale += (scale[1] - scale[0]) * blend;
Quat q = Quat().slerp(rot[0].normalized().inverse() * rot[1].normalized(), blend).normalized();
t->rot = (t->rot * q).normalized();

prev_time = 0;
}
} else {
if (prev_time < time) {
Error err = a->transform_track_interpolate(i, prev_time, &loc[0], &rot[0], &scale[0], reverse);
if (err != OK) {
continue;
}

a->transform_track_interpolate(i, a->get_length(), &loc[1], &rot[1], &scale[1]);
a->transform_track_interpolate(i, 0, &loc[1], &rot[1], &scale[1], reverse);

t->loc += (loc[1] - loc[0]) * blend;
t->scale += (scale[1] - scale[0]) * blend;
Quat q = Quat().slerp(rot[0].normalized().inverse() * rot[1].normalized(), blend).normalized();
t->rot = (t->rot * q).normalized();
t->loc += (loc[1] - loc[0]) * blend;
t->scale += (scale[1] - scale[0]) * blend;
Quat q = Quat().slerp(rot[0].normalized().inverse() * rot[1].normalized(), blend).normalized();
t->rot = (t->rot * q).normalized();

prev_time = 0;
prev_time = a->get_length();
}
}

Error err = a->transform_track_interpolate(i, prev_time, &loc[0], &rot[0], &scale[0]);
Error err = a->transform_track_interpolate(i, prev_time, &loc[0], &rot[0], &scale[0], reverse);
if (err != OK) {
continue;
}

a->transform_track_interpolate(i, time, &loc[1], &rot[1], &scale[1]);
a->transform_track_interpolate(i, time, &loc[1], &rot[1], &scale[1], reverse);

t->loc += (loc[1] - loc[0]) * blend;
t->scale += (scale[1] - scale[0]) * blend;
Quat q = Quat().slerp(rot[0].normalized().inverse() * rot[1].normalized(), blend).normalized();
t->rot = (t->rot * q).normalized();

prev_time = 0;

prev_time = !reverse ? 0 : a->get_length();
} else {
Vector3 loc;
Quat rot;
Vector3 scale;

Error err = a->transform_track_interpolate(i, time, &loc, &rot, &scale);
Error err = a->transform_track_interpolate(i, time, &loc, &rot, &scale, reverse);
//ERR_CONTINUE(err!=OK); //used for testing, should be removed

if (t->process_pass != process_pass) {
Expand Down Expand Up @@ -1082,8 +1110,18 @@ void AnimationTree::_process_graph(float p_delta) {

bool stop = false;

if (!loop && time < t->start) {
stop = true;
if (!loop) {
// An audio will be not stopped when animation end.
// You will be able to stop the audio by making 'stop = true' when 'delta == 0'.
if (delta > 0) {
if (time < t->start) {
stop = true;
}
} else if (delta < 0) {
if (time > t->start) {
stop = true;
}
}
} else if (t->len > 0) {
float len = t->start > time ? (a->get_length() - t->start) + time : time - t->start;

Expand Down Expand Up @@ -1117,7 +1155,7 @@ void AnimationTree::_process_graph(float p_delta) {
continue;
}

if (delta == 0 || seeked) {
if (seeked) {
//seek
int idx = a->track_find_key(i, time);
if (idx < 0) {
Expand Down
Loading

0 comments on commit 4113abd

Please sign in to comment.