00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #include "TriangleMesh.h"
00013 #include <fstream>
00014 #include <iostream>
00015 #include <cassert>
00016 #include <string>
00017
00018
00019 using namespace std;
00020
00021
00022 namespace columbia
00023 {
00024
00025 static void skip_line(istream& is)
00026 {
00027 char next;
00028 while( is >> noskipws >> next && next != '\n' );
00029 }
00030
00031 static bool skip_comment_line(istream& is, char comment_tag)
00032 {
00033 char next;
00034 while( is >> skipws >> next )
00035 {
00036 is.putback(next);
00037 if(next == comment_tag) skip_line(is);
00038 else
00039 return true;
00040 }
00041 return false;
00042 }
00043
00044
00045 TriangleMesh :: TriangleMesh(const char* obj_fname) : has_normal(false), has_texture(false), texImage(0)
00046 {
00047 ifstream is(obj_fname);
00048
00049 if(is)
00050 {
00051 bool no_normal = true;
00052 bool no_tex = true;
00053
00054 while( skip_comment_line(is, '#') )
00055 {
00056 string ele_id;
00057 float x, y, z;
00058
00059 if( ! (is >> ele_id) ) break;
00060
00061 if(ele_id == "v")
00062 {
00063 is >> x >> y >> z;
00064 V.push_back( Vertex(x, y, z) );
00065 }
00066 else if(ele_id == "vt")
00067 {
00068 no_tex = false;
00069 is >> x >> y >> z;
00070 is.clear();
00071 T.push_back( Vector(x, y, z) );
00072 }
00073 else if(ele_id == "vn")
00074 {
00075 no_normal = false;
00076 is >> x >> y >> z;
00077 if(! is.good())
00078 {
00079 x = y = z = 0.0;
00080 is.clear();
00081 skip_line(is);
00082 }
00083 N.push_back( Vector(x, y, z) );
00084 }
00085 else if(ele_id == "f")
00086 {
00087 int vi[10];
00088 int ni[10] = { -1, -1, -1, -1, };
00089 int ti[10] = { -1, -1, -1, -1, };
00090 int i = 0;
00091 for(char c; i<10; ++i)
00092 {
00093 if(no_tex && no_normal) is >> vi[i];
00094 else if(no_tex) is >> vi[i] >> c >> c >> ni[i];
00095 else if(no_normal) is >> vi[i] >> c >> ti[i];
00096 else is >> vi[i] >> c >> ti[i] >> c >> ni[i];
00097
00098 if( ! is.good() ) break;
00099 }
00100 for(int k=0; k<=i-3; k++)
00101 {
00102 F.push_back( TriangleFace(vi[0]-1, vi[k+1]-1, vi[k+2]-1, ti[0]-1, ti[k+1]-1, ti[k+2]-1, ni[0]-1, ni[k+1]-1, ni[k+2]-1) );
00103 }
00104 is.clear();
00105 }
00106 else
00107 skip_line(is);
00108 }
00109 is.close();
00110 init();
00111 }
00112 else
00113 cerr << "Can't open input file " << obj_fname << endl;
00114 }
00115
00116 void TriangleMesh :: init()
00117 {
00118 has_normal = N.size();
00119 has_texture = T.size();
00120 total_triangles = F.size();
00121 cout << "total vertices " << V.size() << endl;
00122 cout << "total normals " << N.size() << endl;
00123 cout << "total texture coordinates " << T.size() << endl;
00124 cout << "total triangles " << F.size() << endl;
00125
00126
00127 bbox = BBox(*this);
00128 cout << "bounding box is " << bbox << endl;
00129 }
00130
00131 void TriangleMesh :: initTexture()
00132 {
00133 if(has_texture && texImage)
00134 {
00135 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
00136
00137 glGenTextures(1, &texName);
00138 glBindTexture(GL_TEXTURE_2D, texName);
00139
00140 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
00141 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
00142 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
00143 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
00144
00145 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, texImage->hReso, texImage->vReso,
00146 0, GL_RGB, GL_FLOAT, texImage->data);
00147 }
00148 }
00149
00150 void TriangleMesh :: glDraw() const
00151 {
00152 if(has_normal)
00153 {
00154 glEnable(GL_LIGHTING);
00155 glEnable(GL_LIGHT0);
00156 }
00157 else
00158 glDisable(GL_LIGHTING);
00159
00160 if(has_texture && texImage)
00161 {
00162 glEnable(GL_TEXTURE_2D);
00163 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, has_normal? GL_MODULATE : GL_DECAL);
00164 glBindTexture(GL_TEXTURE_2D, texName);
00165 glEnable(GL_TEXTURE_2D);
00166
00167 if(has_normal)
00168 {
00169 glBegin(GL_TRIANGLES);
00170 {
00171 for(int f = 0; f < total_triangles; ++f)
00172 {
00173 int i = F[f].i, j = F[f].j, k = F[f].k;
00174 int ni = F[f].ni, nj = F[f].nj, nk = F[f].nk;
00175 int ti = F[f].ti, tj = F[f].tj, tk = F[f].tk;
00176
00177 glTexCoord2f(T[ti].x, T[ti].y); glNormal3f( N[ni].x, N[ni].y, N[ni].z ); glVertex3f( V[i].x, V[i].y, V[i].z );
00178 glTexCoord2f(T[tj].x, T[tj].y); glNormal3f( N[nj].x, N[nj].y, N[nj].z ); glVertex3f( V[j].x, V[j].y, V[j].z );
00179 glTexCoord2f(T[tk].x, T[tk].y); glNormal3f( N[nk].x, N[nk].y, N[nk].z ); glVertex3f( V[k].x, V[k].y, V[k].z );
00180 }
00181 }
00182 glEnd();
00183 }
00184 else
00185 {
00186 glBegin(GL_TRIANGLES);
00187 {
00188 for(int f = 0; f < total_triangles; ++f)
00189 {
00190 int i = F[f].i, j = F[f].j, k = F[f].k;
00191 int ti = F[f].ti, tj = F[f].tj, tk = F[f].tk;
00192
00193 glTexCoord2f(T[ti].x, T[ti].y); glVertex3f( V[i].x, V[i].y, V[i].z );
00194 glTexCoord2f(T[tj].x, T[tj].y); glVertex3f( V[j].x, V[j].y, V[j].z );
00195 glTexCoord2f(T[tk].x, T[tk].y); glVertex3f( V[k].x, V[k].y, V[k].z );
00196 }
00197 }
00198 glEnd();
00199 }
00200 glDisable(GL_TEXTURE_2D);
00201 }
00202 else
00203 {
00204 if(has_normal)
00205 {
00206 glBegin(GL_TRIANGLES);
00207 {
00208 for(int f = 0; f < total_triangles; ++f)
00209 {
00210 int i = F[f].i, j = F[f].j, k = F[f].k;
00211 int ni = F[f].ni, nj = F[f].nj, nk = F[f].nk;
00212
00213 glNormal3f( N[ni].x, N[ni].y, N[ni].z ); glVertex3f( V[i].x, V[i].y, V[i].z );
00214 glNormal3f( N[nj].x, N[nj].y, N[nj].z ); glVertex3f( V[j].x, V[j].y, V[j].z );
00215 glNormal3f( N[nk].x, N[nk].y, N[nk].z ); glVertex3f( V[k].x, V[k].y, V[k].z );
00216 }
00217 }
00218 glEnd();
00219 }
00220 else
00221 {
00222 glBegin(GL_TRIANGLES);
00223 {
00224 for(int f = 0; f < total_triangles; ++f)
00225 {
00226 int i = F[f].i, j = F[f].j, k = F[f].k;
00227
00228 glVertex3f( V[i].x, V[i].y, V[i].z );
00229 glVertex3f( V[j].x, V[j].y, V[j].z );
00230 glVertex3f( V[k].x, V[k].y, V[k].z );
00231 }
00232 }
00233 glEnd();
00234 }
00235 }
00236 }
00237
00238
00239
00240 };
00241
00242
00243
00244