Skip to content

AFNI/NIfTI Server

Sections
Personal tools
You are here: Home » AFNI » Documentation

Doxygen Source Code Documentation


Main Page   Alphabetical List   Data Structures   File List   Data Fields   Globals   Search  

glut_shapes.c

Go to the documentation of this file.
00001 
00002 /* Copyright (c) Mark J. Kilgard, 1994. */
00003 
00004 /**
00005 (c) Copyright 1993, Silicon Graphics, Inc.
00006 
00007 ALL RIGHTS RESERVED
00008 
00009 Permission to use, copy, modify, and distribute this software
00010 for any purpose and without fee is hereby granted, provided
00011 that the above copyright notice appear in all copies and that
00012 both the copyright notice and this permission notice appear in
00013 supporting documentation, and that the name of Silicon
00014 Graphics, Inc. not be used in advertising or publicity
00015 pertaining to distribution of the software without specific,
00016 written prior permission.
00017 
00018 THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU
00019 "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR
00020 OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF
00021 MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  IN NO
00022 EVENT SHALL SILICON GRAPHICS, INC.  BE LIABLE TO YOU OR ANYONE
00023 ELSE FOR ANY DIRECT, SPECIAL, INCIDENTAL, INDIRECT OR
00024 CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER,
00025 INCLUDING WITHOUT LIMITATION, LOSS OF PROFIT, LOSS OF USE,
00026 SAVINGS OR REVENUE, OR THE CLAIMS OF THIRD PARTIES, WHETHER OR
00027 NOT SILICON GRAPHICS, INC.  HAS BEEN ADVISED OF THE POSSIBILITY
00028 OF SUCH LOSS, HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
00029 ARISING OUT OF OR IN CONNECTION WITH THE POSSESSION, USE OR
00030 PERFORMANCE OF THIS SOFTWARE.
00031 
00032 US Government Users Restricted Rights
00033 
00034 Use, duplication, or disclosure by the Government is subject to
00035 restrictions set forth in FAR 52.227.19(c)(2) or subparagraph
00036 (c)(1)(ii) of the Rights in Technical Data and Computer
00037 Software clause at DFARS 252.227-7013 and/or in similar or
00038 successor clauses in the FAR or the DOD or NASA FAR
00039 Supplement.  Unpublished-- rights reserved under the copyright
00040 laws of the United States.  Contractor/manufacturer is Silicon
00041 Graphics, Inc., 2011 N.  Shoreline Blvd., Mountain View, CA
00042 94039-7311.
00043 
00044 OpenGL(TM) is a trademark of Silicon Graphics, Inc.
00045 */
00046 
00047 #include <math.h>
00048 #include <GL/gl.h>
00049 #include <GL/glu.h>
00050 #include <GL/glut.h>
00051 #include "glutint.h"
00052 
00053 static GLUquadricObj *quadObj;
00054 
00055 #define QUAD_OBJ_INIT() { if(!quadObj) initQuadObj(); }
00056 
00057 static void
00058 initQuadObj(void)
00059 {
00060   quadObj = gluNewQuadric();
00061   if (!quadObj)
00062     __glutFatalError("out of memory.");
00063 }
00064 
00065 void
00066 glutWireSphere(GLdouble radius, GLint slices, GLint stacks)
00067 {
00068   QUAD_OBJ_INIT();
00069   gluQuadricDrawStyle(quadObj, GLU_LINE);
00070   gluQuadricNormals(quadObj, GLU_SMOOTH);
00071   /* If we ever changed/used the texture or orientation state
00072      of quadObj, we'd need to change it to the defaults here
00073      with gluQuadricTexture and/or gluQuadricOrientation. */
00074   gluSphere(quadObj, radius, slices, stacks);
00075 }
00076 
00077 void
00078 glutSolidSphere(GLdouble radius, GLint slices, GLint stacks)
00079 {
00080   QUAD_OBJ_INIT();
00081   gluQuadricDrawStyle(quadObj, GLU_FILL);
00082   gluQuadricNormals(quadObj, GLU_SMOOTH);
00083   /* If we ever changed/used the texture or orientation state
00084      of quadObj, we'd need to change it to the defaults here
00085      with gluQuadricTexture and/or gluQuadricOrientation. */
00086   gluSphere(quadObj, radius, slices, stacks);
00087 }
00088 
00089 void
00090 glutWireCone(GLdouble base, GLdouble height,
00091   GLint slices, GLint stacks)
00092 {
00093   QUAD_OBJ_INIT();
00094   gluQuadricDrawStyle(quadObj, GLU_LINE);
00095   gluQuadricNormals(quadObj, GLU_SMOOTH);
00096   /* If we ever changed/used the texture or orientation state
00097      of quadObj, we'd need to change it to the defaults here
00098      with gluQuadricTexture and/or gluQuadricOrientation. */
00099   gluCylinder(quadObj, base, 0.0, height, slices, stacks);
00100 }
00101 
00102 void
00103 glutSolidCone(GLdouble base, GLdouble height,
00104   GLint slices, GLint stacks)
00105 {
00106   QUAD_OBJ_INIT();
00107   gluQuadricDrawStyle(quadObj, GLU_FILL);
00108   gluQuadricNormals(quadObj, GLU_SMOOTH);
00109   /* If we ever changed/used the texture or orientation state
00110      of quadObj, we'd need to change it to the defaults here
00111      with gluQuadricTexture and/or gluQuadricOrientation. */
00112   gluCylinder(quadObj, base, 0.0, height, slices, stacks);
00113 }
00114 
00115 static void
00116 drawBox(GLfloat x0, GLfloat x1, GLfloat y0, GLfloat y1,
00117   GLfloat z0, GLfloat z1, GLenum type)
00118 {
00119   static GLfloat n[6][3] =
00120   {
00121     {-1.0, 0.0, 0.0},
00122     {0.0, 1.0, 0.0},
00123     {1.0, 0.0, 0.0},
00124     {0.0, -1.0, 0.0},
00125     {0.0, 0.0, 1.0},
00126     {0.0, 0.0, -1.0}
00127   };
00128   static GLint faces[6][4] =
00129   {
00130     {0, 1, 2, 3},
00131     {3, 2, 6, 7},
00132     {7, 6, 5, 4},
00133     {4, 5, 1, 0},
00134     {5, 6, 2, 1},
00135     {7, 4, 0, 3}
00136   };
00137   GLfloat v[8][3], tmp;
00138   GLint i;
00139 
00140   if (x0 > x1) {
00141     tmp = x0;
00142     x0 = x1;
00143     x1 = tmp;
00144   }
00145   if (y0 > y1) {
00146     tmp = y0;
00147     y0 = y1;
00148     y1 = tmp;
00149   }
00150   if (z0 > z1) {
00151     tmp = z0;
00152     z0 = z1;
00153     z1 = tmp;
00154   }
00155   v[0][0] = v[1][0] = v[2][0] = v[3][0] = x0;
00156   v[4][0] = v[5][0] = v[6][0] = v[7][0] = x1;
00157   v[0][1] = v[1][1] = v[4][1] = v[5][1] = y0;
00158   v[2][1] = v[3][1] = v[6][1] = v[7][1] = y1;
00159   v[0][2] = v[3][2] = v[4][2] = v[7][2] = z0;
00160   v[1][2] = v[2][2] = v[5][2] = v[6][2] = z1;
00161 
00162   for (i = 0; i < 6; i++) {
00163     glBegin(type);
00164     glNormal3fv(&n[i][0]);
00165     glVertex3fv(&v[faces[i][0]][0]);
00166     glVertex3fv(&v[faces[i][1]][0]);
00167     glVertex3fv(&v[faces[i][2]][0]);
00168     glVertex3fv(&v[faces[i][3]][0]);
00169     glEnd();
00170   }
00171 }
00172 
00173 void
00174 glutWireCube(GLdouble size)
00175 {
00176   drawBox(-size / 2., size / 2.,
00177     -size / 2., size / 2.,
00178     -size / 2., size / 2.,
00179     GL_LINE_LOOP);
00180 }
00181 
00182 void
00183 glutSolidCube(GLdouble size)
00184 {
00185   drawBox(-size / 2., size / 2.,
00186     -size / 2., size / 2.,
00187     -size / 2., size / 2.,
00188     GL_QUADS);
00189 }
00190 
00191 static void
00192 doughnut(GLfloat r, GLfloat R, GLint nsides,
00193   GLint rings, GLenum type)
00194 {
00195   int i, j;
00196   GLfloat theta, phi, theta1, phi1;
00197   GLfloat p0[03], p1[3], p2[3], p3[3];
00198   GLfloat n0[3], n1[3], n2[3], n3[3];
00199 
00200   for (i = 0; i < rings; i++) {
00201     theta = (GLfloat) i *2.0 * M_PI / rings;
00202     theta1 = (GLfloat) (i + 1) * 2.0 * M_PI / rings;
00203     for (j = 0; j < nsides; j++) {
00204       phi = (GLfloat) j *2.0 * M_PI / nsides;
00205       phi1 = (GLfloat) (j + 1) * 2.0 * M_PI / nsides;
00206 
00207       p0[0] = cos(theta) * (R + r * cos(phi));
00208       p0[1] = -sin(theta) * (R + r * cos(phi));
00209       p0[2] = r * sin(phi);
00210 
00211       p1[0] = cos(theta1) * (R + r * cos(phi));
00212       p1[1] = -sin(theta1) * (R + r * cos(phi));
00213       p1[2] = r * sin(phi);
00214 
00215       p2[0] = cos(theta1) * (R + r * cos(phi1));
00216       p2[1] = -sin(theta1) * (R + r * cos(phi1));
00217       p2[2] = r * sin(phi1);
00218 
00219       p3[0] = cos(theta) * (R + r * cos(phi1));
00220       p3[1] = -sin(theta) * (R + r * cos(phi1));
00221       p3[2] = r * sin(phi1);
00222 
00223       n0[0] = cos(theta) * (cos(phi));
00224       n0[1] = -sin(theta) * (cos(phi));
00225       n0[2] = sin(phi);
00226 
00227       n1[0] = cos(theta1) * (cos(phi));
00228       n1[1] = -sin(theta1) * (cos(phi));
00229       n1[2] = sin(phi);
00230 
00231       n2[0] = cos(theta1) * (cos(phi1));
00232       n2[1] = -sin(theta1) * (cos(phi1));
00233       n2[2] = sin(phi1);
00234 
00235       n3[0] = cos(theta) * (cos(phi1));
00236       n3[1] = -sin(theta) * (cos(phi1));
00237       n3[2] = sin(phi1);
00238 
00239       glBegin(type);
00240       glNormal3fv(n3);
00241       glVertex3fv(p3);
00242       glNormal3fv(n2);
00243       glVertex3fv(p2);
00244       glNormal3fv(n1);
00245       glVertex3fv(p1);
00246       glNormal3fv(n0);
00247       glVertex3fv(p0);
00248       glEnd();
00249     }
00250   }
00251 }
00252 
00253 void
00254 glutWireTorus(GLdouble innerRadius, GLdouble outerRadius,
00255   GLint nsides, GLint rings)
00256 {
00257   doughnut(innerRadius, outerRadius,
00258     nsides, rings, GL_LINE_LOOP);
00259 }
00260 
00261 void
00262 glutSolidTorus(GLdouble innerRadius, GLdouble outerRadius,
00263   GLint nsides, GLint rings)
00264 {
00265   doughnut(innerRadius, outerRadius, nsides, rings, GL_QUADS);
00266 }
00267 
00268 static GLfloat dodec[20][3];
00269 
00270 static void
00271 initDodecahedron(void)
00272 {
00273   GLfloat alpha, beta;
00274 
00275   alpha = sqrt(2.0 / (3.0 + sqrt(5.0)));
00276   beta = 1.0 + sqrt(6.0 / (3.0 + sqrt(5.0)) -
00277     2.0 + 2.0 * sqrt(2.0 / (3.0 + sqrt(5.0))));
00278   dodec[0][0] = -alpha; dodec[0][1] = 0; dodec[0][2] = beta;
00279   dodec[1][0] = alpha; dodec[1][1] = 0; dodec[1][2] = beta;
00280   dodec[2][0] = -1; dodec[2][1] = -1; dodec[2][2] = -1;
00281   dodec[3][0] = -1; dodec[3][1] = -1; dodec[3][2] = 1;
00282   dodec[4][0] = -1; dodec[4][1] = 1; dodec[4][2] = -1;
00283   dodec[5][0] = -1; dodec[5][1] = 1; dodec[5][2] = 1;
00284   dodec[6][0] = 1; dodec[6][1] = -1; dodec[6][2] = -1;
00285   dodec[7][0] = 1; dodec[7][1] = -1; dodec[7][2] = 1;
00286   dodec[8][0] = 1; dodec[8][1] = 1; dodec[8][2] = -1;
00287   dodec[9][0] = 1; dodec[9][1] = 1; dodec[9][2] = 1;
00288   dodec[10][0] = beta; dodec[10][1] = alpha; dodec[10][2] = 0;
00289   dodec[11][0] = beta; dodec[11][1] = -alpha; dodec[11][2] = 0;
00290   dodec[12][0] = -beta; dodec[12][1] = alpha; dodec[12][2] = 0;
00291   dodec[13][0] = -beta; dodec[13][1] = -alpha; dodec[13][2] = 0;
00292   dodec[14][0] = -alpha; dodec[14][1] = 0; dodec[14][2] = -beta;
00293   dodec[15][0] = alpha; dodec[15][1] = 0; dodec[15][2] = -beta;
00294   dodec[16][0] = 0; dodec[16][1] = beta; dodec[16][2] = alpha;
00295   dodec[17][0] = 0; dodec[17][1] = beta; dodec[17][2] = -alpha;
00296   dodec[18][0] = 0; dodec[18][1] = -beta; dodec[18][2] = alpha;
00297   dodec[19][0] = 0; dodec[19][1] = -beta; dodec[19][2] = -alpha;
00298 }
00299 
00300 #define DIFF3(_a,_b,_c) { \
00301     (_c)[0] = (_a)[0] - (_b)[0]; \
00302     (_c)[1] = (_a)[1] - (_b)[1]; \
00303     (_c)[2] = (_a)[2] - (_b)[2]; \
00304 }
00305 
00306 static void
00307 crossprod(GLfloat v1[3], GLfloat v2[3], GLfloat prod[3])
00308 {
00309   GLfloat p[3];        /* in case prod == v1 or v2 */
00310 
00311   p[0] = v1[1] * v2[2] - v2[1] * v1[2];
00312   p[1] = v1[2] * v2[0] - v2[2] * v1[0];
00313   p[2] = v1[0] * v2[1] - v2[0] * v1[1];
00314   prod[0] = p[0];
00315   prod[1] = p[1];
00316   prod[2] = p[2];
00317 }
00318 
00319 static void
00320 normalize(GLfloat v[3])
00321 {
00322   GLfloat d;
00323 
00324   d = sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]);
00325   if (d == 0.0) {
00326     __glutWarning("normalize: zero length vector");
00327     v[0] = d = 1.0;
00328   }
00329   d = 1 / d;
00330   v[0] *= d;
00331   v[1] *= d;
00332   v[2] *= d;
00333 }
00334 
00335 static void
00336 pentagon(int a, int b, int c, int d, int e, GLenum shadeType)
00337 {
00338   GLfloat n0[3], d1[3], d2[3];
00339 
00340   DIFF3(dodec[a], dodec[b], d1);
00341   DIFF3(dodec[b], dodec[c], d2);
00342   crossprod(d1, d2, n0);
00343   normalize(n0);
00344 
00345   glBegin(shadeType);
00346   glNormal3fv(n0);
00347   glVertex3fv(&dodec[a][0]);
00348   glVertex3fv(&dodec[b][0]);
00349   glVertex3fv(&dodec[c][0]);
00350   glVertex3fv(&dodec[d][0]);
00351   glVertex3fv(&dodec[e][0]);
00352   glEnd();
00353 }
00354 
00355 static void
00356 dodecahedron(GLenum type)
00357 {
00358   static int inited = 0;
00359 
00360   if (inited == 0) {
00361     inited = 1;
00362     initDodecahedron();
00363   }
00364   pentagon(0, 1, 9, 16, 5, type);
00365   pentagon(1, 0, 3, 18, 7, type);
00366   pentagon(1, 7, 11, 10, 9, type);
00367   pentagon(11, 7, 18, 19, 6, type);
00368   pentagon(8, 17, 16, 9, 10, type);
00369   pentagon(2, 14, 15, 6, 19, type);
00370   pentagon(2, 13, 12, 4, 14, type);
00371   pentagon(2, 19, 18, 3, 13, type);
00372   pentagon(3, 0, 5, 12, 13, type);
00373   pentagon(6, 15, 8, 10, 11, type);
00374   pentagon(4, 17, 8, 15, 14, type);
00375   pentagon(4, 12, 5, 16, 17, type);
00376 }
00377 
00378 void
00379 glutWireDodecahedron(void)
00380 {
00381   dodecahedron(GL_LINE_LOOP);
00382 }
00383 
00384 void
00385 glutSolidDodecahedron(void)
00386 {
00387   dodecahedron(GL_TRIANGLE_FAN);
00388 }
00389 
00390 static void
00391 recorditem(GLfloat * n1, GLfloat * n2, GLfloat * n3,
00392   GLenum shadeType)
00393 {
00394   GLfloat q0[3], q1[3];
00395 
00396   DIFF3(n1, n2, q0);
00397   DIFF3(n2, n3, q1);
00398   crossprod(q0, q1, q1);
00399   normalize(q1);
00400 
00401   glBegin(shadeType);
00402   glNormal3fv(q1);
00403   glVertex3fv(n1);
00404   glVertex3fv(n2);
00405   glVertex3fv(n3);
00406   glEnd();
00407 }
00408 
00409 static void
00410 subdivide(GLfloat * v0, GLfloat * v1, GLfloat * v2,
00411   GLenum shadeType)
00412 {
00413   int depth;
00414   GLfloat w0[3], w1[3], w2[3];
00415   GLfloat l;
00416   int i, j, k, n;
00417 
00418   depth = 1;
00419   for (i = 0; i < depth; i++) {
00420     for (j = 0; i + j < depth; j++) {
00421       k = depth - i - j;
00422       for (n = 0; n < 3; n++) {
00423         w0[n] = (i * v0[n] + j * v1[n] + k * v2[n]) / depth;
00424         w1[n] = ((i + 1) * v0[n] + j * v1[n] + (k - 1) * v2[n])
00425           / depth;
00426         w2[n] = (i * v0[n] + (j + 1) * v1[n] + (k - 1) * v2[n])
00427           / depth;
00428       }
00429       l = sqrt(w0[0] * w0[0] + w0[1] * w0[1] + w0[2] * w0[2]);
00430       w0[0] /= l;
00431       w0[1] /= l;
00432       w0[2] /= l;
00433       l = sqrt(w1[0] * w1[0] + w1[1] * w1[1] + w1[2] * w1[2]);
00434       w1[0] /= l;
00435       w1[1] /= l;
00436       w1[2] /= l;
00437       l = sqrt(w2[0] * w2[0] + w2[1] * w2[1] + w2[2] * w2[2]);
00438       w2[0] /= l;
00439       w2[1] /= l;
00440       w2[2] /= l;
00441       recorditem(w1, w0, w2, shadeType);
00442     }
00443   }
00444 }
00445 
00446 static void
00447 drawtriangle(int i, GLfloat data[][3], int ndx[][3],
00448   GLenum shadeType)
00449 {
00450   GLfloat *x0, *x1, *x2;
00451 
00452   x0 = data[ndx[i][0]];
00453   x1 = data[ndx[i][1]];
00454   x2 = data[ndx[i][2]];
00455   subdivide(x0, x1, x2, shadeType);
00456 }
00457 
00458 /* octahedron data: The octahedron produced is centered at the
00459    origin and has radius 1.0 */
00460 static GLfloat odata[6][3] =
00461 {
00462   {1.0, 0.0, 0.0},
00463   {-1.0, 0.0, 0.0},
00464   {0.0, 1.0, 0.0},
00465   {0.0, -1.0, 0.0},
00466   {0.0, 0.0, 1.0},
00467   {0.0, 0.0, -1.0}
00468 };
00469 
00470 static int ondex[8][3] =
00471 {
00472   {0, 4, 2},
00473   {1, 2, 4},
00474   {0, 3, 4},
00475   {1, 4, 3},
00476   {0, 2, 5},
00477   {1, 5, 2},
00478   {0, 5, 3},
00479   {1, 3, 5}
00480 };
00481 
00482 static void
00483 octahedron(GLenum shadeType)
00484 {
00485   int i;
00486 
00487   for (i = 0; i < 8; i++) {
00488     drawtriangle(i, odata, ondex, shadeType);
00489   }
00490 }
00491 
00492 void
00493 glutWireOctahedron(void)
00494 {
00495   octahedron(GL_LINE_LOOP);
00496 }
00497 
00498 void
00499 glutSolidOctahedron(void)
00500 {
00501   octahedron(GL_TRIANGLES);
00502 }
00503 
00504 /* icosahedron data: These numbers are rigged to make an
00505    icosahedron of radius 1.0 */
00506 
00507 #define X .525731112119133606
00508 #define Z .850650808352039932
00509 
00510 static GLfloat idata[12][3] =
00511 {
00512   {-X, 0, Z},
00513   {X, 0, Z},
00514   {-X, 0, -Z},
00515   {X, 0, -Z},
00516   {0, Z, X},
00517   {0, Z, -X},
00518   {0, -Z, X},
00519   {0, -Z, -X},
00520   {Z, X, 0},
00521   {-Z, X, 0},
00522   {Z, -X, 0},
00523   {-Z, -X, 0}
00524 };
00525 
00526 static int index[20][3] =
00527 {
00528   {0, 4, 1},
00529   {0, 9, 4},
00530   {9, 5, 4},
00531   {4, 5, 8},
00532   {4, 8, 1},
00533   {8, 10, 1},
00534   {8, 3, 10},
00535   {5, 3, 8},
00536   {5, 2, 3},
00537   {2, 7, 3},
00538   {7, 10, 3},
00539   {7, 6, 10},
00540   {7, 11, 6},
00541   {11, 0, 6},
00542   {0, 1, 6},
00543   {6, 1, 10},
00544   {9, 0, 11},
00545   {9, 11, 2},
00546   {9, 2, 5},
00547   {7, 2, 11},
00548 };
00549 
00550 static void
00551 icosahedron(GLenum shadeType)
00552 {
00553   int i;
00554 
00555   for (i = 0; i < 20; i++) {
00556     drawtriangle(i, idata, index, shadeType);
00557   }
00558 }
00559 
00560 void
00561 glutWireIcosahedron(void)
00562 {
00563   icosahedron(GL_LINE_LOOP);
00564 }
00565 
00566 void
00567 glutSolidIcosahedron(void)
00568 {
00569   icosahedron(GL_TRIANGLES);
00570 }
00571 
00572 /* tetrahedron data: */
00573 
00574 #define T       1.73205080756887729
00575 
00576 static GLfloat tdata[4][3] =
00577 {
00578   {T, T, T},
00579   {T, -T, -T},
00580   {-T, T, -T},
00581   {-T, -T, T}
00582 };
00583 
00584 static int tndex[4][3] =
00585 {
00586   {0, 1, 3},
00587   {2, 1, 0},
00588   {3, 2, 0},
00589   {1, 2, 3}
00590 };
00591 
00592 static void
00593 tetrahedron(GLenum shadeType)
00594 {
00595   int i;
00596 
00597   for (i = 0; i < 4; i++)
00598     drawtriangle(i, tdata, tndex, shadeType);
00599 }
00600 
00601 void
00602 glutWireTetrahedron(void)
00603 {
00604   tetrahedron(GL_LINE_LOOP);
00605 }
00606 
00607 void
00608 glutSolidTetrahedron(void)
00609 {
00610   tetrahedron(GL_TRIANGLES);
00611 }
00612 
 

Powered by Plone

This site conforms to the following standards: