From bcf77deaaef4be96edf342360b55b328c79a7f6f Mon Sep 17 00:00:00 2001 From: Gordon MacPherson Date: Tue, 3 Nov 2020 18:21:43 +0000 Subject: [PATCH] FBX fix unskinned bones not being in the Ref causing the rasteriser to error This is because a skin bind count must match skeleton bone count, we should make this not the case for 4.0 IMHO as we can reduce the skin size in godot and make the skin surface simpler to process and have less entries :) --- modules/fbx/data/fbx_bone.cpp | 15 ++++++++++++++- modules/fbx/editor_scene_importer_fbx.cpp | 15 ++++----------- 2 files changed, 18 insertions(+), 12 deletions(-) diff --git a/modules/fbx/data/fbx_bone.cpp b/modules/fbx/data/fbx_bone.cpp index 8371983879c..6f3fc520f6f 100644 --- a/modules/fbx/data/fbx_bone.cpp +++ b/modules/fbx/data/fbx_bone.cpp @@ -35,7 +35,12 @@ Ref 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 link_node; @@ -59,6 +64,14 @@ Ref 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()) { diff --git a/modules/fbx/editor_scene_importer_fbx.cpp b/modules/fbx/editor_scene_importer_fbx.cpp index e140c88a28b..9093facc90f 100644 --- a/modules/fbx/editor_scene_importer_fbx.cpp +++ b/modules/fbx/editor_scene_importer_fbx.cpp @@ -694,17 +694,10 @@ Spatial *EditorSceneImporterFBX::_generate_scene( Ref bone = elem->value(); Transform ignore_t; Ref skeleton = bone->fbx_skeleton; - - if (!bone->cluster) { - continue; // some bones have no skin this is OK. - } - - Ref 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 &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 track_time = curve->GetValueTimeTrack(); + const std::map &track_time = curve->GetValueTimeTrack(); if (track_time.size() > 0) { for (std::pair keyframe : track_time) {