Blender V2.61 - r43446
|
00001 /* 00002 * ***** BEGIN GPL LICENSE BLOCK ***** 00003 * 00004 * This program is free software; you can redistribute it and/or 00005 * modify it under the terms of the GNU General Public License 00006 * as published by the Free Software Foundation; either version 2 00007 * of the License, or (at your option) any later version. 00008 * 00009 * This program is distributed in the hope that it will be useful, 00010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 * GNU General Public License for more details. 00013 * 00014 * You should have received a copy of the GNU General Public License 00015 * along with this program; if not, write to the Free Software Foundation, 00016 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00017 * 00018 * Contributor(s): Chingiz Dyussenov, Arystanbek Dyussenov, Nathan Letwory. 00019 * 00020 * ***** END GPL LICENSE BLOCK ***** 00021 */ 00022 00027 // TODO: 00028 // * name imported objects 00029 // * import object rotation as euler 00030 00031 #include <string> 00032 #include <map> 00033 #include <algorithm> // sort() 00034 00035 #include "COLLADAFWRoot.h" 00036 #include "COLLADAFWStableHeaders.h" 00037 #include "COLLADAFWColorOrTexture.h" 00038 #include "COLLADAFWIndexList.h" 00039 #include "COLLADAFWMeshPrimitiveWithFaceVertexCount.h" 00040 #include "COLLADAFWPolygons.h" 00041 #include "COLLADAFWSampler.h" 00042 #include "COLLADAFWTypes.h" 00043 #include "COLLADAFWVisualScene.h" 00044 #include "COLLADAFWArrayPrimitiveType.h" 00045 #include "COLLADAFWLibraryNodes.h" 00046 #include "COLLADAFWCamera.h" 00047 #include "COLLADAFWLight.h" 00048 00049 #include "COLLADASaxFWLLoader.h" 00050 #include "COLLADASaxFWLIExtraDataCallbackHandler.h" 00051 00052 #include "BLI_listbase.h" 00053 #include "BLI_math.h" 00054 #include "BLI_string.h" 00055 #include "BLI_utildefines.h" 00056 00057 #include "BKE_camera.h" 00058 #include "BKE_main.h" 00059 #include "BKE_lamp.h" 00060 #include "BKE_library.h" 00061 #include "BKE_texture.h" 00062 #include "BKE_fcurve.h" 00063 #include "BKE_depsgraph.h" 00064 #include "BLI_path_util.h" 00065 #include "BKE_scene.h" 00066 #include "BKE_global.h" 00067 #include "BKE_material.h" 00068 #include "BKE_utildefines.h" 00069 #include "BKE_image.h" 00070 00071 #include "DNA_camera_types.h" 00072 #include "DNA_lamp_types.h" 00073 00074 #include "RNA_access.h" 00075 00076 #include "MEM_guardedalloc.h" 00077 00078 #include "ExtraHandler.h" 00079 #include "ErrorHandler.h" 00080 #include "DocumentImporter.h" 00081 #include "TransformReader.h" 00082 00083 #include "collada_internal.h" 00084 #include "collada_utils.h" 00085 00086 00087 /* 00088 COLLADA Importer limitations: 00089 - no multiple scene import, all objects are added to active scene 00090 */ 00091 00092 // #define COLLADA_DEBUG 00093 // creates empties for each imported bone on layer 2, for debugging 00094 // #define ARMATURE_TEST 00095 00096 DocumentImporter::DocumentImporter(bContext *C, const char *filename) : 00097 mImportStage(General), 00098 mFilename(filename), 00099 mContext(C), 00100 armature_importer(&unit_converter, &mesh_importer, &anim_importer, CTX_data_scene(C)), 00101 mesh_importer(&unit_converter, &armature_importer, CTX_data_scene(C)), 00102 anim_importer(&unit_converter, &armature_importer, CTX_data_scene(C)) 00103 {} 00104 00105 DocumentImporter::~DocumentImporter() 00106 { 00107 TagsMap::iterator etit; 00108 etit = uid_tags_map.begin(); 00109 while(etit!=uid_tags_map.end()) { 00110 delete etit->second; 00111 etit++; 00112 } 00113 } 00114 00115 bool DocumentImporter::import() 00116 { 00117 ErrorHandler errorHandler; 00118 COLLADASaxFWL::Loader loader(&errorHandler); 00119 COLLADAFW::Root root(&loader, this); 00120 ExtraHandler *ehandler = new ExtraHandler(this, &(this->anim_importer)); 00121 00122 loader.registerExtraDataCallbackHandler(ehandler); 00123 00124 if (!root.loadDocument(mFilename)) 00125 return false; 00126 00127 if(errorHandler.hasError()) 00128 return false; 00129 00132 mImportStage = Controller; 00133 00134 COLLADASaxFWL::Loader loader2; 00135 COLLADAFW::Root root2(&loader2, this); 00136 00137 if (!root2.loadDocument(mFilename)) 00138 return false; 00139 00140 00141 delete ehandler; 00142 00143 return true; 00144 } 00145 00146 void DocumentImporter::cancel(const COLLADAFW::String& errorMessage) 00147 { 00148 // TODO: if possible show error info 00149 // 00150 // Should we get rid of invisible Meshes that were created so far 00151 // or maybe create objects at coordinate space origin? 00152 // 00153 // The latter sounds better. 00154 } 00155 00156 void DocumentImporter::start(){} 00157 00158 void DocumentImporter::finish() 00159 { 00160 if(mImportStage!=General) 00161 return; 00162 00164 std::vector<const COLLADAFW::VisualScene*>::iterator it; 00165 for (it = vscenes.begin(); it != vscenes.end(); it++) { 00166 PointerRNA sceneptr, unit_settings; 00167 PropertyRNA *system, *scale; 00168 // TODO: create a new scene except the selected <visual_scene> - use current blender scene for it 00169 Scene *sce = CTX_data_scene(mContext); 00170 00171 // for scene unit settings: system, scale_length 00172 RNA_id_pointer_create(&sce->id, &sceneptr); 00173 unit_settings = RNA_pointer_get(&sceneptr, "unit_settings"); 00174 system = RNA_struct_find_property(&unit_settings, "system"); 00175 scale = RNA_struct_find_property(&unit_settings, "scale_length"); 00176 00177 switch(unit_converter.isMetricSystem()) { 00178 case UnitConverter::Metric: 00179 RNA_property_enum_set(&unit_settings, system, USER_UNIT_METRIC); 00180 break; 00181 case UnitConverter::Imperial: 00182 RNA_property_enum_set(&unit_settings, system, USER_UNIT_IMPERIAL); 00183 break; 00184 default: 00185 RNA_property_enum_set(&unit_settings, system, USER_UNIT_NONE); 00186 break; 00187 } 00188 RNA_property_float_set(&unit_settings, scale, unit_converter.getLinearMeter()); 00189 00190 const COLLADAFW::NodePointerArray& roots = (*it)->getRootNodes(); 00191 00192 for (unsigned int i = 0; i < roots.getCount(); i++) { 00193 write_node(roots[i], NULL, sce, NULL, false); 00194 } 00195 } 00196 armature_importer.set_tags_map(this->uid_tags_map); 00197 armature_importer.make_armatures(mContext); 00198 00199 #if 0 00200 armature_importer.fix_animation(); 00201 #endif 00202 00203 for (std::vector<const COLLADAFW::VisualScene*>::iterator it = vscenes.begin(); it != vscenes.end(); it++) { 00204 const COLLADAFW::NodePointerArray& roots = (*it)->getRootNodes(); 00205 00206 for (unsigned int i = 0; i < roots.getCount(); i++) 00207 translate_anim_recursive(roots[i],NULL,NULL); 00208 } 00209 00210 if (libnode_ob.size()) { 00211 Scene *sce = CTX_data_scene(mContext); 00212 00213 fprintf(stderr, "got %d library nodes to free\n", (int)libnode_ob.size()); 00214 // free all library_nodes 00215 std::vector<Object*>::iterator it; 00216 for (it = libnode_ob.begin(); it != libnode_ob.end(); it++) { 00217 Object *ob = *it; 00218 00219 Base *base = object_in_scene(ob, sce); 00220 if (base) { 00221 BLI_remlink(&sce->base, base); 00222 free_libblock_us(&G.main->object, base->object); 00223 if (sce->basact==base) 00224 sce->basact= NULL; 00225 MEM_freeN(base); 00226 } 00227 } 00228 libnode_ob.clear(); 00229 00230 DAG_scene_sort(CTX_data_main(mContext), sce); 00231 DAG_ids_flush_update(CTX_data_main(mContext), 0); 00232 } 00233 } 00234 00235 00236 void DocumentImporter::translate_anim_recursive(COLLADAFW::Node *node, COLLADAFW::Node *par = NULL, Object *parob = NULL) 00237 { 00238 if (par && par->getType() == COLLADAFW::Node::JOINT) { 00239 // par is root if there's no corresp. key in root_map 00240 if (root_map.find(par->getUniqueId()) == root_map.end()) 00241 root_map[node->getUniqueId()] = par; 00242 else 00243 root_map[node->getUniqueId()] = root_map[par->getUniqueId()]; 00244 } 00245 00246 /*COLLADAFW::Transformation::TransformationType types[] = { 00247 COLLADAFW::Transformation::ROTATE, 00248 COLLADAFW::Transformation::SCALE, 00249 COLLADAFW::Transformation::TRANSLATE, 00250 COLLADAFW::Transformation::MATRIX 00251 }; 00252 00253 Object *ob;*/ 00254 unsigned int i; 00255 00256 //for (i = 0; i < 4; i++) 00257 //ob = 00258 anim_importer.translate_Animations(node, root_map, object_map, FW_object_map); 00259 00260 COLLADAFW::NodePointerArray &children = node->getChildNodes(); 00261 for (i = 0; i < children.getCount(); i++) { 00262 translate_anim_recursive(children[i], node, NULL); 00263 } 00264 } 00265 00268 bool DocumentImporter::writeGlobalAsset ( const COLLADAFW::FileInfo* asset ) 00269 { 00270 unit_converter.read_asset(asset); 00271 00272 return true; 00273 } 00274 00277 bool DocumentImporter::writeScene ( const COLLADAFW::Scene* scene ) 00278 { 00279 // XXX could store the scene id, but do nothing for now 00280 return true; 00281 } 00282 Object* DocumentImporter::create_camera_object(COLLADAFW::InstanceCamera *camera, Scene *sce) 00283 { 00284 const COLLADAFW::UniqueId& cam_uid = camera->getInstanciatedObjectId(); 00285 if (uid_camera_map.find(cam_uid) == uid_camera_map.end()) { 00286 fprintf(stderr, "Couldn't find camera by UID.\n"); 00287 return NULL; 00288 } 00289 Object *ob = add_object(sce, OB_CAMERA); 00290 Camera *cam = uid_camera_map[cam_uid]; 00291 Camera *old_cam = (Camera*)ob->data; 00292 ob->data = cam; 00293 old_cam->id.us--; 00294 if (old_cam->id.us == 0) 00295 free_libblock(&G.main->camera, old_cam); 00296 return ob; 00297 } 00298 00299 Object* DocumentImporter::create_lamp_object(COLLADAFW::InstanceLight *lamp, Scene *sce) 00300 { 00301 const COLLADAFW::UniqueId& lamp_uid = lamp->getInstanciatedObjectId(); 00302 if (uid_lamp_map.find(lamp_uid) == uid_lamp_map.end()) { 00303 fprintf(stderr, "Couldn't find lamp by UID. \n"); 00304 return NULL; 00305 } 00306 Object *ob = add_object(sce, OB_LAMP); 00307 Lamp *la = uid_lamp_map[lamp_uid]; 00308 Lamp *old_lamp = (Lamp*)ob->data; 00309 ob->data = la; 00310 old_lamp->id.us--; 00311 if (old_lamp->id.us == 0) 00312 free_libblock(&G.main->lamp, old_lamp); 00313 return ob; 00314 } 00315 00316 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) 00317 { 00318 Object *obn = copy_object(source_ob); 00319 obn->recalc |= OB_RECALC_OB|OB_RECALC_DATA|OB_RECALC_TIME; 00320 scene_add_base(sce, obn); 00321 00322 if (instance_node) { 00323 anim_importer.read_node_transform(instance_node, obn); 00324 // if we also have a source_node (always ;), take its 00325 // transformation matrix and apply it to the newly instantiated 00326 // object to account for node hierarchy transforms in 00327 // .dae 00328 if(source_node) { 00329 COLLADABU::Math::Matrix4 mat4 = source_node->getTransformationMatrix(); 00330 COLLADABU::Math::Matrix4 bmat4 = mat4.transpose(); // transpose to get blender row-major order 00331 float mat[4][4]; 00332 for (int i = 0; i < 4; i++) { 00333 for (int j = 0; j < 4; j++) { 00334 mat[i][j] = bmat4[i][j]; 00335 } 00336 } 00337 // calc new matrix and apply 00338 mult_m4_m4m4(obn->obmat, obn->obmat, mat); 00339 object_apply_mat4(obn, obn->obmat, 0, 0); 00340 } 00341 } 00342 else { 00343 anim_importer.read_node_transform(source_node, obn); 00344 } 00345 00346 DAG_scene_sort(CTX_data_main(mContext), sce); 00347 DAG_ids_flush_update(CTX_data_main(mContext), 0); 00348 00349 COLLADAFW::NodePointerArray &children = source_node->getChildNodes(); 00350 if (children.getCount()) { 00351 for (unsigned int i = 0; i < children.getCount(); i++) { 00352 COLLADAFW::Node *child_node = children[i]; 00353 const COLLADAFW::UniqueId& child_id = child_node->getUniqueId(); 00354 if (object_map.find(child_id) == object_map.end()) 00355 continue; 00356 COLLADAFW::InstanceNodePointerArray &inodes = child_node->getInstanceNodes(); 00357 Object *new_child = NULL; 00358 if (inodes.getCount()) { // \todo loop through instance nodes 00359 const COLLADAFW::UniqueId& id = inodes[0]->getInstanciatedObjectId(); 00360 new_child = create_instance_node(object_map[id], node_map[id], child_node, sce, NULL, is_library_node); 00361 } 00362 else { 00363 new_child = create_instance_node(object_map[child_id], child_node, NULL, sce, NULL, is_library_node); 00364 } 00365 bc_set_parent(new_child, obn, mContext, true); 00366 00367 if (is_library_node) 00368 libnode_ob.push_back(new_child); 00369 } 00370 } 00371 00372 // when we have an instance_node, don't return the object, because otherwise 00373 // its correct location gets overwritten in write_node(). Fixes bug #26012. 00374 if(instance_node) { 00375 if (par_ob && obn) 00376 bc_set_parent(obn, par_ob, mContext); 00377 return NULL; 00378 } 00379 00380 else return obn; 00381 } 00382 00383 void DocumentImporter::write_node (COLLADAFW::Node *node, COLLADAFW::Node *parent_node, Scene *sce, Object *par, bool is_library_node) 00384 { 00385 Object *ob = NULL; 00386 bool is_joint = node->getType() == COLLADAFW::Node::JOINT; 00387 00388 if (is_joint) { 00389 if ( par ) { 00390 Object * empty = par; 00391 par = add_object(sce, OB_ARMATURE); 00392 bc_set_parent(par,empty->parent, mContext); 00393 //remove empty : todo 00394 object_map[parent_node->getUniqueId()] = par; 00395 } 00396 armature_importer.add_joint(node, parent_node == NULL || parent_node->getType() != COLLADAFW::Node::JOINT, par, sce); 00397 } 00398 else { 00399 COLLADAFW::InstanceGeometryPointerArray &geom = node->getInstanceGeometries(); 00400 COLLADAFW::InstanceCameraPointerArray &camera = node->getInstanceCameras(); 00401 COLLADAFW::InstanceLightPointerArray &lamp = node->getInstanceLights(); 00402 COLLADAFW::InstanceControllerPointerArray &controller = node->getInstanceControllers(); 00403 COLLADAFW::InstanceNodePointerArray &inst_node = node->getInstanceNodes(); 00404 size_t geom_done = 0; 00405 size_t camera_done = 0; 00406 size_t lamp_done = 0; 00407 size_t controller_done = 0; 00408 size_t inst_done = 0; 00409 00410 // XXX linking object with the first <instance_geometry>, though a node may have more of them... 00411 // maybe join multiple <instance_...> meshes into 1, and link object with it? not sure... 00412 // <instance_geometry> 00413 while (geom_done < geom.getCount()) { 00414 ob = mesh_importer.create_mesh_object(node, geom[geom_done], false, uid_material_map, 00415 material_texture_mapping_map); 00416 ++geom_done; 00417 } 00418 while (camera_done < camera.getCount()) { 00419 ob = create_camera_object(camera[camera_done], sce); 00420 ++camera_done; 00421 } 00422 while (lamp_done < lamp.getCount()) { 00423 ob = create_lamp_object(lamp[lamp_done], sce); 00424 ++lamp_done; 00425 } 00426 while (controller_done < controller.getCount()) { 00427 COLLADAFW::InstanceGeometry *geom = (COLLADAFW::InstanceGeometry*)controller[controller_done]; 00428 ob = mesh_importer.create_mesh_object(node, geom, true, uid_material_map, material_texture_mapping_map); 00429 ++controller_done; 00430 } 00431 // XXX instance_node is not supported yet 00432 while (inst_done < inst_node.getCount()) { 00433 const COLLADAFW::UniqueId& node_id = inst_node[inst_done]->getInstanciatedObjectId(); 00434 if (object_map.find(node_id) == object_map.end()) { 00435 fprintf(stderr, "Cannot find node to instanciate.\n"); 00436 ob = NULL; 00437 } 00438 else { 00439 Object *source_ob = object_map[node_id]; 00440 COLLADAFW::Node *source_node = node_map[node_id]; 00441 00442 ob = create_instance_node(source_ob, source_node, node, sce, par, is_library_node); 00443 } 00444 ++inst_done; 00445 } 00446 // if node is empty - create empty object 00447 // XXX empty node may not mean it is empty object, not sure about this 00448 if ( (geom_done + camera_done + lamp_done + controller_done + inst_done) < 1) { 00449 ob = add_object(sce, OB_EMPTY); 00450 } 00451 00452 // check if object is not NULL 00453 if (!ob) return; 00454 00455 std::string nodename = node->getName().size() ? node->getName() : node->getOriginalId(); 00456 rename_id(&ob->id, (char*)nodename.c_str()); 00457 00458 object_map[node->getUniqueId()] = ob; 00459 node_map[node->getUniqueId()] = node; 00460 00461 if (is_library_node) 00462 libnode_ob.push_back(ob); 00463 } 00464 00465 anim_importer.read_node_transform(node, ob); // overwrites location set earlier 00466 00467 if (!is_joint) { 00468 // if par was given make this object child of the previous 00469 if (par && ob) 00470 bc_set_parent(ob, par, mContext); 00471 } 00472 00473 // if node has child nodes write them 00474 COLLADAFW::NodePointerArray &child_nodes = node->getChildNodes(); 00475 for (unsigned int i = 0; i < child_nodes.getCount(); i++) { 00476 write_node(child_nodes[i], node, sce, ob, is_library_node); 00477 } 00478 } 00479 00482 bool DocumentImporter::writeVisualScene ( const COLLADAFW::VisualScene* visualScene ) 00483 { 00484 if(mImportStage!=General) 00485 return true; 00486 00487 // this method called on post process after writeGeometry, writeMaterial, etc. 00488 00489 // for each <node> in <visual_scene>: 00490 // create an Object 00491 // if Mesh (previously created in writeGeometry) to which <node> corresponds exists, link Object with that mesh 00492 00493 // update: since we cannot link a Mesh with Object in 00494 // writeGeometry because <geometry> does not reference <node>, 00495 // we link Objects with Meshes here 00496 00497 vscenes.push_back(visualScene); 00498 00499 return true; 00500 } 00501 00505 bool DocumentImporter::writeLibraryNodes ( const COLLADAFW::LibraryNodes* libraryNodes ) 00506 { 00507 if(mImportStage!=General) 00508 return true; 00509 00510 Scene *sce = CTX_data_scene(mContext); 00511 00512 const COLLADAFW::NodePointerArray& nodes = libraryNodes->getNodes(); 00513 00514 for (unsigned int i = 0; i < nodes.getCount(); i++) { 00515 write_node(nodes[i], NULL, sce, NULL, true); 00516 } 00517 00518 return true; 00519 } 00520 00523 bool DocumentImporter::writeGeometry ( const COLLADAFW::Geometry* geom ) 00524 { 00525 if(mImportStage!=General) 00526 return true; 00527 00528 return mesh_importer.write_geometry(geom); 00529 } 00530 00533 bool DocumentImporter::writeMaterial( const COLLADAFW::Material* cmat ) 00534 { 00535 if(mImportStage!=General) 00536 return true; 00537 00538 const std::string& str_mat_id = cmat->getName().size() ? cmat->getName() : cmat->getOriginalId(); 00539 Material *ma = add_material((char*)str_mat_id.c_str()); 00540 00541 this->uid_effect_map[cmat->getInstantiatedEffect()] = ma; 00542 this->uid_material_map[cmat->getUniqueId()] = ma; 00543 00544 return true; 00545 } 00546 00547 // create mtex, create texture, set texture image 00548 MTex* DocumentImporter::create_texture(COLLADAFW::EffectCommon *ef, COLLADAFW::Texture &ctex, Material *ma, 00549 int i, TexIndexTextureArrayMap &texindex_texarray_map) 00550 { 00551 COLLADAFW::SamplerPointerArray& samp_array = ef->getSamplerPointerArray(); 00552 COLLADAFW::Sampler *sampler = samp_array[ctex.getSamplerId()]; 00553 00554 const COLLADAFW::UniqueId& ima_uid = sampler->getSourceImage(); 00555 00556 if (uid_image_map.find(ima_uid) == uid_image_map.end()) { 00557 fprintf(stderr, "Couldn't find an image by UID.\n"); 00558 return NULL; 00559 } 00560 00561 ma->mtex[i] = add_mtex(); 00562 ma->mtex[i]->texco = TEXCO_UV; 00563 ma->mtex[i]->tex = add_texture("Texture"); 00564 ma->mtex[i]->tex->type = TEX_IMAGE; 00565 ma->mtex[i]->tex->imaflag &= ~TEX_USEALPHA; 00566 ma->mtex[i]->tex->ima = uid_image_map[ima_uid]; 00567 00568 texindex_texarray_map[ctex.getTextureMapId()].push_back(ma->mtex[i]); 00569 00570 return ma->mtex[i]; 00571 } 00572 00573 void DocumentImporter::write_profile_COMMON(COLLADAFW::EffectCommon *ef, Material *ma) 00574 { 00575 COLLADAFW::EffectCommon::ShaderType shader = ef->getShaderType(); 00576 00577 // blinn 00578 if (shader == COLLADAFW::EffectCommon::SHADER_BLINN) { 00579 ma->spec_shader = MA_SPEC_BLINN; 00580 ma->spec = ef->getShininess().getFloatValue(); 00581 } 00582 // phong 00583 else if (shader == COLLADAFW::EffectCommon::SHADER_PHONG) { 00584 ma->spec_shader = MA_SPEC_PHONG; 00585 ma->har = ef->getShininess().getFloatValue(); 00586 } 00587 // lambert 00588 else if (shader == COLLADAFW::EffectCommon::SHADER_LAMBERT) { 00589 ma->diff_shader = MA_DIFF_LAMBERT; 00590 } 00591 // default - lambert 00592 else { 00593 ma->diff_shader = MA_DIFF_LAMBERT; 00594 fprintf(stderr, "Current shader type is not supported, default to lambert.\n"); 00595 } 00596 // reflectivity 00597 ma->ray_mirror = ef->getReflectivity().getFloatValue(); 00598 // index of refraction 00599 ma->ang = ef->getIndexOfRefraction().getFloatValue(); 00600 00601 int i = 0; 00602 COLLADAFW::Color col; 00603 MTex *mtex = NULL; 00604 TexIndexTextureArrayMap texindex_texarray_map; 00605 00606 // DIFFUSE 00607 // color 00608 if (ef->getDiffuse().isColor()) { 00609 col = ef->getDiffuse().getColor(); 00610 ma->r = col.getRed(); 00611 ma->g = col.getGreen(); 00612 ma->b = col.getBlue(); 00613 } 00614 // texture 00615 else if (ef->getDiffuse().isTexture()) { 00616 COLLADAFW::Texture ctex = ef->getDiffuse().getTexture(); 00617 mtex = create_texture(ef, ctex, ma, i, texindex_texarray_map); 00618 if (mtex != NULL) { 00619 mtex->mapto = MAP_COL; 00620 ma->texact = (int)i; 00621 i++; 00622 } 00623 } 00624 // AMBIENT 00625 // color 00626 if (ef->getAmbient().isColor()) { 00627 col = ef->getAmbient().getColor(); 00628 ma->ambr = col.getRed(); 00629 ma->ambg = col.getGreen(); 00630 ma->ambb = col.getBlue(); 00631 } 00632 // texture 00633 else if (ef->getAmbient().isTexture()) { 00634 COLLADAFW::Texture ctex = ef->getAmbient().getTexture(); 00635 mtex = create_texture(ef, ctex, ma, i, texindex_texarray_map); 00636 if (mtex != NULL) { 00637 mtex->mapto = MAP_AMB; 00638 i++; 00639 } 00640 } 00641 // SPECULAR 00642 // color 00643 if (ef->getSpecular().isColor()) { 00644 col = ef->getSpecular().getColor(); 00645 ma->specr = col.getRed(); 00646 ma->specg = col.getGreen(); 00647 ma->specb = col.getBlue(); 00648 } 00649 // texture 00650 else if (ef->getSpecular().isTexture()) { 00651 COLLADAFW::Texture ctex = ef->getSpecular().getTexture(); 00652 mtex = create_texture(ef, ctex, ma, i, texindex_texarray_map); 00653 if (mtex != NULL) { 00654 mtex->mapto = MAP_SPEC; 00655 i++; 00656 } 00657 } 00658 // REFLECTIVE 00659 // color 00660 if (ef->getReflective().isColor()) { 00661 col = ef->getReflective().getColor(); 00662 ma->mirr = col.getRed(); 00663 ma->mirg = col.getGreen(); 00664 ma->mirb = col.getBlue(); 00665 } 00666 // texture 00667 else if (ef->getReflective().isTexture()) { 00668 COLLADAFW::Texture ctex = ef->getReflective().getTexture(); 00669 mtex = create_texture(ef, ctex, ma, i, texindex_texarray_map); 00670 if (mtex != NULL) { 00671 mtex->mapto = MAP_REF; 00672 i++; 00673 } 00674 } 00675 // EMISSION 00676 // color 00677 if (ef->getEmission().isColor()) { 00678 // XXX there is no emission color in blender 00679 // but I am not sure 00680 } 00681 // texture 00682 else if (ef->getEmission().isTexture()) { 00683 COLLADAFW::Texture ctex = ef->getEmission().getTexture(); 00684 mtex = create_texture(ef, ctex, ma, i, texindex_texarray_map); 00685 if (mtex != NULL) { 00686 mtex->mapto = MAP_EMIT; 00687 i++; 00688 } 00689 } 00690 00691 if(ef->getOpacity().isTexture()) { 00692 COLLADAFW::Texture ctex = ef->getOpacity().getTexture(); 00693 mtex = create_texture(ef, ctex, ma, i, texindex_texarray_map); 00694 if(mtex != NULL) { 00695 mtex->mapto = MAP_ALPHA; 00696 mtex->tex->imaflag |= TEX_USEALPHA; 00697 i++; 00698 ma->spectra = ma->alpha = 0; 00699 ma->mode |= MA_ZTRANSP|MA_TRANSP; 00700 } 00701 } 00702 // TRANSPARENT 00703 // color 00704 // if (ef->getOpacity().isColor()) { 00705 // // XXX don't know what to do here 00706 // } 00707 // // texture 00708 // else if (ef->getOpacity().isTexture()) { 00709 // ctex = ef->getOpacity().getTexture(); 00710 // if (mtex != NULL) mtex->mapto &= MAP_ALPHA; 00711 // else { 00712 // mtex = create_texture(ef, ctex, ma, i, texindex_texarray_map); 00713 // if (mtex != NULL) mtex->mapto = MAP_ALPHA; 00714 // } 00715 // } 00716 material_texture_mapping_map[ma] = texindex_texarray_map; 00717 } 00718 00722 bool DocumentImporter::writeEffect( const COLLADAFW::Effect* effect ) 00723 { 00724 if(mImportStage!=General) 00725 return true; 00726 00727 const COLLADAFW::UniqueId& uid = effect->getUniqueId(); 00728 00729 if (uid_effect_map.find(uid) == uid_effect_map.end()) { 00730 fprintf(stderr, "Couldn't find a material by UID.\n"); 00731 return true; 00732 } 00733 00734 Material *ma = uid_effect_map[uid]; 00735 std::map<COLLADAFW::UniqueId, Material*>::iterator iter; 00736 for(iter = uid_material_map.begin(); iter != uid_material_map.end() ; iter++ ) 00737 { 00738 if ( iter->second == ma ) { 00739 this->FW_object_map[iter->first] = effect; 00740 break; 00741 } 00742 } 00743 COLLADAFW::CommonEffectPointerArray common_efs = effect->getCommonEffects(); 00744 if (common_efs.getCount() < 1) { 00745 fprintf(stderr, "Couldn't find <profile_COMMON>.\n"); 00746 return true; 00747 } 00748 // XXX TODO: Take all <profile_common>s 00749 // Currently only first <profile_common> is supported 00750 COLLADAFW::EffectCommon *ef = common_efs[0]; 00751 write_profile_COMMON(ef, ma); 00752 this->FW_object_map[effect->getUniqueId()] = effect; 00753 00754 return true; 00755 } 00756 00757 00760 bool DocumentImporter::writeCamera( const COLLADAFW::Camera* camera ) 00761 { 00762 if(mImportStage!=General) 00763 return true; 00764 00765 Camera *cam = NULL; 00766 std::string cam_id, cam_name; 00767 00768 cam_id = camera->getOriginalId(); 00769 cam_name = camera->getName(); 00770 if (cam_name.size()) cam = (Camera*)add_camera((char*)cam_name.c_str()); 00771 else cam = (Camera*)add_camera((char*)cam_id.c_str()); 00772 00773 if (!cam) { 00774 fprintf(stderr, "Cannot create camera. \n"); 00775 return true; 00776 } 00777 cam->clipsta = camera->getNearClippingPlane().getValue(); 00778 cam->clipend = camera->getFarClippingPlane().getValue(); 00779 00780 COLLADAFW::Camera::CameraType type = camera->getCameraType(); 00781 switch(type) { 00782 case COLLADAFW::Camera::ORTHOGRAPHIC: 00783 { 00784 cam->type = CAM_ORTHO; 00785 } 00786 break; 00787 case COLLADAFW::Camera::PERSPECTIVE: 00788 { 00789 cam->type = CAM_PERSP; 00790 } 00791 break; 00792 case COLLADAFW::Camera::UNDEFINED_CAMERATYPE: 00793 { 00794 fprintf(stderr, "Current camera type is not supported. \n"); 00795 cam->type = CAM_PERSP; 00796 } 00797 break; 00798 } 00799 00800 switch(camera->getDescriptionType()) { 00801 case COLLADAFW::Camera::ASPECTRATIO_AND_Y: 00802 { 00803 switch(cam->type) { 00804 case CAM_ORTHO: 00805 { 00806 double ymag = camera->getYMag().getValue(); 00807 double aspect = camera->getAspectRatio().getValue(); 00808 double xmag = aspect*ymag; 00809 cam->ortho_scale = (float)xmag; 00810 } 00811 break; 00812 case CAM_PERSP: 00813 default: 00814 { 00815 double yfov = camera->getYFov().getValue(); 00816 double aspect = camera->getAspectRatio().getValue(); 00817 double xfov = aspect*yfov; 00818 // xfov is in degrees, cam->lens is in millimiters 00819 cam->lens = fov_to_focallength(DEG2RADF(xfov), cam->sensor_x); 00820 } 00821 break; 00822 } 00823 } 00824 break; 00825 /* XXX correct way to do following four is probably to get also render 00826 size and determine proper settings from that somehow */ 00827 case COLLADAFW::Camera::ASPECTRATIO_AND_X: 00828 case COLLADAFW::Camera::SINGLE_X: 00829 case COLLADAFW::Camera::X_AND_Y: 00830 { 00831 switch(cam->type) { 00832 case CAM_ORTHO: 00833 cam->ortho_scale = (float)camera->getXMag().getValue(); 00834 break; 00835 case CAM_PERSP: 00836 default: 00837 { 00838 double x = camera->getXFov().getValue(); 00839 // x is in degrees, cam->lens is in millimiters 00840 cam->lens = fov_to_focallength(DEG2RADF(x), cam->sensor_x); 00841 } 00842 break; 00843 } 00844 } 00845 break; 00846 case COLLADAFW::Camera::SINGLE_Y: 00847 { 00848 switch(cam->type) { 00849 case CAM_ORTHO: 00850 cam->ortho_scale = (float)camera->getYMag().getValue(); 00851 break; 00852 case CAM_PERSP: 00853 default: 00854 { 00855 double yfov = camera->getYFov().getValue(); 00856 // yfov is in degrees, cam->lens is in millimiters 00857 cam->lens = fov_to_focallength(DEG2RADF(yfov), cam->sensor_x); 00858 } 00859 break; 00860 } 00861 } 00862 break; 00863 case COLLADAFW::Camera::UNDEFINED: 00864 // read nothing, use blender defaults. 00865 break; 00866 } 00867 00868 this->uid_camera_map[camera->getUniqueId()] = cam; 00869 this->FW_object_map[camera->getUniqueId()] = camera; 00870 // XXX import camera options 00871 return true; 00872 } 00873 00876 bool DocumentImporter::writeImage( const COLLADAFW::Image* image ) 00877 { 00878 if(mImportStage!=General) 00879 return true; 00880 00881 // XXX maybe it is necessary to check if the path is absolute or relative 00882 const std::string& filepath = image->getImageURI().toNativePath(); 00883 const char *filename = (const char*)mFilename.c_str(); 00884 char dir[FILE_MAX]; 00885 char full_path[FILE_MAX]; 00886 00887 BLI_split_dir_part(filename, dir, sizeof(dir)); 00888 BLI_join_dirfile(full_path, sizeof(full_path), dir, filepath.c_str()); 00889 Image *ima = BKE_add_image_file(full_path); 00890 if (!ima) { 00891 fprintf(stderr, "Cannot create image. \n"); 00892 return true; 00893 } 00894 this->uid_image_map[image->getUniqueId()] = ima; 00895 00896 return true; 00897 } 00898 00901 bool DocumentImporter::writeLight( const COLLADAFW::Light* light ) 00902 { 00903 if(mImportStage!=General) 00904 return true; 00905 00906 Lamp *lamp = NULL; 00907 std::string la_id, la_name; 00908 00909 TagsMap::iterator etit; 00910 ExtraTags *et = 0; 00911 etit = uid_tags_map.find(light->getUniqueId().toAscii()); 00912 if(etit != uid_tags_map.end()) 00913 et = etit->second; 00914 00915 la_id = light->getOriginalId(); 00916 la_name = light->getName(); 00917 if (la_name.size()) lamp = (Lamp*)add_lamp((char*)la_name.c_str()); 00918 else lamp = (Lamp*)add_lamp((char*)la_id.c_str()); 00919 00920 if (!lamp) { 00921 fprintf(stderr, "Cannot create lamp. \n"); 00922 return true; 00923 } 00924 00925 // if we find an ExtraTags for this, use that instead. 00926 if(et && et->isProfile("blender")) { 00927 et->setData("type", &(lamp->type)); 00928 et->setData("flag", &(lamp->flag)); 00929 et->setData("mode", &(lamp->mode)); 00930 et->setData("gamma", &(lamp->k)); 00931 et->setData("red", &(lamp->r)); 00932 et->setData("green", &(lamp->g)); 00933 et->setData("blue", &(lamp->b)); 00934 et->setData("shadow_r", &(lamp->shdwr)); 00935 et->setData("shadow_g", &(lamp->shdwg)); 00936 et->setData("shadow_b", &(lamp->shdwb)); 00937 et->setData("energy", &(lamp->energy)); 00938 et->setData("dist", &(lamp->dist)); 00939 et->setData("spotsize", &(lamp->spotsize)); 00940 et->setData("spotblend", &(lamp->spotblend)); 00941 et->setData("halo_intensity", &(lamp->haint)); 00942 et->setData("att1", &(lamp->att1)); 00943 et->setData("att2", &(lamp->att2)); 00944 et->setData("falloff_type", &(lamp->falloff_type)); 00945 et->setData("clipsta", &(lamp->clipsta)); 00946 et->setData("clipend", &(lamp->clipend)); 00947 et->setData("shadspotsize", &(lamp->shadspotsize)); 00948 et->setData("bias", &(lamp->bias)); 00949 et->setData("soft", &(lamp->soft)); 00950 et->setData("compressthresh", &(lamp->compressthresh)); 00951 et->setData("bufsize", &(lamp->bufsize)); 00952 et->setData("samp", &(lamp->samp)); 00953 et->setData("buffers", &(lamp->buffers)); 00954 et->setData("filtertype", &(lamp->filtertype)); 00955 et->setData("bufflag", &(lamp->bufflag)); 00956 et->setData("buftype", &(lamp->buftype)); 00957 et->setData("ray_samp", &(lamp->ray_samp)); 00958 et->setData("ray_sampy", &(lamp->ray_sampy)); 00959 et->setData("ray_sampz", &(lamp->ray_sampz)); 00960 et->setData("ray_samp_type", &(lamp->ray_samp_type)); 00961 et->setData("area_shape", &(lamp->area_shape)); 00962 et->setData("area_size", &(lamp->area_size)); 00963 et->setData("area_sizey", &(lamp->area_sizey)); 00964 et->setData("area_sizez", &(lamp->area_sizez)); 00965 et->setData("adapt_thresh", &(lamp->adapt_thresh)); 00966 et->setData("ray_samp_method", &(lamp->ray_samp_method)); 00967 et->setData("shadhalostep", &(lamp->shadhalostep)); 00968 et->setData("sun_effect_type", &(lamp->shadhalostep)); 00969 et->setData("skyblendtype", &(lamp->skyblendtype)); 00970 et->setData("horizon_brightness", &(lamp->horizon_brightness)); 00971 et->setData("spread", &(lamp->spread)); 00972 et->setData("sun_brightness", &(lamp->sun_brightness)); 00973 et->setData("sun_size", &(lamp->sun_size)); 00974 et->setData("backscattered_light", &(lamp->backscattered_light)); 00975 et->setData("sun_intensity", &(lamp->sun_intensity)); 00976 et->setData("atm_turbidity", &(lamp->atm_turbidity)); 00977 et->setData("atm_extinction_factor", &(lamp->atm_extinction_factor)); 00978 et->setData("atm_distance_factor", &(lamp->atm_distance_factor)); 00979 et->setData("skyblendfac", &(lamp->skyblendfac)); 00980 et->setData("sky_exposure", &(lamp->sky_exposure)); 00981 et->setData("sky_colorspace", &(lamp->sky_colorspace)); 00982 } 00983 else { 00984 float constatt = light->getConstantAttenuation().getValue(); 00985 float linatt = light->getLinearAttenuation().getValue(); 00986 float quadatt = light->getQuadraticAttenuation().getValue(); 00987 float d = 25.0f; 00988 float att1 = 0.0f; 00989 float att2 = 0.0f; 00990 float e = 1.0f; 00991 00992 if (light->getColor().isValid()) { 00993 COLLADAFW::Color col = light->getColor(); 00994 lamp->r = col.getRed(); 00995 lamp->g = col.getGreen(); 00996 lamp->b = col.getBlue(); 00997 } 00998 00999 if(IS_EQ(linatt, 0.0f) && quadatt > 0.0f) { 01000 att2 = quadatt; 01001 d = sqrt(1.0f/quadatt); 01002 } 01003 // linear light 01004 else if(IS_EQ(quadatt, 0.0f) && linatt > 0.0f) { 01005 att1 = linatt; 01006 d = (1.0f/linatt); 01007 } else if (IS_EQ(constatt, 1.0f)) { 01008 att1 = 1.0f; 01009 } else { 01010 // assuming point light (const att = 1.0); 01011 att1 = 1.0f; 01012 } 01013 01014 d *= ( 1.0f / unit_converter.getLinearMeter()); 01015 01016 lamp->energy = e; 01017 lamp->dist = d; 01018 01019 COLLADAFW::Light::LightType type = light->getLightType(); 01020 switch(type) { 01021 case COLLADAFW::Light::AMBIENT_LIGHT: 01022 { 01023 lamp->type = LA_HEMI; 01024 } 01025 break; 01026 case COLLADAFW::Light::SPOT_LIGHT: 01027 { 01028 lamp->type = LA_SPOT; 01029 lamp->att1 = att1; 01030 lamp->att2 = att2; 01031 if(IS_EQ(att1, 0.0f) && att2 > 0) 01032 lamp->falloff_type = LA_FALLOFF_INVSQUARE; 01033 if(IS_EQ(att2, 0.0f) && att1 > 0) 01034 lamp->falloff_type = LA_FALLOFF_INVLINEAR; 01035 lamp->spotsize = light->getFallOffAngle().getValue(); 01036 lamp->spotblend = light->getFallOffExponent().getValue(); 01037 } 01038 break; 01039 case COLLADAFW::Light::DIRECTIONAL_LIGHT: 01040 { 01041 /* our sun is very strong, so pick a smaller energy level */ 01042 lamp->type = LA_SUN; 01043 lamp->mode |= LA_NO_SPEC; 01044 } 01045 break; 01046 case COLLADAFW::Light::POINT_LIGHT: 01047 { 01048 lamp->type = LA_LOCAL; 01049 lamp->att1 = att1; 01050 lamp->att2 = att2; 01051 if(IS_EQ(att1, 0.0f) && att2 > 0) 01052 lamp->falloff_type = LA_FALLOFF_INVSQUARE; 01053 if(IS_EQ(att2, 0.0f) && att1 > 0) 01054 lamp->falloff_type = LA_FALLOFF_INVLINEAR; 01055 } 01056 break; 01057 case COLLADAFW::Light::UNDEFINED: 01058 { 01059 fprintf(stderr, "Current lamp type is not supported. \n"); 01060 lamp->type = LA_LOCAL; 01061 } 01062 break; 01063 } 01064 } 01065 01066 this->uid_lamp_map[light->getUniqueId()] = lamp; 01067 this->FW_object_map[light->getUniqueId()] = light; 01068 return true; 01069 } 01070 01071 // this function is called only for animations that pass COLLADAFW::validate 01072 bool DocumentImporter::writeAnimation( const COLLADAFW::Animation* anim ) 01073 { 01074 if(mImportStage!=General) 01075 return true; 01076 01077 // return true; 01078 return anim_importer.write_animation(anim); 01079 } 01080 01081 // called on post-process stage after writeVisualScenes 01082 bool DocumentImporter::writeAnimationList( const COLLADAFW::AnimationList* animationList ) 01083 { 01084 if(mImportStage!=General) 01085 return true; 01086 01087 // return true; 01088 return anim_importer.write_animation_list(animationList); 01089 } 01090 01093 bool DocumentImporter::writeSkinControllerData( const COLLADAFW::SkinControllerData* skin ) 01094 { 01095 return armature_importer.write_skin_controller_data(skin); 01096 } 01097 01098 // this is called on postprocess, before writeVisualScenes 01099 bool DocumentImporter::writeController( const COLLADAFW::Controller* controller ) 01100 { 01101 if(mImportStage!=General) 01102 return true; 01103 01104 return armature_importer.write_controller(controller); 01105 } 01106 01107 bool DocumentImporter::writeFormulas( const COLLADAFW::Formulas* formulas ) 01108 { 01109 return true; 01110 } 01111 01112 bool DocumentImporter::writeKinematicsScene( const COLLADAFW::KinematicsScene* kinematicsScene ) 01113 { 01114 return true; 01115 } 01116 01117 ExtraTags* DocumentImporter::getExtraTags(const COLLADAFW::UniqueId &uid) 01118 { 01119 if(uid_tags_map.find(uid.toAscii())==uid_tags_map.end()) { 01120 return NULL; 01121 } 01122 return uid_tags_map[uid.toAscii()]; 01123 } 01124 01125 bool DocumentImporter::addExtraTags( const COLLADAFW::UniqueId &uid, ExtraTags *extra_tags) 01126 { 01127 uid_tags_map[uid.toAscii()] = extra_tags; 01128 return true; 01129 } 01130