~ubuntu-branches/ubuntu/trusty/blender/trusty

« back to all changes in this revision

Viewing changes to source/blender/collada/ControllerExporter.cpp

  • Committer: Package Import Robot
  • Author(s): Jeremy Bicha
  • Date: 2013-03-06 12:08:47 UTC
  • mfrom: (1.5.1) (14.1.8 experimental)
  • Revision ID: package-import@ubuntu.com-20130306120847-frjfaryb2zrotwcg
Tags: 2.66a-1ubuntu1
* Resynchronize with Debian (LP: #1076930, #1089256, #1052743, #999024,
  #1122888, #1147084)
* debian/control:
  - Lower build-depends on libavcodec-dev since we're not
    doing the libav9 transition in Ubuntu yet

Show diffs side-by-side

added added

removed removed

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