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