Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGaia Clary <gaia.clary@machinimatrix.org>2016-06-03 19:26:12 +0300
committerGaia Clary <gaia.clary@machinimatrix.org>2016-06-03 19:31:51 +0300
commit38410e6e2527574176338fe7ba8711cbfdd2cc91 (patch)
treec6dd72c29b76f63bc10118adb79212d40ea088c1
parentb000a01725aff8715ad24b9202ed711a1edffec5 (diff)
changed use_connect from bool to a 3 state value (-1,0,1)
-rw-r--r--source/blender/collada/ArmatureImporter.cpp164
-rw-r--r--source/blender/collada/ArmatureImporter.h8
-rw-r--r--source/blender/collada/DocumentImporter.cpp4
-rw-r--r--source/blender/collada/ImportSettings.h1
-rw-r--r--source/blender/collada/SkinInfo.cpp1
-rw-r--r--source/blender/collada/collada.cpp2
-rw-r--r--source/blender/collada/collada.h1
-rw-r--r--source/blender/collada/collada_utils.h2
-rw-r--r--source/blender/editors/io/io_collada.c10
9 files changed, 128 insertions, 65 deletions
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<COLLADAFW::Node *>::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<COLLADAFW::UniqueId, SkinInfo>::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<Object *> &ob_arms)
{
std::vector<COLLADAFW::Node *>::iterator ri;
std::vector<std::string> 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<Object *> &objects_to_scale)
{
+ std::vector<Object *> ob_arms;
std::map<COLLADAFW::UniqueId, SkinInfo>::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<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);
+ }
+
+ 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<Object *>::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<std::string> &layer_labels)
+BoneExtended &ArmatureImporter::add_bone_extended(EditBone *bone, COLLADAFW::Node *node, int sibcount, std::vector<std::string> &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<std::string> &layer_labels);
- BoneExtended &add_bone_extended(EditBone *bone, COLLADAFW::Node * node, std::vector<std::string> &layer_labels);
+ BoneExtended &add_bone_extended(EditBone *bone, COLLADAFW::Node * node, int sibcount, std::vector<std::string> &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<Object *> &arm_objs);
/** TagsMap typedef for uid_tags_map. */
typedef std::map<std::string, ExtraTags*> 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<Object *> &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<Object *> *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::map<COLLADAFW::Unique
ModifierData *md = ED_object_modifier_add(NULL, bmain, scene, ob, NULL, eModifierType_Armature);
ArmatureModifierData *amd = (ArmatureModifierData *)md;
amd->object = 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;
diff --git a/source/blender/editors/io/io_collada.c b/source/blender/editors/io/io_collada.c
index acb8e8e7512..b1ca95efe04 100644
--- a/source/blender/editors/io/io_collada.c
+++ b/source/blender/editors/io/io_collada.c
@@ -379,6 +379,7 @@ static int wm_collada_import_exec(bContext *C, wmOperator *op)
char filename[FILE_MAX];
int import_units;
int find_chains;
+ int auto_connect;
int fix_orientation;
int min_chain_length;
@@ -390,6 +391,7 @@ static int wm_collada_import_exec(bContext *C, wmOperator *op)
/* Options panel */
import_units = RNA_boolean_get(op->ptr, "import_units");
find_chains = RNA_boolean_get(op->ptr, "find_chains");
+ auto_connect = RNA_boolean_get(op->ptr, "auto_connect");
fix_orientation = RNA_boolean_get(op->ptr, "fix_orientation");
min_chain_length = RNA_int_get(op->ptr, "min_chain_length");
@@ -398,6 +400,7 @@ static int wm_collada_import_exec(bContext *C, wmOperator *op)
C, filename,
import_units,
find_chains,
+ auto_connect,
fix_orientation,
min_chain_length))
{
@@ -432,6 +435,9 @@ static void uiCollada_importSettings(uiLayout *layout, PointerRNA *imfptr)
uiItemR(row, imfptr, "find_chains", 0, NULL, ICON_NONE);
row = uiLayoutRow(box, false);
+ uiItemR(row, imfptr, "auto_connect", 0, NULL, ICON_NONE);
+
+ row = uiLayoutRow(box, false);
uiItemR(row, imfptr, "min_chain_length", 0, NULL, ICON_NONE);
}
@@ -474,6 +480,10 @@ void WM_OT_collada_import(wmOperatorType *ot)
"find_chains", 0, "Find Bone Chains",
"Find best matching Bone Chains and ensure bones in chain are connected");
+ RNA_def_boolean(ot->srna,
+ "auto_connect", 0, "Auto Connect",
+ "set use_connect for parent bones which have exactly one child bone");
+
RNA_def_int(ot->srna,
"min_chain_length",
0,