From 38410e6e2527574176338fe7ba8711cbfdd2cc91 Mon Sep 17 00:00:00 2001 From: Gaia Clary Date: Fri, 3 Jun 2016 18:26:12 +0200 Subject: changed use_connect from bool to a 3 state value (-1,0,1) --- source/blender/collada/ArmatureImporter.cpp | 164 ++++++++++++++++++---------- source/blender/collada/ArmatureImporter.h | 8 +- source/blender/collada/DocumentImporter.cpp | 4 +- source/blender/collada/ImportSettings.h | 1 + source/blender/collada/SkinInfo.cpp | 1 + source/blender/collada/collada.cpp | 2 + source/blender/collada/collada.h | 1 + source/blender/collada/collada_utils.h | 2 +- 8 files changed, 118 insertions(+), 65 deletions(-) (limited to 'source/blender/collada') diff --git a/source/blender/collada/ArmatureImporter.cpp b/source/blender/collada/ArmatureImporter.cpp index fca9b9ffa55..1bc2bff74e3 100644 --- a/source/blender/collada/ArmatureImporter.cpp +++ b/source/blender/collada/ArmatureImporter.cpp @@ -107,27 +107,39 @@ int ArmatureImporter::create_bone(SkinInfo *skin, COLLADAFW::Node *node, EditBon std::vector::iterator it; it = std::find(finished_joints.begin(), finished_joints.end(), node); if (it != finished_joints.end()) return chain_length; - - // JointData* jd = get_joint_data(node); - // TODO rename from Node "name" attrs later EditBone *bone = ED_armature_edit_bone_add(arm, (char *)bc_get_joint_name(node)); totbone++; - if (skin && skin->get_joint_inv_bind_matrix(joint_inv_bind_mat, node)) { - // get original world-space matrix - invert_m4_m4(mat, joint_inv_bind_mat); + /* + * We use the inv_bind_shape matrix to apply the armature bind pose as its rest pose. + */ + + std::map::iterator skin_it; + bool bone_is_not_skinned = true; + for (skin_it = skin_by_data_uid.begin(); skin_it != skin_by_data_uid.end(); skin_it++) { + + SkinInfo *b = &skin_it->second; + if (b->get_joint_inv_bind_matrix(joint_inv_bind_mat, node)) { - // And make local to armature - 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); + // get original world-space matrix + invert_m4_m4(mat, joint_inv_bind_mat); + + // And make local to armature + 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); + } + + bone_is_not_skinned = false; + break; } } + // create a bone even if there's no joint data for it (i.e. it has no influence) - else { + if (bone_is_not_skinned) { float obmat[4][4]; // bone-space get_node_mat(obmat, node, NULL, NULL); @@ -145,7 +157,7 @@ int ArmatureImporter::create_bone(SkinInfo *skin, COLLADAFW::Node *node, EditBon float loc[3], size[3], rot[3][3]; - BoneExtended &be = add_bone_extended(bone, node, layer_labels); + BoneExtended &be = add_bone_extended(bone, node, totchild, layer_labels); int layer = be.get_bone_layers(); if (layer) bone->layer = layer; arm->layer |= layer; // ensure that all populated bone layers are visible after import @@ -168,7 +180,6 @@ int ArmatureImporter::create_bone(SkinInfo *skin, COLLADAFW::Node *node, EditBon mat4_to_loc_rot_size(loc, rot, size, mat); mat3_to_vec_roll(rot, NULL, &angle); } - copy_v3_v3(bone->head, mat[3]); add_v3_v3v3(bone->tail, bone->head, tail); //tail must be non zero @@ -434,12 +445,12 @@ ArmatureJoints& ArmatureImporter::get_armature_joints(Object *ob_arm) return armature_joints.back(); } #endif -void ArmatureImporter::create_armature_bones( ) +Object *ArmatureImporter::create_armature_bones(std::vector &ob_arms) { std::vector::iterator ri; std::vector layer_labels; + Object *ob_arm = NULL; - leaf_bone_length = FLT_MAX; //if there is an armature created for root_joint next root_joint for (ri = root_joints.begin(); ri != root_joints.end(); ri++) { if (get_armature_for_joint(*ri) != NULL) continue; @@ -467,34 +478,21 @@ void ArmatureImporter::create_armature_bones( ) create_bone(NULL, *ri , NULL, (*ri)->getChildNodes().getCount(), NULL, armature, layer_labels); /* exit armature edit mode to populate the Armature object */ + unskinned_armature_map[(*ri)->getUniqueId()] = ob_arm; ED_armature_from_edit(armature); ED_armature_edit_free(armature); - /* and step back to edit mode to fix the leaf nodes */ - ED_armature_to_edit(armature); - - if (this->import_settings->fix_orientation || this->import_settings->find_chains) { - - if (this->import_settings->find_chains) - connect_bone_chains(armature, (Bone *)armature->bonebase.first, UNLIMITED_CHAIN_MAX); - - if (this->import_settings->fix_orientation) - fix_leaf_bones(armature, (Bone *)armature->bonebase.first); - - // exit armature edit mode - unskinned_armature_map[(*ri)->getUniqueId()] = ob_arm; + int index = std::find(ob_arms.begin(), ob_arms.end(), ob_arm) - ob_arms.begin(); + if (index == 0) { + ob_arms.push_back(ob_arm); } - fix_parent_connect(armature, (Bone *)armature->bonebase.first); - - ED_armature_from_edit(armature); - ED_armature_edit_free(armature); - DAG_id_tag_update(&ob_arm->id, OB_RECALC_OB | OB_RECALC_DATA); } + return ob_arm; } -void ArmatureImporter::create_armature_bones(SkinInfo& skin) +Object *ArmatureImporter::create_armature_bones(SkinInfo& skin) { // just do like so: // - get armature @@ -590,7 +588,6 @@ void ArmatureImporter::create_armature_bones(SkinInfo& skin) totbone = 0; // bone_direction_row = 1; // TODO: don't default to Y but use asset and based on it decide on default row - leaf_bone_length = FLT_MAX; // create bones /* @@ -606,6 +603,7 @@ void ArmatureImporter::create_armature_bones(SkinInfo& skin) // since root_joints may contain joints for multiple controllers, we need to filter if (skin.uses_joint_or_descendant(*ri)) { + create_bone(&skin, *ri, NULL, (*ri)->getChildNodes().getCount(), NULL, armature, layer_labels); if (joint_parent_map.find((*ri)->getUniqueId()) != joint_parent_map.end() && !skin.get_parent()) @@ -617,18 +615,9 @@ void ArmatureImporter::create_armature_bones(SkinInfo& skin) ED_armature_from_edit(armature); ED_armature_edit_free(armature); - /* and step back to edit mode to fix the leaf nodes */ - ED_armature_to_edit(armature); - - if (armature->bonebase.first) { - /* Do this only if Armature has bones */ - //connect_bone_chains(armature, (Bone *)armature->bonebase.first, UNLIMITED_CHAIN_MAX); - //fix_leaf_bones(armature, (Bone *)armature->bonebase.first); - } - // exit armature edit mode - ED_armature_from_edit(armature); - ED_armature_edit_free(armature); DAG_id_tag_update(&ob_arm->id, OB_RECALC_OB | OB_RECALC_DATA); + + return ob_arm; } void ArmatureImporter::set_pose(Object *ob_arm, COLLADAFW::Node *root_node, const char *parentname, float parent_mat[4][4]) @@ -703,22 +692,42 @@ void ArmatureImporter::add_root_joint(COLLADAFW::Node *node) #endif // here we add bones to armatures, having armatures previously created in write_controller -void ArmatureImporter::make_armatures(bContext *C) +void ArmatureImporter::make_armatures(bContext *C, std::vector &objects_to_scale) { + std::vector ob_arms; std::map::iterator it; + + leaf_bone_length = FLT_MAX; /*TODO: Make this work for more than one armature in the import file*/ + for (it = skin_by_data_uid.begin(); it != skin_by_data_uid.end(); it++) { SkinInfo& skin = it->second; - create_armature_bones(skin); + Object *ob_arm = create_armature_bones(skin); // link armature with a mesh object const COLLADAFW::UniqueId &uid = skin.get_controller_uid(); const COLLADAFW::UniqueId *guid = get_geometry_uid(uid); if (guid != NULL) { Object *ob = mesh_importer->get_object_by_geom_uid(*guid); - if (ob) + if (ob) { skin.link_armature(C, ob, joint_by_uid, this); + + std::vector::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); + } + + if (std::find(ob_arms.begin(), ob_arms.end(), ob_arm) == ob_arms.end()) { + ob_arms.push_back(ob_arm); + } + } else fprintf(stderr, "Cannot find object to link armature with.\n"); } @@ -735,7 +744,35 @@ void ArmatureImporter::make_armatures(bContext *C) } //for bones without skins - create_armature_bones(); + create_armature_bones(ob_arms); + + // Fix bone relations + std::vector::iterator ob_arm_it; + for (ob_arm_it = ob_arms.begin(); ob_arm_it != ob_arms.end(); ob_arm_it++) { + + 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); + + if (this->import_settings->fix_orientation || this->import_settings->find_chains) { + + if (this->import_settings->find_chains) + connect_bone_chains(armature, (Bone *)armature->bonebase.first, UNLIMITED_CHAIN_MAX); + + if (this->import_settings->fix_orientation) + fix_leaf_bones(armature, (Bone *)armature->bonebase.first); + + // exit armature edit mode + + } + + fix_parent_connect(armature, (Bone *)armature->bonebase.first); + + ED_armature_from_edit(armature); + ED_armature_edit_free(armature); + } } #if 0 @@ -922,7 +959,7 @@ bool ArmatureImporter::get_joint_bind_mat(float m[4][4], COLLADAFW::Node *joint) return found; } -BoneExtended &ArmatureImporter::add_bone_extended(EditBone *bone, COLLADAFW::Node *node, std::vector &layer_labels) +BoneExtended &ArmatureImporter::add_bone_extended(EditBone *bone, COLLADAFW::Node *node, int sibcount, std::vector &layer_labels) { BoneExtended *be = new BoneExtended(bone); extended_bones[bone->name] = be; @@ -930,11 +967,14 @@ BoneExtended &ArmatureImporter::add_bone_extended(EditBone *bone, COLLADAFW::Nod TagsMap::iterator etit; ExtraTags *et = 0; etit = uid_tags_map.find(node->getUniqueId().toAscii()); + + bool has_connect = false; + int connect_type = -1; + if (etit != uid_tags_map.end()) { float tail[3] = { FLT_MAX, FLT_MAX, FLT_MAX }; float roll = 0; - int use_connect = -1; std::string layers; et = etit->second; @@ -944,21 +984,29 @@ BoneExtended &ArmatureImporter::add_bone_extended(EditBone *bone, COLLADAFW::Nod has_tail |= et->setData("tip_y", &tail[1]); has_tail |= et->setData("tip_z", &tail[2]); - bool has_connect = et->setData("connect", &use_connect); - bool has_roll = et->setData("roll", &roll); + has_connect = et->setData("connect", &connect_type); + bool has_roll = et->setData("roll", &roll); layers = et->setData("layer", layers); if (has_tail && !has_connect) { - use_connect = 0; // got a bone tail definition but no connect info -> bone is not connected + /* got a bone tail definition but no connect info -> bone is not connected */ + has_connect = true; + connect_type = 0; } be->set_bone_layers(layers, layer_labels); if (has_tail) be->set_tail(tail); if (has_roll) be->set_roll(roll); - be->set_use_connect(use_connect); } + + 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); be->set_leaf_bone(true); return *be; diff --git a/source/blender/collada/ArmatureImporter.h b/source/blender/collada/ArmatureImporter.h index f38bd1a6c66..e006ccbc94a 100644 --- a/source/blender/collada/ArmatureImporter.h +++ b/source/blender/collada/ArmatureImporter.h @@ -108,7 +108,7 @@ private: int create_bone(SkinInfo* skin, COLLADAFW::Node *node, EditBone *parent, int totchild, float parent_mat[4][4], bArmature *arm, std::vector &layer_labels); - BoneExtended &add_bone_extended(EditBone *bone, COLLADAFW::Node * node, std::vector &layer_labels); + BoneExtended &add_bone_extended(EditBone *bone, COLLADAFW::Node * node, int sibcount, std::vector &layer_labels); void clear_extended_boneset(); void fix_leaf_bones(bArmature *armature, Bone *bone); @@ -131,8 +131,8 @@ private: ArmatureJoints& get_armature_joints(Object *ob_arm); #endif - void create_armature_bones(SkinInfo& skin); - void create_armature_bones( ); + Object *create_armature_bones(SkinInfo& skin); + Object *create_armature_bones(std::vector &arm_objs); /** TagsMap typedef for uid_tags_map. */ typedef std::map TagsMap; @@ -145,7 +145,7 @@ public: void add_root_joint(COLLADAFW::Node *node, Object *parent); // here we add bones to armatures, having armatures previously created in write_controller - void make_armatures(bContext *C); + void make_armatures(bContext *C, std::vector &objects_to_scale); void make_shape_keys(); diff --git a/source/blender/collada/DocumentImporter.cpp b/source/blender/collada/DocumentImporter.cpp index 45dcf436473..3a709da78e1 100644 --- a/source/blender/collada/DocumentImporter.cpp +++ b/source/blender/collada/DocumentImporter.cpp @@ -239,7 +239,7 @@ void DocumentImporter::finish() mesh_importer.optimize_material_assignements(); armature_importer.set_tags_map(this->uid_tags_map); - armature_importer.make_armatures(mContext); + armature_importer.make_armatures(mContext, *objects_to_scale); armature_importer.make_shape_keys(); DAG_relations_tag_update(bmain); @@ -517,7 +517,7 @@ std::vector *DocumentImporter::write_node(COLLADAFW::Node *node, COLLA name.c_str()); if (is_joint) { - if (parent_node == NULL) { + if (parent_node == NULL && !is_library_node) { // A Joint on root level is a skeleton without root node. // Here we add the armature "on the fly": par = bc_add_object(sce, OB_ARMATURE, std::string("Armature").c_str()); diff --git a/source/blender/collada/ImportSettings.h b/source/blender/collada/ImportSettings.h index 783f58e6bff..2c52d73e756 100644 --- a/source/blender/collada/ImportSettings.h +++ b/source/blender/collada/ImportSettings.h @@ -33,6 +33,7 @@ struct ImportSettings { public: bool import_units; bool find_chains; + bool auto_connect; bool fix_orientation; int min_chain_length; char *filepath; diff --git a/source/blender/collada/SkinInfo.cpp b/source/blender/collada/SkinInfo.cpp index 71875d6274a..7242a24523c 100644 --- a/source/blender/collada/SkinInfo.cpp +++ b/source/blender/collada/SkinInfo.cpp @@ -230,6 +230,7 @@ void SkinInfo::link_armature(bContext *C, Object *ob, std::mapobject = ob_arm; + struct bArmature *armature = (bArmature *)ob_arm->data; #if 1 bc_set_parent(ob, ob_arm, C); diff --git a/source/blender/collada/collada.cpp b/source/blender/collada/collada.cpp index e1b8a2dd30a..fe8b1d2320a 100644 --- a/source/blender/collada/collada.cpp +++ b/source/blender/collada/collada.cpp @@ -46,6 +46,7 @@ int collada_import(bContext *C, const char *filepath, int import_units, int find_chains, + int auto_connect, int fix_orientation, int min_chain_length) { @@ -53,6 +54,7 @@ int collada_import(bContext *C, ImportSettings import_settings; import_settings.filepath = (char *)filepath; import_settings.import_units = import_units != 0; + import_settings.auto_connect = auto_connect != 0; import_settings.find_chains = find_chains != 0; import_settings.fix_orientation = fix_orientation != 0; import_settings.min_chain_length = min_chain_length; diff --git a/source/blender/collada/collada.h b/source/blender/collada/collada.h index db8ea884222..0017c66836a 100644 --- a/source/blender/collada/collada.h +++ b/source/blender/collada/collada.h @@ -57,6 +57,7 @@ int collada_import(struct bContext *C, const char *filepath, int import_units, int find_chains, + int auto_connect, int fix_orientation, int min_chain_length); diff --git a/source/blender/collada/collada_utils.h b/source/blender/collada/collada_utils.h index 74f8dca1492..ee371f7959e 100644 --- a/source/blender/collada/collada_utils.h +++ b/source/blender/collada/collada_utils.h @@ -120,7 +120,7 @@ private: float roll; int bone_layers; - bool use_connect; + int use_connect; bool has_custom_tail; bool has_custom_roll; -- cgit v1.2.3