Blender V2.61 - r43446

ArmatureImporter.cpp

Go to the documentation of this file.
00001 /*
00002  * ***** BEGIN GPL LICENSE BLOCK *****
00003  *
00004  * This program is free software; you can redistribute it and/or
00005  * modify it under the terms of the GNU General Public License
00006  * as published by the Free Software Foundation; either version 2
00007  * of the License, or (at your option) any later version.
00008  *
00009  * This program is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  * GNU General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU General Public License
00015  * along with this program; if not, write to the Free Software Foundation,
00016  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00017  *
00018  * Contributor(s): Chingiz Dyussenov, Arystanbek Dyussenov, Nathan Letwory, Sukhitha jayathilake.
00019  *
00020  * ***** END GPL LICENSE BLOCK *****
00021  */
00022 
00028 /* COLLADABU_ASSERT, may be able to remove later */
00029 #include "COLLADABUPlatform.h"
00030 
00031 #include <algorithm>
00032 
00033 #include "COLLADAFWUniqueId.h"
00034 
00035 #include "BKE_action.h"
00036 #include "BKE_depsgraph.h"
00037 #include "BKE_object.h"
00038 #include "BKE_armature.h"
00039 #include "BLI_string.h"
00040 #include "ED_armature.h"
00041 
00042 #include "ArmatureImporter.h"
00043 
00044 // use node name, or fall back to original id if not present (name is optional)
00045 template<class T>
00046 static const char *bc_get_joint_name(T *node)
00047 {
00048     const std::string& id = node->getName();
00049     return id.size() ? id.c_str() : node->getOriginalId().c_str();
00050 }
00051 
00052 ArmatureImporter::ArmatureImporter(UnitConverter *conv, MeshImporterBase *mesh, AnimationImporterBase *anim, Scene *sce) :
00053     TransformReader(conv), scene(sce), empty(NULL), mesh_importer(mesh), anim_importer(anim) {}
00054 
00055 ArmatureImporter::~ArmatureImporter()
00056 {
00057     // free skin controller data if we forget to do this earlier
00058     std::map<COLLADAFW::UniqueId, SkinInfo>::iterator it;
00059     for (it = skin_by_data_uid.begin(); it != skin_by_data_uid.end(); it++) {
00060         it->second.free();
00061     }
00062 }
00063 
00064 #if 0
00065 JointData *ArmatureImporter::get_joint_data(COLLADAFW::Node *node);
00066 {
00067     const COLLADAFW::UniqueId& joint_id = node->getUniqueId();
00068 
00069     if (joint_id_to_joint_index_map.find(joint_id) == joint_id_to_joint_index_map.end()) {
00070         fprintf(stderr, "Cannot find a joint index by joint id for %s.\n",
00071                 node->getOriginalId().c_str());
00072         return NULL;
00073     }
00074 
00075     int joint_index = joint_id_to_joint_index_map[joint_id];
00076 
00077     return &joint_index_to_joint_info_map[joint_index];
00078 }
00079 #endif
00080 void ArmatureImporter::create_unskinned_bone( COLLADAFW::Node *node, EditBone *parent, int totchild,
00081                  float parent_mat[][4], Object * ob_arm)
00082 {
00083     std::vector<COLLADAFW::Node*>::iterator it;
00084     it = std::find(finished_joints.begin(),finished_joints.end(),node);
00085     if ( it != finished_joints.end()) return; 
00086 
00087     float mat[4][4];
00088     float obmat[4][4];
00089 
00090     // object-space
00091     get_node_mat(obmat, node, NULL, NULL);
00092 
00093     EditBone *bone = ED_armature_edit_bone_add((bArmature*)ob_arm->data, (char*)bc_get_joint_name(node));
00094     totbone++;
00095     
00096     if (parent) bone->parent = parent;
00097 
00098     float angle = 0;
00099 
00100     // get world-space
00101     if (parent){
00102         mult_m4_m4m4(mat, parent_mat, obmat);
00103 
00104     }
00105     else {
00106         copy_m4_m4(mat, obmat);
00107 
00108     }
00109     float loc[3], size[3], rot[3][3];
00110     mat4_to_loc_rot_size( loc, rot, size, obmat);
00111     mat3_to_vec_roll(rot, NULL, &angle );
00112     bone->roll=angle;
00113     // set head
00114     copy_v3_v3(bone->head, mat[3]);
00115 
00116     // set tail, don't set it to head because 0-length bones are not allowed
00117     float vec[3] = {0.0f, 0.5f, 0.0f};
00118     add_v3_v3v3(bone->tail, bone->head, vec);
00119 
00120     // set parent tail
00121     if (parent && totchild == 1) {
00122         copy_v3_v3(parent->tail, bone->head);
00123         
00124         // not setting BONE_CONNECTED because this would lock child bone location with respect to parent
00125         // bone->flag |= BONE_CONNECTED;
00126     
00127         // XXX increase this to prevent "very" small bones?
00128         const float epsilon = 0.000001f;
00129 
00130         // derive leaf bone length
00131         float length = len_v3v3(parent->head, parent->tail);
00132         if ((length < leaf_bone_length || totbone == 0) && length > epsilon) {
00133             leaf_bone_length = length;
00134         }
00135 
00136         // treat zero-sized bone like a leaf bone
00137         if (length <= epsilon) {
00138             add_leaf_bone(parent_mat, parent, node);
00139         }
00140 
00141     }
00142 
00143     COLLADAFW::NodePointerArray& children = node->getChildNodes();
00144     for (unsigned int i = 0; i < children.getCount(); i++) {
00145         create_unskinned_bone( children[i], bone, children.getCount(), mat, ob_arm);
00146     }
00147 
00148     // in second case it's not a leaf bone, but we handle it the same way
00149     if (!children.getCount() || children.getCount() > 1) {
00150         add_leaf_bone(mat, bone, node);
00151     }
00152 
00153     finished_joints.push_back(node);
00154 
00155 }
00156 
00157 void ArmatureImporter::create_bone(SkinInfo& skin, COLLADAFW::Node *node, EditBone *parent, int totchild,
00158                  float parent_mat[][4], bArmature *arm)
00159 {
00160     //Checking if bone is already made.
00161     std::vector<COLLADAFW::Node*>::iterator it;
00162     it = std::find(finished_joints.begin(),finished_joints.end(),node);
00163     if ( it != finished_joints.end()) return; 
00164 
00165     float joint_inv_bind_mat[4][4];
00166 
00167     // JointData* jd = get_joint_data(node);
00168 
00169     float mat[4][4];
00170 
00171     // TODO rename from Node "name" attrs later
00172     EditBone *bone = ED_armature_edit_bone_add(arm, (char*)bc_get_joint_name(node));
00173     totbone++;
00174 
00175     if (skin.get_joint_inv_bind_matrix(joint_inv_bind_mat, node)) {
00176         // get original world-space matrix
00177         invert_m4_m4(mat, joint_inv_bind_mat);
00178     }
00179     // create a bone even if there's no joint data for it (i.e. it has no influence)
00180     else {
00181         float obmat[4][4];
00182 
00183         // object-space
00184         get_node_mat(obmat, node, NULL, NULL);
00185 
00186         // get world-space
00187         if (parent)
00188             mult_m4_m4m4(mat, parent_mat, obmat);
00189         else
00190             copy_m4_m4(mat, obmat);
00191 
00192         float loc[3], size[3], rot[3][3] , angle;
00193         mat4_to_loc_rot_size( loc, rot, size, obmat);
00194         mat3_to_vec_roll(rot, NULL, &angle );
00195         bone->roll=angle;
00196     }
00197 
00198     
00199     if (parent) bone->parent = parent;
00200 
00201     // set head
00202     copy_v3_v3(bone->head, mat[3]);
00203 
00204     // set tail, don't set it to head because 0-length bones are not allowed
00205     float vec[3] = {0.0f, 0.5f, 0.0f};
00206     add_v3_v3v3(bone->tail, bone->head, vec);
00207 
00208     // set parent tail
00209     if (parent && totchild == 1) {
00210         copy_v3_v3(parent->tail, bone->head);
00211 
00212         // not setting BONE_CONNECTED because this would lock child bone location with respect to parent
00213         // bone->flag |= BONE_CONNECTED;
00214 
00215         // XXX increase this to prevent "very" small bones?
00216         const float epsilon = 0.000001f;
00217 
00218         // derive leaf bone length
00219         float length = len_v3v3(parent->head, parent->tail);
00220         if ((length < leaf_bone_length || totbone == 0) && length > epsilon) {
00221             leaf_bone_length = length;
00222         }
00223 
00224         // treat zero-sized bone like a leaf bone
00225         if (length <= epsilon) {
00226             add_leaf_bone(parent_mat, parent, node);
00227         }
00228 
00229         /*
00230 #if 0
00231         // and which row in mat is bone direction
00232         float vec[3];
00233         sub_v3_v3v3(vec, parent->tail, parent->head);
00234 #ifdef COLLADA_DEBUG
00235         print_v3("tail - head", vec);
00236         print_m4("matrix", parent_mat);
00237 #endif
00238         for (int i = 0; i < 3; i++) {
00239 #ifdef COLLADA_DEBUG
00240             char *axis_names[] = {"X", "Y", "Z"};
00241             printf("%s-axis length is %f\n", axis_names[i], len_v3(parent_mat[i]));
00242 #endif
00243             float angle = angle_v2v2(vec, parent_mat[i]);
00244             if (angle < min_angle) {
00245 #ifdef COLLADA_DEBUG
00246                 print_v3("picking", parent_mat[i]);
00247                 printf("^ %s axis of %s's matrix\n", axis_names[i], get_dae_name(node));
00248 #endif
00249                 bone_direction_row = i;
00250                 min_angle = angle;
00251             }
00252         }
00253 #endif
00254         */
00255     }
00256 
00257     COLLADAFW::NodePointerArray& children = node->getChildNodes();
00258     for (unsigned int i = 0; i < children.getCount(); i++) {
00259         create_bone(skin, children[i], bone, children.getCount(), mat, arm);
00260     }
00261 
00262     // in second case it's not a leaf bone, but we handle it the same way
00263     if (!children.getCount() || children.getCount() > 1) {
00264         add_leaf_bone(mat, bone , node);
00265     }
00266 
00267     finished_joints.push_back(node);
00268 }
00269 
00270 void ArmatureImporter::add_leaf_bone(float mat[][4], EditBone *bone,  COLLADAFW::Node * node)
00271 {
00272     LeafBone leaf;
00273 
00274     leaf.bone = bone;
00275     copy_m4_m4(leaf.mat, mat);
00276     BLI_strncpy(leaf.name, bone->name, sizeof(leaf.name));
00277     
00278     TagsMap::iterator etit;
00279     ExtraTags *et = 0;
00280     etit = uid_tags_map.find(node->getUniqueId().toAscii());
00281     if(etit !=  uid_tags_map.end())
00282     {
00283         et = etit->second;
00284         //else return;
00285 
00286         float x,y,z;
00287         et->setData("tip_x",&x);
00288         et->setData("tip_y",&y);
00289         et->setData("tip_z",&z);
00290         float vec[3] = {x,y,z};
00291         copy_v3_v3(leaf.bone->tail, leaf.bone->head);
00292         add_v3_v3v3(leaf.bone->tail, leaf.bone->head, vec);
00293     }else
00294         leaf_bones.push_back(leaf);
00295 }
00296 
00297 void ArmatureImporter::fix_leaf_bones( )
00298 {
00299     // just setting tail for leaf bones here
00300 
00301     std::vector<LeafBone>::iterator it;
00302     for (it = leaf_bones.begin(); it != leaf_bones.end(); it++) {
00303         LeafBone& leaf = *it;
00304 
00305         // pointing up
00306         float vec[3] = {0.0f, 0.0f, 0.1f};
00307         
00308         // if parent: take parent length and direction
00309         if(leaf.bone->parent) sub_v3_v3v3(vec, leaf.bone->parent->tail, leaf.bone->parent->head);
00310 
00311         copy_v3_v3(leaf.bone->tail, leaf.bone->head);
00312         add_v3_v3v3(leaf.bone->tail, leaf.bone->head, vec);
00313     }
00314 }
00315 
00316 #if 0
00317 void ArmatureImporter::set_leaf_bone_shapes(Object *ob_arm)
00318 {
00319     bPose *pose = ob_arm->pose;
00320 
00321     std::vector<LeafBone>::iterator it;
00322     for (it = leaf_bones.begin(); it != leaf_bones.end(); it++) {
00323         LeafBone& leaf = *it;
00324 
00325         bPoseChannel *pchan = get_pose_channel(pose, leaf.name);
00326         if (pchan) {
00327             pchan->custom = get_empty_for_leaves();
00328         }
00329         else {
00330             fprintf(stderr, "Cannot find a pose channel for leaf bone %s\n", leaf.name);
00331         }
00332     }
00333 }
00334 
00335 void ArmatureImporter::set_euler_rotmode()
00336 {
00337     // just set rotmode = ROT_MODE_EUL on pose channel for each joint
00338 
00339     std::map<COLLADAFW::UniqueId, COLLADAFW::Node*>::iterator it;
00340 
00341     for (it = joint_by_uid.begin(); it != joint_by_uid.end(); it++) {
00342 
00343         COLLADAFW::Node *joint = it->second;
00344 
00345         std::map<COLLADAFW::UniqueId, SkinInfo>::iterator sit;
00346         
00347         for (sit = skin_by_data_uid.begin(); sit != skin_by_data_uid.end(); sit++) {
00348             SkinInfo& skin = sit->second;
00349 
00350             if (skin.uses_joint_or_descendant(joint)) {
00351                 bPoseChannel *pchan = skin.get_pose_channel_from_node(joint);
00352 
00353                 if (pchan) {
00354                     pchan->rotmode = ROT_MODE_EUL;
00355                 }
00356                 else {
00357                     fprintf(stderr, "Cannot find pose channel for %s.\n", get_joint_name(joint));
00358                 }
00359 
00360                 break;
00361             }
00362         }
00363     }
00364 }
00365 #endif
00366 
00367 Object *ArmatureImporter::get_empty_for_leaves()
00368 {
00369     if (empty) return empty;
00370     
00371     empty = add_object(scene, OB_EMPTY);
00372     empty->empty_drawtype = OB_EMPTY_SPHERE;
00373 
00374     return empty;
00375 }
00376 
00377 #if 0
00378 Object *ArmatureImporter::find_armature(COLLADAFW::Node *node)
00379 {
00380     JointData* jd = get_joint_data(node);
00381     if (jd) return jd->ob_arm;
00382 
00383     COLLADAFW::NodePointerArray& children = node->getChildNodes();
00384     for (int i = 0; i < children.getCount(); i++) {
00385         Object *ob_arm = find_armature(children[i]);
00386         if (ob_arm) return ob_arm;
00387     }
00388 
00389     return NULL;
00390 }
00391 
00392 ArmatureJoints& ArmatureImporter::get_armature_joints(Object *ob_arm)
00393 {
00394     // try finding it
00395     std::vector<ArmatureJoints>::iterator it;
00396     for (it = armature_joints.begin(); it != armature_joints.end(); it++) {
00397         if ((*it).ob_arm == ob_arm) return *it;
00398     }
00399 
00400     // not found, create one
00401     ArmatureJoints aj;
00402     aj.ob_arm = ob_arm;
00403     armature_joints.push_back(aj);
00404 
00405     return armature_joints.back();
00406 }
00407 #endif
00408 void ArmatureImporter::create_armature_bones( )
00409 {
00410     std::vector<COLLADAFW::Node*>::iterator ri;
00411     //if there is an armature created for root_joint next root_joint
00412     for (ri = root_joints.begin(); ri != root_joints.end(); ri++) {
00413             if ( get_armature_for_joint(*ri) != NULL ) continue;
00414         
00415         //add armature object for current joint
00416         //Object *ob_arm = add_object(scene, OB_ARMATURE);
00417 
00418         Object *ob_arm = joint_parent_map[(*ri)->getUniqueId()];
00419         //ob_arm->type = OB_ARMATURE;
00420         ED_armature_to_edit(ob_arm);
00421 
00422         // min_angle = 360.0f;      // minimum angle between bone head-tail and a row of bone matrix
00423 
00424         // create unskinned bones
00425         /*
00426            TODO:
00427            check if bones have already been created for a given joint
00428         */
00429         leaf_bone_length = FLT_MAX;
00430         create_unskinned_bone(*ri, NULL, (*ri)->getChildNodes().getCount(), NULL, ob_arm);
00431 
00432         fix_leaf_bones();
00433 
00434     // exit armature edit mode
00435     
00436     unskinned_armature_map[(*ri)->getUniqueId()] = ob_arm;
00437 
00438     ED_armature_from_edit(ob_arm);
00439 
00440     set_pose(ob_arm , *ri, NULL, NULL ); 
00441 
00442     ED_armature_edit_free(ob_arm);
00443     DAG_id_tag_update(&ob_arm->id, OB_RECALC_OB|OB_RECALC_DATA);
00444     }
00445 
00446     
00447 }
00448 
00449 void ArmatureImporter::create_armature_bones(SkinInfo& skin)
00450 {
00451     // just do like so:
00452     // - get armature
00453     // - enter editmode
00454     // - add edit bones and head/tail properties using matrices and parent-child info
00455     // - exit edit mode
00456     // - set a sphere shape to leaf bones
00457 
00458     Object *ob_arm = NULL;
00459 
00460     /*
00461      * find if there's another skin sharing at least one bone with this skin
00462      * if so, use that skin's armature
00463      */
00464 
00465     /*
00466       Pseudocode:
00467 
00468       find_node_in_tree(node, root_joint)
00469 
00470       skin::find_root_joints(root_joints):
00471         std::vector root_joints;
00472         for each root in root_joints:
00473             for each joint in joints:
00474                 if find_node_in_tree(joint, root):
00475                     if (std::find(root_joints.begin(), root_joints.end(), root) == root_joints.end())
00476                         root_joints.push_back(root);
00477 
00478       for (each skin B with armature) {
00479           find all root joints for skin B
00480 
00481           for each joint X in skin A:
00482             for each root joint R in skin B:
00483                 if (find_node_in_tree(X, R)) {
00484                     shared = 1;
00485                     goto endloop;
00486                 }
00487       }
00488 
00489       endloop:
00490     */
00491 
00492     SkinInfo *a = &skin;
00493     Object *shared = NULL;
00494     std::vector<COLLADAFW::Node*> skin_root_joints;
00495 
00496     std::map<COLLADAFW::UniqueId, SkinInfo>::iterator it;
00497     for (it = skin_by_data_uid.begin(); it != skin_by_data_uid.end(); it++) {
00498         SkinInfo *b = &it->second;
00499         if (b == a || b->get_armature() == NULL)
00500             continue;
00501 
00502         skin_root_joints.clear();
00503 
00504         b->find_root_joints(root_joints, joint_by_uid, skin_root_joints);
00505 
00506         std::vector<COLLADAFW::Node*>::iterator ri;
00507         for (ri = skin_root_joints.begin(); ri != skin_root_joints.end(); ri++) {
00508             if (a->uses_joint_or_descendant(*ri)) {
00509                 shared = b->get_armature();
00510                 break;
00511             }
00512         }
00513 
00514         if (shared != NULL)
00515             break;
00516     }
00517 
00518     if (shared)
00519         ob_arm = skin.set_armature(shared);
00520     else
00521         ob_arm = skin.create_armature(scene); //once for every armature
00522 
00523     // enter armature edit mode
00524     ED_armature_to_edit(ob_arm);
00525 
00526     leaf_bones.clear();
00527     totbone = 0;
00528     // bone_direction_row = 1; // TODO: don't default to Y but use asset and based on it decide on default row
00529     leaf_bone_length = FLT_MAX;
00530     // min_angle = 360.0f;      // minimum angle between bone head-tail and a row of bone matrix
00531 
00532     // create bones
00533     /*
00534        TODO:
00535        check if bones have already been created for a given joint
00536     */
00537 
00538     std::vector<COLLADAFW::Node*>::iterator ri;
00539     for (ri = root_joints.begin(); ri != root_joints.end(); ri++) {
00540         // for shared armature check if bone tree is already created
00541         if (shared && std::find(skin_root_joints.begin(), skin_root_joints.end(), *ri) != skin_root_joints.end())
00542             continue;
00543 
00544         // since root_joints may contain joints for multiple controllers, we need to filter
00545         if (skin.uses_joint_or_descendant(*ri)) {
00546             create_bone(skin, *ri, NULL, (*ri)->getChildNodes().getCount(), NULL, (bArmature*)ob_arm->data);
00547 
00548             if (joint_parent_map.find((*ri)->getUniqueId()) != joint_parent_map.end() && !skin.get_parent())
00549                 skin.set_parent(joint_parent_map[(*ri)->getUniqueId()]);
00550         }
00551     }
00552 
00553     fix_leaf_bones();
00554 
00555     // exit armature edit mode
00556     ED_armature_from_edit(ob_arm);
00557     ED_armature_edit_free(ob_arm);
00558     DAG_id_tag_update(&ob_arm->id, OB_RECALC_OB|OB_RECALC_DATA);
00559 
00560     // set_leaf_bone_shapes(ob_arm);
00561     // set_euler_rotmode();
00562 }
00563 
00564 
00565 // root - if this joint is the top joint in hierarchy, if a joint
00566 // is a child of a node (not joint), root should be true since
00567 // this is where we build armature bones from
00568 
00569 void ArmatureImporter::set_pose ( Object * ob_arm ,  COLLADAFW::Node * root_node , const char *parentname, float parent_mat[][4])
00570 { 
00571     char * bone_name = (char *) bc_get_joint_name ( root_node);
00572     float mat[4][4];
00573    float obmat[4][4];
00574 
00575     float ax[3];
00576     float angle = 0.0f;
00577     
00578     // object-space
00579     get_node_mat(obmat, root_node, NULL, NULL);
00580 
00581     //if(*edbone)
00582     bPoseChannel * pchan  = get_pose_channel(ob_arm -> pose ,  bone_name); 
00583     //else fprintf ( "",
00584 
00585     // get world-space
00586     if (parentname){
00587         mult_m4_m4m4(mat, parent_mat, obmat);
00588         bPoseChannel *parchan = get_pose_channel(ob_arm->pose, parentname);
00589 
00590         mult_m4_m4m4(pchan->pose_mat, parchan->pose_mat, mat );
00591 
00592     }
00593     else {
00594         copy_m4_m4(mat, obmat);
00595         float invObmat[4][4];
00596         invert_m4_m4(invObmat, ob_arm->obmat);
00597         mult_m4_m4m4(pchan->pose_mat, invObmat, mat);
00598     }
00599 
00600     mat4_to_axis_angle(ax,&angle,mat);
00601     pchan->bone->roll = angle;
00602 
00603 
00604     COLLADAFW::NodePointerArray& children = root_node->getChildNodes();
00605     for (unsigned int i = 0; i < children.getCount(); i++) {
00606         set_pose(ob_arm, children[i], bone_name, mat);
00607     }
00608 
00609 }
00610 
00611 void ArmatureImporter::add_joint(COLLADAFW::Node *node, bool root, Object *parent, Scene *sce)
00612 {
00613     joint_by_uid[node->getUniqueId()] = node;
00614     if (root) {
00615         root_joints.push_back(node);
00616 
00617         if (parent) {
00618                     
00619             joint_parent_map[node->getUniqueId()] = parent;
00620         }
00621     }
00622 }
00623 
00624 #if 0
00625 void ArmatureImporter::add_root_joint(COLLADAFW::Node *node)
00626 {
00627     // root_joints.push_back(node);
00628     Object *ob_arm = find_armature(node);
00629     if (ob_arm) {
00630         get_armature_joints(ob_arm).root_joints.push_back(node);
00631     }
00632 #ifdef COLLADA_DEBUG
00633     else {
00634         fprintf(stderr, "%s cannot be added to armature.\n", get_joint_name(node));
00635     }
00636 #endif
00637 }
00638 #endif
00639 
00640 // here we add bones to armatures, having armatures previously created in write_controller
00641 void ArmatureImporter::make_armatures(bContext *C)
00642 {
00643     std::map<COLLADAFW::UniqueId, SkinInfo>::iterator it;
00644     for (it = skin_by_data_uid.begin(); it != skin_by_data_uid.end(); it++) {
00645 
00646         SkinInfo& skin = it->second;
00647 
00648         create_armature_bones(skin);
00649 
00650         // link armature with a mesh object
00651         Object *ob = mesh_importer->get_object_by_geom_uid(*get_geometry_uid(skin.get_controller_uid()));
00652         if (ob)
00653             skin.link_armature(C, ob, joint_by_uid, this);
00654         else
00655             fprintf(stderr, "Cannot find object to link armature with.\n");
00656 
00657         // set armature parent if any
00658         Object *par = skin.get_parent();
00659         if (par)
00660             bc_set_parent(skin.get_armature(), par, C, false);
00661 
00662         // free memory stolen from SkinControllerData
00663         skin.free();
00664     }
00665     
00666     //for bones without skins
00667     create_armature_bones();
00668 }
00669 
00670 #if 0
00671 // link with meshes, create vertex groups, assign weights
00672 void ArmatureImporter::link_armature(Object *ob_arm, const COLLADAFW::UniqueId& geom_id, const COLLADAFW::UniqueId& controller_data_id)
00673 {
00674     Object *ob = mesh_importer->get_object_by_geom_uid(geom_id);
00675 
00676     if (!ob) {
00677         fprintf(stderr, "Cannot find object by geometry UID.\n");
00678         return;
00679     }
00680 
00681     if (skin_by_data_uid.find(controller_data_id) == skin_by_data_uid.end()) {
00682         fprintf(stderr, "Cannot find skin info by controller data UID.\n");
00683         return;
00684     }
00685 
00686     SkinInfo& skin = skin_by_data_uid[conroller_data_id];
00687 
00688     // create vertex groups
00689 }
00690 #endif
00691 
00692 bool ArmatureImporter::write_skin_controller_data(const COLLADAFW::SkinControllerData* data)
00693 {
00694     // at this stage we get vertex influence info that should go into me->verts and ob->defbase
00695     // there's no info to which object this should be long so we associate it with skin controller data UID
00696 
00697     // don't forget to call defgroup_unique_name before we copy
00698 
00699     // controller data uid -> [armature] -> joint data, 
00700     // [mesh object]
00701     // 
00702 
00703     SkinInfo skin(unit_converter);
00704     skin.borrow_skin_controller_data(data);
00705 
00706     // store join inv bind matrix to use it later in armature construction
00707     const COLLADAFW::Matrix4Array& inv_bind_mats = data->getInverseBindMatrices();
00708     for (unsigned int i = 0; i < data->getJointsCount(); i++) {
00709         skin.add_joint(inv_bind_mats[i]);
00710     }
00711 
00712     skin_by_data_uid[data->getUniqueId()] = skin;
00713 
00714     return true;
00715 }
00716 
00717 bool ArmatureImporter::write_controller(const COLLADAFW::Controller* controller)
00718 {
00719     // - create and store armature object
00720 
00721     const COLLADAFW::UniqueId& skin_id = controller->getUniqueId();
00722 
00723     if (controller->getControllerType() == COLLADAFW::Controller::CONTROLLER_TYPE_SKIN) {
00724         COLLADAFW::SkinController *co = (COLLADAFW::SkinController*)controller;
00725         // to be able to find geom id by controller id
00726         geom_uid_by_controller_uid[skin_id] = co->getSource();
00727 
00728         const COLLADAFW::UniqueId& data_uid = co->getSkinControllerData();
00729         if (skin_by_data_uid.find(data_uid) == skin_by_data_uid.end()) {
00730             fprintf(stderr, "Cannot find skin by controller data UID.\n");
00731             return true;
00732         }
00733 
00734         skin_by_data_uid[data_uid].set_controller(co);
00735     }
00736     // morph controller
00737     else {
00738         // shape keys? :)
00739         fprintf(stderr, "Morph controller is not supported yet.\n");
00740     }
00741 
00742     return true;
00743 }
00744 
00745 
00746 COLLADAFW::UniqueId *ArmatureImporter::get_geometry_uid(const COLLADAFW::UniqueId& controller_uid)
00747 {
00748     if (geom_uid_by_controller_uid.find(controller_uid) == geom_uid_by_controller_uid.end())
00749         return NULL;
00750 
00751     return &geom_uid_by_controller_uid[controller_uid];
00752 }
00753 
00754 Object *ArmatureImporter::get_armature_for_joint(COLLADAFW::Node *node)
00755 {
00756     std::map<COLLADAFW::UniqueId, SkinInfo>::iterator it;
00757     for (it = skin_by_data_uid.begin(); it != skin_by_data_uid.end(); it++) {
00758         SkinInfo& skin = it->second;
00759 
00760         if (skin.uses_joint_or_descendant(node))
00761             return skin.get_armature();
00762     }
00763 
00764     std::map<COLLADAFW::UniqueId, Object*>::iterator arm;
00765     for (arm = unskinned_armature_map.begin(); arm != unskinned_armature_map.end(); arm++) {
00766         if(arm->first == node->getUniqueId() )
00767             return arm->second;
00768     }
00769     return NULL;
00770 }
00771 
00772 void ArmatureImporter::set_tags_map(TagsMap & tagsMap)
00773 {
00774     this->uid_tags_map = tagsMap;
00775 }
00776 
00777 void ArmatureImporter::get_rna_path_for_joint(COLLADAFW::Node *node, char *joint_path, size_t count)
00778 {
00779     BLI_snprintf(joint_path, count, "pose.bones[\"%s\"]", bc_get_joint_name(node));
00780 }
00781 
00782 // gives a world-space mat
00783 bool ArmatureImporter::get_joint_bind_mat(float m[][4], COLLADAFW::Node *joint)
00784 {
00785     std::map<COLLADAFW::UniqueId, SkinInfo>::iterator it;
00786     bool found = false;
00787     for (it = skin_by_data_uid.begin(); it != skin_by_data_uid.end(); it++) {
00788         SkinInfo& skin = it->second;
00789         if ((found = skin.get_joint_inv_bind_matrix(m, joint))) {
00790             invert_m4(m);
00791             break;
00792         }
00793     }
00794 
00795     return found;
00796 }
00797 
00798 
00799