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