瀏覽代碼

Reimport bone attachment fixes:
Assign bone_idx to GLTF importer to fix serialization.
Notifies Skeletons and BoneAttachments when reimporting.
Removes usage of NOTIFICATION_NODE_RECACHE_REQUESTED

Saracen 2 年之前
父節點
當前提交
4b671eec0e
共有 5 個文件被更改,包括 48 次插入1 次删除
  1. 24 1
      editor/editor_node.cpp
  2. 2 0
      editor/editor_node.h
  3. 8 0
      modules/gltf/gltf_document.cpp
  4. 10 0
      scene/3d/bone_attachment_3d.cpp
  5. 4 0
      scene/3d/bone_attachment_3d.h

+ 24 - 1
editor/editor_node.cpp

@@ -47,6 +47,7 @@
 #include "core/version.h"
 #include "editor/editor_string_names.h"
 #include "main/main.h"
+#include "scene/3d/bone_attachment_3d.h"
 #include "scene/gui/color_picker.h"
 #include "scene/gui/dialogs.h"
 #include "scene/gui/file_dialog.h"
@@ -6070,6 +6071,27 @@ void EditorNode::_file_access_close_error_notify_impl(const String &p_str) {
 	add_io_error(vformat(TTR("Unable to write to file '%s', file in use, locked or lacking permissions."), p_str));
 }
 
+// Since we felt that a bespoke NOTIFICATION might not be desirable, this function
+// provides the hardcoded callbacks to address known bugs which occur on certain
+// nodes during reimport.
+// Ideally, we should probably agree on a standardized method name which could be
+// called from here instead.
+void EditorNode::_notify_scene_updated(Node *p_node) {
+	Skeleton3D *skel_3d = Object::cast_to<Skeleton3D>(p_node);
+	if (skel_3d) {
+		skel_3d->reset_bone_poses();
+	} else {
+		BoneAttachment3D *attachment = Object::cast_to<BoneAttachment3D>(p_node);
+		if (attachment) {
+			attachment->notify_rebind_required();
+		}
+	}
+
+	for (int i = 0; i < p_node->get_child_count(); i++) {
+		_notify_scene_updated(p_node->get_child(i));
+	}
+}
+
 void EditorNode::reload_scene(const String &p_path) {
 	int scene_idx = -1;
 	for (int i = 0; i < editor_data.get_edited_scene_count(); i++) {
@@ -6453,10 +6475,11 @@ void EditorNode::reload_instances_with_path_in_edited_scenes(const String &p_ins
 					}
 				}
 			}
+
 			// Cleanup the history of the changes.
 			editor_history.cleanup_history();
 
-			current_edited_scene->propagate_notification(NOTIFICATION_NODE_RECACHE_REQUESTED);
+			_notify_scene_updated(current_edited_scene);
 		}
 		edited_scene_map.clear();
 	}

+ 2 - 0
editor/editor_node.h

@@ -692,6 +692,8 @@ private:
 
 	void _begin_first_scan();
 
+	void _notify_scene_updated(Node *p_node);
+
 protected:
 	friend class FileSystemDock;
 

+ 8 - 0
modules/gltf/gltf_document.cpp

@@ -5846,6 +5846,10 @@ void GLTFDocument::_generate_scene_node(Ref<GLTFState> p_state, const GLTFNodeIn
 		BoneAttachment3D *bone_attachment = _generate_bone_attachment(p_state, active_skeleton, p_node_index, gltf_node->parent);
 
 		p_scene_parent->add_child(bone_attachment, true);
+
+		// Find the correct bone_idx so we can properly serialize it.
+		bone_attachment->set_bone_idx(active_skeleton->find_bone(gltf_node->get_name()));
+
 		bone_attachment->set_owner(p_scene_root);
 
 		// There is no gltf_node that represent this, so just directly create a unique name
@@ -5949,6 +5953,10 @@ void GLTFDocument::_generate_skeleton_bone_node(Ref<GLTFState> p_state, const GL
 			BoneAttachment3D *bone_attachment = _generate_bone_attachment(p_state, active_skeleton, p_node_index, p_node_index);
 
 			p_scene_parent->add_child(bone_attachment, true);
+
+			// Find the correct bone_idx so we can properly serialize it.
+			bone_attachment->set_bone_idx(active_skeleton->find_bone(gltf_node->get_name()));
+
 			bone_attachment->set_owner(p_scene_root);
 
 			// There is no gltf_node that represent this, so just directly create a unique name

+ 10 - 0
scene/3d/bone_attachment_3d.cpp

@@ -349,6 +349,16 @@ void BoneAttachment3D::notify_skeleton_bones_renamed(Node *p_base_scene, Skeleto
 		}
 	}
 }
+
+void BoneAttachment3D::notify_rebind_required() {
+	// Ensures bindings are properly updated after a scene reload.
+	_check_unbind();
+	if (use_external_skeleton) {
+		_update_external_skeleton_cache();
+	}
+	bone_idx = -1;
+	_check_bind();
+}
 #endif // TOOLS_ENABLED
 
 BoneAttachment3D::BoneAttachment3D() {

+ 4 - 0
scene/3d/bone_attachment_3d.h

@@ -89,6 +89,10 @@ public:
 
 	virtual void on_bone_pose_update(int p_bone_index);
 
+#ifdef TOOLS_ENABLED
+	virtual void notify_rebind_required();
+#endif
+
 	BoneAttachment3D();
 };