#! /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 archive 18 (of 19)."
# Contents:  libshade/yacc.y rayview/glmethods.c
# Wrapped by cek@oyoy on Sun Feb  9 21:56:52 1992
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'libshade/yacc.y' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'libshade/yacc.y'\"
else
echo shar: Extracting \"'libshade/yacc.y'\" \(29846 characters\)
sed "s/^X//" >'libshade/yacc.y' <<'END_OF_FILE'
X/* yacc.y								   */
X/*									   */
X/* Copyright (C) 1989, 1991, Craig E. Kolb				   */
X/* All rights reserved.							   */
X/*									   */
X/* This software may be freely copied, modified, and redistributed,	   */
X/* provided that this copyright notice is preserved on all copies.	   */
X/*									   */
X/* You may not distribute this software, in whole or in part, as part of   */
X/* any commercial product without the express consent of the authors.	   */
X/* 									   */
X/* There is no warranty or other guarantee of fitness of this software	   */
X/* for any purpose.  It is provided solely "as is".			   */
X/* $Id: yacc.y,v 4.0.1.4 92/01/10 16:29:55 cek Exp Locker: cek $ */
X%{
X#include "rayshade.h"
X
X#include "symtab.h"
X#include "builtin.h"
X
X#include "libsurf/atmosphere.h"
X#include "libsurf/surface.h"
X#include "libtext/texture.h"
X#include "libimage/image.h"
X#include "libobj/geom.h"
X#include "liblight/light.h"
X#include "options.h"
X#include "stats.h"
X#include "viewing.h"
X
X#include "libobj/blob.h"
X#include "libobj/box.h"
X#include "libobj/cone.h"
X#include "libobj/csg.h"
X#include "libobj/cylinder.h"
X#include "libobj/disc.h"
X#include "libobj/grid.h"
X#include "libobj/hf.h"
X#include "libobj/instance.h"
X#include "libobj/list.h"
X#include "libobj/plane.h"
X#include "libobj/poly.h"
X#include "libobj/sphere.h"
X#include "libobj/torus.h"
X#include "libobj/triangle.h"
X
X#include "liblight/point.h"
X#include "liblight/infinite.h"
X#include "liblight/spot.h"
X#include "liblight/jittered.h"
X#include "liblight/extended.h"
X
X#include "libtext/blotch.h"
X#include "libtext/bump.h"
X#include "libtext/checker.h"
X#include "libtext/cloud.h"
X#include "libtext/fbm.h"
X#include "libtext/fbmbump.h"
X#include "libtext/gloss.h"
X#include "libtext/imagetext.h"
X#include "libtext/marble.h"
X#include "libtext/mount.h"
X#include "libtext/sky.h"
X#include "libtext/stripe.h"
X#include "libtext/windy.h"
X#include "libtext/wood.h"
X
X#include "libsurf/fog.h"
X#include "libsurf/fogdeck.h"
X#include "libsurf/mist.h"
X
X#include "libcommon/rotate.h"
X#include "libcommon/scale.h"
X#include "libcommon/translate.h"
X#include "libcommon/xform.h"
X
XGeom *NewAggregate();
Xchar yyfilename[BUFSIZ];			/* Input filename */
XGeomList *Defstack;				/* Geom definition stack. */
Xint Npoints = 0;				/* # of points in Polypoints */
XSurface *tmpsurf;				/* Working surface */
XSurfList *CurSurf;
XTexture *CurText;				/* Working list of textures */
XImageText *Imagetext;				/* Working image texture */
XTrans *TransHead, *TransTail;			/* Linked list of current transformations */
XAtmosphere *CurEffect = (Atmosphere *)NULL;	/* Current atmos. effects */ 
XPointList *Polypoints;				/* List of vertices */
XMetaList *Metapoints, *Metapoint;
Xextern FILE *yyin;				/* input file pointer */
Xextern int yylineno;				/* Current line # in file */
Xextern Atmosphere *AtmosEffects;		/* atmospheric effects */
Xextern Medium TopMedium;			/* "air" */
Xextern void	GeomAddToDefined(),
X		LightAddToDefined(),
X		SurfaceAddToDefined();
Xextern Surface	*SurfaceGetNamed();
Xextern Geom 	*GeomGetNamed();
X%}
X%union {
X	char *c;
X	int i;
X	Float d;
X	Vector v;
X	Vec2d uv;
X	Color col;
X	Atmosphere *atmos;
X	Light *light;
X	Surface *surf;
X	Geom *obj;
X	Texture *text;
X	Mapping *map;
X	Trans *trans;
X	Expr *e;
X	SymtabEntry *sym;
X}
X%token <d> tFLOAT
X%token <c> tSTRING tFILENAME
X%token tAPERTURE tAPPLYSURF
X%token tBACKGROUND tBLOB tBLOTCH tBOX tBUMP tCONE tCYL tDIRECTIONAL tCURSURF
X%token tEXTENDED tEYEP tFBM tFBMBUMP tFOCALDIST tFOG tFOGDECK tFOV tGLOSS tGRID
X%token tHEIGHTFIELD tLIGHT tLIST tLOOKP tMARBLE tMAXDEPTH tMIST
X%token tJITTER tNOJITTER tDEFINE
X%token tOBJECT tOUTFILE  tSKY tDISC tDIFFERENCE tUNION tINTERSECT
X%token tPLANE tPOINT tPOLY tROTATE tSPOT tPRINT
X%token tSCALE tSCREEN tSPHERE tSURFACE
X%token tTHRESH tTRANSLATE tTRANSFORM tTRIANGLE tTRIANGLEUV tUP tEND
X%token tTEXTURE tCHECKER tWOOD tCONTRAST tCUTOFF tCLOUD
X%token tAMBIENT tDIFFUSE tREFLECT tTRANSP tSPECULAR tSPECPOW
X%token tINDEX tATMOSPHERE tNOSHADOW tAREA tTRANSLU tTORUS
X%token tEYESEP tSHADOWTRANSP tREPORT tVERBOSE tQUIET tWINDOW tCROP tSTRIPE
X%token tMAP tUV tSPHERICAL tCYLINDRICAL tPLANAR
X%token tIMAGE tSMOOTH tCOMPONENT tTEXTSURF tRANGE tTILE tSTARTTIME tFRAMELENGTH
X%token tNAME tFILTER tGAUSS tBODY tSAMPLE tEXTINCT tWINDY tMOUNT
X%token tSHUTTER tFRAMES
X%type <c> Filename
X%type <e> AnimExpr MExpr ParenExpr
X%type <d> Expr Float
X%type <v> Vector
X%type <uv> Vec2d
X%type <col> Color Intensity Lightdef
X%type <text> Texturetype
X%type <i> SurfCompName IExpr CombineOp
X%type <atmos> EffectType
X%type <light> LightType
X%type <obj> PrimType Primitive TransTextObj
X%type <obj> Csg Aggregate Object TransObj ObjType
X%type <obj> Blob Box Cone Cylinder Disc HeightField Plane Poly
X%type <obj> Sphere Triangle Torus AggregateType List Grid AggregateCreate
X%type <obj> NamedObject
X%type <surf> Surface OptSurface NamedSurf
X%type <surf> SurfSpec ModifyNamedSurf
X%type <map> Mapping MapMethod OptMapping
X%type <trans> TransformType
X%type <sym> Symtabent
X
X%left '+' '-'
X%left '*' '/' '%'
X%left UMINUS
X%right '^'
X%%
XItems		: /* empty */
X		| Items Item
X		;
XItem		: Eyep
X		| Lookp
X		| Up
X		| Fov
X		| Screen
X		| Window
X		| Crop
X		| Report
X		| Aperture
X		| Focaldist
X		| Eyesep
X		| Maxdepth
X		| Sample
X		| Filter
X		| Contrast
X		| Cutoff
X		| Background
X		| Shadowtransp
X		| Light
X		| SurfDef
X		| CurSurf
X		| Outfile
X		| Instance
X		| NameObject
X		| GlobalEffects
X		| Define
X		| Frames
X		| Starttime
X		| Shutter
X		| Framelength
X    		| Print
X		;
XInstance	: TransTextObj
X		{
X			if ($1) {
X				/*
X				 * Add instance to current object.
X				 */
X				$1->next = Defstack->obj->next;
X				Defstack->obj->next = $1;
X			}
X		}
XTransTextObj	: TransObj Textures
X		{
X			if ($$ && CurText) {
X				$$->texture = TextAppend(CurText, $$->texture);
X			}
X			CurText = (Texture *)NULL;
X		}
X		;	
XTransObj	: Object Transforms
X		{
X			$$ = $1;
X			if ($$ != (Geom *)NULL) {
X				if (TransHead) {
X					$$->trans = TransHead;
X					$$->transtail = TransTail;
X					/*
X					 * We compose non-animated tranformation lists,
X					 * so we're only animated if it's one long,
X					 * or it's animated itself.
X					 */
X					if ($$->trans->assoc || $$->trans->next)
X						/* geometry is animated...*/
X						$$->animtrans = TRUE;
X				}
X			}
X		}
X		;
XObject		: ObjType
X		{
X			if ($$)
X				StatsAddRep($$);
X		}
X		| NamedObject
X		;
XObjType		: Primitive
X		| Aggregate
X		;
XPrimitive	: PrimType
X		{
X			if ($$)
X				$$->prims = 1;	/* one primitive */
X		}
X		;
XPrimType	: Plane
X		| Sphere
X		| Box
X		| Triangle
X		| Cylinder
X		| Cone
X		| Poly
X		| HeightField
X		| Disc
X		| Torus
X		| Blob
X		;
XNameObject	: tNAME tSTRING TransTextObj
X		{
X			if ($3) {
X				$3->name = $2;
X				GeomAddToDefined($3);
X			}
X		};
XAggdefs		: Aggdefs Aggdef
X		|
X		;
XAggdef		: Instance
X		| SurfDef
X		| CurSurf
X		| NameObject
X		;
XTextures	: Textures Texture
X		|
X		;
XTexture		: tTEXTURE Texturetype Transforms
X		{
X			if ($2 != (Texture *)NULL) {
X				/*
X				 * Set transformation information.
X				 */
X				if (TransHead) {
X					$2->trans = TransHead;
X					/*
X					 * We compose non-animated tranformation lists,
X					 * so we're only animated if it's one long,
X					 * or it's animated itself.
X					 */
X					if ($2->trans->assoc || $2->trans->next)
X						/* texture transformation is animated...*/
X						$2->animtrans = TRUE;
X				}
X				/*
X				 * Walk to the end of list of textures and
X				 * append new texture.  This is done so that
X				 * textures are applied in the expected order.
X				 */
X				CurText = TextAppend($2, CurText);
X			}
X		}
X		;
XTexturetype	: tCHECKER Surface
X		{
X			$$ = TextCheckerCreate($2);
X		}
X		| tBLOTCH Expr Surface
X		{
X			$$ = TextBlotchCreate($2, $3);
X		}
X		| tBUMP Expr
X		{
X			$$ = TextBumpCreate($2);
X		}
X		| tMARBLE
X		{
X			$$ = TextMarbleCreate((char *)NULL);
X		}
X		| tMARBLE Filename
X		{
X			$$ = TextMarbleCreate($2);
X		}
X		| tFBM Expr Expr Expr Expr IExpr Expr
X		{
X			$$ = TextFBmCreate($2, $3, $4, $5, $6, $7,
X						(char *)NULL);
X		}
X		| tFBM Expr Expr Expr Expr IExpr Expr Filename
X		{
X			$$ = TextFBmCreate($2, $3, $4, $5, $6, $7, $8);
X		}
X		| tFBMBUMP Expr Expr Expr Expr IExpr 
X		{
X			$$ = TextFBmBumpCreate($2, $3, $4, $5, $6);
X		}
X		| tWOOD
X		{
X			$$ = TextWoodCreate();
X		}
X		| tGLOSS Expr 
X		{
X			$$ = TextGlossCreate($2);
X		}
X		| tCLOUD Expr Expr Expr IExpr Expr Expr Expr
X		{
X			$$ = TextCloudCreate($2, $3, $4, $5, $6, $7, $8);
X		}
X		| tSKY Expr Expr Expr IExpr Expr Expr
X		{
X			$$ = TextSkyCreate($2, $3, $4, $5, $6, $7);
X		}
X		| ImageText
X		{
X			/*
X			 * Image texturing has so many options
X			 * that specification is keyword-based.
X			 */
X			if (Imagetext->image == (Image *)NULL)
X				$$ = (Texture *)NULL;
X			else
X				$$ = TextCreate(Imagetext, ImageTextApply);
X			Imagetext = (ImageText *)NULL;
X		}
X		| tSTRIPE Surface Expr Expr OptMapping
X		{
X			$$ = TextStripeCreate($2, $3, $4, $5);
X		}
X		| tWINDY Expr Expr Expr Expr IExpr Expr Expr Expr
X		{
X			$$ = TextWindyCreate($2, $3, $4, $5, $6, $7, $8, $9);
X		}
X		| tMOUNT Filename Expr Expr
X		{
X			$$ = TextMountCreate($2, $3, $4);
X		}
X		;
XImageText	: ImageTextType ImageTextOptions
X		;
XImageTextType	: tIMAGE Filename
X		{
X			Imagetext = ImageTextCreate($2);
X		}
X		;
XImageTextOptions: ImageTextOptions ImageTextOption
X		| /* EMPTY */
X		;
XImageTextOption: tCOMPONENT SurfCompName
X		{
X			/* set texture to modify given component */	
X			ImageTextSetComponent(Imagetext, $2);
X		}
X		| tTILE Expr Expr
X		{
X			Imagetext->tileu = $2;
X			Imagetext->tilev = $3;
X		}
X		| tTEXTSURF Surface
X		{
X			Imagetext->surf = $2;
X		}
X		| tRANGE Expr Expr
X		{
X			Imagetext->hi = $2;
X			Imagetext->lo = $3;
X		}
X		| tSMOOTH
X		{
X			Imagetext->smooth = TRUE;
X		}
X		| Mapping
X		{
X			Imagetext->mapping = $1;
X		};
XNamedObject	: tOBJECT Surface tSTRING
X		{
X			Geom *otmp;
X			/*
X			 * Create an instance of the named object.
X			 */
X			otmp = GeomGetNamed($3);
X			if (otmp == (Geom *)NULL)
X				RLerror(RL_PANIC,
X				  "There is no object named \"%s\".", $3);
X			$$ = GeomInstanceCreate(otmp);
X			$$->surf = $2;
X			$$->prims = otmp->prims;
X		}
X		| tOBJECT tSTRING
X		{
X			Geom *otmp;
X
X			otmp = GeomGetNamed($2);
X			if (otmp == (Geom *)NULL)
X				RLerror(RL_PANIC,
X				  "There is no object named \"%s\".", $2);
X			$$ = GeomInstanceCreate(otmp);
X			$$->surf = CurSurf->surf;
X			$$->prims = otmp->prims;
X		};
XTransforms	: Transforms PostTransform
X		| /* empty */
X		{
X			TransHead = TransTail = (Trans *)NULL;
X		};
XPostTransform	: TransformType
X		{
X			if (TransHead == (Trans *)NULL) {
X				/* we're the list, head and tail */
X				TransHead = TransTail = $1;
X			} else {
X				if ($1->animated || TransTail->animated) {
X					/* new tail */
X					$1->prev = TransTail;
X					TransTail->next = $1;
X					TransTail = $1;
X				} else {
X					/* collapse with tail */
X					TransCompose(TransTail, $1, TransTail);
X					TransFree($1);
X				}
X			}
X		}
X		;
XTransformType	: tSCALE AnimExpr AnimExpr AnimExpr
X		{
X			$$ = TransScaleCreate();
X			TransScaleSetX($$, $2);
X			TransScaleSetY($$, $3);
X			TransScaleSetZ($$, $4);
X			if (!$$->animated)
X				TransPropagate($$);
X				
X		}
X		| tTRANSLATE AnimExpr AnimExpr AnimExpr
X		{
X			$$ = TransTranslateCreate();
X			TransTranslateSetX($$, $2);
X			TransTranslateSetY($$, $3);
X			TransTranslateSetZ($$, $4);
X			if (!$$->animated)
X				TransPropagate($$);
X		}
X		| tROTATE AnimExpr AnimExpr AnimExpr AnimExpr
X		{
X			$$ = TransRotateCreate();
X			TransRotateSetX($$, $2);
X			TransRotateSetY($$, $3);
X			TransRotateSetZ($$, $4);
X			TransRotateSetTheta($$, $5);
X			if (!$$->animated)
X				TransPropagate($$);
X		}
X		| tTRANSFORM	AnimExpr AnimExpr AnimExpr
X				AnimExpr AnimExpr AnimExpr
X				AnimExpr AnimExpr AnimExpr
X		{
X			$$ = TransXformCreate();
X			TransXformSetX0($$, $2);
X			TransXformSetY0($$, $3);
X			TransXformSetZ0($$, $4);
X			TransXformSetX1($$, $5);
X			TransXformSetY1($$, $6);
X			TransXformSetZ1($$, $7);
X			TransXformSetX2($$, $8);
X			TransXformSetY2($$, $9);
X			TransXformSetZ2($$, $10);
X			if (!$$->animated)
X				TransPropagate($$);
X		}
X		| tTRANSFORM	AnimExpr AnimExpr AnimExpr
X				AnimExpr AnimExpr AnimExpr
X				AnimExpr AnimExpr AnimExpr
X				AnimExpr AnimExpr AnimExpr
X		{
X			$$ = TransXformCreate();
X			TransXformSetX0($$, $2);
X			TransXformSetY0($$, $3);
X			TransXformSetZ0($$, $4);
X			TransXformSetX1($$, $5);
X			TransXformSetY1($$, $6);
X			TransXformSetZ1($$, $7);
X			TransXformSetX2($$, $8);
X			TransXformSetY2($$, $9);
X			TransXformSetZ2($$, $10);
X			TransXformSetXt($$, $11);
X			TransXformSetYt($$, $12);
X			TransXformSetZt($$, $13);
X			if (!$$->animated)
X				TransPropagate($$);
X		};
XEyep		: tEYEP Vector Transforms
X		{
X			Camera.pos = $2;
X			/*
X			 * Eye can be transformed...
X			if (CurMatrix) {
X				PointTransform(&Camera.pos, CurMatrix);
X				free((voidstar)CurMatrix);
X				CurMatrix = (Matrix*)NULL;
X			}
X			 */
X		}
X		;
XLookp		: tLOOKP Vector
X		{
X			Camera.lookp = $2;
X		}
X		;
XUp		: tUP Vector
X		{
X			Camera.up = $2;
X		}
X		;
XFov		: tFOV Expr Expr
X		{
X			Camera.hfov = $2;
X			Camera.vfov = $3;
X		}
X		| tFOV Expr
X		{
X			Camera.hfov = $2;
X			Camera.vfov = UNSET;
X		}
X		;
XSample		: tSAMPLE IExpr tJITTER
X		{
X			if (!Options.samples_set)
X				Options.samples = $2;
X			if (!Options.jitter_set)
X				Options.jitter = TRUE;
X		}
X		| tSAMPLE IExpr tNOJITTER
X		{
X			if (!Options.samples_set)
X				Options.samples = $2;
X			if (!Options.jitter_set)
X				Options.jitter = FALSE;
X		}
X		| tSAMPLE IExpr
X		{
X			if (!Options.samples_set)
X				Options.samples = $2;
X		}
X		;
XFilter		: tFILTER tBOX Expr
X		{
X			Options.gaussian = FALSE;
X			Options.filterwidth = $3;
X		}
X		| tFILTER tBOX
X		{
X			Options.gaussian = FALSE;
X		}	
X		| tFILTER tGAUSS Expr
X		{
X			Options.gaussian = TRUE;
X			Options.filterwidth = $3;
X		}
X		| tFILTER tGAUSS
X		{
X			Options.gaussian = TRUE;
X		};
XStarttime	: tSTARTTIME Expr
X		{
X			Options.starttime = $2;
X		};
XFrames		: tFRAMES IExpr
X		{
X			if (!Options.totalframes_set)
X				Options.totalframes = $2;
X		};
XFramelength	: tFRAMELENGTH Expr
X		{
X			Options.framelength = $2;
X		};
XShutter		: tSHUTTER Expr
X		{
X			Options.shutterspeed = $2;
X		};
XContrast	: tCONTRAST Expr Expr Expr
X		{
X			if (!Options.contrast_set) {
X				Options.contrast.r = $2;
X				Options.contrast.g = $3;
X				Options.contrast.b = $4;
X			}
X		}
X		;
XCutoff		: tCUTOFF Intensity
X		{
X			if (!Options.cutoff_set)
X				Options.cutoff = $2;
X		}
X		;
XScreen		: tSCREEN IExpr IExpr 
X		{
X			if (!Options.resolution_set) {
X				Screen.xres = $2;
X				Screen.yres = $3;
X			}
X		}
X		;
XWindow		: tWINDOW IExpr IExpr IExpr IExpr
X		{
X			if (!Options.window_set) {
X				Options.window[LOW][X] = $2;
X				Options.window[HIGH][X] = $3;
X				Options.window[LOW][Y] = $4;
X				Options.window[HIGH][Y] = $5;
X				/*
X				 * We must let ViewingSetup know
X				 * that a window has been defined.
X				 */
X				Options.window_set = TRUE;
X			}
X		}
X		;
XCrop		: tCROP Expr Expr Expr Expr
X		{
X			if (!Options.crop_set) {
X				Options.crop[LOW][X] = $2;
X				Options.crop[HIGH][X] = $3;
X				Options.crop[LOW][Y] = $4;
X				Options.crop[HIGH][Y] = $5;
X			}
X		}
X		;
XReport		: tREPORT Verbose Quiet IExpr Filename
X		{
X			if (!Options.freq_set)
X				Options.report_freq = $4;
X			if (Options.statsname == (char *)NULL)
X				Options.statsname = strsave($5);
X		}
X		| tREPORT Verbose Quiet IExpr
X		{
X			if (!Options.freq_set)
X				Options.report_freq = $4;
X		}
X		| tREPORT Verbose Quiet Filename
X		{
X			if (Options.statsname == (char *)NULL)
X				Options.statsname = strsave($4);
X		}
X		| tREPORT Verbose Quiet
X		;
XVerbose		: tVERBOSE
X		{ Options.verbose = TRUE; }
X		|
X		;
XQuiet		: tQUIET
X		{ Options.quiet = TRUE; }
X		|
X		;
XAperture	: tAPERTURE Expr
X		{
X			Camera.aperture = $2;
X		}
X		;
XFocaldist	: tFOCALDIST Expr
X		{
X			Camera.focaldist = $2;
X		}
X		;
XEyesep		: tEYESEP Expr
X		{
X			if (!Options.eyesep_set)
X				Options.eyesep = $2;
X		}
X		;
XMaxdepth	: tMAXDEPTH IExpr
X		{
X			if (!Options.maxdepth_set)
X				Options.maxdepth = $2;
X		}
X		;
XBackground	: tBACKGROUND Color
X		{
X			Screen.background = $2;
X		}
X		;
XShadowtransp	: tSHADOWTRANSP
X		{
X			Options.shadowtransp = !Options.shadowtransp;
X		}
X		;
XLight		: LightType
X		{
X			LightAddToDefined($1);
X		}
X		| LightType tNOSHADOW
X		{
X			$1->shadow = FALSE;
X			LightAddToDefined($1);
X		}
X		| tLIGHT Intensity tAMBIENT
X		{
X			Options.ambient = $2;
X		}
X		| Lightdef tAREA Vector Vector IExpr Vector IExpr
X		{
X			extern void AreaLightCreate();
X			/* Area light is strange in that the
X			 * Creation routine does the installation.
X			 */
X			AreaLightCreate(&$1, &$3, &$4, $5, &$6, $7, TRUE);
X		}
X		| Lightdef tAREA Vector Vector IExpr Vector IExpr tNOSHADOW
X		{
X			extern void AreaLightCreate();
X			/* Area light is strange in that the
X			 * Creation routine does the installation.
X			 */
X			AreaLightCreate(&$1, &$3, &$4, $5, &$6, $7, FALSE);
X		};
XLightType	: Lightdef tPOINT Vector
X		{
X			$$ = LightPointCreate(&$1, &$3);
X		}
X		| Lightdef tDIRECTIONAL Vector
X		{
X			$$ = LightInfiniteCreate(&$1, &$3);
X		}
X		| Lightdef tEXTENDED Expr Vector
X		{
X			$$ = LightExtendedCreate(&$1, $3, &$4);
X		}
X		| Lightdef tSPOT Vector Vector Expr
X		{
X			$$ = LightSpotCreate(&$1, &$3, &$4, $5, 0., 0.);
X		}
X		| Lightdef tSPOT Vector Vector Expr Expr Expr
X		{
X			/* light <intens> spot from <to> coef inner_rad
X					outer_rad */
X			$$ = LightSpotCreate(&$1, &$3, &$4, $5, $6, $7);
X		};
XLightdef	: tLIGHT Intensity
X		{
X			$$ = $2;
X		}
X		;
XCurSurf		: tAPPLYSURF Surface
X		{
X			CurSurf->surf = $2;
X		}
X		;
XOptSurface	: Surface
X		| /* EMPTY */
X		{
X			$$ = CurSurf->surf;
X		}
X		;
XSurface		: NamedSurf
X		| ModifyNamedSurf
X		| SurfSpec
X		;
XNamedSurf	: tSTRING
X		{
X			$$ = SurfaceGetNamed($1);
X			/*
X			 * Free up memory allocated for surf name.
X			 * We bother doing this because for large models
X			 * converted from 3.0, surfnames this can account
X			 * for lots o' bytes.
X			 */
X			free((voidstar)$1);
X		}
X		| tCURSURF
X		{
X			extern Surface DefaultSurface;
X
X			if (CurSurf->surf)
X				$$ = CurSurf->surf;
X			else
X				$$ = &DefaultSurface;
X		}
X		;
XModifyNamedSurf : CopyNamedSurf SurfComponent SurfComponents
X		{
X			$$ = tmpsurf;
X			tmpsurf = (Surface *)NULL;
X		}
X		| CopyCurSurf SurfComponent SurfComponents
X		{
X			$$ = tmpsurf;
X			tmpsurf = (Surface *)NULL;
X		}
X		;
XCopyNamedSurf	: tSTRING
X		{
X			tmpsurf = SurfaceCopy(SurfaceGetNamed($1));
X		}
X		;
XCopyCurSurf	: tCURSURF
X		{
X			extern Surface DefaultSurface;
X			if (CurSurf->surf)
X				tmpsurf = SurfaceCopy(CurSurf->surf);
X			else
X				tmpsurf = SurfaceCopy(&DefaultSurface);
X		}
X		;
XSurfSpec	: SurfComponent SurfComponents
X		{
X			$$ = tmpsurf;
X			tmpsurf = (Surface *)NULL;
X		} 
X		;
XSurfDef		: tSURFACE tSTRING Surface
X		{
X			tmpsurf = SurfaceCopy($3);
X			tmpsurf->name = strsave($2);
X			SurfaceAddToDefined(tmpsurf);
X			tmpsurf = (Surface *)NULL;
X		}
X		| tSURFACE tSTRING
X		{
X			/* black surface */
X			tmpsurf = SurfaceCreate();
X			tmpsurf->name = strsave($2);
X			SurfaceAddToDefined(tmpsurf);
X			tmpsurf = (Surface *)NULL;
X		}
X		;
XSurfComponents	: SurfComponents SurfComponent
X		| /* EMPTY */
X		;
XSurfComponent	: Ambient
X		| Diffuse
X		| Specular
X		| Specpow
X		| Body
X		| Reflect
X		| Transp
X		| Extinct
X		| Index
X		| Translu
X		| Noshadow
X		;
XAmbient		: tAMBIENT Color
X		{
X			if (tmpsurf == (Surface *)NULL)
X				tmpsurf = SurfaceCreate();
X			tmpsurf->amb = $2;
X		}
X		;
XDiffuse		: tDIFFUSE Color
X		{
X			if (tmpsurf == (Surface *)NULL)
X				tmpsurf = SurfaceCreate();
X			tmpsurf->diff = $2;
X		}
X		;
XSpecular	: tSPECULAR Color
X		{
X			if (tmpsurf == (Surface *)NULL)
X				tmpsurf = SurfaceCreate();
X			tmpsurf->spec = $2;
X		}
X		;
XBody		: tBODY Color
X		{
X			if (tmpsurf == (Surface *)NULL)
X				tmpsurf = SurfaceCreate();
X			tmpsurf->body = $2;
X		};
XExtinct		: tEXTINCT Expr
X		{
X			if (tmpsurf == (Surface *)NULL)
X				tmpsurf = SurfaceCreate();
X			tmpsurf->statten = $2;
X		};
XSpecpow		: tSPECPOW Expr
X		{
X			if (tmpsurf == (Surface *)NULL)
X				tmpsurf = SurfaceCreate();
X			tmpsurf->srexp = $2;
X		}
X		;
XReflect		: tREFLECT Expr
X		{
X			if (tmpsurf == (Surface *)NULL)
X				tmpsurf = SurfaceCreate();
X			tmpsurf->reflect = $2;
X		}
X		;
XTransp		: tTRANSP Expr
X		{
X			if (tmpsurf == (Surface *)NULL)
X				tmpsurf = SurfaceCreate();
X			tmpsurf->transp = $2;
X		}
X		;
XIndex		: tINDEX Expr
X		{
X			if (tmpsurf == (Surface *)NULL)
X				tmpsurf = SurfaceCreate();
X			tmpsurf->index = $2;
X		}
X		;
XTranslu		: tTRANSLU Expr Color Expr
X		{
X			if (tmpsurf == (Surface *)NULL)
X				tmpsurf = SurfaceCreate();
X			tmpsurf->translucency = $2;
X			tmpsurf->translu = $3;
X			tmpsurf->stexp = $4;
X		}
X		;
XNoshadow	: tNOSHADOW
X		{
X			if (tmpsurf == (Surface *)NULL)
X				tmpsurf = SurfaceCreate();
X			tmpsurf->noshadow = TRUE;
X		}
X		;
XHeightField	: tHEIGHTFIELD Surface Filename
X		{
X			$$ = GeomHfCreate($3);
X			if ($$)
X				$$->surf = $2;
X		}
X		| tHEIGHTFIELD Filename
X		{
X			$$ = GeomHfCreate($2);
X		}
X		;
XPoly		: tPOLY OptSurface Polypoints
X		{
X			$$ = GeomPolygonCreate(Polypoints, Npoints,
X				Options.flipnorm);
X			if ($$)
X				$$->surf = $2;
X			Polypoints = (PointList *)NULL;
X			Npoints = 0;
X		}
X		;
XPolypoints	: /* empty */
X		| Polypoints Polypoint
X		;
XPolypoint	: Vector
X		{
X			PointList *ptmp;
X
X			ptmp = (PointList *)Malloc(sizeof(PointList));
X			ptmp->vec = $1;
X			ptmp->next = Polypoints;
X			Polypoints = ptmp;
X			Npoints++;
X		}
X		;
XAggregate	: AggregateDef
X		{
X			if (Defstack->obj) {
X				/*
X				 * Set object texture to current texture.
X				 */
X				Defstack->obj->texture = CurText;
X			}
X			CurText = (Texture *)NULL;
X			/*
X			 * Pop topmost object on stack.
X			 */
X			$$ = Defstack->obj;
X			Defstack = GeomStackPop(Defstack);
X			/* Pop current surface */
X			CurSurf = SurfPop(CurSurf);
X			/* Make current default surf aggregate's default */
X			$$->surf = CurSurf->surf;
X		}
X		;
XAggregateDef	: AggregateCreate Aggdefs tEND
X		{
X			/* Convert aggregate, pop stacks, etc. */
X			if ($1) {
X				if (Defstack->obj->next == (Geom *)NULL) {
X					RLerror(RL_WARN,
X						"Null object defined.\n");
X					Defstack->obj = (Geom *)NULL;
X				} else {
X					/*
X					 * Convert the linked list of objects
X					 * associated with the topmost object
X					 * to the appropriate aggregate type.
X					 */
X					Defstack->obj->prims=AggregateConvert(
X						Defstack->obj,
X						Defstack->obj->next);
X					/*
X					 * Make sure conversion worked OK.
X					 */
X					if (Defstack->obj->prims <= 0)
X						Defstack->obj = (Geom *)NULL;
X				}
X			}
X		}
X		;
XAggregateCreate	: AggregateType
X		{
X			if ($1) {
X				Defstack = GeomStackPush($1, Defstack);
X				CurSurf = SurfPush((Surface *)NULL, CurSurf);
X			}
X		};
XAggregateType	: List
X		| Grid
X		| Csg
X		;
XList		: tLIST
X		{
X			$$ = GeomListCreate();
X		}
X		;
XGrid		: tGRID IExpr IExpr IExpr
X		{
X			$$ = GeomGridCreate($2, $3, $4);
X		}
X		;
XCsg		: CombineOp
X		{
X			$$ = GeomCsgCreate($1);
X			Options.csg = TRUE;
X		}
X		;
XCombineOp	: tUNION
X		{
X		    $$ = CSG_UNION;
X		}
X		| tINTERSECT
X		{
X		    $$ = CSG_INTERSECT;
X		}
X		| tDIFFERENCE
X		{
X		    $$ = CSG_DIFFERENCE;
X		}
X    		;
XCone		: tCONE OptSurface Expr Vector Expr Vector
X		{
X			if (equal($3, $5)) {
X				/* It's really a cylinder */
X				$$ = GeomCylinderCreate($3, &$4, &$6);
X			} else
X				$$ = GeomConeCreate($3, &$4, $5, &$6);
X			if ($$)
X				$$->surf = $2;
X		}
X		;
XCylinder	: tCYL OptSurface Expr Vector Vector
X		{
X			$$ = GeomCylinderCreate($3, &$4, &$5);
X			if ($$)
X				$$->surf = $2;
X		}
X		;
XSphere		: tSPHERE OptSurface Expr Vector
X		{
X			$$ = GeomSphereCreate($3, &($4));
X			if ($$)
X				$$->surf = $2;
X		}
X		;
XDisc		: tDISC OptSurface Expr Vector Vector
X		{
X			$$ = GeomDiscCreate($3, &($4), &($5));
X			if ($$)
X				$$->surf = $2;
X		}
X		;
XBox		: tBOX OptSurface Vector Vector
X		{
X			$$ = GeomBoxCreate(&$3, &$4);
X			if ($$)
X				$$->surf = $2;
X		}
X		;
XTriangle	: tTRIANGLE OptSurface Vector Vector Vector
X		{
X			$$ = GeomTriangleCreate(FLATTRI, &($3), &($4), &($5),
X				(Vector *)NULL, (Vector *)NULL, (Vector *)NULL,
X				(Vec2d *)NULL, (Vec2d *)NULL, (Vec2d *)NULL,
X				Options.flipnorm);
X			if ($$)
X				$$->surf = $2;
X		}
X		| tTRIANGLE OptSurface  Vector Vector
X					Vector Vector
X					Vector Vector
X		{
X			$$ = GeomTriangleCreate(PHONGTRI, &($3), &($5),
X				&($7), &($4), &($6), &($8),
X				(Vec2d *)NULL, (Vec2d *)NULL, (Vec2d *)NULL,
X				Options.flipnorm);
X			if ($$)
X				$$->surf = $2;
X		}
X		| tTRIANGLEUV OptSurface Vector Vector Vec2d
X					 Vector Vector Vec2d
X					 Vector Vector Vec2d
X		{
X			$$ = GeomTriangleCreate(PHONGTRI, &($3), &($6), &($9),
X						&($4), &($7), &($10),
X						&($5), &($8), &($11),
X						Options.flipnorm);
X			if ($$)
X				$$->surf = $2;
X		}
X		;
XPlane		: tPLANE OptSurface Vector Vector
X		{
X			$$ = GeomPlaneCreate(&($3), &($4));
X			if ($$)
X				$$->surf = $2;
X		}
X		;
XTorus		: tTORUS OptSurface Expr Expr Vector Vector
X		{
X			$$ = GeomTorusCreate($3, $4, &($5), &($6));
X			if ($$)
X				$$->surf = $2;
X		}
X		;
XBlob		: tBLOB OptSurface Expr MetaPoints
X		{
X			$$ = GeomBlobCreate($3, Metapoints, Npoints);
X			if ($$)
X				$$->surf = $2;
X			Metapoints = (MetaList *)NULL;
X			Npoints = 0;
X		}
X		;
XMetaPoints	: /* empty */
X		| MetaPoints MetaPoint
X		;
XMetaPoint	: Expr Expr Expr Expr Expr
X		{
X			Metapoint = (MetaList *)Malloc(sizeof(MetaList));
X			Metapoint->mvec.c0 = $1;
X			Metapoint->mvec.rs = $2;
X			Metapoint->mvec.x = $3;
X			Metapoint->mvec.y = $4;
X			Metapoint->mvec.z = $5;
X			Metapoint->next = Metapoints;
X			Metapoints = Metapoint;
X			Npoints++;
X		}
X		;
XOutfile		: tOUTFILE Filename
X		{
X			if (Options.imgname != (char *)NULL)
X				/* Already set on command line. */
X				RLerror(RL_WARN,
X					"Ignoring output file name \"%s\".\n",
X					$2);
X			else
X				Options.imgname = strsave($2);
X		}
X		;
XGlobalEffects	: tATMOSPHERE Effects
X		{
X			AtmosEffects = CurEffect;
X			CurEffect = (Atmosphere *)NULL;
X		}
X		| tATMOSPHERE IExpr Effects
X		{
X			if ($2 <= 0.)
X				RLerror(RL_PANIC,
X				"Index of refraction must be positive.\n");
X			TopMedium.index = $2;
X			AtmosEffects = CurEffect;
X			CurEffect = (Atmosphere *)NULL;
X		}
X		;
XEffects		: Effects Effect
X		|
X		;
XEffect		: EffectType
X		{
X			$1->next = CurEffect;
X			CurEffect = $1;
X		}
X		;
XEffectType	: tMIST Color Color Expr Expr
X		{
X			$$ = AtmosMistCreate(&($2), &($3), $4, $5);
X		}
X		| tFOG Color Color
X		{
X			$$ = AtmosFogCreate(&($2), &($3));
X		}
X		| tFOGDECK Expr Expr Vector Expr IExpr Color Color
X		{
X			$$ = AtmosFogdeckCreate($2, $3, &$4, $5, $6, &$7, &$8);
X		}
X		;
XColor		: Expr Expr Expr
X		{
X			$$.r = $1;
X			$$.g = $2;
X			$$.b = $3;
X		}
X		;
XVector		: Expr Expr Expr
X		{
X			$$.x = $1;
X			$$.y = $2;
X			$$.z = $3;
X		}
X		;
XVec2d		: Expr Expr 
X		{
X			$$.u = $1;
X			$$.v = $2;
X		}
X		;
XOptMapping	: Mapping
X		| /* EMPTY */
X		{
X			$$ = UVMappingCreate();
X		}
X		;
XMapping		: tMAP MapMethod
X		{
X			$$ = $2;
X		}
X		;
XMapMethod	: tUV
X		{
X			$$ = UVMappingCreate();
X		}
X		| tSPHERICAL
X		{
X			$$ = SphereMappingCreate((Vector *)NULL,
X				(Vector *)NULL, (Vector *)NULL);
X		}
X		| tSPHERICAL Vector Vector Vector
X		{
X			/* origin up uaxis */
X			$$ = SphereMappingCreate(&$2, &$3, &$4);
X		}
X		| tCYLINDRICAL
X		{
X			$$ = CylMappingCreate((Vector *)NULL,
X				(Vector *)NULL, (Vector *)NULL);
X		}
X		| tCYLINDRICAL Vector Vector Vector
X		{
X			/* origin up uaxis */
X			$$ = CylMappingCreate(&$2, &$3, &$4);
X		}
X		| tPLANAR
X		{
X			$$ = LinearMappingCreate((Vector *)NULL,
X				(Vector *)NULL, (Vector *)NULL);
X		}
X		| tPLANAR Vector Vector Vector
X		{
X			/* origin up uaxis */
X			$$ = LinearMappingCreate(&$2, &$3, &$4);
X		}
X		;
XSurfCompName	: tAMBIENT
X		{
X			$$ = AMBIENT;
X		}
X		| tDIFFUSE
X		{
X			$$ = DIFFUSE;
X		}
X		| tBODY
X		{
X			$$ = BODY;
X		}
X		| tSPECULAR
X		{
X			$$ = SPECULAR;
X		}
X		| tREFLECT
X		{
X			$$ = REFLECT;
X		}
X		| tTRANSP
X		{
X			$$ = TRANSP;
X		}
X		| tSPECPOW
X		{
X			$$ = SPECPOW;
X		}
X		| tBUMP
X		{
X			$$ = BUMP;
X		}
X		| tINDEX
X		{
X			$$ = INDEX;
X		}
X		;
XIntensity	: Expr
X		{ $$.r = $$.g = $$.b = $1; }
X		| Color
X		;
XPrint		: tPRINT Expr
X		{
X			fprintf(stderr,"%f\n",$2);
X		}
XDefine		: tDEFINE tSTRING AnimExpr
X		{
X			SymtabAddEntry($2, $3->type, $3, NULL, $3->timevary, 0);
X		};
XIExpr		: Expr
X		{ $$ = (int)$1; }
X		;
XExpr		: Float
X		| ParenExpr
X		{
X			if (!$1->timevary) {
X				$$ = ExprEval($1);
X			} else {
X				RLerror(RL_PANIC, "Illegal expression use.\n");
X			}
X		}
X		;
XAnimExpr	: Float
X		{
X			$$ = ExprReuseFloatCreate($1);
X		}
X		| ParenExpr
X		;
XParenExpr	: '(' MExpr ')'
X		{
X			$$ = $2;
X		};
XMExpr		: tFLOAT
X		{
X			$$ = ExprFloatCreate($1, FALSE);
X		}
X		| tSTRING
X		{
X			$$ = ExprFloatSymtabFind($1);
X		}
X		| Symtabent '(' MExpr ')'
X		{
X			$$ = ExprResolve1($3, $1->value.fp, $1->timevary);
X		}
X		| Symtabent '(' MExpr ',' MExpr ')'
X		{
X			$$ = ExprResolve2($3, $5,
X					$1->value.fp,
X					$1->timevary);
X		}
X		| Symtabent '(' MExpr ',' MExpr ',' MExpr ')'
X		{
X			$$ = ExprResolve3($3, $5, $7, 
X					$1->value.fp,
X					$1->timevary);
X		}
X		| Symtabent '(' MExpr ',' MExpr ',' MExpr ',' MExpr ')'
X		{
X			$$ = ExprResolve4($3, $5, $7, $9, 
X					$1->value.fp,
X					$1->timevary);
X		}
X		| Symtabent
X			'(' MExpr ',' MExpr ',' MExpr ',' MExpr ',' MExpr ')'
X		{
X			$$ = ExprResolve5($3, $5, $7, $9, $11,
X					$1->value.fp,
X					$1->timevary);
X		}
X		| '(' MExpr ')'
X		{
X			$$ = $2;
X		}
X		| MExpr '+' MExpr
X		{
X			$$ = ExprResolve2($1, $3, SumExpr, FALSE);
X		}
X		| MExpr '-' MExpr
X		{
X			$$ = ExprResolve2($1, $3, DiffExpr, FALSE);
X		}
X		| MExpr '*' MExpr
X		{
X			$$ = ExprResolve2($1, $3, MultExpr, FALSE);
X		}
X		| MExpr '/' MExpr
X		{
X			$$ = ExprResolve2($1, $3, DivideExpr, FALSE);
X		}
X		| MExpr '%' MExpr
X		{
X			$$ = ExprResolve2($1, $3, ModExpr, FALSE);
X		}
X		| '-' MExpr %prec UMINUS
X		{
X			$$ = ExprResolve1($2, NegateExpr, FALSE);
X		}
X		| '+' MExpr %prec UMINUS
X		{
X			$$ = $2;
X		}
X		| MExpr '^' MExpr
X		{
X			$$ = ExprResolve2($1, $3, pow, FALSE);
X		} ;
XFloat		: tFLOAT
X		| '-' tFLOAT
X		{ $$ = -$2; }
X		| '+' tFLOAT
X		{ $$ = $2; };
XFilename	: tSTRING
X		| tFILENAME
X		;
XSymtabent	: tSTRING
X		{
X			$$ = SymtabBuiltinFind($1);
X		};
X%%
X/*
X * Issue error message containing filename and line number, and exit.
X */
X/*VARARGS1*/
Xyyerror(s, pat1, pat2)
Xchar *s, *pat1, *pat2;
X{
X	fprintf(stderr,"%s: Error: %s: line %d: ", Options.progname,
X			yyfilename, yylineno);
X	fprintf(stderr, s, pat1, pat2);
X	if (*s && s[strlen(s) -1] != '\n')
X		/* YACC doesn't put newlines on error messages. */
X		fprintf(stderr,"\n");	
X	fflush(stderr);
X	exit(1);
X}
X
XGeom *
XNewAggregate(obj)
XGeom *obj;
X{
X	obj->name = Defstack->obj->name;
X	obj->next = Defstack->obj->next;
X	return obj;
X}
END_OF_FILE
if test 29846 -ne `wc -c <'libshade/yacc.y'`; then
    echo shar: \"'libshade/yacc.y'\" unpacked with wrong size!
