| 
									
										
										
										
											2011-02-23 10:52:22 +00:00
										 |  |  | /*
 | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  |  * This program is free software; you can redistribute it and/or | 
					
						
							|  |  |  |  * modify it under the terms of the GNU General Public License | 
					
						
							|  |  |  |  * as published by the Free Software Foundation; either version 2 | 
					
						
							|  |  |  |  * of the License, or (at your option) any later version. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * This program is distributed in the hope that it will be useful, | 
					
						
							|  |  |  |  * but WITHOUT ANY WARRANTY; without even the implied warranty of | 
					
						
							|  |  |  |  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
					
						
							|  |  |  |  * GNU General Public License for more details. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * You should have received a copy of the GNU General Public License | 
					
						
							|  |  |  |  * along with this program; if not, write to the Free Software Foundation, | 
					
						
							|  |  |  |  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-02-18 08:08:12 +11:00
										 |  |  | /** \file
 | 
					
						
							|  |  |  |  * \ingroup collada | 
					
						
							| 
									
										
										
										
											2011-02-27 20:30:35 +00:00
										 |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-12 06:25:04 +00:00
										 |  |  | /* COLLADABU_ASSERT, may be able to remove later */ | 
					
						
							|  |  |  | #include "COLLADABUPlatform.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  | #include <algorithm>
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "COLLADAFWUniqueId.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "BKE_action.h"
 | 
					
						
							| 
									
										
										
										
											2011-08-16 16:03:37 +00:00
										 |  |  | #include "BKE_armature.h"
 | 
					
						
							| 
									
										
										
										
											2020-03-19 09:33:03 +01:00
										 |  |  | #include "BKE_object.h"
 | 
					
						
							| 
									
										
										
										
											2014-11-29 13:24:26 +01:00
										 |  |  | #include "BLI_listbase.h"
 | 
					
						
							| 
									
										
										
										
											2020-03-19 09:33:03 +01:00
										 |  |  | #include "BLI_string.h"
 | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  | #include "ED_armature.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-06 16:17:21 +02:00
										 |  |  | #include "DEG_depsgraph.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  | #include "ArmatureImporter.h"
 | 
					
						
							| 
									
										
										
										
											2020-03-19 09:33:03 +01:00
										 |  |  | #include "collada_utils.h"
 | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-30 13:41:21 +10:00
										 |  |  | /* use node name, or fall back to original id if not present (name is optional) */ | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  | template<class T> static const char *bc_get_joint_name(T *node) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2011-06-20 12:43:10 +00:00
										 |  |  |   const std::string &id = node->getName(); | 
					
						
							| 
									
										
										
										
											2020-07-03 14:59:27 +02:00
										 |  |  |   return id.empty() ? node->getOriginalId().c_str() : id.c_str(); | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-06-14 15:55:51 +02:00
										 |  |  | ArmatureImporter::ArmatureImporter(UnitConverter *conv, | 
					
						
							|  |  |  |                                    MeshImporterBase *mesh, | 
					
						
							|  |  |  |                                    Main *bmain, | 
					
						
							|  |  |  |                                    Scene *sce, | 
					
						
							|  |  |  |                                    ViewLayer *view_layer, | 
					
						
							|  |  |  |                                    const ImportSettings *import_settings) | 
					
						
							| 
									
										
										
										
											2016-09-24 01:47:55 +02:00
										 |  |  |     : TransformReader(conv), | 
					
						
							| 
									
										
										
										
											2018-06-14 15:15:51 +02:00
										 |  |  |       m_bmain(bmain), | 
					
						
							| 
									
										
										
										
											2016-09-24 01:27:37 +02:00
										 |  |  |       scene(sce), | 
					
						
							| 
									
										
										
										
											2018-01-26 13:13:54 +01:00
										 |  |  |       view_layer(view_layer), | 
					
						
							| 
									
										
										
										
											2013-07-30 07:22:40 +00:00
										 |  |  |       unit_converter(conv), | 
					
						
							| 
									
										
										
										
											2016-09-24 01:27:37 +02:00
										 |  |  |       import_settings(import_settings), | 
					
						
							| 
									
										
										
										
											2018-06-08 08:07:48 +02:00
										 |  |  |       empty(nullptr), | 
					
						
							| 
									
										
										
										
											2013-07-30 07:22:40 +00:00
										 |  |  |       mesh_importer(mesh) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2012-06-12 22:05:33 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | ArmatureImporter::~ArmatureImporter() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-30 13:41:21 +10:00
										 |  |  |   /* free skin controller data if we forget to do this earlier */ | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  |   std::map<COLLADAFW::UniqueId, SkinInfo>::iterator it; | 
					
						
							|  |  |  |   for (it = skin_by_data_uid.begin(); it != skin_by_data_uid.end(); it++) { | 
					
						
							|  |  |  |     it->second.free(); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #if 0
 | 
					
						
							|  |  |  | JointData *ArmatureImporter::get_joint_data(COLLADAFW::Node *node); | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-17 08:24:14 +02:00
										 |  |  |   const COLLADAFW::UniqueId &joint_id = node->getUniqueId(); | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |   if (joint_id_to_joint_index_map.find(joint_id) == joint_id_to_joint_index_map.end()) { | 
					
						
							| 
									
										
										
										
											2019-04-17 08:24:14 +02:00
										 |  |  |     fprintf( | 
					
						
							|  |  |  |         stderr, "Cannot find a joint index by joint id for %s.\n", node->getOriginalId().c_str()); | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  |     return NULL; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   int joint_index = joint_id_to_joint_index_map[joint_id]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return &joint_index_to_joint_info_map[joint_index]; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2011-06-28 19:30:00 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-29 13:24:26 +01:00
										 |  |  | int ArmatureImporter::create_bone(SkinInfo *skin, | 
					
						
							|  |  |  |                                   COLLADAFW::Node *node, | 
					
						
							|  |  |  |                                   EditBone *parent, | 
					
						
							|  |  |  |                                   int totchild, | 
					
						
							| 
									
										
										
										
											2016-05-29 00:35:50 +02:00
										 |  |  |                                   float parent_mat[4][4], | 
					
						
							|  |  |  |                                   bArmature *arm, | 
					
						
							|  |  |  |                                   std::vector<std::string> &layer_labels) | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2013-07-30 11:10:04 +00:00
										 |  |  |   float mat[4][4]; | 
					
						
							|  |  |  |   float joint_inv_bind_mat[4][4]; | 
					
						
							| 
									
										
										
										
											2017-03-23 00:07:05 +01:00
										 |  |  |   float joint_bind_mat[4][4]; | 
					
						
							| 
									
										
										
										
											2014-11-29 13:24:26 +01:00
										 |  |  |   int chain_length = 0; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-30 13:41:21 +10:00
										 |  |  |   /* Checking if bone is already made. */ | 
					
						
							| 
									
										
										
										
											2012-06-12 22:05:33 +00:00
										 |  |  |   std::vector<COLLADAFW::Node *>::iterator it; | 
					
						
							| 
									
										
										
										
											2012-04-29 15:47:02 +00:00
										 |  |  |   it = std::find(finished_joints.begin(), finished_joints.end(), node); | 
					
						
							| 
									
										
										
										
											2019-05-31 22:51:19 +10:00
										 |  |  |   if (it != finished_joints.end()) { | 
					
						
							| 
									
										
										
										
											2014-11-29 13:24:26 +01:00
										 |  |  |     return chain_length; | 
					
						
							| 
									
										
										
										
											2019-05-31 22:51:19 +10:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-04-15 11:57:49 +02:00
										 |  |  |   EditBone *bone = ED_armature_ebone_add(arm, bc_get_joint_name(node)); | 
					
						
							| 
									
										
										
										
											2011-08-17 20:15:40 +00:00
										 |  |  |   totbone++; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-03 18:26:12 +02:00
										 |  |  |   /*
 | 
					
						
							|  |  |  |    * We use the inv_bind_shape matrix to apply the armature bind pose as its rest pose. | 
					
						
							| 
									
										
										
										
											2018-09-02 18:28:27 +10:00
										 |  |  |    */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-03 18:26:12 +02:00
										 |  |  |   std::map<COLLADAFW::UniqueId, SkinInfo>::iterator skin_it; | 
					
						
							| 
									
										
										
										
											2017-03-14 15:07:31 +01:00
										 |  |  |   bool bone_is_skinned = false; | 
					
						
							| 
									
										
										
										
											2016-06-03 18:26:12 +02:00
										 |  |  |   for (skin_it = skin_by_data_uid.begin(); skin_it != skin_by_data_uid.end(); skin_it++) { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-03 18:26:12 +02:00
										 |  |  |     SkinInfo *b = &skin_it->second; | 
					
						
							|  |  |  |     if (b->get_joint_inv_bind_matrix(joint_inv_bind_mat, node)) { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-30 13:41:21 +10:00
										 |  |  |       /* get original world-space matrix */ | 
					
						
							| 
									
										
										
										
											2016-06-03 18:26:12 +02:00
										 |  |  |       invert_m4_m4(mat, joint_inv_bind_mat); | 
					
						
							| 
									
										
										
										
											2017-03-23 00:07:05 +01:00
										 |  |  |       copy_m4_m4(joint_bind_mat, mat); | 
					
						
							| 
									
										
										
										
											2019-04-30 13:41:21 +10:00
										 |  |  |       /* And make local to armature */ | 
					
						
							| 
									
										
										
										
											2016-06-03 18:26:12 +02:00
										 |  |  |       Object *ob_arm = skin->BKE_armature_from_object(); | 
					
						
							|  |  |  |       if (ob_arm) { | 
					
						
							|  |  |  |         float invmat[4][4]; | 
					
						
							|  |  |  |         invert_m4_m4(invmat, ob_arm->obmat); | 
					
						
							|  |  |  |         mul_m4_m4m4(mat, invmat, mat); | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-14 15:07:31 +01:00
										 |  |  |       bone_is_skinned = true; | 
					
						
							| 
									
										
										
										
											2016-06-03 18:26:12 +02:00
										 |  |  |       break; | 
					
						
							| 
									
										
										
										
											2013-07-30 11:10:04 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-30 13:41:21 +10:00
										 |  |  |   /* create a bone even if there's no joint data for it (i.e. it has no influence) */ | 
					
						
							| 
									
										
										
										
											2017-03-14 15:07:31 +01:00
										 |  |  |   if (!bone_is_skinned) { | 
					
						
							| 
									
										
										
										
											2017-03-21 18:05:10 +01:00
										 |  |  |     get_node_mat(mat, node, nullptr, nullptr, parent_mat); | 
					
						
							| 
									
										
										
										
											2011-08-17 20:15:40 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-31 22:51:19 +10:00
										 |  |  |   if (parent) { | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  |     bone->parent = parent; | 
					
						
							| 
									
										
										
										
											2019-05-31 22:51:19 +10:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-06-08 08:07:48 +02:00
										 |  |  |   float loc[3], size[3], rot[3][3]; | 
					
						
							| 
									
										
										
										
											2016-09-23 12:56:04 +02:00
										 |  |  |   BoneExtensionMap &extended_bones = bone_extension_manager.getExtensionMap(arm); | 
					
						
							|  |  |  |   BoneExtended &be = add_bone_extended(bone, node, totchild, layer_labels, extended_bones); | 
					
						
							| 
									
										
										
										
											2016-05-28 18:41:54 +02:00
										 |  |  |   int layer = be.get_bone_layers(); | 
					
						
							| 
									
										
										
										
											2019-05-31 22:51:19 +10:00
										 |  |  |   if (layer) { | 
					
						
							| 
									
										
										
										
											2016-05-28 18:41:54 +02:00
										 |  |  |     bone->layer = layer; | 
					
						
							| 
									
										
										
										
											2019-05-31 22:51:19 +10:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2016-05-28 18:41:54 +02:00
										 |  |  |   arm->layer |= layer; /* ensure that all populated bone layers are visible after import */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-26 17:40:56 +02:00
										 |  |  |   float *tail = be.get_tail(); | 
					
						
							|  |  |  |   int use_connect = be.get_use_connect(); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-26 17:40:56 +02:00
										 |  |  |   switch (use_connect) { | 
					
						
							| 
									
										
										
										
											2017-03-21 17:49:21 +01:00
										 |  |  |     case 1: | 
					
						
							|  |  |  |       bone->flag |= BONE_CONNECTED; | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  |     case -1: /* Connect type not specified */ | 
					
						
							|  |  |  |     case 0: | 
					
						
							|  |  |  |       bone->flag &= ~BONE_CONNECTED; | 
					
						
							|  |  |  |       break; | 
					
						
							| 
									
										
										
										
											2016-05-26 17:40:56 +02:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-28 18:41:54 +02:00
										 |  |  |   if (be.has_roll()) { | 
					
						
							|  |  |  |     bone->roll = be.get_roll(); | 
					
						
							| 
									
										
										
										
											2016-05-29 00:35:50 +02:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2016-05-28 18:41:54 +02:00
										 |  |  |   else { | 
					
						
							|  |  |  |     float angle; | 
					
						
							|  |  |  |     mat4_to_loc_rot_size(loc, rot, size, mat); | 
					
						
							|  |  |  |     mat3_to_vec_roll(rot, nullptr, &angle); | 
					
						
							| 
									
										
										
										
											2016-11-26 18:48:50 +01:00
										 |  |  |     bone->roll = angle; | 
					
						
							| 
									
										
										
										
											2016-05-28 18:41:54 +02:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  |   copy_v3_v3(bone->head, mat[3]); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-26 23:11:29 +01:00
										 |  |  |   if (bone_is_skinned && this->import_settings->keep_bind_info) { | 
					
						
							| 
									
										
										
										
											2017-03-23 00:07:05 +01:00
										 |  |  |     float rest_mat[4][4]; | 
					
						
							|  |  |  |     get_node_mat(rest_mat, node, nullptr, nullptr, nullptr); | 
					
						
							| 
									
										
										
										
											2017-03-23 14:10:57 +01:00
										 |  |  |     bc_set_IDPropertyMatrix(bone, "bind_mat", joint_bind_mat); | 
					
						
							|  |  |  |     bc_set_IDPropertyMatrix(bone, "rest_mat", rest_mat); | 
					
						
							| 
									
										
										
										
											2017-03-23 00:07:05 +01:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-30 13:41:21 +10:00
										 |  |  |   add_v3_v3v3(bone->tail, bone->head, tail); /* tail must be non zero */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-29 13:24:26 +01:00
										 |  |  |   /* find smallest bone length in armature (used later for leaf bone length) */ | 
					
						
							| 
									
										
										
										
											2013-07-17 20:22:08 +00:00
										 |  |  |   if (parent) { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-26 17:40:56 +02:00
										 |  |  |     if (use_connect == 1) { | 
					
						
							|  |  |  |       copy_v3_v3(parent->tail, bone->head); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-29 13:24:26 +01:00
										 |  |  |     /* guess reasonable leaf bone length */ | 
					
						
							| 
									
										
										
										
											2013-07-17 21:06:27 +00:00
										 |  |  |     float length = len_v3v3(parent->head, bone->head); | 
					
						
							| 
									
										
										
										
											2014-11-29 13:24:26 +01:00
										 |  |  |     if ((length < leaf_bone_length || totbone == 0) && length > MINIMUM_BONE_LENGTH) { | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  |       leaf_bone_length = length; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  |   COLLADAFW::NodePointerArray &children = node->getChildNodes(); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  |   for (unsigned int i = 0; i < children.getCount(); i++) { | 
					
						
							| 
									
										
										
										
											2016-05-29 00:35:50 +02:00
										 |  |  |     int cl = create_bone(skin, children[i], bone, children.getCount(), mat, arm, layer_labels); | 
					
						
							| 
									
										
										
										
											2019-05-31 22:51:19 +10:00
										 |  |  |     if (cl > chain_length) { | 
					
						
							| 
									
										
										
										
											2014-11-29 13:24:26 +01:00
										 |  |  |       chain_length = cl; | 
					
						
							| 
									
										
										
										
											2019-05-31 22:51:19 +10:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-01-21 13:45:49 +00:00
										 |  |  |   bone->length = len_v3v3(bone->head, bone->tail); | 
					
						
							| 
									
										
										
										
											2013-07-14 17:21:12 +00:00
										 |  |  |   joint_by_uid[node->getUniqueId()] = node; | 
					
						
							| 
									
										
										
										
											2011-08-21 15:47:21 +00:00
										 |  |  |   finished_joints.push_back(node); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-29 13:24:26 +01:00
										 |  |  |   be.set_chain_length(chain_length + 1); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-29 13:24:26 +01:00
										 |  |  |   return chain_length + 1; | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-29 13:24:26 +01:00
										 |  |  | /**
 | 
					
						
							| 
									
										
										
										
											2019-03-19 15:17:46 +11:00
										 |  |  |  * Collada only knows Joints, hence bones at the end of a bone chain | 
					
						
							|  |  |  |  * don't have a defined length. This function guesses reasonable | 
					
						
							|  |  |  |  * tail locations for the affected bones (nodes which don't have any connected child) | 
					
						
							|  |  |  |  * Hint: The extended_bones set gets populated in ArmatureImporter::create_bone | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2016-09-23 12:56:04 +02:00
										 |  |  | void ArmatureImporter::fix_leaf_bone_hierarchy(bArmature *armature, | 
					
						
							|  |  |  |                                                Bone *bone, | 
					
						
							|  |  |  |                                                bool fix_orientation) | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-05-31 22:51:19 +10:00
										 |  |  |   if (bone == nullptr) { | 
					
						
							| 
									
										
										
										
											2014-11-29 13:24:26 +01:00
										 |  |  |     return; | 
					
						
							| 
									
										
										
										
											2019-05-31 22:51:19 +10:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-26 18:22:36 +02:00
										 |  |  |   if (bc_is_leaf_bone(bone)) { | 
					
						
							| 
									
										
										
										
											2016-09-23 12:56:04 +02:00
										 |  |  |     BoneExtensionMap &extended_bones = bone_extension_manager.getExtensionMap(armature); | 
					
						
							| 
									
										
										
										
											2016-05-26 18:22:36 +02:00
										 |  |  |     BoneExtended *be = extended_bones[bone->name]; | 
					
						
							| 
									
										
										
										
											2016-09-23 12:56:04 +02:00
										 |  |  |     EditBone *ebone = bc_get_edit_bone(armature, bone->name); | 
					
						
							|  |  |  |     fix_leaf_bone(armature, ebone, be, fix_orientation); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-23 12:56:04 +02:00
										 |  |  |   for (Bone *child = (Bone *)bone->childbase.first; child; child = child->next) { | 
					
						
							|  |  |  |     fix_leaf_bone_hierarchy(armature, child, fix_orientation); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2014-12-01 20:31:42 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-23 12:56:04 +02:00
										 |  |  | void ArmatureImporter::fix_leaf_bone(bArmature *armature, | 
					
						
							|  |  |  |                                      EditBone *ebone, | 
					
						
							|  |  |  |                                      BoneExtended *be, | 
					
						
							|  |  |  |                                      bool fix_orientation) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   if (be == nullptr || !be->has_tail()) { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-23 12:56:04 +02:00
										 |  |  |     /* Collada only knows Joints, Here we guess a reasonable leaf bone length */ | 
					
						
							|  |  |  |     float leaf_length = (leaf_bone_length == FLT_MAX) ? 1.0 : leaf_bone_length; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-23 12:56:04 +02:00
										 |  |  |     float vec[3]; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-23 12:56:04 +02:00
										 |  |  |     if (fix_orientation && ebone->parent != nullptr) { | 
					
						
							|  |  |  |       EditBone *parent = ebone->parent; | 
					
						
							|  |  |  |       sub_v3_v3v3(vec, ebone->head, parent->head); | 
					
						
							|  |  |  |       if (len_squared_v3(vec) < MINIMUM_BONE_LENGTH) { | 
					
						
							|  |  |  |         sub_v3_v3v3(vec, parent->tail, parent->head); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2016-09-23 12:56:04 +02:00
										 |  |  |     } | 
					
						
							|  |  |  |     else { | 
					
						
							|  |  |  |       vec[2] = 0.1f; | 
					
						
							|  |  |  |       sub_v3_v3v3(vec, ebone->tail, ebone->head); | 
					
						
							| 
									
										
										
										
											2016-05-26 18:22:36 +02:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-23 12:56:04 +02:00
										 |  |  |     normalize_v3_v3(vec, vec); | 
					
						
							|  |  |  |     mul_v3_fl(vec, leaf_length); | 
					
						
							|  |  |  |     add_v3_v3v3(ebone->tail, ebone->head, vec); | 
					
						
							| 
									
										
										
										
											2014-11-29 13:24:26 +01:00
										 |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2013-07-26 22:19:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-26 17:40:56 +02:00
										 |  |  | void ArmatureImporter::fix_parent_connect(bArmature *armature, Bone *bone) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   /* armature has no bones */ | 
					
						
							| 
									
										
										
										
											2019-05-31 22:51:19 +10:00
										 |  |  |   if (bone == nullptr) { | 
					
						
							| 
									
										
										
										
											2016-05-26 17:40:56 +02:00
										 |  |  |     return; | 
					
						
							| 
									
										
										
										
											2019-05-31 22:51:19 +10:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2016-05-26 17:40:56 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |   if (bone->parent && bone->flag & BONE_CONNECTED) { | 
					
						
							|  |  |  |     copy_v3_v3(bone->parent->tail, bone->head); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-11 20:09:26 +01:00
										 |  |  |   for (Bone *child = (Bone *)bone->childbase.first; child; child = child->next) { | 
					
						
							| 
									
										
										
										
											2016-06-03 18:26:12 +02:00
										 |  |  |     fix_parent_connect(armature, child); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2016-05-26 17:40:56 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-04 20:59:13 +02:00
										 |  |  | void ArmatureImporter::connect_bone_chains(bArmature *armature, | 
					
						
							|  |  |  |                                            Bone *parentbone, | 
					
						
							|  |  |  |                                            int max_chain_length) | 
					
						
							| 
									
										
										
										
											2014-11-29 13:24:26 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2016-09-23 12:56:04 +02:00
										 |  |  |   BoneExtensionMap &extended_bones = bone_extension_manager.getExtensionMap(armature); | 
					
						
							| 
									
										
										
										
											2014-11-29 13:24:26 +01:00
										 |  |  |   BoneExtended *dominant_child = nullptr; | 
					
						
							|  |  |  |   int maxlen = 0; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-31 22:51:19 +10:00
										 |  |  |   if (parentbone == nullptr) { | 
					
						
							| 
									
										
										
										
											2015-10-12 11:35:08 +11:00
										 |  |  |     return; | 
					
						
							| 
									
										
										
										
											2019-05-31 22:51:19 +10:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-11 20:09:26 +01:00
										 |  |  |   Bone *child = (Bone *)parentbone->childbase.first; | 
					
						
							| 
									
										
										
										
											2015-10-12 11:35:08 +11:00
										 |  |  |   if (child && (import_settings->find_chains || child->next == nullptr)) { | 
					
						
							| 
									
										
										
										
											2015-01-11 21:03:15 +01:00
										 |  |  |     for (; child; child = child->next) { | 
					
						
							| 
									
										
										
										
											2014-11-29 13:24:26 +01:00
										 |  |  |       BoneExtended *be = extended_bones[child->name]; | 
					
						
							|  |  |  |       if (be != nullptr) { | 
					
						
							| 
									
										
										
										
											2017-03-21 17:13:31 +01:00
										 |  |  |         int chain_len = be->get_chain_length(); | 
					
						
							| 
									
										
										
										
											2020-09-04 20:59:13 +02:00
										 |  |  |         if (chain_len <= max_chain_length) { | 
					
						
							| 
									
										
										
										
											2017-03-21 17:13:31 +01:00
										 |  |  |           if (chain_len > maxlen) { | 
					
						
							| 
									
										
										
										
											2014-11-29 13:24:26 +01:00
										 |  |  |             dominant_child = be; | 
					
						
							| 
									
										
										
										
											2017-03-21 17:13:31 +01:00
										 |  |  |             maxlen = chain_len; | 
					
						
							| 
									
										
										
										
											2014-11-29 13:24:26 +01:00
										 |  |  |           } | 
					
						
							| 
									
										
										
										
											2017-03-21 17:13:31 +01:00
										 |  |  |           else if (chain_len == maxlen) { | 
					
						
							| 
									
										
										
										
											2014-11-29 13:24:26 +01:00
										 |  |  |             dominant_child = nullptr; | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-29 13:24:26 +01:00
										 |  |  |   BoneExtended *pbe = extended_bones[parentbone->name]; | 
					
						
							|  |  |  |   if (dominant_child != nullptr) { | 
					
						
							|  |  |  |     /* Found a valid chain. Now connect current bone with that chain.*/ | 
					
						
							| 
									
										
										
										
											2016-05-28 18:41:54 +02:00
										 |  |  |     EditBone *pebone = bc_get_edit_bone(armature, parentbone->name); | 
					
						
							|  |  |  |     EditBone *cebone = bc_get_edit_bone(armature, dominant_child->get_name()); | 
					
						
							| 
									
										
										
										
											2014-11-29 13:24:26 +01:00
										 |  |  |     if (pebone && !(cebone->flag & BONE_CONNECTED)) { | 
					
						
							|  |  |  |       float vec[3]; | 
					
						
							|  |  |  |       sub_v3_v3v3(vec, cebone->head, pebone->head); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-29 13:24:26 +01:00
										 |  |  |       /*
 | 
					
						
							|  |  |  |        * It is possible that the child's head is located on the parents head. | 
					
						
							|  |  |  |        * When this happens, then moving the parent's tail to the child's head | 
					
						
							| 
									
										
										
										
											2020-05-09 17:14:35 +10:00
										 |  |  |        * would result in a zero sized bone and Blender would silently remove the bone. | 
					
						
							| 
									
										
										
										
											2014-11-29 13:24:26 +01:00
										 |  |  |        * So we move the tail only when the resulting bone has a minimum length: | 
					
						
							|  |  |  |        */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-29 13:24:26 +01:00
										 |  |  |       if (len_squared_v3(vec) > MINIMUM_BONE_LENGTH) { | 
					
						
							| 
									
										
										
										
											2017-03-21 17:10:19 +01:00
										 |  |  |         copy_v3_v3(pebone->tail, cebone->head); | 
					
						
							| 
									
										
										
										
											2017-03-21 17:24:39 +01:00
										 |  |  |         pbe->set_tail(pebone->tail); /* to make fix_leafbone happy ...*/ | 
					
						
							| 
									
										
										
										
											2014-11-29 13:24:26 +01:00
										 |  |  |         if (pbe && pbe->get_chain_length() >= this->import_settings->min_chain_length) { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-21 17:24:39 +01:00
										 |  |  |           BoneExtended *cbe = extended_bones[cebone->name]; | 
					
						
							|  |  |  |           cbe->set_use_connect(true); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-29 13:24:26 +01:00
										 |  |  |           cebone->flag |= BONE_CONNECTED; | 
					
						
							|  |  |  |           pbe->set_leaf_bone(false); | 
					
						
							| 
									
										
										
										
											2017-03-21 17:24:39 +01:00
										 |  |  |           printf("Connect Bone chain: parent (%s --> %s) child)\n", pebone->name, cebone->name); | 
					
						
							| 
									
										
										
										
											2014-11-29 13:24:26 +01:00
										 |  |  |         } | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2018-03-11 20:09:26 +01:00
										 |  |  |     for (Bone *ch = (Bone *)parentbone->childbase.first; ch; ch = ch->next) { | 
					
						
							|  |  |  |       ArmatureImporter::connect_bone_chains(armature, ch, UNLIMITED_CHAIN_MAX); | 
					
						
							| 
									
										
										
										
											2014-11-29 13:24:26 +01:00
										 |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   else if (maxlen > 1 && maxlen > this->import_settings->min_chain_length) { | 
					
						
							|  |  |  |     /* Try again with smaller chain length */ | 
					
						
							|  |  |  |     ArmatureImporter::connect_bone_chains(armature, parentbone, maxlen - 1); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   else { | 
					
						
							|  |  |  |     /* can't connect this Bone. Proceed with children ... */ | 
					
						
							| 
									
										
										
										
											2019-05-31 22:51:19 +10:00
										 |  |  |     if (pbe) { | 
					
						
							| 
									
										
										
										
											2014-11-29 13:24:26 +01:00
										 |  |  |       pbe->set_leaf_bone(true); | 
					
						
							| 
									
										
										
										
											2019-05-31 22:51:19 +10:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2018-03-11 20:09:26 +01:00
										 |  |  |     for (Bone *ch = (Bone *)parentbone->childbase.first; ch; ch = ch->next) { | 
					
						
							|  |  |  |       ArmatureImporter::connect_bone_chains(armature, ch, UNLIMITED_CHAIN_MAX); | 
					
						
							| 
									
										
										
										
											2013-02-01 15:17:51 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-12-21 10:43:47 +00:00
										 |  |  | #if 0
 | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  | void ArmatureImporter::set_leaf_bone_shapes(Object *ob_arm) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   bPose *pose = ob_arm->pose; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  |   std::vector<LeafBone>::iterator it; | 
					
						
							|  |  |  |   for (it = leaf_bones.begin(); it != leaf_bones.end(); it++) { | 
					
						
							| 
									
										
										
										
											2019-04-17 08:24:14 +02:00
										 |  |  |     LeafBone &leaf = *it; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-05 16:03:57 +00:00
										 |  |  |     bPoseChannel *pchan = BKE_pose_channel_find_name(pose, leaf.name); | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  |     if (pchan) { | 
					
						
							|  |  |  |       pchan->custom = get_empty_for_leaves(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else { | 
					
						
							|  |  |  |       fprintf(stderr, "Cannot find a pose channel for leaf bone %s\n", leaf.name); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void ArmatureImporter::set_euler_rotmode() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-30 13:41:21 +10:00
										 |  |  |   /* just set rotmode = ROT_MODE_EUL on pose channel for each joint */ | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-06-12 22:05:33 +00:00
										 |  |  |   std::map<COLLADAFW::UniqueId, COLLADAFW::Node *>::iterator it; | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |   for (it = joint_by_uid.begin(); it != joint_by_uid.end(); it++) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     COLLADAFW::Node *joint = it->second; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     std::map<COLLADAFW::UniqueId, SkinInfo>::iterator sit; | 
					
						
							| 
									
										
										
										
											2018-06-08 08:07:48 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  |     for (sit = skin_by_data_uid.begin(); sit != skin_by_data_uid.end(); sit++) { | 
					
						
							| 
									
										
										
										
											2019-04-17 08:24:14 +02:00
										 |  |  |       SkinInfo &skin = sit->second; | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |       if (skin.uses_joint_or_descendant(joint)) { | 
					
						
							|  |  |  |         bPoseChannel *pchan = skin.get_pose_channel_from_node(joint); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (pchan) { | 
					
						
							|  |  |  |           pchan->rotmode = ROT_MODE_EUL; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         else { | 
					
						
							|  |  |  |           fprintf(stderr, "Cannot find pose channel for %s.\n", get_joint_name(joint)); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Object *ArmatureImporter::get_empty_for_leaves() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2019-05-31 22:51:19 +10:00
										 |  |  |   if (empty) { | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  |     return empty; | 
					
						
							| 
									
										
										
										
											2019-05-31 22:51:19 +10:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2018-06-08 08:07:48 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-06-14 15:55:51 +02:00
										 |  |  |   empty = bc_add_object(m_bmain, scene, view_layer, OB_EMPTY, nullptr); | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  |   empty->empty_drawtype = OB_EMPTY_SPHERE; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return empty; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #if 0
 | 
					
						
							|  |  |  | Object *ArmatureImporter::find_armature(COLLADAFW::Node *node) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2012-06-12 22:05:33 +00:00
										 |  |  |   JointData *jd = get_joint_data(node); | 
					
						
							| 
									
										
										
										
											2019-05-31 23:21:16 +10:00
										 |  |  |   if (jd) { | 
					
						
							| 
									
										
										
										
											2019-04-17 08:24:14 +02:00
										 |  |  |     return jd->ob_arm; | 
					
						
							| 
									
										
										
										
											2019-05-31 23:21:16 +10:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 08:24:14 +02:00
										 |  |  |   COLLADAFW::NodePointerArray &children = node->getChildNodes(); | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  |   for (int i = 0; i < children.getCount(); i++) { | 
					
						
							|  |  |  |     Object *ob_arm = find_armature(children[i]); | 
					
						
							| 
									
										
										
										
											2019-05-31 23:21:16 +10:00
										 |  |  |     if (ob_arm) { | 
					
						
							| 
									
										
										
										
											2019-04-17 08:24:14 +02:00
										 |  |  |       return ob_arm; | 
					
						
							| 
									
										
										
										
											2019-05-31 23:21:16 +10:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return NULL; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 08:24:14 +02:00
										 |  |  | ArmatureJoints &ArmatureImporter::get_armature_joints(Object *ob_arm) | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-30 13:41:21 +10:00
										 |  |  |   /* try finding it */ | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  |   std::vector<ArmatureJoints>::iterator it; | 
					
						
							|  |  |  |   for (it = armature_joints.begin(); it != armature_joints.end(); it++) { | 
					
						
							| 
									
										
										
										
											2019-05-31 23:21:16 +10:00
										 |  |  |     if ((*it).ob_arm == ob_arm) { | 
					
						
							| 
									
										
										
										
											2019-04-17 08:24:14 +02:00
										 |  |  |       return *it; | 
					
						
							| 
									
										
										
										
											2019-05-31 23:21:16 +10:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-30 13:41:21 +10:00
										 |  |  |   /* not found, create one */ | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  |   ArmatureJoints aj; | 
					
						
							|  |  |  |   aj.ob_arm = ob_arm; | 
					
						
							|  |  |  |   armature_joints.push_back(aj); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  |   return armature_joints.back(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2020-09-04 20:59:13 +02:00
										 |  |  | void ArmatureImporter::create_armature_bones(Main *bmain, std::vector<Object *> &arm_objs) | 
					
						
							| 
									
										
										
										
											2011-06-17 18:41:43 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2012-06-12 22:05:33 +00:00
										 |  |  |   std::vector<COLLADAFW::Node *>::iterator ri; | 
					
						
							| 
									
										
										
										
											2016-05-29 00:35:50 +02:00
										 |  |  |   std::vector<std::string> layer_labels; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-30 13:41:21 +10:00
										 |  |  |   /* if there is an armature created for root_joint next root_joint */ | 
					
						
							| 
									
										
										
										
											2011-08-17 20:15:40 +00:00
										 |  |  |   for (ri = root_joints.begin(); ri != root_joints.end(); ri++) { | 
					
						
							| 
									
										
										
										
											2019-06-02 23:33:22 +02:00
										 |  |  |     COLLADAFW::Node *node = *ri; | 
					
						
							|  |  |  |     if (get_armature_for_joint(node) != nullptr) { | 
					
						
							| 
									
										
										
										
											2012-06-12 22:05:33 +00:00
										 |  |  |       continue; | 
					
						
							| 
									
										
										
										
											2019-05-31 22:51:19 +10:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-02 23:33:22 +02:00
										 |  |  |     Object *ob_arm = joint_parent_map[node->getUniqueId()]; | 
					
						
							| 
									
										
										
										
											2019-05-31 22:51:19 +10:00
										 |  |  |     if (!ob_arm) { | 
					
						
							| 
									
										
										
										
											2012-03-04 13:43:23 +00:00
										 |  |  |       continue; | 
					
						
							| 
									
										
										
										
											2019-05-31 22:51:19 +10:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-11 08:49:28 +11:00
										 |  |  |     bArmature *armature = (bArmature *)ob_arm->data; | 
					
						
							| 
									
										
										
										
											2019-05-31 22:51:19 +10:00
										 |  |  |     if (!armature) { | 
					
						
							| 
									
										
										
										
											2014-02-27 15:23:18 +01:00
										 |  |  |       continue; | 
					
						
							| 
									
										
										
										
											2019-05-31 22:51:19 +10:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-02 23:33:22 +02:00
										 |  |  |     char *bone_name = (char *)bc_get_joint_name(node); | 
					
						
							| 
									
										
										
										
											2014-02-27 15:23:18 +01:00
										 |  |  |     Bone *bone = BKE_armature_find_bone_name(armature, bone_name); | 
					
						
							| 
									
										
										
										
											2014-03-31 05:45:28 +11:00
										 |  |  |     if (bone) { | 
					
						
							| 
									
										
										
										
											2014-02-27 15:23:18 +01:00
										 |  |  |       fprintf(stderr, | 
					
						
							|  |  |  |               "Reuse of child bone [%s] as root bone in same Armature is not supported.\n", | 
					
						
							|  |  |  |               bone_name); | 
					
						
							|  |  |  |       continue; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-27 15:23:18 +01:00
										 |  |  |     ED_armature_to_edit(armature); | 
					
						
							| 
									
										
										
										
											2016-05-28 18:41:54 +02:00
										 |  |  |     armature->layer = 0; /* layer is set according to imported bone set in create_bone() */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-02 23:33:22 +02:00
										 |  |  |     create_bone( | 
					
						
							|  |  |  |         nullptr, node, nullptr, node->getChildNodes().getCount(), nullptr, armature, layer_labels); | 
					
						
							| 
									
										
										
										
											2016-09-23 12:56:04 +02:00
										 |  |  |     if (this->import_settings->find_chains) { | 
					
						
							|  |  |  |       connect_bone_chains(armature, (Bone *)armature->bonebase.first, UNLIMITED_CHAIN_MAX); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-29 13:24:26 +01:00
										 |  |  |     /* exit armature edit mode to populate the Armature object */ | 
					
						
							| 
									
										
										
										
											2018-06-06 15:50:24 +02:00
										 |  |  |     ED_armature_from_edit(bmain, armature); | 
					
						
							| 
									
										
										
										
											2016-09-23 12:56:04 +02:00
										 |  |  |     ED_armature_edit_free(armature); | 
					
						
							|  |  |  |     ED_armature_to_edit(armature); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-23 12:56:04 +02:00
										 |  |  |     fix_leaf_bone_hierarchy( | 
					
						
							|  |  |  |         armature, (Bone *)armature->bonebase.first, this->import_settings->fix_orientation); | 
					
						
							| 
									
										
										
										
											2019-06-02 23:33:22 +02:00
										 |  |  |     unskinned_armature_map[node->getUniqueId()] = ob_arm; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-06-06 15:50:24 +02:00
										 |  |  |     ED_armature_from_edit(bmain, armature); | 
					
						
							| 
									
										
										
										
											2014-11-29 13:24:26 +01:00
										 |  |  |     ED_armature_edit_free(armature); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-04 10:51:48 +10:00
										 |  |  |     set_bone_transformation_type(node, ob_arm); | 
					
						
							| 
									
										
										
										
											2019-06-02 23:33:22 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-04 20:59:13 +02:00
										 |  |  |     int index = std::find(arm_objs.begin(), arm_objs.end(), ob_arm) - arm_objs.begin(); | 
					
						
							| 
									
										
										
										
											2016-06-03 18:26:12 +02:00
										 |  |  |     if (index == 0) { | 
					
						
							| 
									
										
										
										
											2020-09-04 20:59:13 +02:00
										 |  |  |       arm_objs.push_back(ob_arm); | 
					
						
							| 
									
										
										
										
											2016-05-26 17:40:56 +02:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-06 17:52:37 +01:00
										 |  |  |     DEG_id_tag_update(&ob_arm->id, ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY); | 
					
						
							| 
									
										
										
										
											2011-06-17 18:41:43 +00:00
										 |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-06-06 15:50:24 +02:00
										 |  |  | Object *ArmatureImporter::create_armature_bones(Main *bmain, SkinInfo &skin) | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-30 13:41:21 +10:00
										 |  |  |   /* just do like so:
 | 
					
						
							|  |  |  |    * - get armature | 
					
						
							|  |  |  |    * - enter editmode | 
					
						
							|  |  |  |    * - add edit bones and head/tail properties using matrices and parent-child info | 
					
						
							|  |  |  |    * - exit edit mode | 
					
						
							|  |  |  |    * - set a sphere shape to leaf bones */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  |   Object *ob_arm = nullptr; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  |   /*
 | 
					
						
							|  |  |  |    * find if there's another skin sharing at least one bone with this skin | 
					
						
							|  |  |  |    * if so, use that skin's armature | 
					
						
							|  |  |  |    */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-02 18:28:27 +10:00
										 |  |  |   /**
 | 
					
						
							| 
									
										
										
										
											2020-03-22 12:09:48 +11:00
										 |  |  |    * Pseudo-code: | 
					
						
							|  |  |  |    * <pre> | 
					
						
							| 
									
										
										
										
											2018-09-02 18:28:27 +10:00
										 |  |  |    * find_node_in_tree(node, root_joint) | 
					
						
							|  |  |  |    * | 
					
						
							|  |  |  |    * skin::find_root_joints(root_joints): | 
					
						
							|  |  |  |    *     std::vector root_joints; | 
					
						
							|  |  |  |    *     for each root in root_joints: | 
					
						
							|  |  |  |    *         for each joint in joints: | 
					
						
							|  |  |  |    *             if find_node_in_tree(joint, root): | 
					
						
							| 
									
										
										
										
											2019-04-30 13:41:21 +10:00
										 |  |  |    *                 if (std::find(root_joints.begin(), root_joints.end(), root) == | 
					
						
							|  |  |  |    * root_joints.end()) root_joints.push_back(root); | 
					
						
							| 
									
										
										
										
											2018-09-02 18:28:27 +10:00
										 |  |  |    * | 
					
						
							|  |  |  |    * for (each skin B with armature) { | 
					
						
							|  |  |  |    *     find all root joints for skin B | 
					
						
							|  |  |  |    * | 
					
						
							|  |  |  |    *     for each joint X in skin A: | 
					
						
							|  |  |  |    *         for each root joint R in skin B: | 
					
						
							|  |  |  |    *             if (find_node_in_tree(X, R)) { | 
					
						
							|  |  |  |    *                 shared = 1; | 
					
						
							|  |  |  |    *                 goto endloop; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |    *             } | 
					
						
							| 
									
										
										
										
											2018-09-02 18:28:27 +10:00
										 |  |  |    * } | 
					
						
							|  |  |  |    * | 
					
						
							|  |  |  |    * endloop: | 
					
						
							| 
									
										
										
										
											2020-03-22 12:09:48 +11:00
										 |  |  |    * </pre> | 
					
						
							| 
									
										
										
										
											2018-09-02 18:28:27 +10:00
										 |  |  |    */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  |   SkinInfo *a = &skin; | 
					
						
							|  |  |  |   Object *shared = nullptr; | 
					
						
							| 
									
										
										
										
											2012-06-12 22:05:33 +00:00
										 |  |  |   std::vector<COLLADAFW::Node *> skin_root_joints; | 
					
						
							| 
									
										
										
										
											2016-05-29 00:35:50 +02:00
										 |  |  |   std::vector<std::string> layer_labels; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  |   std::map<COLLADAFW::UniqueId, SkinInfo>::iterator it; | 
					
						
							|  |  |  |   for (it = skin_by_data_uid.begin(); it != skin_by_data_uid.end(); it++) { | 
					
						
							|  |  |  |     SkinInfo *b = &it->second; | 
					
						
							| 
									
										
										
										
											2019-05-31 22:51:19 +10:00
										 |  |  |     if (b == a || b->BKE_armature_from_object() == nullptr) { | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  |       continue; | 
					
						
							| 
									
										
										
										
											2019-05-31 22:51:19 +10:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  |     skin_root_joints.clear(); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  |     b->find_root_joints(root_joints, joint_by_uid, skin_root_joints); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-06-12 22:05:33 +00:00
										 |  |  |     std::vector<COLLADAFW::Node *>::iterator ri; | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  |     for (ri = skin_root_joints.begin(); ri != skin_root_joints.end(); ri++) { | 
					
						
							| 
									
										
										
										
											2019-06-02 23:33:22 +02:00
										 |  |  |       COLLADAFW::Node *node = *ri; | 
					
						
							|  |  |  |       if (a->uses_joint_or_descendant(node)) { | 
					
						
							| 
									
										
										
										
											2012-05-05 16:03:57 +00:00
										 |  |  |         shared = b->BKE_armature_from_object(); | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  |         break; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-31 22:51:19 +10:00
										 |  |  |     if (shared != nullptr) { | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  |       break; | 
					
						
							| 
									
										
										
										
											2019-05-31 22:51:19 +10:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-03 14:59:27 +02:00
										 |  |  |   if (!shared && !this->joint_parent_map.empty()) { | 
					
						
							| 
									
										
										
										
											2019-04-30 13:41:21 +10:00
										 |  |  |     /* All armatures have been created while creating the Node tree.
 | 
					
						
							|  |  |  |      * The Collada exporter currently does not create a | 
					
						
							|  |  |  |      * strict relationship between geometries and armatures | 
					
						
							|  |  |  |      * So when we reimport a Blender collada file, then we have | 
					
						
							|  |  |  |      * to guess what is meant. | 
					
						
							|  |  |  |      * XXX This is not safe when we have more than one armatures | 
					
						
							|  |  |  |      * in the import. */ | 
					
						
							| 
									
										
										
										
											2013-02-17 18:33:10 +00:00
										 |  |  |     shared = this->joint_parent_map.begin()->second; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-02-17 18:33:10 +00:00
										 |  |  |   if (shared) { | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  |     ob_arm = skin.set_armature(shared); | 
					
						
							| 
									
										
										
										
											2013-02-17 18:33:10 +00:00
										 |  |  |   } | 
					
						
							|  |  |  |   else { | 
					
						
							| 
									
										
										
										
											2019-04-30 13:41:21 +10:00
										 |  |  |     ob_arm = skin.create_armature(m_bmain, scene, view_layer); /* once for every armature */ | 
					
						
							| 
									
										
										
										
											2013-02-17 18:33:10 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-30 13:41:21 +10:00
										 |  |  |   /* enter armature edit mode */ | 
					
						
							| 
									
										
										
										
											2018-10-11 08:49:28 +11:00
										 |  |  |   bArmature *armature = (bArmature *)ob_arm->data; | 
					
						
							| 
									
										
										
										
											2014-11-29 13:24:26 +01:00
										 |  |  |   ED_armature_to_edit(armature); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  |   totbone = 0; | 
					
						
							| 
									
										
										
										
											2019-04-30 13:41:21 +10:00
										 |  |  |   // bone_direction_row = 1; /* TODO: don't default to Y but use asset and based on it decide on */
 | 
					
						
							|  |  |  |   /* default row */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-30 13:41:21 +10:00
										 |  |  |   /* create bones */ | 
					
						
							| 
									
										
										
										
											2019-04-18 07:21:26 +02:00
										 |  |  |   /* TODO:
 | 
					
						
							|  |  |  |    * check if bones have already been created for a given joint */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-06-12 22:05:33 +00:00
										 |  |  |   std::vector<COLLADAFW::Node *>::iterator ri; | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  |   for (ri = root_joints.begin(); ri != root_joints.end(); ri++) { | 
					
						
							| 
									
										
										
										
											2019-06-02 23:33:22 +02:00
										 |  |  |     COLLADAFW::Node *node = *ri; | 
					
						
							| 
									
										
										
										
											2019-04-30 13:41:21 +10:00
										 |  |  |     /* for shared armature check if bone tree is already created */ | 
					
						
							| 
									
										
										
										
											2019-06-02 23:33:22 +02:00
										 |  |  |     if (shared && std::find(skin_root_joints.begin(), skin_root_joints.end(), node) != | 
					
						
							| 
									
										
										
										
											2019-05-31 22:51:19 +10:00
										 |  |  |                       skin_root_joints.end()) { | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  |       continue; | 
					
						
							| 
									
										
										
										
											2019-05-31 22:51:19 +10:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-30 13:41:21 +10:00
										 |  |  |     /* since root_joints may contain joints for multiple controllers, we need to filter */ | 
					
						
							| 
									
										
										
										
											2019-06-02 23:33:22 +02:00
										 |  |  |     if (skin.uses_joint_or_descendant(node)) { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-29 00:35:50 +02:00
										 |  |  |       create_bone( | 
					
						
							| 
									
										
										
										
											2019-06-02 23:33:22 +02:00
										 |  |  |           &skin, node, nullptr, node->getChildNodes().getCount(), nullptr, armature, layer_labels); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-02 23:33:22 +02:00
										 |  |  |       if (joint_parent_map.find(node->getUniqueId()) != joint_parent_map.end() && | 
					
						
							| 
									
										
										
										
											2019-05-31 22:51:19 +10:00
										 |  |  |           !skin.get_parent()) { | 
					
						
							| 
									
										
										
										
											2019-06-02 23:33:22 +02:00
										 |  |  |         skin.set_parent(joint_parent_map[node->getUniqueId()]); | 
					
						
							| 
									
										
										
										
											2019-05-31 22:51:19 +10:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-29 13:24:26 +01:00
										 |  |  |   /* exit armature edit mode to populate the Armature object */ | 
					
						
							| 
									
										
										
										
											2018-06-06 15:50:24 +02:00
										 |  |  |   ED_armature_from_edit(bmain, armature); | 
					
						
							| 
									
										
										
										
											2014-11-29 13:24:26 +01:00
										 |  |  |   ED_armature_edit_free(armature); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-02 19:06:14 +02:00
										 |  |  |   for (ri = root_joints.begin(); ri != root_joints.end(); ri++) { | 
					
						
							|  |  |  |     COLLADAFW::Node *node = *ri; | 
					
						
							|  |  |  |     set_bone_transformation_type(node, ob_arm); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-23 12:56:04 +02:00
										 |  |  |   ED_armature_to_edit(armature); | 
					
						
							|  |  |  |   if (this->import_settings->find_chains) { | 
					
						
							|  |  |  |     connect_bone_chains(armature, (Bone *)armature->bonebase.first, UNLIMITED_CHAIN_MAX); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   fix_leaf_bone_hierarchy( | 
					
						
							|  |  |  |       armature, (Bone *)armature->bonebase.first, this->import_settings->fix_orientation); | 
					
						
							| 
									
										
										
										
											2018-06-06 15:50:24 +02:00
										 |  |  |   ED_armature_from_edit(bmain, armature); | 
					
						
							| 
									
										
										
										
											2016-09-23 12:56:04 +02:00
										 |  |  |   ED_armature_edit_free(armature); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-06 17:52:37 +01:00
										 |  |  |   DEG_id_tag_update(&ob_arm->id, ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-03 18:26:12 +02:00
										 |  |  |   return ob_arm; | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-02 19:06:14 +02:00
										 |  |  | void ArmatureImporter::set_bone_transformation_type(const COLLADAFW::Node *node, Object *ob_arm) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   bPoseChannel *pchan = BKE_pose_channel_find_name(ob_arm->pose, bc_get_joint_name(node)); | 
					
						
							|  |  |  |   if (pchan) { | 
					
						
							|  |  |  |     pchan->rotmode = (node_is_decomposed(node)) ? ROT_MODE_EUL : ROT_MODE_QUAT; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   COLLADAFW::NodePointerArray childnodes = node->getChildNodes(); | 
					
						
							|  |  |  |   for (int index = 0; index < childnodes.getCount(); index++) { | 
					
						
							|  |  |  |     node = childnodes[index]; | 
					
						
							|  |  |  |     set_bone_transformation_type(node, ob_arm); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-12-11 14:29:01 +00:00
										 |  |  | void ArmatureImporter::set_pose(Object *ob_arm, | 
					
						
							|  |  |  |                                 COLLADAFW::Node *root_node, | 
					
						
							|  |  |  |                                 const char *parentname, | 
					
						
							|  |  |  |                                 float parent_mat[4][4]) | 
					
						
							| 
									
										
										
										
											2018-04-15 11:57:49 +02:00
										 |  |  | { | 
					
						
							|  |  |  |   const char *bone_name = bc_get_joint_name(root_node); | 
					
						
							| 
									
										
										
										
											2011-06-26 18:56:06 +00:00
										 |  |  |   float mat[4][4]; | 
					
						
							| 
									
										
										
										
											2012-03-24 07:36:32 +00:00
										 |  |  |   float obmat[4][4]; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-30 13:41:21 +10:00
										 |  |  |   /* object-space */ | 
					
						
							| 
									
										
										
										
											2011-06-26 18:56:06 +00:00
										 |  |  |   get_node_mat(obmat, root_node, nullptr, nullptr); | 
					
						
							| 
									
										
										
										
											2019-06-02 19:06:14 +02:00
										 |  |  |   bool is_decomposed = node_is_decomposed(root_node); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-30 13:41:21 +10:00
										 |  |  |   // if (*edbone)
 | 
					
						
							| 
									
										
										
										
											2012-06-12 22:05:33 +00:00
										 |  |  |   bPoseChannel *pchan = BKE_pose_channel_find_name(ob_arm->pose, bone_name); | 
					
						
							| 
									
										
										
										
											2019-06-02 19:06:14 +02:00
										 |  |  |   pchan->rotmode = (is_decomposed) ? ROT_MODE_EUL : ROT_MODE_QUAT; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-30 13:41:21 +10:00
										 |  |  |   // else fprintf ( "",
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-30 13:41:21 +10:00
										 |  |  |   /* get world-space */ | 
					
						
							| 
									
										
										
										
											2012-03-28 05:03:24 +00:00
										 |  |  |   if (parentname) { | 
					
						
							| 
									
										
										
										
											2013-05-26 18:36:25 +00:00
										 |  |  |     mul_m4_m4m4(mat, parent_mat, obmat); | 
					
						
							| 
									
										
										
										
											2012-05-05 16:03:57 +00:00
										 |  |  |     bPoseChannel *parchan = BKE_pose_channel_find_name(ob_arm->pose, parentname); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-05-26 18:36:25 +00:00
										 |  |  |     mul_m4_m4m4(pchan->pose_mat, parchan->pose_mat, mat); | 
					
						
							| 
									
										
										
										
											2011-06-26 18:56:06 +00:00
										 |  |  |   } | 
					
						
							|  |  |  |   else { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-06-26 18:56:06 +00:00
										 |  |  |     copy_m4_m4(mat, obmat); | 
					
						
							| 
									
										
										
										
											2011-11-11 13:09:14 +00:00
										 |  |  |     float invObmat[4][4]; | 
					
						
							|  |  |  |     invert_m4_m4(invObmat, ob_arm->obmat); | 
					
						
							| 
									
										
										
										
											2013-05-26 18:36:25 +00:00
										 |  |  |     mul_m4_m4m4(pchan->pose_mat, invObmat, mat); | 
					
						
							| 
									
										
										
										
											2011-06-26 18:56:06 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-18 07:21:26 +02:00
										 |  |  | #if 0
 | 
					
						
							|  |  |  |   float angle = 0.0f; | 
					
						
							|  |  |  |   mat4_to_axis_angle(ax, &angle, mat); | 
					
						
							|  |  |  |   pchan->bone->roll = angle; | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-11-11 13:09:14 +00:00
										 |  |  |   COLLADAFW::NodePointerArray &children = root_node->getChildNodes(); | 
					
						
							| 
									
										
										
										
											2011-06-26 18:56:06 +00:00
										 |  |  |   for (unsigned int i = 0; i < children.getCount(); i++) { | 
					
						
							|  |  |  |     set_pose(ob_arm, children[i], bone_name, mat); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2011-06-26 15:35:02 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-02 19:06:14 +02:00
										 |  |  | bool ArmatureImporter::node_is_decomposed(const COLLADAFW::Node *node) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   const COLLADAFW::TransformationPointerArray &nodeTransforms = node->getTransformations(); | 
					
						
							|  |  |  |   for (unsigned int i = 0; i < nodeTransforms.getCount(); i++) { | 
					
						
							|  |  |  |     COLLADAFW::Transformation *transform = nodeTransforms[i]; | 
					
						
							|  |  |  |     COLLADAFW::Transformation::TransformationType tm_type = transform->getTransformationType(); | 
					
						
							|  |  |  |     if (tm_type == COLLADAFW::Transformation::MATRIX) { | 
					
						
							|  |  |  |       return false; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   return true; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-29 13:24:26 +01:00
										 |  |  | /**
 | 
					
						
							| 
									
										
										
										
											2019-03-19 15:17:46 +11:00
										 |  |  |  * root - if this joint is the top joint in hierarchy, if a joint | 
					
						
							|  |  |  |  * is a child of a node (not joint), root should be true since | 
					
						
							|  |  |  |  * this is where we build armature bones from | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2013-07-14 17:21:12 +00:00
										 |  |  | void ArmatureImporter::add_root_joint(COLLADAFW::Node *node, Object *parent) | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2013-07-14 17:21:12 +00:00
										 |  |  |   root_joints.push_back(node); | 
					
						
							|  |  |  |   if (parent) { | 
					
						
							|  |  |  |     joint_parent_map[node->getUniqueId()] = parent; | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #if 0
 | 
					
						
							|  |  |  | void ArmatureImporter::add_root_joint(COLLADAFW::Node *node) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   // root_joints.push_back(node);
 | 
					
						
							|  |  |  |   Object *ob_arm = find_armature(node); | 
					
						
							| 
									
										
										
										
											2012-06-12 22:05:33 +00:00
										 |  |  |   if (ob_arm) { | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  |     get_armature_joints(ob_arm).root_joints.push_back(node); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | #  ifdef COLLADA_DEBUG
 | 
					
						
							|  |  |  |   else { | 
					
						
							|  |  |  |     fprintf(stderr, "%s cannot be added to armature.\n", get_joint_name(node)); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | #  endif
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-30 13:41:21 +10:00
										 |  |  | /* here we add bones to armatures, having armatures previously created in write_controller */ | 
					
						
							| 
									
										
										
										
											2016-06-03 18:26:12 +02:00
										 |  |  | void ArmatureImporter::make_armatures(bContext *C, std::vector<Object *> &objects_to_scale) | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2018-06-06 15:50:24 +02:00
										 |  |  |   Main *bmain = CTX_data_main(C); | 
					
						
							| 
									
										
										
										
											2020-09-04 20:59:13 +02:00
										 |  |  |   std::vector<Object *> arm_objs; | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  |   std::map<COLLADAFW::UniqueId, SkinInfo>::iterator it; | 
					
						
							| 
									
										
										
										
											2016-06-03 18:26:12 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-02 22:17:22 +10:00
										 |  |  |   /* TODO: Make this work for more than one armature in the import file. */ | 
					
						
							|  |  |  |   leaf_bone_length = FLT_MAX; | 
					
						
							| 
									
										
										
										
											2016-06-03 18:26:12 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  |   for (it = skin_by_data_uid.begin(); it != skin_by_data_uid.end(); it++) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     SkinInfo &skin = it->second; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-06-06 15:50:24 +02:00
										 |  |  |     Object *ob_arm = create_armature_bones(bmain, skin); | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-30 13:41:21 +10:00
										 |  |  |     /* link armature with a mesh object */ | 
					
						
							| 
									
										
										
										
											2012-06-14 14:47:41 +00:00
										 |  |  |     const COLLADAFW::UniqueId &uid = skin.get_controller_uid(); | 
					
						
							|  |  |  |     const COLLADAFW::UniqueId *guid = get_geometry_uid(uid); | 
					
						
							|  |  |  |     if (guid != nullptr) { | 
					
						
							|  |  |  |       Object *ob = mesh_importer->get_object_by_geom_uid(*guid); | 
					
						
							| 
									
										
										
										
											2016-06-03 18:26:12 +02:00
										 |  |  |       if (ob) { | 
					
						
							| 
									
										
										
										
											2012-06-14 14:47:41 +00:00
										 |  |  |         skin.link_armature(C, ob, joint_by_uid, this); | 
					
						
							| 
									
										
										
										
											2016-06-03 18:26:12 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         std::vector<Object *>::iterator ob_it = std::find( | 
					
						
							|  |  |  |             objects_to_scale.begin(), objects_to_scale.end(), ob); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (ob_it != objects_to_scale.end()) { | 
					
						
							|  |  |  |           int index = ob_it - objects_to_scale.begin(); | 
					
						
							|  |  |  |           objects_to_scale.erase(objects_to_scale.begin() + index); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (std::find(objects_to_scale.begin(), objects_to_scale.end(), ob_arm) == | 
					
						
							|  |  |  |             objects_to_scale.end()) { | 
					
						
							|  |  |  |           objects_to_scale.push_back(ob_arm); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-04 20:59:13 +02:00
										 |  |  |         if (std::find(arm_objs.begin(), arm_objs.end(), ob_arm) == arm_objs.end()) { | 
					
						
							|  |  |  |           arm_objs.push_back(ob_arm); | 
					
						
							| 
									
										
										
										
											2016-06-03 18:26:12 +02:00
										 |  |  |         } | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2019-05-31 22:51:19 +10:00
										 |  |  |       else { | 
					
						
							| 
									
										
										
										
											2012-06-14 14:47:41 +00:00
										 |  |  |         fprintf(stderr, "Cannot find object to link armature with.\n"); | 
					
						
							| 
									
										
										
										
											2019-05-31 22:51:19 +10:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2012-06-14 14:47:41 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-05-31 22:51:19 +10:00
										 |  |  |     else { | 
					
						
							| 
									
										
										
										
											2012-06-14 14:47:41 +00:00
										 |  |  |       fprintf(stderr, "Cannot find geometry to link armature with.\n"); | 
					
						
							| 
									
										
										
										
											2019-05-31 22:51:19 +10:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-30 13:41:21 +10:00
										 |  |  |     /* set armature parent if any */ | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  |     Object *par = skin.get_parent(); | 
					
						
							| 
									
										
										
										
											2019-05-31 22:51:19 +10:00
										 |  |  |     if (par) { | 
					
						
							| 
									
										
										
										
											2012-05-05 16:03:57 +00:00
										 |  |  |       bc_set_parent(skin.BKE_armature_from_object(), par, C, false); | 
					
						
							| 
									
										
										
										
											2019-05-31 22:51:19 +10:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-30 13:41:21 +10:00
										 |  |  |     /* free memory stolen from SkinControllerData */ | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  |     skin.free(); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2018-06-08 08:07:48 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-30 13:41:21 +10:00
										 |  |  |   /* for bones without skins */ | 
					
						
							| 
									
										
										
										
											2020-09-04 20:59:13 +02:00
										 |  |  |   create_armature_bones(bmain, arm_objs); | 
					
						
							| 
									
										
										
										
											2016-06-03 18:26:12 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-30 13:41:21 +10:00
										 |  |  |   /* Fix bone relations */ | 
					
						
							| 
									
										
										
										
											2016-06-03 18:26:12 +02:00
										 |  |  |   std::vector<Object *>::iterator ob_arm_it; | 
					
						
							| 
									
										
										
										
											2020-09-04 20:59:13 +02:00
										 |  |  |   for (ob_arm_it = arm_objs.begin(); ob_arm_it != arm_objs.end(); ob_arm_it++) { | 
					
						
							| 
									
										
										
										
											2016-06-03 18:26:12 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     Object *ob_arm = *ob_arm_it; | 
					
						
							|  |  |  |     bArmature *armature = (bArmature *)ob_arm->data; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /* and step back to edit mode to fix the leaf nodes */ | 
					
						
							|  |  |  |     ED_armature_to_edit(armature); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     fix_parent_connect(armature, (Bone *)armature->bonebase.first); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-06-06 15:50:24 +02:00
										 |  |  |     ED_armature_from_edit(bmain, armature); | 
					
						
							| 
									
										
										
										
											2016-06-03 18:26:12 +02:00
										 |  |  |     ED_armature_edit_free(armature); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #if 0
 | 
					
						
							| 
									
										
										
										
											2019-04-30 13:41:21 +10:00
										 |  |  | /* link with meshes, create vertex groups, assign weights */ | 
					
						
							| 
									
										
										
										
											2019-04-17 08:24:14 +02:00
										 |  |  | void ArmatureImporter::link_armature(Object *ob_arm, | 
					
						
							|  |  |  |                                      const COLLADAFW::UniqueId &geom_id, | 
					
						
							|  |  |  |                                      const COLLADAFW::UniqueId &controller_data_id) | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  | { | 
					
						
							|  |  |  |   Object *ob = mesh_importer->get_object_by_geom_uid(geom_id); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (!ob) { | 
					
						
							|  |  |  |     fprintf(stderr, "Cannot find object by geometry UID.\n"); | 
					
						
							|  |  |  |     return; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (skin_by_data_uid.find(controller_data_id) == skin_by_data_uid.end()) { | 
					
						
							|  |  |  |     fprintf(stderr, "Cannot find skin info by controller data UID.\n"); | 
					
						
							|  |  |  |     return; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 08:24:14 +02:00
										 |  |  |   SkinInfo &skin = skin_by_data_uid[conroller_data_id]; | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-30 13:41:21 +10:00
										 |  |  |   /* create vertex groups */ | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  | } | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-06-12 22:05:33 +00:00
										 |  |  | bool ArmatureImporter::write_skin_controller_data(const COLLADAFW::SkinControllerData *data) | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-30 13:41:21 +10:00
										 |  |  |   /* at this stage we get vertex influence info that should go into me->verts and ob->defbase
 | 
					
						
							|  |  |  |    * there's no info to which object this should be long so we associate it with | 
					
						
							|  |  |  |    * skin controller data UID. */ | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-06 12:50:56 +11:00
										 |  |  |   /* don't forget to call BKE_object_defgroup_unique_name before we copy */ | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-30 13:41:21 +10:00
										 |  |  |   /* controller data uid -> [armature] -> joint data,
 | 
					
						
							|  |  |  |    * [mesh object] */ | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |   SkinInfo skin(unit_converter); | 
					
						
							|  |  |  |   skin.borrow_skin_controller_data(data); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-30 13:41:21 +10:00
										 |  |  |   /* store join inv bind matrix to use it later in armature construction */ | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  |   const COLLADAFW::Matrix4Array &inv_bind_mats = data->getInverseBindMatrices(); | 
					
						
							|  |  |  |   for (unsigned int i = 0; i < data->getJointsCount(); i++) { | 
					
						
							|  |  |  |     skin.add_joint(inv_bind_mats[i]); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   skin_by_data_uid[data->getUniqueId()] = skin; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return true; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-06-12 22:05:33 +00:00
										 |  |  | bool ArmatureImporter::write_controller(const COLLADAFW::Controller *controller) | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-04-30 13:41:21 +10:00
										 |  |  |   /* - create and store armature object */ | 
					
						
							| 
									
										
										
										
											2013-01-21 13:45:49 +00:00
										 |  |  |   const COLLADAFW::UniqueId &con_id = controller->getUniqueId(); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  |   if (controller->getControllerType() == COLLADAFW::Controller::CONTROLLER_TYPE_SKIN) { | 
					
						
							| 
									
										
										
										
											2012-06-12 22:05:33 +00:00
										 |  |  |     COLLADAFW::SkinController *co = (COLLADAFW::SkinController *)controller; | 
					
						
							| 
									
										
										
										
											2019-04-30 13:41:21 +10:00
										 |  |  |     /* to be able to find geom id by controller id */ | 
					
						
							| 
									
										
										
										
											2013-01-21 13:45:49 +00:00
										 |  |  |     geom_uid_by_controller_uid[con_id] = co->getSource(); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  |     const COLLADAFW::UniqueId &data_uid = co->getSkinControllerData(); | 
					
						
							|  |  |  |     if (skin_by_data_uid.find(data_uid) == skin_by_data_uid.end()) { | 
					
						
							|  |  |  |       fprintf(stderr, "Cannot find skin by controller data UID.\n"); | 
					
						
							|  |  |  |       return true; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  |     skin_by_data_uid[data_uid].set_controller(co); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-04-30 13:41:21 +10:00
										 |  |  |   /* morph controller */ | 
					
						
							| 
									
										
										
										
											2013-01-21 13:45:49 +00:00
										 |  |  |   else if (controller->getControllerType() == COLLADAFW::Controller::CONTROLLER_TYPE_MORPH) { | 
					
						
							|  |  |  |     COLLADAFW::MorphController *co = (COLLADAFW::MorphController *)controller; | 
					
						
							| 
									
										
										
										
											2019-04-30 13:41:21 +10:00
										 |  |  |     /* to be able to find geom id by controller id */ | 
					
						
							| 
									
										
										
										
											2013-01-21 13:45:49 +00:00
										 |  |  |     geom_uid_by_controller_uid[con_id] = co->getSource(); | 
					
						
							| 
									
										
										
										
											2019-04-30 13:41:21 +10:00
										 |  |  |     /* Shape keys are applied in DocumentImporter->finish() */ | 
					
						
							| 
									
										
										
										
											2013-01-21 13:45:49 +00:00
										 |  |  |     morph_controllers.push_back(co); | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  |   return true; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-06-12 12:53:27 +02:00
										 |  |  | void ArmatureImporter::make_shape_keys(bContext *C) | 
					
						
							| 
									
										
										
										
											2013-02-10 17:06:05 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2018-06-12 12:53:27 +02:00
										 |  |  |   Main *bmain = CTX_data_main(C); | 
					
						
							| 
									
										
										
										
											2013-01-21 13:45:49 +00:00
										 |  |  |   std::vector<COLLADAFW::MorphController *>::iterator mc; | 
					
						
							|  |  |  |   float weight; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-01-21 13:45:49 +00:00
										 |  |  |   for (mc = morph_controllers.begin(); mc != morph_controllers.end(); mc++) { | 
					
						
							| 
									
										
										
										
											2019-04-30 13:41:21 +10:00
										 |  |  |     /* Controller data */ | 
					
						
							| 
									
										
										
										
											2013-01-21 13:45:49 +00:00
										 |  |  |     COLLADAFW::UniqueIdArray &morphTargetIds = (*mc)->getMorphTargets(); | 
					
						
							|  |  |  |     COLLADAFW::FloatOrDoubleArray &morphWeights = (*mc)->getMorphWeights(); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-30 13:41:21 +10:00
										 |  |  |     /* Prereq: all the geometries must be imported and mesh objects must be made */ | 
					
						
							| 
									
										
										
										
											2013-01-21 13:45:49 +00:00
										 |  |  |     Object *source_ob = this->mesh_importer->get_object_by_geom_uid((*mc)->getSource()); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-02-17 18:33:10 +00:00
										 |  |  |     if (source_ob) { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-03-18 11:44:56 +00:00
										 |  |  |       Mesh *source_me = (Mesh *)source_ob->data; | 
					
						
							| 
									
										
										
										
											2019-04-30 13:41:21 +10:00
										 |  |  |       /* insert key to source mesh */ | 
					
						
							| 
									
										
										
										
											2018-06-12 12:53:27 +02:00
										 |  |  |       Key *key = source_me->key = BKE_key_add(bmain, (ID *)source_me); | 
					
						
							| 
									
										
										
										
											2013-02-17 18:33:10 +00:00
										 |  |  |       key->type = KEY_RELATIVE; | 
					
						
							|  |  |  |       KeyBlock *kb; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-30 13:41:21 +10:00
										 |  |  |       /* insert basis key */ | 
					
						
							| 
									
										
										
										
											2014-04-01 11:34:00 +11:00
										 |  |  |       kb = BKE_keyblock_add_ctime(key, "Basis", false); | 
					
						
							| 
									
										
										
										
											2018-06-21 18:24:32 +02:00
										 |  |  |       BKE_keyblock_convert_from_mesh(source_me, key, kb); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-30 13:41:21 +10:00
										 |  |  |       /* insert other shape keys */ | 
					
						
							| 
									
										
										
										
											2013-02-17 18:33:10 +00:00
										 |  |  |       for (int i = 0; i < morphTargetIds.getCount(); i++) { | 
					
						
							| 
									
										
										
										
											2020-07-15 13:11:22 +10:00
										 |  |  |         /* Better to have a separate map of morph objects,
 | 
					
						
							|  |  |  |          * This will do for now since only mesh morphing is imported. */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-02-17 18:33:10 +00:00
										 |  |  |         Mesh *me = this->mesh_importer->get_mesh_by_geom_uid(morphTargetIds[i]); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-02-17 18:33:10 +00:00
										 |  |  |         if (me) { | 
					
						
							|  |  |  |           me->key = key; | 
					
						
							|  |  |  |           std::string morph_name = *this->mesh_importer->get_geometry_name(me->id.name); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-04-01 11:34:00 +11:00
										 |  |  |           kb = BKE_keyblock_add_ctime(key, morph_name.c_str(), false); | 
					
						
							| 
									
										
										
										
											2018-06-21 18:24:32 +02:00
										 |  |  |           BKE_keyblock_convert_from_mesh(me, key, kb); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-30 13:41:21 +10:00
										 |  |  |           /* apply weights */ | 
					
						
							| 
									
										
										
										
											2013-02-17 18:33:10 +00:00
										 |  |  |           weight = morphWeights.getFloatValues()->getData()[i]; | 
					
						
							|  |  |  |           kb->curval = weight; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         else { | 
					
						
							|  |  |  |           fprintf(stderr, "Morph target geometry not found.\n"); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2013-02-10 17:06:05 +00:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2013-01-21 13:45:49 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2013-02-17 18:33:10 +00:00
										 |  |  |     else { | 
					
						
							|  |  |  |       fprintf(stderr, "Morph target object not found.\n"); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2013-01-21 13:45:49 +00:00
										 |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  | COLLADAFW::UniqueId *ArmatureImporter::get_geometry_uid(const COLLADAFW::UniqueId &controller_uid) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2019-05-31 22:51:19 +10:00
										 |  |  |   if (geom_uid_by_controller_uid.find(controller_uid) == geom_uid_by_controller_uid.end()) { | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  |     return nullptr; | 
					
						
							| 
									
										
										
										
											2019-05-31 22:51:19 +10:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |   return &geom_uid_by_controller_uid[controller_uid]; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Object *ArmatureImporter::get_armature_for_joint(COLLADAFW::Node *node) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   std::map<COLLADAFW::UniqueId, SkinInfo>::iterator it; | 
					
						
							|  |  |  |   for (it = skin_by_data_uid.begin(); it != skin_by_data_uid.end(); it++) { | 
					
						
							|  |  |  |     SkinInfo &skin = it->second; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-31 22:51:19 +10:00
										 |  |  |     if (skin.uses_joint_or_descendant(node)) { | 
					
						
							| 
									
										
										
										
											2012-05-05 16:03:57 +00:00
										 |  |  |       return skin.BKE_armature_from_object(); | 
					
						
							| 
									
										
										
										
											2019-05-31 22:51:19 +10:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-06-12 22:05:33 +00:00
										 |  |  |   std::map<COLLADAFW::UniqueId, Object *>::iterator arm; | 
					
						
							| 
									
										
										
										
											2011-06-17 20:01:24 +00:00
										 |  |  |   for (arm = unskinned_armature_map.begin(); arm != unskinned_armature_map.end(); arm++) { | 
					
						
							| 
									
										
										
										
											2019-05-31 22:51:19 +10:00
										 |  |  |     if (arm->first == node->getUniqueId()) { | 
					
						
							| 
									
										
										
										
											2011-06-17 20:01:24 +00:00
										 |  |  |       return arm->second; | 
					
						
							| 
									
										
										
										
											2019-05-31 22:51:19 +10:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2011-06-17 20:01:24 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  |   return nullptr; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-04 20:59:13 +02:00
										 |  |  | void ArmatureImporter::set_tags_map(TagsMap &tags_map) | 
					
						
							| 
									
										
										
										
											2011-07-26 18:28:07 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2020-09-04 20:59:13 +02:00
										 |  |  |   this->uid_tags_map = tags_map; | 
					
						
							| 
									
										
										
										
											2011-07-26 18:28:07 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  | void ArmatureImporter::get_rna_path_for_joint(COLLADAFW::Node *node, | 
					
						
							|  |  |  |                                               char *joint_path, | 
					
						
							|  |  |  |                                               size_t count) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2020-12-14 10:48:11 +01:00
										 |  |  |   char bone_name_esc[sizeof(((Bone *)nullptr)->name) * 2]; | 
					
						
							| 
									
										
										
										
											2020-12-14 18:44:04 +11:00
										 |  |  |   BLI_str_escape(bone_name_esc, bc_get_joint_name(node), sizeof(bone_name_esc)); | 
					
						
							|  |  |  |   BLI_snprintf(joint_path, count, "pose.bones[\"%s\"]", bone_name_esc); | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-30 13:41:21 +10:00
										 |  |  | /* gives a world-space mat */ | 
					
						
							| 
									
										
										
										
											2012-12-11 14:29:01 +00:00
										 |  |  | bool ArmatureImporter::get_joint_bind_mat(float m[4][4], COLLADAFW::Node *joint) | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  | { | 
					
						
							|  |  |  |   std::map<COLLADAFW::UniqueId, SkinInfo>::iterator it; | 
					
						
							|  |  |  |   bool found = false; | 
					
						
							|  |  |  |   for (it = skin_by_data_uid.begin(); it != skin_by_data_uid.end(); it++) { | 
					
						
							|  |  |  |     SkinInfo &skin = it->second; | 
					
						
							|  |  |  |     if ((found = skin.get_joint_inv_bind_matrix(m, joint))) { | 
					
						
							|  |  |  |       invert_m4(m); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-05 00:05:14 +00:00
										 |  |  |   return found; | 
					
						
							| 
									
										
										
										
											2010-10-05 00:49:39 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2014-11-29 13:24:26 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-23 12:56:04 +02:00
										 |  |  | BoneExtended &ArmatureImporter::add_bone_extended(EditBone *bone, | 
					
						
							|  |  |  |                                                   COLLADAFW::Node *node, | 
					
						
							|  |  |  |                                                   int sibcount, | 
					
						
							|  |  |  |                                                   std::vector<std::string> &layer_labels, | 
					
						
							|  |  |  |                                                   BoneExtensionMap &extended_bones) | 
					
						
							| 
									
										
										
										
											2014-11-29 13:24:26 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2016-05-26 17:40:56 +02:00
										 |  |  |   BoneExtended *be = new BoneExtended(bone); | 
					
						
							|  |  |  |   extended_bones[bone->name] = be; | 
					
						
							| 
									
										
										
										
											2014-11-29 13:24:26 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |   TagsMap::iterator etit; | 
					
						
							|  |  |  |   ExtraTags *et = nullptr; | 
					
						
							|  |  |  |   etit = uid_tags_map.find(node->getUniqueId().toAscii()); | 
					
						
							| 
									
										
										
										
											2016-06-03 18:26:12 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |   bool has_connect = false; | 
					
						
							|  |  |  |   int connect_type = -1; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-29 13:24:26 +01:00
										 |  |  |   if (etit != uid_tags_map.end()) { | 
					
						
							| 
									
										
										
										
											2016-05-26 17:40:56 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     float tail[3] = {FLT_MAX, FLT_MAX, FLT_MAX}; | 
					
						
							| 
									
										
										
										
											2016-05-28 18:41:54 +02:00
										 |  |  |     float roll = 0; | 
					
						
							|  |  |  |     std::string layers; | 
					
						
							| 
									
										
										
										
											2014-11-29 13:24:26 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     et = etit->second; | 
					
						
							| 
									
										
										
										
											2016-05-26 17:40:56 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-28 18:41:54 +02:00
										 |  |  |     bool has_tail = false; | 
					
						
							|  |  |  |     has_tail |= et->setData("tip_x", &tail[0]); | 
					
						
							|  |  |  |     has_tail |= et->setData("tip_y", &tail[1]); | 
					
						
							|  |  |  |     has_tail |= et->setData("tip_z", &tail[2]); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-03 18:26:12 +02:00
										 |  |  |     has_connect = et->setData("connect", &connect_type); | 
					
						
							|  |  |  |     bool has_roll = et->setData("roll", &roll); | 
					
						
							| 
									
										
										
										
											2018-06-08 08:07:48 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-28 18:41:54 +02:00
										 |  |  |     layers = et->setData("layer", layers); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (has_tail && !has_connect) { | 
					
						
							| 
									
										
										
										
											2016-06-03 18:26:12 +02:00
										 |  |  |       /* got a bone tail definition but no connect info -> bone is not connected */ | 
					
						
							|  |  |  |       has_connect = true; | 
					
						
							| 
									
										
										
										
											2018-06-08 08:07:48 +02:00
										 |  |  |       connect_type = 0; | 
					
						
							| 
									
										
										
										
											2016-05-26 17:40:56 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-29 00:35:50 +02:00
										 |  |  |     be->set_bone_layers(layers, layer_labels); | 
					
						
							| 
									
										
										
										
											2019-05-31 22:51:19 +10:00
										 |  |  |     if (has_tail) { | 
					
						
							| 
									
										
										
										
											2016-05-28 18:41:54 +02:00
										 |  |  |       be->set_tail(tail); | 
					
						
							| 
									
										
										
										
											2019-05-31 22:51:19 +10:00
										 |  |  |     } | 
					
						
							|  |  |  |     if (has_roll) { | 
					
						
							| 
									
										
										
										
											2016-05-28 18:41:54 +02:00
										 |  |  |       be->set_roll(roll); | 
					
						
							| 
									
										
										
										
											2019-05-31 22:51:19 +10:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2014-11-29 13:24:26 +01:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2016-06-03 18:26:12 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |   if (!has_connect && this->import_settings->auto_connect) { | 
					
						
							|  |  |  |     /* auto connect only whyen parent has exactly one child*/ | 
					
						
							|  |  |  |     connect_type = sibcount == 1; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   be->set_use_connect(connect_type); | 
					
						
							| 
									
										
										
										
											2016-05-26 17:40:56 +02:00
										 |  |  |   be->set_leaf_bone(true); | 
					
						
							| 
									
										
										
										
											2014-11-29 13:24:26 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |   return *be; | 
					
						
							|  |  |  | } |