From c43dfddb655d7ad8b8b4b1cd874e533719dc4463 Mon Sep 17 00:00:00 2001 From: Juan Linietsky Date: Wed, 22 Apr 2015 23:29:03 -0300 Subject: Changed collada importer to properly handle ALL blend shape arrays, fixes problems with animated normals, uvs, etc. --- tools/editor/io_plugins/editor_import_collada.cpp | 81 +++++++++++++++++++---- 1 file changed, 67 insertions(+), 14 deletions(-) (limited to 'tools') diff --git a/tools/editor/io_plugins/editor_import_collada.cpp b/tools/editor/io_plugins/editor_import_collada.cpp index ca2d008206..d7e883ef62 100644 --- a/tools/editor/io_plugins/editor_import_collada.cpp +++ b/tools/editor/io_plugins/editor_import_collada.cpp @@ -84,7 +84,7 @@ struct ColladaImport { Error _create_scene(Collada::Node *p_node, Spatial *p_parent); Error _create_resources(Collada::Node *p_node); Error _create_material(const String& p_material); - Error _create_mesh_surfaces(Ref& p_mesh,const Map& p_material_map,const Collada::MeshData &meshdata,const Transform& p_local_xform,const Vector &bone_remap, const Collada::SkinControllerData *p_skin_data, const Collada::MorphControllerData *p_morph_data); + Error _create_mesh_surfaces(bool p_optimize,Ref& p_mesh,const Map& p_material_map,const Collada::MeshData &meshdata,const Transform& p_local_xform,const Vector &bone_remap, const Collada::SkinControllerData *p_skin_data, const Collada::MorphControllerData *p_morph_data,Vector > p_morph_meshes=Vector >()); Error load(const String& p_path, int p_flags, bool p_force_make_tangents=false); void _fix_param_animation_tracks(); void create_animation(int p_clip,bool p_make_tracks_in_all_bones); @@ -589,7 +589,7 @@ static void _generate_tangents_and_binormals(const DVector& p_indices,const } } -Error ColladaImport::_create_mesh_surfaces(Ref& p_mesh,const Map& p_material_map,const Collada::MeshData &meshdata,const Transform& p_local_xform,const Vector &bone_remap, const Collada::SkinControllerData *skin_controller, const Collada::MorphControllerData *p_morph_data) { +Error ColladaImport::_create_mesh_surfaces(bool p_optimize,Ref& p_mesh,const Map& p_material_map,const Collada::MeshData &meshdata,const Transform& p_local_xform,const Vector &bone_remap, const Collada::SkinControllerData *skin_controller, const Collada::MorphControllerData *p_morph_data,Vector > p_morph_meshes) { bool local_xform_mirror=p_local_xform.basis.determinant() < 0; @@ -750,7 +750,7 @@ Error ColladaImport::_create_mesh_surfaces(Ref& p_mesh,const Map& p_mesh,const Map& p_mesh,const Map::Write(); DVector normals; DVector tangents; + print_line("vertex source id: "+vertex_src_id); if(md.vertices[vertex_src_id].sources.has("NORMAL")){ //has normals normals.resize(vlen); @@ -1409,7 +1410,9 @@ Error ColladaImport::_create_mesh_surfaces(Ref& p_mesh,const Map& p_mesh,const Mapget_surface_count())); + Array a = p_morph_meshes[mi]->surface_get_arrays(surface); + a[Mesh::ARRAY_BONES]=Variant(); + a[Mesh::ARRAY_WEIGHTS]=Variant(); + a[Mesh::ARRAY_INDEX]=Variant(); + //a.resize(Mesh::ARRAY_MAX); //no need for index + mr.push_back(a); + } p_mesh->add_surface(Mesh::PRIMITIVE_TRIANGLES,d,mr); @@ -1566,17 +1580,21 @@ Error ColladaImport::_create_resources(Collada::Node *p_node) { String meshid; Transform apply_xform; Vector bone_remap; + Vector > morphs; print_line("mesh: "+String(mi->get_name())); if (ng->controller) { print_line("has controller"); - if (collada.state.skin_controller_data_map.has(ng->source)) { + + String ngsource = ng->source; + + if (collada.state.skin_controller_data_map.has(ngsource)) { - ERR_FAIL_COND_V(!collada.state.skin_controller_data_map.has(ng->source),ERR_INVALID_DATA); - skin=&collada.state.skin_controller_data_map[ng->source]; + ERR_FAIL_COND_V(!collada.state.skin_controller_data_map.has(ngsource),ERR_INVALID_DATA); + skin=&collada.state.skin_controller_data_map[ngsource]; Vector skeletons = ng->skeletons; @@ -1598,8 +1616,10 @@ Error ColladaImport::_create_resources(Collada::Node *p_node) { if (collada.state.morph_controller_data_map.has(meshid)) { //it's a morph!! - morph = &collada.state.morph_controller_data_map[meshid]; + ngsource=meshid; meshid=morph->mesh; + } else { + ngsource=""; } if (apply_mesh_xform_to_vertices) { @@ -1630,15 +1650,48 @@ Error ColladaImport::_create_resources(Collada::Node *p_node) { ERR_FAIL_COND_V( !bone_remap_map.has(str), ERR_INVALID_DATA ); bone_remap[i]=bone_remap_map[str]; } - } else if (collada.state.morph_controller_data_map.has(ng->source)) { - print_line("is morph "+ng->source); + } + + if (collada.state.morph_controller_data_map.has(ngsource)) { + print_line("is morph "+ngsource); //it's a morph!! - morph = &collada.state.morph_controller_data_map[ng->source]; + morph = &collada.state.morph_controller_data_map[ngsource]; meshid=morph->mesh; printf("KKmorph: %p\n",morph); print_line("morph mshid: "+meshid); - } else { - ERR_EXPLAIN("Controller Instance Source '"+ng->source+"' is neither skin or morph!"); + + Vector targets; + + morph->targets.has("MORPH_TARGET"); + String target = morph->targets["MORPH_TARGET"]; + bool valid=false; + if (morph->sources.has(target)) { + valid=true; + Vector names = morph->sources[target].sarray; + for(int i=0;i mesh=Ref(memnew( Mesh )); + const Collada::MeshData &meshdata = collada.state.mesh_data_map[meshid]; + Error err = _create_mesh_surfaces(false,mesh,ng->material_map,meshdata,apply_xform,bone_remap,skin,NULL); + ERR_FAIL_COND_V(err,err); + + morphs.push_back(mesh); + } else { + valid=false; + } + } + } + + if (!valid) + morphs.clear(); + + ngsource=""; + } + + if (ngsource!=""){ + ERR_EXPLAIN("Controller Instance Source '"+ngsource+"' is neither skin or morph!"); ERR_FAIL_V( ERR_INVALID_DATA ); } @@ -1659,7 +1712,7 @@ Error ColladaImport::_create_resources(Collada::Node *p_node) { mesh=Ref(memnew( Mesh )); const Collada::MeshData &meshdata = collada.state.mesh_data_map[meshid]; mesh->set_name( meshdata.name ); - Error err = _create_mesh_surfaces(mesh,ng->material_map,meshdata,apply_xform,bone_remap,skin,morph); + Error err = _create_mesh_surfaces(morphs.size()==0,mesh,ng->material_map,meshdata,apply_xform,bone_remap,skin,morph,morphs); ERR_FAIL_COND_V(err,err); mesh_cache[meshid]=mesh; -- cgit v1.2.3