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