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