From 5774d574967d81830e8eba22ea6fe70a00761634 Mon Sep 17 00:00:00 2001 From: "Silc Lizard (Tokage) Renew" <61938263+TokageItLab@users.noreply.github.com> Date: Sun, 23 Jun 2024 15:15:43 +0900 Subject: [PATCH] Optimize update flag by SkeletonModifier --- scene/3d/skeleton_3d.cpp | 24 +++++++++++++++++------- scene/3d/skeleton_3d.h | 10 ++++++++-- 2 files changed, 25 insertions(+), 9 deletions(-) diff --git a/scene/3d/skeleton_3d.cpp b/scene/3d/skeleton_3d.cpp index 21e82adf47a8..7c9fbd3b6dee 100644 --- a/scene/3d/skeleton_3d.cpp +++ b/scene/3d/skeleton_3d.cpp @@ -308,6 +308,7 @@ void Skeleton3D::_notification(int p_what) { switch (p_what) { case NOTIFICATION_ENTER_TREE: { _process_changed(); + _make_dirty(); _make_modifiers_dirty(); force_update_all_dirty_bones(); #ifndef DISABLE_DEPRECATED @@ -333,6 +334,13 @@ void Skeleton3D::_notification(int p_what) { _process_modifiers(); } + // Abort if pose is not changed. + if (!(update_flags & UPDATE_FLAG_POSE)) { + updating = false; + update_flags = UPDATE_FLAG_NONE; + return; + } + emit_signal(SceneStringName(skeleton_updated)); // Update skins. @@ -400,13 +408,13 @@ void Skeleton3D::_notification(int p_what) { } updating = false; - is_update_needed = false; + update_flags = UPDATE_FLAG_NONE; } break; case NOTIFICATION_INTERNAL_PROCESS: case NOTIFICATION_INTERNAL_PHYSICS_PROCESS: { _find_modifiers(); if (!modifiers.is_empty()) { - _update_deferred(); + _update_deferred(UPDATE_FLAG_MODIFIER); } } break; } @@ -436,7 +444,7 @@ void Skeleton3D::_process_changed() { void Skeleton3D::_make_modifiers_dirty() { modifiers_dirty = true; - _update_deferred(); + _update_deferred(UPDATE_FLAG_MODIFIER); } Transform3D Skeleton3D::get_bone_global_pose(int p_bone) const { @@ -745,10 +753,12 @@ void Skeleton3D::_make_dirty() { _update_deferred(); } -void Skeleton3D::_update_deferred() { - if (!is_update_needed && !updating && is_inside_tree()) { - is_update_needed = true; - notify_deferred_thread_group(NOTIFICATION_UPDATE_SKELETON); // It must never be called more than once in a single frame. +void Skeleton3D::_update_deferred(UpdateFlag p_update_flag) { + if (is_inside_tree()) { + if (update_flags == UPDATE_FLAG_NONE && !updating) { + notify_deferred_thread_group(NOTIFICATION_UPDATE_SKELETON); // It must never be called more than once in a single frame. + } + update_flags |= p_update_flag; } } diff --git a/scene/3d/skeleton_3d.h b/scene/3d/skeleton_3d.h index b8e38242b9d2..eef7c9318d77 100644 --- a/scene/3d/skeleton_3d.h +++ b/scene/3d/skeleton_3d.h @@ -80,8 +80,14 @@ class Skeleton3D : public Node3D { private: friend class SkinReference; - void _update_deferred(); - bool is_update_needed = false; // Is updating reserved? + enum UpdateFlag { + UPDATE_FLAG_NONE = 1, + UPDATE_FLAG_MODIFIER = 2, + UPDATE_FLAG_POSE = 4, + }; + + void _update_deferred(UpdateFlag p_update_flag = UPDATE_FLAG_POSE); + uint8_t update_flags = UPDATE_FLAG_NONE; bool updating = false; // Is updating now? struct Bone {