home *** CD-ROM | disk | FTP | other *** search
- /* Convert a Sense8 NFF file into VRML */
-
- /* Written by Bernie Roehl, October 1995 */
-
- /*
- NFF Features not supported:
- Textures (VRML doesn't yet support PER_FACE texture maps)
- 24-bit color specifiers (12 bit is assumed)
-
- Also, normal handling is not working right (NFF and VRML have very
- different ideas about how it should work)
-
- */
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <ctype.h>
-
- typedef struct { float x, y, z; } Vertex;
-
- typedef struct
- {
- int npts; /* number of points in this polygon */
- int *points; /* indices into the vertex array */
- int color; /* index into the array of color values */
- } Poly;
-
- typedef unsigned long Color;
-
- Color *colors = NULL; /* one entry for each *unique* color */
- int ncolors = 0; /* number of unique colors defined */
-
- Vertex *vertices = NULL; /* the array of vertices */
- int nvertices = 0; /* number of vertices defined */
-
- Vertex *normals = NULL; /* the array of normals */
- int nnormals = 0; /* number of normals defined */
-
- Poly *polys = NULL; /* polygons */
- int npolys = 0; /* number of polygons defined */
-
- float scale = 1.0; /* scale factor */
-
- char objname[256]; /* the name of the object */
- int shading = 0; /* shading flag (not currently used) */
- int solid = 1; /* set if backface removal okay */
-
- Vertex camloc = { 0, 0, 0 }; /* camera location (currently not used) */
- Vertex camdir = { 0, 0, 0 }; /* camera direction (currently not used) */
-
- char *progname = "NFF2VRML"; /* name of this program */
-
- /* read a line, stripping comments and skipping blank lines */
- /* returns 0 at end of file */
- int getline(char *buff)
- {
- do
- {
- char *p;
- if (gets(buff) == NULL) /* end of file */
- return 0;
- p = strstr(buff, "//"); /* look for start of comment */
- if (p)
- *p = '\0'; /* truncate the line at that point */
- } while (buff[0] == '\0'); /* skip blank lines */
- return 1; /* not end of file */
- }
-
- void *ecalloc(int nitems, int size)
- {
- void *p = calloc(nitems, size);
- if (p == NULL)
- {
- fprintf(stderr, "%s: calloc() failed -- not enough memory\n", progname);
- exit(1);
- }
- return p;
- }
-
- void make_camera(void)
- {
- int i;
- float minx, maxx, miny, maxy, minz, maxz;
- /* compute bounding box */
- minx = maxx = vertices[0].x;
- miny = maxy = vertices[0].y;
- minz = maxz = vertices[0].z;
- for (i = 1; i < nvertices; ++i)
- {
- if (vertices[i].x < minx)
- minx = vertices[i].x;
- if (vertices[i].x > maxx)
- maxx = vertices[i].x;
- if (vertices[i].y < miny)
- miny = vertices[i].y;
- if (vertices[i].y > maxy)
- maxy = vertices[i].y;
- if (vertices[i].z < minz)
- minz = vertices[i].z;
- if (vertices[i].z > maxz)
- maxz = vertices[i].z;
- }
- printf("\tPerspectiveCamera { position %f %f %f }\n",
- (minx + maxx) / 2, -(miny + maxy) / 2, maxz + (maxz - minz));
- }
-
- void main(int argc, char *argv[])
- {
- char buff[256];
- int i, j;
-
- if (argc > 1)
- sscanf(argv[1], "%f", &scale);
-
- getline(buff);
- if (strnicmp(buff, "nff", 3))
- {
- fprintf(stderr, "No header line -- not a valid NFF file\n");
- exit(1);
- }
-
- while (getline(buff))
- {
- if (isdigit(buff[0]))
- break;
- if (!strnicmp(buff, "viewpos", 7))
- sscanf(buff, "viewpos %f %f %f", &camloc.x, &camloc.y, &camloc.z);
- else if (!strnicmp(buff, "viewdir", 7))
- sscanf(buff, "viewdir %f %f %f", &camdir.x, &camdir.y, &camdir.z);
- else if (!strnicmp(buff, "version", 7))
- {
- float version;
- sscanf(buff, "version %f", &version);
- if (version != 2.0)
- fprintf(stderr, "Warning: NFF version is %f, not 2.0\n", version);
- }
- else
- {
- char tempstr[100];
- /* pick up object name */
- if (sscanf(buff, "%s %s", objname, tempstr) == 2)
- shading = toupper(tempstr[9]) == 'n';
- }
- }
-
- /* first line is number of vertices */
- nvertices = atoi(buff);
-
- vertices = ecalloc(nvertices, sizeof(Vertex));
-
- normals = ecalloc(nvertices, sizeof(Vertex));
-
- /* read the vertices themselves */
- for (i = 0; i < nvertices; ++i)
- {
- float x, y, z;
- int m;
- getline(buff);
- m = sscanf(buff, "%f %f %f norm %f %f %f",
- &vertices[i].x, &vertices[i].y, &vertices[i].z,
- &normals[nnormals].x, &normals[nnormals].y, &normals[nnormals].z);
- if (m >= 6)
- ++nnormals;
- }
-
- /* next line is the number of polygons */
- getline(buff);
- npolys = atoi(buff);
-
- /* allocate the polygon array */
- polys = ecalloc(npolys, sizeof(Poly));
-
- /* allocate the color array; at worst, we'll need one for each polygon */
- colors = ecalloc(npolys, sizeof(Color));
-
- /* read the polygons */
- for (i = 0; i < npolys; ++i)
- {
- Color col;
- char *p;
-
- /* read the next line of input */
- getline(buff);
-
- /* if any of the polys are double-sided, the object can't be solid */
- if (strstr(buff, "both"))
- solid = 0;
-
- /* read the number of points */
- polys[i].npts = strtoul(buff, &p, 0);
-
- /* allocate the array of points for this polygon */
- polys[i].points = ecalloc(polys[i].npts, sizeof(int));
-
- /* read the points themselves */
- for (j = 0; j < polys[i].npts; ++j)
- polys[i].points[j] = strtoul(p, &p, 0);
-
- /* read the color (assume 12-bit) */
- col = strtoul(p, &p, 0);
-
- /* see if we've already got this color in the array */
- for (j = 0; j < ncolors; ++j)
- if (colors[j] == col)
- break;
-
- /* if it's a new color, add it to the array of colors */
- if (j >= ncolors)
- colors[ncolors++] = col;
- polys[i].color = j;
- }
-
- /* put out header */
- printf("#VRML V1.0 ascii\n# Converted by NFF2VRML\n\n");
- printf("Separator {\n");
-
- make_camera();
-
- /* put the object name out inside an Info node */
- if (objname[0])
- printf("\tDEF Title Info { string \"%s\" }\n", objname);
-
- /* faces are counterclockwise; if none of the faces were double-sided,
- then it's a SOLID shape */
- printf("\tShapeHints { vertexOrdering COUNTERCLOCKWISE %s }\n",
- solid ? "shapeType SOLID" : "shapeType UNKNOWN_SHAPE_TYPE");
-
- printf("\tMaterialBinding { value PER_FACE_INDEXED }\n");
-
- /* emit the coordinates */
- printf("\tCoordinate3 {\n\t\tpoint [\n");
- for (i = 0; i < nvertices; ++i)
- printf("\t\t\t%f %f %f,\n",
- vertices[i].x * scale,
- -vertices[i].y * scale, /* coordinate system is flipped */
- vertices[i].z * scale);
- printf("\t\t]\n\t}\n");
-
- #ifdef NORMALS_WORKING
- /* if any normals were specified, emit them */
- if (nnormals == nvertices)
- {
- printf("\tNormal {\n\t\tvector [\n");
- for (i = 0; i < nnormals; ++i)
- printf("\t\t\t%f %f %f,\n", normals[i].x, normals[i].y, normals[i].z);
- printf("\t\t]\n");
- }
- #endif
-
- /* put out the unique colors as materials */
- printf("\tMaterial {\n\t\tdiffuseColor [\n");
- for (i = 0; i < ncolors; ++i)
- printf("\t\t\t%f %f %f,\n", ((colors[i] >> 8) & 0x0F)/15.0, ((colors[i] >> 4) & 0x0F)/15.0, (colors[i] & 0x0F)/15.0);
- printf("\t\t]\n\t}\n");
-
- printf("\tIndexedFaceSet {\n");
-
- /* put out the actual polygons */
- printf("\t\tcoordIndex [\n");
- for (i = 0; i < npolys; ++i)
- {
- printf("\t\t\t");
- for (j = 0; j < polys[i].npts; ++j)
- printf("%d,", polys[i].points[j]);
- printf("-1,\n");
- }
- printf("\t\t]\n");
-
- /* and their material indices */
- printf("\t\tmaterialIndex [\n");
- for (i = 0; i < npolys; ++i)
- {
- if (i % 10 == 0)
- printf("\t\t\t");
- printf("%d, ", polys[i].color);
- if ((i+1) % 10 == 0) /* see if we've filled a line */
- printf("\n");
- }
- if (i % 10 != 0)
- printf("\n");
- printf("\t\t]\n");
-
- printf("\t}\n");
- printf("}\n");
- }
-