fi
# end of 'libshade/yacc.y'
fi
if test -f 'rayview/glmethods.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'rayview/glmethods.c'\"
else
echo shar: Extracting \"'rayview/glmethods.c'\" \(20651 characters\)
sed "s/^X//" >'rayview/glmethods.c' <<'END_OF_FILE'
X/*
X * glmethods.c
X *
X * Support routines for SGI/RS6000 machines.
X *
X * Copyright (C) 1989, 1991, Craig E. Kolb, Allan Snyder
X *
X * This software may be freely copied, modified, and redistributed
X * provided that this copyright notice is preserved on all copies.
X *
X * You may not distribute this software, in whole or in part, as part of
X * any commercial product without the express consent of the authors.
X * 
X * There is no warranty or other guarantee of fitness of this software
X * for any purpose.  It is provided solely "as is".
X *
X * $Id: glmethods.c,v 4.0.1.4 92/01/10 17:17:39 cek Exp Locker: cek $
X *
X * $Log:	glmethods.c,v $
X * Revision 4.0.1.4  92/01/10  17:17:39  cek
X * patch3: Added heightfield support.
X * 
X * Revision 4.0.1.3  91/12/13  11:43:11  cek
X * patch3: Spot direction and spread now set correctly.
X * patch3: Set GLC_OLDPOLYGON to 0 on sgi machines to fix VGX weirdness.
X * 
X * Revision 4.0.1.2  91/10/10  22:45:27  cek
X * patch1: Added spotlight support.
X * 
X * Revision 4.0.1.1  1991/09/29  15:28:36  cek
X * patch1: Added support for transparency.
X *
X * Revision 4.0  91/07/17  17:38:43  kolb
X * Initial version
X * 
X */
X#include <gl.h>
X#include <device.h>
X#include "rayshade.h" 
X#include "options.h"
X#include "viewing.h"
X
X#include "libsurf/surface.h"
X
X#include "libobj/box.h"
X#include "libobj/cone.h"
X#include "libobj/csg.h"
X#include "libobj/cylinder.h"
X#include "libobj/disc.h"
X#include "libobj/hf.h"
X#include "libobj/grid.h"
X#include "libobj/instance.h"
X#include "libobj/list.h"
X#include "libobj/plane.h"
X#include "libobj/poly.h"
X#include "libobj/sphere.h"
X#include "libobj/triangle.h"
X
X#include "liblight/light.h"
X#include "liblight/extended.h"
X#include "liblight/infinite.h"
X#include "liblight/point.h"
X#include "liblight/spot.h"
X
X#define CIRCLE_SAMPLES	20	/* # of samples around circle (cone/cyl/etc) */
X#define DEFAULT_NEAR	.2	/* default value for near clipping plane */
X#define DEFAULT_FAR	350.	/* default far clipping plane */
X#define PLANE_RAD	450.	/* radius of disc used to represent planes */
X
X#ifndef SPHERELIB
X#define SPHERE_LEVEL	3
X#endif
X
X/*
X * Pass a normal stored in a Vector to the geometry pipeline.
X */
X#define GLNormal(w)	(glnrm[0] = (w)->x, glnrm[1] = (w)->y, \
X			 glnrm[2] = (w)->z, n3f(glnrm))
X
Xstatic void	GLBoxDraw(), GLConeDraw(), GLCsgDraw(), GLCylinderDraw(),
X		GLDiscDraw(),
X		GLGridDraw(), GLHfDraw(), GLInstanceDraw(),	
X		GLListDraw(), GLPlaneDraw(), GLPolygonDraw(),
X		GLSphereDraw(), GLTorusDraw(), GLTriangleDraw(),
X		GLBoundsDraw(),
X		GLInfiniteLight(), GLPointLight(), GLSpotLight(),
X		GLExtendedLight();
X
Xstatic short	cursurf = 1,
X		curlight = 1;
X
Xstatic Object	GLBoxObject,
X		GLCylObject,
X		GLSphereObject,
X		GLBoxObjectDefine(),
X		GLCylObjectDefine();
X
Xextern Object	GLSphereObjectDefine();
X
Xstatic int	Doublebuffered;
X
Xstatic float	Ident[4][4] =	{1., 0., 0., 0.,
X				 0., 1., 0., 0.,
X				 0., 0., 1., 0.,
X				 0., 0., 0., 1.},
X		glnrm[3];
X
Xstatic float **CirclePoints;
X
Xstatic void LightDraw(), GeomDraw(), GLMultMatrix(),
X		GLPushSurface(), GLPopSurface(), LightDrawInit(),
X		ObjectInit(), GLDrawFrame(), ScreenDrawInit(), DrawInit(),
X		GLUnitCircle(), GLDisc(), ComputeClippingPlanes();
X
XFloat CurrentTime;
X
Xstatic unsigned long BackPack;	/* Packed background color */
Xstatic long Zinit;		/* maximum Zbuffer value */
X
XMethodsRegister()
X{
X	BoxMethodRegister(GLBoxDraw);
X	ConeMethodRegister(GLConeDraw);
X	CsgMethodRegister(GLCsgDraw);
X	CylinderMethodRegister(GLCylinderDraw);
X	DiscMethodRegister(GLDiscDraw);
X	GridMethodRegister(GLGridDraw);
X#ifdef sgi
X	HfMethodRegister(GLHfDraw);
X#endif
X	InstanceMethodRegister(GLInstanceDraw);
X	ListMethodRegister(GLListDraw);
X	PlaneMethodRegister(GLPlaneDraw);
X	PolygonMethodRegister(GLPolygonDraw);
X	SphereMethodRegister(GLSphereDraw);
X	/*TorusMethodRegister(GLTorusDraw);*/
X	TriangleMethodRegister(GLTriangleDraw);
X
X	InfiniteMethodRegister(GLInfiniteLight);
X	PointMethodRegister(GLPointLight);
X	ExtendedMethodRegister(GLExtendedLight);
X	SpotMethodRegister(GLSpotLight);
X}
X
Xvoid
XRender()
X{
X	short val;
X	float tmp;
X
X	/*
X	 * We're only sampling the scene once, so we need
X	 * not do lots of work to determine exactly what
X	 * animated transformations are doing...
X	 */
X	Options.samples = 1;
X	SamplingSetOptions(Options.samples, Options.gaussian,
X			   Options.filterwidth);
X
X	DrawInit();
X	qdevice(ESCKEY);
X	qdevice(SPACEKEY);
X	qdevice(REDRAW);
X
X	DrawFrames();
X
X	while (TRUE) {
X		switch (qread(&val)) {
X			case ESCKEY:
X				exit(0);
X				break;
X			case REDRAW:
X				reshapeviewport();
X				DrawFrames();
X				break;
X			case SPACEKEY:
X				if (!val)
X					DrawFrames();
X				break;
X		}
X	}
X}
X
XDrawFrames()
X{
X	int i;
X	for (i = 0; i < Options.totalframes; i++)
X		GLDrawFrame(i);
X}
X
Xstatic void
XDrawInit()
X{
X	extern Surface DefaultSurface;
X
X	ScreenDrawInit();
X	ObjectInit();
X	LightDrawInit();
X
X	/*
X	 * Push the default surface.
X	 */
X	GLPushSurface(&DefaultSurface);
X}
X
Xstatic void
XScreenDrawInit()
X{
X	/*
X	 * Open window, initialize graphics, etc.
X	 */
X#ifdef sgi
X	foreground();
X#endif
X	prefsize(Screen.xsize, Screen.ysize);
X	winopen("rayview");
X
X#ifdef sgi
X	glcompat(GLC_OLDPOLYGON, 0);
X#endif
X
X	RGBmode();
X	mmode(MVIEWING);
X
X	if (Options.totalframes > 1) {
X		Doublebuffered = TRUE;
X		doublebuffer();
X	}
X
X
X	gconfig();
X	blendfunction(BF_SA, BF_MSA);
X	zbuffer(TRUE);
X
X	/*
X	 * Initialize viewing matrix.
X	 */
X	GLViewingInit();
X
X	BackPack = (unsigned char)(255*Screen.background.r) |
X		((unsigned char)(255*Screen.background.g) << 8) |
X		((unsigned char)(255*Screen.background.b) << 16);
X	Zinit = getgdesc(GD_ZMAX);
X	lsetdepth(0, Zinit);
X}
X
X/*
X * Draw the World object.
X */
Xstatic void
XGLDrawFrame(frame)
Xint frame;
X{
X	extern Geom *World;
X
X	RSStartFrame(frame);
X	CurrentTime = Options.framestart;
X	TimeSet(CurrentTime);
X
X	czclear(BackPack, Zinit);	
X
X	/*
X	 * Draw the World object
X	 */
X	GeomDraw(World);
X	if (Doublebuffered)
X		swapbuffers();
X}
X
XGLViewingInit()
X{
X	float near, far, aspect, dist, T[4][4];
X	short ang;
X	extern Geom *World;
X
X	ang = Camera.vfov * 10 + 0.5;
X	aspect = Camera.hfov / Camera.vfov;
X
X	T[0][0]=Screen.scrni.x; T[0][1]=Screen.scrnj.x; T[0][2]= -Camera.dir.x;
X	T[1][0]=Screen.scrni.y; T[1][1]=Screen.scrnj.y; T[1][2]= -Camera.dir.y;
X	T[2][0]=Screen.scrni.z; T[2][1]=Screen.scrnj.z; T[2][2]= -Camera.dir.z;
X
X	T[0][3] = T[1][3] = T[2][3] = 0.;
X
X	T[3][0] = -dotp(&Camera.lookp, &Screen.scrni);
X	T[3][1] = -dotp(&Camera.lookp, &Screen.scrnj);
X	T[3][2] = dotp(&Camera.lookp, &Camera.dir);
X	T[3][3] = 1.;
X
X	ComputeClippingPlanes(&near, &far, World->bounds);
X
X	loadmatrix(Ident);
X	perspective(ang, aspect, near, far);
X	polarview((float)Camera.lookdist, 0, 0, 0);
X	multmatrix(T);
X}
X
X
Xstatic void
XObjectInit()
X{
X	CircleDefine();
X	GLBoxObject = GLBoxObjectDefine();
X
X#ifdef SPHERELIB
X	GLSphereObject = GLSphereObjectDefine();
X#else
X	GLSphereObject = GLSphereObjectDefine(SPHERE_LEVEL);
X#endif
X
X	GLCylObject = GLCylObjectDefine();
X}
X
Xstatic void
XGeomDraw(obj)
XGeom *obj;
X{
X	Trans *ct;
X	/*
X	 * If object has a surface associated with it,
X	 * start using it.
X	 */
X	if (obj->surf)
X		GLPushSurface(obj->surf);
X	if (obj->trans) {
X		/*
X		 * Take care of any animated transformations that
X		 * exist.
X		 */
X		if (obj->animtrans && !equal(obj->timenow, CurrentTime)) {
X			TransResolveAssoc(obj->trans);
X			obj->timenow = CurrentTime;
X		}
X		pushmatrix();
X		/*
X	 	 * Apply in reverse order.
X		 */
X		for (ct = obj->transtail; ct; ct = ct->prev)
X			GLMultMatrix(&ct->trans);
X	}
X
X	if (obj->methods->user) {
X		/*
X	 	 * Call proper method
X	 	 */
X		(*obj->methods->user)(obj->obj);
X	} else {
X		/*
X		 * Draw bounding box.
X		 */
X		GLBoundsDraw(obj->bounds);
X	}
X
X	if (obj->surf)
X		GLPopSurface();
X	if (obj->trans)
X		popmatrix();
X}
X
Xstatic float surfprops[] =	{AMBIENT, 0, 0, 0,
X				 DIFFUSE, 0, 0, 0,
X				 SPECULAR, 0, 0, 0,
X				 SHININESS, 0,
X				 ALPHA, 1,
X				 LMNULL};
Xstatic float	*amb = &surfprops[1],
X		*diff = &surfprops[5],
X		*spec = &surfprops[9],
X		*shine = &surfprops[13],
X		*alpha = &surfprops[15];
X
Xstatic void
XGLPushSurface(surf)
XSurface *surf;
X{
X	static Surface *lastsurf = NULL;
X
X	/*
X	 * Start using the given surface.
X	 * In the case of the use of an "applysurf",
X	 * the same surface will be applied to many
X	 * primitives individually.  By saving the
X	 * pointer to the last surface, we keep from
X	 * lmdef'ing the surface when we don't need to.
X	 */
X	if (surf != lastsurf) {
X		amb[0] = surf->amb.r; amb[1] = surf->amb.g;
X			amb[2] = surf->amb.b;
X		diff[0] = surf->diff.r; diff[1] = surf->diff.g;
X			diff[2] = surf->diff.b;
X		spec[0] = surf->spec.r; spec[1] = surf->spec.g;
X			spec[2] = surf->spec.b;
X		shine[0] = surf->srexp;
X		*alpha = 1. - surf->transp;
X		lmdef(DEFMATERIAL, cursurf, sizeof(surfprops)/sizeof(float),
X			surfprops);
X		lastsurf = surf;
X	}
X	lmbind(MATERIAL, cursurf);
X	cursurf++;
X}
X
Xstatic void
XGLMultMatrix(trans)
XRSMatrix *trans;
X{
X	float newmat[4][4];
X	/*
X	 * Multiply in the given transformation.
X	 */
X	newmat[0][0] = trans->matrix[0][0]; newmat[0][1] = trans->matrix[0][1];
X	newmat[0][2] = trans->matrix[0][2]; newmat[0][3] = 0.;
X	newmat[1][0] = trans->matrix[1][0]; newmat[1][1] = trans->matrix[1][1];
X	newmat[1][2] = trans->matrix[1][2]; newmat[1][3] = 0.;
X	newmat[2][0] = trans->matrix[2][0]; newmat[2][1] = trans->matrix[2][1];
X	newmat[2][2] = trans->matrix[2][2]; newmat[2][3] = 0.;
X	newmat[3][0] = trans->translate.x; newmat[3][1] = trans->translate.y;
X	newmat[3][2] = trans->translate.z ; newmat[3][3] = 1.;
X	multmatrix(newmat);
X}
X
Xstatic void
XGLPopSurface()
X{
X	cursurf--;
X	lmbind(MATERIAL, cursurf-1);
X}
X
Xstatic void
XGLBoundsDraw(bounds)
XFloat bounds[2][3];
X{
X	float sx, sy, sz;
X
X	pushmatrix();
X
X	translate(bounds[LOW][X], bounds[LOW][Y], bounds[LOW][Z]);
X	scale(	bounds[HIGH][X] - bounds[LOW][X],
X		bounds[HIGH][Y] - bounds[LOW][Y],
X		bounds[HIGH][Z] - bounds[LOW][Z]);
X	pushmatrix();
X	callobj(GLBoxObject);
X	popmatrix();
X	popmatrix();
X}
X
Xstatic void
XGLBoxDraw(box)
XBox *box;
X{
X	GLBoundsDraw(box->bounds);
X}
X
X
Xstatic void
XGLConeDraw(cone)
XCone *cone;
X{
X	int i, j;
X	float norm[3], normconst, ZeroVect[3], tmpv[3];
X
X	ZeroVect[0] = ZeroVect[1] = ZeroVect[2] = 0.;
X	/*
X	 * Sides.
X	 * For the normal, assume we are finding the normal at
X	 * (C_P[i].x, C_P[i].y, 1.) at this point, the unnormalized
X	 * normal = (C_P[i].x, C_P[i].y, -tantheta^2).  When we normalize,
X	 * then length of the vector is simply equal to:
X	 * sqrt(CP[i].x^2 + CP[i].y^2 + tantheta^4)  ==
X	 * sqrt(1. + tantheta^4)
X	 * In our case, tantheta = 1., so...
X	 */
X
X	normconst = 1. / sqrt(2.);
X	norm[2] = -normconst;
X
X	pushmatrix();
X	GLMultMatrix(&cone->trans.trans);
X
X	for (i = 0; i < CIRCLE_SAMPLES; i++) {
X		j = (i + 1) % CIRCLE_SAMPLES;
X		norm[0] = CirclePoints[i][0] * normconst;
X		norm[1] = CirclePoints[i][1] * normconst;
X		n3f(norm);
X		bgnpolygon();
X		if (cone->start_dist > EPSILON) {
X			tmpv[2] = cone->start_dist;
X			tmpv[0] = CirclePoints[i][0] * cone->start_dist;
X			tmpv[1] = CirclePoints[i][1] * cone->start_dist;
X			v3f(tmpv);
X			tmpv[0] = CirclePoints[j][0] * cone->start_dist;
X			tmpv[1] = CirclePoints[j][1] * cone->start_dist;
X			v3f(tmpv);
X		} else
X			v3f(ZeroVect);
X		tmpv[2] = 1.;
X		tmpv[0] = CirclePoints[j][0];
X		tmpv[1] = CirclePoints[j][1];
X		v3f(tmpv);
X		tmpv[0] = CirclePoints[i][0];
X		tmpv[1] = CirclePoints[i][1];
X		v3f(tmpv);
X		endpolygon();
X	}
X	popmatrix();
X}
X
Xstatic void
XGLCsgDraw(csg)
XCsg *csg;
X{
X	/*
X	 * Punt by drawing both objects.
X	 */
X	GeomDraw(csg->obj1);
X	GeomDraw(csg->obj2);
X}
X
Xstatic void
XGLCylinderDraw(cyl)
XCylinder *cyl;
X{
X	pushmatrix();
X	GLMultMatrix(&cyl->trans.trans);
X	callobj(GLCylObject);
X	popmatrix();
X}
X
Xstatic void
XGLDiscDraw(disc)
XDisc *disc;
X{
X	GLDisc((Float)sqrt(disc->radius), &disc->pos, &disc->norm);
X}
X
Xstatic void
XGLDisc(rad, pos, norm)
XFloat rad;
XVector *pos, *norm;
X{
X	RSMatrix m, tmp;
X	Vector atmp;
X
X	/*
X	 * This is kinda disgusting...
X	 */
X	ScaleMatrix(rad, rad, 1., &m);
X	if (fabs(norm->z) == 1.) {
X		atmp.x = 1.;
X		atmp.y = atmp.z = 0.;
X	} else {
X		atmp.x = norm->y;
X		atmp.y = -norm->x;
X		atmp.z= 0.;
X	}
X
X	RotationMatrix(atmp.x, atmp.y, atmp.z, -acos(norm->z), &tmp);
X	MatrixMult(&m, &tmp, &m);
X	TranslationMatrix(pos->x, pos->y, pos->z, &tmp);
X	MatrixMult(&m, &tmp, &m);
X	pushmatrix();
X	GLMultMatrix(&m);
X	/*
X	 * Draw unit circle.
X	 */
X	GLUnitCircle(0., TRUE);
X	popmatrix();
X}
X
Xstatic void
XGLGridDraw(grid)
XGrid *grid;
X{
X	Geom *ltmp;
X
X	for (ltmp = grid->unbounded; ltmp; ltmp = ltmp->next)
X		GeomDraw(ltmp);
X	for (ltmp = grid->objects; ltmp; ltmp = ltmp->next)
X		GeomDraw(ltmp);
X}
X
Xstatic void
XGLHfDraw(hf)
XHf *hf;
X{
X	int x, y;
X	float n[3], v[3], del, del2, del4, dz1, delz, za, zb, zc;
X	float bot, top, left, right, len;
X
X	del = 1. / (hf->size - 1);
X	del2 = del*del;
X	del4 = del2*del2;
X
X	bot = 0.;
X	top = del;
X
X	for (y = 0; y < hf->size -1; y++) {
X		za = hf->data[y+1][0];
X		zb = hf->data[y][0];
X		left = 0;
X		right = del;
X		for (x = 1; x < hf->size; x++) {
X			/*
X			 * A +-+ C
X			 *   |/
X			 * B +
X			 */
X		
X			zc = hf->data[y+1][x];
X			dz1 = za - zb;
X			delz = za - zc;
X			len = sqrt(del2*delz*delz + del2*dz1*dz1 + del4);
X			bgnpolygon();
X			n[0] = del*delz/len;
X			n[1] = -del*dz1/len;
X			n[2] = del2/len;
X			n3f(n);
X			v[0] = left; v[1] = top; v[2] = za; v3f(v);
X			v[1] = bot; v[2] = zb; v3f(v);
X			v[0] = right; v[1] = top; v[2] = zc; v3f(v);
X			endpolygon();
X
X			/*
X			 *   B +
X			 *    /|
X			 * A +-+ C
X			 */
X			za = zb; zb = zc; zc = hf->data[y][x];
X			dz1 = zc - za;
X			delz = zc - zb;
X			len = sqrt(del2*dz1*dz1 + del2*delz*delz + del4);
X			n[0] = -del*dz1/len;
X			n[1] = del*delz/len;
X			n[2] = del2/len;
X			bgnpolygon();
X			n3f(n);
X			v[0] = left; v[1] = bot; v[2] = za; v3f(v);
X			v[0] = right; v[2] = zc; v3f(v);
X			v[1] = top; v[2] = zb; v3f(v);
X			endpolygon();
X			left = right;
X			right += del;
X			za = zb;
X			zb = zc;
X		}
X		bot = top;
X		top += del;
X	}
X	
X}
X
Xstatic void
XGLInstanceDraw(inst)
XInstance *inst;
X{
X	GeomDraw(inst->obj);
X}
X
Xstatic void
XGLListDraw(list)
XList *list;
X{
X	Geom *ltmp;
X
X	for (ltmp = list->unbounded; ltmp; ltmp = ltmp->next)
X		GeomDraw(ltmp);
X	for (ltmp = list->list; ltmp; ltmp = ltmp->next)
X		GeomDraw(ltmp);
X}
X
Xstatic void
XGLPlaneDraw(plane)
XPlane *plane;
X{
X	/*
X	 * Draw a really big disc.
X	 */
X	GLDisc((Float)PLANE_RAD, &plane->pos, &plane->norm);
X}
X
Xstatic void
XGLPolygonDraw(poly)
Xregister Polygon *poly;
X{
X	register int i;
X
X	GLNormal(&poly->norm);
X
X	bgnpolygon();
X	for (i = 0; i < poly->npoints; i++)
X		v3d(&poly->points[i]);
X	endpolygon();
X}
X
Xstatic void
XGLSphereDraw(sph)
XSphere *sph;
X{
X	pushmatrix();
X	translate(sph->x, sph->y, sph->z);
X	scale(sph->r, sph->r, sph->r);
X	callobj(GLSphereObject);
X	popmatrix();
X}
X
Xstatic void
XGLTorusDraw(){}
X
Xstatic void
XGLTriangleDraw(tri)
Xregister Triangle *tri;
X{
X	/*
X	 * If Float is a double, use v3d,
X	 * otherwise use v3f.
X	 */
X	if (tri->type != PHONGTRI) {
X		GLNormal(&tri->nrm);	
X		bgnpolygon();
X		v3d(&tri->p[0]); v3d(&tri->p[1]); v3d(&tri->p[2]);
X		endpolygon();
X	} else {
X		bgnpolygon();
X		GLNormal(&tri->vnorm[0]);
X		v3d(&tri->p[0]);
X		GLNormal(&tri->vnorm[1]);
X		v3d(&tri->p[1]);
X		GLNormal(&tri->vnorm[2]);
X		v3d(&tri->p[2]);
X		endpolygon();
X	}
X}
X
Xfloat lightprops[] =	{POSITION, 0., 0., 0., 0.,
X			 LCOLOR, 0, 0, 0,
X			 SPOTDIRECTION, 0., 0., 0.,
X			 SPOTLIGHT, 0., 180.,
X			 LMNULL};
X
Xfloat 	*lpos = &lightprops[1],
X	*lcolor = &lightprops[6],
X	*spotdir = &lightprops[10],
X	*spotexp = &lightprops[14],
X	*spotspread = &lightprops[15];
X
Xfloat lmodel[] =	{AMBIENT, 1., 1., 1.,
X			 ATTENUATION, 1., 0.,
X			 LOCALVIEWER, 0.,
X#ifdef sgi
X			 ATTENUATION2, 0.,
X			 TWOSIDE, 1.,
X#endif
X			 LMNULL};
X
Xstatic void
XLightDrawInit()
X{
X	Light *light;
X	extern Light *Lights;
X
X	for (light = Lights; light; light = light->next)
X		LightDraw(light);
X
X	switch (curlight-1) {
X		case 8:
X			lmbind(LIGHT7, 8);
X		case 7:
X			lmbind(LIGHT6, 7);
X		case 6:
X			lmbind(LIGHT5, 6);
X		case 5:
X			lmbind(LIGHT4, 5);
X		case 4:
X			lmbind(LIGHT3, 4);
X		case 3:
X			lmbind(LIGHT2, 3);
X		case 2:
X			lmbind(LIGHT1, 2);
X		case 1:
X			lmbind(LIGHT0, 1);
X	}
X
X	lmodel[1] = Options.ambient.r;
X	lmodel[2] = Options.ambient.g;
X	lmodel[3] = Options.ambient.b;
X
X	lmdef(DEFLMODEL, 1, sizeof(lmodel) / sizeof(float), lmodel);
X	lmbind(LMODEL, 1);
X}
X
Xstatic void
XLightDraw(light)
XLight *light;
X{
X	if (!light || !light->methods->user)
X		return;
X	lcolor[0] = light->color.r;
X	lcolor[1] = light->color.g;
X	lcolor[2] = light->color.b;
X	(*light->methods->user)(light->light);
X}
X
Xstatic void
XGLExtendedLight(ext)
XExtended *ext;
X{
X	lpos[0] = ext->pos.x;
X	lpos[1] = ext->pos.y;
X	lpos[2] = ext->pos.z;
X	lpos[3] = 1.;
X	lmdef(DEFLIGHT, curlight++, sizeof(lightprops)/sizeof(float),
X		lightprops);
X}
X
X
Xstatic void
XGLInfiniteLight(inf)
XInfinite *inf;
X{
X	lpos[0] = inf->dir.x;
X	lpos[1] = inf->dir.y;
X	lpos[2] = inf->dir.z;
X	lpos[3] = 0.;
X	lmdef(DEFLIGHT, curlight++, sizeof(lightprops)/sizeof(float),
X		lightprops);
X}
X
Xstatic void
XGLPointLight(pt)
XPointlight *pt;
X{
X	lpos[0] = pt->pos.x;
X	lpos[1] = pt->pos.y;
X	lpos[2] = pt->pos.z;
X	lpos[3] = 1.;
X	lmdef(DEFLIGHT, curlight++, sizeof(lightprops) / sizeof(float),
X			lightprops);
X}
X
Xstatic void
XGLSpotLight(spot)
XSpotlight *spot;
X{
X	lpos[0] = spot->pos.x;
X	lpos[1] = spot->pos.y;
X	lpos[2] = spot->pos.z;
X	lpos[3] = 1.;
X	spotdir[0] = spot->dir.x;
X	spotdir[1] = spot->dir.y;
X	spotdir[2] = spot->dir.z;
X	*spotexp = spot->coef;
X	*spotspread = 180 * acos(spot->falloff) / PI;
X	lmdef(DEFLIGHT, curlight++, sizeof(lightprops) / sizeof(float),
X			lightprops);
X	/* fix up spot defs so other source methods needn't reset them. */
X	*spotspread = 180.;
X	*spotexp = 1.;
X}
X
Xstatic float boxfaces[6][4][3] = {
X{ 	{1., 1., 1.},
X	{0., 1., 1.},
X	{0., 0., 1.},
X	{1., 0., 1.}	},
X{	{1., 0., 1.},
X	{0., 0., 1.},
X	{0., 0., 0.},
X	{1., 0., 0.}	},
X{	{1., 0., 0.},
X	{0., 0., 0.},
X	{0., 1., 0.},
X	{1., 1., 0.}	},
X{	{0., 1., 0.},
X	{0., 1., 1.},
X	{1., 1., 1.},
X	{1., 1., 0.}	},
X{	{1., 1., 1.},
X	{1., 0., 1.},
X	{1., 0., 0.},
X	{1., 1., 0.}	},
X{	{0., 0., 1.},
X	{0., 1., 1.},
X	{0., 1., 0.},
X	{0., 0., 0.}}};
X
Xfloat boxnorms[6][3] = {
X	{0, 0, 1},
X	{0, -1, 0},
X	{0, 0, -1},
X	{0, 1, 0},
X	{1, 0, 0,},
X	{-1, 0, 0}};
X
X/*
X * Define a unit cube centered at (0.5, 0.5, 0.5)
X */
Xstatic Object
XGLBoxObjectDefine()
X{
X	int i, box;
X
X	makeobj(box = genobj());
X	for (i = 0; i < 6; i++)	{
X		n3f(boxnorms[i]);
X		polf(4, boxfaces[i]);
X	}
X	closeobj();
X	return box;
X}
X
Xstatic void
XGLUnitCircle(z, up)
Xfloat z;
Xint up;
X{
X	int i;
X	float norm[3];
X
X	norm[0] = norm[1] = 0.;
X	bgnpolygon();
X
X	if (up) {
X		norm[2] = 1.;
X		n3f(norm);	
X		for (i = 0; i < CIRCLE_SAMPLES; i++) {
X			CirclePoints[i][2] = z;
X			v3f(CirclePoints[i]);
X		}
X	} else {
X		norm[2] = -1.;
X		n3f(norm);	
X		for (i = CIRCLE_SAMPLES -1; i; i--) {
X			CirclePoints[i][2] = z;
X			v3f(CirclePoints[i]);
X		}
X	}
X
X	endpolygon();
X}
X
Xstatic Object
XGLCylObjectDefine()
X{
X	int i, j, cyl;
X	float norm[3];
X
X	makeobj(cyl = genobj());
X	norm[2] = 0;
X	for (i = 0; i < CIRCLE_SAMPLES; i++) {
X		j = (i+1)%CIRCLE_SAMPLES;
X		norm[0] = CirclePoints[i][0];
X		norm[1] = CirclePoints[i][1];
X#ifdef sgi
X		n3f(norm);
X		bgnpolygon();
X		CirclePoints[i][2] = 0;
X		v3f(CirclePoints[i]);
X		CirclePoints[j][2] = 0;
X		v3f(CirclePoints[j]);
X		CirclePoints[j][2] = 1;
X		v3f(CirclePoints[j]);
X		CirclePoints[i][2] = 1;
X		v3f(CirclePoints[i]);
X		endpolygon();
X#else
X		n3f(norm);
X		pmv(CirclePoints[i][0], CirclePoints[i][1], 0.);
X		pdr(CirclePoints[j][0], CirclePoints[j][1], 0.);
X		pdr(CirclePoints[j][0], CirclePoints[j][1], 1.);
X		pdr(CirclePoints[i][0], CirclePoints[i][1], 1.);
X		pclos();
X#endif
X	}
X	closeobj();
X	return cyl;
X}
X
X/*
X * Fill CirclePoints[t] with X and Y values cooresponding to points
X * along the unit circle.  The size of CirclePoints is equal to
X * CIRCLE_SAMPLES.
X */
XCircleDefine()
X{
X	int i;
X	double theta, dtheta;
X
X	dtheta = 2.*M_PI / (double)CIRCLE_SAMPLES;
X	CirclePoints = (float **)malloc(CIRCLE_SAMPLES * sizeof(float *));
X	for (i = 0, theta = 0; i < CIRCLE_SAMPLES; i++, theta += dtheta) {
X		CirclePoints[i] = (float *)malloc(3 * sizeof(float));
X		CirclePoints[i][0] = cos(theta);
X		CirclePoints[i][1] = sin(theta);
X		/* Z is left unset. */	
X	}
X}
X
X/*
X * Given world bounds, determine near and far
X * clipping planes.  Only problem occurs when there are
X * unbbounded objects (planes)...
X */
Xstatic void
XComputeClippingPlanes(near, far, bounds)
Xfloat *near, *far;
XFloat bounds[2][3];
X{
X	Vector e, c;
X	double rad, d;
X
X
X	/*
X	 * Compute 'radius' of scene.
X	 */
X	rad = max(max((bounds[HIGH][X] - bounds[LOW][X])*0.5,
X		      (bounds[HIGH][Y] - bounds[LOW][Y])*0.5),
X		      (bounds[HIGH][Z] - bounds[LOW][Z])*0.5);
X
X	c.x = (bounds[LOW][X] + bounds[HIGH][X])*0.5;
X	c.y = (bounds[LOW][Y] + bounds[HIGH][Y])*0.5;
X	c.z = (bounds[LOW][Z] + bounds[HIGH][Z])*0.5;
X
X	/*
X	 * Compute position of eye relative to the center of the sphere.
X	 */
X	VecSub(Camera.pos, c, &e);
X	d = VecNormalize(&e);
X	if (d <= rad)
X		/*
X		 * Eye is inside sphere.
X		 */
X		*near = DEFAULT_NEAR;
X	else
X		*near = (d - rad)*0.2;
X	*far = (d + rad)*2.;
X}
END_OF_FILE
if test 20651 -ne `wc -c <'rayview/glmethods.c'`; then
    echo shar: \"'rayview/glmethods.c'\" unpacked with wrong size!
fi
# end of 'rayview/glmethods.c'
fi
echo shar: End of archive 18 \(of 19\).
cp /dev/null ark18isdone
MISSING=""
for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked all 19 archives.
    rm -f ark[1-9]isdone ark[1-9][0-9]isdone
else
    echo You still need to unpack the following archives:
    echo "        " ${MISSING}
fi
##  End of shell archive.
exit 0
