📄 glm.cpp
字号:
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 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
}
/* 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
*/
GLfloat glmUnitize(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.0f;
cy = (maxy + miny) / 2.0f;
cz = (maxz + minz) / 2.0f;
/* calculate unitizing scale factor */
scale = 2.0f / 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])
*/
GLvoid glmDimensions(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])
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -