FBX fix unskinned bones not being in the Ref<Skin> 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 :)
This commit is contained in:
Gordon MacPherson 2020-11-03 18:21:43 +00:00
parent df6d845b25
commit bcf77deaae
2 changed files with 18 additions and 12 deletions

View file

@ -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()) {

View file

@ -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) {