Blender V4.3
ArmatureImporter.cpp
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2010-2023 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
9/* COLLADABU_ASSERT, may be able to remove later */
10#include "COLLADABUPlatform.h"
11
12#include <algorithm>
13
14#include "COLLADAFWUniqueId.h"
15
16#include "BKE_action.hh"
17#include "BKE_armature.hh"
18#include "BKE_object.hh"
19#include "BLI_listbase.h"
20#include "BLI_math_matrix.h"
21#include "BLI_string.h"
22#include "ED_armature.hh"
23
25
26#include "DEG_depsgraph.hh"
27
28#include "ArmatureImporter.h"
29#include "collada_utils.h"
30
31/* use node name, or fall back to original id if not present (name is optional) */
32template<class T> static const char *bc_get_joint_name(T *node)
33{
34 const std::string &id = node->getName();
35 return id.empty() ? node->getOriginalId().c_str() : id.c_str();
36}
37
39 MeshImporterBase *mesh,
40 Main *bmain,
41 Scene *sce,
42 ViewLayer *view_layer,
43 const ImportSettings *import_settings)
44 : TransformReader(conv),
45 m_bmain(bmain),
46 scene(sce),
47 view_layer(view_layer),
48 unit_converter(conv),
49 import_settings(import_settings),
50 empty(nullptr),
51 mesh_importer(mesh)
52{
53}
54
56{
57 /* free skin controller data if we forget to do this earlier */
58 std::map<COLLADAFW::UniqueId, SkinInfo>::iterator it;
59 for (it = skin_by_data_uid.begin(); it != skin_by_data_uid.end(); it++) {
60 it->second.free();
61 }
62}
63
64#if 0
65JointData *ArmatureImporter::get_joint_data(COLLADAFW::Node *node);
66{
67 const COLLADAFW::UniqueId &joint_id = node->getUniqueId();
68
69 if (joint_id_to_joint_index_map.find(joint_id) == joint_id_to_joint_index_map.end()) {
70 fprintf(
71 stderr, "Cannot find a joint index by joint id for %s.\n", node->getOriginalId().c_str());
72 return nullptr;
73 }
74
75 int joint_index = joint_id_to_joint_index_map[joint_id];
76
77 return &joint_index_to_joint_info_map[joint_index];
78}
79#endif
80
81int ArmatureImporter::create_bone(SkinInfo *skin,
82 COLLADAFW::Node *node,
83 EditBone *parent,
84 int totchild,
85 float parent_mat[4][4],
86 bArmature *arm,
87 std::vector<std::string> &layer_labels)
88{
89 float mat[4][4];
90 float joint_inv_bind_mat[4][4];
91 float joint_bind_mat[4][4];
92 int chain_length = 0;
93
94 /* Checking if bone is already made. */
95 std::vector<COLLADAFW::Node *>::iterator it;
96 it = std::find(finished_joints.begin(), finished_joints.end(), node);
97 if (it != finished_joints.end()) {
98 return chain_length;
99 }
100
102 totbone++;
103
104 /*
105 * We use the inv_bind_shape matrix to apply the armature bind pose as its rest pose.
106 */
107
108 std::map<COLLADAFW::UniqueId, SkinInfo>::iterator skin_it;
109 bool bone_is_skinned = false;
110 for (skin_it = skin_by_data_uid.begin(); skin_it != skin_by_data_uid.end(); skin_it++) {
111
112 SkinInfo *b = &skin_it->second;
113 if (b->get_joint_inv_bind_matrix(joint_inv_bind_mat, node)) {
114
115 /* get original world-space matrix */
116 invert_m4_m4(mat, joint_inv_bind_mat);
117 copy_m4_m4(joint_bind_mat, mat);
118 /* And make local to armature */
119 Object *ob_arm = skin->BKE_armature_from_object();
120 if (ob_arm) {
121 float invmat[4][4];
122 invert_m4_m4(invmat, ob_arm->object_to_world().ptr());
123 mul_m4_m4m4(mat, invmat, mat);
124 }
125
126 bone_is_skinned = true;
127 break;
128 }
129 }
130
131 /* create a bone even if there's no joint data for it (i.e. it has no influence) */
132 if (!bone_is_skinned) {
133 get_node_mat(mat, node, nullptr, nullptr, parent_mat);
134 }
135
136 if (parent) {
137 bone->parent = parent;
138 }
139
140 float loc[3], size[3], rot[3][3];
141 BoneExtensionMap &extended_bones = bone_extension_manager.getExtensionMap(arm);
142 BoneExtended &be = add_bone_extended(bone, node, totchild, layer_labels, extended_bones);
143
144 for (const std::string &bcoll_name : be.get_bone_collections()) {
145 BoneCollection *bcoll = ANIM_armature_bonecoll_get_by_name(arm, bcoll_name.c_str());
146 if (bcoll) {
148 }
149 }
150
151 float *tail = be.get_tail();
152 int use_connect = be.get_use_connect();
153
154 switch (use_connect) {
155 case 1:
156 bone->flag |= BONE_CONNECTED;
157 break;
158 case -1: /* Connect type not specified */
159 case 0:
160 bone->flag &= ~BONE_CONNECTED;
161 break;
162 }
163
164 if (be.has_roll()) {
165 bone->roll = be.get_roll();
166 }
167 else {
168 float angle;
169 mat4_to_loc_rot_size(loc, rot, size, mat);
170 mat3_to_vec_roll(rot, nullptr, &angle);
171 bone->roll = angle;
172 }
173 copy_v3_v3(bone->head, mat[3]);
174
175 if (bone_is_skinned && this->import_settings->keep_bind_info) {
176 float rest_mat[4][4];
177 get_node_mat(rest_mat, node, nullptr, nullptr, nullptr);
178 bc_set_IDPropertyMatrix(bone, "bind_mat", joint_bind_mat);
179 bc_set_IDPropertyMatrix(bone, "rest_mat", rest_mat);
180 }
181
182 add_v3_v3v3(bone->tail, bone->head, tail); /* tail must be non zero */
183
184 /* find smallest bone length in armature (used later for leaf bone length) */
185 if (parent) {
186
187 if (use_connect == 1) {
188 copy_v3_v3(parent->tail, bone->head);
189 }
190
191 /* guess reasonable leaf bone length */
192 float length = len_v3v3(parent->head, bone->head);
193 if ((length < leaf_bone_length || totbone == 0) && length > MINIMUM_BONE_LENGTH) {
194 leaf_bone_length = length;
195 }
196 }
197
198 COLLADAFW::NodePointerArray &children = node->getChildNodes();
199
200 for (uint i = 0; i < children.getCount(); i++) {
201 int cl = create_bone(skin, children[i], bone, children.getCount(), mat, arm, layer_labels);
202 if (cl > chain_length) {
203 chain_length = cl;
204 }
205 }
206
207 bone->length = len_v3v3(bone->head, bone->tail);
208 joint_by_uid[node->getUniqueId()] = node;
209 finished_joints.push_back(node);
210
211 be.set_chain_length(chain_length + 1);
212
213 return chain_length + 1;
214}
215
216void ArmatureImporter::fix_leaf_bone_hierarchy(bArmature *armature,
217 Bone *bone,
218 bool fix_orientation)
219{
220 if (bone == nullptr) {
221 return;
222 }
223
224 if (bc_is_leaf_bone(bone)) {
225 BoneExtensionMap &extended_bones = bone_extension_manager.getExtensionMap(armature);
226 BoneExtended *be = extended_bones[bone->name];
227 EditBone *ebone = bc_get_edit_bone(armature, bone->name);
228 fix_leaf_bone(armature, ebone, be, fix_orientation);
229 }
230
231 LISTBASE_FOREACH (Bone *, child, &bone->childbase) {
232 fix_leaf_bone_hierarchy(armature, child, fix_orientation);
233 }
234}
235
236void ArmatureImporter::fix_leaf_bone(bArmature *armature,
237 EditBone *ebone,
238 BoneExtended *be,
239 bool fix_orientation)
240{
241 if (be == nullptr || !be->has_tail()) {
242
243 /* Collada only knows Joints, Here we guess a reasonable leaf bone length */
244 float leaf_length = (leaf_bone_length == FLT_MAX) ? 1.0 : leaf_bone_length;
245
246 float vec[3];
247
248 if (fix_orientation && ebone->parent != nullptr) {
249 EditBone *parent = ebone->parent;
250 sub_v3_v3v3(vec, ebone->head, parent->head);
252 sub_v3_v3v3(vec, parent->tail, parent->head);
253 }
254 }
255 else {
256 vec[2] = 0.1f;
257 sub_v3_v3v3(vec, ebone->tail, ebone->head);
258 }
259
260 normalize_v3_v3(vec, vec);
261 mul_v3_fl(vec, leaf_length);
262 add_v3_v3v3(ebone->tail, ebone->head, vec);
263 }
264}
265
266void ArmatureImporter::fix_parent_connect(bArmature *armature, Bone *bone)
267{
268 /* armature has no bones */
269 if (bone == nullptr) {
270 return;
271 }
272
273 if (bone->parent && bone->flag & BONE_CONNECTED) {
274 copy_v3_v3(bone->parent->tail, bone->head);
275 }
276
277 LISTBASE_FOREACH (Bone *, child, &bone->childbase) {
278 fix_parent_connect(armature, child);
279 }
280}
281
282void ArmatureImporter::connect_bone_chains(bArmature *armature,
283 Bone *parentbone,
284 int max_chain_length)
285{
286 BoneExtensionMap &extended_bones = bone_extension_manager.getExtensionMap(armature);
287 BoneExtended *dominant_child = nullptr;
288 int maxlen = 0;
289
290 if (parentbone == nullptr) {
291 return;
292 }
293
294 Bone *child = (Bone *)parentbone->childbase.first;
295 if (child && (import_settings->find_chains || child->next == nullptr)) {
296 for (; child; child = child->next) {
297 BoneExtended *be = extended_bones[child->name];
298 if (be != nullptr) {
299 int chain_len = be->get_chain_length();
300 if (chain_len <= max_chain_length) {
301 if (chain_len > maxlen) {
302 dominant_child = be;
303 maxlen = chain_len;
304 }
305 else if (chain_len == maxlen) {
306 dominant_child = nullptr;
307 }
308 }
309 }
310 }
311 }
312
313 BoneExtended *pbe = extended_bones[parentbone->name];
314 if (dominant_child != nullptr) {
315 /* Found a valid chain. Now connect current bone with that chain. */
316 EditBone *pebone = bc_get_edit_bone(armature, parentbone->name);
317 EditBone *cebone = bc_get_edit_bone(armature, dominant_child->get_name());
318 if (pebone && !(cebone->flag & BONE_CONNECTED)) {
319 float vec[3];
320 sub_v3_v3v3(vec, cebone->head, pebone->head);
321
322 /*
323 * It is possible that the child's head is located on the parents head.
324 * When this happens, then moving the parent's tail to the child's head
325 * would result in a zero sized bone and Blender would silently remove the bone.
326 * So we move the tail only when the resulting bone has a minimum length:
327 */
328
330 copy_v3_v3(pebone->tail, cebone->head);
331 pbe->set_tail(pebone->tail); /* To make fix_leafbone happy. */
332 if (pbe && pbe->get_chain_length() >= this->import_settings->min_chain_length) {
333
334 BoneExtended *cbe = extended_bones[cebone->name];
335 cbe->set_use_connect(true);
336
337 cebone->flag |= BONE_CONNECTED;
338 pbe->set_leaf_bone(false);
339 printf("Connect Bone chain: parent (%s --> %s) child)\n", pebone->name, cebone->name);
340 }
341 }
342 }
343 LISTBASE_FOREACH (Bone *, ch, &parentbone->childbase) {
344 ArmatureImporter::connect_bone_chains(armature, ch, UNLIMITED_CHAIN_MAX);
345 }
346 }
347 else if (maxlen > 1 && maxlen > this->import_settings->min_chain_length) {
348 /* Try again with smaller chain length */
349 ArmatureImporter::connect_bone_chains(armature, parentbone, maxlen - 1);
350 }
351 else {
352 /* can't connect this Bone. Proceed with children ... */
353 if (pbe) {
354 pbe->set_leaf_bone(true);
355 }
356 LISTBASE_FOREACH (Bone *, ch, &parentbone->childbase) {
357 ArmatureImporter::connect_bone_chains(armature, ch, UNLIMITED_CHAIN_MAX);
358 }
359 }
360}
361
362#if 0
363void ArmatureImporter::set_leaf_bone_shapes(Object *ob_arm)
364{
365 bPose *pose = ob_arm->pose;
366
367 std::vector<LeafBone>::iterator it;
368 for (it = leaf_bones.begin(); it != leaf_bones.end(); it++) {
369 LeafBone &leaf = *it;
370
371 bPoseChannel *pchan = BKE_pose_channel_find_name(pose, leaf.name);
372 if (pchan) {
373 pchan->custom = get_empty_for_leaves();
374 }
375 else {
376 fprintf(stderr, "Cannot find a pose channel for leaf bone %s\n", leaf.name);
377 }
378 }
379}
380
381void ArmatureImporter::set_euler_rotmode()
382{
383 /* just set rotmode = ROT_MODE_EUL on pose channel for each joint */
384
385 std::map<COLLADAFW::UniqueId, COLLADAFW::Node *>::iterator it;
386
387 for (it = joint_by_uid.begin(); it != joint_by_uid.end(); it++) {
388
389 COLLADAFW::Node *joint = it->second;
390
391 std::map<COLLADAFW::UniqueId, SkinInfo>::iterator sit;
392
393 for (sit = skin_by_data_uid.begin(); sit != skin_by_data_uid.end(); sit++) {
394 SkinInfo &skin = sit->second;
395
396 if (skin.uses_joint_or_descendant(joint)) {
397 bPoseChannel *pchan = skin.get_pose_channel_from_node(joint);
398
399 if (pchan) {
400 pchan->rotmode = ROT_MODE_EUL;
401 }
402 else {
403 fprintf(stderr, "Cannot find pose channel for %s.\n", get_joint_name(joint));
404 }
405
406 break;
407 }
408 }
409 }
410}
411#endif
412
413Object *ArmatureImporter::get_empty_for_leaves()
414{
415 if (empty) {
416 return empty;
417 }
418
419 empty = bc_add_object(m_bmain, scene, view_layer, OB_EMPTY, nullptr);
421
422 return empty;
423}
424
425#if 0
426Object *ArmatureImporter::find_armature(COLLADAFW::Node *node)
427{
428 JointData *jd = get_joint_data(node);
429 if (jd) {
430 return jd->ob_arm;
431 }
432
433 COLLADAFW::NodePointerArray &children = node->getChildNodes();
434 for (int i = 0; i < children.getCount(); i++) {
435 Object *ob_arm = find_armature(children[i]);
436 if (ob_arm) {
437 return ob_arm;
438 }
439 }
440
441 return nullptr;
442}
443
444ArmatureJoints &ArmatureImporter::get_armature_joints(Object *ob_arm)
445{
446 /* try finding it */
447 std::vector<ArmatureJoints>::iterator it;
448 for (it = armature_joints.begin(); it != armature_joints.end(); it++) {
449 if ((*it).ob_arm == ob_arm) {
450 return *it;
451 }
452 }
453
454 /* not found, create one */
455 ArmatureJoints aj;
456 aj.ob_arm = ob_arm;
457 armature_joints.push_back(aj);
458
459 return armature_joints.back();
460}
461#endif
462void ArmatureImporter::create_armature_bones(Main *bmain, std::vector<Object *> &arm_objs)
463{
464 std::vector<COLLADAFW::Node *>::iterator ri;
465 std::vector<std::string> layer_labels;
466
467 /* if there is an armature created for root_joint next root_joint */
468 for (ri = root_joints.begin(); ri != root_joints.end(); ri++) {
469 COLLADAFW::Node *node = *ri;
470 if (get_armature_for_joint(node) != nullptr) {
471 continue;
472 }
473
474 Object *ob_arm = joint_parent_map[node->getUniqueId()];
475 if (!ob_arm) {
476 continue;
477 }
478
479 /* Assumption that joint_parent_map only lists armatures is apparently wrong (it can be meshes,
480 * too), this needs to be checked again, for now prevent a crash though. */
481 if (ob_arm->type != OB_ARMATURE) {
482 continue;
483 }
484
485 bArmature *armature = (bArmature *)ob_arm->data;
486 if (!armature) {
487 continue;
488 }
489
490 char *bone_name = (char *)bc_get_joint_name(node);
491 Bone *bone = BKE_armature_find_bone_name(armature, bone_name);
492 if (bone) {
493 fprintf(stderr,
494 "Reuse of child bone [%s] as root bone in same Armature is not supported.\n",
495 bone_name);
496 continue;
497 }
498
499 ED_armature_to_edit(armature);
500
501 create_bone(
502 nullptr, node, nullptr, node->getChildNodes().getCount(), nullptr, armature, layer_labels);
503 if (this->import_settings->find_chains) {
504 connect_bone_chains(armature, (Bone *)armature->bonebase.first, UNLIMITED_CHAIN_MAX);
505 }
506
507 /* exit armature edit mode to populate the Armature object */
508 ED_armature_from_edit(bmain, armature);
509 ED_armature_edit_free(armature);
510 ED_armature_to_edit(armature);
511
512 fix_leaf_bone_hierarchy(
513 armature, (Bone *)armature->bonebase.first, this->import_settings->fix_orientation);
514 unskinned_armature_map[node->getUniqueId()] = ob_arm;
515
516 ED_armature_from_edit(bmain, armature);
517 ED_armature_edit_free(armature);
518
519 set_bone_transformation_type(node, ob_arm);
520
521 int index = std::find(arm_objs.begin(), arm_objs.end(), ob_arm) - arm_objs.begin();
522 if (index == 0) {
523 arm_objs.push_back(ob_arm);
524 }
525
527 }
528}
529
530Object *ArmatureImporter::create_armature_bones(Main *bmain, SkinInfo &skin)
531{
532 /* just do like so:
533 * - get armature
534 * - enter editmode
535 * - add edit bones and head/tail properties using matrices and parent-child info
536 * - exit edit mode
537 * - set a sphere shape to leaf bones */
538 Object *ob_arm = nullptr;
539
540 /*
541 * find if there's another skin sharing at least one bone with this skin
542 * if so, use that skin's armature
543 */
544
573 SkinInfo *a = &skin;
574 Object *shared = nullptr;
575 std::vector<COLLADAFW::Node *> skin_root_joints;
576 std::vector<std::string> layer_labels;
577
578 std::map<COLLADAFW::UniqueId, SkinInfo>::iterator it;
579 for (it = skin_by_data_uid.begin(); it != skin_by_data_uid.end(); it++) {
580 SkinInfo *b = &it->second;
581 if (b == a || b->BKE_armature_from_object() == nullptr) {
582 continue;
583 }
584
585 skin_root_joints.clear();
586
587 b->find_root_joints(root_joints, joint_by_uid, skin_root_joints);
588
589 std::vector<COLLADAFW::Node *>::iterator ri;
590 for (ri = skin_root_joints.begin(); ri != skin_root_joints.end(); ri++) {
591 COLLADAFW::Node *node = *ri;
592 if (a->uses_joint_or_descendant(node)) {
593 shared = b->BKE_armature_from_object();
594 break;
595 }
596 }
597
598 if (shared != nullptr) {
599 break;
600 }
601 }
602
603 if (!shared && !this->joint_parent_map.empty()) {
604 /* All armatures have been created while creating the Node tree.
605 * The Collada exporter currently does not create a
606 * strict relationship between geometries and armatures
607 * So when we reimport a Blender collada file, then we have
608 * to guess what is meant.
609 * XXX This is not safe when we have more than one armatures
610 * in the import. */
611 shared = this->joint_parent_map.begin()->second;
612 }
613
614 if (shared) {
615 ob_arm = skin.set_armature(shared);
616 }
617 else {
618 ob_arm = skin.create_armature(m_bmain, scene, view_layer); /* once for every armature */
619 }
620
621 /* enter armature edit mode */
622 bArmature *armature = (bArmature *)ob_arm->data;
623 ED_armature_to_edit(armature);
624
625 totbone = 0;
626 // bone_direction_row = 1; /* TODO: don't default to Y but use asset and based on it decide on */
627 /* default row */
628
629 /* create bones */
630 /* TODO:
631 * check if bones have already been created for a given joint */
632
633 std::vector<COLLADAFW::Node *>::iterator ri;
634 for (ri = root_joints.begin(); ri != root_joints.end(); ri++) {
635 COLLADAFW::Node *node = *ri;
636 /* for shared armature check if bone tree is already created */
637 if (shared && std::find(skin_root_joints.begin(), skin_root_joints.end(), node) !=
638 skin_root_joints.end())
639 {
640 continue;
641 }
642
643 /* since root_joints may contain joints for multiple controllers, we need to filter */
644 if (skin.uses_joint_or_descendant(node)) {
645
646 create_bone(
647 &skin, node, nullptr, node->getChildNodes().getCount(), nullptr, armature, layer_labels);
648
649 if (joint_parent_map.find(node->getUniqueId()) != joint_parent_map.end() &&
650 !skin.get_parent())
651 {
652 skin.set_parent(joint_parent_map[node->getUniqueId()]);
653 }
654 }
655 }
656
657 /* exit armature edit mode to populate the Armature object */
658 ED_armature_from_edit(bmain, armature);
659 ED_armature_edit_free(armature);
660
661 for (ri = root_joints.begin(); ri != root_joints.end(); ri++) {
662 COLLADAFW::Node *node = *ri;
663 set_bone_transformation_type(node, ob_arm);
664 }
665
666 ED_armature_to_edit(armature);
667 if (this->import_settings->find_chains) {
668 connect_bone_chains(armature, (Bone *)armature->bonebase.first, UNLIMITED_CHAIN_MAX);
669 }
670 fix_leaf_bone_hierarchy(
671 armature, (Bone *)armature->bonebase.first, this->import_settings->fix_orientation);
672 ED_armature_from_edit(bmain, armature);
673 ED_armature_edit_free(armature);
674
676
677 return ob_arm;
678}
679
680void ArmatureImporter::set_bone_transformation_type(const COLLADAFW::Node *node, Object *ob_arm)
681{
683 if (pchan) {
684 pchan->rotmode = node_is_decomposed(node) ? ROT_MODE_EUL : ROT_MODE_QUAT;
685 }
686
687 COLLADAFW::NodePointerArray childnodes = node->getChildNodes();
688 for (int index = 0; index < childnodes.getCount(); index++) {
689 node = childnodes[index];
690 set_bone_transformation_type(node, ob_arm);
691 }
692}
693
694void ArmatureImporter::set_pose(Object *ob_arm,
695 COLLADAFW::Node *root_node,
696 const char *parentname,
697 float parent_mat[4][4])
698{
699 const char *bone_name = bc_get_joint_name(root_node);
700 float mat[4][4];
701 float obmat[4][4];
702
703 /* object-space */
704 get_node_mat(obmat, root_node, nullptr, nullptr);
705 bool is_decomposed = node_is_decomposed(root_node);
706
707 // if (*edbone)
708 bPoseChannel *pchan = BKE_pose_channel_find_name(ob_arm->pose, bone_name);
709 pchan->rotmode = (is_decomposed) ? ROT_MODE_EUL : ROT_MODE_QUAT;
710
711 // else fprintf ( "",
712
713 /* get world-space */
714 if (parentname) {
715 mul_m4_m4m4(mat, parent_mat, obmat);
716 bPoseChannel *parchan = BKE_pose_channel_find_name(ob_arm->pose, parentname);
717
718 mul_m4_m4m4(pchan->pose_mat, parchan->pose_mat, mat);
719 }
720 else {
721
722 copy_m4_m4(mat, obmat);
723 float invObmat[4][4];
724 invert_m4_m4(invObmat, ob_arm->object_to_world().ptr());
725 mul_m4_m4m4(pchan->pose_mat, invObmat, mat);
726 }
727
728#if 0
729 float angle = 0.0f;
730 mat4_to_axis_angle(ax, &angle, mat);
731 pchan->bone->roll = angle;
732#endif
733
734 COLLADAFW::NodePointerArray &children = root_node->getChildNodes();
735 for (uint i = 0; i < children.getCount(); i++) {
736 set_pose(ob_arm, children[i], bone_name, mat);
737 }
738}
739
740bool ArmatureImporter::node_is_decomposed(const COLLADAFW::Node *node)
741{
742 const COLLADAFW::TransformationPointerArray &nodeTransforms = node->getTransformations();
743 for (uint i = 0; i < nodeTransforms.getCount(); i++) {
744 COLLADAFW::Transformation *transform = nodeTransforms[i];
745 COLLADAFW::Transformation::TransformationType tm_type = transform->getTransformationType();
746 if (tm_type == COLLADAFW::Transformation::MATRIX) {
747 return false;
748 }
749 }
750 return true;
751}
752
753void ArmatureImporter::add_root_joint(COLLADAFW::Node *node, Object *parent)
754{
755 root_joints.push_back(node);
756 if (parent) {
757 joint_parent_map[node->getUniqueId()] = parent;
758 }
759}
760
761#if 0
762void ArmatureImporter::add_root_joint(COLLADAFW::Node *node)
763{
764 // root_joints.push_back(node);
765 Object *ob_arm = find_armature(node);
766 if (ob_arm) {
767 get_armature_joints(ob_arm).root_joints.push_back(node);
768 }
769# ifdef COLLADA_DEBUG
770 else {
771 fprintf(stderr, "%s cannot be added to armature.\n", get_joint_name(node));
772 }
773# endif
774}
775#endif
776
777void ArmatureImporter::make_armatures(bContext *C, std::vector<Object *> &objects_to_scale)
778{
779 Main *bmain = CTX_data_main(C);
780 std::vector<Object *> arm_objs;
781 std::map<COLLADAFW::UniqueId, SkinInfo>::iterator it;
782
783 /* TODO: Make this work for more than one armature in the import file. */
784 leaf_bone_length = FLT_MAX;
785
786 for (it = skin_by_data_uid.begin(); it != skin_by_data_uid.end(); it++) {
787
788 SkinInfo &skin = it->second;
789
790 Object *ob_arm = create_armature_bones(bmain, skin);
791
792 /* link armature with a mesh object */
793 const COLLADAFW::UniqueId &uid = skin.get_controller_uid();
794 const COLLADAFW::UniqueId *guid = get_geometry_uid(uid);
795 if (guid != nullptr) {
796 Object *ob = mesh_importer->get_object_by_geom_uid(*guid);
797 if (ob) {
798 skin.link_armature(C, ob, joint_by_uid, this);
799
800 std::vector<Object *>::iterator ob_it = std::find(
801 objects_to_scale.begin(), objects_to_scale.end(), ob);
802
803 if (ob_it != objects_to_scale.end()) {
804 int index = ob_it - objects_to_scale.begin();
805 objects_to_scale.erase(objects_to_scale.begin() + index);
806 }
807
808 if (std::find(objects_to_scale.begin(), objects_to_scale.end(), ob_arm) ==
809 objects_to_scale.end())
810 {
811 objects_to_scale.push_back(ob_arm);
812 }
813
814 if (std::find(arm_objs.begin(), arm_objs.end(), ob_arm) == arm_objs.end()) {
815 arm_objs.push_back(ob_arm);
816 }
817 }
818 else {
819 fprintf(stderr, "Cannot find object to link armature with.\n");
820 }
821 }
822 else {
823 fprintf(stderr, "Cannot find geometry to link armature with.\n");
824 }
825
826 /* set armature parent if any */
827 Object *par = skin.get_parent();
828 if (par) {
829 bc_set_parent(skin.BKE_armature_from_object(), par, C, false);
830 }
831
832 /* free memory stolen from SkinControllerData */
833 skin.free();
834 }
835
836 /* for bones without skins */
837 create_armature_bones(bmain, arm_objs);
838
839 /* Fix bone relations */
840 std::vector<Object *>::iterator ob_arm_it;
841 for (ob_arm_it = arm_objs.begin(); ob_arm_it != arm_objs.end(); ob_arm_it++) {
842
843 Object *ob_arm = *ob_arm_it;
844 bArmature *armature = (bArmature *)ob_arm->data;
845
846 /* and step back to edit mode to fix the leaf nodes */
847 ED_armature_to_edit(armature);
848
849 fix_parent_connect(armature, (Bone *)armature->bonebase.first);
850
851 ED_armature_from_edit(bmain, armature);
852 ED_armature_edit_free(armature);
853 }
854}
855
856#if 0
857/* link with meshes, create vertex groups, assign weights */
858void ArmatureImporter::link_armature(Object *ob_arm,
859 const COLLADAFW::UniqueId &geom_id,
860 const COLLADAFW::UniqueId &controller_data_id)
861{
862 Object *ob = mesh_importer->get_object_by_geom_uid(geom_id);
863
864 if (!ob) {
865 fprintf(stderr, "Cannot find object by geometry UID.\n");
866 return;
867 }
868
869 if (skin_by_data_uid.find(controller_data_id) == skin_by_data_uid.end()) {
870 fprintf(stderr, "Cannot find skin info by controller data UID.\n");
871 return;
872 }
873
874 SkinInfo &skin = skin_by_data_uid[conroller_data_id];
875
876 /* create vertex groups */
877}
878#endif
879
880bool ArmatureImporter::write_skin_controller_data(const COLLADAFW::SkinControllerData *data)
881{
882 /* at this stage we get vertex influence info that should go into mesh->verts and ob->defbase
883 * there's no info to which object this should be long so we associate it with
884 * skin controller data UID. */
885
886 /* don't forget to call BKE_object_defgroup_unique_name before we copy */
887
888 /* controller data uid -> [armature] -> joint data,
889 * [mesh object] */
890
891 SkinInfo skin(unit_converter);
892 skin.borrow_skin_controller_data(data);
893
894 /* store join inv bind matrix to use it later in armature construction */
895 const COLLADAFW::Matrix4Array &inv_bind_mats = data->getInverseBindMatrices();
896 for (uint i = 0; i < data->getJointsCount(); i++) {
897 skin.add_joint(inv_bind_mats[i]);
898 }
899
900 skin_by_data_uid[data->getUniqueId()] = skin;
901
902 return true;
903}
904
905bool ArmatureImporter::write_controller(const COLLADAFW::Controller *controller)
906{
907 /* - create and store armature object */
908 const COLLADAFW::UniqueId &con_id = controller->getUniqueId();
909
910 if (controller->getControllerType() == COLLADAFW::Controller::CONTROLLER_TYPE_SKIN) {
911 COLLADAFW::SkinController *co = (COLLADAFW::SkinController *)controller;
912 /* to be able to find geom id by controller id */
913 geom_uid_by_controller_uid[con_id] = co->getSource();
914
915 const COLLADAFW::UniqueId &data_uid = co->getSkinControllerData();
916 if (skin_by_data_uid.find(data_uid) == skin_by_data_uid.end()) {
917 fprintf(stderr, "Cannot find skin by controller data UID.\n");
918 return true;
919 }
920
921 skin_by_data_uid[data_uid].set_controller(co);
922 }
923 /* morph controller */
924 else if (controller->getControllerType() == COLLADAFW::Controller::CONTROLLER_TYPE_MORPH) {
925 COLLADAFW::MorphController *co = (COLLADAFW::MorphController *)controller;
926 /* to be able to find geom id by controller id */
927 geom_uid_by_controller_uid[con_id] = co->getSource();
928 /* Shape keys are applied in DocumentImporter->finish() */
929 morph_controllers.push_back(co);
930 }
931
932 return true;
933}
934
936{
937 Main *bmain = CTX_data_main(C);
938 std::vector<COLLADAFW::MorphController *>::iterator mc;
939 float weight;
940
941 for (mc = morph_controllers.begin(); mc != morph_controllers.end(); mc++) {
942 /* Controller data */
943 COLLADAFW::UniqueIdArray &morphTargetIds = (*mc)->getMorphTargets();
944 COLLADAFW::FloatOrDoubleArray &morphWeights = (*mc)->getMorphWeights();
945
946 /* Prerequisite: all the geometries must be imported and mesh objects must be made. */
947 Object *source_ob = this->mesh_importer->get_object_by_geom_uid((*mc)->getSource());
948
949 if (source_ob) {
950
951 Mesh *source_me = (Mesh *)source_ob->data;
952 /* insert key to source mesh */
953 Key *key = source_me->key = BKE_key_add(bmain, (ID *)source_me);
954 key->type = KEY_RELATIVE;
955 KeyBlock *kb;
956
957 /* insert basis key */
958 kb = BKE_keyblock_add_ctime(key, "Basis", false);
959 BKE_keyblock_convert_from_mesh(source_me, key, kb);
960
961 /* insert other shape keys */
962 for (int i = 0; i < morphTargetIds.getCount(); i++) {
963 /* Better to have a separate map of morph objects,
964 * This will do for now since only mesh morphing is imported. */
965
966 Mesh *mesh = this->mesh_importer->get_mesh_by_geom_uid(morphTargetIds[i]);
967
968 if (mesh) {
969 mesh->key = key;
970 std::string morph_name = *this->mesh_importer->get_geometry_name(mesh->id.name);
971
972 kb = BKE_keyblock_add_ctime(key, morph_name.c_str(), false);
973 BKE_keyblock_convert_from_mesh(mesh, key, kb);
974
975 /* apply weights */
976 weight = morphWeights.getFloatValues()->getData()[i];
977 kb->curval = weight;
978 }
979 else {
980 fprintf(stderr, "Morph target geometry not found.\n");
981 }
982 }
983 }
984 else {
985 fprintf(stderr, "Morph target object not found.\n");
986 }
987 }
988}
989
990COLLADAFW::UniqueId *ArmatureImporter::get_geometry_uid(const COLLADAFW::UniqueId &controller_uid)
991{
992 if (geom_uid_by_controller_uid.find(controller_uid) == geom_uid_by_controller_uid.end()) {
993 return nullptr;
994 }
995
996 return &geom_uid_by_controller_uid[controller_uid];
997}
998
1000{
1001 std::map<COLLADAFW::UniqueId, SkinInfo>::iterator it;
1002 for (it = skin_by_data_uid.begin(); it != skin_by_data_uid.end(); it++) {
1003 SkinInfo &skin = it->second;
1004
1005 if (skin.uses_joint_or_descendant(node)) {
1006 return skin.BKE_armature_from_object();
1007 }
1008 }
1009
1010 std::map<COLLADAFW::UniqueId, Object *>::iterator arm;
1011 for (arm = unskinned_armature_map.begin(); arm != unskinned_armature_map.end(); arm++) {
1012 if (arm->first == node->getUniqueId()) {
1013 return arm->second;
1014 }
1015 }
1016 return nullptr;
1017}
1018
1019void ArmatureImporter::set_tags_map(TagsMap &tags_map)
1020{
1021 this->uid_tags_map = tags_map;
1022}
1023
1025 char *joint_path,
1026 size_t joint_path_maxncpy)
1027{
1028 char bone_name_esc[sizeof(Bone::name) * 2];
1029 BLI_str_escape(bone_name_esc, bc_get_joint_name(node), sizeof(bone_name_esc));
1030 BLI_snprintf(joint_path, joint_path_maxncpy, "pose.bones[\"%s\"]", bone_name_esc);
1031}
1032
1033bool ArmatureImporter::get_joint_bind_mat(float m[4][4], COLLADAFW::Node *joint)
1034{
1035 std::map<COLLADAFW::UniqueId, SkinInfo>::iterator it;
1036 bool found = false;
1037 for (it = skin_by_data_uid.begin(); it != skin_by_data_uid.end(); it++) {
1038 SkinInfo &skin = it->second;
1039 if (skin.get_joint_inv_bind_matrix(m, joint)) {
1040 invert_m4(m);
1041 found = true;
1042 break;
1043 }
1044 }
1045
1046 return found;
1047}
1048
1049BoneExtended &ArmatureImporter::add_bone_extended(EditBone *bone,
1050 COLLADAFW::Node *node,
1051 int sibcount,
1052 std::vector<std::string> &layer_labels,
1053 BoneExtensionMap &extended_bones)
1054{
1055 BoneExtended *be = new BoneExtended(bone);
1056 extended_bones[bone->name] = be;
1057
1058 TagsMap::iterator etit;
1059 ExtraTags *et = nullptr;
1060 etit = uid_tags_map.find(node->getUniqueId().toAscii());
1061
1062 bool has_connect = false;
1063 int connect_type = -1;
1064
1065 if (etit != uid_tags_map.end()) {
1066
1067 float tail[3] = {FLT_MAX, FLT_MAX, FLT_MAX};
1068 float roll = 0;
1069
1070 et = etit->second;
1071
1072 bool has_tail = false;
1073 has_tail |= et->setData("tip_x", &tail[0]);
1074 has_tail |= et->setData("tip_y", &tail[1]);
1075 has_tail |= et->setData("tip_z", &tail[2]);
1076
1077 has_connect = et->setData("connect", &connect_type);
1078 bool has_roll = et->setData("roll", &roll);
1079
1080 be->set_bone_collections(et->dataSplitString("collections"));
1081
1082 if (has_tail && !has_connect) {
1083 /* got a bone tail definition but no connect info -> bone is not connected */
1084 has_connect = true;
1085 connect_type = 0;
1086 }
1087
1088 if (has_tail) {
1089 be->set_tail(tail);
1090 }
1091 if (has_roll) {
1092 be->set_roll(roll);
1093 }
1094 }
1095
1096 if (!has_connect && this->import_settings->auto_connect) {
1097 /* Auto connect only when parent has exactly one child. */
1098 connect_type = sibcount == 1;
1099 }
1100
1101 be->set_use_connect(connect_type);
1102 be->set_leaf_bone(true);
1103
1104 return *be;
1105}
C++ functions to deal with Armature collections (i.e. the successor of bone layers).
BoneCollection * ANIM_armature_bonecoll_get_by_name(bArmature *armature, const char *name) ATTR_WARN_UNUSED_RESULT
bool ANIM_armature_bonecoll_assign_editbone(BoneCollection *bcoll, EditBone *ebone)
static const char * bc_get_joint_name(T *node)
static const char * bc_get_joint_name(T *node)
#define UNLIMITED_CHAIN_MAX
#define MINIMUM_BONE_LENGTH
Blender kernel action and pose functionality.
bPoseChannel * BKE_pose_channel_find_name(const bPose *pose, const char *name)
void mat3_to_vec_roll(const float mat[3][3], float r_vec[3], float *r_roll)
Definition armature.cc:2456
Bone * BKE_armature_find_bone_name(bArmature *arm, const char *name)
Definition armature.cc:779
Main * CTX_data_main(const bContext *C)
Key * BKE_key_add(Main *bmain, ID *id)
Definition key.cc:256
void BKE_keyblock_convert_from_mesh(const Mesh *mesh, const Key *key, KeyBlock *kb)
Definition key.cc:2186
KeyBlock * BKE_keyblock_add_ctime(Key *key, const char *name, bool do_force)
Definition key.cc:1878
General operations, lookup, etc. for blender objects.
#define LISTBASE_FOREACH(type, var, list)
void mul_m4_m4m4(float R[4][4], const float A[4][4], const float B[4][4])
void mat4_to_loc_rot_size(float loc[3], float rot[3][3], float size[3], const float wmat[4][4])
void copy_m4_m4(float m1[4][4], const float m2[4][4])
bool invert_m4_m4(float inverse[4][4], const float mat[4][4])
bool invert_m4(float mat[4][4])
void mat4_to_axis_angle(float axis[3], float *angle, const float mat[4][4])
MINLINE float len_squared_v3(const float v[3]) ATTR_WARN_UNUSED_RESULT
MINLINE float len_v3v3(const float a[3], const float b[3]) ATTR_WARN_UNUSED_RESULT
MINLINE void sub_v3_v3v3(float r[3], const float a[3], const float b[3])
MINLINE void mul_v3_fl(float r[3], float f)
MINLINE void copy_v3_v3(float r[3], const float a[3])
MINLINE void add_v3_v3v3(float r[3], const float a[3], const float b[3])
MINLINE float normalize_v3_v3(float r[3], const float a[3])
size_t BLI_snprintf(char *__restrict dst, size_t dst_maxncpy, const char *__restrict format,...) ATTR_NONNULL(1
size_t BLI_str_escape(char *__restrict dst, const char *__restrict src, size_t dst_maxncpy) ATTR_NONNULL(1
unsigned int uint
void DEG_id_tag_update(ID *id, unsigned int flags)
@ ID_RECALC_TRANSFORM
Definition DNA_ID.h:1021
@ ID_RECALC_GEOMETRY
Definition DNA_ID.h:1041
@ ROT_MODE_QUAT
@ ROT_MODE_EUL
@ BONE_CONNECTED
@ KEY_RELATIVE
@ OB_EMPTY
@ OB_ARMATURE
@ OB_EMPTY_SPHERE
static Controller * controller
static double angle(const Eigen::Vector3d &v1, const Eigen::Vector3d &v2)
Definition IK_Math.h:125
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_to_edit(bArmature *arm)
SIMD_FORCE_INLINE btScalar length() const
Return the length of the vector.
Definition btVector3.h:257
void make_shape_keys(bContext *C)
void make_armatures(bContext *C, std::vector< Object * > &objects_to_scale)
void get_rna_path_for_joint(COLLADAFW::Node *node, char *joint_path, size_t joint_path_maxncpy)
bool write_skin_controller_data(const COLLADAFW::SkinControllerData *data)
bool write_controller(const COLLADAFW::Controller *controller)
void set_tags_map(TagsMap &tags_map)
ArmatureImporter(UnitConverter *conv, MeshImporterBase *mesh, Main *bmain, Scene *sce, ViewLayer *view_layer, const ImportSettings *import_settings)
Object * get_armature_for_joint(COLLADAFW::Node *node)
void add_root_joint(COLLADAFW::Node *node, Object *parent)
bool get_joint_bind_mat(float m[4][4], COLLADAFW::Node *joint)
COLLADAFW::UniqueId * get_geometry_uid(const COLLADAFW::UniqueId &controller_uid)
void set_use_connect(int use_connect)
void set_tail(const float vec[])
void set_leaf_bone(bool state)
BoneExtensionMap & getExtensionMap(bArmature *armature)
Class for saving <extra> tags for a specific UniqueId.
Definition ExtraTags.h:17
std::vector< std::string > dataSplitString(const std::string &tag)
bool setData(std::string tag, short *data)
Definition ExtraTags.cpp:68
virtual Object * get_object_by_geom_uid(const COLLADAFW::UniqueId &geom_uid)=0
virtual std::string * get_geometry_name(const std::string &mesh_name)=0
virtual Mesh * get_mesh_by_geom_uid(const COLLADAFW::UniqueId &mesh_uid)=0
Object * BKE_armature_from_object()
Definition SkinInfo.cpp:164
void get_node_mat(float mat[4][4], COLLADAFW::Node *node, std::map< COLLADAFW::UniqueId, Animation > *animation_map, Object *ob)
Object * bc_add_object(Main *bmain, Scene *scene, ViewLayer *view_layer, int type, const char *name)
bool bc_set_parent(Object *ob, Object *par, bContext *C, bool is_parent_space)
void bc_set_IDPropertyMatrix(EditBone *ebone, const char *key, float mat[4][4])
bool bc_is_leaf_bone(Bone *bone)
EditBone * bc_get_edit_bone(bArmature *armature, char *name)
std::map< std::string, BoneExtended * > BoneExtensionMap
local_group_size(16, 16) .push_constant(Type b
#define printf
OperationNode * node
#define rot(x, k)
#define FLT_MAX
Definition stdcycles.h:14
struct Bone * parent
char name[64]
float tail[3]
float head[3]
ListBase childbase
char name[64]
float tail[3]
EditBone * parent
float length
float head[3]
Definition DNA_ID.h:413
float curval
char type
void * first
struct Key * key
struct bPose * pose
char empty_drawtype
struct Bone * bone
struct Object * custom
float pose_mat[4][4]