/* * mesh_loader.cpp * ACCtessellator * * Created by Denis Kovacs on 8/9/08. * Copyright 2008 NYU. All rights reserved. * */ #include #include #include #include #include #include #include #include "mesh_loader.h" #include "cvec3t.h" #include "cvec2t.h" using namespace std; #define NO_VTX (unsigned int)(-1) typedef CVec3T Vec3; typedef CVec2T Vec2; //------------------------------------------------------------------ // triple of indices used per vertex of a face: //the index of vertex position, the index of vertex texture coords (uv), // and the index of normal struct VTXindex { int posIdx; int uvIdx; int norIdx; VTXindex( int p, int uv, int n): posIdx(p), uvIdx(uv), norIdx(n) {} VTXindex() {} }; struct OBJMesh { vector pos; vector uv; vector nor; // triple of indices for each face vertex vector faces; // indices in array faces where faces start vector face_startidx; bool hasTextureCoords() { return uv.size() != 0; } bool hasNormals() { return nor.size() != 0; } }; struct VTXindex_ltstr { bool operator()(VTXindex v1, VTXindex v2) const { if (v1.posIdx != v2.posIdx) return v1.posIdx VTXmap; //------------------------------------------------------------------ static void skipLine(istream& ifs); static bool skipCommentLine(istream& ifs); // ripped from TooL struct OBJMesh* readOBJ(const char *filename) //------------------------------------------------------------------ { OBJMesh* mesh = new OBJMesh; string ele_id; float x, y, z; ifstream ifs( filename ); if (!ifs) { printf("failed to open %s\n", filename); return mesh; } while(skipCommentLine(ifs)) { if (!(ifs >> ele_id)) return mesh; if ("v" == ele_id) // position { ifs >> x >> y >> z; mesh->pos.push_back(Vec3(x, y, z)); } else if ("vt" == ele_id) // uv coordinates { ifs >> x >> y >> z; ifs.clear(); // is z (i.e. w) is not available, have to clear error flag. mesh->uv.push_back(Vec2(x, y)); } else if ("vn" == ele_id) // normal { ifs >> x >> y >> z; if(!ifs.good()) { // in case it is -1#IND00 x = y = z = 0.0; ifs.clear(); skipLine(ifs); } mesh->nor.push_back(Vec3(x, y, z)); } else if ("f" == ele_id) // face data { // record face size mesh->face_startidx.push_back(mesh->faces.size()); // read in all vertices of a face vector indices; while ( ifs.good() ) { char c; VTXindex v = VTXindex(NO_VTX, NO_VTX, NO_VTX); if(!mesh->hasTextureCoords() && !mesh->hasNormals()) ifs >> v.posIdx; else if(!mesh->hasTextureCoords()) ifs >> v.posIdx >> c >> c >> v.norIdx; else if(!mesh->hasNormals()) ifs >> v.posIdx >> c >> v.uvIdx; else ifs >> v.posIdx >> c >> v.uvIdx >> c >> v.norIdx; if ( ifs.good() ) indices.push_back(v); } for (size_t k=0; k< indices.size(); k++) { mesh->faces.push_back(indices[k]); } ifs.clear(); } else skipLine(ifs); } ifs.close(); return mesh; } static void skipLine(istream& ifs) { char next; ifs >> std::noskipws; while( (ifs >> next) && ('\n' != next) ); } static bool skipCommentLine(istream& ifs) { char next; while( ifs >> std::skipws >> next ) { ifs.putback(next); if ('#' == next) skipLine(ifs); else return true; } return false; } void dumpMeshVerbose(const OBJMesh& mesh) //------------------------------------------------------------------ { int nV; unsigned int i,j; printf("#nV:%d nF:%d", mesh.pos.size(), mesh.face_startidx.size()); printf(" Pos:\n"); nV = 0; for(i=0; i 0 ) { printf("# UV:\n"); nV = 0; for(i=0; i 0 ) { printf("# Nor:\n"); nV = 0; for(i=0; i