diff --git a/scene/3d/skeleton.cpp b/scene/3d/skeleton.cpp index 7dd1027b6..427a5ef4e 100644 --- a/scene/3d/skeleton.cpp +++ b/scene/3d/skeleton.cpp @@ -218,6 +218,8 @@ void Skeleton::_update_process_order() { return; } + ++updating; + Bone *bonesptr = bones.ptrw(); int len = bones.size(); @@ -249,12 +251,15 @@ void Skeleton::_update_process_order() { process_order_dirty = false; + --updating; + emit_signal("bones_updated"); } void Skeleton::_notification(int p_what) { switch (p_what) { case NOTIFICATION_UPDATE_SKELETON: { + ++updating; // Update bone transforms force_update_all_bone_transforms(); @@ -321,6 +326,8 @@ void Skeleton::_notification(int p_what) { } } + --updating; + //TODO Not sure if this is useful or not in runtime //#ifdef TOOLS_ENABLED emit_signal("pose_updated"); @@ -400,7 +407,7 @@ Transform Skeleton::get_bone_global_pose(int p_bone) const { const int bone_size = bones.size(); ERR_FAIL_INDEX_V(p_bone, bone_size, Transform()); - if (dirty) { + if (dirty && updating == 0) { const_cast(this)->notification(NOTIFICATION_UPDATE_SKELETON); } @@ -411,7 +418,7 @@ Transform Skeleton::get_bone_global_pose_no_override(int p_bone) const { const int bone_size = bones.size(); ERR_FAIL_INDEX_V(p_bone, bone_size, Transform()); - if (dirty) { + if (dirty && updating == 0) { const_cast(this)->notification(NOTIFICATION_UPDATE_SKELETON); } @@ -682,7 +689,7 @@ Transform Skeleton::get_bone_global_rest(int p_bone) const { const int bone_size = bones.size(); ERR_FAIL_INDEX_V(p_bone, bone_size, Transform()); - if (rest_dirty) { + if (rest_dirty && updating == 0) { const_cast(this)->notification(NOTIFICATION_UPDATE_SKELETON); } @@ -1069,17 +1076,19 @@ Ref Skeleton::register_skin(const Ref &p_skin) { } void Skeleton::force_update_all_dirty_bones() { - if (dirty) { + if (dirty && updating == 0) { const_cast(this)->notification(NOTIFICATION_UPDATE_SKELETON); } } void Skeleton::force_update_all_bone_transforms() { + ++updating; _update_process_order(); for (int i = 0; i < parentless_bones.size(); i++) { force_update_bone_children_transforms(parentless_bones[i]); } + --updating; } void Skeleton::force_update_bone_children_transforms(int p_bone_idx) { @@ -1357,6 +1366,7 @@ Skeleton::Skeleton() { process_order_dirty = true; show_rest_only = false; rest_dirty = false; + updating = 0; } Skeleton::~Skeleton() { diff --git a/scene/3d/skeleton.h b/scene/3d/skeleton.h index ae59125fa..6407377ab 100644 --- a/scene/3d/skeleton.h +++ b/scene/3d/skeleton.h @@ -151,6 +151,7 @@ private: void _make_dirty(); bool dirty; bool rest_dirty; + int updating; bool show_rest_only;