home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / src / exampleCode / 3Dmodeling / example.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-08-02  |  15.7 KB  |  676 lines

  1. /*
  2.  * Copyright 1992, 1993, 1994, Silicon Graphics, Inc.
  3.  * All Rights Reserved.
  4.  *
  5.  * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
  6.  * the contents of this file may not be disclosed to third parties, copied or
  7.  * duplicated in any form, in whole or in part, without the prior written
  8.  * permission of Silicon Graphics, Inc.
  9.  *
  10.  * RESTRICTED RIGHTS LEGEND:
  11.  * Use, duplication or disclosure by the Government is subject to restrictions
  12.  * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
  13.  * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
  14.  * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
  15.  * rights reserved under the Copyright Laws of the United States.
  16.  */
  17.  
  18. /* Tom Davis -- 1992 */
  19.  
  20. /* draw various 3d models */
  21.  
  22. #include <stdio.h>
  23. #include <math.h>
  24. #include <gl.h>
  25. #include <device.h>
  26. #include "3d.h"
  27.  
  28. #define PI    3.14159265358979
  29.  
  30. float    blackvec[3] = {0.0, 0.0, 0.0};
  31. float    whitevec[3] = {1.0, 1.0, 1.0};
  32. static float idmat[4][4] = {1.0,0.0,0.0,0.0,
  33.                 0.0,1.0,0.0,0.0,
  34.         0.0,0.0,1.0,0.0,
  35.         0.0,0.0,0.0,1.0};
  36.  
  37. float  shiny_material[] = {SPECULAR, 0.8, 0.8, 0.8,
  38.                  DIFFUSE,  0.4, 0.4, 0.4,
  39.                      SHININESS, 30.0,
  40.                  LMNULL};
  41.  
  42. float  purple_material[] = {SPECULAR, 0.3, 0.3, 0.3,
  43.                 DIFFUSE,  0.8, 0.0, 0.8,
  44.                 SHININESS, 5.0,
  45.                 AMBIENT,  0.2, 0.0, 0.2, 
  46.                 LMNULL};
  47.  
  48. float  material1[] = {SPECULAR, 0.3, 0.3, 0.3,
  49.                 DIFFUSE,  0.8, 0.8, 0.8,
  50.                 SHININESS, 1.0,
  51.                 LMNULL};
  52.  
  53. float  material2[] = {SPECULAR, 0.3, 0.3, 0.8,
  54.                 DIFFUSE,  0.0, 0.0, 0.8,
  55.                 SHININESS, 2.0,
  56.                 AMBIENT,  0.2, 0.0, 0.2, 
  57.                 LMNULL};
  58.  
  59. float  material3[] = {SPECULAR, 0.3, 0.3, 0.3,
  60.                 DIFFUSE,  0.8, 0.0, 0.0,
  61.                 SHININESS, 50.0,
  62.                 AMBIENT,  0.2, 0.0, 0.0, 
  63.                 LMNULL};
  64.  
  65. float  material4[] = {SPECULAR, 0.3, 0.3, 0.3,
  66.                 DIFFUSE,  0.0, 0.8, 0.8,
  67.                 SHININESS, 5.0,
  68.                 LMNULL};
  69.  
  70. float  blue_light[] = {LCOLOR, 0.0, 0.0, 0.6,
  71.                POSITION, 0.0, 1.0, 0.0, 0.0,
  72.                LMNULL};
  73.  
  74. /*
  75. ** Tell the Graphics Library to DEFINE a simple lighting model
  76. ** that accounts for diffuse and ambient reflection.  This simple
  77. ** lighting model happens to be the default lighting model for 
  78. ** the Graphics Library.
  79. */
  80. void def_simple_light_model()
  81.  
  82. {
  83.     lmdef(DEFLMODEL, 1, 0, NULL);
  84.     lmdef(DEFMATERIAL, 1, 11, shiny_material);
  85.     lmdef(DEFMATERIAL, 2, 15, purple_material);
  86.     lmdef(DEFMATERIAL, 3, 11, material1);
  87.     lmdef(DEFMATERIAL, 4, 15, material2);
  88.     lmdef(DEFMATERIAL, 5, 15, material3);
  89.     lmdef(DEFMATERIAL, 6, 11, material4);
  90.     lmdef(DEFLIGHT, 1, 0, NULL);
  91.     lmdef(DEFLIGHT, 2, 10, blue_light);
  92. }
  93.  
  94. /*
  95. ** Tell the Graphics Library to USE the simple lighting model
  96. ** that we defined earlier.
  97. */
  98. use_simple_light_model()
  99.  
  100. {
  101.     lmbind(LMODEL, 1);
  102.     lmbind(LIGHT0, 1);
  103.     lmbind(LIGHT1, 2);
  104. }
  105.  
  106. /* Here's an idiotic display list.  Just save the vectors and
  107.  * normals in a giant list, and spew them out in order when the
  108.  * draw command comes.
  109.  */
  110.  
  111. float vectlist[200000][3];
  112. float normlist[200000][3];
  113. long vcount;
  114.  
  115. float trilist[100000][3];
  116. float trinorm[100000][3];
  117. long tcount;
  118.  
  119. void initdisplaylist()
  120. {
  121.     tcount = vcount = 0;
  122. }
  123.  
  124. /* ... and the corresponding idiotic savefunc */
  125.  
  126. void savefunc(type, n0, v0, n1, v1, n2, v2, n3, v3)
  127. long    type;
  128. float    *n0, *n1, *n2, *n3, *v0, *v1, *v2, *v3;
  129. {
  130.     if (type == ADD_QUAD) {
  131.     if (vcount > 200000) {
  132.         fprintf(stderr, "too many points\n");
  133.         exit();
  134.     }
  135.     copy3(n0, &normlist[vcount][0]);
  136.     copy3(v0, &vectlist[vcount++][0]);
  137.     copy3(n1, &normlist[vcount][0]);
  138.     copy3(v1, &vectlist[vcount++][0]);
  139.     copy3(n2, &normlist[vcount][0]);
  140.     copy3(v2, &vectlist[vcount++][0]);
  141.     copy3(n3, &normlist[vcount][0]);
  142.     copy3(v3, &vectlist[vcount++][0]);
  143.     } else {
  144.     if (tcount > 100000) {
  145.         fprintf(stderr, "too many points\n");
  146.         exit();
  147.     }
  148.     copy3(n0, &trinorm[tcount][0]);
  149.     copy3(v0, &trilist[tcount++][0]);
  150.     copy3(n1, &trinorm[tcount][0]);
  151.     copy3(v1, &trilist[tcount++][0]);
  152.     copy3(n2, &trinorm[tcount][0]);
  153.     copy3(v2, &trilist[tcount++][0]);
  154.     }
  155. }
  156.  
  157. void drawdisplaylist()
  158. {
  159.     long i;
  160.  
  161.     for (i = 0; i < vcount;) {
  162.     bgnpolygon();
  163.     n3f(&normlist[i][0]);
  164.     v3f(&vectlist[i++][0]);
  165.     n3f(&normlist[i][0]);
  166.     v3f(&vectlist[i++][0]);
  167.     n3f(&normlist[i][0]);
  168.     v3f(&vectlist[i++][0]);
  169.     n3f(&normlist[i][0]);
  170.     v3f(&vectlist[i++][0]);
  171.     endpolygon();
  172.     }
  173.     for (i = 0; i < tcount;) {
  174.     bgnpolygon();
  175.     n3f(&trinorm[i][0]);
  176.     v3f(&trilist[i++][0]);
  177.     n3f(&trinorm[i][0]);
  178.     v3f(&trilist[i++][0]);
  179.     n3f(&trinorm[i][0]);
  180.     v3f(&trilist[i++][0]);
  181.     endpolygon();
  182.     }
  183. }
  184.  
  185. void drawworld()
  186. {
  187.     c3f(blackvec);
  188.     clear();
  189.     zclear();
  190.     drawdisplaylist();
  191. }
  192.  
  193. void makeethanol()
  194. {
  195.     initdisplaylist();
  196.  
  197.     m_resetmatrixstack();
  198.     quadsphere(14, 14, savefunc);
  199.     m_pushmatrix();
  200.     m_scale(.6, .6, .6);
  201.     m_translate(-1.0, -1.0, -1.0);
  202.     quadsphere(16, 16, savefunc);
  203.     m_popmatrix();
  204.     m_pushmatrix();
  205.     m_scale(.6, .6, .6);
  206.     m_translate(1.0, 1.0, -1.0);
  207.     quadsphere(16, 16, savefunc);
  208.     m_popmatrix();
  209.     m_pushmatrix();
  210.     m_scale(.6, .6, .6);
  211.     m_translate(-1.0, 1.0, 1.0);
  212.     quadsphere(16, 16, savefunc);
  213.     m_popmatrix();
  214.     m_pushmatrix();
  215.     m_translate(.8, -.8, .8);
  216.     quadsphere(14, 14, savefunc);
  217.     m_pushmatrix();
  218.     m_scale(.6, .6, .6);
  219.     m_translate(-1.0, -1.0, 1.0);
  220.     quadsphere(16, 16, savefunc);
  221.     m_popmatrix();
  222.     m_pushmatrix();
  223.     m_scale(.6, .6, .6);
  224.     m_translate(1.0, -1.0, -1.0);
  225.     quadsphere(16, 16, savefunc);
  226.     m_popmatrix();
  227.     m_pushmatrix();
  228.     m_scale(.8, .8, .8);
  229.     m_translate(0.7, 0.7, 0.7);
  230.     quadsphere(16, 16, savefunc);
  231.     m_translate(.5, -.5, .5);
  232.     m_scale(.78, .78, .78);
  233.     quadsphere(16, 16, savefunc);
  234.     m_popmatrix();
  235.     m_popmatrix();
  236. }
  237.  
  238. void makebenzene()
  239. {
  240.     long i;
  241.     float theta, t1, t2;
  242.  
  243.     initdisplaylist();
  244.     m_resetmatrixstack();
  245.     for (i = 0; i < 6; i++) {
  246.     theta = i*2.0*PI/6;
  247.     t1 = cos(theta);
  248.     t2 = sin(theta);
  249.     m_pushmatrix();
  250.     m_translate(t1, t2, 0.0);
  251.     quadsphere(12, 12, savefunc);
  252.     m_popmatrix();
  253.     m_pushmatrix();
  254.     m_translate(t1*1.8, t2*1.8, 0.0);
  255.     m_scale(.6, .6, .6);
  256.     quadsphere(14, 14, savefunc);
  257.     m_popmatrix();
  258.     }
  259. }
  260.  
  261.  
  262. #define NORMFACTOR 40.0
  263.  
  264. #define S   (200.0/NORMFACTOR)   /* side of surrounding cube */
  265. #define R   (18.0/NORMFACTOR)    /* cylinder radius == half D, below */
  266. #define D   (2.0*R)           /* offset for doubled edges */
  267. #define SRD    (S-(R+D))
  268. #define NSIDES    12        /* must be multiple of 4 to match at corners */
  269. #define ELBOWSTEPS 5
  270.  
  271. float endpts[55][3] = {
  272.     {R-S/2.0, 2*R+D-S/2.0, R-S/2.0},
  273.     {R-S/2.0, R+D-S/2.0, R-S/2.0}, /* corner */
  274.     {2*R-S/2.0, R+D-S/2.0, R-S/2.0},
  275.     {SRD-R-S/2.0, R+D-S/2.0, R-S/2.0},
  276.     {SRD-S/2.0, R+D-S/2.0, R-S/2.0}, /* corner */
  277.     {SRD-S/2.0, 2*R+D-S/2.0, R-S/2.0},
  278.     {SRD-S/2.0, S-2*R-S/2.0, R-S/2.0},
  279.     {SRD-S/2.0, S-R-S/2.0, R-S/2.0}, /* corner */
  280.     {SRD-R-S/2.0, S-R-S/2.0, R-S/2.0},
  281.     {2*R+D-S/2.0, S-R-S/2.0, R-S/2.0},
  282.     {R+D-S/2.0, S-R-S/2.0, R-S/2.0}, /* corner */
  283.     {R+D-S/2.0, S-R-S/2.0, 2*R-S/2.0},
  284.     {R+D-S/2.0, S-R-S/2.0, SRD-R-S/2.0},
  285.     {R+D-S/2.0, S-R-S/2.0, SRD-S/2.0}, /* corner */
  286.     {2*R+D-S/2.0, S-R-S/2.0, SRD-S/2.0},
  287.     {S-2*R-S/2.0, S-R-S/2.0, SRD-S/2.0},
  288.     {S-R-S/2.0, S-R-S/2.0, SRD-S/2.0}, /* corner */
  289.     {S-R-S/2.0, S-R-S/2.0, SRD-R-S/2.0},
  290.     {S-R-S/2.0, S-R-S/2.0, 2*R+D-S/2.0},
  291.     {S-R-S/2.0, S-R-S/2.0, R+D-S/2.0}, /* corner */
  292.     {S-R-S/2.0, S-2*R-S/2.0, R+D-S/2.0},
  293.     {S-R-S/2.0, 2*R+D-S/2.0, R+D-S/2.0},
  294.     {S-R-S/2.0, R+D-S/2.0, R+D-S/2.0}, /* corner */
  295.     {S-R-S/2.0, R+D-S/2.0, 2*R+D-S/2.0},
  296.     {S-R-S/2.0, R+D-S/2.0, S-2*R-S/2.0},
  297.     {S-R-S/2.0, R+D-S/2.0, S-R-S/2.0}, /* corner */
  298.     {S-R-S/2.0, 2*R+D-S/2.0, S-R-S/2.0},
  299.     {S-R-S/2.0, SRD-R-S/2.0, S-R-S/2.0},
  300.     {S-R-S/2.0, SRD-S/2.0, S-R-S/2.0}, /* corner */
  301.     {S-2*R-S/2.0, SRD-S/2.0, S-R-S/2.0},
  302.     {2*R+D-S/2.0, SRD-S/2.0, S-R-S/2.0},
  303.     {R+D-S/2.0, SRD-S/2.0, S-R-S/2.0}, /* corner */
  304.     {R+D-S/2.0, SRD-R-S/2.0, S-R-S/2.0},
  305.     {R+D-S/2.0, 2*R-S/2.0, S-R-S/2.0},
  306.     {R+D-S/2.0, R-S/2.0, S-R-S/2.0}, /* corner */
  307.     {2*R+D-S/2.0, R-S/2.0, S-R-S/2.0},
  308.     {SRD-R-S/2.0, R-S/2.0, S-R-S/2.0},
  309.     {SRD-S/2.0, R-S/2.0, S-R-S/2.0}, /* corner */
  310.     {SRD-S/2.0, R-S/2.0, S-2*R-S/2.0},
  311.     {SRD-S/2.0, R-S/2.0, 2*R+D-S/2.0},
  312.     {SRD-S/2.0, R-S/2.0, R+D-S/2.0}, /* corner */
  313.     {SRD-R-S/2.0, R-S/2.0, R+D-S/2.0},
  314.     {2*R-S/2.0, R-S/2.0, R+D-S/2.0},
  315.     {R-S/2.0, R-S/2.0, R+D-S/2.0}, /* corner */
  316.     {R-S/2.0, R-S/2.0, 2*R+D-S/2.0},
  317.     {R-S/2.0, R-S/2.0, SRD-R-S/2.0},
  318.     {R-S/2.0, R-S/2.0, SRD-S/2.0}, /* corner */
  319.     {R-S/2.0, 2*R-S/2.0, SRD-S/2.0},
  320.     {R-S/2.0, SRD-R-S/2.0, SRD-S/2.0},
  321.     {R-S/2.0, SRD-S/2.0, SRD-S/2.0}, /* corner */
  322.     {R-S/2.0, SRD-S/2.0, SRD-R-S/2.0},
  323.     {R-S/2.0, SRD-S/2.0, 2*R-S/2.0},
  324.     {R-S/2.0, SRD-S/2.0, R-S/2.0}, /* corner */
  325.     {R-S/2.0, SRD-R-S/2.0, R-S/2.0},
  326.     {R-S/2.0, 2*R+D-S/2.0, R-S/2.0}, /* duplicate of 0 */
  327. };
  328.  
  329. fixupendpts()
  330. {
  331.     long i, j;
  332.  
  333.     for (i = 1; i < 54; i += 3)
  334.     for (j = 0; j < 3; j++)
  335.         endpts[i][j] = endpts[i-1][j] + endpts[i+1][j] - endpts[i][j];
  336. }
  337.  
  338. makesgilogo()
  339. {
  340.     long i;
  341.     static long inited = 0;
  342.  
  343.     if (inited == 0) { fixupendpts(); inited = 1; }
  344.     initdisplaylist();
  345.     m_resetmatrixstack();
  346.     for (i = 2; i < 54; i+= 3)
  347.     cylinder(&endpts[i][0], &endpts[i+1][0], R*.99, NSIDES, savefunc);
  348.  
  349.     for (i = 0; i < 54; i += 3)
  350.     elbow(&endpts[i][0], &endpts[i+1][0], &endpts[i+2][0],
  351.                         R*.99, NSIDES, 5, savefunc);
  352. }
  353.  
  354. float aa[3] = {5.0, -5.0, -5.5};
  355. float bb[3] = {-5.0, -5.0, -4.5};
  356. float cc[3] = {-5.0, 5.0, -3.5};
  357. float dd[3] = {5.0, 5.0, -2.5};
  358. float ee[3] = {5.0, -5.0, -1.5};
  359. float ff[3] = {-5.0, -5.0, -0.5};
  360. float gg[3] = {-5.0, 5.0, 0.5};
  361. float hh[3] = {5.0, 5.0, 1.5};
  362. float ii[3] = {5.0, -5.0, 2.5};
  363. float jj[3] = {-5.0, -5.0, 3.5};
  364. float kk[3] = {-5.0, 5.0, 4.5};
  365. float ll[3] = {5.0, 5.0, 5.5};
  366.  
  367. float zero[3] = {0.0, 0.0, 0.0};
  368. float one[3] = {1.0, 0.0, 0.0};
  369.  
  370. makespiral()
  371. {
  372.     curve_t    *c;
  373.  
  374.     initdisplaylist();
  375.     m_resetmatrixstack();
  376.     m_scale(0.5, 0.5, 0.5);
  377.     c = newbsplinecurve(aa, bb, cc, dd);
  378.     makeworm(c, .6, 12, 7, savefunc);
  379.     freecurve(c);
  380.     c = newbsplinecurve(bb, cc, dd, ee);
  381.     makeworm(c, .6, 12, 7, savefunc);
  382.     freecurve(c);
  383.     c = newbsplinecurve(cc, dd, ee, ff);
  384.     makeworm(c, .6, 12, 7, savefunc);
  385.     freecurve(c);
  386.     c = newbsplinecurve(dd, ee, ff, gg);
  387.     makeworm(c, .6, 12, 7, savefunc);
  388.     freecurve(c);
  389.     c = newbsplinecurve(ee, ff, gg, hh);
  390.     makeworm(c, .6, 12, 7, savefunc);
  391.     freecurve(c);
  392.     c = newbsplinecurve(ff, gg, hh, ii);
  393.     makeworm(c, .6, 12, 7, savefunc);
  394.     freecurve(c);
  395.     c = newbsplinecurve(gg, hh, ii, jj);
  396.     makeworm(c, .6, 12, 7, savefunc);
  397.     freecurve(c);
  398.     c = newbsplinecurve(hh, ii, jj, kk);
  399.     makeworm(c, .6, 12, 7, savefunc);
  400.     freecurve(c);
  401.     c = newbsplinecurve(ii, jj, kk, ll);
  402.     makeworm(c, .6, 12, 7, savefunc);
  403.     freecurve(c);
  404.     m_rotate(PI/2.0, 'y');
  405.     doughnut(.4, 3.0, 12, 40, savefunc);
  406.     dodecahedron(zero, 1.0, savefunc);
  407. }
  408.  
  409. #define A    5.0
  410. #define B    3.0
  411.  
  412. float xx(float t)
  413. {
  414.     return .3*sin(A*t) + .4*cos(B*t) + 1;
  415. }
  416.  
  417. float yy(float t)
  418. {
  419.     return 2.0*t;
  420. }
  421.  
  422. float zz(float t)
  423. {
  424.     return 0.0;
  425. }
  426.  
  427. float xx1(float t)
  428. {
  429.     return .3*A*cos(A*t) -.4*B*sin(B*t);
  430. }
  431.  
  432. float yy1(float t)
  433. {
  434.     return 2.0;
  435. }
  436.  
  437. float zz1(float t)
  438. {
  439.     return 0.0;
  440. }
  441.  
  442. float xx2(float t)
  443. {
  444.     return -.3*A*A*sin(A*t) -.4*B*B*cos(B*t);
  445. }
  446.  
  447. float yy2(float t)
  448. {
  449.     return 0.0;
  450. }
  451.  
  452. float zz2(float t)
  453. {
  454.     return 0.0;
  455. }
  456.  
  457. makesmoothsolidofrevolution()
  458. {
  459.     pwlin_t    *pw;
  460.     curve_t    *c;
  461.  
  462.     initdisplaylist();
  463.     m_resetmatrixstack();
  464.     c = newanalyticcurve(xx, yy, zz, xx1, yy1, zz1, xx2, yy2, zz2);
  465.     pw = pwlinfromcurve(c, 40);
  466.     freecurve(c);
  467.     smoothsolidofrevolution(pw, 40, savefunc);
  468.     freepwlin(pw);
  469. }
  470.  
  471. float pwdata[] = {
  472.     0, 0, 0,   1, 0, 0,   1, 1, 0,   0, 1, 0,   0, 0, 0
  473. };
  474.  
  475. makesquareworm()
  476. {
  477.     pwlin_t    *pw;
  478.     curve_t    *c;
  479.  
  480.     initdisplaylist();
  481.     m_resetmatrixstack();
  482.     m_scale(0.5, 0.5, 0.5);
  483.     pw = makepwlin(5, pwdata);
  484.     c = newbeziercurve(hh, ii, jj, kk);
  485.     makepwlworm(c, pw, 40, savefunc);
  486.     freecurve(c);
  487.     freepwlin(pw);
  488. }
  489.  
  490. float pw1data[] = {
  491.     0, 0, 0,  .2, .2, 0,  .5, .2, 0,  .5, .5, 0,  .2, 1, 0,  0, 1, 0
  492. };
  493.  
  494. makesolidofrevolution()
  495. {
  496.     pwlin_t    *pw;
  497.  
  498.     initdisplaylist();
  499.     m_resetmatrixstack();
  500.     m_scale(3.0, 3.0, 3.0);
  501.     pw = makepwlin(6, pw1data);
  502.     solidofrevolution(pw, 40, savefunc);
  503.     freepwlin(pw);
  504. }
  505.  
  506. float p1[3] = {-2.0, -2.0, -2.0};
  507. float p2[3] = {-2.0, 2.0, 2.0};
  508. float p3[3] = {2.0, -2.0, 2.0};
  509. float p4[3] = {2.0, 2.0, -2.0};
  510.  
  511. makeplatonicsolids()
  512. {
  513.     initdisplaylist();
  514.     m_resetmatrixstack();
  515.     drawbox(-0.5, 0.5, -0.5, 0.5, -0.5, 0.5, savefunc);
  516.     icosahedron(p1, .5, savefunc);
  517.     octahedron(p2, .5, savefunc);
  518.     tetrahedron(p3, .5, savefunc);
  519.     dodecahedron(p4, .5, savefunc);
  520. }
  521.  
  522. makewarp()
  523. {
  524.     initdisplaylist();
  525.     m_resetmatrixstack();
  526.     m_pushmatrix();
  527.     m_shear(2.0, 1.0, 0.0);
  528.     drawbox(-0.5, 0.5, -0.5, 0.5, -0.5, 0.5, savefunc);
  529.     m_popmatrix();
  530.     m_pushmatrix();
  531.     m_translate(2.0, 0.0, 0.0);
  532.     m_scale(.3, 1.0, 1.7);
  533.     trisphere(zero, 1.0, 4, savefunc);
  534.     m_popmatrix();
  535.     m_pushmatrix();
  536.     m_translate(-2.0, 0.0, 0.0);
  537.     m_rotate(PI/4.0, 'x');
  538.     m_rotate(PI/3.0, 'z');
  539.     cylinder(zero, one, 0.3, 12, savefunc);
  540.     m_popmatrix();
  541. }
  542.  
  543. static long menu, materials, models;
  544.  
  545. initmenus()
  546. {
  547.     materials = defpup("Shiny%x1|Purple%x2|Chalk%x3|Blue%x4|Red Plastic%x5|Cyan%x6");
  548.     models = defpup("Ethanol%x100|SGI Logo%x101|Benzene%x102|Spiral%x103");
  549.     addtopup(models, "Solid of Revolution%x107");
  550.     addtopup(models, "Smooth Solid of Rev.%x104|Square Worm%x105|Platonic Solids%x106");
  551.     addtopup(models, "Warped Stuff%x108");
  552.     menu = defpup("Models %m|Materials %m|Save Spin%x999|Quit%x1000", models, materials);
  553. }
  554.  
  555. main(int argc, char **argv)
  556. {
  557.     long model = 1;
  558.     long material = 1;
  559.     long cmd;
  560.  
  561.     keepaspect(1, 1);
  562.     foreground();
  563.     winopen("worm");
  564.     backface(1);
  565.     RGBmode();
  566.     doublebuffer();
  567.     zbuffer(TRUE);
  568.     gconfig();
  569.     mmode(MVIEWING);
  570.     perspective(450, 1.0, 1.0, 1000.0);
  571.     def_simple_light_model();
  572.     use_simple_light_model();
  573.     initmenus();
  574.     makeethanol();
  575.     lmbind(MATERIAL, material);
  576.     while (1) {
  577.     if (getbutton(RIGHTMOUSE)) {
  578.         cmd = dopup(menu);
  579.         if (cmd > 0 && cmd <= 6)
  580.         lmbind(MATERIAL, material = cmd);
  581.         else switch (cmd) {
  582.         case 100:
  583.             makeethanol();
  584.             break;
  585.         case 101:
  586.             makesgilogo();
  587.             break;
  588.         case 102:
  589.             makebenzene();
  590.             break;
  591.         case 103:
  592.             makespiral();
  593.             break;
  594.         case 104:
  595.             makesmoothsolidofrevolution();
  596.             break;
  597.         case 105:
  598.             makesquareworm();
  599.             break;
  600.         case 106:
  601.             makeplatonicsolids();
  602.             break;
  603.         case 107:
  604.             makesolidofrevolution();
  605.             break;
  606.         case 108:
  607.             makewarp();
  608.             break;
  609.         case 999:
  610. /*
  611.             savetospinfile();
  612. */
  613.             break;
  614.         case 1000:
  615.             return;
  616.         }
  617.     }
  618.     trackmodel(drawworld, 15.0, 0.0, 0.0, 0.0);
  619.     }
  620. }
  621.  
  622. FILE *binfile;
  623.  
  624. xsavetospinfile()
  625. {
  626.     long i;
  627.  
  628.     for (i = 0; i < vcount; i++) {
  629.         printf("{%g,  %g,  %g},\n", vectlist[i][0], vectlist[i][1], vectlist[i][2]);
  630.     }
  631.     fflush(stdout);
  632.     return;
  633. }
  634.  
  635. savetospinfile()
  636. {
  637.     long i;
  638.  
  639.     openfile(vcount + (tcount*4)/3);
  640.     for (i = 0; i < vcount; i++) {
  641.     fwrite(&normlist[i][0], 4, 3, binfile);
  642.     fwrite(&vectlist[i][0], 4, 3, binfile);
  643.     }
  644.     for (i = 0; i < tcount;) { /* hack!!!! write triangle as quad */
  645.     fwrite(&trinorm[i][0], 4, 3, binfile);
  646.     fwrite(&trilist[i++][0], 4, 3, binfile);
  647.     fwrite(&trinorm[i][0], 4, 3, binfile);
  648.     fwrite(&trilist[i++][0], 4, 3, binfile);
  649.     fwrite(&trinorm[i][0], 4, 3, binfile);
  650.     fwrite(&trilist[i][0], 4, 3, binfile);
  651.     fwrite(&trinorm[i][0], 4, 3, binfile);
  652.     fwrite(&trilist[i++][0], 4, 3, binfile);
  653.     }
  654.     fclose(binfile);
  655.     return;
  656. }
  657.  
  658. openfile(long pcount)
  659. {
  660.     long magic[3];
  661.  
  662.     magic[0] = 0x5423;
  663.     magic[1] = pcount*4;
  664.     magic[2] = 0;   /* no color values */
  665.  
  666.     if ((binfile = fopen("model.spin", "w")) == 0) {
  667.     fprintf(stderr, "couldn't open model.sgo\n");
  668.     return;
  669.     }
  670.     fwrite(magic, 4, 3, binfile);
  671. }
  672.                             
  673.  
  674.  
  675.  
  676.