/*************************************************************************** * Copyright (C) 2004 by Murray Evans * * m.evans@rdg.ac.uk * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include "ModelManager.h" #include "DynArray.h" #include using namespace std; // Loads an Alias|Wavefront .obj file int CModelManager::LoadOBJ(string in_Filename_s) { // Wavefront .obj file is a text file. // This loader will load a simple version of it // It can cope with the v, vt, vn and g(?) instructions // and of course, the f one. // v: x z y vertex data // vt: x y texture vertex // vn: x z y vertex normal // f: v/vt/vn v/vt/vn v/vt/vn ... ifstream in; in.open(in_Filename_s.c_str()); // open the file if(!in.is_open()) { cout << "Error loading file: " << in_Filename_s << endl; exit(1); } // parse the file for the appropriate information char ch; CDynArray points; CDynArray normals; CDynArray fnormals; CDynArray uvpoints; CDynArray faces; // .obj does not have vertex colours // vector meshes; string ones, twos, threes, digger; float onef, twof, threef; while(in) { in.get(ch); switch(ch) { case 'v': // read v, vt, or vn ///////////////////////// { // bool istext, isnormal; // CVec4f tpoint; // istext = false; // isnormal=false; // ones=""; // twos=""; // threes=""; // in.get(ch); // if(ch == 't') istext = true; // if(ch == 'n') isnormal = true; // in.get(ch); // // // skip any spaces // while(ch==' ') // { // in.get(ch); // } // // read in first value (x or u) // do // { // ones = ones+ch; // in.get(ch); // }while(ch!=' '); // // // skip any spaces // while(ch==' ') // { // in.get(ch); // } // // read in second value (z or u) // do // { // twos = twos+ch; // in.get(ch); // }while((ch!=' ') && (ch!='\n')); // // // only two values for texture coordinate // if(!istext) // { // // skip any spaces // while(ch==' ') // { // in.get(ch); // } // // read in third value (y coordinate) // do // { // threes = threes+ch; // in.get(ch); // }while((ch!=' ') && (ch != '\n')); // } // // //put info into relevant structure // onef = Cast (ones); // twof = Cast (twos); // threef = Cast (threes); // //tpoint.xyz[0] = onef; // //tpoint.xyz[2] = twof; // //tpoint.xyz[1] = threef; // tpoint.SetXYZW(onef, threef, -twof, 1); // if(istext) // { // CVec2f tpoint2; // // tpoint2.xy[0] = onef; // // tpoint2.xy[1] = twof; // tpoint2.SetXY(onef, twof); // uvpoints.AddToEnd(tpoint2); // } // else if(isnormal) normals.AddToEnd(tpoint); // else points.AddToEnd(tpoint); // }break; // //////////////////////////////////////////////////// case 'f': // read face v/vt/vn v/vt/vn ... ************** { CFace *tface; tface = new(CFace); do { // skip any spaces in.get(ch); while(ch==' ') { in.get(ch); } ones = ""; twos = ""; threes=""; // read to first / to get point do { ones = ones + ch; in.get(ch); }while((ch!=' ') && (ch!='/') && (ch!='\n')); // read until second / to get uvpoint if(ch=='/') { in.get(ch); do { if(ch!='/') twos = twos+ ch; in.get(ch); }while((ch!=' ') && (ch!='/') && (ch!='\n')); } // read until ' ' or '\n' for normal if(ch=='/') { in.get(ch); do { threes = threes + ch; in.get(ch); }while((ch!=' ') && (ch!='\n')); } // and add to the face bool hasp = false; bool hast = false; bool hasn = false; if(ones != "") hasp = true; if(twos != "") hast = true; if(threes!="") hasn = true; if(hasp)onef = Cast (ones)-1; if(hast)twof = Cast (twos)-1; if(hasn)threef=Cast (threes)-1; if(hasp) tface->p.AddToEnd((int)onef); if(hast) tface->uv.AddToEnd((int)twof); if(hasn) tface->n.AddToEnd((int)threef); }while(in && (ch!='\n')); // add new face to list of faces faces.AddToEnd(tface); }break; /******************************************************/ default : // comments or unknowns while(ch != '\n') { in.get(ch); } break; }// switch(ch) } // while(in) // and now, create the mesh. CMesh *tmesh; tmesh = new(CMesh); tmesh->points = points; tmesh->uvpoints = uvpoints; tmesh->fnormals = fnormals; tmesh->normals = normals; tmesh->faces = faces; tmesh->has_faces = true; tmesh->has_points = true; tmesh->has_uvpoints = false; if(normals.Size() > 0) tmesh->has_normals = true; else tmesh->has_normals = false; tmesh->has_fnormals = false; //OBJ file doesn't use if(tmesh->uvpoints.Size() > 0) tmesh->has_uvpoints = true; tmesh->has_colors = false; // add the mesh to the Model Manager's list of meshes meshes.AddToEnd(tmesh); return true; return 0; }