void TriMeshObjLoader::load(const std::string& filename) { pathname = get_path(filename); FILE *fp = fopen(filename.data(), "r"); if (fp==0) { cerr << "File " << filename << " does not exist" << endl; exit(0); } mesh->materials.resize(1); char buf[256]; float3 v_geo; float3 v_normals; float3 v_texcoords; uint3 f_geo; uint3 f_normals; uint3 f_texcoords; int current_material=0; int v, n, t; while(fscanf(fp, "%s", buf) != EOF) { switch(buf[0]) { case '#': // A comment fgets(buf, sizeof(buf), fp); break; case 'm': fgets(buf, sizeof(buf), fp); sscanf(buf, "%s %s", buf, buf); read_material_library(buf, mesh->materials); break; case 'u': fgets(buf, sizeof(buf), fp); sscanf(buf, "%s %s", buf, buf); current_material = mesh->find_material(buf); break; case 'v': // v, vn, vt switch(buf[1]) { case '\0': // vertex fscanf(fp, "%f %f %f", &v_geo.x, &v_geo.y, &v_geo.z); mesh->geometry.add_vertex(v_geo); break; case 'n': // normal fscanf(fp, "%f %f %f", &v_normals.x, &v_normals.y, &v_normals.z); mesh->normals.add_vertex(v_normals); break; case 't': // texcoord fscanf(fp, "%f %f", &v_texcoords.x, &v_texcoords.y); v_texcoords.z=1; mesh->texcoords.add_vertex(v_texcoords); break; } break; case 'f': v = n = t = 0; fscanf(fp, "%s", buf); // can be one of %d, %d//%d, %d/%d, %d/%d/%d if(sscanf(buf, "%d/%d/%d", &v, &t, &n) == 3) { // v/t/n f_geo.x = get_vert(v); f_texcoords.x = get_texcoord(t); f_normals.x = get_normal(n); fscanf(fp, "%d/%d/%d", &v, &t, &n); f_geo.y = get_vert(v); f_texcoords.y = get_texcoord(t); f_normals.y = get_normal(n); fscanf(fp, "%d/%d/%d", &v, &t, &n); f_geo.z = get_vert(v); f_texcoords.z = get_texcoord(t); f_normals.z = get_normal(n); int idx = mesh->geometry.add_face(f_geo); mesh->normals.add_face(f_normals, idx); mesh->texcoords.add_face(f_texcoords, idx); mesh->mat_idx.push_back(current_material); // Load a general polygon and convert to triangles while(fscanf(fp, "%d/%d/%d", &v, &t, &n) == 3) { f_geo.y = f_geo.z; f_normals.y = f_normals.z; f_texcoords.y = f_texcoords.z; f_geo.z = get_vert(v); f_normals.z = get_normal(n); f_texcoords.z = get_texcoord(t); int idx = mesh->geometry.add_face(f_geo); mesh->normals.add_face(f_normals, idx); mesh->texcoords.add_face(f_texcoords, idx); mesh->mat_idx.push_back(current_material); } } else if (sscanf(buf, "%d//%d", &v, &n) == 2) {// v//n f_geo.x = get_vert(v); f_normals.x = get_normal(n); fscanf(fp, "%d//%d", &v, &n); f_geo.y = get_vert(v); f_normals.y = get_normal(n); fscanf(fp, "%d//%d", &v, &n); f_geo.z = get_vert(v); f_normals.z = get_normal(n); int idx = mesh->geometry.add_face(f_geo); mesh->normals.add_face(f_normals, idx); mesh->mat_idx.push_back(current_material); // Load a general polygon and convert to triangles while(fscanf(fp, "%d//%d", &v, &n) == 2) { f_geo.y = f_geo.z; f_normals.y = f_normals.z; f_geo.z = get_vert(v); int idx = mesh->geometry.add_face(f_geo); mesh->normals.add_face(f_normals, idx); mesh->mat_idx.push_back(current_material); } } else if (sscanf(buf, "%d/%d", &v, &t) == 2) { // v/t f_geo.x = get_vert(v); f_texcoords.x = get_texcoord(t); fscanf(fp, "%d/%d", &v, &t); f_geo.y = get_vert(v); f_texcoords.y = get_texcoord(t); fscanf(fp, "%d/%d", &v, &t); f_geo.z = get_vert(v); f_texcoords.z = get_texcoord(t); int idx = mesh->geometry.add_face(f_geo); mesh->texcoords.add_face(f_texcoords, idx); mesh->mat_idx.push_back(current_material); // Load a general polygon and convert to triangles while(fscanf(fp, "%d/%d", &v, &t)==2) { f_geo.y = f_geo.z; f_texcoords.y = f_texcoords.z; f_geo.z = get_vert(v); f_texcoords.z = get_texcoord(t); int idx = mesh->geometry.add_face(f_geo); mesh->texcoords.add_face(f_texcoords, idx); mesh->mat_idx.push_back(current_material); } } else if (sscanf(buf, "%d", &v)==1) { // v f_geo.x = get_vert(v); fscanf(fp, "%d", &v); f_geo.y = get_vert(v); fscanf(fp, "%d", &v); f_geo.z = get_vert(v); mesh->geometry.add_face(f_geo); mesh->mat_idx.push_back(current_material); // Load a general polygon and convert to triangles while(fscanf(fp, "%d", &v)==1) { f_geo.y = f_geo.z; f_geo.z = get_vert(v); mesh->geometry.add_face(f_geo); mesh->mat_idx.push_back(current_material); } } break; default: fgets(buf, sizeof(buf), fp); break; } } fclose(fp); }