1c041511dScube
2c041511dScube/* Copyright (c) Mark J. Kilgard, 1994, 1997. */
3c041511dScube
4c041511dScube/**
5c041511dScube(c) Copyright 1993, Silicon Graphics, Inc.
6c041511dScube
7c041511dScubeALL RIGHTS RESERVED
8c041511dScube
9c041511dScubePermission to use, copy, modify, and distribute this software
10c041511dScubefor any purpose and without fee is hereby granted, provided
11c041511dScubethat the above copyright notice appear in all copies and that
12c041511dScubeboth the copyright notice and this permission notice appear in
13c041511dScubesupporting documentation, and that the name of Silicon
14c041511dScubeGraphics, Inc. not be used in advertising or publicity
15c041511dScubepertaining to distribution of the software without specific,
16c041511dScubewritten prior permission.
17c041511dScube
18c041511dScubeTHE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU
19c041511dScube"AS-IS" AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR
20c041511dScubeOTHERWISE, INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF
21c041511dScubeMERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  IN NO
22c041511dScubeEVENT SHALL SILICON GRAPHICS, INC.  BE LIABLE TO YOU OR ANYONE
23c041511dScubeELSE FOR ANY DIRECT, SPECIAL, INCIDENTAL, INDIRECT OR
24c041511dScubeCONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER,
25c041511dScubeINCLUDING WITHOUT LIMITATION, LOSS OF PROFIT, LOSS OF USE,
26c041511dScubeSAVINGS OR REVENUE, OR THE CLAIMS OF THIRD PARTIES, WHETHER OR
27c041511dScubeNOT SILICON GRAPHICS, INC.  HAS BEEN ADVISED OF THE POSSIBILITY
28c041511dScubeOF SUCH LOSS, HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
29c041511dScubeARISING OUT OF OR IN CONNECTION WITH THE POSSESSION, USE OR
30c041511dScubePERFORMANCE OF THIS SOFTWARE.
31c041511dScube
32c041511dScubeUS Government Users Restricted Rights
33c041511dScube
34c041511dScubeUse, duplication, or disclosure by the Government is subject to
35c041511dScuberestrictions set forth in FAR 52.227.19(c)(2) or subparagraph
36c041511dScube(c)(1)(ii) of the Rights in Technical Data and Computer
37c041511dScubeSoftware clause at DFARS 252.227-7013 and/or in similar or
38c041511dScubesuccessor clauses in the FAR or the DOD or NASA FAR
39c041511dScubeSupplement.  Unpublished-- rights reserved under the copyright
40c041511dScubelaws of the United States.  Contractor/manufacturer is Silicon
41c041511dScubeGraphics, Inc., 2011 N.  Shoreline Blvd., Mountain View, CA
42c041511dScube94039-7311.
43c041511dScube
44c041511dScubeOpenGL(TM) is a trademark of Silicon Graphics, Inc.
45c041511dScube*/
46c041511dScube
47c041511dScube#include <math.h>
48c041511dScube#include "glutint.h"
49c041511dScube
50c041511dScube/* Some <math.h> files do not define M_PI... */
51c041511dScube#ifndef M_PI
52c041511dScube#define M_PI 3.14159265358979323846
53c041511dScube#endif
54c041511dScube
55c041511dScubestatic GLUquadricObj *quadObj;
56c041511dScube
57c041511dScube#define QUAD_OBJ_INIT() { if(!quadObj) initQuadObj(); }
58c041511dScube
59c041511dScubestatic void
60c041511dScubeinitQuadObj(void)
61c041511dScube{
62c041511dScube  quadObj = gluNewQuadric();
63c041511dScube  if (!quadObj)
64c041511dScube    __glutFatalError("out of memory.");
65c041511dScube}
66c041511dScube
67c041511dScube/* CENTRY */
68c041511dScubevoid APIENTRY
69c041511dScubeglutWireSphere(GLdouble radius, GLint slices, GLint stacks)
70c041511dScube{
71c041511dScube  QUAD_OBJ_INIT();
72c041511dScube  gluQuadricDrawStyle(quadObj, GLU_LINE);
73c041511dScube  gluQuadricNormals(quadObj, GLU_SMOOTH);
74c041511dScube  /* If we ever changed/used the texture or orientation state
75c041511dScube     of quadObj, we'd need to change it to the defaults here
76c041511dScube     with gluQuadricTexture and/or gluQuadricOrientation. */
77c041511dScube  gluSphere(quadObj, radius, slices, stacks);
78c041511dScube}
79c041511dScube
80c041511dScubevoid APIENTRY
81c041511dScubeglutSolidSphere(GLdouble radius, GLint slices, GLint stacks)
82c041511dScube{
83c041511dScube  QUAD_OBJ_INIT();
84c041511dScube  gluQuadricDrawStyle(quadObj, GLU_FILL);
85c041511dScube  gluQuadricNormals(quadObj, GLU_SMOOTH);
86c041511dScube  /* If we ever changed/used the texture or orientation state
87c041511dScube     of quadObj, we'd need to change it to the defaults here
88c041511dScube     with gluQuadricTexture and/or gluQuadricOrientation. */
89c041511dScube  gluSphere(quadObj, radius, slices, stacks);
90c041511dScube}
91c041511dScube
92c041511dScubevoid APIENTRY
93c041511dScubeglutWireCone(GLdouble base, GLdouble height,
94c041511dScube  GLint slices, GLint stacks)
95c041511dScube{
96c041511dScube  QUAD_OBJ_INIT();
97c041511dScube  gluQuadricDrawStyle(quadObj, GLU_LINE);
98c041511dScube  gluQuadricNormals(quadObj, GLU_SMOOTH);
99c041511dScube  /* If we ever changed/used the texture or orientation state
100c041511dScube     of quadObj, we'd need to change it to the defaults here
101c041511dScube     with gluQuadricTexture and/or gluQuadricOrientation. */
102c041511dScube  gluCylinder(quadObj, base, 0.0, height, slices, stacks);
103c041511dScube}
104c041511dScube
105c041511dScubevoid APIENTRY
106c041511dScubeglutSolidCone(GLdouble base, GLdouble height,
107c041511dScube  GLint slices, GLint stacks)
108c041511dScube{
109c041511dScube  QUAD_OBJ_INIT();
110c041511dScube  gluQuadricDrawStyle(quadObj, GLU_FILL);
111c041511dScube  gluQuadricNormals(quadObj, GLU_SMOOTH);
112c041511dScube  /* If we ever changed/used the texture or orientation state
113c041511dScube     of quadObj, we'd need to change it to the defaults here
114c041511dScube     with gluQuadricTexture and/or gluQuadricOrientation. */
115c041511dScube  gluCylinder(quadObj, base, 0.0, height, slices, stacks);
116c041511dScube}
117c041511dScube
118c041511dScube/* ENDCENTRY */
119c041511dScube
120c041511dScubestatic void
121c041511dScubedrawBox(GLfloat size, GLenum type)
122c041511dScube{
123c041511dScube  static GLfloat n[6][3] =
124c041511dScube  {
125c041511dScube    {-1.0, 0.0, 0.0},
126c041511dScube    {0.0, 1.0, 0.0},
127c041511dScube    {1.0, 0.0, 0.0},
128c041511dScube    {0.0, -1.0, 0.0},
129c041511dScube    {0.0, 0.0, 1.0},
130c041511dScube    {0.0, 0.0, -1.0}
131c041511dScube  };
132c041511dScube  static GLint faces[6][4] =
133c041511dScube  {
134c041511dScube    {0, 1, 2, 3},
135c041511dScube    {3, 2, 6, 7},
136c041511dScube    {7, 6, 5, 4},
137c041511dScube    {4, 5, 1, 0},
138c041511dScube    {5, 6, 2, 1},
139c041511dScube    {7, 4, 0, 3}
140c041511dScube  };
141c041511dScube  GLfloat v[8][3];
142c041511dScube  GLint i;
143c041511dScube
144c041511dScube  v[0][0] = v[1][0] = v[2][0] = v[3][0] = -size / 2;
145c041511dScube  v[4][0] = v[5][0] = v[6][0] = v[7][0] = size / 2;
146c041511dScube  v[0][1] = v[1][1] = v[4][1] = v[5][1] = -size / 2;
147c041511dScube  v[2][1] = v[3][1] = v[6][1] = v[7][1] = size / 2;
148c041511dScube  v[0][2] = v[3][2] = v[4][2] = v[7][2] = -size / 2;
149c041511dScube  v[1][2] = v[2][2] = v[5][2] = v[6][2] = size / 2;
150c041511dScube
151c041511dScube  for (i = 5; i >= 0; i--) {
152c041511dScube    glBegin(type);
153c041511dScube    glNormal3fv(&n[i][0]);
154c041511dScube    glVertex3fv(&v[faces[i][0]][0]);
155c041511dScube    glVertex3fv(&v[faces[i][1]][0]);
156c041511dScube    glVertex3fv(&v[faces[i][2]][0]);
157c041511dScube    glVertex3fv(&v[faces[i][3]][0]);
158c041511dScube    glEnd();
159c041511dScube  }
160c041511dScube}
161c041511dScube
162c041511dScube/* CENTRY */
163c041511dScubevoid APIENTRY
164c041511dScubeglutWireCube(GLdouble size)
165c041511dScube{
166c041511dScube  drawBox(size, GL_LINE_LOOP);
167c041511dScube}
168c041511dScube
169c041511dScubevoid APIENTRY
170c041511dScubeglutSolidCube(GLdouble size)
171c041511dScube{
172c041511dScube  drawBox(size, GL_QUADS);
173c041511dScube}
174c041511dScube
175c041511dScube/* ENDCENTRY */
176c041511dScube
177c041511dScubestatic void
178c041511dScubedoughnut(GLfloat r, GLfloat R, GLint nsides, GLint rings)
179c041511dScube{
180c041511dScube  int i, j;
181c041511dScube  GLfloat theta, phi, theta1;
182c041511dScube  GLfloat cosTheta, sinTheta;
183c041511dScube  GLfloat cosTheta1, sinTheta1;
184c041511dScube  GLfloat ringDelta, sideDelta;
185c041511dScube
186c041511dScube  ringDelta = 2.0 * M_PI / rings;
187c041511dScube  sideDelta = 2.0 * M_PI / nsides;
188c041511dScube
189c041511dScube  theta = 0.0;
190c041511dScube  cosTheta = 1.0;
191c041511dScube  sinTheta = 0.0;
192c041511dScube  for (i = rings - 1; i >= 0; i--) {
193c041511dScube    theta1 = theta + ringDelta;
194c041511dScube    cosTheta1 = cos(theta1);
195c041511dScube    sinTheta1 = sin(theta1);
196c041511dScube    glBegin(GL_QUAD_STRIP);
197c041511dScube    phi = 0.0;
198c041511dScube    for (j = nsides; j >= 0; j--) {
199c041511dScube      GLfloat cosPhi, sinPhi, dist;
200c041511dScube
201c041511dScube      phi += sideDelta;
202c041511dScube      cosPhi = cos(phi);
203c041511dScube      sinPhi = sin(phi);
204c041511dScube      dist = R + r * cosPhi;
205c041511dScube
206c041511dScube      glNormal3f(cosTheta1 * cosPhi, -sinTheta1 * cosPhi, sinPhi);
207c041511dScube      glVertex3f(cosTheta1 * dist, -sinTheta1 * dist, r * sinPhi);
208c041511dScube      glNormal3f(cosTheta * cosPhi, -sinTheta * cosPhi, sinPhi);
209c041511dScube      glVertex3f(cosTheta * dist, -sinTheta * dist,  r * sinPhi);
210c041511dScube    }
211c041511dScube    glEnd();
212c041511dScube    theta = theta1;
213c041511dScube    cosTheta = cosTheta1;
214c041511dScube    sinTheta = sinTheta1;
215c041511dScube  }
216c041511dScube}
217c041511dScube
218c041511dScube/* CENTRY */
219c041511dScubevoid APIENTRY
220c041511dScubeglutWireTorus(GLdouble innerRadius, GLdouble outerRadius,
221c041511dScube  GLint nsides, GLint rings)
222c041511dScube{
223c041511dScube  glPushAttrib(GL_POLYGON_BIT);
224c041511dScube  glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
225c041511dScube  doughnut(innerRadius, outerRadius, nsides, rings);
226c041511dScube  glPopAttrib();
227c041511dScube}
228c041511dScube
229c041511dScubevoid APIENTRY
230c041511dScubeglutSolidTorus(GLdouble innerRadius, GLdouble outerRadius,
231c041511dScube  GLint nsides, GLint rings)
232c041511dScube{
233c041511dScube  doughnut(innerRadius, outerRadius, nsides, rings);
234c041511dScube}
235c041511dScube
236c041511dScube/* ENDCENTRY */
237c041511dScube
238c041511dScubestatic GLfloat dodec[20][3];
239c041511dScube
240c041511dScubestatic void
241c041511dScubeinitDodecahedron(void)
242c041511dScube{
243c041511dScube  GLfloat alpha, beta;
244c041511dScube
245c041511dScube  alpha = sqrt(2.0 / (3.0 + sqrt(5.0)));
246c041511dScube  beta = 1.0 + sqrt(6.0 / (3.0 + sqrt(5.0)) -
247c041511dScube    2.0 + 2.0 * sqrt(2.0 / (3.0 + sqrt(5.0))));
248c041511dScube  /* *INDENT-OFF* */
249c041511dScube  dodec[0][0] = -alpha; dodec[0][1] = 0; dodec[0][2] = beta;
250c041511dScube  dodec[1][0] = alpha; dodec[1][1] = 0; dodec[1][2] = beta;
251c041511dScube  dodec[2][0] = -1; dodec[2][1] = -1; dodec[2][2] = -1;
252c041511dScube  dodec[3][0] = -1; dodec[3][1] = -1; dodec[3][2] = 1;
253c041511dScube  dodec[4][0] = -1; dodec[4][1] = 1; dodec[4][2] = -1;
254c041511dScube  dodec[5][0] = -1; dodec[5][1] = 1; dodec[5][2] = 1;
255c041511dScube  dodec[6][0] = 1; dodec[6][1] = -1; dodec[6][2] = -1;
256c041511dScube  dodec[7][0] = 1; dodec[7][1] = -1; dodec[7][2] = 1;
257c041511dScube  dodec[8][0] = 1; dodec[8][1] = 1; dodec[8][2] = -1;
258c041511dScube  dodec[9][0] = 1; dodec[9][1] = 1; dodec[9][2] = 1;
259c041511dScube  dodec[10][0] = beta; dodec[10][1] = alpha; dodec[10][2] = 0;
260c041511dScube  dodec[11][0] = beta; dodec[11][1] = -alpha; dodec[11][2] = 0;
261c041511dScube  dodec[12][0] = -beta; dodec[12][1] = alpha; dodec[12][2] = 0;
262c041511dScube  dodec[13][0] = -beta; dodec[13][1] = -alpha; dodec[13][2] = 0;
263c041511dScube  dodec[14][0] = -alpha; dodec[14][1] = 0; dodec[14][2] = -beta;
264c041511dScube  dodec[15][0] = alpha; dodec[15][1] = 0; dodec[15][2] = -beta;
265c041511dScube  dodec[16][0] = 0; dodec[16][1] = beta; dodec[16][2] = alpha;
266c041511dScube  dodec[17][0] = 0; dodec[17][1] = beta; dodec[17][2] = -alpha;
267c041511dScube  dodec[18][0] = 0; dodec[18][1] = -beta; dodec[18][2] = alpha;
268c041511dScube  dodec[19][0] = 0; dodec[19][1] = -beta; dodec[19][2] = -alpha;
269c041511dScube  /* *INDENT-ON* */
270c041511dScube
271c041511dScube}
272c041511dScube
273c041511dScube#define DIFF3(_a,_b,_c) { \
274c041511dScube    (_c)[0] = (_a)[0] - (_b)[0]; \
275c041511dScube    (_c)[1] = (_a)[1] - (_b)[1]; \
276c041511dScube    (_c)[2] = (_a)[2] - (_b)[2]; \
277c041511dScube}
278c041511dScube
279c041511dScubestatic void
280c041511dScubecrossprod(GLfloat v1[3], GLfloat v2[3], GLfloat prod[3])
281c041511dScube{
282c041511dScube  GLfloat p[3];         /* in case prod == v1 or v2 */
283c041511dScube
284c041511dScube  p[0] = v1[1] * v2[2] - v2[1] * v1[2];
285c041511dScube  p[1] = v1[2] * v2[0] - v2[2] * v1[0];
286c041511dScube  p[2] = v1[0] * v2[1] - v2[0] * v1[1];
287c041511dScube  prod[0] = p[0];
288c041511dScube  prod[1] = p[1];
289c041511dScube  prod[2] = p[2];
290c041511dScube}
291c041511dScube
292c041511dScubestatic void
293c041511dScubenormalize(GLfloat v[3])
294c041511dScube{
295c041511dScube  GLfloat d;
296c041511dScube
297c041511dScube  d = sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]);
298c041511dScube  if (d == 0.0) {
299c041511dScube    __glutWarning("normalize: zero length vector");
300c041511dScube    v[0] = d = 1.0;
301c041511dScube  }
302c041511dScube  d = 1 / d;
303c041511dScube  v[0] *= d;
304c041511dScube  v[1] *= d;
305c041511dScube  v[2] *= d;
306c041511dScube}
307c041511dScube
308c041511dScubestatic void
309c041511dScubepentagon(int a, int b, int c, int d, int e, GLenum shadeType)
310c041511dScube{
311c041511dScube  GLfloat n0[3], d1[3], d2[3];
312c041511dScube
313c041511dScube  DIFF3(dodec[a], dodec[b], d1);
314c041511dScube  DIFF3(dodec[b], dodec[c], d2);
315c041511dScube  crossprod(d1, d2, n0);
316c041511dScube  normalize(n0);
317c041511dScube
318c041511dScube  glBegin(shadeType);
319c041511dScube  glNormal3fv(n0);
320c041511dScube  glVertex3fv(&dodec[a][0]);
321c041511dScube  glVertex3fv(&dodec[b][0]);
322c041511dScube  glVertex3fv(&dodec[c][0]);
323c041511dScube  glVertex3fv(&dodec[d][0]);
324c041511dScube  glVertex3fv(&dodec[e][0]);
325c041511dScube  glEnd();
326c041511dScube}
327c041511dScube
328c041511dScubestatic void
329c041511dScubedodecahedron(GLenum type)
330c041511dScube{
331c041511dScube  static int inited = 0;
332c041511dScube
333c041511dScube  if (inited == 0) {
334c041511dScube    inited = 1;
335c041511dScube    initDodecahedron();
336c041511dScube  }
337c041511dScube  pentagon(0, 1, 9, 16, 5, type);
338c041511dScube  pentagon(1, 0, 3, 18, 7, type);
339c041511dScube  pentagon(1, 7, 11, 10, 9, type);
340c041511dScube  pentagon(11, 7, 18, 19, 6, type);
341c041511dScube  pentagon(8, 17, 16, 9, 10, type);
342c041511dScube  pentagon(2, 14, 15, 6, 19, type);
343c041511dScube  pentagon(2, 13, 12, 4, 14, type);
344c041511dScube  pentagon(2, 19, 18, 3, 13, type);
345c041511dScube  pentagon(3, 0, 5, 12, 13, type);
346c041511dScube  pentagon(6, 15, 8, 10, 11, type);
347c041511dScube  pentagon(4, 17, 8, 15, 14, type);
348c041511dScube  pentagon(4, 12, 5, 16, 17, type);
349c041511dScube}
350c041511dScube
351c041511dScube/* CENTRY */
352c041511dScubevoid APIENTRY
353c041511dScubeglutWireDodecahedron(void)
354c041511dScube{
355c041511dScube  dodecahedron(GL_LINE_LOOP);
356c041511dScube}
357c041511dScube
358c041511dScubevoid APIENTRY
359c041511dScubeglutSolidDodecahedron(void)
360c041511dScube{
361c041511dScube  dodecahedron(GL_TRIANGLE_FAN);
362c041511dScube}
363c041511dScube
364c041511dScube/* ENDCENTRY */
365c041511dScube
366c041511dScubestatic void
367c041511dScuberecorditem(GLfloat * n1, GLfloat * n2, GLfloat * n3,
368c041511dScube  GLenum shadeType)
369c041511dScube{
370c041511dScube  GLfloat q0[3], q1[3];
371c041511dScube
372c041511dScube  DIFF3(n1, n2, q0);
373c041511dScube  DIFF3(n2, n3, q1);
374c041511dScube  crossprod(q0, q1, q1);
375c041511dScube  normalize(q1);
376c041511dScube
377c041511dScube  glBegin(shadeType);
378c041511dScube  glNormal3fv(q1);
379c041511dScube  glVertex3fv(n1);
380c041511dScube  glVertex3fv(n2);
381c041511dScube  glVertex3fv(n3);
382c041511dScube  glEnd();
383c041511dScube}
384c041511dScube
385c041511dScubestatic void
386c041511dScubesubdivide(GLfloat * v0, GLfloat * v1, GLfloat * v2,
387c041511dScube  GLenum shadeType)
388c041511dScube{
389c041511dScube  int depth;
390c041511dScube  GLfloat w0[3], w1[3], w2[3];
391c041511dScube  GLfloat l;
392c041511dScube  int i, j, k, n;
393c041511dScube
394c041511dScube  depth = 1;
395c041511dScube  for (i = 0; i < depth; i++) {
396c041511dScube    for (j = 0; i + j < depth; j++) {
397c041511dScube      k = depth - i - j;
398c041511dScube      for (n = 0; n < 3; n++) {
399c041511dScube        w0[n] = (i * v0[n] + j * v1[n] + k * v2[n]) / depth;
400c041511dScube        w1[n] = ((i + 1) * v0[n] + j * v1[n] + (k - 1) * v2[n])
401c041511dScube          / depth;
402c041511dScube        w2[n] = (i * v0[n] + (j + 1) * v1[n] + (k - 1) * v2[n])
403c041511dScube          / depth;
404c041511dScube      }
405c041511dScube      l = sqrt(w0[0] * w0[0] + w0[1] * w0[1] + w0[2] * w0[2]);
406c041511dScube      w0[0] /= l;
407c041511dScube      w0[1] /= l;
408c041511dScube      w0[2] /= l;
409c041511dScube      l = sqrt(w1[0] * w1[0] + w1[1] * w1[1] + w1[2] * w1[2]);
410c041511dScube      w1[0] /= l;
411c041511dScube      w1[1] /= l;
412c041511dScube      w1[2] /= l;
413c041511dScube      l = sqrt(w2[0] * w2[0] + w2[1] * w2[1] + w2[2] * w2[2]);
414c041511dScube      w2[0] /= l;
415c041511dScube      w2[1] /= l;
416c041511dScube      w2[2] /= l;
417c041511dScube      recorditem(w1, w0, w2, shadeType);
418c041511dScube    }
419c041511dScube  }
420c041511dScube}
421c041511dScube
422c041511dScubestatic void
423c041511dScubedrawtriangle(int i, GLfloat data[][3], int ndx[][3],
424c041511dScube  GLenum shadeType)
425c041511dScube{
426c041511dScube  GLfloat *x0, *x1, *x2;
427c041511dScube
428c041511dScube  x0 = data[ndx[i][0]];
429c041511dScube  x1 = data[ndx[i][1]];
430c041511dScube  x2 = data[ndx[i][2]];
431c041511dScube  subdivide(x0, x1, x2, shadeType);
432c041511dScube}
433c041511dScube
434c041511dScube/* octahedron data: The octahedron produced is centered at the
435c041511dScube   origin and has radius 1.0 */
436c041511dScubestatic GLfloat odata[6][3] =
437c041511dScube{
438c041511dScube  {1.0, 0.0, 0.0},
439c041511dScube  {-1.0, 0.0, 0.0},
440c041511dScube  {0.0, 1.0, 0.0},
441c041511dScube  {0.0, -1.0, 0.0},
442c041511dScube  {0.0, 0.0, 1.0},
443c041511dScube  {0.0, 0.0, -1.0}
444c041511dScube};
445c041511dScube
446c041511dScubestatic int ondex[8][3] =
447c041511dScube{
448c041511dScube  {0, 4, 2},
449c041511dScube  {1, 2, 4},
450c041511dScube  {0, 3, 4},
451c041511dScube  {1, 4, 3},
452c041511dScube  {0, 2, 5},
453c041511dScube  {1, 5, 2},
454c041511dScube  {0, 5, 3},
455c041511dScube  {1, 3, 5}
456c041511dScube};
457c041511dScube
458c041511dScubestatic void
459c041511dScubeoctahedron(GLenum shadeType)
460c041511dScube{
461c041511dScube  int i;
462c041511dScube
463c041511dScube  for (i = 7; i >= 0; i--) {
464c041511dScube    drawtriangle(i, odata, ondex, shadeType);
465c041511dScube  }
466c041511dScube}
467c041511dScube
468c041511dScube/* CENTRY */
469c041511dScubevoid APIENTRY
470c041511dScubeglutWireOctahedron(void)
471c041511dScube{
472c041511dScube  octahedron(GL_LINE_LOOP);
473c041511dScube}
474c041511dScube
475c041511dScubevoid APIENTRY
476c041511dScubeglutSolidOctahedron(void)
477c041511dScube{
478c041511dScube  octahedron(GL_TRIANGLES);
479c041511dScube}
480c041511dScube
481c041511dScube/* ENDCENTRY */
482c041511dScube
483c041511dScube/* icosahedron data: These numbers are rigged to make an
484c041511dScube   icosahedron of radius 1.0 */
485c041511dScube
486c041511dScube#define X .525731112119133606
487c041511dScube#define Z .850650808352039932
488c041511dScube
489c041511dScubestatic GLfloat idata[12][3] =
490c041511dScube{
491c041511dScube  {-X, 0, Z},
492c041511dScube  {X, 0, Z},
493c041511dScube  {-X, 0, -Z},
494c041511dScube  {X, 0, -Z},
495c041511dScube  {0, Z, X},
496c041511dScube  {0, Z, -X},
497c041511dScube  {0, -Z, X},
498c041511dScube  {0, -Z, -X},
499c041511dScube  {Z, X, 0},
500c041511dScube  {-Z, X, 0},
501c041511dScube  {Z, -X, 0},
502c041511dScube  {-Z, -X, 0}
503c041511dScube};
504c041511dScube
505c041511dScubestatic int index[20][3] =
506c041511dScube{
507c041511dScube  {0, 4, 1},
508c041511dScube  {0, 9, 4},
509c041511dScube  {9, 5, 4},
510c041511dScube  {4, 5, 8},
511c041511dScube  {4, 8, 1},
512c041511dScube  {8, 10, 1},
513c041511dScube  {8, 3, 10},
514c041511dScube  {5, 3, 8},
515c041511dScube  {5, 2, 3},
516c041511dScube  {2, 7, 3},
517c041511dScube  {7, 10, 3},
518c041511dScube  {7, 6, 10},
519c041511dScube  {7, 11, 6},
520c041511dScube  {11, 0, 6},
521c041511dScube  {0, 1, 6},
522c041511dScube  {6, 1, 10},
523c041511dScube  {9, 0, 11},
524c041511dScube  {9, 11, 2},
525c041511dScube  {9, 2, 5},
526c041511dScube  {7, 2, 11},
527c041511dScube};
528c041511dScube
529c041511dScubestatic void
530c041511dScubeicosahedron(GLenum shadeType)
531c041511dScube{
532c041511dScube  int i;
533c041511dScube
534c041511dScube  for (i = 19; i >= 0; i--) {
535c041511dScube    drawtriangle(i, idata, index, shadeType);
536c041511dScube  }
537c041511dScube}
538c041511dScube
539c041511dScube/* CENTRY */
540c041511dScubevoid APIENTRY
541c041511dScubeglutWireIcosahedron(void)
542c041511dScube{
543c041511dScube  icosahedron(GL_LINE_LOOP);
544c041511dScube}
545c041511dScube
546c041511dScubevoid APIENTRY
547c041511dScubeglutSolidIcosahedron(void)
548c041511dScube{
549c041511dScube  icosahedron(GL_TRIANGLES);
550c041511dScube}
551c041511dScube
552c041511dScube/* ENDCENTRY */
553c041511dScube
554c041511dScube/* tetrahedron data: */
555c041511dScube
556c041511dScube#define T       1.73205080756887729
557c041511dScube
558c041511dScubestatic GLfloat tdata[4][3] =
559c041511dScube{
560c041511dScube  {T, T, T},
561c041511dScube  {T, -T, -T},
562c041511dScube  {-T, T, -T},
563c041511dScube  {-T, -T, T}
564c041511dScube};
565c041511dScube
566c041511dScubestatic int tndex[4][3] =
567c041511dScube{
568c041511dScube  {0, 1, 3},
569c041511dScube  {2, 1, 0},
570c041511dScube  {3, 2, 0},
571c041511dScube  {1, 2, 3}
572c041511dScube};
573c041511dScube
574c041511dScubestatic void
575c041511dScubetetrahedron(GLenum shadeType)
576c041511dScube{
577c041511dScube  int i;
578c041511dScube
579c041511dScube  for (i = 3; i >= 0; i--)
580c041511dScube    drawtriangle(i, tdata, tndex, shadeType);
581c041511dScube}
582c041511dScube
583c041511dScube/* CENTRY */
584c041511dScubevoid APIENTRY
585c041511dScubeglutWireTetrahedron(void)
586c041511dScube{
587c041511dScube  tetrahedron(GL_LINE_LOOP);
588c041511dScube}
589c041511dScube
590c041511dScubevoid APIENTRY
591c041511dScubeglutSolidTetrahedron(void)
592c041511dScube{
593c041511dScube  tetrahedron(GL_TRIANGLES);
594c041511dScube}
595c041511dScube
596c041511dScube/* ENDCENTRY */
597