18 FILE *in= fopen(filename,
"rt");
21 printf(
"[error] loading mesh '%s'...\n", filename);
25 printf(
"loading mesh '%s'...\n", filename);
29 int default_material_id= -1;
37 char line_buffer[1024];
42 if(fgets(line_buffer,
sizeof(line_buffer), in) == NULL)
49 line_buffer[
sizeof(line_buffer) -1]= 0;
52 char *line= line_buffer;
53 while(*line && isspace(*line))
61 if(sscanf(line,
"v %f %f %f", &x, &y, &z) != 3)
63 data.positions.push_back(
vec3(x, y, z) );
65 else if(line[1] ==
'n')
67 if(sscanf(line,
"vn %f %f %f", &x, &y, &z) != 3)
69 data.normals.push_back(
vec3(x, y, z) );
71 else if(line[1] ==
't')
73 if(sscanf(line,
"vt %f %f", &x, &y) != 2)
75 data.texcoords.push_back(
vec2(x, y) );
79 else if(line[0] ==
'f')
86 for(line= line +1; ; line= line + next)
93 if(sscanf(line,
" %d/%d/%d %n", &idp.back(), &idt.back(), &idn.back(), &next) == 3)
95 else if(sscanf(line,
" %d/%d %n", &idp.back(), &idt.back(), &next) == 2)
97 else if(sscanf(line,
" %d//%d %n", &idp.back(), &idn.back(), &next) == 2)
99 else if(sscanf(line,
" %d %n", &idp.back(), &next) == 1)
106 if(material_id == -1)
108 if(default_material_id == -1)
111 default_material_id= data.materials.size();
115 material_id= default_material_id;
116 printf(
"usemtl default\n");
120 for(
int v= 2; v +1 < (int) idp.size(); v++)
122 int idv[3]= { 0, v -1, v };
123 for(
int i= 0; i < 3; i++)
126 int p= (idp[k] < 0) ? (
int) data.positions.size() + idp[k] : idp[k] -1;
127 int t= (idt[k] < 0) ? (
int) data.texcoords.size() + idt[k] : idt[k] -1;
128 int n= (idn[k] < 0) ? (
int) data.normals.size() + idn[k] : idn[k] -1;
130 if(p < 0 || p >= (
int) data.positions.size())
134 data.position_indices.push_back(p);
135 data.texcoord_indices.push_back(t);
136 data.normal_indices.push_back(n);
140 data.material_indices.push_back(material_id);
144 else if(line[0] ==
'm')
146 if(sscanf(line,
"mtllib %[^\r\n]", tmp) == 1)
149 data.materials= materials.data;
153 else if(line[0] ==
'u')
155 if(sscanf(line,
"usemtl %[^\r\n]", tmp) == 1)
158 for(
unsigned int i= 0; i < (
unsigned int) materials.names.size(); i++)
159 if(materials.names[i] == tmp)
162 if(material_id == -1)
165 if(default_material_id == -1)
168 default_material_id= data.materials.size();
172 material_id= default_material_id;
181 printf(
"loading mesh '%s'...\n[error]\n%s\n\n", filename, line_buffer);
183 printf(
" %d positions, %d texcoords, %d normals, %d triangles\n",
184 (
int) data.positions.size(), (
int) data.texcoords.size(), (
int) data.normals.size(), (
int) data.material_indices.size());
191 std::string normalize_path( std::string file )
194 std::replace(file.begin(), file.end(),
'\\',
'/');
196 std::replace(file.begin(), file.end(),
'/',
'\\');
206 FILE *in= fopen(filename,
"rt");
209 printf(
"[error] loading materials '%s'...\n", filename);
213 printf(
"loading materials '%s'...\n", filename);
216 std::string path=
pathname(filename);
219 char line_buffer[1024];
224 if(fgets(line_buffer,
sizeof(line_buffer), in) == NULL)
231 line_buffer[
sizeof(line_buffer) -1]= 0;
234 char *line= line_buffer;
235 while(*line && isspace(*line))
240 if(sscanf(line,
"newmtl %[^\r\n]", tmp) == 1)
242 materials.names.push_back( tmp );
244 material= &materials.data.back();
254 if(sscanf(line,
"Kd %f %f %f", &r, &g, &b) == 3)
256 else if(sscanf(line,
"Ks %f %f %f", &r, &g, &b) == 3)
258 else if(sscanf(line,
"Ke %f %f %f", &r, &g, &b) == 3)
262 else if(line[0] ==
'N')
265 if(sscanf(line,
"Ns %f", &n) == 1)
269 else if(line[0] ==
'm')
271 if(sscanf(line,
"map_Kd %[^\r\n]", tmp) == 1)
274 if(sscanf(line,
"map_Ks %[^\r\n]", tmp) == 1)
284 printf(
"[error] parsing line :\n%s\n", line_buffer);
292 if(data.positions.size() < 1)
295 pmin=
Point(data.positions[0]);
298 for(
int i= 1; i < (int) data.positions.size(); i++)
300 vec3 p= data.positions[i];
309 printf(
"[mesh] building normals...\n");
312 std::vector<Vector>
normals(data.positions.size(),
Vector());
313 for(
int i= 0; i + 2 < (int) data.position_indices.size(); i+= 3)
316 Point a=
Point(data.positions[data.position_indices[i]]);
317 Point b=
Point(data.positions[data.position_indices[i +1]]);
318 Point c=
Point(data.positions[data.position_indices[i +2]]);
333 normals[data.position_indices[i]]=
normals[data.position_indices[i]] + n * anglea;
334 normals[data.position_indices[i +1]]=
normals[data.position_indices[i +1]] + n * angleb;
335 normals[data.position_indices[i +2]]=
normals[data.position_indices[i +2]] + n * anglec;
339 data.normals.clear();
340 data.normals.reserve(
normals.size());
341 for(
int i= 0; i < (int)
normals.size(); i++)
345 for(
int i= 0; i < (int) data.normal_indices.size(); i++)
346 data.normal_indices[i]= data.position_indices[i];
356 mesh.positions.reserve(data.positions.size());
357 mesh.texcoords.reserve(data.texcoords.size());
358 mesh.normals.reserve(data.normals.size());
360 for(
int i= 0; i < (int) data.position_indices.size(); i++)
362 mesh.positions.push_back( data.positions[data.position_indices[i]] );
363 if(data.texcoord_indices[i] >= 0)
364 mesh.texcoords.push_back( data.texcoords[data.texcoord_indices[i]] );
365 if(data.normal_indices[i] >= 0)
366 mesh.normals.push_back( data.normals[data.normal_indices[i]] );
369 data.position_indices.clear();
370 data.texcoord_indices.clear();
371 data.normal_indices.clear();
const std::vector< unsigned int > & material_indices() const
renvoie les indices des matieres des triangles.
const Materials & materials() const
renvoie la description des matieres.
void printf(Text &text, const int px, const int py, const char *format,...)
affiche un texte a la position x, y. meme utilisation que printf().
Point max(const Point &a, const Point &b)
renvoie la plus grande composante de chaque point. x, y, z= max(a.x, b.x), max(a.y,...
Point min(const Point &a, const Point &b)
renvoie la plus petite composante de chaque point. x, y, z= min(a.x, b.x), min(a.y,...
float dot(const Vector &u, const Vector &v)
renvoie le produit scalaire de 2 vecteurs.
Vector normalize(const Vector &v)
renvoie un vecteur unitaire / longueur == 1.
Vector cross(const Vector &u, const Vector &v)
renvoie le produit vectoriel de 2 vecteurs.
charge les textures utiilisees par un ensemble de matieres.
MaterialDataLib read_material_data(const char *filename)
charge un ensemble de matieres texturees.
void normals(MeshData &data)
(re-) calcule les normales des sommets. utiliser avant les reindexations, cf indices() et vertices().
MeshData read_mesh_data(const char *filename)
charge un fichier wavefront .obj et renvoie les donnees.
MeshData vertices(MeshData &data)
construit les sommets. prepare l'affichage openGL, avec glDrawArrays().
void bounds(const MeshData &data, Point &pmin, Point &pmax)
renvoie l'englobant.
representation des donnees d'un fichier wavefront .obj
std::string pathname(const std::string &filename)
ensemble de matieres texturees.
representation d'une couleur (rgba) transparente ou opaque.
representation d'une matiere texturee.
Color specular
couleur du reflet
Color emission
pour une source de lumiere
std::string diffuse_filename
nom de la texture diffuse
float ns
exposant pour les reflets blinn-phong
Color diffuse
couleur diffuse
std::string ns_filename
nom de la texture exposant
representation d'un point 3d.
representation d'un vecteur 3d.
vecteur generique, utilitaire.
vecteur generique, utilitaire.