diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp index 4b7abdf2b072..cbb691d1ecc0 100644 --- a/editor/editor_node.cpp +++ b/editor/editor_node.cpp @@ -1913,14 +1913,12 @@ void EditorNode::_save_scene(String p_file, int idx) { return; } - List>> anim_backups; - _reset_animation_mixers(scene, &anim_backups); - scene->propagate_notification(NOTIFICATION_EDITOR_PRE_SAVE); editor_data.apply_changes_in_editors(); save_default_environment(); - + List>> anim_backups; + _reset_animation_mixers(scene, &anim_backups); _save_editor_states(p_file, idx); Ref sdata; diff --git a/scene/3d/retarget_modifier_3d.cpp b/scene/3d/retarget_modifier_3d.cpp index f40af5dfd268..9b070b8d1409 100644 --- a/scene/3d/retarget_modifier_3d.cpp +++ b/scene/3d/retarget_modifier_3d.cpp @@ -465,12 +465,6 @@ void RetargetModifier3D::_notification(int p_what) { case NOTIFICATION_ENTER_TREE: { _update_child_skeletons(); } break; -#ifdef TOOLS_ENABLED - case NOTIFICATION_EDITOR_PRE_SAVE: { - _reset_child_skeleton_poses(); - _force_update_child_skeletons(); - } break; -#endif // TOOLS_ENABLED case NOTIFICATION_EXIT_TREE: { _reset_child_skeletons(); } break; diff --git a/scene/3d/retarget_modifier_3d.h b/scene/3d/retarget_modifier_3d.h index f3c46cffde69..07bc60a21355 100644 --- a/scene/3d/retarget_modifier_3d.h +++ b/scene/3d/retarget_modifier_3d.h @@ -117,6 +117,10 @@ class RetargetModifier3D : public SkeletonModifier3D { void set_profile(Ref p_profile); Ref get_profile() const; +#ifdef TOOLS_ENABLED + virtual bool is_processed_on_saving() const override { return true; } +#endif + RetargetModifier3D(); virtual ~RetargetModifier3D(); }; diff --git a/scene/3d/skeleton_3d.cpp b/scene/3d/skeleton_3d.cpp index bf3022fd6a21..3fd77d4641a7 100644 --- a/scene/3d/skeleton_3d.cpp +++ b/scene/3d/skeleton_3d.cpp @@ -327,8 +327,10 @@ void Skeleton3D::_notification(int p_what) { } break; #ifdef TOOLS_ENABLED case NOTIFICATION_EDITOR_PRE_SAVE: { - force_update_all_dirty_bones(); - emit_signal(SceneStringName(skeleton_updated)); + saving = true; + } break; + case NOTIFICATION_EDITOR_POST_SAVE: { + saving = false; } break; #endif // TOOLS_ENABLED case NOTIFICATION_UPDATE_SKELETON: { @@ -940,6 +942,13 @@ void Skeleton3D::_make_dirty() { void Skeleton3D::_update_deferred(UpdateFlag p_update_flag) { if (is_inside_tree()) { +#ifdef TOOLS_ENABLED + if (saving) { + update_flags |= p_update_flag; + _notification(NOTIFICATION_UPDATE_SKELETON); + return; + } +#endif //TOOLS_ENABLED 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. } @@ -1165,6 +1174,11 @@ void Skeleton3D::_process_modifiers() { if (!mod) { continue; } +#ifdef TOOLS_ENABLED + if (saving && !mod->is_processed_on_saving()) { + continue; + } +#endif //TOOLS_ENABLED real_t influence = mod->get_influence(); if (influence < 1.0) { LocalVector old_poses; diff --git a/scene/3d/skeleton_3d.h b/scene/3d/skeleton_3d.h index 09ed303f33c8..5b91b50cb99e 100644 --- a/scene/3d/skeleton_3d.h +++ b/scene/3d/skeleton_3d.h @@ -66,6 +66,10 @@ class SkinReference : public RefCounted { class Skeleton3D : public Node3D { GDCLASS(Skeleton3D, Node3D); +#ifdef TOOLS_ENABLED + bool saving = false; +#endif //TOOLS_ENABLED + #ifndef DISABLE_DEPRECATED bool animate_physical_bones = true; Node *simulator = nullptr; diff --git a/scene/3d/skeleton_modifier_3d.h b/scene/3d/skeleton_modifier_3d.h index 86e9d9a67aa5..c7106cb06a50 100644 --- a/scene/3d/skeleton_modifier_3d.h +++ b/scene/3d/skeleton_modifier_3d.h @@ -91,6 +91,10 @@ class SkeletonModifier3D : public Node3D { static Vector3 get_vector_from_axis(Vector3::Axis p_axis); static Vector3::Axis get_axis_from_bone_axis(BoneAxis p_axis); +#ifdef TOOLS_ENABLED + virtual bool is_processed_on_saving() const { return false; } +#endif + SkeletonModifier3D(); }; diff --git a/scene/3d/spring_bone_collision_3d.cpp b/scene/3d/spring_bone_collision_3d.cpp index 25ad37fecadd..76ea1a373d39 100644 --- a/scene/3d/spring_bone_collision_3d.cpp +++ b/scene/3d/spring_bone_collision_3d.cpp @@ -180,13 +180,3 @@ Vector3 SpringBoneCollision3D::collide(const Transform3D &p_center, float p_bone Vector3 SpringBoneCollision3D::_collide(const Transform3D &p_center, float p_bone_radius, float p_bone_length, const Vector3 &p_current) const { return Vector3(0, 0, 0); } - -#ifdef TOOLS_ENABLED -void SpringBoneCollision3D::_notification(int p_what) { - switch (p_what) { - case NOTIFICATION_EDITOR_PRE_SAVE: { - sync_pose(); - } break; - } -} -#endif // TOOLS_ENABLED diff --git a/scene/3d/spring_bone_collision_3d.h b/scene/3d/spring_bone_collision_3d.h index 713891e04d51..31676ba5257b 100644 --- a/scene/3d/spring_bone_collision_3d.h +++ b/scene/3d/spring_bone_collision_3d.h @@ -47,9 +47,6 @@ class SpringBoneCollision3D : public Node3D { void _validate_property(PropertyInfo &p_property) const; static void _bind_methods(); -#ifdef TOOLS_ENABLED - virtual void _notification(int p_what); -#endif // TOOLS_ENABLED virtual Vector3 _collide(const Transform3D &p_center, float p_bone_radius, float p_bone_length, const Vector3 &p_current) const; diff --git a/scene/3d/spring_bone_simulator_3d.cpp b/scene/3d/spring_bone_simulator_3d.cpp index dfec87a28c20..6ceacd695a74 100644 --- a/scene/3d/spring_bone_simulator_3d.cpp +++ b/scene/3d/spring_bone_simulator_3d.cpp @@ -397,6 +397,12 @@ void SpringBoneSimulator3D::_notification(int p_what) { case NOTIFICATION_LOCAL_TRANSFORM_CHANGED: { update_gizmos(); } break; + case NOTIFICATION_EDITOR_PRE_SAVE: { + saving = true; + } break; + case NOTIFICATION_EDITOR_POST_SAVE: { + saving = false; + } break; #endif // TOOLS_ENABLED } } @@ -1467,6 +1473,13 @@ void SpringBoneSimulator3D::_process_modification() { } _find_collisions(); _process_collisions(); + +#ifdef TOOLS_ENABLED + if (saving) { + return; // Collision position has been reset but we don't want to process simulating on saving. Abort. + } +#endif //TOOLS_ENABLED + double delta = skeleton->get_modifier_callback_mode_process() == Skeleton3D::MODIFIER_CALLBACK_MODE_PROCESS_IDLE ? skeleton->get_process_delta_time() : skeleton->get_physics_process_delta_time(); for (int i = 0; i < settings.size(); i++) { _init_joints(skeleton, settings[i]); diff --git a/scene/3d/spring_bone_simulator_3d.h b/scene/3d/spring_bone_simulator_3d.h index 5db2e3bfc006..ade2b6405135 100644 --- a/scene/3d/spring_bone_simulator_3d.h +++ b/scene/3d/spring_bone_simulator_3d.h @@ -36,6 +36,10 @@ class SpringBoneSimulator3D : public SkeletonModifier3D { GDCLASS(SpringBoneSimulator3D, SkeletonModifier3D); +#ifdef TOOLS_ENABLED + bool saving = false; +#endif //TOOLS_ENABLED + bool joints_dirty = false; LocalVector collisions; // To process collisions for sync position with skeleton. @@ -274,6 +278,10 @@ class SpringBoneSimulator3D : public SkeletonModifier3D { // To process manually. void reset(); + +#ifdef TOOLS_ENABLED + virtual bool is_processed_on_saving() const override { return true; } +#endif }; VARIANT_ENUM_CAST(SpringBoneSimulator3D::BoneDirection);