Fix: some cases of bone scale were not handled correctly in new FBX importer
- Was not consistently adjusting for bone adjust_post_scale - Map fbx node "igore parent scale" to Blender bone "inherit scale: none" Pull Request: https://projects.blender.org/blender/blender/pulls/138204
This commit is contained in:
committed by
Aras Pranckevicius
parent
8409a5081b
commit
9315af2170
@@ -289,7 +289,6 @@ void importer_main(Main *bmain, Scene *scene, ViewLayer *view_layer, const FBXIm
|
||||
* cause armatures/skins to not import correctly, when inserted in the middle of bone chain. */
|
||||
opts.geometry_transform_handling = UFBX_GEOMETRY_TRANSFORM_HANDLING_MODIFY_GEOMETRY_NO_FALLBACK;
|
||||
|
||||
//@TODO: axes according to import settings
|
||||
opts.space_conversion = UFBX_SPACE_CONVERSION_ADJUST_TRANSFORMS;
|
||||
opts.target_axes.right = UFBX_COORDINATE_AXIS_POSITIVE_X;
|
||||
opts.target_axes.up = UFBX_COORDINATE_AXIS_POSITIVE_Z;
|
||||
|
||||
@@ -314,20 +314,8 @@ static void create_transform_curves(const FbxElementMapping &mapping,
|
||||
ufbx_transform xform = ufbx_evaluate_transform(fbx_anim, fnode, t);
|
||||
|
||||
if (is_bone) {
|
||||
/* For bones that have "ignore parent scale" on them, ufbx helpfully applies global scale to
|
||||
* the evaluated transform. However we really need to get local transform without global
|
||||
* scale, so undo that. */
|
||||
if (fnode->adjust_post_scale != 1.0) {
|
||||
xform.scale.x /= fnode->adjust_post_scale;
|
||||
xform.scale.y /= fnode->adjust_post_scale;
|
||||
xform.scale.z /= fnode->adjust_post_scale;
|
||||
}
|
||||
|
||||
/* Bone transform curves need to be transformed to the bind transform
|
||||
* in joint-local space. */
|
||||
ufbx_matrix xform_mtx = ufbx_transform_to_matrix(&xform);
|
||||
xform_mtx = ufbx_matrix_mul(&bone_xform, &xform_mtx);
|
||||
xform = ufbx_matrix_to_transform(&xform_mtx);
|
||||
ufbx_matrix matrix = calc_bone_pose_matrix(xform, *fnode, bone_xform);
|
||||
xform = ufbx_matrix_to_transform(&matrix);
|
||||
}
|
||||
|
||||
set_curve_sample(curves_pos[0], i, tf, float(xform.translation.x));
|
||||
|
||||
@@ -101,6 +101,9 @@ void ArmatureImportContext::create_armature_bones(const ufbx_node *node,
|
||||
this->mapping.el_to_object.add(&node->element, arm_obj);
|
||||
bone->flag |= BONE_SELECTED;
|
||||
bone->parent = parent_bone;
|
||||
if (node->inherit_mode == UFBX_INHERIT_MODE_IGNORE_PARENT_SCALE) {
|
||||
bone->inherit_scale_mode = BONE_INHERIT_SCALE_NONE;
|
||||
}
|
||||
|
||||
this->mapping.bone_to_armature.add(node, arm_obj);
|
||||
|
||||
@@ -304,11 +307,12 @@ void ArmatureImportContext::find_armatures(const ufbx_node *node)
|
||||
fbone, world_to_arm, found);
|
||||
if (found) {
|
||||
ufbx_matrix bind_local_mtx_inv = ufbx_matrix_invert(&bind_local_mtx);
|
||||
ufbx_matrix local_mtx = fbone->node_to_parent;
|
||||
ufbx_transform xform = fbone->local_transform;
|
||||
if (fbone->node_depth <= 1) {
|
||||
local_mtx = ufbx_matrix_mul(&world_to_arm, &fbone->node_to_world);
|
||||
ufbx_matrix matrix = ufbx_matrix_mul(&world_to_arm, &fbone->node_to_world);
|
||||
xform = ufbx_matrix_to_transform(&matrix);
|
||||
}
|
||||
ufbx_matrix pose_mtx = ufbx_matrix_mul(&bind_local_mtx_inv, &local_mtx);
|
||||
ufbx_matrix pose_mtx = calc_bone_pose_matrix(xform, *fbone, bind_local_mtx_inv);
|
||||
|
||||
float pchan_matrix[4][4];
|
||||
matrix_to_m44(pose_mtx, pchan_matrix);
|
||||
|
||||
@@ -59,6 +59,27 @@ void m44_to_matrix(const float src[4][4], ufbx_matrix &dst)
|
||||
dst.m23 = src[3][2];
|
||||
}
|
||||
|
||||
ufbx_matrix calc_bone_pose_matrix(const ufbx_transform &local_xform,
|
||||
const ufbx_node &node,
|
||||
const ufbx_matrix &local_bind_inv_matrix)
|
||||
{
|
||||
ufbx_transform xform = local_xform;
|
||||
|
||||
/* For bones that have "ignore parent scale" on them, ufbx helpfully applies global scale to
|
||||
* the evaluated transform. However we really need to get local transform without global
|
||||
* scale, so undo that. */
|
||||
if (node.adjust_post_scale != 1.0) {
|
||||
xform.scale.x /= node.adjust_post_scale;
|
||||
xform.scale.y /= node.adjust_post_scale;
|
||||
xform.scale.z /= node.adjust_post_scale;
|
||||
}
|
||||
|
||||
/* Transformed to the bind transform in joint-local space. */
|
||||
ufbx_matrix matrix = ufbx_transform_to_matrix(&xform);
|
||||
matrix = ufbx_matrix_mul(&local_bind_inv_matrix, &matrix);
|
||||
return matrix;
|
||||
}
|
||||
|
||||
void ufbx_matrix_to_obj(const ufbx_matrix &mtx, Object *obj)
|
||||
{
|
||||
#ifdef FBX_DEBUG_PRINT
|
||||
|
||||
@@ -78,6 +78,10 @@ void node_matrix_to_obj(const ufbx_node *node, Object *obj, const FbxElementMapp
|
||||
void read_custom_properties(const ufbx_props &props, ID &id, bool enums_as_strings);
|
||||
void read_custom_properties(const ufbx_props &props, bPoseChannel &pchan, bool enums_as_strings);
|
||||
|
||||
ufbx_matrix calc_bone_pose_matrix(const ufbx_transform &local_xform,
|
||||
const ufbx_node &node,
|
||||
const ufbx_matrix &local_bind_inv_matrix);
|
||||
|
||||
//@TODO remove debug file print once things are working properly
|
||||
// #define FBX_DEBUG_PRINT
|
||||
|
||||
|
||||
Submodule tests/data updated: 37032655eb...06951a813c
Reference in New Issue
Block a user