GLMgroup* glmAddGroup(GLMmodel* model, char* name) { GLMgroup* group; group = glmFindGroup(model, name); if (!group) { group = (GLMgroup*)malloc(sizeof(GLMgroup)); group->name = strdup(name); group->material = 0; group->numtriangles = 0; group->triangles = NULL; group->next = model->groups; model->groups = group; model->numgroups++; } return group; }
/* glmSecondPass: second pass at a Wavefront OBJ file that gets all * the data. * * model - properly initialized GLMmodel structure * file - (fopen'd) file descriptor */ static GLvoid glmSecondPass(GLMmodel* model, FILE* file) { GLuint numvertices; /* number of vertices in model */ GLuint numnormals; /* number of normals in model */ GLuint numtexcoords; /* number of texcoords in model */ GLuint numtriangles; /* number of triangles in model */ GLfloat* vertices; /* array of vertices */ GLfloat* normals; /* array of normals */ GLfloat* texcoords; /* array of texture coordinates */ GLMgroup* group; /* current group pointer */ GLuint material; /* current material */ GLuint v, n, t; char buf[128]; /* set the pointer shortcuts */ vertices = model->vertices; normals = model->normals; texcoords = model->texcoords; group = model->groups; /* on the second pass through the file, read all the data into the allocated arrays */ numvertices = numnormals = numtexcoords = 1; numtriangles = 0; material = 0; while(fscanf(file, "%s", buf) != EOF) { switch(buf[0]) { case '#': /* comment */ /* eat up rest of line */ fgets(buf, sizeof(buf), file); break; case 'v': /* v, vn, vt */ switch(buf[1]) { case '\0': /* vertex */ fscanf(file, "%f %f %f", &vertices[3 * numvertices + 0], &vertices[3 * numvertices + 1], &vertices[3 * numvertices + 2]); numvertices++; break; case 'n': /* normal */ fscanf(file, "%f %f %f", &normals[3 * numnormals + 0], &normals[3 * numnormals + 1], &normals[3 * numnormals + 2]); numnormals++; break; case 't': /* texcoord */ fscanf(file, "%f %f", &texcoords[2 * numtexcoords + 0], &texcoords[2 * numtexcoords + 1]); numtexcoords++; break; } break; case 'u': fgets(buf, sizeof(buf), file); sscanf(buf, "%s %s", buf, buf); //group->material = material = glmFindMaterial(model, buf); break; case 'g': /* group */ /* eat up rest of line */ fgets(buf, sizeof(buf), file); #if SINGLE_STRING_GROUP_NAMES sscanf(buf, "%s", buf); #else buf[strlen(buf)-1] = '\0'; /* nuke '\n' */ #endif group = glmFindGroup(model, buf); group->material = material; break; case 'f': /* face */ v = n = t = 0; fscanf(file, "%s", buf); /* can be one of %d, %d//%d, %d/%d, %d/%d/%d %d//%d */ if (strstr(buf, "//")) { /* v//n */ sscanf(buf, "%d//%d", &v, &n); T(numtriangles).vindices[0] = v; T(numtriangles).nindices[0] = n; fscanf(file, "%d//%d", &v, &n); T(numtriangles).vindices[1] = v; T(numtriangles).nindices[1] = n; fscanf(file, "%d//%d", &v, &n); T(numtriangles).vindices[2] = v; T(numtriangles).nindices[2] = n; group->triangles[group->numtriangles++] = numtriangles; numtriangles++; while(fscanf(file, "%d//%d", &v, &n) > 0) { T(numtriangles).vindices[0] = T(numtriangles-1).vindices[0]; T(numtriangles).nindices[0] = T(numtriangles-1).nindices[0]; T(numtriangles).vindices[1] = T(numtriangles-1).vindices[2]; T(numtriangles).nindices[1] = T(numtriangles-1).nindices[2]; T(numtriangles).vindices[2] = v; T(numtriangles).nindices[2] = n; group->triangles[group->numtriangles++] = numtriangles; numtriangles++; } } else if (sscanf(buf, "%d/%d/%d", &v, &t, &n) == 3) { /* v/t/n */ T(numtriangles).vindices[0] = v; T(numtriangles).tindices[0] = t; T(numtriangles).nindices[0] = n; fscanf(file, "%d/%d/%d", &v, &t, &n); T(numtriangles).vindices[1] = v; T(numtriangles).tindices[1] = t; T(numtriangles).nindices[1] = n; fscanf(file, "%d/%d/%d", &v, &t, &n); T(numtriangles).vindices[2] = v; T(numtriangles).tindices[2] = t; T(numtriangles).nindices[2] = n; group->triangles[group->numtriangles++] = numtriangles; numtriangles++; while(fscanf(file, "%d/%d/%d", &v, &t, &n) > 0) { T(numtriangles).vindices[0] = T(numtriangles-1).vindices[0]; T(numtriangles).tindices[0] = T(numtriangles-1).tindices[0]; T(numtriangles).nindices[0] = T(numtriangles-1).nindices[0]; T(numtriangles).vindices[1] = T(numtriangles-1).vindices[2]; T(numtriangles).tindices[1] = T(numtriangles-1).tindices[2]; T(numtriangles).nindices[1] = T(numtriangles-1).nindices[2]; T(numtriangles).vindices[2] = v; T(numtriangles).tindices[2] = t; T(numtriangles).nindices[2] = n; group->triangles[group->numtriangles++] = numtriangles; numtriangles++; } } else if (sscanf(buf, "%d/%d", &v, &t) == 2) { /* v/t */ T(numtriangles).vindices[0] = v; T(numtriangles).tindices[0] = t; fscanf(file, "%d/%d", &v, &t); T(numtriangles).vindices[1] = v; T(numtriangles).tindices[1] = t; fscanf(file, "%d/%d", &v, &t); T(numtriangles).vindices[2] = v; T(numtriangles).tindices[2] = t; group->triangles[group->numtriangles++] = numtriangles; numtriangles++; while(fscanf(file, "%d/%d", &v, &t) > 0) { T(numtriangles).vindices[0] = T(numtriangles-1).vindices[0]; T(numtriangles).tindices[0] = T(numtriangles-1).tindices[0]; T(numtriangles).vindices[1] = T(numtriangles-1).vindices[2]; T(numtriangles).tindices[1] = T(numtriangles-1).tindices[2]; T(numtriangles).vindices[2] = v; T(numtriangles).tindices[2] = t; group->triangles[group->numtriangles++] = numtriangles; numtriangles++; } } else { /* v */ sscanf(buf, "%d", &v); T(numtriangles).vindices[0] = v; fscanf(file, "%d", &v); T(numtriangles).vindices[1] = v; fscanf(file, "%d", &v); T(numtriangles).vindices[2] = v; group->triangles[group->numtriangles++] = numtriangles; numtriangles++; while(fscanf(file, "%d", &v) > 0) { T(numtriangles).vindices[0] = T(numtriangles-1).vindices[0]; T(numtriangles).vindices[1] = T(numtriangles-1).vindices[2]; T(numtriangles).vindices[2] = v; group->triangles[group->numtriangles++] = numtriangles; numtriangles++; } } break; default: /* eat up rest of line */ fgets(buf, sizeof(buf), file); break; } } #if 0 /* announce the memory requirements */ printf(" Memory: %d bytes\n", numvertices * 3*sizeof(GLfloat) + numnormals * 3*sizeof(GLfloat) * (numnormals ? 1 : 0) + numtexcoords * 3*sizeof(GLfloat) * (numtexcoords ? 1 : 0) + numtriangles * sizeof(GLMtriangle)); #endif }
/* glmSecondPass: second pass at a Wavefront OBJ file that gets all * the data. * * model - properly initialized GLMmodel structure * file - (fopen'd) file descriptor */ static GLvoid glmSecondPass(GLMmodel* model, FILE* file) { GLuint numvertices; /* number of vertices in model */ GLuint numnormals; /* number of normals in model */ GLuint numtexcoords; /* number of texcoords in model */ GLuint numtriangles; /* number of triangles in model */ GLfloat* vertices; /* array of vertices */ GLfloat* normals; /* array of normals */ GLfloat* texcoords; /* array of texture coordinates */ GLMgroup* group; /* current group pointer */ long int v, n, t; char buf[128]; /* set the pointer shortcuts */ vertices = model->vertices; normals = model->normals; texcoords = model->texcoords; group = model->groups; /* on the second pass through the file, read all the data into the allocated arrays */ numvertices = numnormals = numtexcoords = 1; numtriangles = 0; while(fscanf(file, "%s", buf) != EOF) { switch(buf[0]) { case '#': /* comment */ /* eat up rest of line */ fgets(buf, sizeof(buf), file); break; case 'v': /* v, vn, vt */ switch(buf[1]) { case '\0': /* vertex */ fscanf(file, "%f %f %f", &vertices[3 * numvertices + 0], &vertices[3 * numvertices + 1], &vertices[3 * numvertices + 2]); numvertices++; break; case 'n': /* normal */ fscanf(file, "%f %f %f", &normals[3 * numnormals + 0], &normals[3 * numnormals + 1], &normals[3 * numnormals + 2]); numnormals++; break; case 't': /* texcoord */ fscanf(file, "%f %f", &texcoords[2 * numtexcoords + 0], &texcoords[2 * numtexcoords + 1]); numtexcoords++; break; } break; case 'o': /* group */ /* eat up rest of line */ fgets(buf, sizeof(buf), file); #if SINGLE_STRING_GROUP_NAMES sscanf(buf, "%s", buf); group = glmFindGroup(model, buf); #else buf[strlen(buf)-1] = '\0'; /* nuke '\n' */ group = glmFindGroup(model, buf+1); #endif break; case 'b': /* group */ fgets(buf, sizeof(buf), file); buf[strlen(buf)-1] = '\0'; group->joint = strdup(buf+1); break; case 'd': /* group */ fgets(buf, sizeof(buf), file); buf[strlen(buf)-1] = '\0'; group->depen = strdup(buf+1); break; case 'f': /* face */ v = n = t = 0; fscanf(file, "%s", buf); /* can be one of %d, %d//%d, %d/%d, %d/%d/%d %d//%d */ /* Faces with > 3 vertices will be broken into triangle fans. */ if (strstr(buf, "//")) { /* v//n */ sscanf(buf, "%ld//%ld", &v, &n); T(numtriangles).vindices[0] = v; T(numtriangles).nindices[0] = n; fscanf(file, "%ld//%ld", &v, &n); T(numtriangles).vindices[1] = v; T(numtriangles).nindices[1] = n; fscanf(file, "%ld//%ld", &v, &n); T(numtriangles).vindices[2] = v; T(numtriangles).nindices[2] = n; group->triangles[group->numtriangles++] = numtriangles; numtriangles++; while(fscanf(file, "%ld//%ld", &v, &n) > 0) { T(numtriangles).vindices[0] = T(numtriangles-1).vindices[0]; T(numtriangles).nindices[0] = T(numtriangles-1).nindices[0]; T(numtriangles).vindices[1] = T(numtriangles-1).vindices[2]; T(numtriangles).nindices[1] = T(numtriangles-1).nindices[2]; T(numtriangles).vindices[2] = v; T(numtriangles).nindices[2] = n; group->triangles[group->numtriangles++] = numtriangles; numtriangles++; } } else if (sscanf(buf, "%ld/%ld/%ld", &v, &t, &n) == 3) { /* v/t/n */ T(numtriangles).vindices[0] = v; T(numtriangles).tindices[0] = t; T(numtriangles).nindices[0] = n; fscanf(file, "%ld/%ld/%ld", &v, &t, &n); T(numtriangles).vindices[1] = v; T(numtriangles).tindices[1] = t; T(numtriangles).nindices[1] = n; fscanf(file, "%ld/%ld/%ld", &v, &t, &n); T(numtriangles).vindices[2] = v; T(numtriangles).tindices[2] = t; T(numtriangles).nindices[2] = n; group->triangles[group->numtriangles++] = numtriangles; numtriangles++; while(fscanf(file, "%ld/%ld/%ld", &v, &t, &n) > 0) { T(numtriangles).vindices[0] = T(numtriangles-1).vindices[0]; T(numtriangles).tindices[0] = T(numtriangles-1).tindices[0]; T(numtriangles).nindices[0] = T(numtriangles-1).nindices[0]; T(numtriangles).vindices[1] = T(numtriangles-1).vindices[2]; T(numtriangles).tindices[1] = T(numtriangles-1).tindices[2]; T(numtriangles).nindices[1] = T(numtriangles-1).nindices[2]; T(numtriangles).vindices[2] = v; T(numtriangles).tindices[2] = t; T(numtriangles).nindices[2] = n; group->triangles[group->numtriangles++] = numtriangles; numtriangles++; } } else if (sscanf(buf, "%ld/%ld", &v, &t) == 2) { /* v/t */ T(numtriangles).vindices[0] = v; T(numtriangles).tindices[0] = t; fscanf(file, "%ld/%ld", &v, &t); T(numtriangles).vindices[1] = v; T(numtriangles).tindices[1] = t; fscanf(file, "%ld/%ld", &v, &t); T(numtriangles).vindices[2] = v; T(numtriangles).tindices[2] = t; group->triangles[group->numtriangles++] = numtriangles; numtriangles++; while(fscanf(file, "%ld/%ld", &v, &t) > 0) { T(numtriangles).vindices[0] = T(numtriangles-1).vindices[0]; T(numtriangles).tindices[0] = T(numtriangles-1).tindices[0]; T(numtriangles).vindices[1] = T(numtriangles-1).vindices[2]; T(numtriangles).tindices[1] = T(numtriangles-1).tindices[2]; T(numtriangles).vindices[2] = v; T(numtriangles).tindices[2] = t; group->triangles[group->numtriangles++] = numtriangles; numtriangles++; } } else { /* v */ sscanf(buf, "%ld", &v); T(numtriangles).vindices[0] = v; fscanf(file, "%ld", &v); T(numtriangles).vindices[1] = v; fscanf(file, "%ld", &v); T(numtriangles).vindices[2] = v; group->triangles[group->numtriangles++] = numtriangles; numtriangles++; while(fscanf(file, "%ld", &v) > 0) { T(numtriangles).vindices[0] = T(numtriangles-1).vindices[0]; T(numtriangles).vindices[1] = T(numtriangles-1).vindices[2]; T(numtriangles).vindices[2] = v; group->triangles[group->numtriangles++] = numtriangles; numtriangles++; } } break; default: /* eat up rest of line */ fgets(buf, sizeof(buf), file); break; } /* switch(buf[0]); */ } /* !EOF */ }