+ case 'f':
+ if(!isspace(line[1])) {
+ break;
+ }
+ ptr = line + 2;
+ for(i=0; i<4; i++) {
+ fv[i].nidx = fv[i].tidx = -1;
+ if(!(ptr = parse_face_vert(ptr, fv + i, vcount, tcount, ncount))) {
+ break;
+ }
+ }
+
+ if(i < 2) {
+ fprintf(stderr, "load_mesh: invalid face definition at %d: %s\n", nline, line);
+ break;
+ }
+
+ va = varr[fv[1].vidx];
+ cgm_vsub(&va, varr + fv[0].vidx);
+ vb = varr[fv[2].vidx];
+ cgm_vsub(&vb, varr + fv[0].vidx);
+ cgm_vcross(&fnorm, &va, &vb);
+ cgm_vnormalize(&fnorm);
+
+ if(m->num_faces >= max_faces - 1) {
+ newsz = max_faces ? max_faces * 2 : 16;
+ if(!(tmpptr = realloc(m->faces, newsz * sizeof *m->faces))) {
+ fprintf(stderr, "load_mesh: failed to resize faces array to %d\n", newsz);
+ goto end;
+ }
+ m->faces = tmpptr;
+ max_faces = newsz;
+ }
+
+ num = i > 3 ? 6 : 3;
+ for(i=0; i<num; i++) {
+ if(i % 3 == 0) {
+ tri = m->faces + m->num_faces++;
+ tri->norm = fnorm;
+ tri->mtl = &m->mtl;
+ }
+ sidx = quadidx[i];
+ didx = i >= 3 ? i - 3 : i;
+ tri->v[didx].pos = varr[fv[sidx].vidx];
+ tri->v[didx].norm = fv[sidx].nidx >= 0 ? varr[fv[sidx].nidx] : fnorm;
+ if(fv[sidx].tidx >= 0) {
+ tri->v[didx].tex.x = tarr[fv[sidx].tidx].x;
+ tri->v[didx].tex.y = tarr[fv[sidx].tidx].y;
+ } else {
+ tri->v[didx].tex.x = tri->v[sidx].tex.y = 0;
+ }
+ }
+ break;