[comp.sys.sgi] Graphical Demo Program

markov@ruuinf.cs.ruu.nl (dr.m.h. overmars) (08/02/90)

Here follows a little demo program I wrote. Simply save it to a file, unshar it
(type sh <filename>) and type make. I hope you like it. It probably only runs
well on machines that have at least Turbo Graphics. It was written and tested
on a 4D/25TG. Feel free to extend it and send changes to me.

Mark Overmars

-------------------------------- cut here -------------------------------
#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of shell archive."
# Contents:  Makefile README moving.c object.c object.h
# Wrapped by markov@ruuinf on Thu Aug  2 14:30:05 1990
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'Makefile' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'Makefile'\"
else
echo shar: Extracting \"'Makefile'\" \(168 characters\)
sed "s/^X//" >'Makefile' <<'END_OF_FILE'
XFILEo = moving.o object.o
X
XFILElib = -lgl_s -lm 
X
Xall : 		moving
X
Xmoving : 	$(FILEo) 
X		cc $(FILEo)  $(FILElib) -o moving
X
X$(FILEo): 	
X		cc -O -c $*.c
X
Xclean:
X		rm *.o
END_OF_FILE
if test 168 -ne `wc -c <'Makefile'`; then
    echo shar: \"'Makefile'\" unpacked with wrong size!
fi
# end of 'Makefile'
fi
if test -f 'README' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'README'\"
else
echo shar: Extracting \"'README'\" \(1547 characters\)
sed "s/^X//" >'README' <<'END_OF_FILE'
Xversion 1.0
X                          MOVING
X                          ======
X
XThis is a simple program, showing some of the 3-dim possibilities of
Xthe Graphical Library. It uses object.c that provides a number of basic
Xobjects, like spheres, cubes and cylinders that can also be used in other
Xprograms. moving has some special features like a moving icon, a possible
Xsecond window on the same moving stuff, it can indicate the number of frames
Xper second it makes, etc.
X
XThe right mouse button operates a menu. This has the following items:
X
XShow Front View:	Gives you a second window.
XObjects:		Here you can indicate which objects you want to see.
XDisplay Mode:		Allows you to switch between wire frame and
X			filled polygons.
XLighting Mode:		Allows you to switch between flat shading and
X			Gouraud shading.
XExtras:			Gives you a submenu:
X				Backface Culling: Toggles backface culling.
X				Show Frames:      Indicates frames per second.
X				Faster:           Faster motion.
X				Slower:           Slower motion.
XExit:			This will be clear (also <Esc> exits).
X
XMotion can be stopped and continued at any moment by pressing the left
Xmouse button.
X
XTo create the program, simply type make.
X
XThe program has only been tested on a 4D/25 TG. I think it needs at least
XTG to run reasonably smooth.
X
XThis program and its code can be used freely. No responsibility is taken
Xwhatsoever. If you make any changes (e.g. add objects), please send me
Xa copy.
X
Xwritten by Mark Overmars, Dept. of Computer Science, Utrecht University,
XEmail: markov@cs.ruu.nl.
X
END_OF_FILE
if test 1547 -ne `wc -c <'README'`; then
    echo shar: \"'README'\" unpacked with wrong size!
