home *** CD-ROM | disk | FTP | other *** search
- /*
- * Copyright 1992, 1993, 1994, Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
- * the contents of this file may not be disclosed to third parties, copied or
- * duplicated in any form, in whole or in part, without the prior written
- * permission of Silicon Graphics, Inc.
- *
- * RESTRICTED RIGHTS LEGEND:
- * Use, duplication or disclosure by the Government is subject to restrictions
- * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
- * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
- * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
- * rights reserved under the Copyright Laws of the United States.
- */
-
- /* Routines to build 3 dimensional solids.
- *
- * -- Tom Davis 1990
- *
- * Exported routines include:
- *
- * drawbox, quadsphere, doughnut, elbow, cylinder, trisphere,
- * icosahedron, octahedron, tetrahedron, dodecahedron.
- *
- * Some documentation appears above each routine.
- */
-
- #include <stdio.h>
- #include <math.h>
- #include "3d.h"
-
- void drawbox(float x0, float x1, float y0, float y1,
- float z0, float z1, void (*savefunc)());
- static void drawtriangle(long i, long type, long depth,
- float p0[3], float radius, long avnormal);
- static void recorditem(float *n1, float *n2, float *n3,
- float center[3], float radius, long avnormal);
-
-
- #define PI 3.1415926535897
- #define EPSILON .0001
-
- float cv[8][3];
- float cnorms[6][3] = {
- {-1.0, 0.0, 0.0}, {0.0, 1.0, 0.0}, {1.0, 0.0, 0.0},
- {0.0, -1.0, 0.0}, {0.0, 0.0, 1.0}, {0.0, 0.0, -1.0}
- };
-
- long faces[6][4] = {
- { 0, 1, 2, 3 }, { 3, 2, 6, 7 }, { 7, 6, 5, 4 },
- { 4, 5, 1, 0 }, { 5, 6, 2, 1 }, { 7, 4, 0, 3 }
- };
-
- /* drawbox:
- *
- * draws a cubical box with the given x, y, and z ranges. The box is
- * axis-aligned.
- */
-
- void drawbox(float x0, float x1, float y0, float y1,
- float z0, float z1, void (*savefunc)())
- {
- long i;
- float temp;
- float p0[3], p1[3], p2[3], p3[3];
- float n0[3], n1[3], n2[3], n3[3];
-
- if (x0 > x1) { temp = x0; x0 = x1; x1 = temp; }
- if (y0 > y1) { temp = y0; y0 = y1; y1 = temp; }
- if (z0 > z1) { temp = z0; z0 = z1; z1 = temp; }
- cv[0][0] = cv[1][0] = cv[2][0] = cv[3][0] = x0;
- cv[4][0] = cv[5][0] = cv[6][0] = cv[7][0] = x1;
- cv[0][1] = cv[1][1] = cv[4][1] = cv[5][1] = y0;
- cv[2][1] = cv[3][1] = cv[6][1] = cv[7][1] = y1;
- cv[0][2] = cv[3][2] = cv[4][2] = cv[7][2] = z0;
- cv[1][2] = cv[2][2] = cv[5][2] = cv[6][2] = z1;
- for (i = 0; i < 6; i++) {
- m_xformpt(&cv[faces[i][0]][0], p0, &cnorms[i][0], n0);
- m_xformpt(&cv[faces[i][1]][0], p1, &cnorms[i][0], n1);
- m_xformpt(&cv[faces[i][2]][0], p2, &cnorms[i][0], n2);
- m_xformpt(&cv[faces[i][3]][0], p3, &cnorms[i][0], n3);
- (*savefunc)(ADD_QUAD, n0, p0, n1, p1, n2, p2, n3, p3);
- }
- }
-
- /* quadsphere:
- *
- * draws a sphere centered at 0.0 and radius 1.0. The sphere is composed of
- * quadrilaterals with latsides latitude lines and lonsides longitude lines
- */
-
- void quadsphere(long latsides, long lonsides, void (*savefunc)())
- {
- float theta, phi;
- float p0[3], p1[3], p2[3], p3[3];
- float n0[3], n1[3], n2[3], n3[3];
- long i;
- long lat, lon;
-
- for (lat = 0; lat < latsides; lat++)
- for (lon = 0; lon < lonsides; lon++) {
- theta = lat*PI/latsides;
- phi = lon*2.0*PI/lonsides;
- n0[0]= sin(theta)*cos(phi);
- n0[1]= sin(theta)*sin(phi);
- n0[2]= cos(theta);
-
- n1[0]= sin(theta+PI/latsides)*cos(phi);
- n1[1]= sin(theta+PI/latsides)*sin(phi);
- n1[2]= cos(theta+PI/latsides);
-
- n2[0]= sin(theta+PI/latsides)*cos(phi+2.0*PI/lonsides);
- n2[1]= sin(theta+PI/latsides)*sin(phi+2.0*PI/lonsides);
- n2[2]= cos(theta+PI/latsides);
-
- n3[0]= sin(theta)*cos(phi+2.0*PI/lonsides);
- n3[1]= sin(theta)*sin(phi+2.0*PI/lonsides);
- n3[2]= cos(theta);
-
- m_xformpt(n0, p0, n0, n0);
- m_xformpt(n1, p1, n1, n1);
- m_xformpt(n2, p2, n2, n2);
- m_xformpt(n3, p3, n3, n3);
-
- (*savefunc)(ADD_QUAD, n0, p0, n1, p1, n2, p2, n3, p3);
- }
- }
-
- /* doughnut:
- *
- * draws a doughnut, centered at (0, 0, 0) whose axis is aligned with
- * the z-axis. The doughnut's major radius is R, and minor radius is r.
- */
-
- void doughnut(float r, float R, long nsides, long rings, void (*savefunc)())
- {
- long i, j;
- float theta, phi, theta1, phi1;
- float p0[03], p1[3], p2[3], p3[3];
- float n0[3], n1[3], n2[3], n3[3];
-
- for (i = 0; i < rings; i++) {
- theta = (float)i*2.0*PI/rings;
- theta1 = (float)(i+1)*2.0*PI/rings;
- for (j = 0; j < nsides; j++) {
- phi = (float)j*2.0*PI/nsides;
- phi1 = (float)(j+1)*2.0*PI/nsides;
-
- p0[0] = cos(theta)*(R + r*cos(phi));
- p0[1] = -sin(theta)*(R + r*cos(phi));
- p0[2] = r*sin(phi);
-
- p1[0] = cos(theta1)*(R + r*cos(phi));
- p1[1] = -sin(theta1)*(R + r*cos(phi));
- p1[2] = r*sin(phi);
-
- p2[0] = cos(theta1)*(R + r*cos(phi1));
- p2[1] = -sin(theta1)*(R + r*cos(phi1));
- p2[2] = r*sin(phi1);
-
- p3[0] = cos(theta)*(R + r*cos(phi1));
- p3[1] = -sin(theta)*(R + r*cos(phi1));
- p3[2] = r*sin(phi1);
-
- n0[0] = cos(theta)*(cos(phi));
- n0[1] = -sin(theta)*(cos(phi));
- n0[2] = sin(phi);
-
- n1[0] = cos(theta1)*(cos(phi));
- n1[1] = -sin(theta1)*(cos(phi));
- n1[2] = sin(phi);
-
- n2[0] = cos(theta1)*(cos(phi1));
- n2[1] = -sin(theta1)*(cos(phi1));
- n2[2] = sin(phi1);
-
- n3[0] = cos(theta)*(cos(phi1));
- n3[1] = -sin(theta)*(cos(phi1));
- n3[2] = sin(phi1);
-
- m_xformpt(p0, p0, n0, n0);
- m_xformpt(p1, p1, n1, n1);
- m_xformpt(p2, p2, n2, n2);
- m_xformpt(p3, p3, n3, n3);
-
- (*savefunc)(ADD_QUAD, n3, p3, n2, p2, n1, p1, n0, p0);
- }
- }
- }
-
- /* elbow:
- *
- * draws an elbow of 90 degrees, centered at pt0, and passing through
- * pt1 and pt2. The tube has the given radius, sides around the tube,
- * and number of segments along the tube.
- *
- */
-
- void elbow(float *pt0, float *pt1, float *pt2,
- float radius, long nsides, long nsegs, void (*savefunc)())
- {
- float theta, theta1, phi, phi1;
- float pv[3], pv1[3], vperp[3], diff[3];
- float p0[3], p1[3], p2[3], p3[3];
- float n0[3], n1[3], n2[3], n3[3];
- long i;
-
- for (theta = 0; theta < PI/2 - EPSILON; theta += PI/(2.0*nsegs)) {
- for (i = 0; i < 3; i++) {
- theta1 = theta + PI/(2.0*nsegs);
- pv[i] = pt1[i]+(pt0[i]-pt1[i])*cos(theta)+(pt2[i]-pt1[i])*sin(theta);
- pv1[i] = pt1[i]+(pt0[i]-pt1[i])*cos(theta1)+(pt2[i]-pt1[i])*sin(theta1);
- }
- for (i = 0; i < 3; i++) {
- p0[i] = pv[i] - pt1[i];
- p1[i] = pv1[i] - pt1[i];
- }
- crossprod(p0, p1, vperp);
- normalize(vperp);
- for (phi = 0; phi < 2.0*PI - EPSILON; phi += 2.0*PI/nsides) {
- phi1 = phi + 2*PI/nsides;
- for (i = 0; i < 3; i++) {
- diff3(pt1, pv, diff); normalize(diff);
- p3[i]=pv[i]+radius*(diff[i]*cos(phi)+vperp[i]*sin(phi));
- n3[i] = p3[i] - pv[i];
- diff3(pt1, pv1, diff); normalize(diff);
- p2[i]=pv1[i]+radius*(diff[i]*cos(phi)+vperp[i]*sin(phi));
- n2[i] = p2[i] - pv1[i];
- p1[i]=pv1[i]+radius*(diff[i]*cos(phi1)+vperp[i]*sin(phi1));
- n1[i] = p1[i] - pv1[i];
- diff3(pt1, pv, diff); normalize(diff);
- p0[i]=pv[i]+radius*(diff[i]*cos(phi1)+vperp[i]*sin(phi1));
- n0[i] = p0[i] - pv[i];
- }
- normalize(n0);
- normalize(n1);
- normalize(n2);
- normalize(n3);
-
- m_xformpt(p0, p0, n0, n0);
- m_xformpt(p1, p1, n1, n1);
- m_xformpt(p2, p2, n2, n2);
- m_xformpt(p3, p3, n3, n3);
-
- (*savefunc)(ADD_QUAD, n1, p1, n2, p2, n3, p3, n0, p0);
- }
- }
- }
-
- /* cylinder:
- *
- * Creates rectangles around a cylinder going from pt1 to pt2.
- * Each time a rectangle is created, the function savefunc() is called:
- *
- * savefunc(n0, v0, n1, v1, n2, v2, n3, v3);
- *
- * the cylinder has nsides cylinder sides at the given radius.
- */
-
- void cylinder(float *pt1, float *pt2,
- float radius, long nsides, void (*savefunc)())
- {
- long eq = 0, i, j;
- float vperp[3], uperp[3], diff[3], n1[3], n2[3], n0[3] /* dummy */;
- float v0[3], v1[3], v2[3], v3[3];
- float theta, theta1;
-
- n0[0] = n0[1] = n0[2] = 0.0;
- for (i = 0; i < 3; i++)
- if (pt1[i] == pt2[i]) eq++;
- for (i = 0; i < 3; i++)
- diff[i] = pt1[i] - pt2[i];
- if (eq == 2) { /* it's axis-aligned */
- if (pt1[0] != pt2[0]) {
- vperp[0] = vperp[2] = 0.0;
- vperp[1] = 1.0;
- } else if (pt1[1] != pt2[1]) {
- vperp[0] = vperp[1] = 0.0;
- vperp[2] = 1.0;
- } else {
- vperp[1] = vperp[2] = 0.0;
- vperp[0] = 1.0;
- }
- } else { /* it's a general cylinder */
- if (diff[0] == 0.0) {
- vperp[0] = 0.0;
- vperp[1] = 1.0;
- vperp[2] = -diff[1]/diff[2];
- } else if (diff[1] == 0.0) {
- vperp[1] = 0.0;
- vperp[0] = 1.0;
- vperp[2] = - diff[0]/diff[2];
- } else {
- vperp[2] = 0.0;
- vperp[0] = 1.0;
- vperp[1] = - diff[0]/diff[1];
- }
- normalize(vperp);
- }
- crossprod(diff, vperp, uperp);
- normalize(uperp);
- for (theta = 0.0; theta < 2.0*PI - EPSILON; theta += 2.0*PI/nsides) {
- theta1 = theta + 2.0*PI/nsides;
- for (i = 0; i < 3; i++) {
- n1[i] = vperp[i]*cos(theta) + uperp[i]*sin(theta);
- n2[i] = vperp[i]*cos(theta1) + uperp[i]*sin(theta1);
- }
- v0[0] = pt1[0]+n1[0]*radius;
- v0[1] = pt1[1]+n1[1]*radius;
- v0[2] = pt1[2]+n1[2]*radius;
- v1[0] = pt2[0]+n1[0]*radius;
- v1[1] = pt2[1]+n1[1]*radius;
- v1[2] = pt2[2]+n1[2]*radius;
- v2[0] = pt2[0]+n2[0]*radius;
- v2[1] = pt2[1]+n2[1]*radius;
- v2[2] = pt2[2]+n2[2]*radius;
- v3[0] = pt1[0]+n2[0]*radius;
- v3[1] = pt1[1]+n2[1]*radius;
- v3[2] = pt1[2]+n2[2]*radius;
-
- m_xformpt(v0, v0, n1, n1);
- m_xformptonly(v1, v1);
- m_xformpt(v2, v2, n2, n2);
- m_xformptonly(v3, v3);
-
- (*savefunc)(ADD_QUAD, n1, v0, n1, v1, n2, v2, n2, v3);
- }
- }
-
- /* octahedron data: The octahedron produced is centered at the origin
- * and has radius 1.0 */
-
- static float odata[6][3] = {
- {1.0, 0.0, 0.0},
- {-1.0, 0.0, 0.0},
- {0.0, 1.0, 0.0},
- {0.0, -1.0, 0.0},
- {0.0, 0.0, 1.0},
- {0.0, 0.0, -1.0}
- };
-
- static long ondex[8][3] = {
- {0, 4, 2}, {1, 2, 4}, {0, 3, 4}, {1, 4, 3},
- {0, 2, 5}, {1, 5, 2}, {0, 5, 3}, {1, 3, 5}
- };
-
- /* tetrahedron data: */
-
- #define T 1.73205080756887729
-
- static float tdata[4][3] = {
- {T, T, T}, {T, -T, -T}, {-T, T, -T}, {-T, -T, T}
- };
-
- static long tndex[4][3] = {
- {0, 1, 3}, {2, 1, 0}, {3, 2, 0}, {1, 2, 3}
- };
-
- /* icosahedron data: These numbers are rigged to make an icosahedron
- * of radius 1.0 */
-
- #define X .525731112119133606
- #define Z .850650808352039932
-
- static float idata[12][3] = {
- {-X, 0, Z},
- {X, 0, Z},
- {-X, 0, -Z},
- {X, 0, -Z},
- {0, Z, X},
- {0, Z, -X},
- {0, -Z, X},
- {0, -Z, -X},
- {Z, X, 0},
- {-Z, X, 0},
- {Z, -X, 0},
- {-Z, -X, 0}
- };
-
- static long index[20][3] = {
- {0, 4, 1}, {0, 9, 4},
- {9, 5, 4}, {4, 5, 8},
- {4, 8, 1}, {8, 10, 1},
- {8, 3, 10}, {5, 3, 8},
- {5, 2, 3}, {2, 7, 3},
- {7, 10, 3}, {7, 6, 10},
- {7, 11, 6}, {11, 0, 6},
- {0, 1, 6}, {6, 1, 10},
- {9, 0, 11}, {9, 11, 2},
- {9, 2, 5}, {7, 2, 11},
- };
-
- static void (*sfunc)();
-
- /* trisphere:
- *
- * Draws a sphere of given radius centered at the point p0.
- * depth controls the amount of subdivision. If depth is 1, an
- * icosahedron is drawn. If depth is 2, each triangle is split into 4
- * pieces; if depth is 3, each triangle is split into 10 pieces, etc.
- * The normals generated are perpendicular to the sphere's surface.
- */
-
- void trisphere(float p0[3], float radius, long depth, void (*savefunc)())
- {
- long i;
-
- if (depth < 1) depth = 1;
- sfunc = savefunc;
- for (i = 0; i < 20; i++)
- drawtriangle(i, 0, depth, p0, radius, 1);
- }
-
- /* icosahedron:
- *
- * Draws an icosahedron with center at p0 having the
- * given radius.
- */
-
- void icosahedron(float p0[3], float radius, void (*savefunc)())
- {
- long i;
-
- sfunc = savefunc;
- for (i = 0; i < 20; i++)
- drawtriangle(i, 0, 1, p0, radius, 0);
- }
-
- /* octahedron:
- *
- * Draws an octahedron with center at p0 having the
- * given radius.
- */
-
- void octahedron(float p0[3], float radius, void (*savefunc)())
- {
- long i;
-
- sfunc = savefunc;
- for (i = 0; i < 8; i++)
- drawtriangle(i, 1, 1, p0, radius, 0);
- }
-
- /* tetrahedron:
- *
- * Draws an tetrahedron with center at p0 having the
- * given radius.
- */
-
- void tetrahedron(float p0[3], float radius, void (*savefunc)())
- {
- long i;
-
- sfunc = savefunc;
- for (i = 0; i < 4; i++)
- drawtriangle(i, 2, 1, p0, radius, 0);
- }
-
- static void subdivide(long depth, float *v0, float *v1, float *v2,
- float p0[3], float radius, long avnormal)
- {
- float w0[3], w1[3], w2[3];
- float l;
- long i, j, k, n;
-
- for (i = 0; i < depth; i++)
- for (j = 0; i + j < depth; j++) {
- k = depth - i - j;
- for (n = 0; n < 3; n++) {
- w0[n] = (i*v0[n] + j*v1[n] + k*v2[n])/depth;
- w1[n] = ((i+1)*v0[n] + j*v1[n] + (k-1)*v2[n])/depth;
- w2[n] = (i*v0[n] + (j+1)*v1[n] + (k-1)*v2[n])/depth;
- }
- l = sqrt(w0[0]*w0[0] + w0[1]*w0[1] + w0[2]*w0[2]);
- w0[0] /= l; w0[1] /= l; w0[2] /= l;
- l = sqrt(w1[0]*w1[0] + w1[1]*w1[1] + w1[2]*w1[2]);
- w1[0] /= l; w1[1] /= l; w1[2] /= l;
- l = sqrt(w2[0]*w2[0] + w2[1]*w2[1] + w2[2]*w2[2]);
- w2[0] /= l; w2[1] /= l; w2[2] /= l;
- recorditem(w1, w0, w2, p0, radius, avnormal);
- }
- for (i = 0; i < depth-1; i++)
- for (j = 0; i + j < depth-1; j++) {
- k = depth - i - j;
- for (n = 0; n < 3; n++) {
- w0[n] = ((i+1)*v0[n] + (j+1)*v1[n] + (k-2)*v2[n])/depth;
- w1[n] = ((i+1)*v0[n] + j*v1[n] + (k-1)*v2[n])/depth;
- w2[n] = (i*v0[n] + (j+1)*v1[n] + (k-1)*v2[n])/depth;
- }
- l = sqrt(w0[0]*w0[0] + w0[1]*w0[1] + w0[2]*w0[2]);
- w0[0] /= l; w0[1] /= l; w0[2] /= l;
- l = sqrt(w1[0]*w1[0] + w1[1]*w1[1] + w1[2]*w1[2]);
- w1[0] /= l; w1[1] /= l; w1[2] /= l;
- l = sqrt(w2[0]*w2[0] + w2[1]*w2[1] + w2[2]*w2[2]);
- w2[0] /= l; w2[1] /= l; w2[2] /= l;
- recorditem(w0, w1, w2, p0, radius, avnormal);
- }
- }
-
- static void drawtriangle(long i, long type, long depth,
- float p0[3], float radius, long avnormal)
- {
- float *x0, *x1, *x2;
-
- switch (type) {
- case 0: /* icosahedron */
- x0 = &idata[index[i][0]][0];
- x1 = &idata[index[i][1]][0];
- x2 = &idata[index[i][2]][0];
- break;
- case 1: /* octahedron */
- x0 = &odata[ondex[i][0]][0];
- x1 = &odata[ondex[i][1]][0];
- x2 = &odata[ondex[i][2]][0];
- break;
- case 2: /* tetrahedron */
- x0 = &tdata[tndex[i][0]][0];
- x1 = &tdata[tndex[i][1]][0];
- x2 = &tdata[tndex[i][2]][0];
- break;
- }
- subdivide(depth, x0, x1, x2, p0, radius, avnormal);
- }
-
- static void recorditem(float *n1, float *n2, float *n3,
- float center[3], float radius, long avnormal)
- {
- float p1[3], p2[3], p3[3], q0[3], q1[3], n11[3], n22[3], n33[3];
- long i;
-
- for (i = 0; i < 3; i++) {
- p1[i] = n1[i]*radius + center[i];
- p2[i] = n2[i]*radius + center[i];
- p3[i] = n3[i]*radius + center[i];
- }
- if (avnormal == 0) {
- diff3(p1, p2, q0);
- diff3(p2, p3, q1);
- crossprod(q0, q1, q1);
- normalize(q1);
- m_xformpt(p1, p1, q1, n11);
- m_xformptonly(p2, p2);
- m_xformptonly(p3, p3);
-
- (*sfunc)(ADD_TRI, n11, p1, n11, p2, n11, p3);
- return;
- }
- m_xformpt(p1, p1, n1, n11);
- m_xformpt(p2, p2, n2, n22);
- m_xformpt(p3, p3, n3, n33);
-
- (*sfunc)(ADD_TRI, n11, p1, n22, p2, n33, p3);
- }
-
- float dodec[20][3];
-
- static void initdodec()
- {
- float alpha, beta;
-
- alpha = sqrt(2.0/(3.0 + sqrt(5.0)));
- beta = 1.0 + sqrt(6.0/(3.0 + sqrt(5.0)) - 2.0 + 2.0*sqrt(2.0/(3.0 +
- sqrt(5.0))));
- dodec[0][0] = -alpha; dodec[0][1] = 0; dodec[0][2] = beta;
- dodec[1][0] = alpha; dodec[1][1] = 0; dodec[1][2] = beta;
- dodec[2][0] = -1; dodec[2][1] = -1; dodec[2][2] = -1;
- dodec[3][0] = -1; dodec[3][1] = -1; dodec[3][2] = 1;
- dodec[4][0] = -1; dodec[4][1] = 1; dodec[4][2] = -1;
- dodec[5][0] = -1; dodec[5][1] = 1; dodec[5][2] = 1;
- dodec[6][0] = 1; dodec[6][1] = -1; dodec[6][2] = -1;
- dodec[7][0] = 1; dodec[7][1] = -1; dodec[7][2] = 1;
- dodec[8][0] = 1; dodec[8][1] = 1; dodec[8][2] = -1;
- dodec[9][0] = 1; dodec[9][1] = 1; dodec[9][2] = 1;
- dodec[10][0] = beta; dodec[10][1] = alpha; dodec[10][2] = 0;
- dodec[11][0] = beta; dodec[11][1] = -alpha; dodec[11][2] = 0;
- dodec[12][0] = -beta; dodec[12][1] = alpha; dodec[12][2] = 0;
- dodec[13][0] = -beta; dodec[13][1] = -alpha; dodec[13][2] = 0;
- dodec[14][0] = -alpha; dodec[14][1] = 0; dodec[14][2] = -beta;
- dodec[15][0] = alpha; dodec[15][1] = 0; dodec[15][2] = -beta;
- dodec[16][0] = 0; dodec[16][1] = beta; dodec[16][2] = alpha;
- dodec[17][0] = 0; dodec[17][1] = beta; dodec[17][2] = -alpha;
- dodec[18][0] = 0; dodec[18][1] = -beta; dodec[18][2] = alpha;
- dodec[19][0] = 0; dodec[19][1] = -beta; dodec[19][2] = -alpha;
- }
-
- /* dodecahedron:
- *
- * Draws an dodecahedron with center at 0.0. The radius
- * is sqrt(3).
- */
-
- void dodecahedron(float center[3], float sc, void (*savefunc)())
- {
- static long inited = 0;
-
- if ( inited == 0) {
- inited = 1;
- initdodec();
- }
- m_pushmatrix();
- m_translate(center[0], center[1], center[2]);
- m_scale(sc, sc, sc);
- sfunc = savefunc;
- pentagon(0, 1, 9, 16, 5);
- pentagon(1, 0, 3, 18, 7);
- pentagon(1, 7, 11, 10, 9);
- pentagon(11, 7, 18, 19, 6);
- pentagon(8, 17, 16, 9, 10);
- pentagon(2, 14, 15, 6, 19);
- pentagon(2, 13, 12, 4, 14);
- pentagon(2, 19, 18, 3, 13);
- pentagon(3, 0, 5, 12, 13);
- pentagon(6, 15, 8, 10, 11);
- pentagon(4, 17, 8, 15, 14);
- pentagon(4, 12, 5, 16, 17);
- m_popmatrix();
- }
-
- static void pentagon(long a, long b, long c, long d, long e)
- {
- float n0[3], d1[3], d2[3], d3[3], d4[3], d5[3], nout[3];
-
- diff3(&dodec[a][0], &dodec[b][0], d1);
- diff3(&dodec[b][0], &dodec[c][0], d2);
- crossprod(d1, d2, n0);
- normalize(n0);
- m_xformpt(&dodec[a][0], d1, n0, nout);
- m_xformptonly(&dodec[b][0], d2);
- m_xformptonly(&dodec[c][0], d3);
- m_xformptonly(&dodec[d][0], d4);
- m_xformptonly(&dodec[e][0], d5);
- (*sfunc)(ADD_TRI, nout, d1, nout, d2, nout, d3);
- (*sfunc)(ADD_TRI, nout, d1, nout, d3, nout, d4);
- (*sfunc)(ADD_TRI, nout, d1, nout, d4, nout, d5);
- }
-