summaryrefslogtreecommitdiff
path: root/scene/animation/animation_tree.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'scene/animation/animation_tree.cpp')
-rw-r--r--scene/animation/animation_tree.cpp180
1 files changed, 93 insertions, 87 deletions
diff --git a/scene/animation/animation_tree.cpp b/scene/animation/animation_tree.cpp
index 7369713e69..9ca8d478b1 100644
--- a/scene/animation/animation_tree.cpp
+++ b/scene/animation/animation_tree.cpp
@@ -36,8 +36,9 @@
#include "servers/audio/audio_stream.h"
void AnimationNode::get_parameter_list(List<PropertyInfo> *r_list) const {
- if (get_script_instance()) {
- Array parameters = get_script_instance()->call("get_parameter_list");
+ Array parameters;
+
+ if (GDVIRTUAL_CALL(_get_parameter_list, parameters)) {
for (int i = 0; i < parameters.size(); i++) {
Dictionary d = parameters[i];
ERR_CONTINUE(d.is_empty());
@@ -47,8 +48,9 @@ void AnimationNode::get_parameter_list(List<PropertyInfo> *r_list) const {
}
Variant AnimationNode::get_parameter_default_value(const StringName &p_parameter) const {
- if (get_script_instance()) {
- return get_script_instance()->call("get_parameter_default_value", p_parameter);
+ Variant ret;
+ if (GDVIRTUAL_CALL(_get_parameter_default_value, p_parameter, ret)) {
+ return ret;
}
return Variant();
}
@@ -72,20 +74,20 @@ Variant AnimationNode::get_parameter(const StringName &p_name) const {
}
void AnimationNode::get_child_nodes(List<ChildNode> *r_child_nodes) {
- if (get_script_instance()) {
- Dictionary cn = get_script_instance()->call("get_child_nodes");
+ Dictionary cn;
+ if (GDVIRTUAL_CALL(_get_child_nodes, cn)) {
List<Variant> keys;
cn.get_key_list(&keys);
- for (List<Variant>::Element *E = keys.front(); E; E = E->next()) {
+ for (const Variant &E : keys) {
ChildNode child;
- child.name = E->get();
- child.node = cn[E->get()];
+ child.name = E;
+ child.node = cn[E];
r_child_nodes->push_back(child);
}
}
}
-void AnimationNode::blend_animation(const StringName &p_animation, float p_time, float p_delta, bool p_seeked, float p_blend) {
+void AnimationNode::blend_animation(const StringName &p_animation, real_t p_time, real_t p_delta, bool p_seeked, real_t p_blend) {
ERR_FAIL_COND(!state);
ERR_FAIL_COND(!state->player->has_animation(p_animation));
@@ -115,13 +117,13 @@ void AnimationNode::blend_animation(const StringName &p_animation, float p_time,
state->animation_states.push_back(anim_state);
}
-float AnimationNode::_pre_process(const StringName &p_base_path, AnimationNode *p_parent, State *p_state, float p_time, bool p_seek, const Vector<StringName> &p_connections) {
+real_t AnimationNode::_pre_process(const StringName &p_base_path, AnimationNode *p_parent, State *p_state, real_t p_time, bool p_seek, const Vector<StringName> &p_connections) {
base_path = p_base_path;
parent = p_parent;
connections = p_connections;
state = p_state;
- float t = process(p_time, p_seek);
+ real_t t = process(p_time, p_seek);
state = nullptr;
parent = nullptr;
@@ -137,10 +139,10 @@ void AnimationNode::make_invalid(const String &p_reason) {
if (state->invalid_reasons != String()) {
state->invalid_reasons += "\n";
}
- state->invalid_reasons += "- " + 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) {
+real_t AnimationNode::blend_input(int p_input, real_t p_time, bool p_seek, real_t p_blend, FilterAction p_filter, bool p_optimize) {
ERR_FAIL_INDEX_V(p_input, inputs.size(), 0);
ERR_FAIL_COND_V(!state, 0);
@@ -158,8 +160,8 @@ float AnimationNode::blend_input(int p_input, float p_time, bool p_seek, float p
Ref<AnimationNode> node = blend_tree->get_node(node_name);
//inputs.write[p_input].last_pass = state->last_pass;
- float activity = 0.0;
- float ret = _blend_node(node_name, blend_tree->get_node_connection_array(node_name), nullptr, node, p_time, p_seek, p_blend, p_filter, p_optimize, &activity);
+ real_t activity = 0.0;
+ real_t ret = _blend_node(node_name, blend_tree->get_node_connection_array(node_name), nullptr, node, p_time, p_seek, p_blend, p_filter, p_optimize, &activity);
Vector<AnimationTree::Activity> *activity_ptr = state->tree->input_activity_map.getptr(base_path);
@@ -170,11 +172,11 @@ float AnimationNode::blend_input(int p_input, float p_time, bool p_seek, float p
return ret;
}
-float AnimationNode::blend_node(const StringName &p_sub_path, Ref<AnimationNode> p_node, float p_time, bool p_seek, float p_blend, FilterAction p_filter, bool p_optimize) {
+real_t AnimationNode::blend_node(const StringName &p_sub_path, Ref<AnimationNode> p_node, real_t p_time, bool p_seek, real_t p_blend, FilterAction p_filter, bool p_optimize) {
return _blend_node(p_sub_path, Vector<StringName>(), this, p_node, p_time, p_seek, p_blend, p_filter, p_optimize);
}
-float AnimationNode::_blend_node(const StringName &p_subpath, const Vector<StringName> &p_connections, AnimationNode *p_new_parent, Ref<AnimationNode> p_node, float p_time, bool p_seek, float p_blend, FilterAction p_filter, bool p_optimize, float *r_max) {
+real_t AnimationNode::_blend_node(const StringName &p_subpath, const Vector<StringName> &p_connections, AnimationNode *p_new_parent, Ref<AnimationNode> p_node, real_t p_time, bool p_seek, real_t p_blend, FilterAction p_filter, bool p_optimize, real_t *r_max) {
ERR_FAIL_COND_V(!p_node.is_valid(), 0);
ERR_FAIL_COND_V(!state, 0);
@@ -184,8 +186,8 @@ float AnimationNode::_blend_node(const StringName &p_subpath, const Vector<Strin
p_node->blends.resize(blend_count);
}
- float *blendw = p_node->blends.ptrw();
- const float *blendr = blends.ptr();
+ real_t *blendw = p_node->blends.ptrw();
+ const real_t *blendr = blends.ptr();
bool any_valid = false;
@@ -298,8 +300,9 @@ String AnimationNode::get_input_name(int p_input) {
}
String AnimationNode::get_caption() const {
- if (get_script_instance()) {
- return get_script_instance()->call("get_caption");
+ String ret;
+ if (GDVIRTUAL_CALL(_get_caption, ret)) {
+ return ret;
}
return "Node";
@@ -328,9 +331,10 @@ void AnimationNode::remove_input(int p_index) {
emit_changed();
}
-float AnimationNode::process(float p_time, bool p_seek) {
- if (get_script_instance()) {
- return get_script_instance()->call("process", p_time, p_seek);
+double AnimationNode::process(double p_time, bool p_seek) {
+ double ret;
+ if (GDVIRTUAL_CALL(_process, p_time, p_seek, ret)) {
+ return ret;
}
return 0;
@@ -357,6 +361,11 @@ bool AnimationNode::is_path_filtered(const NodePath &p_path) const {
}
bool AnimationNode::has_filter() const {
+ bool ret;
+ if (GDVIRTUAL_CALL(_has_filter, ret)) {
+ return ret;
+ }
+
return false;
}
@@ -381,13 +390,14 @@ void AnimationNode::_set_filters(const Array &p_filters) {
void AnimationNode::_validate_property(PropertyInfo &property) const {
if (!has_filter() && (property.name == "filter_enabled" || property.name == "filters")) {
- property.usage = 0;
+ property.usage = PROPERTY_USAGE_NONE;
}
}
Ref<AnimationNode> AnimationNode::get_child_by_name(const StringName &p_name) {
- if (get_script_instance()) {
- return get_script_instance()->call("get_child_by_name", p_name);
+ Ref<AnimationNode> ret;
+ if (GDVIRTUAL_CALL(_get_child_by_name, p_name, ret)) {
+ return ret;
}
return Ref<AnimationNode>();
}
@@ -418,17 +428,13 @@ void AnimationNode::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "filter_enabled", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_filter_enabled", "is_filter_enabled");
ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "filters", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "_set_filters", "_get_filters");
- BIND_VMETHOD(MethodInfo(Variant::DICTIONARY, "get_child_nodes"));
- BIND_VMETHOD(MethodInfo(Variant::ARRAY, "get_parameter_list"));
- BIND_VMETHOD(MethodInfo(Variant::OBJECT, "get_child_by_name", PropertyInfo(Variant::STRING, "name")));
- {
- MethodInfo mi = MethodInfo(Variant::NIL, "get_parameter_default_value", PropertyInfo(Variant::STRING_NAME, "name"));
- mi.return_val.usage = PROPERTY_USAGE_NIL_IS_VARIANT;
- BIND_VMETHOD(mi);
- }
- BIND_VMETHOD(MethodInfo("process", PropertyInfo(Variant::FLOAT, "time"), PropertyInfo(Variant::BOOL, "seek")));
- BIND_VMETHOD(MethodInfo(Variant::STRING, "get_caption"));
- BIND_VMETHOD(MethodInfo(Variant::BOOL, "has_filter"));
+ GDVIRTUAL_BIND(_get_child_nodes);
+ GDVIRTUAL_BIND(_get_parameter_list);
+ GDVIRTUAL_BIND(_get_child_by_name, "name");
+ GDVIRTUAL_BIND(_get_parameter_default_value, "parameter");
+ GDVIRTUAL_BIND(_process, "time", "seek");
+ GDVIRTUAL_BIND(_get_caption);
+ GDVIRTUAL_BIND(_has_filter);
ADD_SIGNAL(MethodInfo("removed_from_graph"));
@@ -532,8 +538,8 @@ bool AnimationTree::_update_caches(AnimationPlayer *player) {
List<StringName> sname;
player->get_animation_list(&sname);
- for (List<StringName>::Element *E = sname.front(); E; E = E->next()) {
- Ref<Animation> anim = player->get_animation(E->get());
+ for (const StringName &E : sname) {
+ Ref<Animation> anim = player->get_animation(E);
for (int i = 0; i < anim->get_track_count(); i++) {
NodePath path = anim->track_get_path(i);
Animation::TrackType track_type = anim->track_get_type(i);
@@ -557,7 +563,7 @@ bool AnimationTree::_update_caches(AnimationPlayer *player) {
Node *child = parent->get_node_and_resource(path, resource, leftover_path);
if (!child) {
- ERR_PRINT("AnimationTree: '" + String(E->get()) + "', couldn't resolve track: '" + String(path) + "'");
+ ERR_PRINT("AnimationTree: '" + String(E) + "', couldn't resolve track: '" + String(path) + "'");
continue;
}
@@ -586,7 +592,7 @@ bool AnimationTree::_update_caches(AnimationPlayer *player) {
Node3D *node_3d = Object::cast_to<Node3D>(child);
if (!node_3d) {
- ERR_PRINT("AnimationTree: '" + String(E->get()) + "', transform track does not point to Node3D: '" + String(path) + "'");
+ ERR_PRINT("AnimationTree: '" + String(E) + "', transform track does not point to Node3D: '" + String(path) + "'");
continue;
}
@@ -714,7 +720,7 @@ void AnimationTree::_clear_caches() {
cache_valid = false;
}
-void AnimationTree::_process_graph(float p_delta) {
+void AnimationTree::_process_graph(real_t p_delta) {
_update_properties(); //if properties need updating, update them
//check all tracks, see if they need modification
@@ -786,7 +792,7 @@ void AnimationTree::_process_graph(float p_delta) {
// root source blends
root->blends.resize(state.track_count);
- float *src_blendsw = root->blends.ptrw();
+ real_t *src_blendsw = root->blends.ptrw();
for (int i = 0; i < state.track_count; i++) {
src_blendsw[i] = 1.0; //by default all go to 1 for the root input
}
@@ -812,13 +818,11 @@ void AnimationTree::_process_graph(float p_delta) {
{
bool can_call = is_inside_tree() && !Engine::get_singleton()->is_editor_hint();
- for (List<AnimationNode::AnimationState>::Element *E = state.animation_states.front(); E; E = E->next()) {
- const AnimationNode::AnimationState &as = E->get();
-
+ for (const AnimationNode::AnimationState &as : state.animation_states) {
Ref<Animation> a = as.animation;
- float time = as.time;
- float delta = as.delta;
- float weight = as.blend;
+ double time = as.time;
+ double delta = as.delta;
+ real_t weight = as.blend;
bool seeked = as.seeked;
for (int i = 0; i < a->get_track_count(); i++) {
@@ -838,7 +842,7 @@ void AnimationTree::_process_graph(float p_delta) {
ERR_CONTINUE(blend_idx < 0 || blend_idx >= state.track_count);
- float blend = (*as.track_blends)[blend_idx] * weight;
+ real_t blend = (*as.track_blends)[blend_idx] * weight;
if (blend < CMP_EPSILON) {
continue; //nothing to blend
@@ -858,7 +862,7 @@ void AnimationTree::_process_graph(float p_delta) {
t->scale = Vector3(1, 1, 1);
}
- float prev_time = time - delta;
+ real_t prev_time = time - delta;
if (prev_time < 0) {
if (!a->has_loop()) {
prev_time = 0;
@@ -926,7 +930,7 @@ void AnimationTree::_process_graph(float p_delta) {
t->rot = rot;
t->rot_blend_accum = blend;
} else {
- float rot_total = t->rot_blend_accum + blend;
+ real_t 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;
}
@@ -954,12 +958,12 @@ void AnimationTree::_process_graph(float p_delta) {
Variant::interpolate(t->value, value, blend, t->value);
- } else if (delta != 0) {
+ } else {
List<int> indices;
a->value_track_get_key_indices(i, time, delta, &indices);
- for (List<int>::Element *F = indices.front(); F; F = F->next()) {
- Variant value = a->track_get_key_value(i, F->get());
+ for (int &F : indices) {
+ Variant value = a->track_get_key_value(i, F);
t->object->set_indexed(t->subpath, value);
}
}
@@ -975,12 +979,13 @@ void AnimationTree::_process_graph(float p_delta) {
a->method_track_get_key_indices(i, time, delta, &indices);
- for (List<int>::Element *F = indices.front(); F; F = F->next()) {
- StringName method = a->method_track_get_name(i, F->get());
- Vector<Variant> params = a->method_track_get_params(i, F->get());
+ for (int &F : indices) {
+ StringName method = a->method_track_get_name(i, F);
+ Vector<Variant> params = a->method_track_get_params(i, F);
int s = params.size();
+ static_assert(VARIANT_ARG_MAX == 8, "This code needs to be updated if VARIANT_ARG_MAX != 8");
ERR_CONTINUE(s > VARIANT_ARG_MAX);
if (can_call) {
t->object->call_deferred(
@@ -989,7 +994,10 @@ void AnimationTree::_process_graph(float p_delta) {
s >= 2 ? params[1] : Variant(),
s >= 3 ? params[2] : Variant(),
s >= 4 ? params[3] : Variant(),
- s >= 5 ? params[4] : Variant());
+ s >= 5 ? params[4] : Variant(),
+ s >= 6 ? params[5] : Variant(),
+ s >= 7 ? params[6] : Variant(),
+ s >= 8 ? params[7] : Variant());
}
}
@@ -997,7 +1005,7 @@ void AnimationTree::_process_graph(float p_delta) {
case Animation::TYPE_BEZIER: {
TrackCacheBezier *t = static_cast<TrackCacheBezier *>(track);
- float bezier = a->bezier_track_interpolate(i, time);
+ real_t bezier = a->bezier_track_interpolate(i, time);
if (t->process_pass != process_pass) {
t->value = bezier;
@@ -1023,10 +1031,10 @@ void AnimationTree::_process_graph(float p_delta) {
t->playing = false;
playing_caches.erase(t);
} else {
- float start_ofs = a->audio_track_get_key_start_offset(i, idx);
+ real_t start_ofs = a->audio_track_get_key_start_offset(i, idx);
start_ofs += time - a->track_get_key_time(i, idx);
- float end_ofs = a->audio_track_get_key_end_offset(i, idx);
- float len = stream->get_length();
+ real_t end_ofs = a->audio_track_get_key_end_offset(i, idx);
+ real_t len = stream->get_length();
if (start_ofs > len - end_ofs) {
t->object->call("stop");
@@ -1062,9 +1070,9 @@ void AnimationTree::_process_graph(float p_delta) {
t->playing = false;
playing_caches.erase(t);
} else {
- float start_ofs = a->audio_track_get_key_start_offset(i, idx);
- float end_ofs = a->audio_track_get_key_end_offset(i, idx);
- float len = stream->get_length();
+ real_t start_ofs = a->audio_track_get_key_start_offset(i, idx);
+ real_t end_ofs = a->audio_track_get_key_end_offset(i, idx);
+ real_t len = stream->get_length();
t->object->call("set_stream", stream);
t->object->call("play", start_ofs);
@@ -1087,7 +1095,7 @@ void AnimationTree::_process_graph(float p_delta) {
if (!loop && time < t->start) {
stop = true;
} else if (t->len > 0) {
- float len = t->start > time ? (a->get_length() - t->start) + time : time - t->start;
+ real_t len = t->start > time ? (a->get_length() - t->start) + time : time - t->start;
if (len > t->len) {
stop = true;
@@ -1103,7 +1111,7 @@ void AnimationTree::_process_graph(float p_delta) {
}
}
- float db = Math::linear2db(MAX(blend, 0.00001));
+ real_t db = Math::linear2db(MAX(blend, 0.00001));
if (t->object->has_method("set_unit_db")) {
t->object->call("set_unit_db", db);
} else {
@@ -1126,7 +1134,7 @@ void AnimationTree::_process_graph(float p_delta) {
continue;
}
- float pos = a->track_get_key_time(i, idx);
+ double pos = a->track_get_key_time(i, idx);
StringName anim_name = a->animation_track_get_key_animation(i, idx);
if (String(anim_name) == "[stop]" || !player2->has_animation(anim_name)) {
@@ -1135,10 +1143,10 @@ void AnimationTree::_process_graph(float p_delta) {
Ref<Animation> anim = player2->get_animation(anim_name);
- float at_anim_pos;
+ real_t at_anim_pos;
if (anim->has_loop()) {
- at_anim_pos = Math::fposmod(time - pos, anim->get_length()); //seek to loop
+ at_anim_pos = Math::fposmod(time - pos, (double)anim->get_length()); //seek to loop
} else {
at_anim_pos = MAX(anim->get_length(), time - pos); //seek to end
}
@@ -1232,7 +1240,7 @@ void AnimationTree::_process_graph(float p_delta) {
}
}
-void AnimationTree::advance(float p_time) {
+void AnimationTree::advance(real_t p_time) {
_process_graph(p_time);
}
@@ -1323,7 +1331,7 @@ void AnimationTree::_tree_changed() {
return;
}
- call_deferred("_update_properties");
+ call_deferred(SNAME("_update_properties"));
properties_dirty = true;
}
@@ -1347,9 +1355,7 @@ void AnimationTree::_update_properties_for_node(const String &p_base_path, Ref<A
List<PropertyInfo> plist;
node->get_parameter_list(&plist);
- for (List<PropertyInfo>::Element *E = plist.front(); E; E = E->next()) {
- PropertyInfo pinfo = E->get();
-
+ for (PropertyInfo &pinfo : plist) {
StringName key = pinfo.name;
if (!property_map.has(p_base_path + key)) {
@@ -1365,8 +1371,8 @@ void AnimationTree::_update_properties_for_node(const String &p_base_path, Ref<A
List<AnimationNode::ChildNode> children;
node->get_child_nodes(&children);
- for (List<AnimationNode::ChildNode>::Element *E = children.front(); E; E = E->next()) {
- _update_properties_for_node(p_base_path + E->get().name + "/", E->get().node);
+ for (const AnimationNode::ChildNode &E : children) {
+ _update_properties_for_node(p_base_path + E.name + "/", E.node);
}
}
@@ -1420,17 +1426,17 @@ void AnimationTree::_get_property_list(List<PropertyInfo> *p_list) const {
const_cast<AnimationTree *>(this)->_update_properties();
}
- for (const List<PropertyInfo>::Element *E = properties.front(); E; E = E->next()) {
- p_list->push_back(E->get());
+ for (const PropertyInfo &E : properties) {
+ p_list->push_back(E);
}
}
void AnimationTree::rename_parameter(const String &p_base, const String &p_new_base) {
//rename values first
- for (const List<PropertyInfo>::Element *E = properties.front(); E; E = E->next()) {
- if (E->get().name.begins_with(p_base)) {
- String new_name = E->get().name.replace_first(p_base, p_new_base);
- property_map[new_name] = property_map[E->get().name];
+ for (const PropertyInfo &E : properties) {
+ if (E.name.begins_with(p_base)) {
+ String new_name = E.name.replace_first(p_base, p_new_base);
+ property_map[new_name] = property_map[E.name];
}
}
@@ -1439,7 +1445,7 @@ void AnimationTree::rename_parameter(const String &p_base, const String &p_new_b
_update_properties();
}
-float AnimationTree::get_connection_activity(const StringName &p_path, int p_connection) const {
+real_t AnimationTree::get_connection_activity(const StringName &p_path, int p_connection) const {
if (!input_activity_map_get.has(p_path)) {
return 0;
}