fi
# end of 'README'
fi
if test -f 'moving.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'moving.c'\"
else
echo shar: Extracting \"'moving.c'\" \(10214 characters\)
sed "s/^X//" >'moving.c' <<'END_OF_FILE'
X#include <gl/gl.h>
X#include <gl/device.h>
X#include <stdio.h>
X#include <sys/time.h>
X#include "object.h"
X
X/****
X   This is a simple application to use the objects defined in\
X   object.c. It draws some rotating objects, using
X   different materials and different transformations.
X   It allows for multiple views of the object in different windows.
X   The right mouse button operates the pop-up menu.
X
X   To add objects: 
X      - create a new object in object.c (and object.h)
X      - add a draw command in redraw
X      - add a material and bind it
X      - add a menu entry
X   Up to 20 different objects are supported
X
X   This is version 1.0.
X
X   Written by Mark Overmars, Dept. of Computer Science, University of Utrecht,
X   Email: markov@cs.ruu.nl
X****/
X
X#define MAXOBJ 20
X
Xint frames,back,wire,flat,incr; /* toggles to indicate whay of display */
Xint ob[MAXOBJ];                 /* indicates which objects to show */
Xint lcount;                     /* last frame cout */
Xfloat time;                     /* the "time" so far */
Xfloat speed;			/* the rotation speed */
Xlong win1, win2;                /* the window identifiers */
X
Xdrw(obj,r1,r2,r3,t1,t2,t3,s1,s2,s3,mat)
X/* draws a particular object. */
XOBJECT obj;
Xfloat r1,r2,r3,t1,t2,t3,s1,s2,s3;
Xint mat;
X{
X    pushmatrix();
X    rot(time*r1,'X'); rot(time*r2,'Y'); rot(time*r3,'Z');
X    translate(t1,t2,t3); scale(s1,s2,s3);
X    lmbind(MATERIAL,mat); drawobject(obj,wire,flat);
X    popmatrix();
X}
X
Xredraw()
X/* draws all the objects in the current window */
X{
X    char str[100];
X    backface(back);
X    /* clear the screen */
X    zclear();
X    RGBcolor(43,169,255);
X    clear();
X    /* do the drawing */
X    if (ob[0]) drw(      sphere,  3.0,3.1,2.0,  2.2, 1.2, 2.0,  0.8,0.8,0.8, 1);
X    if (ob[1]) drw(    cylinder,  3.2,2.6,1.8, -1.9, 1.2, 1.6,  0.3,0.3,1.0, 4);
X    if (ob[2]) drw(        cube,  2.2,3.3,1.4, -1.0, 1.2,-1.5,  0.6,0.6,0.6, 3);
X    if (ob[3]) drw(        cone,  4.2,2.1,3.2,  1.2, 1.3, 1.0,  0.5,0.5,0.8, 2);
X    if (ob[3]) drw(      sphere,  4.2,2.1,3.2,  1.2, 1.3, 0.0,  0.5,0.5,0.5,51);
X    if (ob[4]) drw(      sphere,  1.2,3.3,2.4, -2.0, 1.4,-2.1,  0.8,0.8,0.2, 5);
X    if (ob[5]) drw(        cube,  3.2,3.6,2.4,  1.1, 1.6, 2.5,  0.8,0.3,0.1, 6);
X    if (ob[6]) drw(       glass,  2.7,1.9,3.1,  1.6, 1.3, 0.7,  2.0,2.0,2.0, 7);
X    if (ob[7]) drw(     pyramid,  2.3,2.7,3.3,  1.1, 2.3, 1.7,  0.6,0.6,0.5, 8);
X    /* show frame count if required */
X    if (frames && winget() == win1)
X    {
X    	cpack(0xffffff);
X	cmov(-2.1,-2.1,4.0);
X	sprintf(str,"%d frames per second",lcount);
X	charstr(str);
X    };
X    /* ready */
X    swapbuffers();
X}
X
X/* The identity matrix. */
XMatrix idmat = {1.0,0.0,0.0,0.0,
X	        0.0,1.0,0.0,0.0,
X		0.0,0.0,1.0,0.0,
X		0.0,0.0,0.0,1.0};
X
X/* The different materials. */
Xfloat mater1[] = 
X    {SPECULAR,0.8,0.0,0.0,DIFFUSE,0.4,0.0,0.0,SHININESS,40.0,LMNULL};
Xfloat mater51[] = 
X    {SPECULAR,0.2,0.0,0.1,DIFFUSE,0.8,0.0,0.3,SHININESS,10.0,LMNULL};
Xfloat mater2[] =
X    {SPECULAR,1.0,0.4,0.0,DIFFUSE,1.0,0.4,0.0,SHININESS,80.0,LMNULL};
Xfloat mater3[] =
X    {SPECULAR,0.0,0.0,0.6,DIFFUSE,0.0,0.0,0.8,SHININESS,60.0,LMNULL};
Xfloat mater4[] =
X    {SPECULAR,0.0,1.0,0.0,DIFFUSE,0.0,0.6,0.0,SHININESS,120.0,LMNULL};
Xfloat mater5[] =
X    {SPECULAR,1.0,1.0,0.0,DIFFUSE,0.6,0.6,0.0,SHININESS,100.0,LMNULL};
Xfloat mater6[] =
X    {SPECULAR,1.0,0.0,1.0,DIFFUSE,0.6,0.0,0.6,SHININESS,120.0,LMNULL};
Xfloat mater7[] =
X    {SPECULAR,0.9,0.9,0.9,DIFFUSE,0.6,0.6,0.6,SHININESS,120.0,LMNULL};
Xfloat mater8[] =
X    {SPECULAR,0.4,0.7,0.4,DIFFUSE,0.5,1.0,0.5,SHININESS,50.0,LMNULL};
X
X/* The lightsources. */
Xfloat light1[] = {LCOLOR,1.0,1.0,1.0,POSITION,10.0,10.0,5.0,0.0,LMNULL};
Xfloat light2[] = {LCOLOR,1.0,1.0,1.0,POSITION,-10.0,10.0,5.0,0.0,LMNULL};
X
X/* The lightmodel. */
Xfloat model[] = {AMBIENT,0.4,0.4,0.4,LMNULL};
X
Xinit()
X/* Initializes all settings for a window. */
X{
X    zbuffer(TRUE);
X    doublebuffer();
X    RGBmode();
X    gconfig();
X    mmode(MVIEWING);
X    perspective(400,1.0,1.0,34.0);
X    loadmatrix(idmat);
X    /* set up the devices */
X    qdevice(MOUSE1);
X    qdevice(MOUSE3);
X    qdevice(ESCKEY);
X    qdevice(WINFREEZE);
X    qdevice(WINTHAW);
X    /* define materials and lights */
X    lmdef(DEFMATERIAL, 1, 11, mater1);
X    lmdef(DEFMATERIAL,51, 11, mater51);
X    lmdef(DEFMATERIAL, 2, 11, mater2);
X    lmdef(DEFMATERIAL, 3, 11, mater3);
X    lmdef(DEFMATERIAL, 4, 11, mater4);
X    lmdef(DEFMATERIAL, 5, 11, mater5);
X    lmdef(DEFMATERIAL, 6, 11, mater6);
X    lmdef(DEFMATERIAL, 7, 11, mater7);
X    lmdef(DEFMATERIAL, 8, 11, mater8);
X    lmdef(DEFLIGHT, 1, 10, light1);
X    lmdef(DEFLIGHT, 2, 10, light2);
X    lmdef(DEFLMODEL, 1, 5, model);
X    lmbind(LIGHT0,1);
X    lmbind(LIGHT1,2);
X    lmbind(LMODEL,1);
X}
X
X/*** Handling the menu. ***/
X
Xlong mainmenu, confirmmenu, speedmenu, formmenu, lightmenu, extramenu, omenu;
X
Xcreateobjectmenu()
X{
X    omenu = newpup();
X    addtopup(omenu,"  Show All %x71 | Show None %x72 %l");
X    if (ob[0]) {addtopup(omenu,"-> Sphere %x41");}
X         else  {addtopup(omenu,"   Sphere %x41");};
X    if (ob[1]) {addtopup(omenu,"-> Cylinder %x42");}
X         else  {addtopup(omenu,"   Cylinder %x42");};
X    if (ob[2]) {addtopup(omenu,"-> Cube %x43");}
X         else  {addtopup(omenu,"   Cube %x43");};
X    if (ob[3]) {addtopup(omenu,"-> Ice Cream %x44");}
X         else  {addtopup(omenu,"   Ice Cream %x44");};
X    if (ob[4]) {addtopup(omenu,"-> Disk %x45");}
X         else  {addtopup(omenu,"   Disk %x45");};
X    if (ob[5]) {addtopup(omenu,"-> Diamond %x46");}
X         else  {addtopup(omenu,"   Diamond %x46");};
X    if (ob[6]) {addtopup(omenu,"-> Glass %x47");}
X         else  {addtopup(omenu,"   Glass %x47");};
X    if (ob[7]) {addtopup(omenu,"-> Pyramid %x48");}
X         else  {addtopup(omenu,"   Pyramid %x48");};
X}
X
Xcreateformmenu()
X{
X    formmenu = newpup();
X    if (wire)  {addtopup(formmenu,"-> Wire Frame %x11");}
X         else  {addtopup(formmenu,"   Wire Frame %x11");};
X    if (wire)  {addtopup(formmenu,"   Filled %x12");}
X         else  {addtopup(formmenu,"-> Filled %x12");};
X}
X
Xcreatelightmenu()
X{
X    lightmenu = newpup();
X    if (flat)  {addtopup(lightmenu,"-> Flat Shaded %x21");}
X         else  {addtopup(lightmenu,"   Flat Shaded %x21");};
X    if (flat)  {addtopup(lightmenu,"   Gouraud Shaded %x22");}
X         else  {addtopup(lightmenu,"-> Gouraud Shaded %x22");};
X}
X
Xcreateextramenu()
X{
X    extramenu = newpup();
X    if (back)  {addtopup(extramenu,"-> Backface Culling %x31");}
X         else  {addtopup(extramenu,"   Backface Culling %x31");};
X    if (frames){addtopup(extramenu,"-> Show Frames %x32 %l");}
X         else  {addtopup(extramenu,"   Show Frames %x32 %l");};
X    addtopup(extramenu,"  Faster %x33 |  Slower %x34");
X}
X
Xcreatemenu()
X/* Creates the menu */
X{
X    createobjectmenu();
X    createformmenu();
X    createlightmenu();
X    createextramenu();
X    mainmenu = newpup();
X    addtopup(mainmenu,"Objects Demo %t");
X    if (win2 == 0){addtopup(mainmenu,"Show Front View %x1 %l");}
X    addtopup(mainmenu,"Objects %m",omenu);
X    addtopup(mainmenu,"Display Mode %m",formmenu);
X    addtopup(mainmenu,"Lighting Mode %m",lightmenu);
X    addtopup(mainmenu,"Extras %m %l",extramenu);
X    addtopup(mainmenu,"Exit %x5");
X    confirmmenu = newpup();
X    addtopup(confirmmenu,"Are You Sure? %t|Yes|No");
X}
X
Xdestroymenu()
X/* kills all the menus */
X{
X    freepup(mainmenu);
X    freepup(lightmenu);
X    freepup(formmenu);
X    freepup(confirmmenu);
X    freepup(omenu);
X    freepup(extramenu);
X}
X
X
Xpostmenu()
X/* Displays the menu and takes action. */
X{
X    long entry;
X    int i;
X    entry = dopup(mainmenu);
X    switch (entry) 
X    {
X	case 1:	setpup(mainmenu,1,PUP_GREY);
X    		prefposition(600,1000,500,900);
X    		win2 = winopen("Front View");
X    		winconstraints();
X		iconsize(85,66); keepaspect(1,1);
X		winconstraints();
X    		init();
X    		lookat(10.0,0.0,0.0,0.0,0.0,0.0,0.0);
X		break;
X	case 5:	if (dopup(confirmmenu) == 1) exit(0);
X		break;
X	case 11: wire = 1; break;
X	case 12: wire = 0; break;
X	case 21: flat = 1; break;
X	case 22: flat = 0; break;
X	case 31: back = 1 - back; break;
X	case 32: frames = 1 - frames; break;
X	case 33: speed = speed * 1.5; break;
X	case 34: speed = speed / 1.5; break;
X	case 41:
X	case 42:
X	case 43:
X	case 44:
X	case 45:
X	case 46:
X	case 47:
X	case 48:
X	case 49:
X	case 50:
X	case 51:
X	case 52:
X	case 53:
X	case 54:
X	case 55:
X	case 56:
X	case 57:
X	case 58:
X	case 59:
X	case 60: ob[entry-41] = 1 - ob[entry-41]; break;
X	case 71: for (i=0; i<MAXOBJ; i++) ob[i] = 1; break;
X	case 72: for (i=0; i<MAXOBJ; i++) ob[i] = 0; break;
X    };
X    destroymenu();
X    createmenu();
X}
X
Xmain()
X{
X    Device dev;
X    short val;
X    struct timeval tp;
X    struct timezone tzp;
X    long passed,lastsec,lasttime;
X    int count;
X    int i;
X    /* start up the stuff */
X    makeobjects();
X    prefposition(100,500,500,900);
X    win1 = winopen("Objects");
X    winconstraints(); iconsize(85,66); keepaspect(1,1); winconstraints();
X    init();
X    lookat(0.0,0.0,10.0,0.0,0.0,0.0,0.0);
X    win2 = 0;
X    for (i=0; i<MAXOBJ; i++) ob[i] = 0;
X    ob[0] = ob[1] = ob[2] = 1;
X    frames = 1; back = 1; wire = 0; flat = 0; incr = 1; time= 0.0;
X    speed = 5.0;
X    createmenu();
X    /* ready to go */
X    gettimeofday(&tp,&tzp);
X    lastsec = tp.tv_sec;
X    lasttime = tp.tv_usec;
X    while (1)
X    {
X	/* draw the stuff */
X	gettimeofday(&tp,&tzp);
X        if (incr)
X  	{
X	    passed = 1000000 * (tp.tv_sec - lastsec) + (tp.tv_usec - lasttime);
X	    time = time + speed * passed/250000.0;
X	};
X        if (lastsec != tp.tv_sec) {lcount = count; count = 0;};
X        count++;
X        lastsec = tp.tv_sec;
X        lasttime = tp.tv_usec;
X	winset(win1); redraw();
X	if (win2) {winset(win2); redraw();}
X	/* listen at the devices */
X	if (qtest())
X	{
X	    dev = qread(&val);
X	    if (dev == MOUSE1 && val )
X            {
X		postmenu();
X		gettimeofday(&tp,&tzp);
X        	lastsec = tp.tv_sec;
X        	lasttime = tp.tv_usec;
X            }
X	    else if (dev == ESCKEY) { exit(0); }
X	    else if (dev == REDRAW)
X	        { winset(val); reshapeviewport();}
X	    else if (dev == REDRAWICONIC)
X	        { winset(val); reshapeviewport();}
X	    else if (dev == WINTHAW)
X	        { winset(val); reshapeviewport();}
X	    else if (dev == MOUSE3 && val){ incr = 1 - incr;}
X        }
X    }
X}
END_OF_FILE
if test 10214 -ne `wc -c <'moving.c'`; then
    echo shar: \"'moving.c'\" unpacked with wrong size!
