📄 glm.c
字号:
/* eat up rest of line */ fgets(buf, sizeof(buf), file); numvertices++; break; case 'n': /* normal */ /* eat up rest of line */ fgets(buf, sizeof(buf), file); numnormals++; break; case 't': /* texcoord */ /* eat up rest of line */ fgets(buf, sizeof(buf), file); numtexcoords++; break; default: printf("glmFirstPass(): Unknown token \"%s\".\n", buf); exit(1); break; } break; case 'm': fgets(buf, sizeof(buf), file); sscanf(buf, "%s %s", buf, buf); model->mtllibname = strdup(buf); glmReadMTL(model, buf); break; case 'u': /* eat up rest of line */ fgets(buf, sizeof(buf), file); 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 = glmAddGroup(model, buf); 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); fscanf(file, "%d//%d", &v, &n); fscanf(file, "%d//%d", &v, &n); numtriangles++; group->numtriangles++; while(fscanf(file, "%d//%d", &v, &n) > 0) { numtriangles++; group->numtriangles++; } } else if (sscanf(buf, "%d/%d/%d", &v, &t, &n) == 3) { /* v/t/n */ fscanf(file, "%d/%d/%d", &v, &t, &n); fscanf(file, "%d/%d/%d", &v, &t, &n); numtriangles++; group->numtriangles++; while(fscanf(file, "%d/%d/%d", &v, &t, &n) > 0) { numtriangles++; group->numtriangles++; } } else if (sscanf(buf, "%d/%d", &v, &t) == 2) { /* v/t */ fscanf(file, "%d/%d", &v, &t); fscanf(file, "%d/%d", &v, &t); numtriangles++; group->numtriangles++; while(fscanf(file, "%d/%d", &v, &t) > 0) { numtriangles++; group->numtriangles++; } } else { /* v */ fscanf(file, "%d", &v); fscanf(file, "%d", &v); numtriangles++; group->numtriangles++; while(fscanf(file, "%d", &v) > 0) { numtriangles++; group->numtriangles++; } } break; default: /* eat up rest of line */ fgets(buf, sizeof(buf), file); break; } } /* set the stats in the model structure */ model->numvertices = numvertices; model->numnormals = numnormals; model->numtexcoords = numtexcoords; model->numtriangles = numtriangles; /* allocate memory for the triangles in each group */ group = model->groups; while(group) { group->triangles = (GLuint*)malloc(sizeof(GLuint) * group->numtriangles); group->numtriangles = 0; group = group->next; }}/* glmSecondPass: second pass at a Wavefront OBJ file that gets all * the data. * * model - properly initialized GLMmodel structure * file - (fopen'd) file descriptor */static GLvoidglmSecondPass(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}/* glmUnitize: "unitize" a model by translating it to the origin and * scaling it to fit in a unit cube around the origin (-1 to 1 in all * dimensions). * Returns the scalefactor used. * * model - properly initialized GLMmodel structure */GLfloatglmUnitize(GLMmodel* model){ GLuint i; GLfloat maxx, minx, maxy, miny, maxz, minz; GLfloat cx, cy, cz, w, h, d; GLfloat scale; assert(model); assert(model->vertices); /* get the max/mins */ maxx = minx = model->vertices[3 + 0]; maxy = miny = model->vertices[3 + 1]; maxz = minz = model->vertices[3 + 2]; for (i = 1; i <= model->numvertices; i++) { if (maxx < model->vertices[3 * i + 0]) maxx = model->vertices[3 * i + 0]; if (minx > model->vertices[3 * i + 0]) minx = model->vertices[3 * i + 0]; if (maxy < model->vertices[3 * i + 1]) maxy = model->vertices[3 * i + 1]; if (miny > model->vertices[3 * i + 1]) miny = model->vertices[3 * i + 1]; if (maxz < model->vertices[3 * i + 2]) maxz = model->vertices[3 * i + 2]; if (minz > model->vertices[3 * i + 2]) minz = model->vertices[3 * i + 2]; } /* calculate model width, height, and depth */ w = glmAbs(maxx) + glmAbs(minx); h = glmAbs(maxy) + glmAbs(miny); d = glmAbs(maxz) + glmAbs(minz); /* calculate center of the model */ cx = (maxx + minx) / 2.0; cy = (maxy + miny) / 2.0; cz = (maxz + minz) / 2.0; /* calculate unitizing scale factor */ scale = 2.0 / glmMax(glmMax(w, h), d); /* translate around center then scale */ for (i = 1; i <= model->numvertices; i++) { model->vertices[3 * i + 0] -= cx; model->vertices[3 * i + 1] -= cy; model->vertices[3 * i + 2] -= cz; model->vertices[3 * i + 0] *= scale; model->vertices[3 * i + 1] *= scale; model->vertices[3 * i + 2] *= scale; } return scale;}/* glmDimensions: Calculates the dimensions (width, height, depth) of * a model. * * model - initialized GLMmodel structure * dimensions - array of 3 GLfloats (GLfloat dimensions[3]) */GLvoidglmDimensions(GLMmodel* model, GLfloat* dimensions){ GLuint i; GLfloat maxx, minx, maxy, miny, maxz, minz; assert(model); assert(model->vertices); assert(dimensions); /* get the max/mins */ maxx = minx = model->vertices[3 + 0]; maxy = miny = model->vertices[3 + 1]; maxz = minz = model->vertices[3 + 2]; for (i = 1; i <= model->numvertices; i++) { if (maxx < model->vertices[3 * i + 0]) maxx = model->vertices[3 * i + 0]; if (minx > model->vertices[3 * i + 0]) minx = model->vertices[3 * i + 0]; if (maxy < model->vertices[3 * i + 1]) maxy = model->vertices[3 * i + 1]; if (miny > model->vertices[3 * i + 1]) miny = model->vertices[3 * i + 1]; if (maxz < model->vertices[3 * i + 2]) maxz = model->vertices[3 * i + 2]; if (minz > model->vertices[3 * i + 2]) minz = model->vertices[3 * i + 2]; } /* calculate model width, height, and depth */ dimensions[0] = glmAbs(maxx) + glmAbs(minx); dimensions[1] = glmAbs(maxy) + glmAbs(miny); dimensions[2] = glmAbs(maxz) + glmAbs(minz);}/* glmScale: Scales a model by a given amount. * * model - properly initialized GLMmodel structure * scale - scalefactor (0.5 = half as large, 2.0 = twice as large) */GLvoidglmScale(GLMmodel* model, GLfloat scale){ GLuint i; for (i = 1; i <= model->numvertices; i++) { model->vertices[3 * i + 0] *= scale; model->vertices[3 * i + 1] *= scale; model->vertices[3 * i + 2] *= scale; }}/* glmReverseWinding: Reverse the polygon winding for all polygons in * this model. Default winding is counter-clockwise. Also changes * the direction of the normals. * * model - properly initialized GLMmodel structure */GLvoidglmReverseWinding(GLMmodel* model){ GLuint i, swap; assert(model); for (i = 0; i < model->numtriangles; i++) { swap = T(i).vindices[0]; T(i).vindices[0] = T(i).vindices[2]; T(i).vindices[2] = swap; if (model->numnormals) { swap = T(i).nindices[0]; T(i).nindices[0] = T(i).nindices[2]; T(i).nindices[2] = swap; } if (model->numtexcoords) { swap = T(i).tindices[0]; T(i).tindices[0] = T(i).tindices[2]; T(i).tindices[2] = swap; } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -