/** * Loads the specified file, then validates. */ bool OBJModel::loadFile(const std::string& filename) { writeToLog(MessageLevel::INFO, "Loading model from file \"%s\"\n", filename.c_str()); valid = false; path p(filename); uint32_t fileLine = 0; if (exists(p) && is_regular_file(p)) { std::ifstream file(p.generic_string()); vertices.clear(); textureCoords.clear(); normals.clear(); faces.clear(); vertices.push_back(Vector3(0.0f, 0.0f, 0.0f)); textureCoords.push_back(Vector2(0.0f, 0.0f)); normals.push_back(Vector3(0.0f, 0.0f, 0.0f)); do { std::string line; std::getline(file, line); fileLine++; StringTokenizer tokens(line, ' '); if (tokens.getTokenCount() > 0) { std::string type = tokens.getToken(0); if (type.compare("v") == 0) { Vector3 vertex = vector3FromTokens(tokens.getToken(1), tokens.getToken(2), tokens.getToken(3)); vertices.push_back(vertex); } else if (type.compare("vt") == 0) { Vector2 texCoord = vector2FromTokens(tokens.getToken(1), tokens.getToken(2)); textureCoords.push_back(texCoord); } else if (type.compare("vn") == 0) { Vector3 normal = vector3FromTokens(tokens.getToken(1), tokens.getToken(2), tokens.getToken(3)); normals.push_back(normal); } else if (type.compare("f") == 0) { OBJFace face; for (uint32_t i = 1; i < tokens.getTokenCount(); i++) { StringTokenizer faceTokens(tokens.getToken(i), '/'); int32_t v = 0; int32_t vt = 0; int32_t vn = 0; try { v = std::stoi(faceTokens.getToken(0)); if (v < 0) { v += vertices.size(); } } catch (std::exception&) { v = 0; } try { vt = std::stoi(faceTokens.getToken(1)); if (vt < 0) { vt += textureCoords.size(); } } catch (std::exception&) { vt = 0; } try { vn = std::stoi(faceTokens.getToken(2)); if (vn < 0) { vn += normals.size(); } } catch (std::exception&) { vn = 0; } face.push(v, vt, vn); } // We only support triangulated models. if (face.getTripletCount() > 3) { writeToLog(MessageLevel::ERROR, "Malformed face on line %d in \"%s\": Too many points, only triangles are supported.\n", fileLine, filename.c_str()); return false; } faces.push_back(face); } else { // Currently a no-op. } } } while(!file.eof() && file.good()); } else { writeToLog(MessageLevel::ERROR, "Could not find file \"%s\".\n", filename.c_str()); return false; } return validate(); }
void VBOWFModel::Tokenise_Data(std::string input) { float tempfloat[3]; //temporary float array of 3 StringTokens tokens(input,' '); if(tokens.First_token()=="v") //if vertices { tokens.Next_token(); tempfloat[0] = (float)atof(tokens.Next_token().c_str()); //x value tempfloat[1] = (float)atof(tokens.Next_token().c_str()); //y value tempfloat[2] = (float)atof(tokens.Next_token().c_str()); //z value verts.push_back(Vec3f(tempfloat[0],tempfloat[1],tempfloat[2])); } else if(tokens.First_token()=="vn") //if normals { tokens.Next_token(); tempfloat[0] = (float)atof(tokens.Next_token().c_str()); //x value tempfloat[1] = (float)atof(tokens.Next_token().c_str()); //y value tempfloat[2] = (float)atof(tokens.Next_token().c_str()); //z value norms.push_back(Vec3f(tempfloat[0],tempfloat[1],tempfloat[2])); } else if(tokens.First_token()=="vt") //if texture coords { tokens.Next_token(); tempfloat[0] = (float)atof(tokens.Next_token().c_str()); //x value tempfloat[1] = (float)atof(tokens.Next_token().c_str()); //y value tempfloat[2] = (float)atof(tokens.Next_token().c_str()); //z value tex.push_back(Vec2f(tempfloat[0],tempfloat[1])); } else if(tokens.First_token()=="f") //if face { tokens.Next_token(); Vec3f temp; for(int i=0; i<3; i++) //get 3 vert indexes, text coord index, normals index { StringTokens faceTokens(tokens.Next_token(),'/'); m_Vindices.push_back(atoi(faceTokens.Next_token().c_str())-1); //store vertex index m_Tindices.push_back(atoi(faceTokens.Next_token().c_str())-1); m_Nindices.push_back(atoi(faceTokens.Next_token().c_str())-1); } } else if(tokens.First_token()=="mtllib") //if material lib { string mtl = "Model/"; //mtl file location string image = "textures/wdworld/"; //image file location string temp2; tokens.Next_token(); mtl.append(tokens.Next_token()); //add it to the location ifstream material(mtl.c_str()); //create input filestream for MTL if(material) //if material exists { while(std::getline(material, temp2)) //tokenize MTL { istringstream matName(temp2); getline(matName,temp2); //get image name image.append(temp2); //add it to the location mtlName.push_back(image); //store it image = "textures/wdworld/"; //reset image to only location } m_texture = Texture(mtlName.back()); if(!(m_texture.LoadTexture()))//if loaded succesfully { cout << "File DNE" << endl; } } else //if material DNE { cout << "material file " << temp2 << " DNE" << endl; } } }