10 FILE *in= fopen(filename,
"rt");
13 printf(
"loading mesh '%s'... failed.\n", filename);
17 Mesh data(GL_TRIANGLES);
19 printf(
"loading mesh '%s'...\n", filename);
21 std::vector<vec3> positions;
22 std::vector<vec2> texcoords;
23 std::vector<vec3> normals;
29 char line_buffer[1024];
34 if(fgets(line_buffer,
sizeof(line_buffer), in) == NULL)
41 line_buffer[
sizeof(line_buffer) -1]= 0;
44 char *line= line_buffer;
45 while(*line && isspace(*line))
53 if(sscanf(line,
"v %f %f %f", &x, &y, &z) != 3)
55 positions.push_back(
vec3(x, y, z) );
57 else if(line[1] ==
'n')
59 if(sscanf(line,
"vn %f %f %f", &x, &y, &z) != 3)
61 normals.push_back(
vec3(x, y, z) );
63 else if(line[1] ==
't')
65 if(sscanf(line,
"vt %f %f", &x, &y) != 2)
67 texcoords.push_back(
vec2(x, y) );
71 else if(line[0] ==
'f')
78 for(line= line +1; ; line= line + next)
85 if(sscanf(line,
" %d/%d/%d %n", &idp.back(), &idt.back(), &idn.back(), &next) == 3)
87 else if(sscanf(line,
" %d/%d %n", &idp.back(), &idt.back(), &next) == 2)
89 else if(sscanf(line,
" %d//%d %n", &idp.back(), &idn.back(), &next) == 2)
91 else if(sscanf(line,
" %d %n", &idp.back(), &next) == 1)
97 for(
int v= 2; v +1 < (int) idp.size(); v++)
99 int idv[3]= { 0, v -1, v };
100 for(
int i= 0; i < 3; i++)
103 int p= (idp[k] < 0) ? (
int) positions.size() + idp[k] : idp[k] -1;
104 int t= (idt[k] < 0) ? (
int) texcoords.size() + idt[k] : idt[k] -1;
105 int n= (idn[k] < 0) ? (
int) normals.size() + idn[k] : idn[k] -1;
107 if(t >= 0) data.
texcoord(texcoords[t]);
108 if(n >= 0) data.
normal(normals[n]);
111 data.
vertex(positions[p]);
120 printf(
"loading mesh '%s'...\n[error]\n%s\n\n", filename, line_buffer);
130 if(mesh.primitives() != GL_TRIANGLES)
132 if(mesh.positions().size() == 0)
137 FILE *out= fopen(filename,
"wt");
141 printf(
"writing mesh '%s'...\n", filename);
143 const std::vector<vec3>& positions= mesh.positions();
144 for(
unsigned int i= 0; i < (
unsigned int) positions.size(); i++)
145 fprintf(out,
"v %f %f %f\n", positions[i].x, positions[i].y, positions[i].z);
148 const std::vector<vec2>& texcoords= mesh.texcoords();
149 bool has_texcoords= (texcoords.size() == positions.size());
150 for(
unsigned int i= 0; i < (
unsigned int) texcoords.size(); i++)
151 fprintf(out,
"vt %f %f\n", texcoords[i].x, texcoords[i].y);
154 const std::vector<vec3>& normals= mesh.normals();
155 bool has_normals= (normals.size() == positions.size());
156 for(
unsigned int i= 0; i < (
unsigned int) normals.size(); i++)
157 fprintf(out,
"vn %f %f %f\n", normals[i].x, normals[i].y, normals[i].z);
160 const std::vector<unsigned int>& indices= mesh.indices();
161 bool has_indices= (indices.size() > 0);
162 unsigned int n= has_indices ? (
unsigned int) indices.size() : (
unsigned int) positions.size();
163 for(
unsigned int i= 0; i +2 < n; i+= 3)
166 for(
unsigned int k= 0; k < 3; k++)
168 unsigned int id= has_indices ? indices[i+k] +1 : i+k +1;
169 fprintf(out,
" %u",
id);
170 if(has_texcoords && has_normals)
171 fprintf(out,
"/%u/%u",
id,
id);
172 else if(has_texcoords)
173 fprintf(out,
"/%u",
id);
175 fprintf(out,
"//%u",
id);
vecteur generique, utilitaire.
vecteur generique, utilitaire.
representation d'un objet / maillage.
unsigned int vertex(const vec3 &p)
insere un sommet de position p, et ses attributs (s'ils sont definis par color(), texcoord()...
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().
int write_mesh(const Mesh &mesh, const char *filename)
enregistre un mesh dans un fichier .obj.
Mesh & normal(const vec3 &n)
definit la normale du prochain sommet.
Mesh & texcoord(const vec2 &uv)
definit les coordonnees de texture du prochain sommet.
Mesh read_mesh(const char *filename)
charge un fichier wavefront .obj et renvoie un mesh compose de triangles non indexes. utiliser glDrawArrays pour l'afficher. a detruire avec Mesh::release( ).