瀏覽代碼

Merge pull request #43294 from RevoluPowered/fbx-bugfix-skinning-unused-deformers-polyfiller

FBX polyfill the skin information for deformers which were optimised out of the FBX
Rémi Verschelde 4 年之前
父節點
當前提交
75afe4ed78
共有 2 個文件被更改,包括 18 次插入12 次删除
  1. 14 1
      modules/fbx/data/fbx_bone.cpp
  2. 4 11
      modules/fbx/editor_scene_importer_fbx.cpp

+ 14 - 1
modules/fbx/data/fbx_bone.cpp

@@ -35,7 +35,12 @@
 
 Ref<FBXNode> FBXBone::get_link(const ImportState &state) const {
 	print_verbose("bone name: " + bone_name);
-	ERR_FAIL_COND_V_MSG(cluster == nullptr, nullptr, "bone has invalid cluster");
+
+	// safe for when deformers must be polyfilled when skin has different count of binds to bones in the scene ;)
+	if (!cluster) {
+		return nullptr;
+	}
+
 	ERR_FAIL_COND_V_MSG(cluster->TargetNode() == nullptr, nullptr, "bone has invalid target node");
 
 	Ref<FBXNode> link_node;
@@ -59,6 +64,14 @@ Ref<FBXNode> FBXBone::get_link(const ImportState &state) const {
 Transform FBXBone::get_vertex_skin_xform(const ImportState &state, Transform mesh_global_position, bool &r_valid_pose) {
 	r_valid_pose = false;
 	print_verbose("get_vertex_skin_xform: " + bone_name);
+
+	// safe to do, this means we have 'remove unused deformer' checked.
+	if (!cluster) {
+		print_verbose("bone [" + itos(bone_id) + "] " + bone_name + ": has no skin offset poly-filling the skin to make rasterizer happy with unused deformers not being skinned");
+		r_valid_pose = true;
+		return Transform();
+	}
+
 	ERR_FAIL_COND_V_MSG(cluster == nullptr, Transform(), "[serious] unable to resolve the fbx cluster for this bone " + bone_name);
 	// these methods will ONLY work for Maya.
 	if (cluster->TransformAssociateModelValid()) {

+ 4 - 11
modules/fbx/editor_scene_importer_fbx.cpp

@@ -694,17 +694,10 @@ Spatial *EditorSceneImporterFBX::_generate_scene(
 			Ref<FBXBone> bone = elem->value();
 			Transform ignore_t;
 			Ref<FBXSkeleton> skeleton = bone->fbx_skeleton;
-
-			if (!bone->cluster) {
-				continue; // some bones have no skin this is OK.
-			}
-
-			Ref<FBXNode> bone_link = bone->get_link(state);
-			ERR_CONTINUE_MSG(bone_link.is_null(), "invalid skin pose bone link");
-
+			// grab the skin bind
 			bool valid_bind = false;
-
 			Transform bind = bone->get_vertex_skin_xform(state, fbx_node->pivot_transform->GlobalTransform, valid_bind);
+
 			ERR_CONTINUE_MSG(!valid_bind, "invalid bind");
 
 			if (bind.basis.determinant() == 0) {
@@ -918,7 +911,7 @@ Spatial *EditorSceneImporterFBX::_generate_scene(
 						// note: do not use C++17 syntax here for dicts.
 						// this is banned in Godot.
 						for (std::pair<const std::string, const FBXDocParser::AnimationCurve *> &kvp : curves) {
-							String curve_element = ImportUtils::FBXNodeToName(kvp.first);
+							const String curve_element = ImportUtils::FBXNodeToName(kvp.first);
 							const FBXDocParser::AnimationCurve *curve = kvp.second;
 							String curve_name = ImportUtils::FBXNodeToName(curve->Name());
 							uint64_t curve_id = curve->ID();
@@ -930,7 +923,7 @@ Spatial *EditorSceneImporterFBX::_generate_scene(
 							}
 
 							// FBX has no name for AnimCurveNode::, most of the time, not seen any with valid name here.
-							const std::map<int64_t, float> track_time = curve->GetValueTimeTrack();
+							const std::map<int64_t, float> &track_time = curve->GetValueTimeTrack();
 
 							if (track_time.size() > 0) {
 								for (std::pair<int64_t, float> keyframe : track_time) {