home *** CD-ROM | disk | FTP | other *** search
- /* Generates the vertices for a ball approximated with polygonal
- facets, in a form suitable for including into a C module. Vertices,
- faces, and supporting info is generated, in the following format:
-
- ----------------------------start------------------------------
- #define NUM_FACES <number of faces in object>
- #define NUM_VERTS <number of vertices in object>
-
- Point3 Verts[] = { <vertices in object> };
-
- static int Face0[] = { <vertex indexes for face, clockwise> };
- static int Face1[] = { <vertex indexes for face, clockwise> };
- :
- static int Face<n>[] = { <vertex indexes for face, clockwise> };
-
- static int *VertNumList[] = { <ptr to vertex index list per face> };
- static int VertsInFace[] = { <# vertices in each face> };
- ----------------------------end--------------------------------
- */
-
- #include <stdio.h>
- #include <conio.h>
- #include <math.h>
- #include <string.h>
- #include "polygon.h"
-
- #define PI 3.14159265358979323846
- #define DOUBLE_TO_FIXED(x) ((long) (x * 65536.0 + 0.5))
-
- void main(void);
- void PrintVertex(struct Point3 *);
- void Print3Indexes(int, int, int, int);
- void Print4Indexes(int, int, int, int, int);
-
- /* Used to rotate around the Y axis by one band's width */
- static double YXform[4][4] = {
- {1.0, 0.0, 0.0, 0.0},
- {0.0, 1.0, 0.0, 0.0},
- {0.0, 0.0, 1.0, 0.0},
- {0.0, 0.0, 0.0, 1.0}
- };
-
- /* Used to rotate around the Z axis by one band's width */
- static double ZXform[4][4] = {
- {1.0, 0.0, 0.0, 0.0},
- {0.0, 1.0, 0.0, 0.0},
- {0.0, 0.0, 1.0, 0.0},
- {0.0, 0.0, 0.0, 1.0}
- };
-
- static FILE *OutputFile; /* where we'll write to */
-
- void main()
- {
- int Radius, Bands, i, j, LastIndex, BandsX2, LastBandStartIndex;
- int TopBandStartIndex, BottomBandStartIndex, FaceNum;
- struct Point3 BaseVec, BandVec, WorkingVec, TempVec;
- char OutputFilename[130];
- char Description[130];
-
- printf("Radius: ");
- scanf("%d",&Radius);
- printf("Bands: ");
- scanf("%d",&Bands);
- printf("Output file: ");
- OutputFilename[0] = 128;
- cgets(OutputFilename);
- printf("\nBrief description: ");
- Description[0] = 128;
- cgets(Description);
- printf("\n");
-
- BandsX2 = Bands*2;
-
- if ((OutputFile = fopen(&OutputFilename[2], "w")) == NULL) {
- printf("Error\n");
- exit(1);
- }
-
- /* Descriptive comments */
- fprintf(OutputFile, "/* %s */\n", &Description[2]);
- fprintf(OutputFile, "/* Created with radius = %d, bands = %d */\n",
- Radius, Bands);
-
- /* Defines for # of faces and vertices */
- fprintf(OutputFile, "#define NUM_FACES %d\n", BandsX2*Bands);
- fprintf(OutputFile, "#define NUM_VERTS %d\n\n",
- BandsX2*(Bands-1)+2);
-
- /* Do the vertices */
- fprintf(OutputFile, "Point3 Verts[] = {\n");
-
- /* Generate the rotation matrices */
- AppendRotationY(YXform, PI / Bands);
- AppendRotationZ(ZXform, PI / Bands);
-
- /* Do the point at the top */
- BaseVec.X = 0.0;
- BaseVec.Y = Radius;
- BaseVec.Z = 0.0;
- BaseVec.W = 1.0;
- PrintVertex(&BaseVec);
-
- BandVec = BaseVec;
-
- /* Do the vertices in each band in turn */
- for (i=1; i<Bands; i++) {
- /* Rotate around Z to the next band's latitude */
- XformVec(ZXform, (double *)&BandVec, (double *)&TempVec);
- WorkingVec = BandVec = TempVec;
- /* Do the vertices in this band */
- for (j=0; j<BandsX2; j++) {
- WorkingVec = TempVec;
- PrintVertex(&WorkingVec);
- /* Now rotate around Y to the next vertex's longitude */
- XformVec(YXform, (double *)&WorkingVec, (double *)&TempVec);
- }
- }
-
- /* Do the point at the bottom */
- BaseVec.Y = -Radius;
- PrintVertex(&BaseVec);
-
- fprintf(OutputFile, "};\n\n");
-
- /* Do the vertex indexes for each face in each band */
- FaceNum = 0;
-
- /* Vertex indexes in top band */
- for (i=0; i<BandsX2; i++) {
- Print3Indexes(FaceNum++, 0, ((i+1)%BandsX2)+1, i+1);
- }
-
- /* Vertex indexes in middle bands */
- for (j=0; j<(Bands-2); j++) {
- TopBandStartIndex = j*BandsX2 + 1;
- BottomBandStartIndex = (j+1)*BandsX2 + 1;
- /* Indexes in this band */
- for (i=0; i<BandsX2; i++) {
- Print4Indexes(FaceNum++, i+TopBandStartIndex,
- ((i+1)%BandsX2)+TopBandStartIndex,
- ((i+1)%BandsX2)+BottomBandStartIndex,
- i+BottomBandStartIndex);
- }
- }
-
- /* Vertex indexes in bottom band */
- LastIndex = BandsX2*(Bands-1)+1;
- LastBandStartIndex = BandsX2*(Bands-2)+1;
- for (i=0; i<BandsX2; i++) {
- Print3Indexes(FaceNum++, LastBandStartIndex+i,
- LastBandStartIndex+((i+1)%BandsX2), LastIndex);
- }
-
- /* Do the list of pointers to index arrays for each face */
- fprintf(OutputFile, "\nstatic int *VertNumList[] = {\n");
- for (i=0; i<(BandsX2*Bands); i++) {
- fprintf(OutputFile, "Face%d,\n", i);
- }
- fprintf(OutputFile, "};\n");
-
- /* Do the # of vertices in each face (3 for the top and bottom
- bands, 4 for the rest) */
- fprintf(OutputFile, "\nstatic int VertsInFace[] = {\n");
- for (i=0; i<BandsX2; i++) fprintf(OutputFile, "3,\n");
- for (i=0; i<(BandsX2*(Bands-2)); i++) fprintf(OutputFile, "4,\n");
- for (i=0; i<BandsX2; i++) fprintf(OutputFile, "3,\n");
- fprintf(OutputFile, "};\n");
-
- exit(0);
- }
-
- /* Prints the array of indexes for a 4-vertex face */
- void Print4Indexes(int FaceNum, int V1, int V2, int V3, int V4)
- {
- fprintf(OutputFile, "static int Face%d[] = {%d,%d,%d,%d};\n",
- FaceNum, V1, V2, V3, V4);
- }
-
- /* Prints the array of indexes for a 3-vertex face */
- void Print3Indexes(int FaceNum, int V1, int V2, int V3)
- {
- fprintf(OutputFile, "static int Face%d[] = {%d,%d,%d};\n",
- FaceNum, V1, V2, V3);
- }
-
- /* Prints a vertex, in 16.16 fixed-point form */
- void PrintVertex(struct Point3 *Vec)
- {
- long X = DOUBLE_TO_FIXED(Vec->X);
- long Y = DOUBLE_TO_FIXED(Vec->Y);
- long Z = DOUBLE_TO_FIXED(Vec->Z);
-
- fprintf(OutputFile, "{%ld, %ld, %ld},\n", X, Y, Z);
- }
-