#include <cmath>#include <cstdio>#include <cstring>#include <cstdlib>#include <cassert>#include <FL/glut.H>#include "glm.H"Include dependency graph for glm.cxx:

Compounds | |
| struct | _GLMnode |
Defines | |
| #define | T(x) model->triangles[(x)] |
Typedefs | |
| typedef _GLMnode | GLMnode |
Enumerations | |
| enum | { X, Y, Z, W } |
Functions | |
| char * | stralloc (const char *string) |
| GLfloat | _glmMax (GLfloat a, GLfloat b) |
| GLfloat | _glmAbs (GLfloat f) |
| GLfloat | _glmDot (GLfloat *u, GLfloat *v) |
| GLvoid | _glmCross (GLfloat *u, GLfloat *v, GLfloat *n) |
| GLvoid | _glmNormalize (GLfloat *n) |
| GLboolean | _glmEqual (GLfloat *u, GLfloat *v, GLfloat epsilon) |
| GLfloat * | _glmWeldVectors (GLfloat *vectors, GLuint *numvectors, GLfloat epsilon) |
| GLMgroup * | _glmFindGroup (GLMmodel *model, char *name) |
| GLMgroup * | _glmAddGroup (GLMmodel *model, char *name) |
| GLuint | _glmFindMaterial (GLMmodel *model, char *name) |
| char * | _glmDirName (char *path) |
| GLvoid | _glmReadMTL (GLMmodel *model, char *name) |
| GLvoid | _glmWriteMTL (GLMmodel *model, char *modelpath, char *mtllibname) |
| GLvoid | _glmFirstPass (GLMmodel *model, FILE *file) |
| GLvoid | _glmSecondPass (GLMmodel *model, FILE *file) |
| GLfloat | glmUnitize (GLMmodel *model) |
| GLvoid | glmDimensions (GLMmodel *model, GLfloat *dimensions) |
| GLvoid | glmScale (GLMmodel *model, GLfloat scale) |
| GLvoid | glmReverseWinding (GLMmodel *model) |
| GLvoid | glmFacetNormals (GLMmodel *model) |
| GLvoid | glmVertexNormals (GLMmodel *model, GLfloat angle) |
| GLvoid | glmLinearTexture (GLMmodel *model) |
| GLvoid | glmSpheremapTexture (GLMmodel *model) |
| GLvoid | glmDelete (GLMmodel *model) |
| GLMmodel * | glmReadOBJ (char *filename) |
| GLvoid | glmWriteOBJ (GLMmodel *model, char *filename, GLuint mode) |
| GLvoid | glmDraw (GLMmodel *model, GLuint mode) |
| GLuint | glmList (GLMmodel *model, GLuint mode) |
| GLvoid | glmWeld (GLMmodel *model, GLfloat epsilon) |
|
|
|
|
|
|
|
|
|
|
|
00049 {
00050 char *copy;
00051
00052 copy = (char *) malloc(strlen(string) + 1);
00053 if (copy == NULL)
00054 return NULL;
00055 strcpy(copy, string);
00056 return copy;
00057 }
|
|
||||||||||||
|
00064 {
00065 if (a > b)
00066 return a;
00067 return b;
00068 }
|
|
|
00073 {
00074 if (f < 0)
00075 return -f;
00076 return f;
00077 }
|
|
||||||||||||
|
|
|
||||||||||||||||
|
|
|
|
|
|
||||||||||||||||
|
|
|
||||||||||||||||
|
00160 {
00161 GLfloat* copies;
00162 GLuint copied;
00163 GLuint i, j;
00164
00165 copies = (GLfloat*)malloc(sizeof(GLfloat) * 3 * (*numvectors + 1));
00166 memcpy(copies, vectors, (sizeof(GLfloat) * 3 * (*numvectors + 1)));
00167
00168 copied = 1;
00169 for (i = 1; i <= *numvectors; i++) {
00170 for (j = 1; j <= copied; j++) {
00171 if (_glmEqual(&vectors[3 * i], &copies[3 * j], epsilon)) {
00172 goto duplicate;
00173 }
00174 }
00175
00176 /* must not be any duplicates -- add to the copies array */
00177 copies[3 * copied + 0] = vectors[3 * i + 0];
00178 copies[3 * copied + 1] = vectors[3 * i + 1];
00179 copies[3 * copied + 2] = vectors[3 * i + 2];
00180 j = copied; /* pass this along for below */
00181 copied++;
00182
00183 duplicate:
00184 /* set the first component of this vector to point at the correct
00185 index into the new copies array */
00186 vectors[3 * i + 0] = (GLfloat)j;
00187 }
00188
00189 *numvectors = copied-1;
00190 return copies;
00191 }
|
|
||||||||||||
|
00197 {
00198 GLMgroup* group;
00199
00200 assert(model);
00201
00202 group = model->groups;
00203 while(group) {
00204 if (!strcmp(name, group->name))
00205 break;
00206 group = group->next;
00207 }
00208
00209 return group;
00210 }
|
|
||||||||||||
|
00216 {
00217 GLMgroup* group;
00218
00219 group = _glmFindGroup(model, name);
00220 if (!group) {
00221 group = (GLMgroup*)malloc(sizeof(GLMgroup));
00222 group->name = stralloc(name);
00223 group->material = 0;
00224 group->numtriangles = 0;
00225 group->triangles = NULL;
00226 group->next = model->groups;
00227 model->groups = group;
00228 model->numgroups++;
00229 }
00230
00231 return group;
00232 }
|
|
||||||||||||
|
00238 {
00239 GLuint i;
00240
00241 for (i = 0; i < model->nummaterials; i++) {
00242 if (!strcmp(model->materials[i].name, name))
00243 goto found;
00244 }
00245
00246 /* didn't find the name, so set it as the default material */
00247 printf("_glmFindMaterial(): can't find material \"%s\".\n", name);
00248 i = 0;
00249
00250 found:
00251 return i;
00252 }
|
|
|
00263 {
00264 char* dir;
00265 char* s;
00266
00267 dir = stralloc(path);
00268
00269 s = strrchr(dir, '/');
00270 if (s)
00271 s[1] = '\0';
00272 else
00273 dir[0] = '\0';
00274
00275 return dir;
00276 }
|
|
||||||||||||
|
00286 {
00287 FILE* file;
00288 char* dir;
00289 char* filename;
00290 char buf[128];
00291 GLuint nummaterials, i;
00292
00293 dir = _glmDirName(model->pathname);
00294 filename = (char*)malloc(sizeof(char) * (strlen(dir) + strlen(name) + 1));
00295 strcpy(filename, dir);
00296 strcat(filename, name);
00297 free(dir);
00298
00299 /* open the file */
00300 file = fopen(filename, "r");
00301 if (!file) {
00302 fprintf(stderr, "_glmReadMTL() failed: can't open material file \"%s\".\n",
00303 filename);
00304 exit(1);
00305 }
00306 free(filename);
00307
00308 /* count the number of materials in the file */
00309 nummaterials = 1;
00310 while(fscanf(file, "%s", buf) != EOF) {
00311 switch(buf[0]) {
00312 case '#': /* comment */
00313 /* eat up rest of line */
00314 fgets(buf, sizeof(buf), file);
00315 break;
00316 case 'n': /* newmtl */
00317 fgets(buf, sizeof(buf), file);
00318 nummaterials++;
00319 sscanf(buf, "%s %s", buf, buf);
00320 break;
00321 default:
00322 /* eat up rest of line */
00323 fgets(buf, sizeof(buf), file);
00324 break;
00325 }
00326 }
00327
00328 rewind(file);
00329
00330 /* allocate memory for the materials */
00331 model->materials = (GLMmaterial*)malloc(sizeof(GLMmaterial) * nummaterials);
00332 model->nummaterials = nummaterials;
00333
00334 /* set the default material */
00335 for (i = 0; i < nummaterials; i++) {
00336 model->materials[i].name = NULL;
00337 model->materials[i].shininess = 0;
00338 model->materials[i].diffuse[0] = 0.8;
00339 model->materials[i].diffuse[1] = 0.8;
00340 model->materials[i].diffuse[2] = 0.8;
00341 model->materials[i].diffuse[3] = 1.0;
00342 model->materials[i].ambient[0] = 0.2;
00343 model->materials[i].ambient[1] = 0.2;
00344 model->materials[i].ambient[2] = 0.2;
00345 model->materials[i].ambient[3] = 1.0;
00346 model->materials[i].specular[0] = 0.0;
00347 model->materials[i].specular[1] = 0.0;
00348 model->materials[i].specular[2] = 0.0;
00349 model->materials[i].specular[3] = 1.0;
00350 }
00351 model->materials[0].name = stralloc("default");
00352
00353 /* now, read in the data */
00354 nummaterials = 0;
00355 while(fscanf(file, "%s", buf) != EOF) {
00356 switch(buf[0]) {
00357 case '#': /* comment */
00358 /* eat up rest of line */
00359 fgets(buf, sizeof(buf), file);
00360 break;
00361 case 'n': /* newmtl */
00362 fgets(buf, sizeof(buf), file);
00363 sscanf(buf, "%s %s", buf, buf);
00364 nummaterials++;
00365 model->materials[nummaterials].name = stralloc(buf);
00366 break;
00367 case 'N':
00368 fscanf(file, "%f", &model->materials[nummaterials].shininess);
00369 /* wavefront shininess is from [0, 1000], so scale for OpenGL */
00370 model->materials[nummaterials].shininess /= 1000.0;
00371 model->materials[nummaterials].shininess *= 128.0;
00372 break;
00373 case 'K':
00374 switch(buf[1]) {
00375 case 'd':
00376 fscanf(file, "%f %f %f",
00377 &model->materials[nummaterials].diffuse[0],
00378 &model->materials[nummaterials].diffuse[1],
00379 &model->materials[nummaterials].diffuse[2]);
00380 break;
00381 case 's':
00382 fscanf(file, "%f %f %f",
00383 &model->materials[nummaterials].specular[0],
00384 &model->materials[nummaterials].specular[1],
00385 &model->materials[nummaterials].specular[2]);
00386 break;
00387 case 'a':
00388 fscanf(file, "%f %f %f",
00389 &model->materials[nummaterials].ambient[0],
00390 &model->materials[nummaterials].ambient[1],
00391 &model->materials[nummaterials].ambient[2]);
00392 break;
00393 default:
00394 /* eat up rest of line */
00395 fgets(buf, sizeof(buf), file);
00396 break;
00397 }
00398 break;
00399 default:
00400 /* eat up rest of line */
00401 fgets(buf, sizeof(buf), file);
00402 break;
00403 }
00404 }
00405 }
|
|
||||||||||||||||
|
00415 {
00416 FILE* file;
00417 char* dir;
00418 char* filename;
00419 GLMmaterial* material;
00420 GLuint i;
00421
00422 dir = _glmDirName(modelpath);
00423 filename = (char*)malloc(sizeof(char) * (strlen(dir) + strlen(mtllibname)));
00424 strcpy(filename, dir);
00425 strcat(filename, mtllibname);
00426 free(dir);
00427
00428 /* open the file */
00429 file = fopen(filename, "w");
00430 if (!file) {
00431 fprintf(stderr, "_glmWriteMTL() failed: can't open file \"%s\".\n",
00432 filename);
00433 exit(1);
00434 }
00435 free(filename);
00436
00437 /* spit out a header */
00438 fprintf(file, "# \n");
00439 fprintf(file, "# Wavefront MTL generated by GLM library\n");
00440 fprintf(file, "# \n");
00441 fprintf(file, "# GLM library copyright (C) 1997 by Nate Robins\n");
00442 fprintf(file, "# email: ndr@pobox.com\n");
00443 fprintf(file, "# www: http://www.pobox.com/~ndr\n");
00444 fprintf(file, "# \n\n");
00445
00446 for (i = 0; i < model->nummaterials; i++) {
00447 material = &model->materials[i];
00448 fprintf(file, "newmtl %s\n", material->name);
00449 fprintf(file, "Ka %f %f %f\n",
00450 material->ambient[0], material->ambient[1], material->ambient[2]);
00451 fprintf(file, "Kd %f %f %f\n",
00452 material->diffuse[0], material->diffuse[1], material->diffuse[2]);
00453 fprintf(file, "Ks %f %f %f\n",
00454 material->specular[0],material->specular[1],material->specular[2]);
00455 fprintf(file, "Ns %f\n", material->shininess);
00456 fprintf(file, "\n");
00457 }
00458 }
|
|
||||||||||||
|
00469 {
00470 GLuint numvertices; /* number of vertices in model */
00471 GLuint numnormals; /* number of normals in model */
00472 GLuint numtexcoords; /* number of texcoords in model */
00473 GLuint numtriangles; /* number of triangles in model */
00474 GLMgroup* group; /* current group */
00475 unsigned v, n, t;
00476 char buf[128];
00477
00478 /* make a default group */
00479 group = _glmAddGroup(model, "default");
00480
00481 numvertices = numnormals = numtexcoords = numtriangles = 0;
00482 while(fscanf(file, "%s", buf) != EOF) {
00483 switch(buf[0]) {
00484 case '#': /* comment */
00485 /* eat up rest of line */
00486 fgets(buf, sizeof(buf), file);
00487 break;
00488 case 'v': /* v, vn, vt */
00489 switch(buf[1]) {
00490 case '\0': /* vertex */
00491 /* eat up rest of line */
00492 fgets(buf, sizeof(buf), file);
00493 numvertices++;
00494 break;
00495 case 'n': /* normal */
00496 /* eat up rest of line */
00497 fgets(buf, sizeof(buf), file);
00498 numnormals++;
00499 break;
00500 case 't': /* texcoord */
00501 /* eat up rest of line */
00502 fgets(buf, sizeof(buf), file);
00503 numtexcoords++;
00504 break;
00505 default:
00506 printf("_glmFirstPass(): Unknown token \"%s\".\n", buf);
00507 exit(1);
00508 break;
00509 }
00510 break;
00511 case 'm':
00512 fgets(buf, sizeof(buf), file);
00513 sscanf(buf, "%s %s", buf, buf);
00514 model->mtllibname = stralloc(buf);
00515 _glmReadMTL(model, buf);
00516 break;
00517 case 'u':
00518 /* eat up rest of line */
00519 fgets(buf, sizeof(buf), file);
00520 break;
00521 case 'g': /* group */
00522 /* eat up rest of line */
00523 fgets(buf, sizeof(buf), file);
00524 sscanf(buf, "%[^\t\n\r]", buf);
00525 group = _glmAddGroup(model, buf);
00526 break;
00527 case 'f': /* face */
00528 v = n = t = 0;
00529 fscanf(file, "%s", buf);
00530 /* can be one of %d, %d//%d, %d/%d, %d/%d/%d %d//%d */
00531 if (strstr(buf, "//")) {
00532 /* v//n */
00533 sscanf(buf, "%d//%d", &v, &n);
00534 fscanf(file, "%d//%d", &v, &n);
00535 fscanf(file, "%d//%d", &v, &n);
00536 numtriangles++;
00537 group->numtriangles++;
00538 while(fscanf(file, "%d//%d", &v, &n) > 0) {
00539 numtriangles++;
00540 group->numtriangles++;
00541 }
00542 } else if (sscanf(buf, "%d/%d/%d", &v, &t, &n) == 3) {
00543 /* v/t/n */
00544 fscanf(file, "%d/%d/%d", &v, &t, &n);
00545 fscanf(file, "%d/%d/%d", &v, &t, &n);
00546 numtriangles++;
00547 group->numtriangles++;
00548 while(fscanf(file, "%d/%d/%d", &v, &t, &n) > 0) {
00549 numtriangles++;
00550 group->numtriangles++;
00551 }
00552 } else if (sscanf(buf, "%d/%d", &v, &t) == 2) {
00553 /* v/t */
00554 fscanf(file, "%d/%d", &v, &t);
00555 fscanf(file, "%d/%d", &v, &t);
00556 numtriangles++;
00557 group->numtriangles++;
00558 while(fscanf(file, "%d/%d", &v, &t) > 0) {
00559 numtriangles++;
00560 group->numtriangles++;
00561 }
00562 } else {
00563 /* v */
00564 fscanf(file, "%d", &v);
00565 fscanf(file, "%d", &v);
00566 numtriangles++;
00567 group->numtriangles++;
00568 while(fscanf(file, "%d", &v) > 0) {
00569 numtriangles++;
00570 group->numtriangles++;
00571 }
00572 }
00573 break;
00574
00575 default:
00576 /* eat up rest of line */
00577 fgets(buf, sizeof(buf), file);
00578 break;
00579 }
00580 }
00581
00582 #if 0
00583 /* announce the model statistics */
00584 printf(" Vertices: %d\n", numvertices);
00585 printf(" Normals: %d\n", numnormals);
00586 printf(" Texcoords: %d\n", numtexcoords);
00587 printf(" Triangles: %d\n", numtriangles);
00588 printf(" Groups: %d\n", model->numgroups);
00589 #endif
00590
00591 /* set the stats in the model structure */
00592 model->numvertices = numvertices;
00593 model->numnormals = numnormals;
00594 model->numtexcoords = numtexcoords;
00595 model->numtriangles = numtriangles;
00596
00597 /* allocate memory for the triangles in each group */
00598 group = model->groups;
00599 while(group) {
00600 group->triangles = (GLuint*)malloc(sizeof(GLuint) * group->numtriangles);
00601 group->numtriangles = 0;
00602 group = group->next;
00603 }
00604 }
|
|
||||||||||||
|
00614 {
00615 GLuint numvertices; /* number of vertices in model */
00616 GLuint numnormals; /* number of normals in model */
00617 GLuint numtexcoords; /* number of texcoords in model */
00618 GLuint numtriangles; /* number of triangles in model */
00619 GLfloat* vertices; /* array of vertices */
00620 GLfloat* normals; /* array of normals */
00621 GLfloat* texcoords; /* array of texture coordinates */
00622 GLMgroup* group; /* current group pointer */
00623 GLuint material; /* current material */
00624 GLuint v, n, t;
00625 char buf[128];
00626
00627 /* set the pointer shortcuts */
00628 vertices = model->vertices;
00629 normals = model->normals;
00630 texcoords = model->texcoords;
00631 group = model->groups;
00632
00633 /* on the second pass through the file, read all the data into the
00634 allocated arrays */
00635 numvertices = numnormals = numtexcoords = 1;
00636 numtriangles = 0;
00637 material = 0;
00638 while(fscanf(file, "%s", buf) != EOF) {
00639 switch(buf[0]) {
00640 case '#': /* comment */
00641 /* eat up rest of line */
00642 fgets(buf, sizeof(buf), file);
00643 break;
00644 case 'v': /* v, vn, vt */
00645 switch(buf[1]) {
00646 case '\0': /* vertex */
00647 fscanf(file, "%f %f %f",
00648 &vertices[3 * numvertices + X],
00649 &vertices[3 * numvertices + Y],
00650 &vertices[3 * numvertices + Z]);
00651 numvertices++;
00652 break;
00653 case 'n': /* normal */
00654 fscanf(file, "%f %f %f",
00655 &normals[3 * numnormals + X],
00656 &normals[3 * numnormals + Y],
00657 &normals[3 * numnormals + Z]);
00658 numnormals++;
00659 break;
00660 case 't': /* texcoord */
00661 fscanf(file, "%f %f",
00662 &texcoords[2 * numtexcoords + X],
00663 &texcoords[2 * numtexcoords + Y]);
00664 numtexcoords++;
00665 break;
00666 }
00667 break;
00668 case 'u':
00669 fgets(buf, sizeof(buf), file);
00670 sscanf(buf, "%s %s", buf, buf);
00671 group->material = material = _glmFindMaterial(model, buf);
00672 break;
00673 case 'g': /* group */
00674 /* eat up rest of line */
00675 fgets(buf, sizeof(buf), file);
00676 sscanf(buf, "%[^\t\r\n]", buf);
00677 group = _glmFindGroup(model, buf);
00678 group->material = material;
00679 break;
00680 case 'f': /* face */
00681 v = n = t = 0;
00682 fscanf(file, "%s", buf);
00683 /* can be one of %d, %d//%d, %d/%d, %d/%d/%d %d//%d */
00684 if (strstr(buf, "//")) {
00685 /* v//n */
00686 sscanf(buf, "%d//%d", &v, &n);
00687 T(numtriangles).vindices[0] = v;
00688 T(numtriangles).nindices[0] = n;
00689 fscanf(file, "%d//%d", &v, &n);
00690 T(numtriangles).vindices[1] = v;
00691 T(numtriangles).nindices[1] = n;
00692 fscanf(file, "%d//%d", &v, &n);
00693 T(numtriangles).vindices[2] = v;
00694 T(numtriangles).nindices[2] = n;
00695 group->triangles[group->numtriangles++] = numtriangles;
00696 numtriangles++;
00697 while(fscanf(file, "%d//%d", &v, &n) > 0) {
00698 T(numtriangles).vindices[0] = T(numtriangles-1).vindices[0];
00699 T(numtriangles).nindices[0] = T(numtriangles-1).nindices[0];
00700 T(numtriangles).vindices[1] = T(numtriangles-1).vindices[2];
00701 T(numtriangles).nindices[1] = T(numtriangles-1).nindices[2];
00702 T(numtriangles).vindices[2] = v;
00703 T(numtriangles).nindices[2] = n;
00704 group->triangles[group->numtriangles++] = numtriangles;
00705 numtriangles++;
00706 }
00707 } else if (sscanf(buf, "%d/%d/%d", &v, &t, &n) == 3) {
00708 /* v/t/n */
00709 T(numtriangles).vindices[0] = v;
00710 T(numtriangles).tindices[0] = t;
00711 T(numtriangles).nindices[0] = n;
00712 fscanf(file, "%d/%d/%d", &v, &t, &n);
00713 T(numtriangles).vindices[1] = v;
00714 T(numtriangles).tindices[1] = t;
00715 T(numtriangles).nindices[1] = n;
00716 fscanf(file, "%d/%d/%d", &v, &t, &n);
00717 T(numtriangles).vindices[2] = v;
00718 T(numtriangles).tindices[2] = t;
00719 T(numtriangles).nindices[2] = n;
00720 group->triangles[group->numtriangles++] = numtriangles;
00721 numtriangles++;
00722 while(fscanf(file, "%d/%d/%d", &v, &t, &n) > 0) {
00723 T(numtriangles).vindices[0] = T(numtriangles-1).vindices[0];
00724 T(numtriangles).tindices[0] = T(numtriangles-1).tindices[0];
00725 T(numtriangles).nindices[0] = T(numtriangles-1).nindices[0];
00726 T(numtriangles).vindices[1] = T(numtriangles-1).vindices[2];
00727 T(numtriangles).tindices[1] = T(numtriangles-1).tindices[2];
00728 T(numtriangles).nindices[1] = T(numtriangles-1).nindices[2];
00729 T(numtriangles).vindices[2] = v;
00730 T(numtriangles).tindices[2] = t;
00731 T(numtriangles).nindices[2] = n;
00732 group->triangles[group->numtriangles++] = numtriangles;
00733 numtriangles++;
00734 }
00735 } else if (sscanf(buf, "%d/%d", &v, &t) == 2) {
00736 /* v/t */
00737 T(numtriangles).vindices[0] = v;
00738 T(numtriangles).tindices[0] = t;
00739 fscanf(file, "%d/%d", &v, &t);
00740 T(numtriangles).vindices[1] = v;
00741 T(numtriangles).tindices[1] = t;
00742 fscanf(file, "%d/%d", &v, &t);
00743 T(numtriangles).vindices[2] = v;
00744 T(numtriangles).tindices[2] = t;
00745 group->triangles[group->numtriangles++] = numtriangles;
00746 numtriangles++;
00747 while(fscanf(file, "%d/%d", &v, &t) > 0) {
00748 T(numtriangles).vindices[0] = T(numtriangles-1).vindices[0];
00749 T(numtriangles).tindices[0] = T(numtriangles-1).tindices[0];
00750 T(numtriangles).vindices[1] = T(numtriangles-1).vindices[2];
00751 T(numtriangles).tindices[1] = T(numtriangles-1).tindices[2];
00752 T(numtriangles).vindices[2] = v;
00753 T(numtriangles).tindices[2] = t;
00754 group->triangles[group->numtriangles++] = numtriangles;
00755 numtriangles++;
00756 }
00757 } else {
00758 /* v */
00759 sscanf(buf, "%d", &v);
00760 T(numtriangles).vindices[0] = v;
00761 fscanf(file, "%d", &v);
00762 T(numtriangles).vindices[1] = v;
00763 fscanf(file, "%d", &v);
00764 T(numtriangles).vindices[2] = v;
00765 group->triangles[group->numtriangles++] = numtriangles;
00766 numtriangles++;
00767 while(fscanf(file, "%d", &v) > 0) {
00768 T(numtriangles).vindices[0] = T(numtriangles-1).vindices[0];
00769 T(numtriangles).vindices[1] = T(numtriangles-1).vindices[2];
00770 T(numtriangles).vindices[2] = v;
00771 group->triangles[group->numtriangles++] = numtriangles;
00772 numtriangles++;
00773 }
00774 }
00775 break;
00776
00777 default:
00778 /* eat up rest of line */
00779 fgets(buf, sizeof(buf), file);
00780 break;
00781 }
00782 }
00783
00784 #if 0
00785 /* announce the memory requirements */
00786 printf(" Memory: %d bytes\n",
00787 numvertices * 3*sizeof(GLfloat) +
00788 numnormals * 3*sizeof(GLfloat) * (numnormals ? 1 : 0) +
00789 numtexcoords * 3*sizeof(GLfloat) * (numtexcoords ? 1 : 0) +
00790 numtriangles * sizeof(GLMtriangle));
00791 #endif
00792 }
|
|
|
00807 {
00808 GLuint i;
00809 GLfloat maxx, minx, maxy, miny, maxz, minz;
00810 GLfloat cx, cy, cz, w, h, d;
00811 GLfloat scale;
00812
00813 assert(model);
00814 assert(model->vertices);
00815
00816 /* get the max/mins */
00817 maxx = minx = model->vertices[3 + X];
00818 maxy = miny = model->vertices[3 + Y];
00819 maxz = minz = model->vertices[3 + Z];
00820 for (i = 1; i <= model->numvertices; i++) {
00821 if (maxx < model->vertices[3 * i + X])
00822 maxx = model->vertices[3 * i + X];
00823 if (minx > model->vertices[3 * i + X])
00824 minx = model->vertices[3 * i + X];
00825
00826 if (maxy < model->vertices[3 * i + Y])
00827 maxy = model->vertices[3 * i + Y];
00828 if (miny > model->vertices[3 * i + Y])
00829 miny = model->vertices[3 * i + Y];
00830
00831 if (maxz < model->vertices[3 * i + Z])
00832 maxz = model->vertices[3 * i + Z];
00833 if (minz > model->vertices[3 * i + Z])
00834 minz = model->vertices[3 * i + Z];
00835 }
00836
00837 /* calculate model width, height, and depth */
00838 w = _glmAbs(maxx) + _glmAbs(minx);
00839 h = _glmAbs(maxy) + _glmAbs(miny);
00840 d = _glmAbs(maxz) + _glmAbs(minz);
00841
00842 /* calculate center of the model */
00843 cx = (maxx + minx) / 2.0;
00844 cy = (maxy + miny) / 2.0;
00845 cz = (maxz + minz) / 2.0;
00846
00847 /* calculate unitizing scale factor */
00848 scale = 2.0 / _glmMax(_glmMax(w, h), d);
00849
00850 /* translate around center then scale */
00851 for (i = 1; i <= model->numvertices; i++) {
00852 model->vertices[3 * i + X] -= cx;
00853 model->vertices[3 * i + Y] -= cy;
00854 model->vertices[3 * i + Z] -= cz;
00855 model->vertices[3 * i + X] *= scale;
00856 model->vertices[3 * i + Y] *= scale;
00857 model->vertices[3 * i + Z] *= scale;
00858 }
00859
00860 return scale;
00861 }
|
|
||||||||||||
|
00871 {
00872 GLuint i;
00873 GLfloat maxx, minx, maxy, miny, maxz, minz;
00874
00875 assert(model);
00876 assert(model->vertices);
00877 assert(dimensions);
00878
00879 /* get the max/mins */
00880 maxx = minx = model->vertices[3 + X];
00881 maxy = miny = model->vertices[3 + Y];
00882 maxz = minz = model->vertices[3 + Z];
00883 for (i = 1; i <= model->numvertices; i++) {
00884 if (maxx < model->vertices[3 * i + X])
00885 maxx = model->vertices[3 * i + X];
00886 if (minx > model->vertices[3 * i + X])
00887 minx = model->vertices[3 * i + X];
00888
00889 if (maxy < model->vertices[3 * i + Y])
00890 maxy = model->vertices[3 * i + Y];
00891 if (miny > model->vertices[3 * i + Y])
00892 miny = model->vertices[3 * i + Y];
00893
00894 if (maxz < model->vertices[3 * i + Z])
00895 maxz = model->vertices[3 * i + Z];
00896 if (minz > model->vertices[3 * i + Z])
00897 minz = model->vertices[3 * i + Z];
00898 }
00899
00900 /* calculate model width, height, and depth */
00901 dimensions[X] = _glmAbs(maxx) + _glmAbs(minx);
00902 dimensions[Y] = _glmAbs(maxy) + _glmAbs(miny);
00903 dimensions[Z] = _glmAbs(maxz) + _glmAbs(minz);
00904 }
|
|
||||||||||||
|
|
|
|
00931 {
00932 GLuint i, swap;
00933
00934 assert(model);
00935
00936 for (i = 0; i < model->numtriangles; i++) {
00937 swap = T(i).vindices[0];
00938 T(i).vindices[0] = T(i).vindices[2];
00939 T(i).vindices[2] = swap;
00940
00941 if (model->numnormals) {
00942 swap = T(i).nindices[0];
00943 T(i).nindices[0] = T(i).nindices[2];
00944 T(i).nindices[2] = swap;
00945 }
00946
00947 if (model->numtexcoords) {
00948 swap = T(i).tindices[0];
00949 T(i).tindices[0] = T(i).tindices[2];
00950 T(i).tindices[2] = swap;
00951 }
00952 }
00953
00954 /* reverse facet normals */
00955 for (i = 1; i <= model->numfacetnorms; i++) {
00956 model->facetnorms[3 * i + X] = -model->facetnorms[3 * i + X];
00957 model->facetnorms[3 * i + Y] = -model->facetnorms[3 * i + Y];
00958 model->facetnorms[3 * i + Z] = -model->facetnorms[3 * i + Z];
00959 }
00960
00961 /* reverse vertex normals */
00962 for (i = 1; i <= model->numnormals; i++) {
00963 model->normals[3 * i + X] = -model->normals[3 * i + X];
00964 model->normals[3 * i + Y] = -model->normals[3 * i + Y];
00965 model->normals[3 * i + Z] = -model->normals[3 * i + Z];
00966 }
00967 }
|
|
|
00977 {
00978 GLuint i;
00979 GLfloat u[3];
00980 GLfloat v[3];
00981
00982 assert(model);
00983 assert(model->vertices);
00984
00985 /* clobber any old facetnormals */
00986 if (model->facetnorms)
00987 free(model->facetnorms);
00988
00989 /* allocate memory for the new facet normals */
00990 model->numfacetnorms = model->numtriangles;
00991 model->facetnorms = (GLfloat*)malloc(sizeof(GLfloat) *
00992 3 * (model->numfacetnorms + 1));
00993
00994 for (i = 0; i < model->numtriangles; i++) {
00995 model->triangles[i].findex = i+1;
00996
00997 u[X] = model->vertices[3 * T(i).vindices[1] + X] -
00998 model->vertices[3 * T(i).vindices[0] + X];
00999 u[Y] = model->vertices[3 * T(i).vindices[1] + Y] -
01000 model->vertices[3 * T(i).vindices[0] + Y];
01001 u[Z] = model->vertices[3 * T(i).vindices[1] + Z] -
01002 model->vertices[3 * T(i).vindices[0] + Z];
01003
01004 v[X] = model->vertices[3 * T(i).vindices[2] + X] -
01005 model->vertices[3 * T(i).vindices[0] + X];
01006 v[Y] = model->vertices[3 * T(i).vindices[2] + Y] -
01007 model->vertices[3 * T(i).vindices[0] + Y];
01008 v[Z] = model->vertices[3 * T(i).vindices[2] + Z] -
01009 model->vertices[3 * T(i).vindices[0] + Z];
01010
01011 _glmCross(u, v, &model->facetnorms[3 * (i+1)]);
01012 _glmNormalize(&model->facetnorms[3 * (i+1)]);
01013 }
01014 }
|
|
||||||||||||
|
01034 {
01035 GLMnode* node;
01036 GLMnode* tail;
01037 GLMnode** members;
01038 GLfloat* normals;
01039 GLuint numnormals;
01040 GLfloat average[3];
01041 GLfloat dot, cos_angle;
01042 GLuint i, avg;
01043
01044 assert(model);
01045 assert(model->facetnorms);
01046
01047 /* calculate the cosine of the angle (in degrees) */
01048 cos_angle = cos(angle * M_PI / 180.0);
01049
01050 /* nuke any previous normals */
01051 if (model->normals)
01052 free(model->normals);
01053
01054 /* allocate space for new normals */
01055 model->numnormals = model->numtriangles * 3; /* 3 normals per triangle */
01056 model->normals = (GLfloat*)malloc(sizeof(GLfloat)* 3* (model->numnormals+1));
01057
01058 /* allocate a structure that will hold a linked list of triangle
01059 indices for each vertex */
01060 members = (GLMnode**)malloc(sizeof(GLMnode*) * (model->numvertices + 1));
01061 for (i = 1; i <= model->numvertices; i++)
01062 members[i] = NULL;
01063
01064 /* for every triangle, create a node for each vertex in it */
01065 for (i = 0; i < model->numtriangles; i++) {
01066 node = (GLMnode*)malloc(sizeof(GLMnode));
01067 node->index = i;
01068 node->next = members[T(i).vindices[0]];
01069 members[T(i).vindices[0]] = node;
01070
01071 node = (GLMnode*)malloc(sizeof(GLMnode));
01072 node->index = i;
01073 node->next = members[T(i).vindices[1]];
01074 members[T(i).vindices[1]] = node;
01075
01076 node = (GLMnode*)malloc(sizeof(GLMnode));
01077 node->index = i;
01078 node->next = members[T(i).vindices[2]];
01079 members[T(i).vindices[2]] = node;
01080 }
01081
01082 /* calculate the average normal for each vertex */
01083 numnormals = 1;
01084 for (i = 1; i <= model->numvertices; i++) {
01085 /* calculate an average normal for this vertex by averaging the
01086 facet normal of every triangle this vertex is in */
01087 node = members[i];
01088 if (!node)
01089 fprintf(stderr, "glmVertexNormals(): vertex w/o a triangle\n");
01090 average[0] = 0.0; average[1] = 0.0; average[2] = 0.0;
01091 avg = 0;
01092 while (node) {
01093 /* only average if the dot product of the angle between the two
01094 facet normals is greater than the cosine of the threshold
01095 angle -- or, said another way, the angle between the two
01096 facet normals is less than (or equal to) the threshold angle */
01097 dot = _glmDot(&model->facetnorms[3 * T(node->index).findex],
01098 &model->facetnorms[3 * T(members[i]->index).findex]);
01099 if (dot > cos_angle) {
01100 node->averaged = GL_TRUE;
01101 average[0] += model->facetnorms[3 * T(node->index).findex + 0];
01102 average[1] += model->facetnorms[3 * T(node->index).findex + 1];
01103 average[2] += model->facetnorms[3 * T(node->index).findex + 2];
01104 avg = 1; /* we averaged at least one normal! */
01105 } else {
01106 node->averaged = GL_FALSE;
01107 }
01108 node = node->next;
01109 }
01110
01111 if (avg) {
01112 /* normalize the averaged normal */
01113 _glmNormalize(average);
01114
01115 /* add the normal to the vertex normals list */
01116 model->normals[3 * numnormals + 0] = average[0];
01117 model->normals[3 * numnormals + 1] = average[1];
01118 model->normals[3 * numnormals + 2] = average[2];
01119 avg = numnormals;
01120 numnormals++;
01121 }
01122
01123 /* set the normal of this vertex in each triangle it is in */
01124 node = members[i];
01125 while (node) {
01126 if (node->averaged) {
01127 /* if this node was averaged, use the average normal */
01128 if (T(node->index).vindices[0] == i)
01129 T(node->index).nindices[0] = avg;
01130 else if (T(node->index).vindices[1] == i)
01131 T(node->index).nindices[1] = avg;
01132 else if (T(node->index).vindices[2] == i)
01133 T(node->index).nindices[2] = avg;
01134 } else {
01135 /* if this node wasn't averaged, use the facet normal */
01136 model->normals[3 * numnormals + 0] =
01137 model->facetnorms[3 * T(node->index).findex + 0];
01138 model->normals[3 * numnormals + 1] =
01139 model->facetnorms[3 * T(node->index).findex + 1];
01140 model->normals[3 * numnormals + 2] =
01141 model->facetnorms[3 * T(node->index).findex + 2];
01142 if (T(node->index).vindices[0] == i)
01143 T(node->index).nindices[0] = numnormals;
01144 else if (T(node->index).vindices[1] == i)
01145 T(node->index).nindices[1] = numnormals;
01146 else if (T(node->index).vindices[2] == i)
01147 T(node->index).nindices[2] = numnormals;
01148 numnormals++;
01149 }
01150 node = node->next;
01151 }
01152 }
01153
01154 model->numnormals = numnormals - 1;
01155
01156 /* free the member information */
01157 for (i = 1; i <= model->numvertices; i++) {
01158 node = members[i];
01159 while (node) {
01160 tail = node;
01161 node = node->next;
01162 free(tail);
01163 }
01164 }
01165 free(members);
01166
01167 /* pack the normals array (we previously allocated the maximum
01168 number of normals that could possibly be created (numtriangles *
01169 3), so get rid of some of them (usually alot unless none of the
01170 facet normals were averaged)) */
01171 normals = model->normals;
01172 model->normals = (GLfloat*)malloc(sizeof(GLfloat)* 3* (model->numnormals+1));
01173 for (i = 1; i <= model->numnormals; i++) {
01174 model->normals[3 * i + 0] = normals[3 * i + 0];
01175 model->normals[3 * i + 1] = normals[3 * i + 1];
01176 model->normals[3 * i + 2] = normals[3 * i + 2];
01177 }
01178 free(normals);
01179
01180 printf("glmVertexNormals(): %d normals generated\n", model->numnormals);
01181 }
|
|
|
01192 {
01193 GLMgroup *group;
01194 GLfloat dimensions[3];
01195 GLfloat x, y, scalefactor;
01196 GLuint i;
01197
01198 assert(model);
01199
01200 if (model->texcoords)
01201 free(model->texcoords);
01202 model->numtexcoords = model->numvertices;
01203 model->texcoords=(GLfloat*)malloc(sizeof(GLfloat)*2*(model->numtexcoords+1));
01204
01205 glmDimensions(model, dimensions);
01206 scalefactor = 2.0 /
01207 _glmAbs(_glmMax(_glmMax(dimensions[0], dimensions[1]), dimensions[2]));
01208
01209 /* do the calculations */
01210 for(i = 1; i <= model->numvertices; i++) {
01211 x = model->vertices[3 * i + 0] * scalefactor;
01212 y = model->vertices[3 * i + 2] * scalefactor;
01213 model->texcoords[2 * i + 0] = (x + 1.0) / 2.0;
01214 model->texcoords[2 * i + 1] = (y + 1.0) / 2.0;
01215 }
01216
01217 /* go through and put texture coordinate indices in all the triangles */
01218 group = model->groups;
01219 while(group) {
01220 for(i = 0; i < group->numtriangles; i++) {
01221 T(group->triangles[i]).tindices[0] = T(group->triangles[i]).vindices[0];
01222 T(group->triangles[i]).tindices[1] = T(group->triangles[i]).vindices[1];
01223 T(group->triangles[i]).tindices[2] = T(group->triangles[i]).vindices[2];
01224 }
01225 group = group->next;
01226 }
01227
01228 #if 0
01229 printf("glmLinearTexture(): generated %d linear texture coordinates\n",
01230 model->numtexcoords);
01231 #endif
01232 }
|
|
|
01247 {
01248 GLMgroup* group;
01249 GLfloat theta, phi, rho, x, y, z, r;
01250 GLuint i;
01251
01252 assert(model);
01253 assert(model->normals);
01254
01255 if (model->texcoords)
01256 free(model->texcoords);
01257 model->numtexcoords = model->numnormals;
01258 model->texcoords=(GLfloat*)malloc(sizeof(GLfloat)*2*(model->numtexcoords+1));
01259
01260 /* do the calculations */
01261 for (i = 1; i <= model->numnormals; i++) {
01262 z = model->normals[3 * i + 0]; /* re-arrange for pole distortion */
01263 y = model->normals[3 * i + 1];
01264 x = model->normals[3 * i + 2];
01265 r = sqrt((x * x) + (y * y));
01266 rho = sqrt((r * r) + (z * z));
01267
01268 if(r == 0.0) {
01269 theta = 0.0;
01270 phi = 0.0;
01271 } else {
01272 if(z == 0.0)
01273 phi = M_PI / 2.0;
01274 else
01275 phi = acos(z / rho);
01276
01277 #if WE_DONT_NEED_THIS_CODE
01278 if(x == 0.0)
01279 theta = M_PI / 2.0; /* asin(y / r); */
01280 else
01281 theta = acos(x / r);
01282 #endif
01283
01284 if(y == 0.0)
01285 theta = M_PI / 2.0; /* acos(x / r); */
01286 else
01287 theta = asin(y / r) + (M_PI / 2.0);
01288 }
01289
01290 model->texcoords[2 * i + 0] = theta / M_PI;
01291 model->texcoords[2 * i + 1] = phi / M_PI;
01292 }
01293
01294 /* go through and put texcoord indices in all the triangles */
01295 group = model->groups;
01296 while(group) {
01297 for (i = 0; i < group->numtriangles; i++) {
01298 T(group->triangles[i]).tindices[0] = T(group->triangles[i]).nindices[0];
01299 T(group->triangles[i]).tindices[1] = T(group->triangles[i]).nindices[1];
01300 T(group->triangles[i]).tindices[2] = T(group->triangles[i]).nindices[2];
01301 }
01302 group = group->next;
01303 }
01304
01305 #if 0
01306 printf("glmSpheremapTexture(): generated %d spheremap texture coordinates\n",
01307 model->numtexcoords);
01308 #endif
01309 }
|
|
|
01317 {
01318 GLMgroup* group;
01319 GLuint i;
01320
01321 assert(model);
01322
01323 if (model->pathname) free(model->pathname);
01324 if (model->mtllibname) free(model->mtllibname);
01325 if (model->vertices) free(model->vertices);
01326 if (model->normals) free(model->normals);
01327 if (model->texcoords) free(model->texcoords);
01328 if (model->facetnorms) free(model->facetnorms);
01329 if (model->triangles) free(model->triangles);
01330 if (model->materials) {
01331 for (i = 0; i < model->nummaterials; i++)
01332 free(model->materials[i].name);
01333 }
01334 free(model->materials);
01335 while(model->groups) {
01336 group = model->groups;
01337 model->groups = model->groups->next;
01338 free(group->name);
01339 free(group->triangles);
01340 free(group);
01341 }
01342
01343 free(model);
01344 }
|
|
|
01354 {
01355 GLMmodel* model;
01356 FILE* file;
01357
01358 /* open the file */
01359 file = fopen(filename, "r");
01360 if (!file) {
01361 fprintf(stderr, "glmReadOBJ() failed: can't open data file \"%s\".\n",
01362 filename);
01363 exit(1);
01364 }
01365
01366 #if 0
01367 /* announce the model name */
01368 printf("Model: %s\n", filename);
01369 #endif
01370
01371 /* allocate a new model */
01372 model = (GLMmodel*)malloc(sizeof(GLMmodel));
01373 model->pathname = stralloc(filename);
01374 model->mtllibname = NULL;
01375 model->numvertices = 0;
01376 model->vertices = NULL;
01377 model->numnormals = 0;
01378 model->normals = NULL;
01379 model->numtexcoords = 0;
01380 model->texcoords = NULL;
01381 model->numfacetnorms = 0;
01382 model->facetnorms = NULL;
01383 model->numtriangles = 0;
01384 model->triangles = NULL;
01385 model->nummaterials = 0;
01386 model->materials = NULL;
01387 model->numgroups = 0;
01388 model->groups = NULL;
01389 model->position[0] = 0.0;
01390 model->position[1] = 0.0;
01391 model->position[2] = 0.0;
01392
01393 /* make a first pass through the file to get a count of the number
01394 of vertices, normals, texcoords & triangles */
01395 _glmFirstPass(model, file);
01396
01397 /* allocate memory */
01398 model->vertices = (GLfloat*)malloc(sizeof(GLfloat) *
01399 3 * (model->numvertices + 1));
01400 model->triangles = (GLMtriangle*)malloc(sizeof(GLMtriangle) *
01401 model->numtriangles);
01402 if (model->numnormals) {
01403 model->normals = (GLfloat*)malloc(sizeof(GLfloat) *
01404 3 * (model->numnormals + 1));
01405 }
01406 if (model->numtexcoords) {
01407 model->texcoords = (GLfloat*)malloc(sizeof(GLfloat) *
01408 2 * (model->numtexcoords + 1));
01409 }
01410
01411 /* rewind to beginning of file and read in the data this pass */
01412 rewind(file);
01413
01414 _glmSecondPass(model, file);
01415
01416 /* close the file */
01417 fclose(file);
01418
01419 return model;
01420 }
|
|
||||||||||||||||
|
01439 {
01440 GLuint i;
01441 FILE* file;
01442 GLMgroup* group;
01443
01444 assert(model);
01445
01446 /* do a bit of warning */
01447 if (mode & GLM_FLAT && !model->facetnorms) {
01448 printf("glmWriteOBJ() warning: flat normal output requested "
01449 "with no facet normals defined.\n");
01450 mode &= ~GLM_FLAT;
01451 }
01452 if (mode & GLM_SMOOTH && !model->normals) {
01453 printf("glmWriteOBJ() warning: smooth normal output requested "
01454 "with no normals defined.\n");
01455 mode &= ~GLM_SMOOTH;
01456 }
01457 if (mode & GLM_TEXTURE && !model->texcoords) {
01458 printf("glmWriteOBJ() warning: texture coordinate output requested "
01459 "with no texture coordinates defined.\n");
01460 mode &= ~GLM_TEXTURE;
01461 }
01462 if (mode & GLM_FLAT && mode & GLM_SMOOTH) {
01463 printf("glmWriteOBJ() warning: flat normal output requested "
01464 "and smooth normal output requested (using smooth).\n");
01465 mode &= ~GLM_FLAT;
01466 }
01467
01468 /* open the file */
01469 file = fopen(filename, "w");
01470 if (!file) {
01471 fprintf(stderr, "glmWriteOBJ() failed: can't open file \"%s\" to write.\n",
01472 filename);
01473 exit(1);
01474 }
01475
01476 /* spit out a header */
01477 fprintf(file, "# \n");
01478 fprintf(file, "# Wavefront OBJ generated by GLM library\n");
01479 fprintf(file, "# \n");
01480 fprintf(file, "# GLM library copyright (C) 1997 by Nate Robins\n");
01481 fprintf(file, "# email: ndr@pobox.com\n");
01482 fprintf(file, "# www: http://www.pobox.com/~ndr\n");
01483 fprintf(file, "# \n");
01484
01485 if (mode & GLM_MATERIAL && model->mtllibname) {
01486 fprintf(file, "\nmtllib %s\n\n", model->mtllibname);
01487 _glmWriteMTL(model, filename, model->mtllibname);
01488 }
01489
01490 /* spit out the vertices */
01491 fprintf(file, "\n");
01492 fprintf(file, "# %d vertices\n", model->numvertices);
01493 for (i = 1; i <= model->numvertices; i++) {
01494 fprintf(file, "v %f %f %f\n",
01495 model->vertices[3 * i + 0],
01496 model->vertices[3 * i + 1],
01497 model->vertices[3 * i + 2]);
01498 }
01499
01500 /* spit out the smooth/flat normals */
01501 if (mode & GLM_SMOOTH) {
01502 fprintf(file, "\n");
01503 fprintf(file, "# %d normals\n", model->numnormals);
01504 for (i = 1; i <= model->numnormals; i++) {
01505 fprintf(file, "vn %f %f %f\n",
01506 model->normals[3 * i + 0],
01507 model->normals[3 * i + 1],
01508 model->normals[3 * i + 2]);
01509 }
01510 } else if (mode & GLM_FLAT) {
01511 fprintf(file, "\n");
01512 fprintf(file, "# %d normals\n", model->numfacetnorms);
01513 for (i = 1; i <= model->numnormals; i++) {
01514 fprintf(file, "vn %f %f %f\n",
01515 model->facetnorms[3 * i + 0],
01516 model->facetnorms[3 * i + 1],
01517 model->facetnorms[3 * i + 2]);
01518 }
01519 }
01520
01521 /* spit out the texture coordinates */
01522 if (mode & GLM_TEXTURE) {
01523 fprintf(file, "\n");
01524 fprintf(file, "# %d texcoords\n", model->numtexcoords);
01525 for (i = 1; i <= model->numtexcoords; i++) {
01526 fprintf(file, "vt %f %f\n",
01527 model->texcoords[2 * i + 0],
01528 model->texcoords[2 * i + 1]);
01529 }
01530 }
01531
01532 fprintf(file, "\n");
01533 fprintf(file, "# %d groups\n", model->numgroups);
01534 fprintf(file, "# %d faces (triangles)\n", model->numtriangles);
01535 fprintf(file, "\n");
01536
01537 group = model->groups;
01538 while(group) {
01539 fprintf(file, "g %s\n", group->name);
01540 if (mode & GLM_MATERIAL)
01541 fprintf(file, "usemtl %s\n", model->materials[group->material].name);
01542 for (i = 0; i < group->numtriangles; i++) {
01543 if (mode & GLM_SMOOTH && mode & GLM_TEXTURE) {
01544 fprintf(file, "f %d/%d/%d %d/%d/%d %d/%d/%d\n",
01545 T(group->triangles[i]).vindices[0],
01546 T(group->triangles[i]).nindices[0],
01547 T(group->triangles[i]).tindices[0],
01548 T(group->triangles[i]).vindices[1],
01549 T(group->triangles[i]).nindices[1],
01550 T(group->triangles[i]).tindices[1],
01551 T(group->triangles[i]).vindices[2],
01552 T(group->triangles[i]).nindices[2],
01553 T(group->triangles[i]).tindices[2]);
01554 } else if (mode & GLM_FLAT && mode & GLM_TEXTURE) {
01555 fprintf(file, "f %d/%d %d/%d %d/%d\n",
01556 T(group->triangles[i]).vindices[0],
01557 T(group->triangles[i]).findex,
01558 T(group->triangles[i]).vindices[1],
01559 T(group->triangles[i]).findex,
01560 T(group->triangles[i]).vindices[2],
01561 T(group->triangles[i]).findex);
01562 } else if (mode & GLM_TEXTURE) {
01563 fprintf(file, "f %d/%d %d/%d %d/%d\n",
01564 T(group->triangles[i]).vindices[0],
01565 T(group->triangles[i]).tindices[0],
01566 T(group->triangles[i]).vindices[1],
01567 T(group->triangles[i]).tindices[1],
01568 T(group->triangles[i]).vindices[2],
01569 T(group->triangles[i]).tindices[2]);
01570 } else if (mode & GLM_SMOOTH) {
01571 fprintf(file, "f %d//%d %d//%d %d//%d\n",
01572 T(group->triangles[i]).vindices[0],
01573 T(group->triangles[i]).nindices[0],
01574 T(group->triangles[i]).vindices[1],
01575 T(group->triangles[i]).nindices[1],
01576 T(group->triangles[i]).vindices[2],
01577 T(group->triangles[i]).nindices[2]);
01578 } else if (mode & GLM_FLAT) {
01579 fprintf(file, "f %d//%d %d//%d %d//%d\n",
01580 T(group->triangles[i]).vindices[0],
01581 T(group->triangles[i]).findex,
01582 T(group->triangles[i]).vindices[1],
01583 T(group->triangles[i]).findex,
01584 T(group->triangles[i]).vindices[2],
01585 T(group->triangles[i]).findex);
01586 } else {
01587 fprintf(file, "f %d %d %d\n",
01588 T(group->triangles[i]).vindices[0],
01589 T(group->triangles[i]).vindices[1],
01590 T(group->triangles[i]).vindices[2]);
01591 }
01592 }
01593 fprintf(file, "\n");
01594 group = group->next;
01595 }
01596
01597 fclose(file);
01598 }
|
|
||||||||||||
|
01616 {
01617 GLuint i;
01618 GLMgroup* group;
01619
01620 assert(model);
01621 assert(model->vertices);
01622
01623 /* do a bit of warning */
01624 if (mode & GLM_FLAT && !model->facetnorms) {
01625 printf("glmDraw() warning: flat render mode requested "
01626 "with no facet normals defined.\n");
01627 mode &= ~GLM_FLAT;
01628 }
01629 if (mode & GLM_SMOOTH && !model->normals) {
01630 printf("glmDraw() warning: smooth render mode requested "
01631 "with no normals defined.\n");
01632 mode &= ~GLM_SMOOTH;
01633 }
01634 if (mode & GLM_TEXTURE && !model->texcoords) {
01635 printf("glmDraw() warning: texture render mode requested "
01636 "with no texture coordinates defined.\n");
01637 mode &= ~GLM_TEXTURE;
01638 }
01639 if (mode & GLM_FLAT && mode & GLM_SMOOTH) {
01640 printf("glmDraw() warning: flat render mode requested "
01641 "and smooth render mode requested (using smooth).\n");
01642 mode &= ~GLM_FLAT;
01643 }
01644 if (mode & GLM_COLOR && !model->materials) {
01645 printf("glmDraw() warning: color render mode requested "
01646 "with no materials defined.\n");
01647 mode &= ~GLM_COLOR;
01648 }
01649 if (mode & GLM_MATERIAL && !model->materials) {
01650 printf("glmDraw() warning: material render mode requested "
01651 "with no materials defined.\n");
01652 mode &= ~GLM_MATERIAL;
01653 }
01654 if (mode & GLM_COLOR && mode & GLM_MATERIAL) {
01655 printf("glmDraw() warning: color and material render mode requested "
01656 "using only material mode\n");
01657 mode &= ~GLM_COLOR;
01658 }
01659 if (mode & GLM_COLOR)
01660 glEnable(GL_COLOR_MATERIAL);
01661 if (mode & GLM_MATERIAL)
01662 glDisable(GL_COLOR_MATERIAL);
01663
01664 glPushMatrix();
01665 glTranslatef(model->position[0], model->position[1], model->position[2]);
01666
01667 glBegin(GL_TRIANGLES);
01668 group = model->groups;
01669 while (group) {
01670 if (mode & GLM_MATERIAL) {
01671 glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT,
01672 model->materials[group->material].ambient);
01673 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE,
01674 model->materials[group->material].diffuse);
01675 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR,
01676 model->materials[group->material].specular);
01677 glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS,
01678 model->materials[group->material].shininess);
01679 }
01680
01681 if (mode & GLM_COLOR) {
01682 glColor3fv(model->materials[group->material].diffuse);
01683 }
01684
01685 for (i = 0; i < group->numtriangles; i++) {
01686 if (mode & GLM_FLAT)
01687 glNormal3fv(&model->facetnorms[3 * T(group->triangles[i]).findex]);
01688
01689 if (mode & GLM_SMOOTH)
01690 glNormal3fv(&model->normals[3 * T(group->triangles[i]).nindices[0]]);
01691 if (mode & GLM_TEXTURE)
01692 glTexCoord2fv(&model->texcoords[2*T(group->triangles[i]).tindices[0]]);
01693 glVertex3fv(&model->vertices[3 * T(group->triangles[i]).vindices[0]]);
01694 #if 0
01695 printf("%f %f %f\n",
01696 model->vertices[3 * T(group->triangles[i]).vindices[0] + X],
01697 model->vertices[3 * T(group->triangles[i]).vindices[0] + Y],
01698 model->vertices[3 * T(group->triangles[i]).vindices[0] + Z]);
01699 #endif
01700
01701 if (mode & GLM_SMOOTH)
01702 glNormal3fv(&model->normals[3 * T(group->triangles[i]).nindices[1]]);
01703 if (mode & GLM_TEXTURE)
01704 glTexCoord2fv(&model->texcoords[2*T(group->triangles[i]).tindices[1]]);
01705 glVertex3fv(&model->vertices[3 * T(group->triangles[i]).vindices[1]]);
01706 #if 0
01707 printf("%f %f %f\n",
01708 model->vertices[3 * T(group->triangles[i]).vindices[1] + X],
01709 model->vertices[3 * T(group->triangles[i]).vindices[1] + Y],
01710 model->vertices[3 * T(group->triangles[i]).vindices[1] + Z]);
01711 #endif
01712
01713 if (mode & GLM_SMOOTH)
01714 glNormal3fv(&model->normals[3 * T(group->triangles[i]).nindices[2]]);
01715 if (mode & GLM_TEXTURE)
01716 glTexCoord2fv(&model->texcoords[2*T(group->triangles[i]).tindices[2]]);
01717 glVertex3fv(&model->vertices[3 * T(group->triangles[i]).vindices[2]]);
01718 #if 0
01719 printf("%f %f %f\n",
01720 model->vertices[3 * T(group->triangles[i]).vindices[2] + X],
01721 model->vertices[3 * T(group->triangles[i]).vindices[2] + Y],
01722 model->vertices[3 * T(group->triangles[i]).vindices[2] + Z]);
01723 #endif
01724
01725 }
01726
01727 group = group->next;
01728 }
01729 glEnd();
01730
01731 glPopMatrix();
01732 }
|
|
||||||||||||
|
01750 {
01751 GLuint list;
01752
01753 list = glGenLists(1);
01754 glNewList(list, GL_COMPILE);
01755 glmDraw(model, mode);
01756 glEndList();
01757
01758 return list;
01759 }
|
|
||||||||||||
|
01771 {
01772 GLfloat* vectors;
01773 GLfloat* copies;
01774 GLuint numvectors;
01775 GLuint i;
01776
01777 /* vertices */
01778 numvectors = model->numvertices;
01779 vectors = model->vertices;
01780 copies = _glmWeldVectors(vectors, &numvectors, epsilon);
01781
01782 printf("glmWeld(): %d redundant vertices.\n",
01783 model->numvertices - numvectors - 1);
01784
01785 for (i = 0; i < model->numtriangles; i++) {
01786 T(i).vindices[0] = (GLuint)vectors[3 * T(i).vindices[0] + 0];
01787 T(i).vindices[1] = (GLuint)vectors[3 * T(i).vindices[1] + 0];
01788 T(i).vindices[2] = (GLuint)vectors[3 * T(i).vindices[2] + 0];
01789 }
01790
01791 /* free space for old vertices */
01792 free(vectors);
01793
01794 /* allocate space for the new vertices */
01795 model->numvertices = numvectors;
01796 model->vertices = (GLfloat*)malloc(sizeof(GLfloat) *
01797 3 * (model->numvertices + 1));
01798
01799 /* copy the optimized vertices into the actual vertex list */
01800 for (i = 1; i <= model->numvertices; i++) {
01801 model->vertices[3 * i + 0] = copies[3 * i + 0];
01802 model->vertices[3 * i + 1] = copies[3 * i + 1];
01803 model->vertices[3 * i + 2] = copies[3 * i + 2];
01804 }
01805
01806 free(copies);
01807 }
|
1.2.18