From 9f6a66d5f9feb34377cf0e6465020cc80f673d8e Mon Sep 17 00:00:00 2001 From: Gaia Clary Date: Fri, 15 Jun 2012 22:00:25 +0000 Subject: Collada: (Exporter) Add new option 'deform bones only' --- source/blender/collada/ArmatureExporter.cpp | 111 ++++++++++++++++------------ source/blender/collada/ArmatureExporter.h | 2 + source/blender/collada/ExportSettings.h | 5 +- source/blender/collada/collada.cpp | 30 +++++--- source/blender/collada/collada.h | 5 +- source/blender/collada/collada_utils.cpp | 28 ++++++- source/blender/collada/collada_utils.h | 1 + 7 files changed, 117 insertions(+), 65 deletions(-) (limited to 'source/blender/collada') diff --git a/source/blender/collada/ArmatureExporter.cpp b/source/blender/collada/ArmatureExporter.cpp index 98047df8aa4..8301066edaf 100644 --- a/source/blender/collada/ArmatureExporter.cpp +++ b/source/blender/collada/ArmatureExporter.cpp @@ -80,6 +80,18 @@ bool ArmatureExporter::is_skinned_mesh(Object *ob) return bc_get_assigned_armature(ob) != NULL; } + +void ArmatureExporter::write_bone_URLs(COLLADASW::InstanceController &ins, Object *ob_arm, Bone *bone) +{ + if ( bc_is_root_bone(bone, this->export_settings->deform_bones_only) ) + ins.addSkeleton(COLLADABU::URI(COLLADABU::Utils::EMPTY_STRING, get_joint_id(bone, ob_arm))); + else { + for (Bone *child = (Bone *)bone->childbase.first; child; child = child->next) { + write_bone_URLs(ins, ob_arm, child); + } + } +} + bool ArmatureExporter::add_instance_controller(Object *ob) { Object *ob_arm = bc_get_assigned_armature(ob); @@ -96,8 +108,7 @@ bool ArmatureExporter::add_instance_controller(Object *ob) // write root bone URLs Bone *bone; for (bone = (Bone *)arm->bonebase.first; bone; bone = bone->next) { - if (!bone->parent) - ins.addSkeleton(COLLADABU::URI(COLLADABU::Utils::EMPTY_STRING, get_joint_id(bone, ob_arm))); + write_bone_URLs(ins, ob_arm, bone); } InstanceWriter::add_material_bindings(ins.getBindMaterial(), ob); @@ -164,67 +175,73 @@ void ArmatureExporter::add_bone_node(Bone *bone, Object *ob_arm, Scene *sce, SceneExporter *se, std::list& child_objects) { - std::string node_id = get_joint_id(bone, ob_arm); - std::string node_name = std::string(bone->name); - std::string node_sid = get_joint_sid(bone, ob_arm); + if (!(this->export_settings->deform_bones_only && bone->flag & BONE_NO_DEFORM)) { + std::string node_id = get_joint_id(bone, ob_arm); + std::string node_name = std::string(bone->name); + std::string node_sid = get_joint_sid(bone, ob_arm); - COLLADASW::Node node(mSW); + COLLADASW::Node node(mSW); - node.setType(COLLADASW::Node::JOINT); - node.setNodeId(node_id); - node.setNodeName(node_name); - node.setNodeSid(node_sid); + node.setType(COLLADASW::Node::JOINT); + node.setNodeId(node_id); + node.setNodeName(node_name); + node.setNodeSid(node_sid); - /*if ( bone->childbase.first == NULL || BLI_countlist(&(bone->childbase))>=2) - add_blender_leaf_bone( bone, ob_arm , node ); - else{*/ - node.start(); + /*if ( bone->childbase.first == NULL || BLI_countlist(&(bone->childbase))>=2) + add_blender_leaf_bone( bone, ob_arm , node ); + else{*/ + node.start(); - add_bone_transform(ob_arm, bone, node); + add_bone_transform(ob_arm, bone, node); - // Write nodes of childobjects, remove written objects from list - std::list::iterator i = child_objects.begin(); + // Write nodes of childobjects, remove written objects from list + std::list::iterator i = child_objects.begin(); - while (i != child_objects.end()) { - if ((*i)->partype == PARBONE && (0 == strcmp((*i)->parsubstr, bone->name))) { - float backup_parinv[4][4]; - copy_m4_m4(backup_parinv, (*i)->parentinv); + while (i != child_objects.end()) { + if ((*i)->partype == PARBONE && (0 == strcmp((*i)->parsubstr, bone->name))) { + float backup_parinv[4][4]; + copy_m4_m4(backup_parinv, (*i)->parentinv); - // crude, temporary change to parentinv - // so transform gets exported correctly. + // crude, temporary change to parentinv + // so transform gets exported correctly. - // Add bone tail- translation... don't know why - // bone parenting is against the tail of a bone - // and not it's head, seems arbitrary. - (*i)->parentinv[3][1] += bone->length; + // Add bone tail- translation... don't know why + // bone parenting is against the tail of a bone + // and not it's head, seems arbitrary. + (*i)->parentinv[3][1] += bone->length; - // SECOND_LIFE_COMPATIBILITY - // TODO: when such objects are animated as - // single matrix the tweak must be applied - // to the result. - if (export_settings->second_life) { - // tweak objects parentinverse to match compatibility - float temp[4][4]; + // SECOND_LIFE_COMPATIBILITY + // TODO: when such objects are animated as + // single matrix the tweak must be applied + // to the result. + if (export_settings->second_life) { + // tweak objects parentinverse to match compatibility + float temp[4][4]; - copy_m4_m4(temp, bone->arm_mat); - temp[3][0] = temp[3][1] = temp[3][2] = 0.0f; + copy_m4_m4(temp, bone->arm_mat); + temp[3][0] = temp[3][1] = temp[3][2] = 0.0f; - mult_m4_m4m4((*i)->parentinv, temp, (*i)->parentinv); - } + mult_m4_m4m4((*i)->parentinv, temp, (*i)->parentinv); + } - se->writeNodes(*i, sce); + se->writeNodes(*i, sce); - copy_m4_m4((*i)->parentinv, backup_parinv); - child_objects.erase(i++); + copy_m4_m4((*i)->parentinv, backup_parinv); + child_objects.erase(i++); + } + else i++; } - else i++; - } - for (Bone *child = (Bone *)bone->childbase.first; child; child = child->next) { - add_bone_node(child, ob_arm, sce, se, child_objects); + for (Bone *child = (Bone *)bone->childbase.first; child; child = child->next) { + add_bone_node(child, ob_arm, sce, se, child_objects); + } + node.end(); + } + else { + for (Bone *child = (Bone *)bone->childbase.first; child; child = child->next) { + add_bone_node(child, ob_arm, sce, se, child_objects); + } } - node.end(); - //} } #if 0 diff --git a/source/blender/collada/ArmatureExporter.h b/source/blender/collada/ArmatureExporter.h index beef77af767..a7575e9fc09 100644 --- a/source/blender/collada/ArmatureExporter.h +++ b/source/blender/collada/ArmatureExporter.h @@ -120,6 +120,8 @@ private: void add_vertex_weights_element(const std::string& weights_source_id, const std::string& joints_source_id, const std::list& vcount, const std::list& joints); + + void write_bone_URLs(COLLADASW::InstanceController &ins, Object *ob_arm, Bone *bone); }; #endif diff --git a/source/blender/collada/ExportSettings.h b/source/blender/collada/ExportSettings.h index e856eefab99..c93a1b500ae 100644 --- a/source/blender/collada/ExportSettings.h +++ b/source/blender/collada/ExportSettings.h @@ -34,10 +34,11 @@ extern "C" { struct ExportSettings { public: - bool selected; bool apply_modifiers; - bool include_armatures; + bool selected; bool include_children; + bool include_armatures; + bool deform_bones_only; bool use_object_instantiation; bool sort_by_name; bool second_life; diff --git a/source/blender/collada/collada.cpp b/source/blender/collada/collada.cpp index 9a4fd44b9e9..5b970c236a4 100644 --- a/source/blender/collada/collada.cpp +++ b/source/blender/collada/collada.cpp @@ -50,17 +50,19 @@ int collada_import(bContext *C, const char *filepath) } int collada_export( - Scene *sce, - const char *filepath, - int selected, - int apply_modifiers, + Scene *sce, + const char *filepath, - int include_armatures, - int include_children, + int apply_modifiers, - int use_object_instantiation, + int selected, + int include_children, + int include_armatures, + int deform_bones_only, + + int use_object_instantiation, int sort_by_name, - int second_life) + int second_life) { ExportSettings export_settings; @@ -73,15 +75,19 @@ int collada_export( } /* end! */ + export_settings.filepath = (char *)filepath; - export_settings.selected = selected != 0; export_settings.apply_modifiers = apply_modifiers != 0; + + export_settings.selected = selected != 0; + export_settings.include_children = include_children != 0; export_settings.include_armatures = include_armatures != 0; - export_settings.include_children = include_children != 0; - export_settings.second_life = second_life != 0; + export_settings.deform_bones_only = deform_bones_only != 0; + export_settings.use_object_instantiation = use_object_instantiation != 0; export_settings.sort_by_name = sort_by_name != 0; - export_settings.filepath = (char *)filepath; + export_settings.second_life = second_life != 0; + int includeFilter = OB_REL_NONE; if (export_settings.include_armatures) includeFilter |= OB_REL_MOD_ARMATURE; diff --git a/source/blender/collada/collada.h b/source/blender/collada/collada.h index 8daf2b65fe2..89b0e299408 100644 --- a/source/blender/collada/collada.h +++ b/source/blender/collada/collada.h @@ -40,11 +40,12 @@ extern "C" { int collada_export( Scene *sce, const char *filepath, - int selected, int apply_modifiers, - int include_armatures, + int selected, int include_children, + int include_armatures, + int deform_bones_only, int use_object_instantiation, int sort_by_name, diff --git a/source/blender/collada/collada_utils.cpp b/source/blender/collada/collada_utils.cpp index aa6f0b3c515..041ffd48f9d 100644 --- a/source/blender/collada/collada_utils.cpp +++ b/source/blender/collada/collada_utils.cpp @@ -34,11 +34,14 @@ #include "collada_utils.h" +extern "C" { + #include "DNA_modifier_types.h" #include "DNA_customdata_types.h" #include "DNA_object_types.h" #include "DNA_mesh_types.h" #include "DNA_scene_types.h" +#include "DNA_armature_types.h" #include "BLI_math.h" @@ -49,13 +52,13 @@ #include "BKE_mesh.h" #include "BKE_scene.h" -extern "C" { #include "BKE_DerivedMesh.h" #include "BLI_linklist.h" -} + #include "WM_api.h" // XXX hrm, see if we can do without this #include "WM_types.h" +} float bc_get_float_value(const COLLADAFW::FloatOrDoubleArray& array, unsigned int index) { @@ -181,6 +184,7 @@ Object *bc_get_highest_selected_ancestor_or_self(LinkNode *export_set, Object *o return ancestor; } + bool bc_is_base_node(LinkNode *export_set, Object *ob) { Object *root = bc_get_highest_selected_ancestor_or_self(export_set, ob); @@ -253,3 +257,23 @@ void bc_bubble_sort_by_Object_name(LinkNode *export_set) } } } + +/* Check if a bone is the top most exportable bone in the bone hierarchy. + * When deform_bones_only == false, then only bones with NO parent + * can be root bones. Otherwise the top most deform bones in the hierarchy + * are root bones. + */ +bool bc_is_root_bone(Bone *aBone, bool deform_bones_only) { + if(deform_bones_only) { + Bone *root = NULL; + Bone *bone = aBone; + while (bone) { + if (!(bone->flag & BONE_NO_DEFORM)) + root = bone; + bone = bone->parent; + } + return aBone==root; + } + else + return !(aBone->parent); +} diff --git a/source/blender/collada/collada_utils.h b/source/blender/collada/collada_utils.h index 139a2cb93bd..6558ad3e9ca 100644 --- a/source/blender/collada/collada_utils.h +++ b/source/blender/collada/collada_utils.h @@ -72,5 +72,6 @@ extern char *bc_CustomData_get_layer_name(const CustomData *data, int type, int extern char *bc_CustomData_get_active_layer_name(const CustomData *data, int type); extern void bc_bubble_sort_by_Object_name(LinkNode *export_set); +extern bool bc_is_root_bone(Bone *aBone, bool deform_bones_only); #endif -- cgit v1.2.3