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);
}