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, Jan Diederich, Tod Liverseed, 00019 * Nathan Letwory 00020 * 00021 * ***** END GPL LICENSE BLOCK ***** 00022 */ 00023 00029 #include "COLLADASWBaseInputElement.h" 00030 #include "COLLADASWInstanceController.h" 00031 #include "COLLADASWPrimitves.h" 00032 #include "COLLADASWSource.h" 00033 00034 #include "DNA_action_types.h" 00035 #include "DNA_meshdata_types.h" 00036 #include "DNA_modifier_types.h" 00037 00038 #include "BKE_action.h" 00039 #include "BKE_armature.h" 00040 #include "ED_armature.h" 00041 00042 #include "BLI_listbase.h" 00043 00044 #include "GeometryExporter.h" 00045 #include "ArmatureExporter.h" 00046 00047 // XXX exporter writes wrong data for shared armatures. A separate 00048 // controller should be written for each armature-mesh binding how do 00049 // we make controller ids then? 00050 ArmatureExporter::ArmatureExporter(COLLADASW::StreamWriter *sw, const ExportSettings *export_settings) : COLLADASW::LibraryControllers(sw), export_settings(export_settings) {} 00051 00052 // write bone nodes 00053 void ArmatureExporter::add_armature_bones(Object *ob_arm, Scene *sce) 00054 { 00055 // write bone nodes 00056 bArmature *arm = (bArmature*)ob_arm->data; 00057 for (Bone *bone = (Bone*)arm->bonebase.first; bone; bone = bone->next) { 00058 // start from root bones 00059 if (!bone->parent) 00060 add_bone_node(bone, ob_arm); 00061 } 00062 } 00063 00064 bool ArmatureExporter::is_skinned_mesh(Object *ob) 00065 { 00066 return get_assigned_armature(ob) != NULL; 00067 } 00068 00069 void ArmatureExporter::add_instance_controller(Object *ob) 00070 { 00071 Object *ob_arm = get_assigned_armature(ob); 00072 bArmature *arm = (bArmature*)ob_arm->data; 00073 00074 const std::string& controller_id = get_controller_id(ob_arm, ob); 00075 00076 COLLADASW::InstanceController ins(mSW); 00077 ins.setUrl(COLLADASW::URI(COLLADABU::Utils::EMPTY_STRING, controller_id)); 00078 00079 // write root bone URLs 00080 Bone *bone; 00081 for (bone = (Bone*)arm->bonebase.first; bone; bone = bone->next) { 00082 if (!bone->parent) 00083 ins.addSkeleton(COLLADABU::URI(COLLADABU::Utils::EMPTY_STRING, get_joint_id(bone, ob_arm))); 00084 } 00085 00086 InstanceWriter::add_material_bindings(ins.getBindMaterial(), ob); 00087 00088 ins.add(); 00089 } 00090 00091 void ArmatureExporter::export_controllers(Scene *sce) 00092 { 00093 scene = sce; 00094 00095 openLibrary(); 00096 00097 GeometryFunctor gf; 00098 gf.forEachMeshObjectInScene<ArmatureExporter>(sce, *this, this->export_settings->selected); 00099 00100 closeLibrary(); 00101 } 00102 00103 void ArmatureExporter::operator()(Object *ob) 00104 { 00105 Object *ob_arm = get_assigned_armature(ob); 00106 00107 if (ob_arm /*&& !already_written(ob_arm)*/) 00108 export_controller(ob, ob_arm); 00109 } 00110 #if 0 00111 00112 bool ArmatureExporter::already_written(Object *ob_arm) 00113 { 00114 return std::find(written_armatures.begin(), written_armatures.end(), ob_arm) != written_armatures.end(); 00115 } 00116 00117 void ArmatureExporter::wrote(Object *ob_arm) 00118 { 00119 written_armatures.push_back(ob_arm); 00120 } 00121 00122 void ArmatureExporter::find_objects_using_armature(Object *ob_arm, std::vector<Object *>& objects, Scene *sce) 00123 { 00124 objects.clear(); 00125 00126 Base *base= (Base*) sce->base.first; 00127 while(base) { 00128 Object *ob = base->object; 00129 00130 if (ob->type == OB_MESH && get_assigned_armature(ob) == ob_arm) { 00131 objects.push_back(ob); 00132 } 00133 00134 base= base->next; 00135 } 00136 } 00137 #endif 00138 00139 Object *ArmatureExporter::get_assigned_armature(Object *ob) 00140 { 00141 Object *ob_arm = NULL; 00142 00143 if (ob->parent && ob->partype == PARSKEL && ob->parent->type == OB_ARMATURE) { 00144 ob_arm = ob->parent; 00145 } 00146 else { 00147 ModifierData *mod = (ModifierData*)ob->modifiers.first; 00148 while (mod) { 00149 if (mod->type == eModifierType_Armature) { 00150 ob_arm = ((ArmatureModifierData*)mod)->object; 00151 } 00152 00153 mod = mod->next; 00154 } 00155 } 00156 00157 return ob_arm; 00158 } 00159 00160 std::string ArmatureExporter::get_joint_sid(Bone *bone, Object *ob_arm) 00161 { 00162 return get_joint_id(bone, ob_arm); 00163 } 00164 00165 // parent_mat is armature-space 00166 void ArmatureExporter::add_bone_node(Bone *bone, Object *ob_arm) 00167 { 00168 std::string node_id = get_joint_id(bone, ob_arm); 00169 std::string node_name = std::string(bone->name); 00170 std::string node_sid = get_joint_sid(bone, ob_arm); 00171 00172 COLLADASW::Node node(mSW); 00173 00174 node.setType(COLLADASW::Node::JOINT); 00175 node.setNodeId(node_id); 00176 node.setNodeName(node_name); 00177 node.setNodeSid(node_sid); 00178 00179 /*if ( bone->childbase.first == NULL || BLI_countlist(&(bone->childbase))>=2) 00180 add_blender_leaf_bone( bone, ob_arm , node ); 00181 else{*/ 00182 node.start(); 00183 00184 add_bone_transform(ob_arm, bone, node); 00185 00186 for (Bone *child = (Bone*)bone->childbase.first; child; child = child->next) { 00187 add_bone_node(child, ob_arm); 00188 } 00189 node.end(); 00190 //} 00191 } 00192 00193 void ArmatureExporter::add_blender_leaf_bone(Bone *bone, Object *ob_arm, COLLADASW::Node& node) 00194 { 00195 node.start(); 00196 00197 add_bone_transform(ob_arm, bone, node); 00198 00199 node.addExtraTechniqueParameter("blender", "tip_x", bone->tail[0] ); 00200 node.addExtraTechniqueParameter("blender", "tip_y", bone->tail[1] ); 00201 node.addExtraTechniqueParameter("blender", "tip_z", bone->tail[2] ); 00202 00203 for (Bone *child = (Bone*)bone->childbase.first; child; child = child->next) { 00204 add_bone_node(child, ob_arm); 00205 } 00206 node.end(); 00207 00208 } 00209 void ArmatureExporter::add_bone_transform(Object *ob_arm, Bone *bone, COLLADASW::Node& node) 00210 { 00211 bPoseChannel *pchan = get_pose_channel(ob_arm->pose, bone->name); 00212 00213 float mat[4][4]; 00214 00215 if (bone->parent) { 00216 // get bone-space matrix from armature-space 00217 bPoseChannel *parchan = get_pose_channel(ob_arm->pose, bone->parent->name); 00218 00219 float invpar[4][4]; 00220 invert_m4_m4(invpar, parchan->pose_mat); 00221 mult_m4_m4m4(mat, invpar, pchan->pose_mat); 00222 } 00223 else { 00224 // get world-space from armature-space 00225 mult_m4_m4m4(mat, ob_arm->obmat, pchan->pose_mat); 00226 } 00227 00228 TransformWriter::add_node_transform(node, mat,NULL ); 00229 } 00230 00231 std::string ArmatureExporter::get_controller_id(Object *ob_arm, Object *ob) 00232 { 00233 return translate_id(id_name(ob_arm)) + "_" + translate_id(id_name(ob)) + SKIN_CONTROLLER_ID_SUFFIX; 00234 } 00235 00236 // ob should be of type OB_MESH 00237 // both args are required 00238 void ArmatureExporter::export_controller(Object* ob, Object *ob_arm) 00239 { 00240 // joint names 00241 // joint inverse bind matrices 00242 // vertex weights 00243 00244 // input: 00245 // joint names: ob -> vertex group names 00246 // vertex group weights: me->dvert -> groups -> index, weight 00247 00248 /* 00249 me->dvert: 00250 00251 typedef struct MDeformVert { 00252 struct MDeformWeight *dw; 00253 int totweight; 00254 int flag; // flag only in use for weightpaint now 00255 } MDeformVert; 00256 00257 typedef struct MDeformWeight { 00258 int def_nr; 00259 float weight; 00260 } MDeformWeight; 00261 */ 00262 00263 Mesh *me = (Mesh*)ob->data; 00264 if (!me->dvert) return; 00265 00266 std::string controller_name = id_name(ob_arm); 00267 std::string controller_id = get_controller_id(ob_arm, ob); 00268 00269 openSkin(controller_id, controller_name, 00270 COLLADABU::URI(COLLADABU::Utils::EMPTY_STRING, get_geometry_id(ob))); 00271 00272 add_bind_shape_mat(ob); 00273 00274 std::string joints_source_id = add_joints_source(ob_arm, &ob->defbase, controller_id); 00275 std::string inv_bind_mat_source_id = add_inv_bind_mats_source(ob_arm, &ob->defbase, controller_id); 00276 std::string weights_source_id = add_weights_source(me, controller_id); 00277 00278 add_joints_element(&ob->defbase, joints_source_id, inv_bind_mat_source_id); 00279 add_vertex_weights_element(weights_source_id, joints_source_id, me, ob_arm, &ob->defbase); 00280 00281 closeSkin(); 00282 closeController(); 00283 } 00284 00285 void ArmatureExporter::add_joints_element(ListBase *defbase, 00286 const std::string& joints_source_id, const std::string& inv_bind_mat_source_id) 00287 { 00288 COLLADASW::JointsElement joints(mSW); 00289 COLLADASW::InputList &input = joints.getInputList(); 00290 00291 input.push_back(COLLADASW::Input(COLLADASW::InputSemantic::JOINT, // constant declared in COLLADASWInputList.h 00292 COLLADASW::URI(COLLADABU::Utils::EMPTY_STRING, joints_source_id))); 00293 input.push_back(COLLADASW::Input(COLLADASW::InputSemantic::BINDMATRIX, 00294 COLLADASW::URI(COLLADABU::Utils::EMPTY_STRING, inv_bind_mat_source_id))); 00295 joints.add(); 00296 } 00297 00298 void ArmatureExporter::add_bind_shape_mat(Object *ob) 00299 { 00300 double bind_mat[4][4]; 00301 00302 converter.mat4_to_dae_double(bind_mat, ob->obmat); 00303 00304 addBindShapeTransform(bind_mat); 00305 } 00306 00307 std::string ArmatureExporter::add_joints_source(Object *ob_arm, ListBase *defbase, const std::string& controller_id) 00308 { 00309 std::string source_id = controller_id + JOINTS_SOURCE_ID_SUFFIX; 00310 00311 int totjoint = 0; 00312 bDeformGroup *def; 00313 for (def = (bDeformGroup*)defbase->first; def; def = def->next) { 00314 if (is_bone_defgroup(ob_arm, def)) 00315 totjoint++; 00316 } 00317 00318 COLLADASW::NameSource source(mSW); 00319 source.setId(source_id); 00320 source.setArrayId(source_id + ARRAY_ID_SUFFIX); 00321 source.setAccessorCount(totjoint); 00322 source.setAccessorStride(1); 00323 00324 COLLADASW::SourceBase::ParameterNameList ¶m = source.getParameterNameList(); 00325 param.push_back("JOINT"); 00326 00327 source.prepareToAppendValues(); 00328 00329 for (def = (bDeformGroup*)defbase->first; def; def = def->next) { 00330 Bone *bone = get_bone_from_defgroup(ob_arm, def); 00331 if (bone) 00332 source.appendValues(get_joint_sid(bone, ob_arm)); 00333 } 00334 00335 source.finish(); 00336 00337 return source_id; 00338 } 00339 00340 std::string ArmatureExporter::add_inv_bind_mats_source(Object *ob_arm, ListBase *defbase, const std::string& controller_id) 00341 { 00342 std::string source_id = controller_id + BIND_POSES_SOURCE_ID_SUFFIX; 00343 00344 COLLADASW::FloatSourceF source(mSW); 00345 source.setId(source_id); 00346 source.setArrayId(source_id + ARRAY_ID_SUFFIX); 00347 source.setAccessorCount(BLI_countlist(defbase)); 00348 source.setAccessorStride(16); 00349 00350 source.setParameterTypeName(&COLLADASW::CSWC::CSW_VALUE_TYPE_FLOAT4x4); 00351 COLLADASW::SourceBase::ParameterNameList ¶m = source.getParameterNameList(); 00352 param.push_back("TRANSFORM"); 00353 00354 source.prepareToAppendValues(); 00355 00356 bPose *pose = ob_arm->pose; 00357 bArmature *arm = (bArmature*)ob_arm->data; 00358 00359 int flag = arm->flag; 00360 00361 // put armature in rest position 00362 if (!(arm->flag & ARM_RESTPOS)) { 00363 arm->flag |= ARM_RESTPOS; 00364 where_is_pose(scene, ob_arm); 00365 } 00366 00367 for (bDeformGroup *def = (bDeformGroup*)defbase->first; def; def = def->next) { 00368 if (is_bone_defgroup(ob_arm, def)) { 00369 00370 bPoseChannel *pchan = get_pose_channel(pose, def->name); 00371 00372 float mat[4][4]; 00373 float world[4][4]; 00374 float inv_bind_mat[4][4]; 00375 00376 // make world-space matrix, arm_mat is armature-space 00377 mult_m4_m4m4(world, ob_arm->obmat, pchan->bone->arm_mat); 00378 00379 invert_m4_m4(mat, world); 00380 converter.mat4_to_dae(inv_bind_mat, mat); 00381 00382 source.appendValues(inv_bind_mat); 00383 } 00384 } 00385 00386 // back from rest positon 00387 if (!(flag & ARM_RESTPOS)) { 00388 arm->flag = flag; 00389 where_is_pose(scene, ob_arm); 00390 } 00391 00392 source.finish(); 00393 00394 return source_id; 00395 } 00396 00397 Bone *ArmatureExporter::get_bone_from_defgroup(Object *ob_arm, bDeformGroup* def) 00398 { 00399 bPoseChannel *pchan = get_pose_channel(ob_arm->pose, def->name); 00400 return pchan ? pchan->bone : NULL; 00401 } 00402 00403 bool ArmatureExporter::is_bone_defgroup(Object *ob_arm, bDeformGroup* def) 00404 { 00405 return get_bone_from_defgroup(ob_arm, def) != NULL; 00406 } 00407 00408 std::string ArmatureExporter::add_weights_source(Mesh *me, const std::string& controller_id) 00409 { 00410 std::string source_id = controller_id + WEIGHTS_SOURCE_ID_SUFFIX; 00411 00412 int i; 00413 int totweight = 0; 00414 00415 for (i = 0; i < me->totvert; i++) { 00416 totweight += me->dvert[i].totweight; 00417 } 00418 00419 COLLADASW::FloatSourceF source(mSW); 00420 source.setId(source_id); 00421 source.setArrayId(source_id + ARRAY_ID_SUFFIX); 00422 source.setAccessorCount(totweight); 00423 source.setAccessorStride(1); 00424 00425 COLLADASW::SourceBase::ParameterNameList ¶m = source.getParameterNameList(); 00426 param.push_back("WEIGHT"); 00427 00428 source.prepareToAppendValues(); 00429 00430 // NOTE: COLLADA spec says weights should be normalized 00431 00432 for (i = 0; i < me->totvert; i++) { 00433 MDeformVert *vert = &me->dvert[i]; 00434 for (int j = 0; j < vert->totweight; j++) { 00435 source.appendValues(vert->dw[j].weight); 00436 } 00437 } 00438 00439 source.finish(); 00440 00441 return source_id; 00442 } 00443 00444 void ArmatureExporter::add_vertex_weights_element(const std::string& weights_source_id, const std::string& joints_source_id, Mesh *me, 00445 Object *ob_arm, ListBase *defbase) 00446 { 00447 COLLADASW::VertexWeightsElement weights(mSW); 00448 COLLADASW::InputList &input = weights.getInputList(); 00449 00450 int offset = 0; 00451 input.push_back(COLLADASW::Input(COLLADASW::InputSemantic::JOINT, // constant declared in COLLADASWInputList.h 00452 COLLADASW::URI(COLLADABU::Utils::EMPTY_STRING, joints_source_id), offset++)); 00453 input.push_back(COLLADASW::Input(COLLADASW::InputSemantic::WEIGHT, 00454 COLLADASW::URI(COLLADABU::Utils::EMPTY_STRING, weights_source_id), offset++)); 00455 00456 weights.setCount(me->totvert); 00457 00458 // write number of deformers per vertex 00459 COLLADASW::PrimitivesBase::VCountList vcount; 00460 int i; 00461 for (i = 0; i < me->totvert; i++) { 00462 vcount.push_back(me->dvert[i].totweight); 00463 } 00464 00465 weights.prepareToAppendVCountValues(); 00466 weights.appendVertexCount(vcount); 00467 00468 // def group index -> joint index 00469 std::map<int, int> joint_index_by_def_index; 00470 bDeformGroup *def; 00471 int j; 00472 for (def = (bDeformGroup*)defbase->first, i = 0, j = 0; def; def = def->next, i++) { 00473 if (is_bone_defgroup(ob_arm, def)) 00474 joint_index_by_def_index[i] = j++; 00475 else 00476 joint_index_by_def_index[i] = -1; 00477 } 00478 00479 weights.CloseVCountAndOpenVElement(); 00480 00481 // write deformer index - weight index pairs 00482 int weight_index = 0; 00483 for (i = 0; i < me->totvert; i++) { 00484 MDeformVert *dvert = &me->dvert[i]; 00485 for (int j = 0; j < dvert->totweight; j++) { 00486 weights.appendValues(joint_index_by_def_index[dvert->dw[j].def_nr]); 00487 weights.appendValues(weight_index++); 00488 } 00489 } 00490 00491 weights.finish(); 00492 }