54 BLI_assert_msg(node !=
nullptr,
"fbx: node for armature creation should not be null");
56 const char *arm_name =
get_fbx_name(node->name,
"Armature");
57 const char *obj_name =
get_fbx_name(node->name,
"Armature");
59 fprintf(g_debug_file,
"create ARMATURE %s\n", arm_name);
68 this->
mapping.el_to_object.add(&node->element,
obj);
69 if (this->
params.use_custom_props) {
75 ufbx_matrix world_to_arm = ufbx_matrix_invert(&node->node_to_world);
76 this->
mapping.armature_world_to_arm_node_matrix.add(
obj, world_to_arm);
79 if (node->bind_pose && node->bind_pose->is_bind_pose) {
80 for (
const ufbx_bone_pose &pose : node->bind_pose->bone_poses) {
81 if (pose.bone_node == node) {
82 world_to_arm = ufbx_matrix_invert(&pose.bone_to_world);
87 this->
mapping.armature_world_to_arm_pose_matrix.add(
obj, world_to_arm);
93 ufbx_matrix world_to_arm = ufbx_matrix_invert(&this->
mapping.global_conv_matrix);
94 this->
mapping.armature_world_to_arm_pose_matrix.add(
obj, world_to_arm);
95 this->
mapping.armature_world_to_arm_node_matrix.add(
obj, world_to_arm);
104 const ufbx_matrix &parent_mtx,
105 const ufbx_matrix &world_to_arm,
106 const float parent_bone_size)
108 BLI_assert(node !=
nullptr && !node->is_root);
113 if (node->is_geometry_transform_helper) {
115 name =
get_fbx_name(node->parent->name,
"Bone") + std::string(
"_GeomAdjust");
122 this->
mapping.node_is_blender_bone.add(node);
123 this->
mapping.bone_to_armature.add(node, arm_obj);
125 bone->
parent = parent_bone;
126 if (node->inherit_mode == UFBX_INHERIT_MODE_IGNORE_PARENT_SCALE) {
129#ifdef FBX_DEBUG_PRINT
130 fprintf(g_debug_file,
131 "create BONE %s (parent %s) parent_mtx:\n",
133 parent_bone ? parent_bone->
name :
"");
134 print_matrix(parent_mtx);
137 ufbx_matrix bone_mtx = this->
mapping.get_node_bind_matrix(node);
138 bone_mtx = ufbx_matrix_mul(&world_to_arm, &bone_mtx);
139 bone_mtx.cols[0] = ufbx_vec3_normalize(bone_mtx.cols[0]);
140 bone_mtx.cols[1] = ufbx_vec3_normalize(bone_mtx.cols[1]);
141 bone_mtx.cols[2] = ufbx_vec3_normalize(bone_mtx.cols[2]);
143#ifdef FBX_DEBUG_PRINT
144 fprintf(g_debug_file,
" bone_mtx:\n");
145 print_matrix(bone_mtx);
149 float bone_size = 0.0f;
150 int child_bone_count = 0;
151 for (
const ufbx_node *fchild : node->children) {
158 ufbx_vec3
pos = fchild->local_transform.translation;
159 if (this->
mapping.bone_to_bind_matrix.contains(fchild)) {
160 ufbx_matrix local_mtx = this->
mapping.calc_local_bind_matrix(fchild, world_to_arm);
161 pos = local_mtx.cols[3];
166 if (child_bone_count > 0) {
167 bone_size /= child_bone_count;
171 bone_size = parent_bone_size;
174 if (!this->
mapping.bone_to_bind_matrix.contains(node)) {
175 ufbx_matrix offset_mtx = ufbx_transform_to_matrix(&node->local_transform);
176 bone_mtx = ufbx_matrix_mul(&parent_mtx, &offset_mtx);
177 bone_mtx.cols[0] = ufbx_vec3_normalize(bone_mtx.cols[0]);
178 bone_mtx.cols[1] = ufbx_vec3_normalize(bone_mtx.cols[1]);
179 bone_mtx.cols[2] = ufbx_vec3_normalize(bone_mtx.cols[2]);
180#ifdef FBX_DEBUG_PRINT
181 fprintf(g_debug_file,
" bone_mtx adj for non-posed bones:\n");
182 print_matrix(bone_mtx);
189 this->
mapping.bone_to_length.add(node, bone_size);
191 bone->
tail[0] = 0.0f;
192 bone->
tail[1] = bone_size;
193 bone->
tail[2] = 0.0f;
195 float bone_matrix[4][4];
199#ifdef FBX_DEBUG_PRINT
200 fprintf(g_debug_file,
201 " length %.3f head (%.3f %.3f %.3f) tail (%.3f %.3f %.3f)\n",
208 adjf(bone->
tail[2]));
213 if (parent_bone !=
nullptr) {
216 const float connect_dist = 1.0e-4f;
217 const float connect_dist_sq = connect_dist * connect_dist;
219 if (dist_sq_rest < connect_dist_sq) {
221 ufbx_vec3 self_head_cur_u = node->node_to_world.cols[3];
224 par_tail.y = parent_bone_size;
226 ufbx_vec3 par_tail_cur_u = ufbx_transform_position(&node->parent->node_to_world, par_tail);
227 float3 self_head_cur(self_head_cur_u.x, self_head_cur_u.y, self_head_cur_u.z);
228 float3 par_tail_cur(par_tail_cur_u.x, par_tail_cur_u.y, par_tail_cur_u.z);
231 if (dist_sq_cur < connect_dist_sq) {
239 for (
const ufbx_node *fchild : node->children) {
244 bool skip_child =
false;
245 if (this->
params.ignore_leaf_bones) {
246 if (node->children.count == 1 && fchild->children.count == 0 &&
247 !
mapping.bone_is_skinned.contains(fchild))
252 this->
mapping.node_is_blender_bone.add(fchild);
326 ufbx_matrix world_to_arm = this->
mapping.armature_world_to_arm_pose_matrix.lookup_default(
327 arm_obj, ufbx_identity_matrix);
335 for (
const ufbx_node *fchild : node->children) {
338 fchild, arm_obj, bone_nodes,
nullptr, ufbx_identity_matrix, world_to_arm, 1.0f);
346 for (
const ufbx_node *fbone : bone_nodes) {
347 if (!this->
mapping.node_is_blender_bone.contains(fbone)) {
351 arm_obj->
pose, this->mapping.node_to_name.lookup_default(fbone,
"").c_str());
352 if (pchan ==
nullptr) {
359 if (this->
mapping.bone_to_bind_matrix.contains(fbone)) {
360 ufbx_matrix bind_local_mtx = this->
mapping.calc_local_bind_matrix(fbone, world_to_arm);
361 ufbx_matrix bind_local_mtx_inv = ufbx_matrix_invert(&bind_local_mtx);
362 ufbx_transform xform = fbone->local_transform;
363 if (fbone->node_depth <= 1) {
364 ufbx_matrix matrix = ufbx_matrix_mul(&world_to_arm, &fbone->node_to_world);
365 xform = ufbx_matrix_to_transform(&matrix);
369 float pchan_matrix[4][4];
373#ifdef FBX_DEBUG_PRINT
374 fprintf(g_debug_file,
"set POSE matrix of %s matrix_basis:\n", fbone->name.data);
375 print_matrix(pose_mtx);
382 for (
const ufbx_node *fchild : node->children) {
383 if (!this->
mapping.node_is_blender_bone.contains(fchild)) {
396 for (
const ufbx_pose *fpose : this->
fbx.poses) {
397 if (!fpose->is_bind_pose) {
400 for (
const ufbx_bone_pose &bone_pose : fpose->bone_poses) {
401 const ufbx_matrix &bind_matrix = bone_pose.bone_to_world;
402 this->
mapping.bone_to_bind_matrix.add_overwrite(bone_pose.bone_node, bind_matrix);
403#ifdef FBX_DEBUG_PRINT
404 fprintf(g_debug_file,
"bone POSE matrix %s\n", bone_pose.bone_node->name.data);
405 print_matrix(bind_matrix);
410 for (
const ufbx_skin_deformer *fskin : this->
fbx.skin_deformers) {
411 for (
const ufbx_skin_cluster *fbone : fskin->clusters) {
412 const ufbx_matrix &bind_matrix = fbone->bind_to_world;
413 this->
mapping.bone_to_bind_matrix.add_overwrite(fbone->bone_node, bind_matrix);
414 this->
mapping.bone_is_skinned.add(fbone->bone_node);
415#ifdef FBX_DEBUG_PRINT
416 fprintf(g_debug_file,
"bone SKIN matrix %s\n", fbone->bone_node->name.data);
417 print_matrix(bind_matrix);
void find_armatures(const ufbx_node *node)
void create_armature_bones(const ufbx_node *node, Object *arm_obj, const Set< const ufbx_node * > &bone_nodes, EditBone *parent_bone, const ufbx_matrix &parent_mtx, const ufbx_matrix &world_to_arm, const float parent_bone_size)
Object * create_armature_for_node(const ufbx_node *node)
ArmatureImportContext(Main &main, const ufbx_scene &fbx, const FBXImportParams ¶ms, FbxElementMapping &mapping)