Blender V2.61 - r43446
|
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. 00019 * 00020 * ***** END GPL LICENSE BLOCK ***** 00021 */ 00022 00028 #include <algorithm> 00029 00030 #if !defined(WIN32) || defined(FREE_WINDOWS) 00031 #include <stdint.h> 00032 #endif 00033 00034 /* COLLADABU_ASSERT, may be able to remove later */ 00035 #include "COLLADABUPlatform.h" 00036 00037 #include "BKE_object.h" 00038 #include "DNA_armature_types.h" 00039 #include "DNA_modifier_types.h" 00040 #include "ED_mesh.h" 00041 #include "ED_object.h" 00042 #include "BKE_action.h" 00043 #include "BLI_listbase.h" 00044 #include "BLI_math.h" 00045 00046 #include "SkinInfo.h" 00047 #include "collada_utils.h" 00048 00049 // use name, or fall back to original id if name not present (name is optional) 00050 template<class T> 00051 static const char *bc_get_joint_name(T *node) 00052 { 00053 const std::string& id = node->getName(); 00054 return id.size() ? id.c_str() : node->getOriginalId().c_str(); 00055 } 00056 00057 // This is used to store data passed in write_controller_data. 00058 // Arrays from COLLADAFW::SkinControllerData lose ownership, so do this class members 00059 // so that arrays don't get freed until we free them explicitly. 00060 SkinInfo::SkinInfo() {} 00061 00062 SkinInfo::SkinInfo(const SkinInfo& skin) : weights(skin.weights), 00063 joint_data(skin.joint_data), 00064 unit_converter(skin.unit_converter), 00065 ob_arm(skin.ob_arm), 00066 controller_uid(skin.controller_uid), 00067 parent(skin.parent) 00068 { 00069 copy_m4_m4(bind_shape_matrix, (float (*)[4])skin.bind_shape_matrix); 00070 00071 transfer_uint_array_data_const(skin.joints_per_vertex, joints_per_vertex); 00072 transfer_uint_array_data_const(skin.weight_indices, weight_indices); 00073 transfer_int_array_data_const(skin.joint_indices, joint_indices); 00074 } 00075 00076 SkinInfo::SkinInfo(UnitConverter *conv) : unit_converter(conv), ob_arm(NULL), parent(NULL) {} 00077 00078 // nobody owns the data after this, so it should be freed manually with releaseMemory 00079 template <class T> 00080 void SkinInfo::transfer_array_data(T& src, T& dest) 00081 { 00082 dest.setData(src.getData(), src.getCount()); 00083 src.yieldOwnerShip(); 00084 dest.yieldOwnerShip(); 00085 } 00086 00087 // when src is const we cannot src.yieldOwnerShip, this is used by copy constructor 00088 void SkinInfo::transfer_int_array_data_const(const COLLADAFW::IntValuesArray& src, COLLADAFW::IntValuesArray& dest) 00089 { 00090 dest.setData((int*)src.getData(), src.getCount()); 00091 dest.yieldOwnerShip(); 00092 } 00093 00094 void SkinInfo::transfer_uint_array_data_const(const COLLADAFW::UIntValuesArray& src, COLLADAFW::UIntValuesArray& dest) 00095 { 00096 dest.setData((unsigned int*)src.getData(), src.getCount()); 00097 dest.yieldOwnerShip(); 00098 } 00099 00100 void SkinInfo::borrow_skin_controller_data(const COLLADAFW::SkinControllerData* skin) 00101 { 00102 transfer_array_data((COLLADAFW::UIntValuesArray&)skin->getJointsPerVertex(), joints_per_vertex); 00103 transfer_array_data((COLLADAFW::UIntValuesArray&)skin->getWeightIndices(), weight_indices); 00104 transfer_array_data((COLLADAFW::IntValuesArray&)skin->getJointIndices(), joint_indices); 00105 // transfer_array_data(skin->getWeights(), weights); 00106 00107 // cannot transfer data for FloatOrDoubleArray, copy values manually 00108 const COLLADAFW::FloatOrDoubleArray& weight = skin->getWeights(); 00109 for (unsigned int i = 0; i < weight.getValuesCount(); i++) 00110 weights.push_back(bc_get_float_value(weight, i)); 00111 00112 unit_converter->dae_matrix_to_mat4_(bind_shape_matrix, skin->getBindShapeMatrix()); 00113 } 00114 00115 void SkinInfo::free() 00116 { 00117 joints_per_vertex.releaseMemory(); 00118 weight_indices.releaseMemory(); 00119 joint_indices.releaseMemory(); 00120 // weights.releaseMemory(); 00121 } 00122 00123 // using inverse bind matrices to construct armature 00124 // it is safe to invert them to get the original matrices 00125 // because if they are inverse matrices, they can be inverted 00126 void SkinInfo::add_joint(const COLLADABU::Math::Matrix4& matrix) 00127 { 00128 JointData jd; 00129 unit_converter->dae_matrix_to_mat4_(jd.inv_bind_mat, matrix); 00130 joint_data.push_back(jd); 00131 } 00132 00133 void SkinInfo::set_controller(const COLLADAFW::SkinController* co) 00134 { 00135 controller_uid = co->getUniqueId(); 00136 00137 // fill in joint UIDs 00138 const COLLADAFW::UniqueIdArray& joint_uids = co->getJoints(); 00139 for (unsigned int i = 0; i < joint_uids.getCount(); i++) { 00140 joint_data[i].joint_uid = joint_uids[i]; 00141 00142 // // store armature pointer 00143 // JointData& jd = joint_index_to_joint_info_map[i]; 00144 // jd.ob_arm = ob_arm; 00145 00146 // now we'll be able to get inv bind matrix from joint id 00147 // joint_id_to_joint_index_map[joint_ids[i]] = i; 00148 } 00149 } 00150 00151 // called from write_controller 00152 Object *SkinInfo::create_armature(Scene *scene) 00153 { 00154 ob_arm = add_object(scene, OB_ARMATURE); 00155 return ob_arm; 00156 } 00157 00158 Object* SkinInfo::set_armature(Object *ob_arm) 00159 { 00160 if (this->ob_arm) 00161 return this->ob_arm; 00162 00163 this->ob_arm = ob_arm; 00164 return ob_arm; 00165 } 00166 00167 bool SkinInfo::get_joint_inv_bind_matrix(float inv_bind_mat[][4], COLLADAFW::Node *node) 00168 { 00169 const COLLADAFW::UniqueId& uid = node->getUniqueId(); 00170 std::vector<JointData>::iterator it; 00171 for (it = joint_data.begin(); it != joint_data.end(); it++) { 00172 if ((*it).joint_uid == uid) { 00173 copy_m4_m4(inv_bind_mat, (*it).inv_bind_mat); 00174 return true; 00175 } 00176 } 00177 00178 return false; 00179 } 00180 00181 Object *SkinInfo::get_armature() 00182 { 00183 return ob_arm; 00184 } 00185 00186 const COLLADAFW::UniqueId& SkinInfo::get_controller_uid() 00187 { 00188 return controller_uid; 00189 } 00190 00191 // check if this skin controller references a joint or any descendant of it 00192 // 00193 // some nodes may not be referenced by SkinController, 00194 // in this case to determine if the node belongs to this armature, 00195 // we need to search down the tree 00196 bool SkinInfo::uses_joint_or_descendant(COLLADAFW::Node *node) 00197 { 00198 const COLLADAFW::UniqueId& uid = node->getUniqueId(); 00199 std::vector<JointData>::iterator it; 00200 for (it = joint_data.begin(); it != joint_data.end(); it++) { 00201 if ((*it).joint_uid == uid) 00202 return true; 00203 } 00204 00205 COLLADAFW::NodePointerArray& children = node->getChildNodes(); 00206 for (unsigned int i = 0; i < children.getCount(); i++) { 00207 if (uses_joint_or_descendant(children[i])) 00208 return true; 00209 } 00210 00211 return false; 00212 } 00213 00214 void SkinInfo::link_armature(bContext *C, Object *ob, std::map<COLLADAFW::UniqueId, COLLADAFW::Node*>& joint_by_uid, 00215 TransformReader *tm) 00216 { 00217 Main *bmain = CTX_data_main(C); 00218 Scene *scene = CTX_data_scene(C); 00219 00220 ModifierData *md = ED_object_modifier_add(NULL, bmain, scene, ob, NULL, eModifierType_Armature); 00221 ((ArmatureModifierData *)md)->object = ob_arm; 00222 00223 copy_m4_m4(ob->obmat, bind_shape_matrix); 00224 object_apply_mat4(ob, ob->obmat, 0, 0); 00225 #if 1 00226 bc_set_parent(ob, ob_arm, C); 00227 #else 00228 Object workob; 00229 ob->parent = ob_arm; 00230 ob->partype = PAROBJECT; 00231 00232 what_does_parent(scene, ob, &workob); 00233 invert_m4_m4(ob->parentinv, workob.obmat); 00234 00235 ob->recalc |= OB_RECALC_OB|OB_RECALC_DATA; 00236 00237 DAG_scene_sort(bmain, scene); 00238 DAG_ids_flush_update(bmain, 0); 00239 WM_event_add_notifier(C, NC_OBJECT|ND_TRANSFORM, NULL); 00240 #endif 00241 00242 ((bArmature*)ob_arm->data)->deformflag = ARM_DEF_VGROUP; 00243 00244 // create all vertex groups 00245 std::vector<JointData>::iterator it; 00246 int joint_index; 00247 for (it = joint_data.begin(), joint_index = 0; it != joint_data.end(); it++, joint_index++) { 00248 const char *name = "Group"; 00249 00250 // skip joints that have invalid UID 00251 if ((*it).joint_uid == COLLADAFW::UniqueId::INVALID) continue; 00252 00253 // name group by joint node name 00254 00255 if (joint_by_uid.find((*it).joint_uid) != joint_by_uid.end()) { 00256 name = bc_get_joint_name(joint_by_uid[(*it).joint_uid]); 00257 } 00258 00259 ED_vgroup_add_name(ob, (char*)name); 00260 } 00261 00262 // <vcount> - number of joints per vertex - joints_per_vertex 00263 // <v> - [[bone index, weight index] * joints per vertex] * vertices - weight indices 00264 // ^ bone index can be -1 meaning weight toward bind shape, how to express this in Blender? 00265 00266 // for each vertex in weight indices 00267 // for each bone index in vertex 00268 // add vertex to group at group index 00269 // treat group index -1 specially 00270 00271 // get def group by index with BLI_findlink 00272 00273 for (unsigned int vertex = 0, weight = 0; vertex < joints_per_vertex.getCount(); vertex++) { 00274 00275 unsigned int limit = weight + joints_per_vertex[vertex]; 00276 for ( ; weight < limit; weight++) { 00277 int joint = joint_indices[weight], joint_weight = weight_indices[weight]; 00278 00279 // -1 means "weight towards the bind shape", we just don't assign it to any group 00280 if (joint != -1) { 00281 bDeformGroup *def = (bDeformGroup*)BLI_findlink(&ob->defbase, joint); 00282 00283 ED_vgroup_vert_add(ob, def, vertex, weights[joint_weight], WEIGHT_REPLACE); 00284 } 00285 } 00286 } 00287 } 00288 00289 bPoseChannel *SkinInfo::get_pose_channel_from_node(COLLADAFW::Node *node) 00290 { 00291 return get_pose_channel(ob_arm->pose, bc_get_joint_name(node)); 00292 } 00293 00294 void SkinInfo::set_parent(Object *_parent) 00295 { 00296 parent = _parent; 00297 } 00298 00299 Object* SkinInfo::get_parent() 00300 { 00301 return parent; 00302 } 00303 00304 void SkinInfo::find_root_joints(const std::vector<COLLADAFW::Node*> &root_joints, 00305 std::map<COLLADAFW::UniqueId, COLLADAFW::Node*>& joint_by_uid, 00306 std::vector<COLLADAFW::Node*>& result) 00307 { 00308 std::vector<COLLADAFW::Node*>::const_iterator it; 00309 // for each root_joint 00310 for (it = root_joints.begin(); it != root_joints.end(); it++) { 00311 COLLADAFW::Node *root = *it; 00312 std::vector<JointData>::iterator ji; 00313 //for each joint_data in this skin 00314 for (ji = joint_data.begin(); ji != joint_data.end(); ji++) { 00315 //get joint node from joint map 00316 COLLADAFW::Node *joint = joint_by_uid[(*ji).joint_uid]; 00317 //find if joint node is in the tree belonging to the root_joint 00318 if (find_node_in_tree(joint, root)) { 00319 if (std::find(result.begin(), result.end(), root) == result.end()) 00320 result.push_back(root); 00321 } 00322 } 00323 } 00324 } 00325 00326 bool SkinInfo::find_node_in_tree(COLLADAFW::Node *node, COLLADAFW::Node *tree_root) 00327 { 00328 if (node == tree_root) 00329 return true; 00330 00331 COLLADAFW::NodePointerArray& children = tree_root->getChildNodes(); 00332 for (unsigned int i = 0; i < children.getCount(); i++) { 00333 if (find_node_in_tree(node, children[i])) 00334 return true; 00335 } 00336 00337 return false; 00338 }