22
20
* ***** END GPL LICENSE BLOCK *****
23
/** \file blender/collada/DocumentImporter.cpp
25
28
// * name imported objects
26
29
// * import object rotation as euler
33
#include <algorithm> // sort()
28
35
#include "COLLADAFWRoot.h"
29
#include "COLLADAFWIWriter.h"
30
36
#include "COLLADAFWStableHeaders.h"
31
#include "COLLADAFWAnimationCurve.h"
32
#include "COLLADAFWAnimationList.h"
33
#include "COLLADAFWCamera.h"
34
37
#include "COLLADAFWColorOrTexture.h"
35
#include "COLLADAFWEffect.h"
36
#include "COLLADAFWFloatOrDoubleArray.h"
37
#include "COLLADAFWGeometry.h"
38
#include "COLLADAFWImage.h"
39
38
#include "COLLADAFWIndexList.h"
40
#include "COLLADAFWInstanceGeometry.h"
41
#include "COLLADAFWLight.h"
42
#include "COLLADAFWMaterial.h"
43
#include "COLLADAFWMesh.h"
44
39
#include "COLLADAFWMeshPrimitiveWithFaceVertexCount.h"
45
#include "COLLADAFWNode.h"
46
40
#include "COLLADAFWPolygons.h"
47
41
#include "COLLADAFWSampler.h"
48
#include "COLLADAFWSkinController.h"
49
#include "COLLADAFWSkinControllerData.h"
50
#include "COLLADAFWTransformation.h"
51
#include "COLLADAFWTranslate.h"
52
#include "COLLADAFWRotate.h"
53
#include "COLLADAFWScale.h"
54
#include "COLLADAFWMatrix.h"
55
42
#include "COLLADAFWTypes.h"
56
43
#include "COLLADAFWVisualScene.h"
57
#include "COLLADAFWFileInfo.h"
58
44
#include "COLLADAFWArrayPrimitiveType.h"
45
#include "COLLADAFWLibraryNodes.h"
46
#include "COLLADAFWCamera.h"
47
#include "COLLADAFWLight.h"
60
49
#include "COLLADASaxFWLLoader.h"
62
// TODO move "extern C" into header files
65
#include "ED_keyframing.h"
66
#include "ED_armature.h"
67
#include "ED_mesh.h" // ED_vgroup_vert_add, ...
68
#include "ED_anim_api.h"
69
#include "ED_object.h"
50
#include "COLLADASaxFWLIExtraDataCallbackHandler.h"
52
#include "BLI_listbase.h"
54
#include "BLI_string.h"
55
#include "BLI_utildefines.h"
57
#include "BKE_camera.h"
74
58
#include "BKE_main.h"
75
#include "BKE_customdata.h"
76
60
#include "BKE_library.h"
77
61
#include "BKE_texture.h"
78
62
#include "BKE_fcurve.h"
79
63
#include "BKE_depsgraph.h"
80
64
#include "BLI_path_util.h"
81
#include "BKE_displist.h"
83
65
#include "BKE_scene.h"
85
#include "BKE_armature.h"
87
66
#include "BKE_global.h"
88
#include "BKE_context.h"
89
#include "BKE_object.h"
90
#include "BKE_image.h"
91
67
#include "BKE_material.h"
92
68
#include "BKE_utildefines.h"
93
#include "BKE_action.h"
96
#include "BLI_listbase.h"
97
#include "BLI_string.h"
69
#include "BKE_image.h"
71
#include "DNA_camera_types.h"
99
72
#include "DNA_lamp_types.h"
100
#include "DNA_armature_types.h"
101
#include "DNA_anim_types.h"
102
#include "DNA_curve_types.h"
103
#include "DNA_texture_types.h"
104
#include "DNA_camera_types.h"
105
#include "DNA_object_types.h"
106
#include "DNA_meshdata_types.h"
107
#include "DNA_mesh_types.h"
108
#include "DNA_material_types.h"
109
#include "DNA_scene_types.h"
110
#include "DNA_modifier_types.h"
74
#include "RNA_access.h"
112
76
#include "MEM_guardedalloc.h"
78
#include "ExtraHandler.h"
79
#include "ErrorHandler.h"
114
80
#include "DocumentImporter.h"
81
#include "TransformReader.h"
115
83
#include "collada_internal.h"
119
#include <algorithm> // sort()
84
#include "collada_utils.h"
88
COLLADA Importer limitations:
89
- no multiple scene import, all objects are added to active scene
124
92
// #define COLLADA_DEBUG
126
93
// creates empties for each imported bone on layer 2, for debugging
127
94
// #define ARMATURE_TEST
129
char *CustomData_get_layer_name(const struct CustomData *data, int type, int n);
131
static const char *primTypeToStr(COLLADAFW::MeshPrimitive::PrimitiveType type)
133
using namespace COLLADAFW;
136
case MeshPrimitive::LINES:
138
case MeshPrimitive::LINE_STRIPS:
140
case MeshPrimitive::POLYGONS:
142
case MeshPrimitive::POLYLIST:
144
case MeshPrimitive::TRIANGLES:
146
case MeshPrimitive::TRIANGLE_FANS:
147
return "TRIANGLE_FANS";
148
case MeshPrimitive::TRIANGLE_STRIPS:
149
return "TRIANGLE_FANS";
150
case MeshPrimitive::POINTS:
152
case MeshPrimitive::UNDEFINED_PRIMITIVE_TYPE:
153
return "UNDEFINED_PRIMITIVE_TYPE";
158
static const char *geomTypeToStr(COLLADAFW::Geometry::GeometryType type)
161
case COLLADAFW::Geometry::GEO_TYPE_MESH:
163
case COLLADAFW::Geometry::GEO_TYPE_SPLINE:
165
case COLLADAFW::Geometry::GEO_TYPE_CONVEX_MESH:
166
return "CONVEX_MESH";
167
case COLLADAFW::Geometry::GEO_TYPE_UNKNOWN:
173
// works for COLLADAFW::Node, COLLADAFW::Geometry
175
static const char *get_dae_name(T *node)
177
const std::string& name = node->getName();
178
return name.size() ? name.c_str() : node->getOriginalId().c_str();
181
// use this for retrieving bone names, since these must be unique
183
static const char *get_joint_name(T *node)
185
const std::string& id = node->getOriginalId();
186
return id.size() ? id.c_str() : node->getName().c_str();
189
static float get_float_value(const COLLADAFW::FloatOrDoubleArray& array, unsigned int index)
191
if (index >= array.getValuesCount())
194
if (array.getType() == COLLADAFW::MeshVertexData::DATA_TYPE_FLOAT)
195
return array.getFloatValues()->getData()[index];
197
return array.getDoubleValues()->getData()[index];
200
// copied from /editors/object/object_relations.c
201
static int test_parent_loop(Object *par, Object *ob)
203
/* test if 'ob' is a parent somewhere in par's parents */
205
if(par == NULL) return 0;
206
if(ob == par) return 1;
208
return test_parent_loop(par->parent, ob);
211
// a shortened version of parent_set_exec()
212
// if is_parent_space is true then ob->obmat will be multiplied by par->obmat before parenting
213
static int set_parent(Object *ob, Object *par, bContext *C, bool is_parent_space=true)
215
if (!par || test_parent_loop(par, ob))
219
Scene *sce = CTX_data_scene(C);
222
ob->partype = PAROBJECT;
224
ob->parsubstr[0] = 0;
226
if (is_parent_space) {
228
where_is_object(sce, par);
230
// move child obmat into world space
232
mul_m4_m4m4(mat, ob->obmat, par->obmat);
233
copy_m4_m4(ob->obmat, mat);
236
// apply child obmat (i.e. decompose it into rot/loc/size)
237
object_apply_mat4(ob, ob->obmat);
240
what_does_parent(sce, ob, &workob);
241
invert_m4_m4(ob->parentinv, workob.obmat);
243
ob->recalc |= OB_RECALC_OB | OB_RECALC_DATA;
244
par->recalc |= OB_RECALC_OB;
247
DAG_ids_flush_update(0);
248
WM_event_add_notifier(C, NC_OBJECT|ND_TRANSFORM, NULL);
96
DocumentImporter::DocumentImporter(bContext *C, const char *filename) :
97
mImportStage(General),
100
armature_importer(&unit_converter, &mesh_importer, &anim_importer, CTX_data_scene(C)),
101
mesh_importer(&unit_converter, &armature_importer, CTX_data_scene(C)),
102
anim_importer(&unit_converter, &armature_importer, CTX_data_scene(C))
105
DocumentImporter::~DocumentImporter()
107
TagsMap::iterator etit;
108
etit = uid_tags_map.begin();
109
while(etit!=uid_tags_map.end()) {
115
bool DocumentImporter::import()
117
ErrorHandler errorHandler;
118
COLLADASaxFWL::Loader loader(&errorHandler);
119
COLLADAFW::Root root(&loader, this);
120
ExtraHandler *ehandler = new ExtraHandler(this, &(this->anim_importer));
122
loader.registerExtraDataCallbackHandler(ehandler);
124
// deselect all to select new objects
125
scene_deselect_all(CTX_data_scene(mContext));
127
if (!root.loadDocument(mFilename)) {
128
fprintf(stderr, "COLLADAFW::Root::loadDocument() returned false on 1st pass\n");
132
if (errorHandler.hasError())
135
/** TODO set up scene graph and such here */
137
mImportStage = Controller;
139
COLLADASaxFWL::Loader loader2;
140
COLLADAFW::Root root2(&loader2, this);
142
if (!root2.loadDocument(mFilename)) {
143
fprintf(stderr, "COLLADAFW::Root::loadDocument() returned false on 2nd pass\n");
150
mesh_importer.bmeshConversion();
253
typedef std::map<COLLADAFW::TextureMapId, std::vector<MTex*> > TexIndexTextureArrayMap;
255
class TransformReader : public TransformBase
259
UnitConverter *unit_converter;
263
COLLADAFW::Node *node;
264
COLLADAFW::Transformation *tm; // which transform is animated by an AnimationList->id
269
TransformReader(UnitConverter* conv) : unit_converter(conv) {}
271
void get_node_mat(float mat[][4], COLLADAFW::Node *node, std::map<COLLADAFW::UniqueId, Animation> *animation_map,
279
for (unsigned int i = 0; i < node->getTransformations().getCount(); i++) {
281
COLLADAFW::Transformation *tm = node->getTransformations()[i];
282
COLLADAFW::Transformation::TransformationType type = tm->getTransformationType();
285
case COLLADAFW::Transformation::TRANSLATE:
286
dae_translate_to_mat4(tm, cur);
288
case COLLADAFW::Transformation::ROTATE:
289
dae_rotate_to_mat4(tm, cur);
291
case COLLADAFW::Transformation::SCALE:
292
dae_scale_to_mat4(tm, cur);
294
case COLLADAFW::Transformation::MATRIX:
295
dae_matrix_to_mat4(tm, cur);
297
case COLLADAFW::Transformation::LOOKAT:
298
case COLLADAFW::Transformation::SKEW:
299
fprintf(stderr, "LOOKAT and SKEW transformations are not supported yet.\n");
303
copy_m4_m4(copy, mat);
304
mul_m4_m4m4(mat, cur, copy);
307
// AnimationList that drives this Transformation
308
const COLLADAFW::UniqueId& anim_list_id = tm->getAnimationList();
310
// store this so later we can link animation data with ob
311
Animation anim = {ob, node, tm};
312
(*animation_map)[anim_list_id] = anim;
317
void dae_rotate_to_mat4(COLLADAFW::Transformation *tm, float m[][4])
319
COLLADAFW::Rotate *ro = (COLLADAFW::Rotate*)tm;
320
COLLADABU::Math::Vector3& axis = ro->getRotationAxis();
321
float angle = (float)(ro->getRotationAngle() * M_PI / 180.0f);
322
float ax[] = {axis[0], axis[1], axis[2]};
324
// axis_angle_to_quat(quat, axis, angle);
325
// quat_to_mat4(m, quat);
326
axis_angle_to_mat4(m, ax, angle);
329
void dae_translate_to_mat4(COLLADAFW::Transformation *tm, float m[][4])
331
COLLADAFW::Translate *tra = (COLLADAFW::Translate*)tm;
332
COLLADABU::Math::Vector3& t = tra->getTranslation();
336
m[3][0] = (float)t[0];
337
m[3][1] = (float)t[1];
338
m[3][2] = (float)t[2];
341
void dae_scale_to_mat4(COLLADAFW::Transformation *tm, float m[][4])
343
COLLADABU::Math::Vector3& s = ((COLLADAFW::Scale*)tm)->getScale();
344
float size[3] = {(float)s[0], (float)s[1], (float)s[2]};
345
size_to_mat4(m, size);
348
void dae_matrix_to_mat4(COLLADAFW::Transformation *tm, float m[][4])
350
unit_converter->dae_matrix_to_mat4(m, ((COLLADAFW::Matrix*)tm)->getMatrix());
353
void dae_translate_to_v3(COLLADAFW::Transformation *tm, float v[3])
355
dae_vector3_to_v3(((COLLADAFW::Translate*)tm)->getTranslation(), v);
358
void dae_scale_to_v3(COLLADAFW::Transformation *tm, float v[3])
360
dae_vector3_to_v3(((COLLADAFW::Scale*)tm)->getScale(), v);
363
void dae_vector3_to_v3(const COLLADABU::Math::Vector3 &v3, float v[3])
371
// only for ArmatureImporter to "see" MeshImporter::get_object_by_geom_uid
372
class MeshImporterBase
375
virtual Object *get_object_by_geom_uid(const COLLADAFW::UniqueId& geom_uid) = 0;
379
class AnimationImporterBase
382
// virtual void change_eul_to_quat(Object *ob, bAction *act) = 0;
385
class ArmatureImporter : private TransformReader
389
UnitConverter *unit_converter;
391
// std::map<int, JointData> joint_index_to_joint_info_map;
392
// std::map<COLLADAFW::UniqueId, int> joint_id_to_joint_index_map;
395
// COLLADAFW::Node *node;
398
float mat[4][4]; // bone matrix, derived from inv_bind_mat
400
std::vector<LeafBone> leaf_bones;
401
// int bone_direction_row; // XXX not used
402
float leaf_bone_length;
405
// float min_angle; // minimum angle between bone head-tail and a row of bone matrix
408
struct ArmatureJoints {
410
std::vector<COLLADAFW::Node*> root_joints;
412
std::vector<ArmatureJoints> armature_joints;
415
Object *empty; // empty for leaf bones
417
std::map<COLLADAFW::UniqueId, COLLADAFW::UniqueId> geom_uid_by_controller_uid;
418
std::map<COLLADAFW::UniqueId, COLLADAFW::Node*> joint_by_uid; // contains all joints
419
std::vector<COLLADAFW::Node*> root_joints;
420
std::map<COLLADAFW::UniqueId, Object*> joint_parent_map;
422
MeshImporterBase *mesh_importer;
423
AnimationImporterBase *anim_importer;
425
// This is used to store data passed in write_controller_data.
426
// Arrays from COLLADAFW::SkinControllerData lose ownership, so do this class members
427
// so that arrays don't get freed until we free them explicitly.
431
// to build armature bones from inverse bind matrices
433
float inv_bind_mat[4][4]; // joint inverse bind matrix
434
COLLADAFW::UniqueId joint_uid; // joint node UID
435
// Object *ob_arm; // armature object
438
float bind_shape_matrix[4][4];
440
// data from COLLADAFW::SkinControllerData, each array should be freed
441
COLLADAFW::UIntValuesArray joints_per_vertex;
442
COLLADAFW::UIntValuesArray weight_indices;
443
COLLADAFW::IntValuesArray joint_indices;
444
// COLLADAFW::FloatOrDoubleArray weights;
445
std::vector<float> weights;
447
std::vector<JointData> joint_data; // index to this vector is joint index
449
UnitConverter *unit_converter;
452
COLLADAFW::UniqueId controller_uid;
459
SkinInfo(const SkinInfo& skin) : weights(skin.weights),
460
joint_data(skin.joint_data),
461
unit_converter(skin.unit_converter),
463
controller_uid(skin.controller_uid),
466
copy_m4_m4(bind_shape_matrix, (float (*)[4])skin.bind_shape_matrix);
468
transfer_uint_array_data_const(skin.joints_per_vertex, joints_per_vertex);
469
transfer_uint_array_data_const(skin.weight_indices, weight_indices);
470
transfer_int_array_data_const(skin.joint_indices, joint_indices);
473
SkinInfo(UnitConverter *conv) : unit_converter(conv), ob_arm(NULL), parent(NULL) {}
475
// nobody owns the data after this, so it should be freed manually with releaseMemory
477
void transfer_array_data(T& src, T& dest)
479
dest.setData(src.getData(), src.getCount());
480
src.yieldOwnerShip();
481
dest.yieldOwnerShip();
484
// when src is const we cannot src.yieldOwnerShip, this is used by copy constructor
485
void transfer_int_array_data_const(const COLLADAFW::IntValuesArray& src, COLLADAFW::IntValuesArray& dest)
487
dest.setData((int*)src.getData(), src.getCount());
488
dest.yieldOwnerShip();
491
void transfer_uint_array_data_const(const COLLADAFW::UIntValuesArray& src, COLLADAFW::UIntValuesArray& dest)
493
dest.setData((unsigned int*)src.getData(), src.getCount());
494
dest.yieldOwnerShip();
497
void borrow_skin_controller_data(const COLLADAFW::SkinControllerData* skin)
499
transfer_array_data((COLLADAFW::UIntValuesArray&)skin->getJointsPerVertex(), joints_per_vertex);
500
transfer_array_data((COLLADAFW::UIntValuesArray&)skin->getWeightIndices(), weight_indices);
501
transfer_array_data((COLLADAFW::IntValuesArray&)skin->getJointIndices(), joint_indices);
502
// transfer_array_data(skin->getWeights(), weights);
504
// cannot transfer data for FloatOrDoubleArray, copy values manually
505
const COLLADAFW::FloatOrDoubleArray& weight = skin->getWeights();
506
for (unsigned int i = 0; i < weight.getValuesCount(); i++)
507
weights.push_back(get_float_value(weight, i));
509
unit_converter->dae_matrix_to_mat4(bind_shape_matrix, skin->getBindShapeMatrix());
514
joints_per_vertex.releaseMemory();
515
weight_indices.releaseMemory();
516
joint_indices.releaseMemory();
517
// weights.releaseMemory();
520
// using inverse bind matrices to construct armature
521
// it is safe to invert them to get the original matrices
522
// because if they are inverse matrices, they can be inverted
523
void add_joint(const COLLADABU::Math::Matrix4& matrix)
526
unit_converter->dae_matrix_to_mat4(jd.inv_bind_mat, matrix);
527
joint_data.push_back(jd);
530
void set_controller(const COLLADAFW::SkinController* co)
532
controller_uid = co->getUniqueId();
534
// fill in joint UIDs
535
const COLLADAFW::UniqueIdArray& joint_uids = co->getJoints();
536
for (unsigned int i = 0; i < joint_uids.getCount(); i++) {
537
joint_data[i].joint_uid = joint_uids[i];
539
// // store armature pointer
540
// JointData& jd = joint_index_to_joint_info_map[i];
541
// jd.ob_arm = ob_arm;
543
// now we'll be able to get inv bind matrix from joint id
544
// joint_id_to_joint_index_map[joint_ids[i]] = i;
548
// called from write_controller
549
Object *create_armature(Scene *scene)
551
ob_arm = add_object(scene, OB_ARMATURE);
555
Object* set_armature(Object *ob_arm)
560
this->ob_arm = ob_arm;
564
bool get_joint_inv_bind_matrix(float inv_bind_mat[][4], COLLADAFW::Node *node)
566
const COLLADAFW::UniqueId& uid = node->getUniqueId();
567
std::vector<JointData>::iterator it;
568
for (it = joint_data.begin(); it != joint_data.end(); it++) {
569
if ((*it).joint_uid == uid) {
570
copy_m4_m4(inv_bind_mat, (*it).inv_bind_mat);
578
Object *get_armature()
583
const COLLADAFW::UniqueId& get_controller_uid()
585
return controller_uid;
588
// check if this skin controller references a joint or any descendant of it
590
// some nodes may not be referenced by SkinController,
591
// in this case to determine if the node belongs to this armature,
592
// we need to search down the tree
593
bool uses_joint_or_descendant(COLLADAFW::Node *node)
595
const COLLADAFW::UniqueId& uid = node->getUniqueId();
596
std::vector<JointData>::iterator it;
597
for (it = joint_data.begin(); it != joint_data.end(); it++) {
598
if ((*it).joint_uid == uid)
602
COLLADAFW::NodePointerArray& children = node->getChildNodes();
603
for (unsigned int i = 0; i < children.getCount(); i++) {
604
if (uses_joint_or_descendant(children[i]))
611
void link_armature(bContext *C, Object *ob, std::map<COLLADAFW::UniqueId, COLLADAFW::Node*>& joint_by_uid,
614
Scene *scene = CTX_data_scene(C);
616
ModifierData *md = ED_object_modifier_add(NULL, scene, ob, NULL, eModifierType_Armature);
617
((ArmatureModifierData *)md)->object = ob_arm;
619
copy_m4_m4(ob->obmat, bind_shape_matrix);
620
object_apply_mat4(ob, ob->obmat);
622
::set_parent(ob, ob_arm, C);
626
ob->partype = PAROBJECT;
628
what_does_parent(scene, ob, &workob);
629
invert_m4_m4(ob->parentinv, workob.obmat);
631
ob->recalc |= OB_RECALC_OB|OB_RECALC_DATA;
633
DAG_scene_sort(scene);
634
DAG_ids_flush_update(0);
635
WM_event_add_notifier(C, NC_OBJECT|ND_TRANSFORM, NULL);
638
((bArmature*)ob_arm->data)->deformflag = ARM_DEF_VGROUP;
640
// create all vertex groups
641
std::vector<JointData>::iterator it;
643
for (it = joint_data.begin(), joint_index = 0; it != joint_data.end(); it++, joint_index++) {
644
const char *name = "Group";
646
// name group by joint node name
647
if (joint_by_uid.find((*it).joint_uid) != joint_by_uid.end()) {
648
name = get_joint_name(joint_by_uid[(*it).joint_uid]);
651
ED_vgroup_add_name(ob, (char*)name);
654
// <vcount> - number of joints per vertex - joints_per_vertex
655
// <v> - [[bone index, weight index] * joints per vertex] * vertices - weight indices
656
// ^ bone index can be -1 meaning weight toward bind shape, how to express this in Blender?
658
// for each vertex in weight indices
659
// for each bone index in vertex
660
// add vertex to group at group index
661
// treat group index -1 specially
663
// get def group by index with BLI_findlink
665
for (unsigned int vertex = 0, weight = 0; vertex < joints_per_vertex.getCount(); vertex++) {
667
unsigned int limit = weight + joints_per_vertex[vertex];
668
for ( ; weight < limit; weight++) {
669
int joint = joint_indices[weight], joint_weight = weight_indices[weight];
671
// -1 means "weight towards the bind shape", we just don't assign it to any group
673
bDeformGroup *def = (bDeformGroup*)BLI_findlink(&ob->defbase, joint);
675
ED_vgroup_vert_add(ob, def, vertex, weights[joint_weight], WEIGHT_REPLACE);
681
bPoseChannel *get_pose_channel_from_node(COLLADAFW::Node *node)
683
return get_pose_channel(ob_arm->pose, get_joint_name(node));
686
void set_parent(Object *_parent)
696
void find_root_joints(const std::vector<COLLADAFW::Node*> &root_joints,
697
std::map<COLLADAFW::UniqueId, COLLADAFW::Node*>& joint_by_uid,
698
std::vector<COLLADAFW::Node*>& result)
700
std::vector<COLLADAFW::Node*>::const_iterator it;
701
for (it = root_joints.begin(); it != root_joints.end(); it++) {
702
COLLADAFW::Node *root = *it;
703
std::vector<JointData>::iterator ji;
704
for (ji = joint_data.begin(); ji != joint_data.end(); ji++) {
705
COLLADAFW::Node *joint = joint_by_uid[(*ji).joint_uid];
706
if (find_node_in_tree(joint, root)) {
707
if (std::find(result.begin(), result.end(), root) == result.end())
708
result.push_back(root);
714
bool find_node_in_tree(COLLADAFW::Node *node, COLLADAFW::Node *tree_root)
716
if (node == tree_root)
719
COLLADAFW::NodePointerArray& children = tree_root->getChildNodes();
720
for (unsigned int i = 0; i < children.getCount(); i++) {
721
if (find_node_in_tree(node, children[i]))
730
std::map<COLLADAFW::UniqueId, SkinInfo> skin_by_data_uid; // data UID = skin controller data UID
732
JointData *get_joint_data(COLLADAFW::Node *node)
734
const COLLADAFW::UniqueId& joint_id = node->getUniqueId();
736
if (joint_id_to_joint_index_map.find(joint_id) == joint_id_to_joint_index_map.end()) {
737
fprintf(stderr, "Cannot find a joint index by joint id for %s.\n",
738
node->getOriginalId().c_str());
742
int joint_index = joint_id_to_joint_index_map[joint_id];
744
return &joint_index_to_joint_info_map[joint_index];
748
void create_bone(SkinInfo& skin, COLLADAFW::Node *node, EditBone *parent, int totchild,
749
float parent_mat[][4], bArmature *arm)
751
float joint_inv_bind_mat[4][4];
753
// JointData* jd = get_joint_data(node);
757
if (skin.get_joint_inv_bind_matrix(joint_inv_bind_mat, node)) {
758
// get original world-space matrix
759
invert_m4_m4(mat, joint_inv_bind_mat);
761
// create a bone even if there's no joint data for it (i.e. it has no influence)
766
get_node_mat(obmat, node, NULL, NULL);
770
mul_m4_m4m4(mat, obmat, parent_mat);
772
copy_m4_m4(mat, obmat);
775
// TODO rename from Node "name" attrs later
776
EditBone *bone = ED_armature_edit_bone_add(arm, (char*)get_joint_name(node));
779
if (parent) bone->parent = parent;
782
copy_v3_v3(bone->head, mat[3]);
784
// set tail, don't set it to head because 0-length bones are not allowed
785
float vec[3] = {0.0f, 0.5f, 0.0f};
786
add_v3_v3v3(bone->tail, bone->head, vec);
789
if (parent && totchild == 1) {
790
copy_v3_v3(parent->tail, bone->head);
792
// not setting BONE_CONNECTED because this would lock child bone location with respect to parent
793
// bone->flag |= BONE_CONNECTED;
795
// XXX increase this to prevent "very" small bones?
796
const float epsilon = 0.000001f;
798
// derive leaf bone length
799
float length = len_v3v3(parent->head, parent->tail);
800
if ((length < leaf_bone_length || totbone == 0) && length > epsilon) {
801
leaf_bone_length = length;
804
// treat zero-sized bone like a leaf bone
805
if (length <= epsilon) {
806
add_leaf_bone(parent_mat, parent);
811
// and which row in mat is bone direction
813
sub_v3_v3v3(vec, parent->tail, parent->head);
815
print_v3("tail - head", vec);
816
print_m4("matrix", parent_mat);
818
for (int i = 0; i < 3; i++) {
820
char *axis_names[] = {"X", "Y", "Z"};
821
printf("%s-axis length is %f\n", axis_names[i], len_v3(parent_mat[i]));
823
float angle = angle_v2v2(vec, parent_mat[i]);
824
if (angle < min_angle) {
826
print_v3("picking", parent_mat[i]);
827
printf("^ %s axis of %s's matrix\n", axis_names[i], get_dae_name(node));
829
bone_direction_row = i;
837
COLLADAFW::NodePointerArray& children = node->getChildNodes();
838
for (unsigned int i = 0; i < children.getCount(); i++) {
839
create_bone(skin, children[i], bone, children.getCount(), mat, arm);
842
// in second case it's not a leaf bone, but we handle it the same way
843
if (!children.getCount() || children.getCount() > 1) {
844
add_leaf_bone(mat, bone);
848
void add_leaf_bone(float mat[][4], EditBone *bone)
853
copy_m4_m4(leaf.mat, mat);
854
BLI_strncpy(leaf.name, bone->name, sizeof(leaf.name));
856
leaf_bones.push_back(leaf);
859
void fix_leaf_bones()
861
// just setting tail for leaf bones here
863
std::vector<LeafBone>::iterator it;
864
for (it = leaf_bones.begin(); it != leaf_bones.end(); it++) {
865
LeafBone& leaf = *it;
868
float vec[3] = {0.0f, 0.0f, 1.0f};
870
mul_v3_fl(vec, leaf_bone_length);
872
copy_v3_v3(leaf.bone->tail, leaf.bone->head);
873
add_v3_v3v3(leaf.bone->tail, leaf.bone->head, vec);
877
void set_leaf_bone_shapes(Object *ob_arm)
879
bPose *pose = ob_arm->pose;
881
std::vector<LeafBone>::iterator it;
882
for (it = leaf_bones.begin(); it != leaf_bones.end(); it++) {
883
LeafBone& leaf = *it;
885
bPoseChannel *pchan = get_pose_channel(pose, leaf.name);
887
pchan->custom = get_empty_for_leaves();
890
fprintf(stderr, "Cannot find a pose channel for leaf bone %s\n", leaf.name);
896
void set_euler_rotmode()
898
// just set rotmode = ROT_MODE_EUL on pose channel for each joint
900
std::map<COLLADAFW::UniqueId, COLLADAFW::Node*>::iterator it;
902
for (it = joint_by_uid.begin(); it != joint_by_uid.end(); it++) {
904
COLLADAFW::Node *joint = it->second;
906
std::map<COLLADAFW::UniqueId, SkinInfo>::iterator sit;
908
for (sit = skin_by_data_uid.begin(); sit != skin_by_data_uid.end(); sit++) {
909
SkinInfo& skin = sit->second;
911
if (skin.uses_joint_or_descendant(joint)) {
912
bPoseChannel *pchan = skin.get_pose_channel_from_node(joint);
915
pchan->rotmode = ROT_MODE_EUL;
918
fprintf(stderr, "Cannot find pose channel for %s.\n", get_joint_name(joint));
928
Object *get_empty_for_leaves()
930
if (empty) return empty;
932
empty = add_object(scene, OB_EMPTY);
933
empty->empty_drawtype = OB_EMPTY_SPHERE;
939
Object *find_armature(COLLADAFW::Node *node)
941
JointData* jd = get_joint_data(node);
942
if (jd) return jd->ob_arm;
944
COLLADAFW::NodePointerArray& children = node->getChildNodes();
945
for (int i = 0; i < children.getCount(); i++) {
946
Object *ob_arm = find_armature(children[i]);
947
if (ob_arm) return ob_arm;
953
ArmatureJoints& get_armature_joints(Object *ob_arm)
956
std::vector<ArmatureJoints>::iterator it;
957
for (it = armature_joints.begin(); it != armature_joints.end(); it++) {
958
if ((*it).ob_arm == ob_arm) return *it;
961
// not found, create one
964
armature_joints.push_back(aj);
966
return armature_joints.back();
970
void create_armature_bones(SkinInfo& skin)
975
// - add edit bones and head/tail properties using matrices and parent-child info
977
// - set a sphere shape to leaf bones
979
Object *ob_arm = NULL;
982
* find if there's another skin sharing at least one bone with this skin
983
* if so, use that skin's armature
989
find_node_in_tree(node, root_joint)
991
skin::find_root_joints(root_joints):
992
std::vector root_joints;
993
for each root in root_joints:
994
for each joint in joints:
995
if find_node_in_tree(joint, root):
996
if (std::find(root_joints.begin(), root_joints.end(), root) == root_joints.end())
997
root_joints.push_back(root);
999
for (each skin B with armature) {
1000
find all root joints for skin B
1002
for each joint X in skin A:
1003
for each root joint R in skin B:
1004
if (find_node_in_tree(X, R)) {
1013
SkinInfo *a = &skin;
1014
Object *shared = NULL;
1015
std::vector<COLLADAFW::Node*> skin_root_joints;
1017
std::map<COLLADAFW::UniqueId, SkinInfo>::iterator it;
1018
for (it = skin_by_data_uid.begin(); it != skin_by_data_uid.end(); it++) {
1019
SkinInfo *b = &it->second;
1020
if (b == a || b->get_armature() == NULL)
1023
skin_root_joints.clear();
1025
b->find_root_joints(root_joints, joint_by_uid, skin_root_joints);
1027
std::vector<COLLADAFW::Node*>::iterator ri;
1028
for (ri = skin_root_joints.begin(); ri != skin_root_joints.end(); ri++) {
1029
if (a->uses_joint_or_descendant(*ri)) {
1030
shared = b->get_armature();
1040
ob_arm = skin.set_armature(shared);
155
void DocumentImporter::cancel(const COLLADAFW::String& errorMessage)
157
// TODO: if possible show error info
159
// Should we get rid of invisible Meshes that were created so far
160
// or maybe create objects at coordinate space origin?
162
// The latter sounds better.
165
void DocumentImporter::start()
169
void DocumentImporter::finish()
171
if (mImportStage!=General)
174
/** TODO Break up and put into 2-pass parsing of DAE */
175
std::vector<const COLLADAFW::VisualScene*>::iterator it;
176
for (it = vscenes.begin(); it != vscenes.end(); it++) {
177
PointerRNA sceneptr, unit_settings;
178
PropertyRNA *system, *scale;
179
// TODO: create a new scene except the selected <visual_scene> - use current blender scene for it
180
Scene *sce = CTX_data_scene(mContext);
182
// for scene unit settings: system, scale_length
183
RNA_id_pointer_create(&sce->id, &sceneptr);
184
unit_settings = RNA_pointer_get(&sceneptr, "unit_settings");
185
system = RNA_struct_find_property(&unit_settings, "system");
186
scale = RNA_struct_find_property(&unit_settings, "scale_length");
188
switch(unit_converter.isMetricSystem()) {
189
case UnitConverter::Metric:
190
RNA_property_enum_set(&unit_settings, system, USER_UNIT_METRIC);
192
case UnitConverter::Imperial:
193
RNA_property_enum_set(&unit_settings, system, USER_UNIT_IMPERIAL);
196
RNA_property_enum_set(&unit_settings, system, USER_UNIT_NONE);
199
RNA_property_float_set(&unit_settings, scale, unit_converter.getLinearMeter());
201
const COLLADAFW::NodePointerArray& roots = (*it)->getRootNodes();
203
for (unsigned int i = 0; i < roots.getCount(); i++) {
204
write_node(roots[i], NULL, sce, NULL, false);
207
armature_importer.set_tags_map(this->uid_tags_map);
208
armature_importer.make_armatures(mContext);
211
armature_importer.fix_animation();
214
for (std::vector<const COLLADAFW::VisualScene*>::iterator it = vscenes.begin(); it != vscenes.end(); it++) {
215
const COLLADAFW::NodePointerArray& roots = (*it)->getRootNodes();
217
for (unsigned int i = 0; i < roots.getCount(); i++)
218
translate_anim_recursive(roots[i],NULL,NULL);
221
if (libnode_ob.size()) {
222
Scene *sce = CTX_data_scene(mContext);
224
fprintf(stderr, "got %d library nodes to free\n", (int)libnode_ob.size());
225
// free all library_nodes
226
std::vector<Object*>::iterator it;
227
for (it = libnode_ob.begin(); it != libnode_ob.end(); it++) {
230
Base *base = object_in_scene(ob, sce);
232
BLI_remlink(&sce->base, base);
233
free_libblock_us(&G.main->object, base->object);
234
if (sce->basact==base)
241
DAG_scene_sort(CTX_data_main(mContext), sce);
242
DAG_ids_flush_update(CTX_data_main(mContext), 0);
247
void DocumentImporter::translate_anim_recursive(COLLADAFW::Node *node, COLLADAFW::Node *par = NULL, Object *parob = NULL)
250
// The split in #29246, rootmap must point at actual root when
251
// calculating bones in apply_curves_as_matrix.
252
// This has to do with inverse bind poses being world space
253
// (the sources for skinned bones' restposes) and the way
254
// non-skinning nodes have their "restpose" recursively calculated.
255
// XXX TODO: design issue, how to support unrelated joints taking
257
if (par) { // && par->getType() == COLLADAFW::Node::JOINT) {
258
// par is root if there's no corresp. key in root_map
259
if (root_map.find(par->getUniqueId()) == root_map.end())
260
root_map[node->getUniqueId()] = par;
1042
ob_arm = skin.create_armature(scene);
1044
// enter armature edit mode
1045
ED_armature_to_edit(ob_arm);
1049
// bone_direction_row = 1; // TODO: don't default to Y but use asset and based on it decide on default row
1050
leaf_bone_length = 0.1f;
1051
// min_angle = 360.0f; // minimum angle between bone head-tail and a row of bone matrix
1056
check if bones have already been created for a given joint
1059
std::vector<COLLADAFW::Node*>::iterator ri;
1060
for (ri = root_joints.begin(); ri != root_joints.end(); ri++) {
1061
// for shared armature check if bone tree is already created
1062
if (shared && std::find(skin_root_joints.begin(), skin_root_joints.end(), *ri) != skin_root_joints.end())
1065
// since root_joints may contain joints for multiple controllers, we need to filter
1066
if (skin.uses_joint_or_descendant(*ri)) {
1067
create_bone(skin, *ri, NULL, (*ri)->getChildNodes().getCount(), NULL, (bArmature*)ob_arm->data);
1069
if (joint_parent_map.find((*ri)->getUniqueId()) != joint_parent_map.end() && !skin.get_parent())
1070
skin.set_parent(joint_parent_map[(*ri)->getUniqueId()]);
1076
// exit armature edit mode
1077
ED_armature_from_edit(ob_arm);
1078
ED_armature_edit_free(ob_arm);
1079
DAG_id_flush_update(&ob_arm->id, OB_RECALC_OB|OB_RECALC_DATA);
1081
set_leaf_bone_shapes(ob_arm);
1083
// set_euler_rotmode();
1089
ArmatureImporter(UnitConverter *conv, MeshImporterBase *mesh, AnimationImporterBase *anim, Scene *sce) :
1090
TransformReader(conv), scene(sce), empty(NULL), mesh_importer(mesh), anim_importer(anim) {}
1094
// free skin controller data if we forget to do this earlier
1095
std::map<COLLADAFW::UniqueId, SkinInfo>::iterator it;
1096
for (it = skin_by_data_uid.begin(); it != skin_by_data_uid.end(); it++) {
1101
// root - if this joint is the top joint in hierarchy, if a joint
1102
// is a child of a node (not joint), root should be true since
1103
// this is where we build armature bones from
1104
void add_joint(COLLADAFW::Node *node, bool root, Object *parent)
1106
joint_by_uid[node->getUniqueId()] = node;
1108
root_joints.push_back(node);
1111
joint_parent_map[node->getUniqueId()] = parent;
1116
void add_root_joint(COLLADAFW::Node *node)
1118
// root_joints.push_back(node);
1119
Object *ob_arm = find_armature(node);
1121
get_armature_joints(ob_arm).root_joints.push_back(node);
1123
#ifdef COLLADA_DEBUG
1125
fprintf(stderr, "%s cannot be added to armature.\n", get_joint_name(node));
1131
// here we add bones to armatures, having armatures previously created in write_controller
1132
void make_armatures(bContext *C)
1134
std::map<COLLADAFW::UniqueId, SkinInfo>::iterator it;
1135
for (it = skin_by_data_uid.begin(); it != skin_by_data_uid.end(); it++) {
1137
SkinInfo& skin = it->second;
1139
create_armature_bones(skin);
1141
// link armature with a mesh object
1142
Object *ob = mesh_importer->get_object_by_geom_uid(*get_geometry_uid(skin.get_controller_uid()));
1144
skin.link_armature(C, ob, joint_by_uid, this);
1146
fprintf(stderr, "Cannot find object to link armature with.\n");
1148
// set armature parent if any
1149
Object *par = skin.get_parent();
1151
set_parent(skin.get_armature(), par, C, false);
1153
// free memory stolen from SkinControllerData
1159
// link with meshes, create vertex groups, assign weights
1160
void link_armature(Object *ob_arm, const COLLADAFW::UniqueId& geom_id, const COLLADAFW::UniqueId& controller_data_id)
1162
Object *ob = mesh_importer->get_object_by_geom_uid(geom_id);
1165
fprintf(stderr, "Cannot find object by geometry UID.\n");
1169
if (skin_by_data_uid.find(controller_data_id) == skin_by_data_uid.end()) {
1170
fprintf(stderr, "Cannot find skin info by controller data UID.\n");
1174
SkinInfo& skin = skin_by_data_uid[conroller_data_id];
1176
// create vertex groups
1180
bool write_skin_controller_data(const COLLADAFW::SkinControllerData* data)
1182
// at this stage we get vertex influence info that should go into me->verts and ob->defbase
1183
// there's no info to which object this should be long so we associate it with skin controller data UID
1185
// don't forget to call defgroup_unique_name before we copy
1187
// controller data uid -> [armature] -> joint data,
1191
SkinInfo skin(unit_converter);
1192
skin.borrow_skin_controller_data(data);
1194
// store join inv bind matrix to use it later in armature construction
1195
const COLLADAFW::Matrix4Array& inv_bind_mats = data->getInverseBindMatrices();
1196
for (unsigned int i = 0; i < data->getJointsCount(); i++) {
1197
skin.add_joint(inv_bind_mats[i]);
1200
skin_by_data_uid[data->getUniqueId()] = skin;
1205
bool write_controller(const COLLADAFW::Controller* controller)
1207
// - create and store armature object
1209
const COLLADAFW::UniqueId& skin_id = controller->getUniqueId();
1211
if (controller->getControllerType() == COLLADAFW::Controller::CONTROLLER_TYPE_SKIN) {
1212
COLLADAFW::SkinController *co = (COLLADAFW::SkinController*)controller;
1213
// to be able to find geom id by controller id
1214
geom_uid_by_controller_uid[skin_id] = co->getSource();
1216
const COLLADAFW::UniqueId& data_uid = co->getSkinControllerData();
1217
if (skin_by_data_uid.find(data_uid) == skin_by_data_uid.end()) {
1218
fprintf(stderr, "Cannot find skin by controller data UID.\n");
1222
skin_by_data_uid[data_uid].set_controller(co);
1227
fprintf(stderr, "Morph controller is not supported yet.\n");
1233
COLLADAFW::UniqueId *get_geometry_uid(const COLLADAFW::UniqueId& controller_uid)
1235
if (geom_uid_by_controller_uid.find(controller_uid) == geom_uid_by_controller_uid.end())
1238
return &geom_uid_by_controller_uid[controller_uid];
1241
Object *get_armature_for_joint(COLLADAFW::Node *node)
1243
std::map<COLLADAFW::UniqueId, SkinInfo>::iterator it;
1244
for (it = skin_by_data_uid.begin(); it != skin_by_data_uid.end(); it++) {
1245
SkinInfo& skin = it->second;
1247
if (skin.uses_joint_or_descendant(node))
1248
return skin.get_armature();
1254
void get_rna_path_for_joint(COLLADAFW::Node *node, char *joint_path, size_t count)
1256
BLI_snprintf(joint_path, count, "pose.bones[\"%s\"]", get_joint_name(node));
1259
// gives a world-space mat
1260
bool get_joint_bind_mat(float m[][4], COLLADAFW::Node *joint)
1262
std::map<COLLADAFW::UniqueId, SkinInfo>::iterator it;
1264
for (it = skin_by_data_uid.begin(); it != skin_by_data_uid.end(); it++) {
1265
SkinInfo& skin = it->second;
1266
if ((found = skin.get_joint_inv_bind_matrix(m, joint))) {
1276
class MeshImporter : public MeshImporterBase
1281
ArmatureImporter *armature_importer;
1283
std::map<COLLADAFW::UniqueId, Mesh*> uid_mesh_map; // geometry unique id-to-mesh map
1284
std::map<COLLADAFW::UniqueId, Object*> uid_object_map; // geom uid-to-object
1285
// this structure is used to assign material indices to faces
1286
// it holds a portion of Mesh faces and corresponds to a DAE primitive list (<triangles>, <polylist>, etc.)
1289
unsigned int totface;
1291
typedef std::map<COLLADAFW::MaterialId, std::vector<Primitive> > MaterialIdPrimitiveArrayMap;
1292
std::map<COLLADAFW::UniqueId, MaterialIdPrimitiveArrayMap> geom_uid_mat_mapping_map; // crazy name!
1296
COLLADAFW::MeshVertexData *mVData;
1298
UVDataWrapper(COLLADAFW::MeshVertexData& vdata) : mVData(&vdata)
1301
#ifdef COLLADA_DEBUG
1304
fprintf(stderr, "UVs:\n");
1305
switch(mVData->getType()) {
1306
case COLLADAFW::MeshVertexData::DATA_TYPE_FLOAT:
1308
COLLADAFW::ArrayPrimitiveType<float>* values = mVData->getFloatValues();
1309
if (values->getCount()) {
1310
for (int i = 0; i < values->getCount(); i += 2) {
1311
fprintf(stderr, "%.1f, %.1f\n", (*values)[i], (*values)[i+1]);
1316
case COLLADAFW::MeshVertexData::DATA_TYPE_DOUBLE:
1318
COLLADAFW::ArrayPrimitiveType<double>* values = mVData->getDoubleValues();
1319
if (values->getCount()) {
1320
for (int i = 0; i < values->getCount(); i += 2) {
1321
fprintf(stderr, "%.1f, %.1f\n", (float)(*values)[i], (float)(*values)[i+1]);
1327
fprintf(stderr, "\n");
1331
void getUV(int uv_index[2], float *uv)
1333
switch(mVData->getType()) {
1334
case COLLADAFW::MeshVertexData::DATA_TYPE_FLOAT:
1336
COLLADAFW::ArrayPrimitiveType<float>* values = mVData->getFloatValues();
1337
if (values->empty()) return;
1338
uv[0] = (*values)[uv_index[0]];
1339
uv[1] = (*values)[uv_index[1]];
1343
case COLLADAFW::MeshVertexData::DATA_TYPE_DOUBLE:
1345
COLLADAFW::ArrayPrimitiveType<double>* values = mVData->getDoubleValues();
1346
if (values->empty()) return;
1347
uv[0] = (float)(*values)[uv_index[0]];
1348
uv[1] = (float)(*values)[uv_index[1]];
1352
case COLLADAFW::MeshVertexData::DATA_TYPE_UNKNOWN:
1354
fprintf(stderr, "MeshImporter.getUV(): unknown data type\n");
1359
void set_face_indices(MFace *mface, unsigned int *indices, bool quad)
1361
mface->v1 = indices[0];
1362
mface->v2 = indices[1];
1363
mface->v3 = indices[2];
1364
if (quad) mface->v4 = indices[3];
1366
#ifdef COLLADA_DEBUG
1367
// fprintf(stderr, "%u, %u, %u \n", indices[0], indices[1], indices[2]);
1371
// not used anymore, test_index_face from blenkernel is better
1373
// change face indices order so that v4 is not 0
1374
void rotate_face_indices(MFace *mface) {
1375
mface->v4 = mface->v1;
1376
mface->v1 = mface->v2;
1377
mface->v2 = mface->v3;
1382
void set_face_uv(MTFace *mtface, UVDataWrapper &uvs,
1383
COLLADAFW::IndexList& index_list, unsigned int *tris_indices)
1385
int uv_indices[4][2];
1387
// per face vertex indices, this means for quad we have 4 indices, not 8
1388
COLLADAFW::UIntValuesArray& indices = index_list.getIndices();
1390
// make indices into FloatOrDoubleArray
1391
for (int i = 0; i < 3; i++) {
1392
int uv_index = indices[tris_indices[i]];
1393
uv_indices[i][0] = uv_index * 2;
1394
uv_indices[i][1] = uv_index * 2 + 1;
1397
uvs.getUV(uv_indices[0], mtface->uv[0]);
1398
uvs.getUV(uv_indices[1], mtface->uv[1]);
1399
uvs.getUV(uv_indices[2], mtface->uv[2]);
1402
void set_face_uv(MTFace *mtface, UVDataWrapper &uvs,
1403
COLLADAFW::IndexList& index_list, int index, bool quad)
1405
int uv_indices[4][2];
1407
// per face vertex indices, this means for quad we have 4 indices, not 8
1408
COLLADAFW::UIntValuesArray& indices = index_list.getIndices();
1410
// make indices into FloatOrDoubleArray
1411
for (int i = 0; i < (quad ? 4 : 3); i++) {
1412
int uv_index = indices[index + i];
1413
uv_indices[i][0] = uv_index * 2;
1414
uv_indices[i][1] = uv_index * 2 + 1;
1417
uvs.getUV(uv_indices[0], mtface->uv[0]);
1418
uvs.getUV(uv_indices[1], mtface->uv[1]);
1419
uvs.getUV(uv_indices[2], mtface->uv[2]);
1421
if (quad) uvs.getUV(uv_indices[3], mtface->uv[3]);
1423
#ifdef COLLADA_DEBUG
1425
fprintf(stderr, "face uv:\n"
1426
"((%d, %d), (%d, %d), (%d, %d), (%d, %d))\n"
1427
"((%.1f, %.1f), (%.1f, %.1f), (%.1f, %.1f), (%.1f, %.1f))\n",
1429
uv_indices[0][0], uv_indices[0][1],
1430
uv_indices[1][0], uv_indices[1][1],
1431
uv_indices[2][0], uv_indices[2][1],
1432
uv_indices[3][0], uv_indices[3][1],
1434
mtface->uv[0][0], mtface->uv[0][1],
1435
mtface->uv[1][0], mtface->uv[1][1],
1436
mtface->uv[2][0], mtface->uv[2][1],
1437
mtface->uv[3][0], mtface->uv[3][1]);
1440
fprintf(stderr, "face uv:\n"
1441
"((%d, %d), (%d, %d), (%d, %d))\n"
1442
"((%.1f, %.1f), (%.1f, %.1f), (%.1f, %.1f))\n",
1444
uv_indices[0][0], uv_indices[0][1],
1445
uv_indices[1][0], uv_indices[1][1],
1446
uv_indices[2][0], uv_indices[2][1],
1448
mtface->uv[0][0], mtface->uv[0][1],
1449
mtface->uv[1][0], mtface->uv[1][1],
1450
mtface->uv[2][0], mtface->uv[2][1]);
1455
#ifdef COLLADA_DEBUG
1456
void print_index_list(COLLADAFW::IndexList& index_list)
1458
fprintf(stderr, "Index list for \"%s\":\n", index_list.getName().c_str());
1459
for (int i = 0; i < index_list.getIndicesCount(); i += 2) {
1460
fprintf(stderr, "%u, %u\n", index_list.getIndex(i), index_list.getIndex(i + 1));
1462
fprintf(stderr, "\n");
1466
bool is_nice_mesh(COLLADAFW::Mesh *mesh)
1468
COLLADAFW::MeshPrimitiveArray& prim_arr = mesh->getMeshPrimitives();
1470
const char *name = get_dae_name(mesh);
1472
for (unsigned i = 0; i < prim_arr.getCount(); i++) {
1474
COLLADAFW::MeshPrimitive *mp = prim_arr[i];
1475
COLLADAFW::MeshPrimitive::PrimitiveType type = mp->getPrimitiveType();
1477
const char *type_str = primTypeToStr(type);
1479
// OpenCollada passes POLYGONS type for <polylist>
1480
if (type == COLLADAFW::MeshPrimitive::POLYLIST || type == COLLADAFW::MeshPrimitive::POLYGONS) {
1482
COLLADAFW::Polygons *mpvc = (COLLADAFW::Polygons*)mp;
1483
COLLADAFW::Polygons::VertexCountArray& vca = mpvc->getGroupedVerticesVertexCountArray();
1485
for(unsigned int j = 0; j < vca.getCount(); j++){
1488
fprintf(stderr, "Primitive %s in %s has at least one face with vertex count < 3\n",
1495
else if(type != COLLADAFW::MeshPrimitive::TRIANGLES) {
1496
fprintf(stderr, "Primitive type %s is not supported.\n", type_str);
1501
if (mesh->getPositions().empty()) {
1502
fprintf(stderr, "Mesh %s has no vertices.\n", name);
1509
void read_vertices(COLLADAFW::Mesh *mesh, Mesh *me)
1512
me->totvert = mesh->getPositions().getFloatValues()->getCount() / 3;
1513
me->mvert = (MVert*)CustomData_add_layer(&me->vdata, CD_MVERT, CD_CALLOC, NULL, me->totvert);
1515
COLLADAFW::MeshVertexData& pos = mesh->getPositions();
1519
for (i = 0, mvert = me->mvert; i < me->totvert; i++, mvert++)
1520
get_vector(mvert->co, pos, i);
1523
int triangulate_poly(unsigned int *indices, int totvert, MVert *verts, std::vector<unsigned int>& tri)
1530
dispbase.first = dispbase.last = NULL;
1532
dl = (DispList*)MEM_callocN(sizeof(DispList), "poly disp");
1536
dl->verts = vert = (float*)MEM_callocN(totvert * 3 * sizeof(float), "poly verts");
1537
dl->index = (int*)MEM_callocN(sizeof(int) * 3 * totvert, "dl index");
1539
BLI_addtail(&dispbase, dl);
1541
for (i = 0; i < totvert; i++) {
1542
copy_v3_v3(vert, verts[indices[i]].co);
1546
filldisplist(&dispbase, &dispbase, 0);
1549
dl= (DispList*)dispbase.first;
1551
if (dl->type == DL_INDEX3) {
1554
int *index = dl->index;
1555
for (i= 0; i < tottri; i++) {
1556
int t[3]= {*index, *(index + 1), *(index + 2)};
1558
std::sort(t, t + 3);
1560
tri.push_back(t[0]);
1561
tri.push_back(t[1]);
1562
tri.push_back(t[2]);
1568
freedisplist(&dispbase);
1573
int count_new_tris(COLLADAFW::Mesh *mesh, Mesh *me)
1575
COLLADAFW::MeshPrimitiveArray& prim_arr = mesh->getMeshPrimitives();
1579
for (i = 0; i < prim_arr.getCount(); i++) {
1581
COLLADAFW::MeshPrimitive *mp = prim_arr[i];
1582
int type = mp->getPrimitiveType();
1583
size_t prim_totface = mp->getFaceCount();
1584
unsigned int *indices = mp->getPositionIndices().getData();
1586
if (type == COLLADAFW::MeshPrimitive::POLYLIST ||
1587
type == COLLADAFW::MeshPrimitive::POLYGONS) {
1589
COLLADAFW::Polygons *mpvc = (COLLADAFW::Polygons*)mp;
1590
COLLADAFW::Polygons::VertexCountArray& vcounta = mpvc->getGroupedVerticesVertexCountArray();
1592
for (unsigned int j = 0; j < prim_totface; j++) {
1593
int vcount = vcounta[j];
1596
std::vector<unsigned int> tri;
1598
// tottri += triangulate_poly(indices, vcount, me->mvert, tri) - 1; // XXX why - 1?!
1599
tottri += triangulate_poly(indices, vcount, me->mvert, tri);
1609
// TODO: import uv set names
1610
void read_faces(COLLADAFW::Mesh *mesh, Mesh *me, int new_tris)
1615
me->totface = mesh->getFacesCount() + new_tris;
1616
me->mface = (MFace*)CustomData_add_layer(&me->fdata, CD_MFACE, CD_CALLOC, NULL, me->totface);
1618
// allocate UV layers
1619
unsigned int totuvset = mesh->getUVCoords().getInputInfosArray().getCount();
1621
// for (i = 0; i < totuvset; i++) {
1622
// if (mesh->getUVCoords().getLength(i) == 0) {
1628
for (i = 0; i < totuvset; i++) {
1629
CustomData_add_layer(&me->fdata, CD_MTFACE, CD_CALLOC, NULL, me->totface);
1630
//this->set_layername_map[i] = CustomData_get_layer_name(&me->fdata, CD_MTFACE, i);
1633
// activate the first uv layer
1634
if (totuvset) me->mtface = (MTFace*)CustomData_get_layer_n(&me->fdata, CD_MTFACE, 0);
1636
UVDataWrapper uvs(mesh->getUVCoords());
1638
#ifdef COLLADA_DEBUG
1642
MFace *mface = me->mface;
1644
MaterialIdPrimitiveArrayMap mat_prim_map;
1648
COLLADAFW::MeshPrimitiveArray& prim_arr = mesh->getMeshPrimitives();
1650
bool has_normals = mesh->hasNormals();
1651
COLLADAFW::MeshVertexData& nor = mesh->getNormals();
1653
for (i = 0; i < prim_arr.getCount(); i++) {
1655
COLLADAFW::MeshPrimitive *mp = prim_arr[i];
1658
size_t prim_totface = mp->getFaceCount();
1659
unsigned int *indices = mp->getPositionIndices().getData();
1660
unsigned int *nind = mp->getNormalIndices().getData();
1662
int type = mp->getPrimitiveType();
1665
// since we cannot set mface->mat_nr here, we store a portion of me->mface in Primitive
1666
Primitive prim = {mface, 0};
1667
COLLADAFW::IndexListArray& index_list_array = mp->getUVCoordIndicesArray();
1669
#ifdef COLLADA_DEBUG
1671
fprintf(stderr, "Primitive %d:\n", i);
1672
for (int j = 0; j < totuvset; j++) {
1673
print_index_list(*index_list_array[j]);
1678
if (type == COLLADAFW::MeshPrimitive::TRIANGLES) {
1679
for (j = 0; j < prim_totface; j++){
1681
set_face_indices(mface, indices, false);
1685
for (k = 0; k < totuvset; k++) {
1686
if (!index_list_array.empty() && index_list_array[k]) {
1687
// get mtface by face index and uv set index
1688
MTFace *mtface = (MTFace*)CustomData_get_layer_n(&me->fdata, CD_MTFACE, k);
1689
set_face_uv(&mtface[face_index], uvs, k, *index_list_array[k], index, false);
1693
for (k = 0; k < index_list_array.getCount(); k++) {
1694
int uvset_index = index_list_array[k]->getSetIndex();
1696
// get mtface by face index and uv set index
1697
MTFace *mtface = (MTFace*)CustomData_get_layer_n(&me->fdata, CD_MTFACE, uvset_index);
1698
set_face_uv(&mtface[face_index], uvs, *index_list_array[k], index, false);
1702
test_index_face(mface, &me->fdata, face_index, 3);
1705
if (!flat_face(nind, nor, 3))
1706
mface->flag |= ME_SMOOTH;
1717
else if (type == COLLADAFW::MeshPrimitive::POLYLIST || type == COLLADAFW::MeshPrimitive::POLYGONS) {
1718
COLLADAFW::Polygons *mpvc = (COLLADAFW::Polygons*)mp;
1719
COLLADAFW::Polygons::VertexCountArray& vcounta = mpvc->getGroupedVerticesVertexCountArray();
1721
for (j = 0; j < prim_totface; j++) {
1724
int vcount = vcounta[j];
1725
if (vcount == 3 || vcount == 4) {
1727
set_face_indices(mface, indices, vcount == 4);
1729
// set mtface for each uv set
1730
// it is assumed that all primitives have equal number of UV sets
1733
for (k = 0; k < totuvset; k++) {
1734
if (!index_list_array.empty() && index_list_array[k]) {
1735
// get mtface by face index and uv set index
1736
MTFace *mtface = (MTFace*)CustomData_get_layer_n(&me->fdata, CD_MTFACE, k);
1737
set_face_uv(&mtface[face_index], uvs, k, *index_list_array[k], index, mface->v4 != 0);
1741
for (k = 0; k < index_list_array.getCount(); k++) {
1742
int uvset_index = index_list_array[k]->getSetIndex();
1744
// get mtface by face index and uv set index
1745
MTFace *mtface = (MTFace*)CustomData_get_layer_n(&me->fdata, CD_MTFACE, uvset_index);
1746
set_face_uv(&mtface[face_index], uvs, *index_list_array[k], index, mface->v4 != 0);
1750
test_index_face(mface, &me->fdata, face_index, vcount);
1753
if (!flat_face(nind, nor, vcount))
1754
mface->flag |= ME_SMOOTH;
1765
std::vector<unsigned int> tri;
1767
triangulate_poly(indices, vcount, me->mvert, tri);
1769
for (k = 0; k < tri.size() / 3; k++) {
1771
unsigned int uv_indices[3] = {
1776
unsigned int tri_indices[3] = {
1778
indices[tri[v + 1]],
1782
set_face_indices(mface, tri_indices, false);
1785
for (unsigned int l = 0; l < totuvset; l++) {
1786
if (!index_list_array.empty() && index_list_array[l]) {
1787
// get mtface by face index and uv set index
1788
MTFace *mtface = (MTFace*)CustomData_get_layer_n(&me->fdata, CD_MTFACE, l);
1789
set_face_uv(&mtface[face_index], uvs, l, *index_list_array[l], uv_indices);
1793
for (unsigned int l = 0; l < index_list_array.getCount(); l++) {
1794
int uvset_index = index_list_array[l]->getSetIndex();
1796
// get mtface by face index and uv set index
1797
MTFace *mtface = (MTFace*)CustomData_get_layer_n(&me->fdata, CD_MTFACE, uvset_index);
1798
set_face_uv(&mtface[face_index], uvs, *index_list_array[l], uv_indices);
1803
test_index_face(mface, &me->fdata, face_index, 3);
1806
unsigned int ntri[3] = {nind[tri[v]], nind[tri[v + 1]], nind[tri[v + 2]]};
1808
if (!flat_face(ntri, nor, 3))
1809
mface->flag |= ME_SMOOTH;
1826
mat_prim_map[mp->getMaterialId()].push_back(prim);
1829
geom_uid_mat_mapping_map[mesh->getUniqueId()] = mat_prim_map;
1832
void get_vector(float v[3], COLLADAFW::MeshVertexData& arr, int i)
1836
switch(arr.getType()) {
1837
case COLLADAFW::MeshVertexData::DATA_TYPE_FLOAT:
1839
COLLADAFW::ArrayPrimitiveType<float>* values = arr.getFloatValues();
1840
if (values->empty()) return;
1842
v[0] = (*values)[i++];
1843
v[1] = (*values)[i++];
1844
v[2] = (*values)[i];
1847
case COLLADAFW::MeshVertexData::DATA_TYPE_DOUBLE:
1849
COLLADAFW::ArrayPrimitiveType<double>* values = arr.getDoubleValues();
1850
if (values->empty()) return;
1852
v[0] = (float)(*values)[i++];
1853
v[1] = (float)(*values)[i++];
1854
v[2] = (float)(*values)[i];
1862
bool flat_face(unsigned int *nind, COLLADAFW::MeshVertexData& nor, int count)
1866
get_vector(a, nor, *nind);
1871
for (int i = 1; i < count; i++, nind++) {
1872
get_vector(b, nor, *nind);
1875
float dp = dot_v3v3(a, b);
1877
if (dp < 0.99999f || dp > 1.00001f)
1886
MeshImporter(ArmatureImporter *arm, Scene *sce) : scene(sce), armature_importer(arm) {}
1888
virtual Object *get_object_by_geom_uid(const COLLADAFW::UniqueId& geom_uid)
1890
if (uid_object_map.find(geom_uid) != uid_object_map.end())
1891
return uid_object_map[geom_uid];
1895
MTex *assign_textures_to_uvlayer(COLLADAFW::TextureCoordinateBinding &ctexture,
1896
Mesh *me, TexIndexTextureArrayMap& texindex_texarray_map,
1897
MTex *color_texture)
1899
COLLADAFW::TextureMapId texture_index = ctexture.getTextureMapId();
1900
char *uvname = CustomData_get_layer_name(&me->fdata, CD_MTFACE, ctexture.getSetIndex());
1902
if (texindex_texarray_map.find(texture_index) == texindex_texarray_map.end()) {
1904
fprintf(stderr, "Cannot find texture array by texture index.\n");
1905
return color_texture;
1908
std::vector<MTex*> textures = texindex_texarray_map[texture_index];
1910
std::vector<MTex*>::iterator it;
1912
for (it = textures.begin(); it != textures.end(); it++) {
1914
MTex *texture = *it;
1917
strcpy(texture->uvname, uvname);
1918
if (texture->mapto == MAP_COL) color_texture = texture;
1921
return color_texture;
1924
MTFace *assign_material_to_geom(COLLADAFW::MaterialBinding cmaterial,
1925
std::map<COLLADAFW::UniqueId, Material*>& uid_material_map,
1926
Object *ob, const COLLADAFW::UniqueId *geom_uid,
1927
MTex **color_texture, char *layername, MTFace *texture_face,
1928
std::map<Material*, TexIndexTextureArrayMap>& material_texture_mapping_map, int mat_index)
1930
Mesh *me = (Mesh*)ob->data;
1931
const COLLADAFW::UniqueId& ma_uid = cmaterial.getReferencedMaterial();
1933
// do we know this material?
1934
if (uid_material_map.find(ma_uid) == uid_material_map.end()) {
1936
fprintf(stderr, "Cannot find material by UID.\n");
1940
Material *ma = uid_material_map[ma_uid];
1941
assign_material(ob, ma, ob->totcol + 1);
1943
COLLADAFW::TextureCoordinateBindingArray& tex_array =
1944
cmaterial.getTextureCoordinateBindingArray();
1945
TexIndexTextureArrayMap texindex_texarray_map = material_texture_mapping_map[ma];
1947
// loop through <bind_vertex_inputs>
1948
for (i = 0; i < tex_array.getCount(); i++) {
1950
*color_texture = assign_textures_to_uvlayer(tex_array[i], me, texindex_texarray_map,
1955
if (*color_texture &&
1956
strlen((*color_texture)->uvname) &&
1957
strcmp(layername, (*color_texture)->uvname) != 0) {
1959
texture_face = (MTFace*)CustomData_get_layer_named(&me->fdata, CD_MTFACE,
1960
(*color_texture)->uvname);
1961
strcpy(layername, (*color_texture)->uvname);
1964
MaterialIdPrimitiveArrayMap& mat_prim_map = geom_uid_mat_mapping_map[*geom_uid];
1965
COLLADAFW::MaterialId mat_id = cmaterial.getMaterialId();
1967
// assign material indices to mesh faces
1968
if (mat_prim_map.find(mat_id) != mat_prim_map.end()) {
1970
std::vector<Primitive>& prims = mat_prim_map[mat_id];
1972
std::vector<Primitive>::iterator it;
1974
for (it = prims.begin(); it != prims.end(); it++) {
1975
Primitive& prim = *it;
1977
while (i++ < prim.totface) {
1978
prim.mface->mat_nr = mat_index;
1980
// bind texture images to faces
1981
if (texture_face && (*color_texture)) {
1982
texture_face->mode = TF_TEX;
1983
texture_face->tpage = (Image*)(*color_texture)->tex->ima;
1990
return texture_face;
1994
Object *create_mesh_object(COLLADAFW::Node *node, COLLADAFW::InstanceGeometry *geom,
1996
std::map<COLLADAFW::UniqueId, Material*>& uid_material_map,
1997
std::map<Material*, TexIndexTextureArrayMap>& material_texture_mapping_map)
1999
const COLLADAFW::UniqueId *geom_uid = &geom->getInstanciatedObjectId();
2001
// check if node instanciates controller or geometry
2004
geom_uid = armature_importer->get_geometry_uid(*geom_uid);
2007
fprintf(stderr, "Couldn't find a mesh UID by controller's UID.\n");
2013
if (uid_mesh_map.find(*geom_uid) == uid_mesh_map.end()) {
2014
// this could happen if a mesh was not created
2015
// (e.g. if it contains unsupported geometry)
2016
fprintf(stderr, "Couldn't find a mesh by UID.\n");
2020
if (!uid_mesh_map[*geom_uid]) return NULL;
2022
Object *ob = add_object(scene, OB_MESH);
2024
// store object pointer for ArmatureImporter
2025
uid_object_map[*geom_uid] = ob;
2028
const std::string& id = node->getOriginalId();
2030
rename_id(&ob->id, (char*)id.c_str());
2032
// replace ob->data freeing the old one
2033
Mesh *old_mesh = (Mesh*)ob->data;
2035
set_mesh(ob, uid_mesh_map[*geom_uid]);
2037
if (old_mesh->id.us == 0) free_libblock(&G.main->mesh, old_mesh);
2039
char layername[100];
2040
MTFace *texture_face = NULL;
2041
MTex *color_texture = NULL;
2043
COLLADAFW::MaterialBindingArray& mat_array =
2044
geom->getMaterialBindings();
2046
// loop through geom's materials
2047
for (unsigned int i = 0; i < mat_array.getCount(); i++) {
2049
texture_face = assign_material_to_geom(mat_array[i], uid_material_map, ob, geom_uid,
2050
&color_texture, layername, texture_face,
2051
material_texture_mapping_map, i);
2057
// create a mesh storing a pointer in a map so it can be retrieved later by geometry UID
2058
bool write_geometry(const COLLADAFW::Geometry* geom)
2060
// TODO: import also uvs, normals
2061
// XXX what to do with normal indices?
2062
// XXX num_normals may be != num verts, then what to do?
2064
// check geometry->getType() first
2065
if (geom->getType() != COLLADAFW::Geometry::GEO_TYPE_MESH) {
2066
// TODO: report warning
2067
fprintf(stderr, "Mesh type %s is not supported\n", geomTypeToStr(geom->getType()));
2071
COLLADAFW::Mesh *mesh = (COLLADAFW::Mesh*)geom;
2073
if (!is_nice_mesh(mesh)) {
2074
fprintf(stderr, "Ignoring mesh %s\n", get_dae_name(mesh));
2078
const std::string& str_geom_id = mesh->getOriginalId();
2079
Mesh *me = add_mesh((char*)str_geom_id.c_str());
2081
// store the Mesh pointer to link it later with an Object
2082
this->uid_mesh_map[mesh->getUniqueId()] = me;
2086
read_vertices(mesh, me);
2088
new_tris = count_new_tris(mesh, me);
2090
read_faces(mesh, me, new_tris);
2094
mesh_calc_normals(me->mvert, me->totvert, me->mface, me->totface, NULL);
2101
class AnimationImporter : private TransformReader, public AnimationImporterBase
2105
ArmatureImporter *armature_importer;
2108
std::map<COLLADAFW::UniqueId, std::vector<FCurve*> > curve_map;
2109
std::map<COLLADAFW::UniqueId, TransformReader::Animation> uid_animated_map;
2110
// std::map<bActionGroup*, std::vector<FCurve*> > fcurves_actionGroup_map;
2111
std::map<COLLADAFW::UniqueId, const COLLADAFW::AnimationList*> animlist_map;
2112
std::vector<FCurve*> unused_curves;
2113
std::map<COLLADAFW::UniqueId, Object*> joint_objects;
2115
FCurve *create_fcurve(int array_index, const char *rna_path)
2117
FCurve *fcu = (FCurve*)MEM_callocN(sizeof(FCurve), "FCurve");
2119
fcu->flag = (FCURVE_VISIBLE|FCURVE_AUTO_HANDLES|FCURVE_SELECTED);
2120
fcu->rna_path = BLI_strdupn(rna_path, strlen(rna_path));
2121
fcu->array_index = array_index;
2125
void create_bezt(FCurve *fcu, float frame, float output)
2128
memset(&bez, 0, sizeof(BezTriple));
2129
bez.vec[1][0] = frame;
2130
bez.vec[1][1] = output;
2131
bez.ipo = U.ipo_new; /* use default interpolation mode here... */
2132
bez.f1 = bez.f2 = bez.f3 = SELECT;
2133
bez.h1 = bez.h2 = HD_AUTO;
2134
insert_bezt_fcurve(fcu, &bez, 0);
2135
calchandles_fcurve(fcu);
2138
// create one or several fcurves depending on the number of parameters being animated
2139
void animation_to_fcurves(COLLADAFW::AnimationCurve *curve)
2141
COLLADAFW::FloatOrDoubleArray& input = curve->getInputValues();
2142
COLLADAFW::FloatOrDoubleArray& output = curve->getOutputValues();
2143
// COLLADAFW::FloatOrDoubleArray& intan = curve->getInTangentValues();
2144
// COLLADAFW::FloatOrDoubleArray& outtan = curve->getOutTangentValues();
2145
float fps = (float)FPS;
2146
size_t dim = curve->getOutDimension();
2149
std::vector<FCurve*>& fcurves = curve_map[curve->getUniqueId()];
2152
case 1: // X, Y, Z or angle
2156
for (i = 0; i < dim; i++ ) {
2157
FCurve *fcu = (FCurve*)MEM_callocN(sizeof(FCurve), "FCurve");
2159
fcu->flag = (FCURVE_VISIBLE|FCURVE_AUTO_HANDLES|FCURVE_SELECTED);
2160
// fcu->rna_path = BLI_strdupn(path, strlen(path));
2161
fcu->array_index = 0;
2162
//fcu->totvert = curve->getKeyCount();
2164
// create beztriple for each key
2165
for (unsigned int j = 0; j < curve->getKeyCount(); j++) {
2167
memset(&bez, 0, sizeof(BezTriple));
2170
// bez.vec[0][0] = get_float_value(intan, j * 6 + i + i) * fps;
2171
// bez.vec[0][1] = get_float_value(intan, j * 6 + i + i + 1);
2174
bez.vec[1][0] = get_float_value(input, j) * fps;
2175
bez.vec[1][1] = get_float_value(output, j * dim + i);
2178
// bez.vec[2][0] = get_float_value(outtan, j * 6 + i + i) * fps;
2179
// bez.vec[2][1] = get_float_value(outtan, j * 6 + i + i + 1);
2181
bez.ipo = U.ipo_new; /* use default interpolation mode here... */
2182
bez.f1 = bez.f2 = bez.f3 = SELECT;
2183
bez.h1 = bez.h2 = HD_AUTO;
2184
insert_bezt_fcurve(fcu, &bez, 0);
2187
calchandles_fcurve(fcu);
2189
fcurves.push_back(fcu);
2194
fprintf(stderr, "Output dimension of %d is not yet supported (animation id = %s)\n", dim, curve->getOriginalId().c_str());
2197
for (std::vector<FCurve*>::iterator it = fcurves.begin(); it != fcurves.end(); it++)
2198
unused_curves.push_back(*it);
2201
void fcurve_deg_to_rad(FCurve *cu)
2203
for (unsigned int i = 0; i < cu->totvert; i++) {
2204
// TODO convert handles too
2205
cu->bezt[i].vec[1][1] *= M_PI / 180.0f;
2209
void add_fcurves_to_object(Object *ob, std::vector<FCurve*>& curves, char *rna_path, int array_index, Animation *animated)
2213
if (!ob->adt || !ob->adt->action) act = verify_adt_action((ID*)&ob->id, 1);
2214
else act = ob->adt->action;
2216
std::vector<FCurve*>::iterator it;
2220
char *p = strstr(rna_path, "rotation_euler");
2221
bool is_rotation = p && *(p + strlen("rotation_euler")) == '\0';
2223
// convert degrees to radians for rotation
2225
fcurve_deg_to_rad(fcu);
2228
for (it = curves.begin(), i = 0; it != curves.end(); it++, i++) {
2230
fcu->rna_path = BLI_strdupn(rna_path, strlen(rna_path));
2232
if (array_index == -1) fcu->array_index = i;
2233
else fcu->array_index = array_index;
2235
if (ob->type == OB_ARMATURE) {
2236
bActionGroup *grp = NULL;
2237
const char *bone_name = get_joint_name(animated->node);
2240
/* try to find group */
2241
grp = action_groups_find_named(act, bone_name);
2243
/* no matching groups, so add one */
2245
/* Add a new group, and make it active */
2246
grp = (bActionGroup*)MEM_callocN(sizeof(bActionGroup), "bActionGroup");
2248
grp->flag = AGRP_SELECTED;
2249
BLI_strncpy(grp->name, bone_name, sizeof(grp->name));
2251
BLI_addtail(&act->groups, grp);
2252
BLI_uniquename(&act->groups, grp, "Group", '.', offsetof(bActionGroup, name), 64);
2255
/* add F-Curve to group */
2256
action_groups_add_channel(act, grp, fcu);
2261
fcurves_actionGroup_map[grp].push_back(fcu);
2266
BLI_addtail(&act->curves, fcu);
2269
// curve is used, so remove it from unused_curves
2270
unused_curves.erase(std::remove(unused_curves.begin(), unused_curves.end(), fcu), unused_curves.end());
2275
AnimationImporter(UnitConverter *conv, ArmatureImporter *arm, Scene *scene) :
2276
TransformReader(conv), armature_importer(arm), scene(scene) { }
2278
~AnimationImporter()
2280
// free unused FCurves
2281
for (std::vector<FCurve*>::iterator it = unused_curves.begin(); it != unused_curves.end(); it++)
2284
if (unused_curves.size())
2285
fprintf(stderr, "removed %u unused curves\n", unused_curves.size());
2288
bool write_animation(const COLLADAFW::Animation* anim)
2290
if (anim->getAnimationType() == COLLADAFW::Animation::ANIMATION_CURVE) {
2291
COLLADAFW::AnimationCurve *curve = (COLLADAFW::AnimationCurve*)anim;
2293
// XXX Don't know if it's necessary
2294
// Should we check outPhysicalDimension?
2295
if (curve->getInPhysicalDimension() != COLLADAFW::PHYSICAL_DIMENSION_TIME) {
2296
fprintf(stderr, "Inputs physical dimension is not time. \n");
2300
// a curve can have mixed interpolation type,
2301
// in this case curve->getInterpolationTypes returns a list of interpolation types per key
2302
COLLADAFW::AnimationCurve::InterpolationType interp = curve->getInterpolationType();
2304
if (interp != COLLADAFW::AnimationCurve::INTERPOLATION_MIXED) {
2306
case COLLADAFW::AnimationCurve::INTERPOLATION_LINEAR:
2307
case COLLADAFW::AnimationCurve::INTERPOLATION_BEZIER:
2308
animation_to_fcurves(curve);
2311
// TODO there're also CARDINAL, HERMITE, BSPLINE and STEP types
2312
fprintf(stderr, "CARDINAL, HERMITE, BSPLINE and STEP anim interpolation types not supported yet.\n");
2317
// not supported yet
2318
fprintf(stderr, "MIXED anim interpolation type is not supported yet.\n");
2322
fprintf(stderr, "FORMULA animation type is not supported yet.\n");
2328
// called on post-process stage after writeVisualScenes
2329
bool write_animation_list(const COLLADAFW::AnimationList* animlist)
2331
const COLLADAFW::UniqueId& animlist_id = animlist->getUniqueId();
2333
animlist_map[animlist_id] = animlist;
2336
// should not happen
2337
if (uid_animated_map.find(animlist_id) == uid_animated_map.end()) {
2341
// for bones rna_path is like: pose.bones["bone-name"].rotation
2343
// what does this AnimationList animate?
2344
Animation& animated = uid_animated_map[animlist_id];
2345
Object *ob = animated.ob;
2348
char joint_path[100];
2349
bool is_joint = false;
2351
// if ob is NULL, it should be a JOINT
2353
ob = armature_importer->get_armature_for_joint(animated.node);
2356
fprintf(stderr, "Cannot find armature for node %s\n", get_joint_name(animated.node));
2360
armature_importer->get_rna_path_for_joint(animated.node, joint_path, sizeof(joint_path));
2365
const COLLADAFW::AnimationList::AnimationBindings& bindings = animlist->getAnimationBindings();
2367
switch (animated.tm->getTransformationType()) {
2368
case COLLADAFW::Transformation::TRANSLATE:
2369
case COLLADAFW::Transformation::SCALE:
2371
bool loc = animated.tm->getTransformationType() == COLLADAFW::Transformation::TRANSLATE;
2373
BLI_snprintf(rna_path, sizeof(rna_path), "%s.%s", joint_path, loc ? "location" : "scale");
2375
BLI_strncpy(rna_path, loc ? "location" : "scale", sizeof(rna_path));
2377
for (int i = 0; i < bindings.getCount(); i++) {
2378
const COLLADAFW::AnimationList::AnimationBinding& binding = bindings[i];
2379
COLLADAFW::UniqueId anim_uid = binding.animation;
2381
if (curve_map.find(anim_uid) == curve_map.end()) {
2382
fprintf(stderr, "Cannot find FCurve by animation UID.\n");
2386
std::vector<FCurve*>& fcurves = curve_map[anim_uid];
2388
switch (binding.animationClass) {
2389
case COLLADAFW::AnimationList::POSITION_X:
2390
add_fcurves_to_object(ob, fcurves, rna_path, 0, &animated);
2392
case COLLADAFW::AnimationList::POSITION_Y:
2393
add_fcurves_to_object(ob, fcurves, rna_path, 1, &animated);
2395
case COLLADAFW::AnimationList::POSITION_Z:
2396
add_fcurves_to_object(ob, fcurves, rna_path, 2, &animated);
2398
case COLLADAFW::AnimationList::POSITION_XYZ:
2399
add_fcurves_to_object(ob, fcurves, rna_path, -1, &animated);
2402
fprintf(stderr, "AnimationClass %d is not supported for %s.\n",
2403
binding.animationClass, loc ? "TRANSLATE" : "SCALE");
2408
case COLLADAFW::Transformation::ROTATE:
2411
BLI_snprintf(rna_path, sizeof(rna_path), "%s.rotation_euler", joint_path);
2413
BLI_strncpy(rna_path, "rotation_euler", sizeof(rna_path));
2415
COLLADAFW::Rotate* rot = (COLLADAFW::Rotate*)animated.tm;
2416
COLLADABU::Math::Vector3& axis = rot->getRotationAxis();
2418
for (int i = 0; i < bindings.getCount(); i++) {
2419
const COLLADAFW::AnimationList::AnimationBinding& binding = bindings[i];
2420
COLLADAFW::UniqueId anim_uid = binding.animation;
2422
if (curve_map.find(anim_uid) == curve_map.end()) {
2423
fprintf(stderr, "Cannot find FCurve by animation UID.\n");
2427
std::vector<FCurve*>& fcurves = curve_map[anim_uid];
2429
switch (binding.animationClass) {
2430
case COLLADAFW::AnimationList::ANGLE:
2431
if (COLLADABU::Math::Vector3::UNIT_X == axis) {
2432
add_fcurves_to_object(ob, fcurves, rna_path, 0, &animated);
2434
else if (COLLADABU::Math::Vector3::UNIT_Y == axis) {
2435
add_fcurves_to_object(ob, fcurves, rna_path, 1, &animated);
2437
else if (COLLADABU::Math::Vector3::UNIT_Z == axis) {
2438
add_fcurves_to_object(ob, fcurves, rna_path, 2, &animated);
2441
case COLLADAFW::AnimationList::AXISANGLE:
2442
// TODO convert axis-angle to quat? or XYZ?
2444
fprintf(stderr, "AnimationClass %d is not supported for ROTATE transformation.\n",
2445
binding.animationClass);
2450
case COLLADAFW::Transformation::MATRIX:
2451
case COLLADAFW::Transformation::SKEW:
2452
case COLLADAFW::Transformation::LOOKAT:
2453
fprintf(stderr, "Animation of MATRIX, SKEW and LOOKAT transformations is not supported yet.\n");
2461
void read_node_transform(COLLADAFW::Node *node, Object *ob)
2464
TransformReader::get_node_mat(mat, node, &uid_animated_map, ob);
2466
copy_m4_m4(ob->obmat, mat);
2467
object_apply_mat4(ob, ob->obmat);
2472
virtual void change_eul_to_quat(Object *ob, bAction *act)
2477
for (grp = (bActionGroup*)act->groups.first; grp; grp = grp->next) {
2479
FCurve *eulcu[3] = {NULL, NULL, NULL};
2481
if (fcurves_actionGroup_map.find(grp) == fcurves_actionGroup_map.end())
2484
std::vector<FCurve*> &rot_fcurves = fcurves_actionGroup_map[grp];
2486
if (rot_fcurves.size() > 3) continue;
2488
for (i = 0; i < rot_fcurves.size(); i++)
2489
eulcu[rot_fcurves[i]->array_index] = rot_fcurves[i];
2491
char joint_path[100];
2494
BLI_snprintf(joint_path, sizeof(joint_path), "pose.bones[\"%s\"]", grp->name);
2495
BLI_snprintf(rna_path, sizeof(rna_path), "%s.rotation_quaternion", joint_path);
2497
FCurve *quatcu[4] = {
2498
create_fcurve(0, rna_path),
2499
create_fcurve(1, rna_path),
2500
create_fcurve(2, rna_path),
2501
create_fcurve(3, rna_path)
2504
bPoseChannel *chan = get_pose_channel(ob->pose, grp->name);
2506
float m4[4][4], irest[3][3];
2507
invert_m4_m4(m4, chan->bone->arm_mat);
2508
copy_m3_m4(irest, m4);
2510
for (i = 0; i < 3; i++) {
2512
FCurve *cu = eulcu[i];
2516
for (int j = 0; j < cu->totvert; j++) {
2517
float frame = cu->bezt[j].vec[1][0];
2520
eulcu[0] ? evaluate_fcurve(eulcu[0], frame) : 0.0f,
2521
eulcu[1] ? evaluate_fcurve(eulcu[1], frame) : 0.0f,
2522
eulcu[2] ? evaluate_fcurve(eulcu[2], frame) : 0.0f
2525
// make eul relative to bone rest pose
2526
float rot[3][3], rel[3][3], quat[4];
2528
/*eul_to_mat3(rot, eul);
2530
mul_m3_m3m3(rel, irest, rot);
2532
mat3_to_quat(quat, rel);
2535
eul_to_quat(quat, eul);
2537
for (int k = 0; k < 4; k++)
2538
create_bezt(quatcu[k], frame, quat[k]);
2542
// now replace old Euler curves
2544
for (i = 0; i < 3; i++) {
2545
if (!eulcu[i]) continue;
2547
action_groups_remove_channel(act, eulcu[i]);
2548
free_fcurve(eulcu[i]);
2551
chan->rotmode = ROT_MODE_QUAT;
2553
for (i = 0; i < 4; i++)
2554
action_groups_add_channel(act, grp, quatcu[i]);
2557
bPoseChannel *pchan;
2558
for (pchan = (bPoseChannel*)ob->pose->chanbase.first; pchan; pchan = pchan->next) {
2559
pchan->rotmode = ROT_MODE_QUAT;
2565
// animlist_map - map animlist id -> animlist
2566
// curve_map - map anim id -> curve(s)
2567
Object *translate_animation(COLLADAFW::Node *node,
2568
std::map<COLLADAFW::UniqueId, Object*>& object_map,
2569
std::map<COLLADAFW::UniqueId, COLLADAFW::Node*>& root_map,
2570
COLLADAFW::Transformation::TransformationType tm_type,
2571
Object *par_job = NULL)
2573
bool is_rotation = tm_type == COLLADAFW::Transformation::ROTATE;
2574
bool is_matrix = tm_type == COLLADAFW::Transformation::MATRIX;
2575
bool is_joint = node->getType() == COLLADAFW::Node::JOINT;
2577
COLLADAFW::Node *root = root_map.find(node->getUniqueId()) == root_map.end() ? node : root_map[node->getUniqueId()];
2578
Object *ob = is_joint ? armature_importer->get_armature_for_joint(node) : object_map[node->getUniqueId()];
2579
const char *bone_name = is_joint ? get_joint_name(node) : NULL;
2582
fprintf(stderr, "cannot find Object for Node with id=\"%s\"\n", node->getOriginalId().c_str());
2586
// frames at which to sample
2587
std::vector<float> frames;
2589
// for each <rotate>, <translate>, etc. there is a separate Transformation
2590
const COLLADAFW::TransformationPointerArray& tms = node->getTransformations();
2594
// find frames at which to sample plus convert all rotation keys to radians
2595
for (i = 0; i < tms.getCount(); i++) {
2596
COLLADAFW::Transformation *tm = tms[i];
2597
COLLADAFW::Transformation::TransformationType type = tm->getTransformationType();
2599
if (type == tm_type) {
2600
const COLLADAFW::UniqueId& listid = tm->getAnimationList();
2602
if (animlist_map.find(listid) != animlist_map.end()) {
2603
const COLLADAFW::AnimationList *animlist = animlist_map[listid];
2604
const COLLADAFW::AnimationList::AnimationBindings& bindings = animlist->getAnimationBindings();
2606
if (bindings.getCount()) {
2607
for (unsigned int j = 0; j < bindings.getCount(); j++) {
2608
std::vector<FCurve*>& curves = curve_map[bindings[j].animation];
2609
bool xyz = ((type == COLLADAFW::Transformation::TRANSLATE || type == COLLADAFW::Transformation::SCALE) && bindings[j].animationClass == COLLADAFW::AnimationList::POSITION_XYZ);
2611
if ((!xyz && curves.size() == 1) || (xyz && curves.size() == 3) || is_matrix) {
2612
std::vector<FCurve*>::iterator iter;
2614
for (iter = curves.begin(); iter != curves.end(); iter++) {
2615
FCurve *fcu = *iter;
2618
fcurve_deg_to_rad(fcu);
2620
for (unsigned int k = 0; k < fcu->totvert; k++) {
2621
float fra = fcu->bezt[k].vec[1][0];
2622
if (std::find(frames.begin(), frames.end(), fra) == frames.end())
2623
frames.push_back(fra);
2628
fprintf(stderr, "expected %d curves, got %u\n", xyz ? 3 : 1, curves.size());
2636
float irest_dae[4][4];
2637
float rest[4][4], irest[4][4];
2640
get_joint_rest_mat(irest_dae, root, node);
2641
invert_m4(irest_dae);
2643
Bone *bone = get_named_bone((bArmature*)ob->data, bone_name);
2645
fprintf(stderr, "cannot find bone \"%s\"\n", bone_name);
2650
copy_m4_m4(rest, bone->arm_mat);
2651
invert_m4_m4(irest, rest);
2656
#ifdef ARMATURE_TEST
2657
FCurve *job_curves[10];
2658
job = get_joint_object(root, node, par_job);
2661
if (frames.size() == 0)
2664
std::sort(frames.begin(), frames.end());
2666
const char *tm_str = NULL;
2668
case COLLADAFW::Transformation::ROTATE:
2669
tm_str = "rotation_quaternion";
2671
case COLLADAFW::Transformation::SCALE:
2674
case COLLADAFW::Transformation::TRANSLATE:
2675
tm_str = "location";
2677
case COLLADAFW::Transformation::MATRIX:
2684
char joint_path[200];
2687
armature_importer->get_rna_path_for_joint(node, joint_path, sizeof(joint_path));
2690
FCurve *newcu[10]; // if tm_type is matrix, then create 10 curves: 4 rot, 3 loc, 3 scale
2691
unsigned int totcu = is_matrix ? 10 : (is_rotation ? 4 : 3);
2693
for (i = 0; i < totcu; i++) {
2699
tm_str = "rotation_quaternion";
2703
tm_str = "location";
2713
BLI_snprintf(rna_path, sizeof(rna_path), "%s.%s", joint_path, tm_str);
2715
strcpy(rna_path, tm_str);
2717
newcu[i] = create_fcurve(axis, rna_path);
2719
#ifdef ARMATURE_TEST
2721
job_curves[i] = create_fcurve(axis, tm_str);
2725
std::vector<float>::iterator it;
2727
// sample values at each frame
2728
for (it = frames.begin(); it != frames.end(); it++) {
262
root_map[node->getUniqueId()] = root_map[par->getUniqueId()];
265
/*COLLADAFW::Transformation::TransformationType types[] = {
266
COLLADAFW::Transformation::ROTATE,
267
COLLADAFW::Transformation::SCALE,
268
COLLADAFW::Transformation::TRANSLATE,
269
COLLADAFW::Transformation::MATRIX
275
//for (i = 0; i < 4; i++)
277
anim_importer.translate_Animations(node, root_map, object_map, FW_object_map);
279
COLLADAFW::NodePointerArray &children = node->getChildNodes();
280
for (i = 0; i < children.getCount(); i++) {
281
translate_anim_recursive(children[i], node, NULL);
285
/** When this method is called, the writer must write the global document asset.
286
\return The writer should return true, if writing succeeded, false otherwise.*/
287
bool DocumentImporter::writeGlobalAsset ( const COLLADAFW::FileInfo* asset )
289
unit_converter.read_asset(asset);
294
/** When this method is called, the writer must write the scene.
295
\return The writer should return true, if writing succeeded, false otherwise.*/
296
bool DocumentImporter::writeScene ( const COLLADAFW::Scene* scene )
298
// XXX could store the scene id, but do nothing for now
301
Object* DocumentImporter::create_camera_object(COLLADAFW::InstanceCamera *camera, Scene *sce)
303
const COLLADAFW::UniqueId& cam_uid = camera->getInstanciatedObjectId();
304
if (uid_camera_map.find(cam_uid) == uid_camera_map.end()) {
305
fprintf(stderr, "Couldn't find camera by UID.\n");
309
Object *ob = bc_add_object(sce, OB_CAMERA, NULL);
310
Camera *cam = uid_camera_map[cam_uid];
311
Camera *old_cam = (Camera*)ob->data;
314
if (old_cam->id.us == 0)
315
free_libblock(&G.main->camera, old_cam);
319
Object* DocumentImporter::create_lamp_object(COLLADAFW::InstanceLight *lamp, Scene *sce)
321
const COLLADAFW::UniqueId& lamp_uid = lamp->getInstanciatedObjectId();
322
if (uid_lamp_map.find(lamp_uid) == uid_lamp_map.end()) {
323
fprintf(stderr, "Couldn't find lamp by UID.\n");
327
Object *ob = bc_add_object(sce, OB_LAMP, NULL);
328
Lamp *la = uid_lamp_map[lamp_uid];
329
Lamp *old_lamp = (Lamp*)ob->data;
332
if (old_lamp->id.us == 0)
333
free_libblock(&G.main->lamp, old_lamp);
337
Object* DocumentImporter::create_instance_node(Object *source_ob, COLLADAFW::Node *source_node, COLLADAFW::Node *instance_node, Scene *sce, bool is_library_node)
339
fprintf(stderr, "create <instance_node> under node id=%s from node id=%s\n", instance_node ? instance_node->getOriginalId().c_str() : NULL, source_node ? source_node->getOriginalId().c_str() : NULL);
341
Object *obn = copy_object(source_ob);
342
obn->recalc |= OB_RECALC_OB|OB_RECALC_DATA|OB_RECALC_TIME;
343
scene_add_base(sce, obn);
346
anim_importer.read_node_transform(instance_node, obn);
347
// if we also have a source_node (always ;), take its
348
// transformation matrix and apply it to the newly instantiated
349
// object to account for node hierarchy transforms in
352
COLLADABU::Math::Matrix4 mat4 = source_node->getTransformationMatrix();
353
COLLADABU::Math::Matrix4 bmat4 = mat4.transpose(); // transpose to get blender row-major order
2731
354
float mat[4][4];
2736
// calc object-space mat
2737
evaluate_transform_at_frame(matfra, node, fra);
2739
// for joints, we need a special matrix
2741
// special matrix: iR * M * iR_dae * R
2742
// where R, iR are bone rest and inverse rest mats in world space (Blender bones),
2743
// iR_dae is joint inverse rest matrix (DAE) and M is an evaluated joint world-space matrix (DAE)
2744
float temp[4][4], par[4][4];
2747
calc_joint_parent_mat_rest(par, NULL, root, node);
2748
mul_m4_m4m4(temp, matfra, par);
2750
// evaluate_joint_world_transform_at_frame(temp, NULL, , node, fra);
2752
// calc special matrix
2753
mul_serie_m4(mat, irest, temp, irest_dae, rest, NULL, NULL, NULL, NULL);
2756
copy_m4_m4(mat, matfra);
2759
float val[4], rot[4], loc[3], scale[3];
2762
case COLLADAFW::Transformation::ROTATE:
2763
mat4_to_quat(val, mat);
2765
case COLLADAFW::Transformation::SCALE:
2766
mat4_to_size(val, mat);
2768
case COLLADAFW::Transformation::TRANSLATE:
2769
copy_v3_v3(val, mat[3]);
2771
case COLLADAFW::Transformation::MATRIX:
2772
mat4_to_quat(rot, mat);
2773
copy_v3_v3(loc, mat[3]);
2774
mat4_to_size(scale, mat);
2781
for (i = 0; i < totcu; i++) {
2784
add_bezt(newcu[i], fra, rot[i]);
2786
add_bezt(newcu[i], fra, loc[i - 4]);
2788
add_bezt(newcu[i], fra, scale[i - 7]);
2791
add_bezt(newcu[i], fra, val[i]);
2795
#ifdef ARMATURE_TEST
2798
case COLLADAFW::Transformation::ROTATE:
2799
mat4_to_quat(val, matfra);
2801
case COLLADAFW::Transformation::SCALE:
2802
mat4_to_size(val, matfra);
2804
case COLLADAFW::Transformation::TRANSLATE:
2805
copy_v3_v3(val, matfra[3]);
2808
mat4_to_quat(rot, matfra);
2809
copy_v3_v3(loc, matfra[3]);
2810
mat4_to_size(scale, matfra);
2816
for (i = 0; i < totcu; i++) {
2819
add_bezt(job_curves[i], fra, rot[i]);
2821
add_bezt(job_curves[i], fra, loc[i - 4]);
2823
add_bezt(job_curves[i], fra, scale[i - 7]);
2826
add_bezt(job_curves[i], fra, val[i]);
2833
verify_adt_action((ID*)&ob->id, 1);
2835
ListBase *curves = &ob->adt->action->curves;
2838
for (i = 0; i < totcu; i++) {
2840
add_bone_fcurve(ob, node, newcu[i]);
2842
BLI_addtail(curves, newcu[i]);
2844
#ifdef ARMATURE_TEST
2846
BLI_addtail(&job->adt->action->curves, job_curves[i]);
2850
if (is_rotation || is_matrix) {
2852
bPoseChannel *chan = get_pose_channel(ob->pose, bone_name);
2853
chan->rotmode = ROT_MODE_QUAT;
2856
ob->rotmode = ROT_MODE_QUAT;
2863
// internal, better make it private
2864
// warning: evaluates only rotation
2865
// prerequisites: animlist_map, curve_map
2866
void evaluate_transform_at_frame(float mat[4][4], COLLADAFW::Node *node, float fra)
2868
const COLLADAFW::TransformationPointerArray& tms = node->getTransformations();
2872
for (unsigned int i = 0; i < tms.getCount(); i++) {
2873
COLLADAFW::Transformation *tm = tms[i];
2874
COLLADAFW::Transformation::TransformationType type = tm->getTransformationType();
2879
if (!evaluate_animation(tm, m, fra, node->getOriginalId().c_str())) {
2881
case COLLADAFW::Transformation::ROTATE:
2882
dae_rotate_to_mat4(tm, m);
2884
case COLLADAFW::Transformation::TRANSLATE:
2885
dae_translate_to_mat4(tm, m);
2887
case COLLADAFW::Transformation::SCALE:
2888
dae_scale_to_mat4(tm, m);
2890
case COLLADAFW::Transformation::MATRIX:
2891
dae_matrix_to_mat4(tm, m);
2894
fprintf(stderr, "unsupported transformation type %d\n", type);
2899
copy_m4_m4(temp, mat);
2901
mul_m4_m4m4(mat, m, temp);
2905
// return true to indicate that mat contains a sane value
2906
bool evaluate_animation(COLLADAFW::Transformation *tm, float mat[4][4], float fra, const char *node_id)
2908
const COLLADAFW::UniqueId& listid = tm->getAnimationList();
2909
COLLADAFW::Transformation::TransformationType type = tm->getTransformationType();
2911
if (type != COLLADAFW::Transformation::ROTATE &&
2912
type != COLLADAFW::Transformation::SCALE &&
2913
type != COLLADAFW::Transformation::TRANSLATE &&
2914
type != COLLADAFW::Transformation::MATRIX) {
2915
fprintf(stderr, "animation of transformation %d is not supported yet\n", type);
2919
if (animlist_map.find(listid) == animlist_map.end())
2922
const COLLADAFW::AnimationList *animlist = animlist_map[listid];
2923
const COLLADAFW::AnimationList::AnimationBindings& bindings = animlist->getAnimationBindings();
2925
if (bindings.getCount()) {
2928
bool is_scale = (type == COLLADAFW::Transformation::SCALE);
2929
bool is_translate = (type == COLLADAFW::Transformation::TRANSLATE);
2931
if (type == COLLADAFW::Transformation::SCALE)
2932
dae_scale_to_v3(tm, vec);
2933
else if (type == COLLADAFW::Transformation::TRANSLATE)
2934
dae_translate_to_v3(tm, vec);
2936
for (unsigned int j = 0; j < bindings.getCount(); j++) {
2937
const COLLADAFW::AnimationList::AnimationBinding& binding = bindings[j];
2938
std::vector<FCurve*>& curves = curve_map[binding.animation];
2939
COLLADAFW::AnimationList::AnimationClass animclass = binding.animationClass;
2943
case COLLADAFW::Transformation::ROTATE:
2944
BLI_snprintf(path, sizeof(path), "%s.rotate (binding %u)", node_id, j);
2946
case COLLADAFW::Transformation::SCALE:
2947
BLI_snprintf(path, sizeof(path), "%s.scale (binding %u)", node_id, j);
2949
case COLLADAFW::Transformation::TRANSLATE:
2950
BLI_snprintf(path, sizeof(path), "%s.translate (binding %u)", node_id, j);
2952
case COLLADAFW::Transformation::MATRIX:
2953
BLI_snprintf(path, sizeof(path), "%s.matrix (binding %u)", node_id, j);
2959
if (animclass == COLLADAFW::AnimationList::UNKNOWN_CLASS) {
2960
fprintf(stderr, "%s: UNKNOWN animation class\n", path);
2964
if (type == COLLADAFW::Transformation::ROTATE) {
2965
if (curves.size() != 1) {
2966
fprintf(stderr, "expected 1 curve, got %u\n", curves.size());
2970
// TODO support other animclasses
2971
if (animclass != COLLADAFW::AnimationList::ANGLE) {
2972
fprintf(stderr, "%s: animation class %d is not supported yet\n", path, animclass);
2976
COLLADABU::Math::Vector3& axis = ((COLLADAFW::Rotate*)tm)->getRotationAxis();
2977
float ax[3] = {axis[0], axis[1], axis[2]};
2978
float angle = evaluate_fcurve(curves[0], fra);
2979
axis_angle_to_mat4(mat, ax, angle);
2983
else if (is_scale || is_translate) {
2984
bool is_xyz = animclass == COLLADAFW::AnimationList::POSITION_XYZ;
2986
if ((!is_xyz && curves.size() != 1) || (is_xyz && curves.size() != 3)) {
2988
fprintf(stderr, "%s: expected 3 curves, got %u\n", path, curves.size());
2990
fprintf(stderr, "%s: expected 1 curve, got %u\n", path, curves.size());
2994
switch (animclass) {
2995
case COLLADAFW::AnimationList::POSITION_X:
2996
vec[0] = evaluate_fcurve(curves[0], fra);
2998
case COLLADAFW::AnimationList::POSITION_Y:
2999
vec[1] = evaluate_fcurve(curves[0], fra);
3001
case COLLADAFW::AnimationList::POSITION_Z:
3002
vec[2] = evaluate_fcurve(curves[0], fra);
3004
case COLLADAFW::AnimationList::POSITION_XYZ:
3005
vec[0] = evaluate_fcurve(curves[0], fra);
3006
vec[1] = evaluate_fcurve(curves[1], fra);
3007
vec[2] = evaluate_fcurve(curves[2], fra);
3010
fprintf(stderr, "%s: animation class %d is not supported yet\n", path, animclass);
3014
else if (type == COLLADAFW::Transformation::MATRIX) {
3015
// for now, of matrix animation, support only the case when all values are packed into one animation
3016
if (curves.size() != 16) {
3017
fprintf(stderr, "%s: expected 16 curves, got %u\n", path, curves.size());
3021
COLLADABU::Math::Matrix4 matrix;
3024
for (std::vector<FCurve*>::iterator it = curves.begin(); it != curves.end(); it++) {
3025
matrix.setElement(i, j, evaluate_fcurve(*it, fra));
3033
COLLADAFW::Matrix tm(matrix);
3034
dae_matrix_to_mat4(&tm, mat);
3041
size_to_mat4(mat, vec);
3043
copy_v3_v3(mat[3], vec);
3045
return is_scale || is_translate;
3051
// gives a world-space mat of joint at rest position
3052
void get_joint_rest_mat(float mat[4][4], COLLADAFW::Node *root, COLLADAFW::Node *node)
3054
// if bind mat is not available,
3055
// use "current" node transform, i.e. all those tms listed inside <node>
3056
if (!armature_importer->get_joint_bind_mat(mat, node)) {
3057
float par[4][4], m[4][4];
3059
calc_joint_parent_mat_rest(par, NULL, root, node);
3060
get_node_mat(m, node, NULL, NULL);
3061
mul_m4_m4m4(mat, m, par);
3065
// gives a world-space mat, end's mat not included
3066
bool calc_joint_parent_mat_rest(float mat[4][4], float par[4][4], COLLADAFW::Node *node, COLLADAFW::Node *end)
3071
par ? copy_m4_m4(mat, par) : unit_m4(mat);
3075
// use bind matrix if available or calc "current" world mat
3076
if (!armature_importer->get_joint_bind_mat(m, node)) {
3079
get_node_mat(temp, node, NULL, NULL);
3080
mul_m4_m4m4(m, temp, par);
3083
get_node_mat(m, node, NULL, NULL);
3087
COLLADAFW::NodePointerArray& children = node->getChildNodes();
355
for (int i = 0; i < 4; i++) {
356
for (int j = 0; j < 4; j++) {
357
mat[i][j] = bmat4[i][j];
360
// calc new matrix and apply
361
mult_m4_m4m4(obn->obmat, obn->obmat, mat);
362
object_apply_mat4(obn, obn->obmat, 0, 0);
366
anim_importer.read_node_transform(source_node, obn);
369
DAG_scene_sort(CTX_data_main(mContext), sce);
370
DAG_ids_flush_update(CTX_data_main(mContext), 0);
372
COLLADAFW::NodePointerArray &children = source_node->getChildNodes();
373
if (children.getCount()) {
3088
374
for (unsigned int i = 0; i < children.getCount(); i++) {
3089
if (calc_joint_parent_mat_rest(mat, m, children[i], end))
3096
#ifdef ARMATURE_TEST
3097
Object *get_joint_object(COLLADAFW::Node *root, COLLADAFW::Node *node, Object *par_job)
3099
if (joint_objects.find(node->getUniqueId()) == joint_objects.end()) {
3100
Object *job = add_object(scene, OB_EMPTY);
3102
rename_id((ID*)&job->id, (char*)get_joint_name(node));
3104
job->lay = object_in_scene(job, scene)->lay = 2;
3106
mul_v3_fl(job->size, 0.5f);
3107
job->recalc |= OB_RECALC_OB;
3109
verify_adt_action((ID*)&job->id, 1);
3111
job->rotmode = ROT_MODE_QUAT;
3114
get_joint_rest_mat(mat, root, node);
3117
float temp[4][4], ipar[4][4];
3118
invert_m4_m4(ipar, par_job->obmat);
3119
copy_m4_m4(temp, mat);
3120
mul_m4_m4m4(mat, temp, ipar);
3123
TransformBase::decompose(mat, job->loc, NULL, job->quat, job->size);
3126
job->parent = par_job;
3128
par_job->recalc |= OB_RECALC_OB;
3129
job->parsubstr[0] = 0;
3132
where_is_object(scene, job);
3134
// after parenting and layer change
3135
DAG_scene_sort(scene);
3137
joint_objects[node->getUniqueId()] = job;
3140
return joint_objects[node->getUniqueId()];
3145
// recursively evaluates joint tree until end is found, mat then is world-space matrix of end
3146
// mat must be identity on enter, node must be root
3147
bool evaluate_joint_world_transform_at_frame(float mat[4][4], float par[4][4], COLLADAFW::Node *node, COLLADAFW::Node *end, float fra)
3152
evaluate_transform_at_frame(temp, node, node == end ? fra : 0.0f);
3153
mul_m4_m4m4(m, temp, par);
3156
evaluate_transform_at_frame(m, node, node == end ? fra : 0.0f);
3164
COLLADAFW::NodePointerArray& children = node->getChildNodes();
3165
for (int i = 0; i < children.getCount(); i++) {
3166
if (evaluate_joint_world_transform_at_frame(mat, m, children[i], end, fra))
3175
void add_bone_fcurve(Object *ob, COLLADAFW::Node *node, FCurve *fcu)
3177
const char *bone_name = get_joint_name(node);
3178
bAction *act = ob->adt->action;
3180
/* try to find group */
3181
bActionGroup *grp = action_groups_find_named(act, bone_name);
3183
/* no matching groups, so add one */
3185
/* Add a new group, and make it active */
3186
grp = (bActionGroup*)MEM_callocN(sizeof(bActionGroup), "bActionGroup");
3188
grp->flag = AGRP_SELECTED;
3189
BLI_strncpy(grp->name, bone_name, sizeof(grp->name));
3191
BLI_addtail(&act->groups, grp);
3192
BLI_uniquename(&act->groups, grp, "Group", '.', offsetof(bActionGroup, name), 64);
3195
/* add F-Curve to group */
3196
action_groups_add_channel(act, grp, fcu);
3199
void add_bezt(FCurve *fcu, float fra, float value)
3202
memset(&bez, 0, sizeof(BezTriple));
3203
bez.vec[1][0] = fra;
3204
bez.vec[1][1] = value;
3205
bez.ipo = U.ipo_new; /* use default interpolation mode here... */
3206
bez.f1 = bez.f2 = bez.f3 = SELECT;
3207
bez.h1 = bez.h2 = HD_AUTO;
3208
insert_bezt_fcurve(fcu, &bez, 0);
3209
calchandles_fcurve(fcu);
3215
COLLADA Importer limitations:
3217
- no multiple scene import, all objects are added to active scene
3220
/** Class that needs to be implemented by a writer.
3221
IMPORTANT: The write functions are called in arbitrary order.*/
3222
class Writer: public COLLADAFW::IWriter
3225
std::string mFilename;
3229
UnitConverter unit_converter;
3230
ArmatureImporter armature_importer;
3231
MeshImporter mesh_importer;
3232
AnimationImporter anim_importer;
3234
std::map<COLLADAFW::UniqueId, Image*> uid_image_map;
3235
std::map<COLLADAFW::UniqueId, Material*> uid_material_map;
3236
std::map<COLLADAFW::UniqueId, Material*> uid_effect_map;
3237
std::map<COLLADAFW::UniqueId, Camera*> uid_camera_map;
3238
std::map<COLLADAFW::UniqueId, Lamp*> uid_lamp_map;
3239
std::map<Material*, TexIndexTextureArrayMap> material_texture_mapping_map;
3240
std::map<COLLADAFW::UniqueId, Object*> object_map;
3241
std::vector<const COLLADAFW::VisualScene*> vscenes;
3243
std::map<COLLADAFW::UniqueId, COLLADAFW::Node*> root_map; // find root joint by child joint uid, for bone tree evaluation during resampling
3246
// std::map<COLLADAFW::UniqueId, std::vector<FCurve*> > uid_fcurve_map;
3247
// Nodes don't share AnimationLists (Arystan)
3248
// std::map<COLLADAFW::UniqueId, Animation> uid_animated_map; // AnimationList->uniqueId to AnimatedObject map
3253
Writer(bContext *C, const char *filename) : mFilename(filename), mContext(C),
3254
armature_importer(&unit_converter, &mesh_importer, &anim_importer, CTX_data_scene(C)),
3255
mesh_importer(&armature_importer, CTX_data_scene(C)),
3256
anim_importer(&unit_converter, &armature_importer, CTX_data_scene(C)) {}
3263
COLLADASaxFWL::Loader loader;
3264
COLLADAFW::Root root(&loader, this);
3267
if (!root.loadDocument(mFilename))
3273
/** This method will be called if an error in the loading process occurred and the loader cannot
3274
continue to load. The writer should undo all operations that have been performed.
3275
@param errorMessage A message containing informations about the error that occurred.
3277
virtual void cancel(const COLLADAFW::String& errorMessage)
3279
// TODO: if possible show error info
3281
// Should we get rid of invisible Meshes that were created so far
3282
// or maybe create objects at coordinate space origin?
3284
// The latter sounds better.
3287
/** This is the method called. The writer hast to prepare to receive data.*/
3288
virtual void start()
3292
/** This method is called after the last write* method. No other methods will be called after this.*/
3293
virtual void finish()
3296
armature_importer.fix_animation();
3299
for (std::vector<const COLLADAFW::VisualScene*>::iterator it = vscenes.begin(); it != vscenes.end(); it++) {
3300
const COLLADAFW::NodePointerArray& roots = (*it)->getRootNodes();
3302
for (unsigned int i = 0; i < roots.getCount(); i++)
3303
translate_anim_recursive(roots[i]);
3309
void translate_anim_recursive(COLLADAFW::Node *node, COLLADAFW::Node *par = NULL, Object *parob = NULL)
3311
if (par && par->getType() == COLLADAFW::Node::JOINT) {
3312
// par is root if there's no corresp. key in root_map
3313
if (root_map.find(par->getUniqueId()) == root_map.end())
3314
root_map[node->getUniqueId()] = par;
3316
root_map[node->getUniqueId()] = root_map[par->getUniqueId()];
3319
COLLADAFW::Transformation::TransformationType types[] = {
3320
COLLADAFW::Transformation::ROTATE,
3321
COLLADAFW::Transformation::SCALE,
3322
COLLADAFW::Transformation::TRANSLATE,
3323
COLLADAFW::Transformation::MATRIX
3329
for (i = 0; i < 4; i++)
3330
ob = anim_importer.translate_animation(node, object_map, root_map, types[i]);
3332
COLLADAFW::NodePointerArray &children = node->getChildNodes();
3333
for (i = 0; i < children.getCount(); i++) {
3334
translate_anim_recursive(children[i], node, ob);
3338
/** When this method is called, the writer must write the global document asset.
3339
@return The writer should return true, if writing succeeded, false otherwise.*/
3340
virtual bool writeGlobalAsset ( const COLLADAFW::FileInfo* asset )
3342
// XXX take up_axis, unit into account
3343
// COLLADAFW::FileInfo::Unit unit = asset->getUnit();
3344
// COLLADAFW::FileInfo::UpAxisType upAxis = asset->getUpAxisType();
3345
unit_converter.read_asset(asset);
3350
/** When this method is called, the writer must write the scene.
3351
@return The writer should return true, if writing succeeded, false otherwise.*/
3352
virtual bool writeScene ( const COLLADAFW::Scene* scene )
3354
// XXX could store the scene id, but do nothing for now
3357
Object *create_camera_object(COLLADAFW::InstanceCamera *camera, Object *ob, Scene *sce)
3359
const COLLADAFW::UniqueId& cam_uid = camera->getInstanciatedObjectId();
3360
if (uid_camera_map.find(cam_uid) == uid_camera_map.end()) {
3361
fprintf(stderr, "Couldn't find camera by UID. \n");
3364
ob = add_object(sce, OB_CAMERA);
3365
Camera *cam = uid_camera_map[cam_uid];
3366
Camera *old_cam = (Camera*)ob->data;
3369
if (old_cam->id.us == 0) free_libblock(&G.main->camera, old_cam);
3373
Object *create_lamp_object(COLLADAFW::InstanceLight *lamp, Object *ob, Scene *sce)
3375
const COLLADAFW::UniqueId& lamp_uid = lamp->getInstanciatedObjectId();
3376
if (uid_lamp_map.find(lamp_uid) == uid_lamp_map.end()) {
3377
fprintf(stderr, "Couldn't find lamp by UID. \n");
3380
ob = add_object(sce, OB_LAMP);
3381
Lamp *la = uid_lamp_map[lamp_uid];
3382
Lamp *old_lamp = (Lamp*)ob->data;
3385
if (old_lamp->id.us == 0) free_libblock(&G.main->lamp, old_lamp);
3389
void write_node (COLLADAFW::Node *node, COLLADAFW::Node *parent_node, Scene *sce, Object *par)
3392
bool is_joint = node->getType() == COLLADAFW::Node::JOINT;
3395
armature_importer.add_joint(node, parent_node == NULL || parent_node->getType() != COLLADAFW::Node::JOINT, par);
3398
COLLADAFW::InstanceGeometryPointerArray &geom = node->getInstanceGeometries();
3399
COLLADAFW::InstanceCameraPointerArray &camera = node->getInstanceCameras();
3400
COLLADAFW::InstanceLightPointerArray &lamp = node->getInstanceLights();
3401
COLLADAFW::InstanceControllerPointerArray &controller = node->getInstanceControllers();
3402
COLLADAFW::InstanceNodePointerArray &inst_node = node->getInstanceNodes();
3404
// XXX linking object with the first <instance_geometry>, though a node may have more of them...
3405
// maybe join multiple <instance_...> meshes into 1, and link object with it? not sure...
3406
// <instance_geometry>
3407
if (geom.getCount() != 0) {
3408
ob = mesh_importer.create_mesh_object(node, geom[0], false, uid_material_map,
3409
material_texture_mapping_map);
3411
else if (camera.getCount() != 0) {
3412
ob = create_camera_object(camera[0], ob, sce);
3414
else if (lamp.getCount() != 0) {
3415
ob = create_lamp_object(lamp[0], ob, sce);
3417
else if (controller.getCount() != 0) {
3418
COLLADAFW::InstanceGeometry *geom = (COLLADAFW::InstanceGeometry*)controller[0];
3419
ob = mesh_importer.create_mesh_object(node, geom, true, uid_material_map, material_texture_mapping_map);
3421
// XXX instance_node is not supported yet
3422
else if (inst_node.getCount() != 0) {
3425
// if node is empty - create empty object
3426
// XXX empty node may not mean it is empty object, not sure about this
3428
ob = add_object(sce, OB_EMPTY);
3429
rename_id(&ob->id, (char*)node->getOriginalId().c_str());
3432
// check if object is not NULL
3435
object_map[node->getUniqueId()] = ob;
3438
anim_importer.read_node_transform(node, ob);
3441
// if par was given make this object child of the previous
3443
set_parent(ob, par, mContext);
3446
// if node has child nodes write them
3447
COLLADAFW::NodePointerArray &child_nodes = node->getChildNodes();
3448
for (unsigned int i = 0; i < child_nodes.getCount(); i++) {
3449
write_node(child_nodes[i], node, sce, ob);
3453
/** When this method is called, the writer must write the entire visual scene.
3454
@return The writer should return true, if writing succeeded, false otherwise.*/
3455
virtual bool writeVisualScene ( const COLLADAFW::VisualScene* visualScene )
3457
// this method called on post process after writeGeometry, writeMaterial, etc.
3459
// for each <node> in <visual_scene>:
3461
// if Mesh (previously created in writeGeometry) to which <node> corresponds exists, link Object with that mesh
3463
// update: since we cannot link a Mesh with Object in
3464
// writeGeometry because <geometry> does not reference <node>,
3465
// we link Objects with Meshes here
3467
vscenes.push_back(visualScene);
3469
// TODO: create a new scene except the selected <visual_scene> - use current blender
3471
Scene *sce = CTX_data_scene(mContext);
3472
const COLLADAFW::NodePointerArray& roots = visualScene->getRootNodes();
3474
for (unsigned int i = 0; i < roots.getCount(); i++) {
3475
write_node(roots[i], NULL, sce, NULL);
3478
armature_importer.make_armatures(mContext);
3483
/** When this method is called, the writer must handle all nodes contained in the
3485
@return The writer should return true, if writing succeeded, false otherwise.*/
3486
virtual bool writeLibraryNodes ( const COLLADAFW::LibraryNodes* libraryNodes )
3491
/** When this method is called, the writer must write the geometry.
3492
@return The writer should return true, if writing succeeded, false otherwise.*/
3493
virtual bool writeGeometry ( const COLLADAFW::Geometry* geom )
3495
return mesh_importer.write_geometry(geom);
3498
/** When this method is called, the writer must write the material.
3499
@return The writer should return true, if writing succeeded, false otherwise.*/
3500
virtual bool writeMaterial( const COLLADAFW::Material* cmat )
3502
const std::string& str_mat_id = cmat->getOriginalId();
3503
Material *ma = add_material((char*)str_mat_id.c_str());
3505
this->uid_effect_map[cmat->getInstantiatedEffect()] = ma;
3506
this->uid_material_map[cmat->getUniqueId()] = ma;
3511
// create mtex, create texture, set texture image
3512
MTex *create_texture(COLLADAFW::EffectCommon *ef, COLLADAFW::Texture &ctex, Material *ma,
3513
int i, TexIndexTextureArrayMap &texindex_texarray_map)
3515
COLLADAFW::SamplerPointerArray& samp_array = ef->getSamplerPointerArray();
3516
COLLADAFW::Sampler *sampler = samp_array[ctex.getSamplerId()];
3518
const COLLADAFW::UniqueId& ima_uid = sampler->getSourceImage();
3520
if (uid_image_map.find(ima_uid) == uid_image_map.end()) {
3521
fprintf(stderr, "Couldn't find an image by UID.\n");
3525
ma->mtex[i] = add_mtex();
3526
ma->mtex[i]->texco = TEXCO_UV;
3527
ma->mtex[i]->tex = add_texture("Texture");
3528
ma->mtex[i]->tex->type = TEX_IMAGE;
3529
ma->mtex[i]->tex->imaflag &= ~TEX_USEALPHA;
3530
ma->mtex[i]->tex->ima = uid_image_map[ima_uid];
3532
texindex_texarray_map[ctex.getTextureMapId()].push_back(ma->mtex[i]);
3537
void write_profile_COMMON(COLLADAFW::EffectCommon *ef, Material *ma)
3539
COLLADAFW::EffectCommon::ShaderType shader = ef->getShaderType();
3542
if (shader == COLLADAFW::EffectCommon::SHADER_BLINN) {
3543
ma->spec_shader = MA_SPEC_BLINN;
3544
ma->spec = ef->getShininess().getFloatValue();
3547
else if (shader == COLLADAFW::EffectCommon::SHADER_PHONG) {
3548
ma->spec_shader = MA_SPEC_PHONG;
3549
// XXX setting specular hardness instead of specularity intensity
3550
ma->har = ef->getShininess().getFloatValue() * 4;
3553
else if (shader == COLLADAFW::EffectCommon::SHADER_LAMBERT) {
3554
ma->diff_shader = MA_DIFF_LAMBERT;
3556
// default - lambert
3558
ma->diff_shader = MA_DIFF_LAMBERT;
3559
fprintf(stderr, "Current shader type is not supported.\n");
3562
ma->ray_mirror = ef->getReflectivity().getFloatValue();
3563
// index of refraction
3564
ma->ang = ef->getIndexOfRefraction().getFloatValue();
3567
COLLADAFW::Color col;
3569
TexIndexTextureArrayMap texindex_texarray_map;
3573
if (ef->getDiffuse().isColor()) {
3574
col = ef->getDiffuse().getColor();
3575
ma->r = col.getRed();
3576
ma->g = col.getGreen();
3577
ma->b = col.getBlue();
3580
else if (ef->getDiffuse().isTexture()) {
3581
COLLADAFW::Texture ctex = ef->getDiffuse().getTexture();
3582
mtex = create_texture(ef, ctex, ma, i, texindex_texarray_map);
3584
mtex->mapto = MAP_COL;
3585
ma->texact = (int)i;
3591
if (ef->getAmbient().isColor()) {
3592
col = ef->getAmbient().getColor();
3593
ma->ambr = col.getRed();
3594
ma->ambg = col.getGreen();
3595
ma->ambb = col.getBlue();
3598
else if (ef->getAmbient().isTexture()) {
3599
COLLADAFW::Texture ctex = ef->getAmbient().getTexture();
3600
mtex = create_texture(ef, ctex, ma, i, texindex_texarray_map);
3602
mtex->mapto = MAP_AMB;
3608
if (ef->getSpecular().isColor()) {
3609
col = ef->getSpecular().getColor();
3610
ma->specr = col.getRed();
3611
ma->specg = col.getGreen();
3612
ma->specb = col.getBlue();
3615
else if (ef->getSpecular().isTexture()) {
3616
COLLADAFW::Texture ctex = ef->getSpecular().getTexture();
3617
mtex = create_texture(ef, ctex, ma, i, texindex_texarray_map);
3619
mtex->mapto = MAP_SPEC;
3625
if (ef->getReflective().isColor()) {
3626
col = ef->getReflective().getColor();
3627
ma->mirr = col.getRed();
3628
ma->mirg = col.getGreen();
3629
ma->mirb = col.getBlue();
3632
else if (ef->getReflective().isTexture()) {
3633
COLLADAFW::Texture ctex = ef->getReflective().getTexture();
3634
mtex = create_texture(ef, ctex, ma, i, texindex_texarray_map);
3636
mtex->mapto = MAP_REF;
3642
if (ef->getEmission().isColor()) {
3643
// XXX there is no emission color in blender
3644
// but I am not sure
3647
else if (ef->getEmission().isTexture()) {
3648
COLLADAFW::Texture ctex = ef->getEmission().getTexture();
3649
mtex = create_texture(ef, ctex, ma, i, texindex_texarray_map);
3651
mtex->mapto = MAP_EMIT;
3657
// if (ef->getOpacity().isColor()) {
375
COLLADAFW::Node *child_node = children[i];
376
const COLLADAFW::UniqueId& child_id = child_node->getUniqueId();
377
if (object_map.find(child_id) == object_map.end())
379
COLLADAFW::InstanceNodePointerArray &inodes = child_node->getInstanceNodes();
380
Object *new_child = NULL;
381
if (inodes.getCount()) { // \todo loop through instance nodes
382
const COLLADAFW::UniqueId& id = inodes[0]->getInstanciatedObjectId();
383
new_child = create_instance_node(object_map[id], node_map[id], child_node, sce, is_library_node);
386
new_child = create_instance_node(object_map[child_id], child_node, NULL, sce, is_library_node);
388
bc_set_parent(new_child, obn, mContext, true);
391
libnode_ob.push_back(new_child);
398
void DocumentImporter::write_node (COLLADAFW::Node *node, COLLADAFW::Node *parent_node, Scene *sce, Object *par, bool is_library_node)
401
bool is_joint = node->getType() == COLLADAFW::Node::JOINT;
402
bool read_transform = true;
406
Object * empty = par;
407
par = bc_add_object(sce, OB_ARMATURE, NULL);
408
bc_set_parent(par,empty->parent, mContext);
409
//remove empty : todo
410
object_map[parent_node->getUniqueId()] = par;
412
armature_importer.add_joint(node, parent_node == NULL || parent_node->getType() != COLLADAFW::Node::JOINT, par, sce);
415
COLLADAFW::InstanceGeometryPointerArray &geom = node->getInstanceGeometries();
416
COLLADAFW::InstanceCameraPointerArray &camera = node->getInstanceCameras();
417
COLLADAFW::InstanceLightPointerArray &lamp = node->getInstanceLights();
418
COLLADAFW::InstanceControllerPointerArray &controller = node->getInstanceControllers();
419
COLLADAFW::InstanceNodePointerArray &inst_node = node->getInstanceNodes();
420
size_t geom_done = 0;
421
size_t camera_done = 0;
422
size_t lamp_done = 0;
423
size_t controller_done = 0;
424
size_t inst_done = 0;
426
// XXX linking object with the first <instance_geometry>, though a node may have more of them...
427
// maybe join multiple <instance_...> meshes into 1, and link object with it? not sure...
428
// <instance_geometry>
429
while (geom_done < geom.getCount()) {
430
ob = mesh_importer.create_mesh_object(node, geom[geom_done], false, uid_material_map,
431
material_texture_mapping_map);
434
while (camera_done < camera.getCount()) {
435
ob = create_camera_object(camera[camera_done], sce);
438
while (lamp_done < lamp.getCount()) {
439
ob = create_lamp_object(lamp[lamp_done], sce);
442
while (controller_done < controller.getCount()) {
443
COLLADAFW::InstanceGeometry *geom = (COLLADAFW::InstanceGeometry*)controller[controller_done];
444
ob = mesh_importer.create_mesh_object(node, geom, true, uid_material_map, material_texture_mapping_map);
447
// XXX instance_node is not supported yet
448
while (inst_done < inst_node.getCount()) {
449
const COLLADAFW::UniqueId& node_id = inst_node[inst_done]->getInstanciatedObjectId();
450
if (object_map.find(node_id) == object_map.end()) {
451
fprintf(stderr, "Cannot find object for node referenced by <instance_node name=\"%s\">.\n", inst_node[inst_done]->getName().c_str());
455
Object *source_ob = object_map[node_id];
456
COLLADAFW::Node *source_node = node_map[node_id];
458
ob = create_instance_node(source_ob, source_node, node, sce, is_library_node);
462
read_transform = false;
464
// if node is empty - create empty object
465
// XXX empty node may not mean it is empty object, not sure about this
466
if ( (geom_done + camera_done + lamp_done + controller_done + inst_done) < 1) {
467
ob = bc_add_object(sce, OB_EMPTY, NULL);
470
// XXX: if there're multiple instances, only one is stored
474
std::string nodename = node->getName().size() ? node->getName() : node->getOriginalId();
475
rename_id(&ob->id, (char*)nodename.c_str());
477
object_map[node->getUniqueId()] = ob;
478
node_map[node->getUniqueId()] = node;
481
libnode_ob.push_back(ob);
485
anim_importer.read_node_transform(node, ob); // overwrites location set earlier
488
// if par was given make this object child of the previous
490
bc_set_parent(ob, par, mContext);
493
// if node has child nodes write them
494
COLLADAFW::NodePointerArray &child_nodes = node->getChildNodes();
495
for (unsigned int i = 0; i < child_nodes.getCount(); i++) {
496
write_node(child_nodes[i], node, sce, ob, is_library_node);
500
/** When this method is called, the writer must write the entire visual scene.
501
\return The writer should return true, if writing succeeded, false otherwise.*/
502
bool DocumentImporter::writeVisualScene ( const COLLADAFW::VisualScene* visualScene )
504
if (mImportStage!=General)
507
// this method called on post process after writeGeometry, writeMaterial, etc.
509
// for each <node> in <visual_scene>:
511
// if Mesh (previously created in writeGeometry) to which <node> corresponds exists, link Object with that mesh
513
// update: since we cannot link a Mesh with Object in
514
// writeGeometry because <geometry> does not reference <node>,
515
// we link Objects with Meshes here
517
vscenes.push_back(visualScene);
522
/** When this method is called, the writer must handle all nodes contained in the
524
\return The writer should return true, if writing succeeded, false otherwise.*/
525
bool DocumentImporter::writeLibraryNodes ( const COLLADAFW::LibraryNodes* libraryNodes )
527
if (mImportStage!=General)
530
Scene *sce = CTX_data_scene(mContext);
532
const COLLADAFW::NodePointerArray& nodes = libraryNodes->getNodes();
534
for (unsigned int i = 0; i < nodes.getCount(); i++) {
535
write_node(nodes[i], NULL, sce, NULL, true);
541
/** When this method is called, the writer must write the geometry.
542
\return The writer should return true, if writing succeeded, false otherwise.*/
543
bool DocumentImporter::writeGeometry ( const COLLADAFW::Geometry* geom )
545
if (mImportStage!=General)
548
return mesh_importer.write_geometry(geom);
551
/** When this method is called, the writer must write the material.
552
\return The writer should return true, if writing succeeded, false otherwise.*/
553
bool DocumentImporter::writeMaterial( const COLLADAFW::Material* cmat )
555
if (mImportStage!=General)
558
const std::string& str_mat_id = cmat->getName().size() ? cmat->getName() : cmat->getOriginalId();
559
Material *ma = add_material((char*)str_mat_id.c_str());
561
this->uid_effect_map[cmat->getInstantiatedEffect()] = ma;
562
this->uid_material_map[cmat->getUniqueId()] = ma;
567
// create mtex, create texture, set texture image
568
MTex* DocumentImporter::create_texture(COLLADAFW::EffectCommon *ef, COLLADAFW::Texture &ctex, Material *ma,
569
int i, TexIndexTextureArrayMap &texindex_texarray_map)
571
COLLADAFW::SamplerPointerArray& samp_array = ef->getSamplerPointerArray();
572
COLLADAFW::Sampler *sampler = samp_array[ctex.getSamplerId()];
574
const COLLADAFW::UniqueId& ima_uid = sampler->getSourceImage();
576
if (uid_image_map.find(ima_uid) == uid_image_map.end()) {
577
fprintf(stderr, "Couldn't find an image by UID.\n");
581
ma->mtex[i] = add_mtex();
582
ma->mtex[i]->texco = TEXCO_UV;
583
ma->mtex[i]->tex = add_texture("Texture");
584
ma->mtex[i]->tex->type = TEX_IMAGE;
585
ma->mtex[i]->tex->imaflag &= ~TEX_USEALPHA;
586
ma->mtex[i]->tex->ima = uid_image_map[ima_uid];
588
texindex_texarray_map[ctex.getTextureMapId()].push_back(ma->mtex[i]);
593
void DocumentImporter::write_profile_COMMON(COLLADAFW::EffectCommon *ef, Material *ma)
595
COLLADAFW::EffectCommon::ShaderType shader = ef->getShaderType();
598
if (shader == COLLADAFW::EffectCommon::SHADER_BLINN) {
599
ma->spec_shader = MA_SPEC_BLINN;
600
ma->spec = ef->getShininess().getFloatValue();
603
else if (shader == COLLADAFW::EffectCommon::SHADER_PHONG) {
604
ma->spec_shader = MA_SPEC_PHONG;
605
ma->har = ef->getShininess().getFloatValue();
608
else if (shader == COLLADAFW::EffectCommon::SHADER_LAMBERT) {
609
ma->diff_shader = MA_DIFF_LAMBERT;
613
ma->diff_shader = MA_DIFF_LAMBERT;
614
fprintf(stderr, "Current shader type is not supported, default to lambert.\n");
617
ma->ray_mirror = ef->getReflectivity().getFloatValue();
618
// index of refraction
619
ma->ang = ef->getIndexOfRefraction().getFloatValue();
622
COLLADAFW::Color col;
624
TexIndexTextureArrayMap texindex_texarray_map;
628
if (ef->getDiffuse().isColor()) {
629
col = ef->getDiffuse().getColor();
630
ma->r = col.getRed();
631
ma->g = col.getGreen();
632
ma->b = col.getBlue();
635
else if (ef->getDiffuse().isTexture()) {
636
COLLADAFW::Texture ctex = ef->getDiffuse().getTexture();
637
mtex = create_texture(ef, ctex, ma, i, texindex_texarray_map);
639
mtex->mapto = MAP_COL;
646
if (ef->getAmbient().isColor()) {
647
col = ef->getAmbient().getColor();
648
ma->ambr = col.getRed();
649
ma->ambg = col.getGreen();
650
ma->ambb = col.getBlue();
653
else if (ef->getAmbient().isTexture()) {
654
COLLADAFW::Texture ctex = ef->getAmbient().getTexture();
655
mtex = create_texture(ef, ctex, ma, i, texindex_texarray_map);
657
mtex->mapto = MAP_AMB;
663
if (ef->getSpecular().isColor()) {
664
col = ef->getSpecular().getColor();
665
ma->specr = col.getRed();
666
ma->specg = col.getGreen();
667
ma->specb = col.getBlue();
670
else if (ef->getSpecular().isTexture()) {
671
COLLADAFW::Texture ctex = ef->getSpecular().getTexture();
672
mtex = create_texture(ef, ctex, ma, i, texindex_texarray_map);
674
mtex->mapto = MAP_SPEC;
680
if (ef->getReflective().isColor()) {
681
col = ef->getReflective().getColor();
682
ma->mirr = col.getRed();
683
ma->mirg = col.getGreen();
684
ma->mirb = col.getBlue();
687
else if (ef->getReflective().isTexture()) {
688
COLLADAFW::Texture ctex = ef->getReflective().getTexture();
689
mtex = create_texture(ef, ctex, ma, i, texindex_texarray_map);
691
mtex->mapto = MAP_REF;
697
if (ef->getEmission().isColor()) {
698
// XXX there is no emission color in blender
702
else if (ef->getEmission().isTexture()) {
703
COLLADAFW::Texture ctex = ef->getEmission().getTexture();
704
mtex = create_texture(ef, ctex, ma, i, texindex_texarray_map);
706
mtex->mapto = MAP_EMIT;
711
if (ef->getOpacity().isTexture()) {
712
COLLADAFW::Texture ctex = ef->getOpacity().getTexture();
713
mtex = create_texture(ef, ctex, ma, i, texindex_texarray_map);
715
mtex->mapto = MAP_ALPHA;
716
mtex->tex->imaflag |= TEX_USEALPHA;
718
ma->spectra = ma->alpha = 0;
719
ma->mode |= MA_ZTRANSP|MA_TRANSP;
724
// if (ef->getOpacity().isColor()) {
3658
725
// // XXX don't know what to do here