28 const ufbx_scene &
fbx;
33 const ufbx_scene &
fbx,
45 const ufbx_matrix &parent_mtx,
46 const ufbx_matrix &world_to_arm,
47 const float parent_bone_size);
59 fprintf(g_debug_file,
"create ARMATURE %s\n", arm_name);
75 ufbx_matrix world_to_arm = ufbx_matrix_invert(&
node->node_to_world);
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);
104 const ufbx_matrix &parent_mtx,
105 const ufbx_matrix &world_to_arm,
106 const float parent_bone_size)
113 if (
node->is_geometry_transform_helper) {
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);
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;
161 pos = local_mtx.cols[3];
166 if (child_bone_count > 0) {
167 bone_size /= child_bone_count;
171 bone_size = parent_bone_size;
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);
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;
246 if (node->children.count == 1 && fchild->children.count == 0 &&
265 if (
node->bone &&
node->bone->is_root) {
268 for (
const ufbx_node *fchild :
node->children) {
269 if (fchild->bone && !fchild->bone->is_root) {
278 if (
node->bone !=
nullptr) {
281 for (
const ufbx_node *child :
node->children) {
290 for (
const ufbx_node *bone_node : bones) {
291 const ufbx_node *
node = bone_node->parent;
292 while (!
ELEM(
node,
nullptr, root_node)) {
293 if (
node->bone ==
nullptr) {
314 for (
const ufbx_node *
b : fake_bones) {
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) {
351 arm_obj->
pose,
this->mapping.node_to_name.lookup_default(fbone,
"").c_str());
352 if (pchan ==
nullptr) {
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) {
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;
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;
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);
424 const ufbx_scene &fbx,
429 context.calc_bone_bind_matrices();
430 context.find_armatures(fbx.root_node);
Blender kernel action and pose functionality.
bPoseChannel * BKE_pose_channel_find_name(const bPose *pose, const char *name)
void BKE_pchan_apply_mat4(bPoseChannel *pchan, const float mat[4][4], bool use_compat)
bArmature * BKE_armature_add(Main *bmain, const char *name)
const char * BKE_id_name(const ID &id)
General operations, lookup, etc. for blender objects.
Object * BKE_object_add_only_object(Main *bmain, int type, const char *name) ATTR_RETURNS_NONNULL
#define BLI_assert_msg(a, msg)
@ BONE_INHERIT_SCALE_NONE
Object is a sort of wrapper for general info.
EditBone * ED_armature_ebone_add(bArmature *arm, const char *name)
void ED_armature_edit_free(bArmature *arm)
void ED_armature_from_edit(Main *bmain, bArmature *arm)
void ED_armature_ebone_from_mat4(EditBone *ebone, const float mat[4][4])
void ED_armature_to_edit(bArmature *arm)
bool add_overwrite(const Key &key, const Value &value)
bool add(const Key &key, const Value &value)
Value lookup_default(const Key &key, const Value &default_value) const
bool contains(const Key &key) const
bool contains(const Key &key) const
void ufbx_matrix_to_obj(const ufbx_matrix &mtx, Object *obj)
const char * get_fbx_name(const ufbx_string &name, const char *def)
void read_custom_properties(const ufbx_props &props, ID &id, bool enums_as_strings)
void node_matrix_to_obj(const ufbx_node *node, Object *obj, const FbxElementMapping &mapping)
static bool need_create_armature_for_node(const ufbx_node *node)
void matrix_to_m44(const ufbx_matrix &src, float dst[4][4])
void import_armatures(Main &bmain, const ufbx_scene &fbx, FbxElementMapping &mapping, const FBXImportParams ¶ms)
ufbx_matrix calc_bone_pose_matrix(const ufbx_transform &local_xform, const ufbx_node &node, const ufbx_matrix &local_bind_inv_matrix)
static void find_bones(const ufbx_node *node, Set< const ufbx_node * > &r_bones)
static void find_fake_bones(const ufbx_node *root_node, const Set< const ufbx_node * > &bones, Set< const ufbx_node * > &r_fake_bones)
static Set< const ufbx_node * > find_all_bones(const ufbx_node *root_node)
T length(const VecBase< T, Size > &a)
T distance_squared(const VecBase< T, Size > &a, const VecBase< T, Size > &b)
T max(const T &a, const T &b)
VecBase< float, 3 > float3
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)
void calc_bone_bind_matrices()
FbxElementMapping & mapping
const FBXImportParams & params
ArmatureImportContext(Main &main, const ufbx_scene &fbx, const FBXImportParams ¶ms, FbxElementMapping &mapping)
ufbx_matrix get_node_bind_matrix(const ufbx_node *node) const
Map< const ufbx_node *, ufbx_real > bone_to_length
Map< const Object *, ufbx_matrix > armature_world_to_arm_node_matrix
Map< const ufbx_node *, ufbx_matrix > bone_to_bind_matrix
Set< const ufbx_node * > bone_is_skinned
Map< const ufbx_node *, Object * > bone_to_armature
Map< const ufbx_node *, std::string > node_to_name
Set< const ufbx_node * > node_is_blender_bone
Map< const Object *, ufbx_matrix > armature_world_to_arm_pose_matrix
ufbx_matrix calc_local_bind_matrix(const ufbx_node *bone_node, const ufbx_matrix &world_to_arm) const
Map< const ufbx_element *, Object * > el_to_object
ufbx_matrix global_conv_matrix
Set< Object * > imported_objects