Changed collada importer to properly handle ALL blend shape arrays, fixes problems with animated normals, uvs, etc.

This commit is contained in:
Juan Linietsky 2015-04-22 23:29:03 -03:00
parent 66c71c21df
commit c43dfddb65

View file

@ -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<Mesh>& p_mesh,const Map<String,Collada::NodeGeometry::Material>& p_material_map,const Collada::MeshData &meshdata,const Transform& p_local_xform,const Vector<int> &bone_remap, const Collada::SkinControllerData *p_skin_data, const Collada::MorphControllerData *p_morph_data);
Error _create_mesh_surfaces(bool p_optimize,Ref<Mesh>& p_mesh,const Map<String,Collada::NodeGeometry::Material>& p_material_map,const Collada::MeshData &meshdata,const Transform& p_local_xform,const Vector<int> &bone_remap, const Collada::SkinControllerData *p_skin_data, const Collada::MorphControllerData *p_morph_data,Vector<Ref<Mesh> > p_morph_meshes=Vector<Ref<Mesh> >());
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<int>& p_indices,const
}
}
Error ColladaImport::_create_mesh_surfaces(Ref<Mesh>& p_mesh,const Map<String,Collada::NodeGeometry::Material>& p_material_map,const Collada::MeshData &meshdata,const Transform& p_local_xform,const Vector<int> &bone_remap, const Collada::SkinControllerData *skin_controller, const Collada::MorphControllerData *p_morph_data) {
Error ColladaImport::_create_mesh_surfaces(bool p_optimize,Ref<Mesh>& p_mesh,const Map<String,Collada::NodeGeometry::Material>& p_material_map,const Collada::MeshData &meshdata,const Transform& p_local_xform,const Vector<int> &bone_remap, const Collada::SkinControllerData *skin_controller, const Collada::MorphControllerData *p_morph_data,Vector<Ref<Mesh> > p_morph_meshes) {
bool local_xform_mirror=p_local_xform.basis.determinant() < 0;
@ -750,7 +750,7 @@ Error ColladaImport::_create_mesh_surfaces(Ref<Mesh>& p_mesh,const Map<String,Co
ERR_FAIL_INDEX_V(src,p.indices.size(),ERR_INVALID_DATA);
Collada::Vertex vertex;
if (p_morph_data)
if (!p_optimize)
vertex.uid=vertidx++;
int vertex_index=p.indices[src+vertex_ofs]; //used for index field (later used by controllers)
@ -1276,7 +1276,7 @@ Error ColladaImport::_create_mesh_surfaces(Ref<Mesh>& p_mesh,const Map<String,Co
////////////////////////////
// THEN THE MORPH TARGETS //
////////////////////////////
#if 0
if (p_morph_data) {
//add morphie target
@ -1358,6 +1358,7 @@ Error ColladaImport::_create_mesh_surfaces(Ref<Mesh>& p_mesh,const Map<String,Co
vertw = DVector<Vector3>::Write();
DVector<Vector3> normals;
DVector<float> 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<Mesh>& p_mesh,const Map<String,Co
}
}
print_line("using built-in normals");
}else{
print_line("generating normals");
_generate_normals(index_array,vertices,normals);//no normals
}
if (final_tangent_array.size() && final_uv_array.size()) {
@ -1436,6 +1439,17 @@ Error ColladaImport::_create_mesh_surfaces(Ref<Mesh>& p_mesh,const Map<String,Co
}
#endif
for(int mi=0;mi<p_morph_meshes.size();mi++) {
print_line("want surface "+itos(mi)+" has "+itos(p_morph_meshes[mi]->get_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<int> bone_remap;
Vector<Ref<Mesh> > 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<String> 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<String> targets;
morph->targets.has("MORPH_TARGET");
String target = morph->targets["MORPH_TARGET"];
bool valid=false;
if (morph->sources.has(target)) {
valid=true;
Vector<String> names = morph->sources[target].sarray;
for(int i=0;i<names.size();i++) {
String meshid=names[i];
if (collada.state.mesh_data_map.has(meshid)) {
Ref<Mesh> mesh=Ref<Mesh>(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<Mesh>(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;