diff options
Diffstat (limited to 'scene/animation')
-rw-r--r-- | scene/animation/animation_node_state_machine.cpp | 3 | ||||
-rw-r--r-- | scene/animation/animation_node_state_machine.h | 1 | ||||
-rw-r--r-- | scene/animation/animation_player.cpp | 74 | ||||
-rw-r--r-- | scene/animation/animation_tree.cpp | 104 | ||||
-rw-r--r-- | scene/animation/root_motion_view.cpp | 131 | ||||
-rw-r--r-- | scene/animation/root_motion_view.h | 1 |
6 files changed, 152 insertions, 162 deletions
diff --git a/scene/animation/animation_node_state_machine.cpp b/scene/animation/animation_node_state_machine.cpp index a68f7e037d..5ea7f4b7d9 100644 --- a/scene/animation/animation_node_state_machine.cpp +++ b/scene/animation/animation_node_state_machine.cpp @@ -807,9 +807,6 @@ String AnimationNodeStateMachine::get_caption() const { return "StateMachine"; } -void AnimationNodeStateMachine::_notification(int p_what) { -} - Ref<AnimationNode> AnimationNodeStateMachine::get_child_by_name(const StringName &p_name) { return get_node(p_name); } diff --git a/scene/animation/animation_node_state_machine.h b/scene/animation/animation_node_state_machine.h index b980556875..3bae0fcffa 100644 --- a/scene/animation/animation_node_state_machine.h +++ b/scene/animation/animation_node_state_machine.h @@ -164,7 +164,6 @@ private: void _tree_changed(); protected: - void _notification(int p_what); static void _bind_methods(); bool _set(const StringName &p_name, const Variant &p_value); diff --git a/scene/animation/animation_player.cpp b/scene/animation/animation_player.cpp index 4a3fd72080..402418e5a9 100644 --- a/scene/animation/animation_player.cpp +++ b/scene/animation/animation_player.cpp @@ -202,15 +202,16 @@ void AnimationPlayer::_notification(int p_what) { set_physics_process_internal(false); set_process_internal(false); } - //_set_process(false); clear_caches(); } break; + case NOTIFICATION_READY: { if (!Engine::get_singleton()->is_editor_hint() && animation_set.has(autoplay)) { play(autoplay); _animation_process(0); } } break; + case NOTIFICATION_INTERNAL_PROCESS: { if (process_callback == ANIMATION_PROCESS_PHYSICS) { break; @@ -220,6 +221,7 @@ void AnimationPlayer::_notification(int p_what) { _animation_process(get_process_delta_time()); } } break; + case NOTIFICATION_INTERNAL_PHYSICS_PROCESS: { if (process_callback == ANIMATION_PROCESS_IDLE) { break; @@ -229,6 +231,7 @@ void AnimationPlayer::_notification(int p_what) { _animation_process(get_physics_process_delta_time()); } } break; + case NOTIFICATION_EXIT_TREE: { clear_caches(); } break; @@ -398,6 +401,22 @@ void AnimationPlayer::_ensure_node_caches(AnimationData *p_anim, Node *p_root_ov } } +static void _call_object(Object *p_object, const StringName &p_method, const Vector<Variant> &p_params, bool p_deferred) { + // Separate function to use alloca() more efficiently + const Variant **argptrs = (const Variant **)alloca(sizeof(const Variant **) * p_params.size()); + const Variant *args = p_params.ptr(); + uint32_t argcount = p_params.size(); + for (uint32_t i = 0; i < argcount; i++) { + argptrs[i] = &args[i]; + } + if (p_deferred) { + MessageQueue::get_singleton()->push_callp(p_object, p_method, argptrs, argcount); + } else { + Callable::CallError ce; + p_object->callp(p_method, argptrs, argcount, ce); + } +} + void AnimationPlayer::_animation_process_animation(AnimationData *p_anim, double p_time, double p_delta, float p_interp, bool p_is_current, bool p_seeked, bool p_started, int p_pingponged) { _ensure_node_caches(p_anim); ERR_FAIL_COND(p_anim->node_cache.size() != p_anim->animation->get_track_count()); @@ -592,18 +611,12 @@ void AnimationPlayer::_animation_process_animation(AnimationData *p_anim, double } if (update_mode == Animation::UPDATE_CONTINUOUS || update_mode == Animation::UPDATE_CAPTURE || (p_delta == 0 && update_mode == Animation::UPDATE_DISCRETE)) { //delta == 0 means seek - Variant value = a->value_track_interpolate(i, p_time); if (value == Variant()) { continue; } - //thanks to trigger mode, this should be solved now.. - /* - if (p_delta==0 && value.get_type()==Variant::STRING) - continue; // doing this with strings is messy, should find another way - */ if (pa->accum_pass != accum_pass) { ERR_CONTINUE(cache_update_prop_size >= NODE_CACHE_UPDATE_MAX); cache_update_prop[cache_update_prop_size++] = pa; @@ -680,41 +693,14 @@ void AnimationPlayer::_animation_process_animation(AnimationData *p_anim, double StringName method = a->method_track_get_name(i, E); Vector<Variant> params = a->method_track_get_params(i, E); - int s = params.size(); - - ERR_CONTINUE(s > VARIANT_ARG_MAX); #ifdef DEBUG_ENABLED if (!nc->node->has_method(method)) { ERR_PRINT("Invalid method call '" + method + "'. '" + a->get_name() + "' at node '" + get_path() + "'."); } #endif - static_assert(VARIANT_ARG_MAX == 8, "This code needs to be updated if VARIANT_ARG_MAX != 8"); if (can_call) { - if (method_call_mode == ANIMATION_METHOD_CALL_DEFERRED) { - MessageQueue::get_singleton()->push_call( - nc->node, - method, - s >= 1 ? params[0] : Variant(), - s >= 2 ? params[1] : Variant(), - s >= 3 ? params[2] : Variant(), - s >= 4 ? params[3] : Variant(), - s >= 5 ? params[4] : Variant(), - s >= 6 ? params[5] : Variant(), - s >= 7 ? params[6] : Variant(), - s >= 8 ? params[7] : Variant()); - } else { - nc->node->call( - method, - s >= 1 ? params[0] : Variant(), - s >= 2 ? params[1] : Variant(), - s >= 3 ? params[2] : Variant(), - s >= 4 ? params[3] : Variant(), - s >= 5 ? params[4] : Variant(), - s >= 6 ? params[5] : Variant(), - s >= 7 ? params[6] : Variant(), - s >= 8 ? params[7] : Variant()); - } + _call_object(nc->node, method, params, method_call_mode == ANIMATION_METHOD_CALL_DEFERRED); } } @@ -757,7 +743,7 @@ void AnimationPlayer::_animation_process_animation(AnimationData *p_anim, double Ref<AudioStream> stream = a->audio_track_get_key_stream(i, idx); if (!stream.is_valid()) { - nc->node->call("stop"); + nc->node->call(SNAME("stop")); nc->audio_playing = false; playing_caches.erase(nc); } else { @@ -767,14 +753,14 @@ void AnimationPlayer::_animation_process_animation(AnimationData *p_anim, double float len = stream->get_length(); if (start_ofs > len - end_ofs) { - nc->node->call("stop"); + nc->node->call(SNAME("stop")); nc->audio_playing = false; playing_caches.erase(nc); continue; } - nc->node->call("set_stream", stream); - nc->node->call("play", start_ofs); + nc->node->call(SNAME("set_stream"), stream); + nc->node->call(SNAME("play"), start_ofs); nc->audio_playing = true; playing_caches.insert(nc); @@ -796,7 +782,7 @@ void AnimationPlayer::_animation_process_animation(AnimationData *p_anim, double Ref<AudioStream> stream = a->audio_track_get_key_stream(i, idx); if (!stream.is_valid()) { - nc->node->call("stop"); + nc->node->call(SNAME("stop")); nc->audio_playing = false; playing_caches.erase(nc); } else { @@ -804,8 +790,8 @@ void AnimationPlayer::_animation_process_animation(AnimationData *p_anim, double float end_ofs = a->audio_track_get_key_end_offset(i, idx); float len = stream->get_length(); - nc->node->call("set_stream", stream); - nc->node->call("play", start_ofs); + nc->node->call(SNAME("set_stream"), stream); + nc->node->call(SNAME("play"), start_ofs); nc->audio_playing = true; playing_caches.insert(nc); @@ -836,7 +822,7 @@ void AnimationPlayer::_animation_process_animation(AnimationData *p_anim, double if (stop) { //time to stop - nc->node->call("stop"); + nc->node->call(SNAME("stop")); nc->audio_playing = false; playing_caches.erase(nc); } @@ -1547,7 +1533,7 @@ void AnimationPlayer::_animation_changed() { void AnimationPlayer::_stop_playing_caches() { for (Set<TrackNodeCache *>::Element *E = playing_caches.front(); E; E = E->next()) { if (E->get()->node && E->get()->audio_playing) { - E->get()->node->call("stop"); + E->get()->node->call(SNAME("stop")); } if (E->get()->node && E->get()->animation_playing) { AnimationPlayer *player = Object::cast_to<AnimationPlayer>(E->get()->node); diff --git a/scene/animation/animation_tree.cpp b/scene/animation/animation_tree.cpp index f2f69fc439..e0e94d8632 100644 --- a/scene/animation/animation_tree.cpp +++ b/scene/animation/animation_tree.cpp @@ -490,7 +490,7 @@ void AnimationTree::set_active(bool p_active) { if (!active && is_inside_tree()) { for (Set<TrackCache *>::Element *E = playing_caches.front(); E; E = E->next()) { if (ObjectDB::get_instance(E->get()->object_id)) { - E->get()->object->call("stop"); + E->get()->object->call(SNAME("stop")); } } @@ -796,6 +796,21 @@ void AnimationTree::_clear_caches() { cache_valid = false; } +static void _call_object(Object *p_object, const StringName &p_method, const Vector<Variant> &p_params, bool p_deferred) { + // Separate function to use alloca() more efficiently + const Variant **argptrs = (const Variant **)alloca(sizeof(const Variant **) * p_params.size()); + const Variant *args = p_params.ptr(); + uint32_t argcount = p_params.size(); + for (uint32_t i = 0; i < argcount; i++) { + argptrs[i] = &args[i]; + } + if (p_deferred) { + MessageQueue::get_singleton()->push_callp(p_object, p_method, argptrs, argcount); + } else { + Callable::CallError ce; + p_object->callp(p_method, argptrs, argcount, ce); + } +} void AnimationTree::_process_graph(double p_delta) { _update_properties(); //if properties need updating, update them @@ -1286,25 +1301,10 @@ void AnimationTree::_process_graph(double p_delta) { 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( - method, - s >= 1 ? params[0] : Variant(), - s >= 2 ? params[1] : Variant(), - s >= 3 ? params[2] : Variant(), - s >= 4 ? params[3] : Variant(), - s >= 5 ? params[4] : Variant(), - s >= 6 ? params[5] : Variant(), - s >= 7 ? params[6] : Variant(), - s >= 8 ? params[7] : Variant()); + _call_object(t->object, method, params, true); } } - } break; case Animation::TYPE_BEZIER: { TrackCacheBezier *t = static_cast<TrackCacheBezier *>(track); @@ -1331,7 +1331,7 @@ void AnimationTree::_process_graph(double p_delta) { Ref<AudioStream> stream = a->audio_track_get_key_stream(i, idx); if (!stream.is_valid()) { - t->object->call("stop"); + t->object->call(SNAME("stop")); t->playing = false; playing_caches.erase(t); } else { @@ -1341,14 +1341,14 @@ void AnimationTree::_process_graph(double p_delta) { double len = stream->get_length(); if (start_ofs > len - end_ofs) { - t->object->call("stop"); + t->object->call(SNAME("stop")); t->playing = false; playing_caches.erase(t); continue; } - t->object->call("set_stream", stream); - t->object->call("play", start_ofs); + t->object->call(SNAME("set_stream"), stream); + t->object->call(SNAME("play"), start_ofs); t->playing = true; playing_caches.insert(t); @@ -1370,7 +1370,7 @@ void AnimationTree::_process_graph(double p_delta) { Ref<AudioStream> stream = a->audio_track_get_key_stream(i, idx); if (!stream.is_valid()) { - t->object->call("stop"); + t->object->call(SNAME("stop")); t->playing = false; playing_caches.erase(t); } else { @@ -1378,8 +1378,8 @@ void AnimationTree::_process_graph(double p_delta) { double end_ofs = a->audio_track_get_key_end_offset(i, idx); double len = stream->get_length(); - t->object->call("set_stream", stream); - t->object->call("play", start_ofs); + t->object->call(SNAME("set_stream"), stream); + t->object->call(SNAME("play"), start_ofs); t->playing = true; playing_caches.insert(t); @@ -1416,7 +1416,7 @@ void AnimationTree::_process_graph(double p_delta) { if (stop) { //time to stop - t->object->call("stop"); + t->object->call(SNAME("stop")); t->playing = false; playing_caches.erase(t); } @@ -1424,10 +1424,10 @@ void AnimationTree::_process_graph(double p_delta) { } real_t db = Math::linear2db(MAX(blend, 0.00001)); - if (t->object->has_method("set_unit_db")) { - t->object->call("set_unit_db", db); + if (t->object->has_method(SNAME("set_unit_db"))) { + t->object->call(SNAME("set_unit_db"), db); } else { - t->object->call("set_volume_db", db); + t->object->call(SNAME("set_volume_db"), db); } } break; case Animation::TYPE_ANIMATION: { @@ -1586,29 +1586,37 @@ void AnimationTree::advance(real_t p_time) { } void AnimationTree::_notification(int p_what) { - if (active && p_what == NOTIFICATION_INTERNAL_PHYSICS_PROCESS && process_callback == ANIMATION_PROCESS_PHYSICS) { - _process_graph(get_physics_process_delta_time()); - } - - if (active && p_what == NOTIFICATION_INTERNAL_PROCESS && process_callback == ANIMATION_PROCESS_IDLE) { - _process_graph(get_process_delta_time()); - } + switch (p_what) { + case NOTIFICATION_ENTER_TREE: { + if (last_animation_player.is_valid()) { + Object *player = ObjectDB::get_instance(last_animation_player); + if (player) { + player->connect("caches_cleared", callable_mp(this, &AnimationTree::_clear_caches)); + } + } + } break; + + case NOTIFICATION_EXIT_TREE: { + _clear_caches(); + if (last_animation_player.is_valid()) { + Object *player = ObjectDB::get_instance(last_animation_player); + if (player) { + player->disconnect("caches_cleared", callable_mp(this, &AnimationTree::_clear_caches)); + } + } + } break; - if (p_what == NOTIFICATION_EXIT_TREE) { - _clear_caches(); - if (last_animation_player.is_valid()) { - Object *player = ObjectDB::get_instance(last_animation_player); - if (player) { - player->disconnect("caches_cleared", callable_mp(this, &AnimationTree::_clear_caches)); + case NOTIFICATION_INTERNAL_PROCESS: { + if (active && process_callback == ANIMATION_PROCESS_IDLE) { + _process_graph(get_process_delta_time()); } - } - } else if (p_what == NOTIFICATION_ENTER_TREE) { - if (last_animation_player.is_valid()) { - Object *player = ObjectDB::get_instance(last_animation_player); - if (player) { - player->connect("caches_cleared", callable_mp(this, &AnimationTree::_clear_caches)); + } break; + + case NOTIFICATION_INTERNAL_PHYSICS_PROCESS: { + if (active && process_callback == ANIMATION_PROCESS_PHYSICS) { + _process_graph(get_physics_process_delta_time()); } - } + } break; } } diff --git a/scene/animation/root_motion_view.cpp b/scene/animation/root_motion_view.cpp index 0d44687588..42adc1ea02 100644 --- a/scene/animation/root_motion_view.cpp +++ b/scene/animation/root_motion_view.cpp @@ -29,8 +29,10 @@ /*************************************************************************/ #include "root_motion_view.h" + #include "scene/animation/animation_tree.h" #include "scene/resources/material.h" + void RootMotionView::set_animation_path(const NodePath &p_path) { path = p_path; first = true; @@ -76,84 +78,87 @@ bool RootMotionView::get_zero_y() const { } void RootMotionView::_notification(int p_what) { - if (p_what == NOTIFICATION_ENTER_TREE) { - immediate_material = StandardMaterial3D::get_material_for_2d(false, true, false, false, false); - first = true; - } - - if (p_what == NOTIFICATION_INTERNAL_PROCESS || p_what == NOTIFICATION_INTERNAL_PHYSICS_PROCESS) { - Transform3D transform; - - if (has_node(path)) { - Node *node = get_node(path); - - AnimationTree *tree = Object::cast_to<AnimationTree>(node); - if (tree && tree->is_active() && tree->get_root_motion_track() != NodePath()) { - if (is_processing_internal() && tree->get_process_callback() == AnimationTree::ANIMATION_PROCESS_PHYSICS) { - set_process_internal(false); - set_physics_process_internal(true); - } - - if (is_physics_processing_internal() && tree->get_process_callback() == AnimationTree::ANIMATION_PROCESS_IDLE) { - set_process_internal(true); - set_physics_process_internal(false); + switch (p_what) { + case NOTIFICATION_ENTER_TREE: { + immediate_material = StandardMaterial3D::get_material_for_2d(false, true, false, false, false); + first = true; + } break; + + case NOTIFICATION_INTERNAL_PROCESS: + case NOTIFICATION_INTERNAL_PHYSICS_PROCESS: { + Transform3D transform; + + if (has_node(path)) { + Node *node = get_node(path); + + AnimationTree *tree = Object::cast_to<AnimationTree>(node); + if (tree && tree->is_active() && tree->get_root_motion_track() != NodePath()) { + if (is_processing_internal() && tree->get_process_callback() == AnimationTree::ANIMATION_PROCESS_PHYSICS) { + set_process_internal(false); + set_physics_process_internal(true); + } + + if (is_physics_processing_internal() && tree->get_process_callback() == AnimationTree::ANIMATION_PROCESS_IDLE) { + set_process_internal(true); + set_physics_process_internal(false); + } + + transform = tree->get_root_motion_transform(); } - - transform = tree->get_root_motion_transform(); } - } - if (!first && transform == Transform3D()) { - return; - } + if (!first && transform == Transform3D()) { + return; + } - first = false; + first = false; - transform.orthonormalize(); //don't want scale, too imprecise - transform.affine_invert(); + transform.orthonormalize(); //don't want scale, too imprecise + transform.affine_invert(); - accumulated = transform * accumulated; - accumulated.origin.x = Math::fposmod(accumulated.origin.x, cell_size); - if (zero_y) { - accumulated.origin.y = 0; - } - accumulated.origin.z = Math::fposmod(accumulated.origin.z, cell_size); + accumulated = transform * accumulated; + accumulated.origin.x = Math::fposmod(accumulated.origin.x, cell_size); + if (zero_y) { + accumulated.origin.y = 0; + } + accumulated.origin.z = Math::fposmod(accumulated.origin.z, cell_size); - immediate->clear_surfaces(); + immediate->clear_surfaces(); - int cells_in_radius = int((radius / cell_size) + 1.0); + int cells_in_radius = int((radius / cell_size) + 1.0); - immediate->surface_begin(Mesh::PRIMITIVE_LINES, immediate_material); + immediate->surface_begin(Mesh::PRIMITIVE_LINES, immediate_material); - for (int i = -cells_in_radius; i < cells_in_radius; i++) { - for (int j = -cells_in_radius; j < cells_in_radius; j++) { - Vector3 from(i * cell_size, 0, j * cell_size); - Vector3 from_i((i + 1) * cell_size, 0, j * cell_size); - Vector3 from_j(i * cell_size, 0, (j + 1) * cell_size); - from = accumulated.xform(from); - from_i = accumulated.xform(from_i); - from_j = accumulated.xform(from_j); + for (int i = -cells_in_radius; i < cells_in_radius; i++) { + for (int j = -cells_in_radius; j < cells_in_radius; j++) { + Vector3 from(i * cell_size, 0, j * cell_size); + Vector3 from_i((i + 1) * cell_size, 0, j * cell_size); + Vector3 from_j(i * cell_size, 0, (j + 1) * cell_size); + from = accumulated.xform(from); + from_i = accumulated.xform(from_i); + from_j = accumulated.xform(from_j); - Color c = color, c_i = color, c_j = color; - c.a *= MAX(0, 1.0 - from.length() / radius); - c_i.a *= MAX(0, 1.0 - from_i.length() / radius); - c_j.a *= MAX(0, 1.0 - from_j.length() / radius); + Color c = color, c_i = color, c_j = color; + c.a *= MAX(0, 1.0 - from.length() / radius); + c_i.a *= MAX(0, 1.0 - from_i.length() / radius); + c_j.a *= MAX(0, 1.0 - from_j.length() / radius); - immediate->surface_set_color(c); - immediate->surface_add_vertex(from); + immediate->surface_set_color(c); + immediate->surface_add_vertex(from); - immediate->surface_set_color(c_i); - immediate->surface_add_vertex(from_i); + immediate->surface_set_color(c_i); + immediate->surface_add_vertex(from_i); - immediate->surface_set_color(c); - immediate->surface_add_vertex(from); + immediate->surface_set_color(c); + immediate->surface_add_vertex(from); - immediate->surface_set_color(c_j); - immediate->surface_add_vertex(from_j); + immediate->surface_set_color(c_j); + immediate->surface_add_vertex(from_j); + } } - } - immediate->surface_end(); + immediate->surface_end(); + } break; } } @@ -161,10 +166,6 @@ AABB RootMotionView::get_aabb() const { return AABB(Vector3(-radius, 0, -radius), Vector3(radius * 2, 0.001, radius * 2)); } -Vector<Face3> RootMotionView::get_faces(uint32_t p_usage_flags) const { - return Vector<Face3>(); -} - void RootMotionView::_bind_methods() { ClassDB::bind_method(D_METHOD("set_animation_path", "path"), &RootMotionView::set_animation_path); ClassDB::bind_method(D_METHOD("get_animation_path"), &RootMotionView::get_animation_path); diff --git a/scene/animation/root_motion_view.h b/scene/animation/root_motion_view.h index e8b141c1fd..8cb8ea8a9a 100644 --- a/scene/animation/root_motion_view.h +++ b/scene/animation/root_motion_view.h @@ -71,7 +71,6 @@ public: bool get_zero_y() const; virtual AABB get_aabb() const override; - virtual Vector<Face3> get_faces(uint32_t p_usage_flags) const override; RootMotionView(); ~RootMotionView(); |