changed use_connect from bool to a 3 state value (-1,0,1)

This commit is contained in:
Gaia Clary 2016-06-03 18:26:12 +02:00
parent b000a01725
commit 38410e6e25
9 changed files with 128 additions and 65 deletions

View File

@ -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.
*/
// 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);
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)) {
// 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;

View File

@ -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();

View File

@ -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());

View File

@ -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;

View File

@ -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);

View File

@ -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;

View File

@ -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);

View File

@ -120,7 +120,7 @@ private:
float roll;
int bone_layers;
bool use_connect;
int use_connect;
bool has_custom_tail;
bool has_custom_roll;

View File

@ -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))
{
@ -431,6 +434,9 @@ static void uiCollada_importSettings(uiLayout *layout, PointerRNA *imfptr)
row = uiLayoutRow(box, false);
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,