Collada exporter update
[blender.git] / source / blender / collada / ControllerExporter.cpp
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  */
16
17 /** \file
18  * \ingroup collada
19  */
20
21 #include "COLLADASWBaseInputElement.h"
22 #include "COLLADASWInstanceController.h"
23 #include "COLLADASWPrimitves.h"
24 #include "COLLADASWSource.h"
25
26 #include "DNA_action_types.h"
27 #include "DNA_meshdata_types.h"
28 #include "DNA_modifier_types.h"
29
30 #include "BKE_action.h"
31 #include "BKE_armature.h"
32
33 extern "C" {
34 #include "BKE_global.h"
35 #include "BKE_idprop.h"
36 #include "BKE_library.h"
37 #include "BKE_mesh.h"
38 }
39
40 #include "ED_armature.h"
41
42 #include "BLI_listbase.h"
43
44 #include "GeometryExporter.h"
45 #include "ArmatureExporter.h"
46 #include "ControllerExporter.h"
47 #include "SceneExporter.h"
48
49 #include "collada_utils.h"
50
51 bool ControllerExporter::is_skinned_mesh(Object *ob)
52 {
53   return bc_get_assigned_armature(ob) != NULL;
54 }
55
56 void ControllerExporter::write_bone_URLs(COLLADASW::InstanceController &ins,
57                                          Object *ob_arm,
58                                          Bone *bone)
59 {
60   if (bc_is_root_bone(bone, this->export_settings.get_deform_bones_only())) {
61     std::string node_id = translate_id(id_name(ob_arm) + "_" + bone->name);
62     ins.addSkeleton(COLLADABU::URI(COLLADABU::Utils::EMPTY_STRING, node_id));
63   }
64   else {
65     for (Bone *child = (Bone *)bone->childbase.first; child; child = child->next) {
66       write_bone_URLs(ins, ob_arm, child);
67     }
68   }
69 }
70
71 bool ControllerExporter::add_instance_controller(Object *ob)
72 {
73   Object *ob_arm = bc_get_assigned_armature(ob);
74   bArmature *arm = (bArmature *)ob_arm->data;
75
76   const std::string &controller_id = get_controller_id(ob_arm, ob);
77
78   COLLADASW::InstanceController ins(mSW);
79   ins.setUrl(COLLADASW::URI(COLLADABU::Utils::EMPTY_STRING, controller_id));
80
81   Mesh *me = (Mesh *)ob->data;
82   if (!me->dvert)
83     return false;
84
85   /* write root bone URLs */
86   Bone *bone;
87   for (bone = (Bone *)arm->bonebase.first; bone; bone = bone->next) {
88     write_bone_URLs(ins, ob_arm, bone);
89   }
90
91   InstanceWriter::add_material_bindings(
92       ins.getBindMaterial(), ob, this->export_settings.get_active_uv_only());
93
94   ins.add();
95   return true;
96 }
97
98 void ControllerExporter::export_controllers()
99 {
100   Scene *sce = blender_context.get_scene();
101   openLibrary();
102
103   GeometryFunctor gf;
104   gf.forEachMeshObjectInExportSet<ControllerExporter>(
105       sce, *this, this->export_settings.get_export_set());
106
107   closeLibrary();
108 }
109
110 void ControllerExporter::operator()(Object *ob)
111 {
112   Object *ob_arm = bc_get_assigned_armature(ob);
113   Key *key = BKE_key_from_object(ob);
114
115   if (ob_arm) {
116     export_skin_controller(ob, ob_arm);
117   }
118   if (key && this->export_settings.get_include_shapekeys()) {
119     export_morph_controller(ob, key);
120   }
121 }
122 #if 0
123
124 bool ArmatureExporter::already_written(Object *ob_arm)
125 {
126   return std::find(written_armatures.begin(), written_armatures.end(), ob_arm) !=
127          written_armatures.end();
128 }
129
130 void ArmatureExporter::wrote(Object *ob_arm)
131 {
132   written_armatures.push_back(ob_arm);
133 }
134
135 void ArmatureExporter::find_objects_using_armature(Object *ob_arm,
136                                                    std::vector<Object *> &objects,
137                                                    Scene *sce)
138 {
139   objects.clear();
140
141   Base *base = (Base *)sce->base.first;
142   while (base) {
143     Object *ob = base->object;
144
145     if (ob->type == OB_MESH && get_assigned_armature(ob) == ob_arm) {
146       objects.push_back(ob);
147     }
148
149     base = base->next;
150   }
151 }
152 #endif
153
154 std::string ControllerExporter::get_controller_id(Object *ob_arm, Object *ob)
155 {
156   return translate_id(id_name(ob_arm)) + "_" + translate_id(id_name(ob)) +
157          SKIN_CONTROLLER_ID_SUFFIX;
158 }
159
160 std::string ControllerExporter::get_controller_id(Key *key, Object *ob)
161 {
162   return translate_id(id_name(ob)) + MORPH_CONTROLLER_ID_SUFFIX;
163 }
164
165 /* ob should be of type OB_MESH
166  * both args are required */
167 void ControllerExporter::export_skin_controller(Object *ob, Object *ob_arm)
168 {
169   /* joint names
170    * joint inverse bind matrices
171    * vertex weights */
172
173   /* input:
174    * joint names: ob -> vertex group names
175    * vertex group weights: me->dvert -> groups -> index, weight */
176
177 #if 0
178   me->dvert :
179
180       typedef struct MDeformVert {
181     struct MDeformWeight *dw;
182     int totweight;
183     int flag;  // flag only in use for weightpaint now
184   } MDeformVert;
185
186   typedef struct MDeformWeight {
187     int def_nr;
188     float weight;
189   } MDeformWeight;
190 #endif
191
192   bool use_instantiation = this->export_settings.get_use_object_instantiation();
193   Mesh *me;
194
195   if (((Mesh *)ob->data)->dvert == NULL) {
196     return;
197   }
198
199   me = bc_get_mesh_copy(blender_context,
200                         ob,
201                         this->export_settings.get_export_mesh_type(),
202                         this->export_settings.get_apply_modifiers(),
203                         this->export_settings.get_triangulate());
204
205   std::string controller_name = id_name(ob_arm);
206   std::string controller_id = get_controller_id(ob_arm, ob);
207
208   openSkin(controller_id,
209            controller_name,
210            COLLADABU::URI(COLLADABU::Utils::EMPTY_STRING, get_geometry_id(ob, use_instantiation)));
211
212   add_bind_shape_mat(ob);
213
214   std::string joints_source_id = add_joints_source(ob_arm, &ob->defbase, controller_id);
215   std::string inv_bind_mat_source_id = add_inv_bind_mats_source(
216       ob_arm, &ob->defbase, controller_id);
217
218   std::list<int> vcounts;
219   std::list<int> joints;
220   std::list<float> weights;
221
222   {
223     int i, j;
224
225     /* def group index -> joint index */
226     std::vector<int> joint_index_by_def_index;
227     bDeformGroup *def;
228
229     for (def = (bDeformGroup *)ob->defbase.first, i = 0, j = 0; def; def = def->next, i++) {
230       if (is_bone_defgroup(ob_arm, def))
231         joint_index_by_def_index.push_back(j++);
232       else
233         joint_index_by_def_index.push_back(-1);
234     }
235
236     int oob_counter = 0;
237     for (i = 0; i < me->totvert; i++) {
238       MDeformVert *vert = &me->dvert[i];
239       std::map<int, float> jw;
240
241       /* We're normalizing the weights later */
242       float sumw = 0.0f;
243
244       for (j = 0; j < vert->totweight; j++) {
245         int idx = vert->dw[j].def_nr;
246         if (idx >= joint_index_by_def_index.size()) {
247           /* XXX: Maybe better find out where and
248            *      why the Out Of Bound indexes get created ? */
249           oob_counter += 1;
250         }
251         else {
252           if (idx >= 0) {
253             int joint_index = joint_index_by_def_index[idx];
254             if (joint_index != -1 && vert->dw[j].weight > 0.0f) {
255               jw[joint_index] += vert->dw[j].weight;
256               sumw += vert->dw[j].weight;
257             }
258           }
259         }
260       }
261
262       if (sumw > 0.0f) {
263         float invsumw = 1.0f / sumw;
264         vcounts.push_back(jw.size());
265         for (std::map<int, float>::iterator m = jw.begin(); m != jw.end(); ++m) {
266           joints.push_back((*m).first);
267           weights.push_back(invsumw * (*m).second);
268         }
269       }
270       else {
271         vcounts.push_back(0);
272 #if 0
273         vcounts.push_back(1);
274         joints.push_back(-1);
275         weights.push_back(1.0f);
276 #endif
277       }
278     }
279
280     if (oob_counter > 0) {
281       fprintf(stderr,
282               "Ignored %d Vertex weights which use index to non existing VGroup %zu.\n",
283               oob_counter,
284               joint_index_by_def_index.size());
285     }
286   }
287
288   std::string weights_source_id = add_weights_source(me, controller_id, weights);
289   add_joints_element(&ob->defbase, joints_source_id, inv_bind_mat_source_id);
290   add_vertex_weights_element(weights_source_id, joints_source_id, vcounts, joints);
291
292   BKE_id_free(NULL, me);
293
294   closeSkin();
295   closeController();
296 }
297
298 void ControllerExporter::export_morph_controller(Object *ob, Key *key)
299 {
300   bool use_instantiation = this->export_settings.get_use_object_instantiation();
301   Mesh *me;
302
303   me = bc_get_mesh_copy(blender_context,
304                         ob,
305                         this->export_settings.get_export_mesh_type(),
306                         this->export_settings.get_apply_modifiers(),
307                         this->export_settings.get_triangulate());
308
309   std::string controller_name = id_name(ob) + "-morph";
310   std::string controller_id = get_controller_id(key, ob);
311
312   openMorph(
313       controller_id,
314       controller_name,
315       COLLADABU::URI(COLLADABU::Utils::EMPTY_STRING, get_geometry_id(ob, use_instantiation)));
316
317   std::string targets_id = add_morph_targets(key, ob);
318   std::string morph_weights_id = add_morph_weights(key, ob);
319
320   COLLADASW::TargetsElement targets(mSW);
321
322   COLLADASW::InputList &input = targets.getInputList();
323
324   input.push_back(COLLADASW::Input(
325       COLLADASW::InputSemantic::MORPH_TARGET,  // constant declared in COLLADASWInputList.h
326       COLLADASW::URI(COLLADABU::Utils::EMPTY_STRING, targets_id)));
327   input.push_back(
328       COLLADASW::Input(COLLADASW::InputSemantic::MORPH_WEIGHT,
329                        COLLADASW::URI(COLLADABU::Utils::EMPTY_STRING, morph_weights_id)));
330   targets.add();
331
332   BKE_id_free(NULL, me);
333
334   /* support for animations
335    * can also try the base element and param alternative */
336   add_weight_extras(key);
337   closeMorph();
338   closeController();
339 }
340
341 std::string ControllerExporter::add_morph_targets(Key *key, Object *ob)
342 {
343   std::string source_id = translate_id(id_name(ob)) + TARGETS_SOURCE_ID_SUFFIX;
344
345   COLLADASW::IdRefSource source(mSW);
346   source.setId(source_id);
347   source.setArrayId(source_id + ARRAY_ID_SUFFIX);
348   source.setAccessorCount(key->totkey - 1);
349   source.setAccessorStride(1);
350
351   COLLADASW::SourceBase::ParameterNameList &param = source.getParameterNameList();
352   param.push_back("IDREF");
353
354   source.prepareToAppendValues();
355
356   KeyBlock *kb = (KeyBlock *)key->block.first;
357   /* skip the basis */
358   kb = kb->next;
359   for (; kb; kb = kb->next) {
360     std::string geom_id = get_geometry_id(ob, false) + "_morph_" + translate_id(kb->name);
361     source.appendValues(geom_id);
362   }
363
364   source.finish();
365
366   return source_id;
367 }
368
369 std::string ControllerExporter::add_morph_weights(Key *key, Object *ob)
370 {
371   std::string source_id = translate_id(id_name(ob)) + WEIGHTS_SOURCE_ID_SUFFIX;
372
373   COLLADASW::FloatSourceF source(mSW);
374   source.setId(source_id);
375   source.setArrayId(source_id + ARRAY_ID_SUFFIX);
376   source.setAccessorCount(key->totkey - 1);
377   source.setAccessorStride(1);
378
379   COLLADASW::SourceBase::ParameterNameList &param = source.getParameterNameList();
380   param.push_back("MORPH_WEIGHT");
381
382   source.prepareToAppendValues();
383
384   KeyBlock *kb = (KeyBlock *)key->block.first;
385   /* skip the basis */
386   kb = kb->next;
387   for (; kb; kb = kb->next) {
388     float weight = kb->curval;
389     source.appendValues(weight);
390   }
391   source.finish();
392
393   return source_id;
394 }
395
396 /* Added to implement support for animations. */
397 void ControllerExporter::add_weight_extras(Key *key)
398 {
399   /* can also try the base element and param alternative */
400   COLLADASW::BaseExtraTechnique extra;
401
402   KeyBlock *kb = (KeyBlock *)key->block.first;
403   /* skip the basis */
404   kb = kb->next;
405   for (; kb; kb = kb->next) {
406     /* XXX why is the weight not used here and set to 0.0?
407      * float weight = kb->curval; */
408     extra.addExtraTechniqueParameter("KHR", "morph_weights", 0.000, "MORPH_WEIGHT_TO_TARGET");
409   }
410 }
411
412 void ControllerExporter::add_joints_element(ListBase *defbase,
413                                             const std::string &joints_source_id,
414                                             const std::string &inv_bind_mat_source_id)
415 {
416   COLLADASW::JointsElement joints(mSW);
417   COLLADASW::InputList &input = joints.getInputList();
418
419   input.push_back(COLLADASW::Input(
420       COLLADASW::InputSemantic::JOINT,  // constant declared in COLLADASWInputList.h
421       COLLADASW::URI(COLLADABU::Utils::EMPTY_STRING, joints_source_id)));
422   input.push_back(
423       COLLADASW::Input(COLLADASW::InputSemantic::BINDMATRIX,
424                        COLLADASW::URI(COLLADABU::Utils::EMPTY_STRING, inv_bind_mat_source_id)));
425   joints.add();
426 }
427
428 void ControllerExporter::add_bind_shape_mat(Object *ob)
429 {
430   double bind_mat[4][4];
431   float f_obmat[4][4];
432   BKE_object_matrix_local_get(ob, f_obmat);
433
434   if (export_settings.get_apply_global_orientation()) {
435     // do nothing, rotation is going to be applied to the Data
436   }
437   else {
438     bc_add_global_transform(f_obmat, export_settings.get_global_transform());
439   }
440
441   // UnitConverter::mat4_to_dae_double(bind_mat, ob->obmat);
442   UnitConverter::mat4_to_dae_double(bind_mat, f_obmat);
443   if (this->export_settings.get_limit_precision())
444     bc_sanitize_mat(bind_mat, LIMITTED_PRECISION);
445
446   addBindShapeTransform(bind_mat);
447 }
448
449 std::string ControllerExporter::add_joints_source(Object *ob_arm,
450                                                   ListBase *defbase,
451                                                   const std::string &controller_id)
452 {
453   std::string source_id = controller_id + JOINTS_SOURCE_ID_SUFFIX;
454
455   int totjoint = 0;
456   bDeformGroup *def;
457   for (def = (bDeformGroup *)defbase->first; def; def = def->next) {
458     if (is_bone_defgroup(ob_arm, def))
459       totjoint++;
460   }
461
462   COLLADASW::NameSource source(mSW);
463   source.setId(source_id);
464   source.setArrayId(source_id + ARRAY_ID_SUFFIX);
465   source.setAccessorCount(totjoint);
466   source.setAccessorStride(1);
467
468   COLLADASW::SourceBase::ParameterNameList &param = source.getParameterNameList();
469   param.push_back("JOINT");
470
471   source.prepareToAppendValues();
472
473   for (def = (bDeformGroup *)defbase->first; def; def = def->next) {
474     Bone *bone = get_bone_from_defgroup(ob_arm, def);
475     if (bone)
476       source.appendValues(get_joint_sid(bone));
477   }
478
479   source.finish();
480
481   return source_id;
482 }
483
484 std::string ControllerExporter::add_inv_bind_mats_source(Object *ob_arm,
485                                                          ListBase *defbase,
486                                                          const std::string &controller_id)
487 {
488   std::string source_id = controller_id + BIND_POSES_SOURCE_ID_SUFFIX;
489
490   int totjoint = 0;
491   for (bDeformGroup *def = (bDeformGroup *)defbase->first; def; def = def->next) {
492     if (is_bone_defgroup(ob_arm, def))
493       totjoint++;
494   }
495
496   COLLADASW::FloatSourceF source(mSW);
497   source.setId(source_id);
498   source.setArrayId(source_id + ARRAY_ID_SUFFIX);
499   source.setAccessorCount(totjoint);  // BLI_listbase_count(defbase));
500   source.setAccessorStride(16);
501
502   source.setParameterTypeName(&COLLADASW::CSWC::CSW_VALUE_TYPE_FLOAT4x4);
503   COLLADASW::SourceBase::ParameterNameList &param = source.getParameterNameList();
504   param.push_back("TRANSFORM");
505
506   source.prepareToAppendValues();
507
508   bPose *pose = ob_arm->pose;
509   bArmature *arm = (bArmature *)ob_arm->data;
510
511   int flag = arm->flag;
512
513   /* put armature in rest position */
514   if (!(arm->flag & ARM_RESTPOS)) {
515     Depsgraph *depsgraph = blender_context.get_depsgraph();
516     Scene *scene = blender_context.get_scene();
517
518     arm->flag |= ARM_RESTPOS;
519     BKE_pose_where_is(depsgraph, scene, ob_arm);
520   }
521
522   for (bDeformGroup *def = (bDeformGroup *)defbase->first; def; def = def->next) {
523     if (is_bone_defgroup(ob_arm, def)) {
524       bPoseChannel *pchan = BKE_pose_channel_find_name(pose, def->name);
525
526       float mat[4][4];
527       float world[4][4];
528       float inv_bind_mat[4][4];
529
530       float bind_mat[4][4]; /* derived from bone->arm_mat */
531
532       bool has_bindmat = bc_get_property_matrix(pchan->bone, "bind_mat", bind_mat);
533
534       if (!has_bindmat) {
535
536         /* Have no bind matrix stored, try old style <= Blender 2.78 */
537
538         bc_create_restpose_mat(
539             this->export_settings, pchan->bone, bind_mat, pchan->bone->arm_mat, true);
540
541         /* SL/OPEN_SIM COMPATIBILITY */
542         if (export_settings.get_open_sim()) {
543           float loc[3];
544           float rot[3] = {0, 0, 0};
545           float scale[3];
546           bc_decompose(bind_mat, loc, NULL, NULL, scale);
547
548           /* Only translations, no rotation vs armature */
549           loc_eulO_size_to_mat4(bind_mat, loc, rot, scale, 6);
550         }
551       }
552
553       /* make world-space matrix (bind_mat is armature-space) */
554       mul_m4_m4m4(world, ob_arm->obmat, bind_mat);
555
556       if (export_settings.get_apply_global_orientation()) {
557         bc_apply_global_transform(world, export_settings.get_global_transform());
558       }
559
560       invert_m4_m4(mat, world);
561       UnitConverter::mat4_to_dae(inv_bind_mat, mat);
562       if (this->export_settings.get_limit_precision())
563         bc_sanitize_mat(inv_bind_mat, LIMITTED_PRECISION);
564       source.appendValues(inv_bind_mat);
565     }
566   }
567
568   /* back from rest position */
569   if (!(flag & ARM_RESTPOS)) {
570     Depsgraph *depsgraph = blender_context.get_depsgraph();
571     Scene *scene = blender_context.get_scene();
572     arm->flag = flag;
573     BKE_pose_where_is(depsgraph, scene, ob_arm);
574   }
575
576   source.finish();
577
578   return source_id;
579 }
580
581 Bone *ControllerExporter::get_bone_from_defgroup(Object *ob_arm, bDeformGroup *def)
582 {
583   bPoseChannel *pchan = BKE_pose_channel_find_name(ob_arm->pose, def->name);
584   return pchan ? pchan->bone : NULL;
585 }
586
587 bool ControllerExporter::is_bone_defgroup(Object *ob_arm, bDeformGroup *def)
588 {
589   return get_bone_from_defgroup(ob_arm, def) != NULL;
590 }
591
592 std::string ControllerExporter::add_weights_source(Mesh *me,
593                                                    const std::string &controller_id,
594                                                    const std::list<float> &weights)
595 {
596   std::string source_id = controller_id + WEIGHTS_SOURCE_ID_SUFFIX;
597
598   COLLADASW::FloatSourceF source(mSW);
599   source.setId(source_id);
600   source.setArrayId(source_id + ARRAY_ID_SUFFIX);
601   source.setAccessorCount(weights.size());
602   source.setAccessorStride(1);
603
604   COLLADASW::SourceBase::ParameterNameList &param = source.getParameterNameList();
605   param.push_back("WEIGHT");
606
607   source.prepareToAppendValues();
608
609   for (std::list<float>::const_iterator i = weights.begin(); i != weights.end(); ++i) {
610     source.appendValues(*i);
611   }
612
613   source.finish();
614
615   return source_id;
616 }
617
618 void ControllerExporter::add_vertex_weights_element(const std::string &weights_source_id,
619                                                     const std::string &joints_source_id,
620                                                     const std::list<int> &vcounts,
621                                                     const std::list<int> &joints)
622 {
623   COLLADASW::VertexWeightsElement weightselem(mSW);
624   COLLADASW::InputList &input = weightselem.getInputList();
625
626   int offset = 0;
627   input.push_back(COLLADASW::Input(
628       COLLADASW::InputSemantic::JOINT,  // constant declared in COLLADASWInputList.h
629       COLLADASW::URI(COLLADABU::Utils::EMPTY_STRING, joints_source_id),
630       offset++));
631   input.push_back(
632       COLLADASW::Input(COLLADASW::InputSemantic::WEIGHT,
633                        COLLADASW::URI(COLLADABU::Utils::EMPTY_STRING, weights_source_id),
634                        offset++));
635
636   weightselem.setCount(vcounts.size());
637
638   /* write number of deformers per vertex */
639   COLLADASW::PrimitivesBase::VCountList vcountlist;
640
641   vcountlist.resize(vcounts.size());
642   std::copy(vcounts.begin(), vcounts.end(), vcountlist.begin());
643
644   weightselem.prepareToAppendVCountValues();
645   weightselem.appendVertexCount(vcountlist);
646
647   weightselem.CloseVCountAndOpenVElement();
648
649   /* write deformer index - weight index pairs */
650   int weight_index = 0;
651   for (std::list<int>::const_iterator i = joints.begin(); i != joints.end(); ++i) {
652     weightselem.appendValues(*i, weight_index++);
653   }
654
655   weightselem.finish();
656 }