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-09-23 13:56:04 +0300
committerSergey Sharybin <sergey.vfx@gmail.com>2016-09-26 11:51:49 +0300
commit01ed1de0d824f3c5107fdea9bae0a54c0a4726cb (patch)
treebbd790ad5ceca730ff10ae8ceef5e72b486ccbcd
parent35f81587b58657b2497ffd1e0637edc0140713bd (diff)
Fix: Collada Importer did not import the Blender Profile information correctly when multiple objects are bound to same armature. This caused Bone tails to be placed wrong.
-rw-r--r--source/blender/collada/ArmatureImporter.cpp105
-rw-r--r--source/blender/collada/ArmatureImporter.h12
-rw-r--r--source/blender/collada/collada_utils.cpp32
-rw-r--r--source/blender/collada/collada_utils.h19
4 files changed, 110 insertions, 58 deletions
diff --git a/source/blender/collada/ArmatureImporter.cpp b/source/blender/collada/ArmatureImporter.cpp
index d97fb55af9c..0d5c482aef5 100644
--- a/source/blender/collada/ArmatureImporter.cpp
+++ b/source/blender/collada/ArmatureImporter.cpp
@@ -60,15 +60,6 @@ ArmatureImporter::ArmatureImporter(UnitConverter *conv, MeshImporterBase *mesh,
mesh_importer(mesh) {
}
-void ArmatureImporter::clear_extended_boneset()
-{
- for (std::map<std::string, BoneExtended *>::iterator it = extended_bones.begin(); it != extended_bones.end(); ++it) {
- if (it->second != NULL)
- delete it->second;
- }
- extended_bones.clear();
-}
-
ArmatureImporter::~ArmatureImporter()
{
// free skin controller data if we forget to do this earlier
@@ -76,7 +67,6 @@ ArmatureImporter::~ArmatureImporter()
for (it = skin_by_data_uid.begin(); it != skin_by_data_uid.end(); it++) {
it->second.free();
}
- clear_extended_boneset();
}
#if 0
@@ -156,8 +146,8 @@ int ArmatureImporter::create_bone(SkinInfo *skin, COLLADAFW::Node *node, EditBon
if (parent) bone->parent = parent;
float loc[3], size[3], rot[3][3];
-
- BoneExtended &be = add_bone_extended(bone, node, totchild, layer_labels);
+ BoneExtensionMap &extended_bones = bone_extension_manager.getExtensionMap(arm);
+ BoneExtended &be = add_bone_extended(bone, node, totchild, layer_labels, extended_bones);
int layer = be.get_bone_layers();
if (layer) bone->layer = layer;
arm->layer |= layer; // ensure that all populated bone layers are visible after import
@@ -205,7 +195,6 @@ int ArmatureImporter::create_bone(SkinInfo *skin, COLLADAFW::Node *node, EditBon
chain_length = cl;
}
-
bone->length = len_v3v3(bone->head, bone->tail);
joint_by_uid[node->getUniqueId()] = node;
finished_joints.push_back(node);
@@ -221,43 +210,49 @@ int ArmatureImporter::create_bone(SkinInfo *skin, COLLADAFW::Node *node, EditBon
* tail locations for the affected bones (nodes which don't have any connected child)
* Hint: The extended_bones set gets populated in ArmatureImporter::create_bone
**/
-void ArmatureImporter::fix_leaf_bones(bArmature *armature, Bone *bone, bool fix_orientation)
+void ArmatureImporter::fix_leaf_bone_hierarchy(bArmature *armature, Bone *bone, bool fix_orientation)
{
if (bone == NULL)
return;
if (bc_is_leaf_bone(bone)) {
-
+ BoneExtensionMap &extended_bones = bone_extension_manager.getExtensionMap(armature);
BoneExtended *be = extended_bones[bone->name];
- if (be == NULL || !be->has_tail()) {
+ EditBone *ebone = bc_get_edit_bone(armature, bone->name);
+ fix_leaf_bone(armature, ebone, be, fix_orientation);
+ }
+
+ for (Bone *child = (Bone *)bone->childbase.first; child; child = child->next) {
+ fix_leaf_bone_hierarchy(armature, child, fix_orientation);
+ }
+}
- /* 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;
+void ArmatureImporter::fix_leaf_bone(bArmature *armature, EditBone *ebone, BoneExtended *be , bool fix_orientation)
+{
+ if (be == NULL || !be->has_tail()) {
- EditBone *ebone = bc_get_edit_bone(armature, bone->name);
- float vec[3];
+ /* 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;
- if (ebone->parent != NULL && fix_orientation) {
- 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);
- }
- normalize_v3_v3(vec, vec);
- mul_v3_fl(vec, leaf_length);
- add_v3_v3v3(ebone->tail, ebone->head, vec);
+ float vec[3];
+
+ if (fix_orientation && 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);
}
- }
- for (Bone *child = (Bone *)bone->childbase.first; child; child = child->next) {
- fix_leaf_bones(armature, child, fix_orientation);
+ normalize_v3_v3(vec, vec);
+ mul_v3_fl(vec, leaf_length);
+ add_v3_v3v3(ebone->tail, ebone->head, vec);
}
}
@@ -280,6 +275,7 @@ void ArmatureImporter::fix_parent_connect(bArmature *armature, Bone *bone)
void ArmatureImporter::connect_bone_chains(bArmature *armature, Bone *parentbone, int clip)
{
+ BoneExtensionMap &extended_bones = bone_extension_manager.getExtensionMap(armature);
BoneExtended *dominant_child = NULL;
int maxlen = 0;
Bone *child;
@@ -445,11 +441,10 @@ ArmatureJoints& ArmatureImporter::get_armature_joints(Object *ob_arm)
return armature_joints.back();
}
#endif
-Object *ArmatureImporter::create_armature_bones(std::vector<Object *> &ob_arms)
+void 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;
//if there is an armature created for root_joint next root_joint
for (ri = root_joints.begin(); ri != root_joints.end(); ri++) {
@@ -470,15 +465,23 @@ Object *ArmatureImporter::create_armature_bones(std::vector<Object *> &ob_arms)
continue;
}
- clear_extended_boneset();
-
ED_armature_to_edit(armature);
armature->layer = 0; // layer is set according to imported bone set in create_bone()
create_bone(NULL, *ri , NULL, (*ri)->getChildNodes().getCount(), NULL, armature, layer_labels);
+ if (this->import_settings->find_chains) {
+ connect_bone_chains(armature, (Bone *)armature->bonebase.first, UNLIMITED_CHAIN_MAX);
+ }
/* exit armature edit mode to populate the Armature object */
+ ED_armature_from_edit(armature);
+ ED_armature_edit_free(armature);
+
+ ED_armature_to_edit(armature);
+
+ fix_leaf_bone_hierarchy(armature, (Bone *)armature->bonebase.first, this->import_settings->fix_orientation);
unskinned_armature_map[(*ri)->getUniqueId()] = ob_arm;
+
ED_armature_from_edit(armature);
ED_armature_edit_free(armature);
@@ -489,7 +492,6 @@ Object *ArmatureImporter::create_armature_bones(std::vector<Object *> &ob_arms)
DAG_id_tag_update(&ob_arm->id, OB_RECALC_OB | OB_RECALC_DATA);
}
- return ob_arm;
}
Object *ArmatureImporter::create_armature_bones(SkinInfo& skin)
@@ -584,8 +586,6 @@ Object *ArmatureImporter::create_armature_bones(SkinInfo& skin)
bArmature * armature = (bArmature *)ob_arm->data;
ED_armature_to_edit(armature);
- clear_extended_boneset();
-
totbone = 0;
// bone_direction_row = 1; // TODO: don't default to Y but use asset and based on it decide on default row
@@ -615,6 +615,14 @@ Object *ArmatureImporter::create_armature_bones(SkinInfo& skin)
ED_armature_from_edit(armature);
ED_armature_edit_free(armature);
+ ED_armature_to_edit(armature);
+ if (this->import_settings->find_chains) {
+ connect_bone_chains(armature, (Bone *)armature->bonebase.first, UNLIMITED_CHAIN_MAX);
+ }
+ fix_leaf_bone_hierarchy(armature, (Bone *)armature->bonebase.first, this->import_settings->fix_orientation);
+ 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;
@@ -756,11 +764,6 @@ void ArmatureImporter::make_armatures(bContext *C, std::vector<Object *> &object
/* and step back to edit mode to fix the leaf nodes */
ED_armature_to_edit(armature);
- if (this->import_settings->find_chains)
- connect_bone_chains(armature, (Bone *)armature->bonebase.first, UNLIMITED_CHAIN_MAX);
-
- fix_leaf_bones(armature, (Bone *)armature->bonebase.first, this->import_settings->fix_orientation);
-
fix_parent_connect(armature, (Bone *)armature->bonebase.first);
ED_armature_from_edit(armature);
@@ -952,7 +955,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, int sibcount, std::vector<std::string> &layer_labels)
+BoneExtended &ArmatureImporter::add_bone_extended(EditBone *bone, COLLADAFW::Node *node, int sibcount, std::vector<std::string> &layer_labels, BoneExtensionMap &extended_bones)
{
BoneExtended *be = new BoneExtended(bone);
extended_bones[bone->name] = be;
diff --git a/source/blender/collada/ArmatureImporter.h b/source/blender/collada/ArmatureImporter.h
index 524c524c9c9..17173f157e5 100644
--- a/source/blender/collada/ArmatureImporter.h
+++ b/source/blender/collada/ArmatureImporter.h
@@ -68,8 +68,7 @@ private:
// std::map<int, JointData> joint_index_to_joint_info_map;
// std::map<COLLADAFW::UniqueId, int> joint_id_to_joint_index_map;
-
- std::map<std::string, BoneExtended *> extended_bones;
+ BoneExtensionManager bone_extension_manager;
// int bone_direction_row; // XXX not used
float leaf_bone_length;
int totbone;
@@ -108,16 +107,15 @@ 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, int sibcount, std::vector<std::string> &layer_labels);
- void clear_extended_boneset();
+ BoneExtended &add_bone_extended(EditBone *bone, COLLADAFW::Node * node, int sibcount, std::vector<std::string> &layer_labels, BoneExtensionMap &extended_bones);
- void fix_leaf_bones(bArmature *armature, Bone *bone, bool fix_orientation);
+ void fix_leaf_bone_hierarchy(bArmature *armature, Bone *bone, bool fix_orientation);
+ void fix_leaf_bone(bArmature *armature, EditBone *ebone, BoneExtended *be, bool fix_orientation);
void fix_parent_connect(bArmature *armature, Bone *bone);
void connect_bone_chains(bArmature *armature, Bone *bone, const int max_chain_length);
void set_pose( Object *ob_arm, COLLADAFW::Node *root_node, const char *parentname, float parent_mat[4][4]);
-
#if 0
void set_leaf_bone_shapes(Object *ob_arm);
void set_euler_rotmode();
@@ -132,7 +130,7 @@ private:
#endif
Object *create_armature_bones(SkinInfo& skin);
- Object *create_armature_bones(std::vector<Object *> &arm_objs);
+ void create_armature_bones(std::vector<Object *> &arm_objs);
/** TagsMap typedef for uid_tags_map. */
typedef std::map<std::string, ExtraTags*> TagsMap;
diff --git a/source/blender/collada/collada_utils.cpp b/source/blender/collada/collada_utils.cpp
index abe5130b9c1..2efa8b21d81 100644
--- a/source/blender/collada/collada_utils.cpp
+++ b/source/blender/collada/collada_utils.cpp
@@ -412,6 +412,38 @@ int bc_set_layer(int bitfield, int layer, bool enable)
return bitfield;
}
+/*
+ | This method creates a new extension map when needed.
+ | Note: The ~BoneExtensionManager destructor takes care
+ | to delete the created maps when the manager is removed.
+*/
+BoneExtensionMap &BoneExtensionManager::getExtensionMap(bArmature *armature)
+{
+ std::string key = armature->id.name;
+ BoneExtensionMap *result = extended_bone_maps[key];
+ if (result == NULL)
+ {
+ result = new BoneExtensionMap();
+ extended_bone_maps[key] = result;
+ }
+ return *result;
+}
+
+BoneExtensionManager::~BoneExtensionManager()
+{
+ std::map<std::string, BoneExtensionMap *>::iterator map_it;
+ for (map_it = extended_bone_maps.begin(); map_it != extended_bone_maps.end(); ++map_it)
+ {
+ BoneExtensionMap *extended_bones = map_it->second;
+ for (BoneExtensionMap::iterator ext_it = extended_bones->begin(); ext_it != extended_bones->end(); ++ext_it) {
+ if (ext_it->second != NULL)
+ delete ext_it->second;
+ }
+ extended_bones->clear();
+ delete extended_bones;
+ }
+}
+
/**
* BoneExtended is a helper class needed for the Bone chain finder
* See ArmatureImporter::fix_leaf_bones()
diff --git a/source/blender/collada/collada_utils.h b/source/blender/collada/collada_utils.h
index ee371f7959e..7fdbef3b6cb 100644
--- a/source/blender/collada/collada_utils.h
+++ b/source/blender/collada/collada_utils.h
@@ -153,5 +153,24 @@ public:
int get_use_connect();
};
+/* a map to store bone extension maps
+| std:string : an armature name
+| BoneExtended * : a map that contains extra data for bones
+*/
+typedef std::map<std::string, BoneExtended *> BoneExtensionMap;
+
+/*
+| A class to organise bone extendion data for multiple Armatures.
+| this is needed for the case where a Collada file contains 2 or more
+| separate armatures.
+*/
+class BoneExtensionManager {
+private:
+ std::map<std::string, BoneExtensionMap *> extended_bone_maps;
+
+public:
+ BoneExtensionMap &getExtensionMap(bArmature *armature);
+ ~BoneExtensionManager();
+};
#endif