Commit: 29aa13cfa284182ee47818a477a3b8b7297a12c8 Author: Gaia Clary Date: Thu May 26 17:40:56 2016 +0200 Branches: master https://developer.blender.org/rB29aa13cfa284182ee47818a477a3b8b7297a12c8
fix: Import of meshes with holes is now reported as WARNING (unsupported) improved: add support for bone tail export/import using Blender Collada profile Differential Revision: https://developer.blender.org/D2031 =================================================================== M source/blender/collada/ArmatureExporter.cpp M source/blender/collada/ArmatureExporter.h M source/blender/collada/ArmatureImporter.cpp M source/blender/collada/ArmatureImporter.h M source/blender/collada/ExportSettings.h M source/blender/collada/collada.cpp M source/blender/collada/collada.h M source/blender/editors/io/io_collada.c M source/blender/makesrna/intern/rna_scene_api.c =================================================================== diff --git a/source/blender/collada/ArmatureExporter.cpp b/source/blender/collada/ArmatureExporter.cpp index 36ab85b..cf02293 100644 --- a/source/blender/collada/ArmatureExporter.cpp +++ b/source/blender/collada/ArmatureExporter.cpp @@ -150,6 +150,16 @@ std::string ArmatureExporter::get_joint_sid(Bone *bone, Object *ob_arm) return get_joint_id(bone, ob_arm); } +static bool is_leaf_bone(Bone *bone) +{ + for (Bone *child = (Bone *)bone->childbase.first; child; child = child->next) { + if (child->flag & BONE_CONNECTED) { + return false; + } + } + return true; +} + // parent_mat is armature-space void ArmatureExporter::add_bone_node(Bone *bone, Object *ob_arm, Scene *sce, SceneExporter *se, @@ -167,12 +177,22 @@ void ArmatureExporter::add_bone_node(Bone *bone, Object *ob_arm, Scene *sce, node.setNodeName(node_name); node.setNodeSid(node_sid); -#if 0 - if (BLI_listbase_is_empty(&bone->childbase) || BLI_listbase_count_ex(&bone->childbase, 2) == 2) { - add_blender_leaf_bone( bone, ob_arm, node); + if (this->export_settings->use_blender_profile) + { + if (bone->parent) { + if (bone->flag & BONE_CONNECTED) { + node.addExtraTechniqueParameter("blender", "connect", true); + } + } + + if (is_leaf_bone(bone)) + { + node.addExtraTechniqueParameter("blender", "tip_x", bone->arm_tail[0] - bone->arm_head[0]); + node.addExtraTechniqueParameter("blender", "tip_y", bone->arm_tail[1] - bone->arm_head[1]); + node.addExtraTechniqueParameter("blender", "tip_z", bone->arm_tail[2] - bone->arm_head[2]); + } } - else { -#endif + node.start(); add_bone_transform(ob_arm, bone, node); @@ -227,25 +247,6 @@ void ArmatureExporter::add_bone_node(Bone *bone, Object *ob_arm, Scene *sce, } } -//#if 1 -void ArmatureExporter::add_blender_leaf_bone(Bone *bone, Object *ob_arm, COLLADASW::Node& node) -{ - node.start(); - - add_bone_transform(ob_arm, bone, node); - - node.addExtraTechniqueParameter("blender", "tip_x", bone->tail[0]); - node.addExtraTechniqueParameter("blender", "tip_y", bone->tail[1]); - node.addExtraTechniqueParameter("blender", "tip_z", bone->tail[2]); - - /*for (Bone *child = (Bone *)bone->childbase.first; child; child = child->next) { - add_bone_node(child, ob_arm, sce, se, child_objects); - }*/ - node.end(); - -} -//#endif - void ArmatureExporter::add_bone_transform(Object *ob_arm, Bone *bone, COLLADASW::Node& node) { //bPoseChannel *pchan = BKE_pose_channel_find_name(ob_arm->pose, bone->name); diff --git a/source/blender/collada/ArmatureExporter.h b/source/blender/collada/ArmatureExporter.h index 931cc5d..883a6ac 100644 --- a/source/blender/collada/ArmatureExporter.h +++ b/source/blender/collada/ArmatureExporter.h @@ -92,8 +92,6 @@ private: void add_bone_transform(Object *ob_arm, Bone *bone, COLLADASW::Node& node); - void add_blender_leaf_bone(Bone *bone, Object *ob_arm, COLLADASW::Node& node); - std::string get_controller_id(Object *ob_arm, Object *ob); void write_bone_URLs(COLLADASW::InstanceController &ins, Object *ob_arm, Bone *bone); diff --git a/source/blender/collada/ArmatureImporter.cpp b/source/blender/collada/ArmatureImporter.cpp index fd08e1e..df60b21 100644 --- a/source/blender/collada/ArmatureImporter.cpp +++ b/source/blender/collada/ArmatureImporter.cpp @@ -158,21 +158,33 @@ int ArmatureImporter::create_bone(SkinInfo *skin, COLLADAFW::Node *node, EditBon float loc[3], size[3], rot[3][3]; float angle; - float vec[3] = {0.0f, 0.5f, 0.0f}; + + BoneExtended &be = add_bone_extended(bone, node); + + float *tail = be.get_tail(); + int use_connect = be.get_use_connect(); + + switch (use_connect) { + case 1: bone->flag |= BONE_CONNECTED; + break; + case 0: bone->flag &= ~BONE_CONNECTED; + case -1: break; // not defined + } + mat4_to_loc_rot_size(loc, rot, size, mat); - //copy_m3_m4(bonemat,mat); - mat3_to_vec_roll(rot, vec, &angle); + mat3_to_vec_roll(rot, NULL, &angle); bone->roll = angle; - // set head copy_v3_v3(bone->head, mat[3]); - - // set tail, don't set it to head because 0-length bones are not allowed - add_v3_v3v3(bone->tail, bone->head, vec); + add_v3_v3v3(bone->tail, bone->head, tail); //tail must be non zero /* find smallest bone length in armature (used later for leaf bone length) */ if (parent) { + if (use_connect == 1) { + copy_v3_v3(parent->tail, bone->head); + } + /* guess reasonable leaf bone length */ float length = len_v3v3(parent->head, bone->head); if ((length < leaf_bone_length || totbone == 0) && length > MINIMUM_BONE_LENGTH) { @@ -182,9 +194,6 @@ int ArmatureImporter::create_bone(SkinInfo *skin, COLLADAFW::Node *node, EditBon COLLADAFW::NodePointerArray& children = node->getChildNodes(); - BoneExtended &be = add_bone_extended(bone, node); - be.set_leaf_bone(true); - for (unsigned int i = 0; i < children.getCount(); i++) { int cl = create_bone(skin, children[i], bone, children.getCount(), mat, arm); if (cl > chain_length) @@ -201,6 +210,18 @@ int ArmatureImporter::create_bone(SkinInfo *skin, COLLADAFW::Node *node, EditBon return chain_length + 1; } +/* + * A bone is a leaf when it has no children or all children are not connected. + */ +static bool is_leaf_bone(Bone *bone) +{ + for (Bone *child = (Bone *)bone->childbase.first; child; child = child->next) { + if (child->flag & BONE_CONNECTED) + return false; + } + return true; +} + /** * Collada only knows Joints, hence bones at the end of a bone chain * don't have a defined length. This function guesses reasonable @@ -209,33 +230,26 @@ int ArmatureImporter::create_bone(SkinInfo *skin, COLLADAFW::Node *node, EditBon **/ void ArmatureImporter::fix_leaf_bones(bArmature *armature, Bone *bone) { - /* armature has no bones */ if (bone == NULL) return; - BoneExtended *be = extended_bones[bone->name]; - if (be != NULL && be->is_leaf_bone() ) { + if (is_leaf_bone(bone)) { /* 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; EditBone *ebone = get_edit_bone(armature, bone->name); float vec[3]; - if (this->import_settings->fix_orientation) { - if (ebone->parent != NULL) { - EditBone *parent = ebone->parent; - sub_v3_v3v3(vec, ebone->head, parent->tail); - if (len_squared_v3(vec) < MINIMUM_BONE_LENGTH) - { - sub_v3_v3v3(vec, parent->tail, parent->head); - } - } - else { - vec[2] = 0.1f; - sub_v3_v3v3(vec, ebone->tail, ebone->head); + if (ebone->parent != NULL) { + 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); } } else { + vec[2] = 0.1f; sub_v3_v3v3(vec, ebone->tail, ebone->head); } @@ -250,6 +264,22 @@ void ArmatureImporter::fix_leaf_bones(bArmature *armature, Bone *bone) } +void ArmatureImporter::fix_parent_connect(bArmature *armature, Bone *bone) +{ + /* armature has no bones */ + if (bone == NULL) + return; + + if (bone->parent && bone->flag & BONE_CONNECTED) { + copy_v3_v3(bone->parent->tail, bone->head); + } + + for (Bone *child = (Bone *)bone->childbase.first; child; child = child->next) { + fix_parent_connect(armature, child); + } + +} + void ArmatureImporter::connect_bone_chains(bArmature *armature, Bone *parentbone, int clip) { @@ -455,14 +485,23 @@ void ArmatureImporter::create_armature_bones( ) /* and step back to edit mode to fix the leaf nodes */ ED_armature_to_edit(armature); - connect_bone_chains(armature, (Bone *)armature->bonebase.first, UNLIMITED_CHAIN_MAX); - fix_leaf_bones(armature, (Bone *)armature->bonebase.first); + 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); - // exit armature edit mode - unskinned_armature_map[(*ri)->getUniqueId()] = ob_arm; + 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; + } + + 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); } } @@ -594,8 +633,8 @@ void ArmatureImporter::create_armature_bones(SkinInfo& skin) 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); + //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); @@ -905,7 +944,11 @@ BoneExtended::BoneExtended(EditBone *aBone) { this->set_name(aBone->name); this->chain_length = 0; - this->is_leaf = false; + this->is_leaf = false; + this->tail[0] = 0.0f; + this->tail[1] = 0.5f; + this->tail[2] = 0.0f; + this->use_connect = -1; } char *BoneExtended::get_name() @@ -928,7 +971,6 @@ void BoneExtended::set_chain_length(const int aLength) chain_length = aLength; } - void BoneExtended::set_leaf_bone(bool state) { is_leaf = state; @@ -939,25 +981,60 @@ bool BoneExtended::is_leaf_bone() return is_leaf; } +void BoneExtended::set_tail(float vec[]) +{ + this->tail[0] = vec[0]; + this->tail[1] = vec[1]; + this->tail[2] = vec[2]; +} + +float *BoneExtended::get_tail() +{ + return this->tail; +} + +void BoneExtended::set_use_connect(int use_connect) +{ + this->use_connect = use_connect; +} + +int BoneExtended::get_use_connect() +{ + return this->use_connect; +} + + BoneExtended &ArmatureImporter::add_bone_extended(EditBone *bone, COLLADAFW::Node *node) { + BoneExtended *be = new BoneExtended(bone); + extended_bones[bone->name] = be; TagsMap::iterator etit; ExtraTags *et = 0; etit = uid_tags_ @@ Diff output truncated at 10240 characters. @@ _______________________________________________ Bf-blender-cvs mailing list [email protected] https://lists.blender.org/mailman/listinfo/bf-blender-cvs
