summaryrefslogtreecommitdiff
path: root/scene/animation/animation_blend_tree.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'scene/animation/animation_blend_tree.cpp')
-rw-r--r--scene/animation/animation_blend_tree.cpp87
1 files changed, 68 insertions, 19 deletions
diff --git a/scene/animation/animation_blend_tree.cpp b/scene/animation/animation_blend_tree.cpp
index 10a66386eb..d6c5d0b51c 100644
--- a/scene/animation/animation_blend_tree.cpp
+++ b/scene/animation/animation_blend_tree.cpp
@@ -30,6 +30,7 @@
#include "animation_blend_tree.h"
+#include "scene/resources/animation.h"
#include "scene/scene_string_names.h"
void AnimationNodeAnimation::set_animation(const StringName &p_name) {
@@ -83,30 +84,55 @@ double AnimationNodeAnimation::process(double p_time, bool p_seek) {
}
Ref<Animation> anim = ap->get_animation(animation);
-
- double step;
+ double anim_size = (double)anim->get_length();
+ double step = 0.0;
+ double prev_time = time;
+ int pingponged = 0;
+ bool current_backward = signbit(p_time);
if (p_seek) {
+ step = p_time - time;
time = p_time;
- step = 0;
} else {
- time = MAX(0, time + p_time);
- step = p_time;
+ p_time *= backward ? -1.0 : 1.0;
+ if (!(time == anim_size && !current_backward) && !(time == 0 && current_backward)) {
+ time = time + p_time;
+ step = p_time;
+ }
}
- double anim_size = anim->get_length();
-
- if (anim->has_loop()) {
+ if (anim->get_loop_mode() == Animation::LoopMode::LOOP_PINGPONG) {
if (anim_size) {
- time = Math::fposmod(time, anim_size);
+ if ((int)Math::floor(abs(time - prev_time) / anim_size) % 2 == 0) {
+ if (prev_time > 0 && time <= 0) {
+ backward = !backward;
+ pingponged = -1;
+ }
+ if (prev_time < anim_size && time >= anim_size) {
+ backward = !backward;
+ pingponged = 1;
+ }
+ }
+ time = Math::pingpong(time, anim_size);
}
-
- } else if (time > anim_size) {
- time = anim_size;
+ } else {
+ if (anim->get_loop_mode() == Animation::LoopMode::LOOP_LINEAR) {
+ if (anim_size) {
+ time = Math::fposmod(time, anim_size);
+ }
+ } else if (time < 0) {
+ time = 0;
+ } else if (time > anim_size) {
+ time = anim_size;
+ }
+ backward = false;
}
- blend_animation(animation, time, step, p_seek, 1.0);
-
+ if (play_mode == PLAY_MODE_FORWARD) {
+ blend_animation(animation, time, step, p_seek, 1.0, pingponged);
+ } else {
+ blend_animation(animation, anim_size - time, -step, p_seek, 1.0, pingponged);
+ }
set_parameter(this->time, time);
return anim_size - time;
@@ -116,11 +142,34 @@ String AnimationNodeAnimation::get_caption() const {
return "Animation";
}
+void AnimationNodeAnimation::set_play_mode(PlayMode p_play_mode) {
+ play_mode = p_play_mode;
+}
+
+AnimationNodeAnimation::PlayMode AnimationNodeAnimation::get_play_mode() const {
+ return play_mode;
+}
+
+void AnimationNodeAnimation::set_backward(bool p_backward) {
+ backward = p_backward;
+}
+
+bool AnimationNodeAnimation::is_backward() const {
+ return backward;
+}
+
void AnimationNodeAnimation::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_animation", "name"), &AnimationNodeAnimation::set_animation);
ClassDB::bind_method(D_METHOD("get_animation"), &AnimationNodeAnimation::get_animation);
+ ClassDB::bind_method(D_METHOD("set_play_mode", "mode"), &AnimationNodeAnimation::set_play_mode);
+ ClassDB::bind_method(D_METHOD("get_play_mode"), &AnimationNodeAnimation::get_play_mode);
+
ADD_PROPERTY(PropertyInfo(Variant::STRING_NAME, "animation"), "set_animation", "get_animation");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "play_mode", PROPERTY_HINT_ENUM, "Forward,Backward"), "set_play_mode", "get_play_mode");
+
+ BIND_ENUM_CONSTANT(PLAY_MODE_FORWARD);
+ BIND_ENUM_CONSTANT(PLAY_MODE_BACKWARD);
}
AnimationNodeAnimation::AnimationNodeAnimation() {
@@ -533,7 +582,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_lesser,or_greater"));
}
Variant AnimationNodeTimeScale::get_parameter_default_value(const StringName &p_parameter) const {
@@ -1112,12 +1161,12 @@ void AnimationNodeBlendTree::_get_property_list(List<PropertyInfo> *p_list) cons
for (const StringName &E : names) {
String name = E;
if (name != "output") {
- p_list->push_back(PropertyInfo(Variant::OBJECT, "nodes/" + name + "/node", PROPERTY_HINT_RESOURCE_TYPE, "AnimationNode", PROPERTY_USAGE_NOEDITOR));
+ p_list->push_back(PropertyInfo(Variant::OBJECT, "nodes/" + name + "/node", PROPERTY_HINT_RESOURCE_TYPE, "AnimationNode", PROPERTY_USAGE_NO_EDITOR));
}
- p_list->push_back(PropertyInfo(Variant::VECTOR2, "nodes/" + name + "/position", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR));
+ p_list->push_back(PropertyInfo(Variant::VECTOR2, "nodes/" + name + "/position", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR));
}
- p_list->push_back(PropertyInfo(Variant::ARRAY, "node_connections", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR));
+ p_list->push_back(PropertyInfo(Variant::ARRAY, "node_connections", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR));
}
void AnimationNodeBlendTree::reset_state() {
@@ -1152,7 +1201,7 @@ void AnimationNodeBlendTree::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_graph_offset", "offset"), &AnimationNodeBlendTree::set_graph_offset);
ClassDB::bind_method(D_METHOD("get_graph_offset"), &AnimationNodeBlendTree::get_graph_offset);
- ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "graph_offset", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_graph_offset", "get_graph_offset");
+ ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "graph_offset", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR), "set_graph_offset", "get_graph_offset");
BIND_CONSTANT(CONNECTION_OK);
BIND_CONSTANT(CONNECTION_ERROR_NO_INPUT);