fi
# end of 'moving.c'
fi
if test -f 'object.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'object.c'\"
else
echo shar: Extracting \"'object.c'\" \(7718 characters\)
sed "s/^X//" >'object.c' <<'END_OF_FILE'
X#include <gl/gl.h>
X#include <math.h>
X#include <stdio.h>
X#include "object.h"
X/*
X   This library contains a number of basic objects plus a routine to
X   draw them. All objects have their center at point (0,0,0) and are
X   maximal in a box of size 2*2*2 around the origin. The currently
X   supported objects are:
X
X   cube           	: a simple cube, origin is the center.
X   sphere         	: a nice looking sphere, origin is the center.
X   cylinder       	: a cylinder.
X   cone                 : a cone
X   glass		: a nice glass
X   pyramid              : guess what
X
X
X
X   The following routines exist for use:
X
X   makeobjects()
X		should be called once before using the objects.
X
X   drawobject(obj,wire,flat)
X		to draw object obj. wire indicate whether wire frame
X		drawing is required. flat indicate whether flat shading
X		should be used.
X
X*/
X
X/*************************
X Making Spin Objects
X*************************/
X
X#define PI    3.14159265
X#define ZERO  0.00001
X
Xmakespinobject(obj,smooth,rot,n,x1,z1,nx1,nz1,x2,z2,nx2,nz2)
X/* makes a spin object */
XOBJECT *obj;         /* the object to be created */
Xint smooth;          /* whether smooth or not */
Xint rot;             /* the number of rotation steps */
Xint n;               /* the number of segments to spin */
Xfloat x1[],z1[];     /* (x,z) coordinates of first endpoint of segments */
Xfloat nx1[],nz1[];   /* their normals */
Xfloat x2[],z2[];     /* (x,z) coordinates of second endpoint of segments */
Xfloat nx2[],nz2[];   /* their normals */
X{
X    float th,dth,a1,a2;
X    PATCH *p;
X    int i,j;
X    obj->numb = rot*n;
X    p = obj->pat = (PATCH *) malloc(obj->numb * sizeof(PATCH));
X    dth = 2.0*PI/rot;
X    for (i=0; i<n; i++)
X    {
X        for (j=0; j<rot; j++)
X        {
X 	    th =  dth * j;   
X	    if (smooth) {a1 = th; a2 =th+dth;} else { a1 = a2 = th +dth/2.0;};
X	    if (x1[i] < ZERO || x2[i] <ZERO) {p->numb=3;} else {p->numb = 4;};
X	    p->v[0].x = x1[i]*sin(th);     p->n[0].x = nx1[i]*sin(a1);
X	    p->v[0].y = x1[i]*cos(th);     p->n[0].y = nx1[i]*cos(a1);
X	    p->v[0].z = z1[i];             p->n[0].z = nz1[i];
X	    p->v[1].x = x1[i]*sin(th+dth); p->n[1].x = nx1[i]*sin(a2);
X	    p->v[1].y = x1[i]*cos(th+dth); p->n[1].y = nx1[i]*cos(a2);
X	    p->v[1].z = z1[i];             p->n[1].z = nz1[i];
X	    p->v[2].x = x2[i]*sin(th+dth); p->n[2].x = nx2[i]*sin(a2);
X	    p->v[2].y = x2[i]*cos(th+dth); p->n[2].y = nx2[i]*cos(a2);
X	    p->v[2].z = z2[i];             p->n[2].z = nz2[i];
X	    p->v[3].x = x2[i]*sin(th);     p->n[3].x = nx2[i]*sin(a1);
X	    p->v[3].y = x2[i]*cos(th);     p->n[3].y = nx2[i]*cos(a1);
X	    p->v[3].z = z2[i];             p->n[3].z = nz2[i];
X	    if (x1[i] <ZERO) 
X	    {
X		p->v[1] = p->v[2]; p->n[1] = p->n[2];
X		p->v[2] = p->v[3]; p->n[2] = p->n[3];
X	    };
X	    p++;
X	}
X    }
X}
X
Xmakesmoothspinobject(obj,rot,n,x,z)
X/* makes a smooth, connected spin object */
XOBJECT *obj;         /* the object to be created */
Xint rot;             /* the number of rotation steps */
Xint n;               /* the number of points */
Xfloat x[],z[];       /* (x,z) coordinates of endpoints of segments */
X{
X    float x1[20],z1[20],nx1[20],nz1[20],x2[20],z2[20],nx2[20],nz2[20],l[20];
X    int i;
X    /* fill in the points */
X    x1[0] = x[0]; z1[0] = z[0];
X    for (i=1; i<n ; i++)
X    	{ x1[i] = x2[i-1] = x[i]; z1[i] = z2[i-1] = z[i]; };
X    /* fill in the normals */
X    for (i=0; i<n-1 ; i++)
X      {l[i] = sqrt((x[i+1]-x[i])*(x[i+1]-x[i]) + (z[i+1]-z[i])*(z[i+1]-z[i]));};
X    nx1[0]   = 0.0; nz1[0]   =  1.0;
X    nx2[n-2] = 0.0; nz2[n-2] = -1.0;
X    for (i=1; i<n-1 ; i++)
X    {
X	nx1[i] = nx2[i-1] = ((z[i-1]-z[i])/l[i-1] + (z[i] - z[i+1])/l[i] )/2.0;
X	nz1[i] = nz2[i-1] = ((x[i]-x[i-1])/l[i-1] + (x[i+1] - x[i])/l[i] )/2.0;
X    }
X    /* make it */
X    makespinobject(obj,1,rot,n-1,x1,z1,nx1,nz1,x2,z2,nx2,nz2);
X}
X
X/*Making some nice objects */
X
Xfloat x1[20],z1[20],nx1[20],nz1[20],x2[20],z2[20],nx2[20],nz2[20];
X
Xmakesphere(sphere,n)
XOBJECT *sphere;
Xint n;
X{
X    int i;
X    x1[0] = nx1[0] = 0.0; z1[0] = nz1[0] = 1.0;
X    for (i=0; i<n-1; i++)
X    {
X	x2[i] = nx2[i] = x1[i+1] = nx1[i+1] = sin((PI/n)*(1.0+i));
X	z2[i] = nz2[i] = z1[i+1] = nz1[i+1] = cos((PI/n)*(1.0+i));
X    }
X    x2[n-1] = nx2[n-1] = 0.0; z2[n-1] = nz2[n-1] = -1.0;
X    makespinobject(sphere,1,2*n,n,x1,z1,nx1,nz1,x2,z2,nx2,nz2);
X}
X
Xmakecylinder(cylinder,n)
XOBJECT *cylinder;
Xint n;
X{
X    x1[0] =  0.0; nx1[0] = 0.0; z1[0] =  1.0; nz1[0] =  1.0;
X    x2[0] =  1.0; nx2[0] = 0.0; z2[0] =  1.0; nz2[0] =  1.0;
X    x1[1] =  1.0; nx1[1] = 1.0; z1[1] =  1.0; nz1[1] =  0.0;
X    x2[1] =  1.0; nx2[1] = 1.0; z2[1] = -1.0; nz2[1] =  0.0;
X    x1[2] =  1.0; nx1[2] = 0.0; z1[2] = -1.0; nz1[2] = -1.0;
X    x2[2] =  0.0; nx2[2] = 0.0; z2[2] = -1.0; nz2[2] = -1.0;
X    makespinobject(cylinder,1,2*n,3,x1,z1,nx1,nz1,x2,z2,nx2,nz2);
X}
X
Xmakecone(cone,n)
XOBJECT *cone;
Xint n;
X{
X    x1[0] =  0.0; nx1[0] = 2.0/sqrt(5.0); z1[0] =  1.0; nz1[0] = 1.0/sqrt(5.0);
X    x2[0] =  1.0; nx2[0] = 2.0/sqrt(5.0); z2[0] = -1.0; nz2[0] = 1.0/sqrt(5.0);
X    x1[1] =  1.0; nx1[1] = 0.0;           z1[1] = -1.0; nz1[1] = -1.0;
X    x2[1] =  0.0; nx2[1] = 0.0;           z2[1] = -1.0; nz2[1] = -1.0;
X    makespinobject(cone,1,2*n,2,x1,z1,nx1,nz1,x2,z2,nx2,nz2);
X}
X
Xmakecube(cube)
XOBJECT *cube;
X{
X    x1[0] =  0.0;       nx1[0] = 0.0; z1[0] =  1.0; nz1[0] =  1.0;
X    x2[0] =  sqrt(2.0); nx2[0] = 0.0; z2[0] =  1.0; nz2[0] =  1.0;
X    x1[1] =  sqrt(2.0); nx1[1] = 1.0; z1[1] =  1.0; nz1[1] =  0.0;
X    x2[1] =  sqrt(2.0); nx2[1] = 1.0; z2[1] = -1.0; nz2[1] =  0.0;
X    x1[2] =  sqrt(2.0); nx1[2] = 0.0; z1[2] = -1.0; nz1[2] = -1.0;
X    x2[2] =  0.0;       nx2[2] = 0.0; z2[2] = -1.0; nz2[2] = -1.0;
X    makespinobject(cube,0,4,3,x1,z1,nx1,nz1,x2,z2,nx2,nz2);
X}
X
Xmakepyramid(pyramid)
XOBJECT *pyramid;
X{
X    x1[0] = 0.0;      nx1[0] = 2.0/sqrt(5.0);z1[0] =  1.0;nz1[0] =1.0/sqrt(5.0);
X    x2[0] = sqrt(2.0);nx2[0] = 2.0/sqrt(5.0);z2[0] = -1.0;nz2[0] =1.0/sqrt(5.0);
X    x1[1] = sqrt(2.0);nx1[1] = 0.0;          z1[1] = -1.0;nz1[1] = -1.0;
X    x2[1] = 0.0;      nx2[1] = 0.0;          z2[1] = -1.0;nz2[1] = -1.0;
X    makespinobject(pyramid,0,4,2,x1,z1,nx1,nz1,x2,z2,nx2,nz2);
X}
X
X
Xmakeglass(glass,n)
XOBJECT *glass;
Xint n;
X{
X    x1[ 0] = 0.000; z1[ 0] = 0.575;
X    x1[ 1] = 0.050; z1[ 1] = 0.575;
X    x1[ 2] = 0.100; z1[ 2] = 0.600;
X    x1[ 3] = 0.200; z1[ 3] = 0.700;
X    x1[ 4] = 0.250; z1[ 4] = 0.800;
X    x1[ 5] = 0.250; z1[ 5] = 1.000;
X    x1[ 6] = 0.275; z1[ 6] = 1.000;
X    x1[ 7] = 0.275; z1[ 7] = 0.800;
X    x1[ 8] = 0.250; z1[ 8] = 0.700;
X    x1[ 9] = 0.200; z1[ 9] = 0.625;
X    x1[10] = 0.100; z1[10] = 0.550;
X    x1[11] = 0.050; z1[11] = 0.500;
X    x1[12] = 0.025; z1[12] = 0.450;
X    x1[13] = 0.025; z1[13] = 0.100;
X    x1[14] = 0.050; z1[14] = 0.050;
X    x1[15] = 0.250; z1[15] = 0.025;
X    x1[16] = 0.250; z1[16] = 0.000;
X    x1[17] = 0.225; z1[17] = 0.000;
X    x1[18] = 0.000; z1[18] = 0.000;
X    makesmoothspinobject(glass,n,19,x1,z1);
X}
X
X/*************************************************************
X
X  WHAT THE USER SEES
X
X*************************************************************/
X
X
Xmakeobjects()
X/* Creates all the objects. */
X{
X    makecube(&cube);
X    makesphere(&sphere,12);
X    makecylinder(&cylinder,12);
X    makecone(&cone,12);
X    makeglass(&glass,18);
X    makepyramid(&pyramid);
X}
X    
Xdrawobject(obj,wire,flat)
X/* Draws a defined object. wire indicates whether wireframe. 
X   flat indicates whether flat shaded. */
XOBJECT obj;
Xint wire,flat;
X{
X    int i,j;
X    PATCH *p;
X    p = obj.pat;
X    if (flat) {shademodel(FLAT);} else {shademodel(GOURAUD);};
X    for (i=0; i < obj.numb ; i++)
X    {
X	if (wire) {bgnclosedline();} else {bgnpolygon();};
X	for (j=0; j < p->numb; j++)
X	    { n3f(&p->n[j]); v3f(&p->v[j]);};
X	if (wire) {endclosedline();} else {endpolygon();};
X	p++;
X    }
X}
X
END_OF_FILE
if test 7718 -ne `wc -c <'object.c'`; then
    echo shar: \"'object.c'\" unpacked with wrong size!
fi
# end of 'object.c'
fi
if test -f 'object.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'object.h'\"
else
echo shar: Extracting \"'object.h'\" \(327 characters\)
sed "s/^X//" >'object.h' <<'END_OF_FILE'
Xtypedef struct {
X   Coord x,y,z;
X} POINT;
X
Xtypedef struct {
X    int numb;   /* number of vertices */
X    POINT v[4]; /* vertices */
X    POINT n[4]; /* normals */
X} PATCH;
X
Xtypedef struct {
X    int numb;     /* number of patches */
X    PATCH *pat;   /* the patches */
X} OBJECT;
X
X
XOBJECT sphere,cube,cylinder,cone,glass,pyramid;
END_OF_FILE
if test 327 -ne `wc -c <'object.h'`; then
    echo shar: \"'object.h'\" unpacked with wrong size!
fi
# end of 'object.h'
fi
echo shar: End of shell archive.
exit 0