#include "ofxObjLoader.h" ofxObjLoader::ofxObjLoader(){ verbose=false; } ofxObjLoader::ofxObjLoader(char file[]){ ofxObjLoader(); loadFile(file); } void ofxObjLoader::loadFile(char file[]){ string newFileName = ofToDataPath(file); //validate the file name if(strlen(file)==0){ complain("filename string was empty"); return; } //make sure the file exists on the disk ifstream existanceChecker(newFileName.c_str()); if(!existanceChecker.is_open()){ complain("file not found"); return; } existanceChecker.close(); // we will now slowly parse through the file f ifstream f; f.open(newFileName.c_str(),iostream::binary); while(f.good()){ //get the first token on this line. it's a command char objCommand[256]; f.getline(objCommand,256,' '); if(!strcmp(objCommand,"v")){ vertices.push_back(objVertex()); f >> vertices.back().x; f >> vertices.back().y; f >> vertices.back().z; ignoreRestOfLine(&f); }else if(!strcmp(objCommand,"#")){//comment ignoreRestOfLine(&f); }else if(!strcmp(objCommand,"vt")){ texCoords.push_back(objVertex()); f >> texCoords.back().x; f >> texCoords.back().y; f >> texCoords.back().z; ignoreRestOfLine(&f); }else if(!strcmp(objCommand,"vn")){ normals.push_back(objVertex()); f >> normals.back().x; f >> normals.back().y; f >> normals.back().z; ignoreRestOfLine(&f); }else if(!strcmp(objCommand,"f") || !strcmp(objCommand,"fo")){ char x[256]; int strlen_x; faces.push_back(objFace()); /** get the number of vertices in this face and store it in the face struct. */ int oldpos = f.tellg(); //push file ptr f.getline(x,256); strlen_x=strlen(x); faces.back().count = 1; for(int i=0;i4 ){ complain("Unrecognized face vertex count."); ignoreRestOfLine(&f); continue; } /** validate vertex.type - the data-depth. ie. how many numbers per chunk. */ if(faces.back().type!=3 && faces.back().type!=2 && faces.back().type!=1 ){ complain("Unrecognized face vertex type."); ignoreRestOfLine(&f); continue; } /** loop through and collect the appropriate data into the arrays. */ for(int thisVertexID=0;thisVertexID=thisVertexID+1){ //depending on the syntax of the face vertex chunk, parse accordingly if(faces.back().type==3){ // %i/%i/%i //collect the geometric vertex f.getline(x,256,'/'); faces.back().vertices[thisVertexID] = strtol(x,NULL,10); //collect the texture vertex f.getline(x,256,'/'); faces.back().texCoords[thisVertexID] = strtol(x,NULL,10); //collect the vertex normal, but beware of the end-of-line if(faces.back().count==thisVertexID+1)f.getline(x,256); else f.getline(x,256,' '); faces.back().normals[thisVertexID] = strtol(x,NULL,10); }else if(faces.back().type==2){ // %i/%i //collect the geometric vertex f.getline(x,256,'/'); faces.back().vertices[thisVertexID] = strtol(x,NULL,10); //collect the texture vertex, but beware of the end-of-line if(faces.back().count==thisVertexID+1)f.getline(x,256); else f.getline(x,256,' '); faces.back().texCoords[thisVertexID] = strtol(x,NULL,10); }else if(faces.back().type==1){ // %i //collect the geometric vertex, but beware of the end-of-line if(faces.back().count==thisVertexID+1)f.getline(x,256); else f.getline(x,256,' '); faces.back().vertices[thisVertexID] = strtol(x,NULL,10); } } } }else if(strlen(objCommand)==0){ }else{ if(objCommand[0]!='#'){ char s[256]; sprintf(s,"command token not parsed: %s",objCommand); complain(s); } ignoreRestOfLine(&f); } } f.close(); } ofxObjLoader::~ofxObjLoader(){ } objVertex ofxObjLoader::getVertex(int i){ if(i3){ glTexCoord2f(texCoords[faces[i].texCoords[ii]-1].x, texCoords[faces[i].texCoords[ii]-1].y); } if(faces[i].type>2){ glNormal3f(normals[faces[i].normals[ii]-1].x, normals[faces[i].normals[ii]-1].y, normals[faces[i].normals[ii]-1].z); } int index = faces[i].vertices[ii]-1; float x=vertices[index].x; float y=vertices[index].y; float z=vertices[index].z; glVertex3f(x,y,z); } } void ofxObjLoader::fillFaces(){ #if defined(__DARWIN__) glEnable(GL_RESCALE_NORMAL); #endif for(int i=0;igetline(buff,256); //ok, now skip empty lines as well. if(f->peek()=='\n'||f->peek()=='\r')ignoreRestOfLine(f); } void ofxObjLoader::complain(char *s){ if(verbose)fprintf(stderr,"ofxObjLoader: %s\n",s); } objVertex::objVertex(float xx,float yy,float zz){ x=xx; y=yy; z=zz; } objVertex::objVertex(){ x=0; y=0; z=0; }