#! /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 '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 tFLOAT X%token 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 Filename X%type AnimExpr MExpr ParenExpr X%type Expr Float X%type Vector X%type Vec2d X%type Color Intensity Lightdef X%type Texturetype X%type SurfCompName IExpr CombineOp X%type EffectType X%type LightType X%type PrimType Primitive TransTextObj X%type Csg Aggregate Object TransObj ObjType X%type Blob Box Cone Cylinder Disc HeightField Plane Poly X%type Sphere Triangle Torus AggregateType List Grid AggregateCreate X%type NamedObject X%type Surface OptSurface NamedSurf X%type SurfSpec ModifyNamedSurf X%type Mapping MapMethod OptMapping X%type TransformType X%type 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 spot from 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 X#include 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