4 * ***** BEGIN GPL LICENSE BLOCK *****
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software Foundation,
18 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 * Contributor(s): Chingiz Dyussenov, Arystanbek Dyussenov, Nathan Letwory.
22 * ***** END GPL LICENSE BLOCK *****
25 /** \file blender/collada/DocumentImporter.cpp
30 // * name imported objects
31 // * import object rotation as euler
35 #include <algorithm> // sort()
37 #include "COLLADAFWRoot.h"
38 #include "COLLADAFWStableHeaders.h"
39 #include "COLLADAFWColorOrTexture.h"
40 #include "COLLADAFWIndexList.h"
41 #include "COLLADAFWMeshPrimitiveWithFaceVertexCount.h"
42 #include "COLLADAFWPolygons.h"
43 #include "COLLADAFWSampler.h"
44 #include "COLLADAFWTypes.h"
45 #include "COLLADAFWVisualScene.h"
46 #include "COLLADAFWArrayPrimitiveType.h"
47 #include "COLLADAFWLibraryNodes.h"
48 #include "COLLADAFWCamera.h"
49 #include "COLLADAFWLight.h"
51 #include "COLLADASaxFWLLoader.h"
52 #include "COLLADASaxFWLIExtraDataCallbackHandler.h"
54 #include "BLI_listbase.h"
56 #include "BLI_string.h"
57 #include "BLI_utildefines.h"
60 #include "BKE_library.h"
61 #include "BKE_texture.h"
62 #include "BKE_fcurve.h"
63 #include "BKE_depsgraph.h"
64 #include "BLI_path_util.h"
65 #include "BKE_scene.h"
66 #include "BKE_global.h"
67 #include "BKE_material.h"
68 #include "BKE_utildefines.h"
69 #include "BKE_image.h"
71 #include "DNA_camera_types.h"
72 #include "DNA_lamp_types.h"
74 #include "RNA_access.h"
76 #include "MEM_guardedalloc.h"
78 #include "ExtraHandler.h"
79 #include "DocumentImporter.h"
80 #include "TransformReader.h"
82 #include "collada_internal.h"
83 #include "collada_utils.h"
87 COLLADA Importer limitations:
88 - no multiple scene import, all objects are added to active scene
91 // #define COLLADA_DEBUG
92 // creates empties for each imported bone on layer 2, for debugging
93 // #define ARMATURE_TEST
95 DocumentImporter::DocumentImporter(bContext *C, const char *filename) :
96 mImportStage(General),
99 armature_importer(&unit_converter, &mesh_importer, &anim_importer, CTX_data_scene(C)),
100 mesh_importer(&unit_converter, &armature_importer, CTX_data_scene(C)),
101 anim_importer(&unit_converter, &armature_importer, CTX_data_scene(C))
104 DocumentImporter::~DocumentImporter()
106 TagsMap::iterator etit;
107 etit = uid_tags_map.begin();
108 while(etit!=uid_tags_map.end()) {
114 bool DocumentImporter::import()
116 /** TODO Add error handler (implement COLLADASaxFWL::IErrorHandler */
117 COLLADASaxFWL::Loader loader;
118 COLLADAFW::Root root(&loader, this);
119 ExtraHandler *ehandler = new ExtraHandler(this);
121 loader.registerExtraDataCallbackHandler(ehandler);
124 if (!root.loadDocument(mFilename))
127 /** TODO set up scene graph and such here */
129 mImportStage = Controller;
131 COLLADASaxFWL::Loader loader2;
132 COLLADAFW::Root root2(&loader2, this);
134 if (!root2.loadDocument(mFilename))
143 void DocumentImporter::cancel(const COLLADAFW::String& errorMessage)
145 // TODO: if possible show error info
147 // Should we get rid of invisible Meshes that were created so far
148 // or maybe create objects at coordinate space origin?
150 // The latter sounds better.
153 void DocumentImporter::start(){}
155 void DocumentImporter::finish()
157 if(mImportStage!=General)
160 /** TODO Break up and put into 2-pass parsing of DAE */
161 std::vector<const COLLADAFW::VisualScene*>::iterator it;
162 for (it = vscenes.begin(); it != vscenes.end(); it++) {
163 PointerRNA sceneptr, unit_settings;
164 PropertyRNA *system, *scale;
165 // TODO: create a new scene except the selected <visual_scene> - use current blender scene for it
166 Scene *sce = CTX_data_scene(mContext);
168 // for scene unit settings: system, scale_length
169 RNA_id_pointer_create(&sce->id, &sceneptr);
170 unit_settings = RNA_pointer_get(&sceneptr, "unit_settings");
171 system = RNA_struct_find_property(&unit_settings, "system");
172 scale = RNA_struct_find_property(&unit_settings, "scale_length");
174 switch(unit_converter.isMetricSystem()) {
175 case UnitConverter::Metric:
176 RNA_property_enum_set(&unit_settings, system, USER_UNIT_METRIC);
178 case UnitConverter::Imperial:
179 RNA_property_enum_set(&unit_settings, system, USER_UNIT_IMPERIAL);
182 RNA_property_enum_set(&unit_settings, system, USER_UNIT_NONE);
185 RNA_property_float_set(&unit_settings, scale, unit_converter.getLinearMeter());
187 const COLLADAFW::NodePointerArray& roots = (*it)->getRootNodes();
189 for (unsigned int i = 0; i < roots.getCount(); i++) {
190 write_node(roots[i], NULL, sce, NULL, false);
194 armature_importer.make_armatures(mContext);
197 armature_importer.fix_animation();
200 for (std::vector<const COLLADAFW::VisualScene*>::iterator it = vscenes.begin(); it != vscenes.end(); it++) {
201 const COLLADAFW::NodePointerArray& roots = (*it)->getRootNodes();
203 for (unsigned int i = 0; i < roots.getCount(); i++)
204 translate_anim_recursive(roots[i],NULL,NULL);
207 if (libnode_ob.size()) {
208 Scene *sce = CTX_data_scene(mContext);
210 fprintf(stderr, "got %d library nodes to free\n", (int)libnode_ob.size());
211 // free all library_nodes
212 std::vector<Object*>::iterator it;
213 for (it = libnode_ob.begin(); it != libnode_ob.end(); it++) {
216 Base *base = object_in_scene(ob, sce);
218 BLI_remlink(&sce->base, base);
219 free_libblock_us(&G.main->object, base->object);
220 if (sce->basact==base)
227 DAG_scene_sort(CTX_data_main(mContext), sce);
228 DAG_ids_flush_update(CTX_data_main(mContext), 0);
233 void DocumentImporter::translate_anim_recursive(COLLADAFW::Node *node, COLLADAFW::Node *par = NULL, Object *parob = NULL)
235 if (par && par->getType() == COLLADAFW::Node::JOINT) {
236 // par is root if there's no corresp. key in root_map
237 if (root_map.find(par->getUniqueId()) == root_map.end())
238 root_map[node->getUniqueId()] = par;
240 root_map[node->getUniqueId()] = root_map[par->getUniqueId()];
243 COLLADAFW::Transformation::TransformationType types[] = {
244 COLLADAFW::Transformation::ROTATE,
245 COLLADAFW::Transformation::SCALE,
246 COLLADAFW::Transformation::TRANSLATE,
247 COLLADAFW::Transformation::MATRIX
253 for (i = 0; i < 4; i++)
254 ob = anim_importer.translate_animation(node, object_map, root_map, types[i]);
256 COLLADAFW::NodePointerArray &children = node->getChildNodes();
257 for (i = 0; i < children.getCount(); i++) {
258 translate_anim_recursive(children[i], node, ob);
262 /** When this method is called, the writer must write the global document asset.
263 @return The writer should return true, if writing succeeded, false otherwise.*/
264 bool DocumentImporter::writeGlobalAsset ( const COLLADAFW::FileInfo* asset )
266 unit_converter.read_asset(asset);
271 /** When this method is called, the writer must write the scene.
272 @return The writer should return true, if writing succeeded, false otherwise.*/
273 bool DocumentImporter::writeScene ( const COLLADAFW::Scene* scene )
275 // XXX could store the scene id, but do nothing for now
278 Object* DocumentImporter::create_camera_object(COLLADAFW::InstanceCamera *camera, Scene *sce)
280 const COLLADAFW::UniqueId& cam_uid = camera->getInstanciatedObjectId();
281 if (uid_camera_map.find(cam_uid) == uid_camera_map.end()) {
282 fprintf(stderr, "Couldn't find camera by UID.\n");
285 Object *ob = add_object(sce, OB_CAMERA);
286 Camera *cam = uid_camera_map[cam_uid];
287 Camera *old_cam = (Camera*)ob->data;
290 if (old_cam->id.us == 0)
291 free_libblock(&G.main->camera, old_cam);
295 Object* DocumentImporter::create_lamp_object(COLLADAFW::InstanceLight *lamp, Scene *sce)
297 const COLLADAFW::UniqueId& lamp_uid = lamp->getInstanciatedObjectId();
298 if (uid_lamp_map.find(lamp_uid) == uid_lamp_map.end()) {
299 fprintf(stderr, "Couldn't find lamp by UID. \n");
302 Object *ob = add_object(sce, OB_LAMP);
303 Lamp *la = uid_lamp_map[lamp_uid];
304 Lamp *old_lamp = (Lamp*)ob->data;
307 if (old_lamp->id.us == 0)
308 free_libblock(&G.main->lamp, old_lamp);
312 Object* DocumentImporter::create_instance_node(Object *source_ob, COLLADAFW::Node *source_node, COLLADAFW::Node *instance_node, Scene *sce, Object *par_ob, bool is_library_node)
314 Object *obn = copy_object(source_ob);
315 obn->recalc |= OB_RECALC_OB|OB_RECALC_DATA|OB_RECALC_TIME;
316 scene_add_base(sce, obn);
319 anim_importer.read_node_transform(instance_node, obn);
320 // if we also have a source_node (always ;), take its
321 // transformation matrix and apply it to the newly instantiated
322 // object to account for node hierarchy transforms in
325 COLLADABU::Math::Matrix4 mat4 = source_node->getTransformationMatrix();
326 COLLADABU::Math::Matrix4 bmat4 = mat4.transpose(); // transpose to get blender row-major order
328 for (int i = 0; i < 4; i++) {
329 for (int j = 0; j < 4; j++) {
330 mat[i][j] = bmat4[i][j];
333 // calc new matrix and apply
334 mul_m4_m4m4(obn->obmat, mat, obn->obmat);
335 object_apply_mat4(obn, obn->obmat, 0, 0);
339 anim_importer.read_node_transform(source_node, obn);
342 DAG_scene_sort(CTX_data_main(mContext), sce);
343 DAG_ids_flush_update(CTX_data_main(mContext), 0);
345 COLLADAFW::NodePointerArray &children = source_node->getChildNodes();
346 if (children.getCount()) {
347 for (unsigned int i = 0; i < children.getCount(); i++) {
348 COLLADAFW::Node *child_node = children[i];
349 const COLLADAFW::UniqueId& child_id = child_node->getUniqueId();
350 if (object_map.find(child_id) == object_map.end())
352 COLLADAFW::InstanceNodePointerArray &inodes = child_node->getInstanceNodes();
353 Object *new_child = NULL;
354 if (inodes.getCount()) { // \todo loop through instance nodes
355 const COLLADAFW::UniqueId& id = inodes[0]->getInstanciatedObjectId();
356 new_child = create_instance_node(object_map[id], node_map[id], child_node, sce, NULL, is_library_node);
359 new_child = create_instance_node(object_map[child_id], child_node, NULL, sce, NULL, is_library_node);
361 bc_set_parent(new_child, obn, mContext, true);
364 libnode_ob.push_back(new_child);
368 // when we have an instance_node, don't return the object, because otherwise
369 // its correct location gets overwritten in write_node(). Fixes bug #26012.
372 bc_set_parent(obn, par_ob, mContext);
379 void DocumentImporter::write_node (COLLADAFW::Node *node, COLLADAFW::Node *parent_node, Scene *sce, Object *par, bool is_library_node)
382 bool is_joint = node->getType() == COLLADAFW::Node::JOINT;
385 armature_importer.add_joint(node, parent_node == NULL || parent_node->getType() != COLLADAFW::Node::JOINT, par);
388 COLLADAFW::InstanceGeometryPointerArray &geom = node->getInstanceGeometries();
389 COLLADAFW::InstanceCameraPointerArray &camera = node->getInstanceCameras();
390 COLLADAFW::InstanceLightPointerArray &lamp = node->getInstanceLights();
391 COLLADAFW::InstanceControllerPointerArray &controller = node->getInstanceControllers();
392 COLLADAFW::InstanceNodePointerArray &inst_node = node->getInstanceNodes();
393 size_t geom_done = 0;
394 size_t camera_done = 0;
395 size_t lamp_done = 0;
396 size_t controller_done = 0;
397 size_t inst_done = 0;
399 // XXX linking object with the first <instance_geometry>, though a node may have more of them...
400 // maybe join multiple <instance_...> meshes into 1, and link object with it? not sure...
401 // <instance_geometry>
402 while (geom_done < geom.getCount()) {
403 ob = mesh_importer.create_mesh_object(node, geom[geom_done], false, uid_material_map,
404 material_texture_mapping_map);
407 while (camera_done < camera.getCount()) {
408 ob = create_camera_object(camera[camera_done], sce);
411 while (lamp_done < lamp.getCount()) {
412 ob = create_lamp_object(lamp[lamp_done], sce);
415 while (controller_done < controller.getCount()) {
416 COLLADAFW::InstanceGeometry *geom = (COLLADAFW::InstanceGeometry*)controller[controller_done];
417 ob = mesh_importer.create_mesh_object(node, geom, true, uid_material_map, material_texture_mapping_map);
420 // XXX instance_node is not supported yet
421 while (inst_done < inst_node.getCount()) {
422 const COLLADAFW::UniqueId& node_id = inst_node[inst_done]->getInstanciatedObjectId();
423 if (object_map.find(node_id) == object_map.end()) {
424 fprintf(stderr, "Cannot find node to instanciate.\n");
428 Object *source_ob = object_map[node_id];
429 COLLADAFW::Node *source_node = node_map[node_id];
431 ob = create_instance_node(source_ob, source_node, node, sce, par, is_library_node);
435 // if node is empty - create empty object
436 // XXX empty node may not mean it is empty object, not sure about this
437 if ( (geom_done + camera_done + lamp_done + controller_done + inst_done) < 1) {
438 ob = add_object(sce, OB_EMPTY);
441 // check if object is not NULL
444 std::string nodename = node->getName().size() ? node->getName() : node->getOriginalId();
445 rename_id(&ob->id, (char*)nodename.c_str());
447 object_map[node->getUniqueId()] = ob;
448 node_map[node->getUniqueId()] = node;
451 libnode_ob.push_back(ob);
454 anim_importer.read_node_transform(node, ob); // overwrites location set earlier
457 // if par was given make this object child of the previous
459 bc_set_parent(ob, par, mContext);
462 // if node has child nodes write them
463 COLLADAFW::NodePointerArray &child_nodes = node->getChildNodes();
464 for (unsigned int i = 0; i < child_nodes.getCount(); i++) {
465 write_node(child_nodes[i], node, sce, ob, is_library_node);
469 /** When this method is called, the writer must write the entire visual scene.
470 @return The writer should return true, if writing succeeded, false otherwise.*/
471 bool DocumentImporter::writeVisualScene ( const COLLADAFW::VisualScene* visualScene )
473 if(mImportStage!=General)
476 // this method called on post process after writeGeometry, writeMaterial, etc.
478 // for each <node> in <visual_scene>:
480 // if Mesh (previously created in writeGeometry) to which <node> corresponds exists, link Object with that mesh
482 // update: since we cannot link a Mesh with Object in
483 // writeGeometry because <geometry> does not reference <node>,
484 // we link Objects with Meshes here
486 vscenes.push_back(visualScene);
491 /** When this method is called, the writer must handle all nodes contained in the
493 @return The writer should return true, if writing succeeded, false otherwise.*/
494 bool DocumentImporter::writeLibraryNodes ( const COLLADAFW::LibraryNodes* libraryNodes )
496 if(mImportStage!=General)
499 Scene *sce = CTX_data_scene(mContext);
501 const COLLADAFW::NodePointerArray& nodes = libraryNodes->getNodes();
503 for (unsigned int i = 0; i < nodes.getCount(); i++) {
504 write_node(nodes[i], NULL, sce, NULL, true);
510 /** When this method is called, the writer must write the geometry.
511 @return The writer should return true, if writing succeeded, false otherwise.*/
512 bool DocumentImporter::writeGeometry ( const COLLADAFW::Geometry* geom )
514 if(mImportStage!=General)
517 return mesh_importer.write_geometry(geom);
520 /** When this method is called, the writer must write the material.
521 @return The writer should return true, if writing succeeded, false otherwise.*/
522 bool DocumentImporter::writeMaterial( const COLLADAFW::Material* cmat )
524 if(mImportStage!=General)
527 const std::string& str_mat_id = cmat->getName().size() ? cmat->getName() : cmat->getOriginalId();
528 Material *ma = add_material((char*)str_mat_id.c_str());
530 this->uid_effect_map[cmat->getInstantiatedEffect()] = ma;
531 this->uid_material_map[cmat->getUniqueId()] = ma;
536 // create mtex, create texture, set texture image
537 MTex* DocumentImporter::create_texture(COLLADAFW::EffectCommon *ef, COLLADAFW::Texture &ctex, Material *ma,
538 int i, TexIndexTextureArrayMap &texindex_texarray_map)
540 COLLADAFW::SamplerPointerArray& samp_array = ef->getSamplerPointerArray();
541 COLLADAFW::Sampler *sampler = samp_array[ctex.getSamplerId()];
543 const COLLADAFW::UniqueId& ima_uid = sampler->getSourceImage();
545 if (uid_image_map.find(ima_uid) == uid_image_map.end()) {
546 fprintf(stderr, "Couldn't find an image by UID.\n");
550 ma->mtex[i] = add_mtex();
551 ma->mtex[i]->texco = TEXCO_UV;
552 ma->mtex[i]->tex = add_texture("Texture");
553 ma->mtex[i]->tex->type = TEX_IMAGE;
554 ma->mtex[i]->tex->imaflag &= ~TEX_USEALPHA;
555 ma->mtex[i]->tex->ima = uid_image_map[ima_uid];
557 texindex_texarray_map[ctex.getTextureMapId()].push_back(ma->mtex[i]);
562 void DocumentImporter::write_profile_COMMON(COLLADAFW::EffectCommon *ef, Material *ma)
564 COLLADAFW::EffectCommon::ShaderType shader = ef->getShaderType();
567 if (shader == COLLADAFW::EffectCommon::SHADER_BLINN) {
568 ma->spec_shader = MA_SPEC_BLINN;
569 ma->spec = ef->getShininess().getFloatValue();
572 else if (shader == COLLADAFW::EffectCommon::SHADER_PHONG) {
573 ma->spec_shader = MA_SPEC_PHONG;
574 ma->har = ef->getShininess().getFloatValue();
577 else if (shader == COLLADAFW::EffectCommon::SHADER_LAMBERT) {
578 ma->diff_shader = MA_DIFF_LAMBERT;
582 ma->diff_shader = MA_DIFF_LAMBERT;
583 fprintf(stderr, "Current shader type is not supported, default to lambert.\n");
586 ma->ray_mirror = ef->getReflectivity().getFloatValue();
587 // index of refraction
588 ma->ang = ef->getIndexOfRefraction().getFloatValue();
591 COLLADAFW::Color col;
593 TexIndexTextureArrayMap texindex_texarray_map;
597 if (ef->getDiffuse().isColor()) {
598 col = ef->getDiffuse().getColor();
599 ma->r = col.getRed();
600 ma->g = col.getGreen();
601 ma->b = col.getBlue();
604 else if (ef->getDiffuse().isTexture()) {
605 COLLADAFW::Texture ctex = ef->getDiffuse().getTexture();
606 mtex = create_texture(ef, ctex, ma, i, texindex_texarray_map);
608 mtex->mapto = MAP_COL;
615 if (ef->getAmbient().isColor()) {
616 col = ef->getAmbient().getColor();
617 ma->ambr = col.getRed();
618 ma->ambg = col.getGreen();
619 ma->ambb = col.getBlue();
622 else if (ef->getAmbient().isTexture()) {
623 COLLADAFW::Texture ctex = ef->getAmbient().getTexture();
624 mtex = create_texture(ef, ctex, ma, i, texindex_texarray_map);
626 mtex->mapto = MAP_AMB;
632 if (ef->getSpecular().isColor()) {
633 col = ef->getSpecular().getColor();
634 ma->specr = col.getRed();
635 ma->specg = col.getGreen();
636 ma->specb = col.getBlue();
639 else if (ef->getSpecular().isTexture()) {
640 COLLADAFW::Texture ctex = ef->getSpecular().getTexture();
641 mtex = create_texture(ef, ctex, ma, i, texindex_texarray_map);
643 mtex->mapto = MAP_SPEC;
649 if (ef->getReflective().isColor()) {
650 col = ef->getReflective().getColor();
651 ma->mirr = col.getRed();
652 ma->mirg = col.getGreen();
653 ma->mirb = col.getBlue();
656 else if (ef->getReflective().isTexture()) {
657 COLLADAFW::Texture ctex = ef->getReflective().getTexture();
658 mtex = create_texture(ef, ctex, ma, i, texindex_texarray_map);
660 mtex->mapto = MAP_REF;
666 if (ef->getEmission().isColor()) {
667 // XXX there is no emission color in blender
671 else if (ef->getEmission().isTexture()) {
672 COLLADAFW::Texture ctex = ef->getEmission().getTexture();
673 mtex = create_texture(ef, ctex, ma, i, texindex_texarray_map);
675 mtex->mapto = MAP_EMIT;
680 if(ef->getOpacity().isTexture()) {
681 COLLADAFW::Texture ctex = ef->getOpacity().getTexture();
682 mtex = create_texture(ef, ctex, ma, i, texindex_texarray_map);
684 mtex->mapto = MAP_ALPHA;
685 mtex->tex->imaflag |= TEX_USEALPHA;
687 ma->spectra = ma->alpha = 0;
688 ma->mode |= MA_ZTRANSP|MA_TRANSP;
693 // if (ef->getOpacity().isColor()) {
694 // // XXX don't know what to do here
697 // else if (ef->getOpacity().isTexture()) {
698 // ctex = ef->getOpacity().getTexture();
699 // if (mtex != NULL) mtex->mapto &= MAP_ALPHA;
701 // mtex = create_texture(ef, ctex, ma, i, texindex_texarray_map);
702 // if (mtex != NULL) mtex->mapto = MAP_ALPHA;
705 material_texture_mapping_map[ma] = texindex_texarray_map;
708 /** When this method is called, the writer must write the effect.
709 @return The writer should return true, if writing succeeded, false otherwise.*/
711 bool DocumentImporter::writeEffect( const COLLADAFW::Effect* effect )
713 if(mImportStage!=General)
716 const COLLADAFW::UniqueId& uid = effect->getUniqueId();
717 if (uid_effect_map.find(uid) == uid_effect_map.end()) {
718 fprintf(stderr, "Couldn't find a material by UID.\n");
722 Material *ma = uid_effect_map[uid];
724 COLLADAFW::CommonEffectPointerArray common_efs = effect->getCommonEffects();
725 if (common_efs.getCount() < 1) {
726 fprintf(stderr, "Couldn't find <profile_COMMON>.\n");
729 // XXX TODO: Take all <profile_common>s
730 // Currently only first <profile_common> is supported
731 COLLADAFW::EffectCommon *ef = common_efs[0];
732 write_profile_COMMON(ef, ma);
738 /** When this method is called, the writer must write the camera.
739 @return The writer should return true, if writing succeeded, false otherwise.*/
740 bool DocumentImporter::writeCamera( const COLLADAFW::Camera* camera )
742 if(mImportStage!=General)
746 std::string cam_id, cam_name;
748 cam_id = camera->getOriginalId();
749 cam_name = camera->getName();
750 if (cam_name.size()) cam = (Camera*)add_camera((char*)cam_name.c_str());
751 else cam = (Camera*)add_camera((char*)cam_id.c_str());
754 fprintf(stderr, "Cannot create camera. \n");
757 cam->clipsta = camera->getNearClippingPlane().getValue();
758 cam->clipend = camera->getFarClippingPlane().getValue();
760 COLLADAFW::Camera::CameraType type = camera->getCameraType();
762 case COLLADAFW::Camera::ORTHOGRAPHIC:
764 cam->type = CAM_ORTHO;
767 case COLLADAFW::Camera::PERSPECTIVE:
769 cam->type = CAM_PERSP;
772 case COLLADAFW::Camera::UNDEFINED_CAMERATYPE:
774 fprintf(stderr, "Current camera type is not supported. \n");
775 cam->type = CAM_PERSP;
780 switch(camera->getDescriptionType()) {
781 case COLLADAFW::Camera::ASPECTRATIO_AND_Y:
786 double ymag = camera->getYMag().getValue();
787 double aspect = camera->getAspectRatio().getValue();
788 double xmag = aspect*ymag;
789 cam->ortho_scale = (float)xmag;
795 double yfov = camera->getYFov().getValue();
796 double aspect = camera->getAspectRatio().getValue();
797 double xfov = aspect*yfov;
798 // xfov is in degrees, cam->lens is in millimiters
799 cam->lens = hfov_to_focallength((float)xfov*(M_PI/180.0f), cam->sensor_x);
805 /* XXX correct way to do following four is probably to get also render
806 size and determine proper settings from that somehow */
807 case COLLADAFW::Camera::ASPECTRATIO_AND_X:
808 case COLLADAFW::Camera::SINGLE_X:
809 case COLLADAFW::Camera::X_AND_Y:
813 cam->ortho_scale = (float)camera->getXMag().getValue();
818 double x = camera->getXFov().getValue();
819 // x is in degrees, cam->lens is in millimiters
820 cam->lens = hfov_to_focallength((float)x*(M_PI/180.0f), cam->sensor_x);
826 case COLLADAFW::Camera::SINGLE_Y:
830 cam->ortho_scale = (float)camera->getYMag().getValue();
835 double yfov = camera->getYFov().getValue();
836 // yfov is in degrees, cam->lens is in millimiters
837 cam->lens = hfov_to_focallength((float)yfov*(M_PI/180.0f), cam->sensor_x);
843 case COLLADAFW::Camera::UNDEFINED:
844 // read nothing, use blender defaults.
848 this->uid_camera_map[camera->getUniqueId()] = cam;
849 // XXX import camera options
853 /** When this method is called, the writer must write the image.
854 @return The writer should return true, if writing succeeded, false otherwise.*/
855 bool DocumentImporter::writeImage( const COLLADAFW::Image* image )
857 if(mImportStage!=General)
860 // XXX maybe it is necessary to check if the path is absolute or relative
861 const std::string& filepath = image->getImageURI().toNativePath();
862 const char *filename = (const char*)mFilename.c_str();
864 char full_path[FILE_MAX];
866 BLI_split_dirfile(filename, dir, NULL);
867 BLI_join_dirfile(full_path, sizeof(full_path), dir, filepath.c_str());
868 Image *ima = BKE_add_image_file(full_path);
870 fprintf(stderr, "Cannot create image. \n");
873 this->uid_image_map[image->getUniqueId()] = ima;
878 /** When this method is called, the writer must write the light.
879 @return The writer should return true, if writing succeeded, false otherwise.*/
880 bool DocumentImporter::writeLight( const COLLADAFW::Light* light )
882 if(mImportStage!=General)
886 std::string la_id, la_name;
888 TagsMap::iterator etit;
890 etit = uid_tags_map.find(light->getUniqueId().toAscii());
891 if(etit != uid_tags_map.end())
894 la_id = light->getOriginalId();
895 la_name = light->getName();
896 if (la_name.size()) lamp = (Lamp*)add_lamp((char*)la_name.c_str());
897 else lamp = (Lamp*)add_lamp((char*)la_id.c_str());
900 fprintf(stderr, "Cannot create lamp. \n");
904 // if we find an ExtraTags for this, use that instead.
905 if(et && et->isProfile("blender")) {
906 et->setData("type", &(lamp->type));
907 et->setData("flag", &(lamp->flag));
908 et->setData("mode", &(lamp->mode));
909 et->setData("gamma", &(lamp->k));
910 et->setData("red", &(lamp->r));
911 et->setData("green", &(lamp->g));
912 et->setData("blue", &(lamp->b));
913 et->setData("shadow_r", &(lamp->shdwr));
914 et->setData("shadow_g", &(lamp->shdwg));
915 et->setData("shadow_b", &(lamp->shdwb));
916 et->setData("energy", &(lamp->energy));
917 et->setData("dist", &(lamp->dist));
918 et->setData("spotsize", &(lamp->spotsize));
919 et->setData("spotblend", &(lamp->spotblend));
920 et->setData("halo_intensity", &(lamp->haint));
921 et->setData("att1", &(lamp->att1));
922 et->setData("att2", &(lamp->att2));
923 et->setData("falloff_type", &(lamp->falloff_type));
924 et->setData("clipsta", &(lamp->clipsta));
925 et->setData("clipend", &(lamp->clipend));
926 et->setData("shadspotsize", &(lamp->shadspotsize));
927 et->setData("bias", &(lamp->bias));
928 et->setData("soft", &(lamp->soft));
929 et->setData("compressthresh", &(lamp->compressthresh));
930 et->setData("bufsize", &(lamp->bufsize));
931 et->setData("samp", &(lamp->samp));
932 et->setData("buffers", &(lamp->buffers));
933 et->setData("filtertype", &(lamp->filtertype));
934 et->setData("bufflag", &(lamp->bufflag));
935 et->setData("buftype", &(lamp->buftype));
936 et->setData("ray_samp", &(lamp->ray_samp));
937 et->setData("ray_sampy", &(lamp->ray_sampy));
938 et->setData("ray_sampz", &(lamp->ray_sampz));
939 et->setData("ray_samp_type", &(lamp->ray_samp_type));
940 et->setData("area_shape", &(lamp->area_shape));
941 et->setData("area_size", &(lamp->area_size));
942 et->setData("area_sizey", &(lamp->area_sizey));
943 et->setData("area_sizez", &(lamp->area_sizez));
944 et->setData("adapt_thresh", &(lamp->adapt_thresh));
945 et->setData("ray_samp_method", &(lamp->ray_samp_method));
946 et->setData("shadhalostep", &(lamp->shadhalostep));
947 et->setData("sun_effect_type", &(lamp->shadhalostep));
948 et->setData("skyblendtype", &(lamp->skyblendtype));
949 et->setData("horizon_brightness", &(lamp->horizon_brightness));
950 et->setData("spread", &(lamp->spread));
951 et->setData("sun_brightness", &(lamp->sun_brightness));
952 et->setData("sun_size", &(lamp->sun_size));
953 et->setData("backscattered_light", &(lamp->backscattered_light));
954 et->setData("sun_intensity", &(lamp->sun_intensity));
955 et->setData("atm_turbidity", &(lamp->atm_turbidity));
956 et->setData("atm_extinction_factor", &(lamp->atm_extinction_factor));
957 et->setData("atm_distance_factor", &(lamp->atm_distance_factor));
958 et->setData("skyblendfac", &(lamp->skyblendfac));
959 et->setData("sky_exposure", &(lamp->sky_exposure));
960 et->setData("sky_colorspace", &(lamp->sky_colorspace));
963 float constatt = light->getConstantAttenuation().getValue();
964 float linatt = light->getLinearAttenuation().getValue();
965 float quadatt = light->getQuadraticAttenuation().getValue();
971 if (light->getColor().isValid()) {
972 COLLADAFW::Color col = light->getColor();
973 lamp->r = col.getRed();
974 lamp->g = col.getGreen();
975 lamp->b = col.getBlue();
978 if(IS_EQ(linatt, 0.0f) && quadatt > 0.0f) {
980 d = sqrt(1.0f/quadatt);
983 else if(IS_EQ(quadatt, 0.0f) && linatt > 0.0f) {
986 } else if (IS_EQ(constatt, 1.0f)) {
989 // assuming point light (const att = 1.0);
993 d *= ( 1.0f / unit_converter.getLinearMeter());
998 COLLADAFW::Light::LightType type = light->getLightType();
1000 case COLLADAFW::Light::AMBIENT_LIGHT:
1002 lamp->type = LA_HEMI;
1005 case COLLADAFW::Light::SPOT_LIGHT:
1007 lamp->type = LA_SPOT;
1010 if(IS_EQ(att1, 0.0f) && att2 > 0)
1011 lamp->falloff_type = LA_FALLOFF_INVSQUARE;
1012 if(IS_EQ(att2, 0.0f) && att1 > 0)
1013 lamp->falloff_type = LA_FALLOFF_INVLINEAR;
1014 lamp->spotsize = light->getFallOffAngle().getValue();
1015 lamp->spotblend = light->getFallOffExponent().getValue();
1018 case COLLADAFW::Light::DIRECTIONAL_LIGHT:
1020 /* our sun is very strong, so pick a smaller energy level */
1021 lamp->type = LA_SUN;
1022 lamp->mode |= LA_NO_SPEC;
1025 case COLLADAFW::Light::POINT_LIGHT:
1027 lamp->type = LA_LOCAL;
1030 if(IS_EQ(att1, 0.0f) && att2 > 0)
1031 lamp->falloff_type = LA_FALLOFF_INVSQUARE;
1032 if(IS_EQ(att2, 0.0f) && att1 > 0)
1033 lamp->falloff_type = LA_FALLOFF_INVLINEAR;
1036 case COLLADAFW::Light::UNDEFINED:
1038 fprintf(stderr, "Current lamp type is not supported. \n");
1039 lamp->type = LA_LOCAL;
1045 this->uid_lamp_map[light->getUniqueId()] = lamp;
1049 // this function is called only for animations that pass COLLADAFW::validate
1050 bool DocumentImporter::writeAnimation( const COLLADAFW::Animation* anim )
1052 if(mImportStage!=General)
1056 return anim_importer.write_animation(anim);
1059 // called on post-process stage after writeVisualScenes
1060 bool DocumentImporter::writeAnimationList( const COLLADAFW::AnimationList* animationList )
1062 if(mImportStage!=General)
1066 return anim_importer.write_animation_list(animationList);
1069 /** When this method is called, the writer must write the skin controller data.
1070 @return The writer should return true, if writing succeeded, false otherwise.*/
1071 bool DocumentImporter::writeSkinControllerData( const COLLADAFW::SkinControllerData* skin )
1073 return armature_importer.write_skin_controller_data(skin);
1076 // this is called on postprocess, before writeVisualScenes
1077 bool DocumentImporter::writeController( const COLLADAFW::Controller* controller )
1079 if(mImportStage!=General)
1082 return armature_importer.write_controller(controller);
1085 bool DocumentImporter::writeFormulas( const COLLADAFW::Formulas* formulas )
1090 bool DocumentImporter::writeKinematicsScene( const COLLADAFW::KinematicsScene* kinematicsScene )
1095 ExtraTags* DocumentImporter::getExtraTags(const COLLADAFW::UniqueId &uid)
1097 if(uid_tags_map.find(uid.toAscii())==uid_tags_map.end()) {
1100 return uid_tags_map[uid.toAscii()];
1103 bool DocumentImporter::addExtraTags( const COLLADAFW::UniqueId &uid, ExtraTags *extra_tags)
1105 uid_tags_map[uid.toAscii()] = extra_tags;