1 /* yacc.y */
2 /* */
3 /* Copyright (C) 1989, 1991, Craig E. Kolb */
4 /* All rights reserved. */
5 /* */
6 /* This software may be freely copied, modified, and redistributed, */
7 /* provided that this copyright notice is preserved on all copies. */
8 /* */
9 /* You may not distribute this software, in whole or in part, as part of */
10 /* any commercial product without the express consent of the authors. */
11 /* */
12 /* There is no warranty or other guarantee of fitness of this software */
13 /* for any purpose. It is provided solely "as is". */
14 /* $Id: yacc.y,v 4.0.1.4 92/01/10 16:29:55 cek Exp Locker: cek $ */
15 %{
16 #include <stdlib.h>
17 #include <string.h>
18 #include "rayshade.h"
19
20 #include "symtab.h"
21 #include "builtin.h"
22
23 #include "libsurf/atmosphere.h"
24 #include "libsurf/surface.h"
25 #include "libtext/texture.h"
26 #include "libimage/image.h"
27 #include "libobj/geom.h"
28 #include "liblight/light.h"
29 #include "options.h"
30 #include "stats.h"
31 #include "viewing.h"
32
33 #include "libobj/blob.h"
34 #include "libobj/box.h"
35 #include "libobj/cone.h"
36 #include "libobj/csg.h"
37 #include "libobj/cylinder.h"
38 #include "libobj/disc.h"
39 #include "libobj/grid.h"
40 #include "libobj/hf.h"
41 #include "libobj/instance.h"
42 #include "libobj/list.h"
43 #include "libobj/plane.h"
44 #include "libobj/poly.h"
45 #include "libobj/sphere.h"
46 #include "libobj/torus.h"
47 #include "libobj/triangle.h"
48
49 #include "liblight/point.h"
50 #include "liblight/infinite.h"
51 #include "liblight/spot.h"
52 #include "liblight/jittered.h"
53 #include "liblight/extended.h"
54
55 #include "libtext/blotch.h"
56 #include "libtext/bump.h"
57 #include "libtext/checker.h"
58 #include "libtext/cloud.h"
59 #include "libtext/fbm.h"
60 #include "libtext/fbmbump.h"
61 #include "libtext/gloss.h"
62 #include "libtext/imagetext.h"
63 #include "libtext/marble.h"
64 #include "libtext/mount.h"
65 #include "libtext/sky.h"
66 #include "libtext/stripe.h"
67 #include "libtext/windy.h"
68 #include "libtext/wood.h"
69
70 #include "libsurf/fog.h"
71 #include "libsurf/fogdeck.h"
72 #include "libsurf/mist.h"
73
74 #include "libcommon/rotate.h"
75 #include "libcommon/scale.h"
76 #include "libcommon/translate.h"
77 #include "libcommon/xform.h"
78
79 Geom *NewAggregate();
80 char yyfilename[BUFSIZ]; /* Input filename */
81 GeomList *Defstack; /* Geom definition stack. */
82 int Npoints = 0; /* # of points in Polypoints */
83 Surface *tmpsurf; /* Working surface */
84 SurfList *CurSurf;
85 Texture *CurText; /* Working list of textures */
86 ImageText *Imagetext; /* Working image texture */
87 Trans *TransHead, *TransTail; /* Linked list of current transformations */
88 Atmosphere *CurEffect = (Atmosphere *)NULL; /* Current atmos. effects */
89 PointList *Polypoints; /* List of vertices */
90 MetaList *Metapoints, *Metapoint;
91 extern FILE *yyin; /* input file pointer */
92 extern int yylineno; /* Current line # in file */
93 extern Atmosphere *AtmosEffects; /* atmospheric effects */
94 extern Medium TopMedium; /* "air" */
95 extern void GeomAddToDefined(),
96 LightAddToDefined(),
97 SurfaceAddToDefined();
98 extern Surface *SurfaceGetNamed();
99 extern Geom *GeomGetNamed();
100 %}
101 %union {
102 char *c;
103 int i;
104 Float d;
105 Vector v;
106 Vec2d uv;
107 Color col;
108 Atmosphere *atmos;
109 Light *light;
110 Surface *surf;
111 Geom *obj;
112 Texture *text;
113 Mapping *map;
114 Trans *trans;
115 Expr *e;
116 SymtabEntry *sym;
117 }
118 %token <d> tFLOAT
119 %token <c> tSTRING tFILENAME
120 %token tAPERTURE tAPPLYSURF
121 %token tBACKGROUND tBLOB tBLOTCH tBOX tBUMP tCONE tCYL tDIRECTIONAL tCURSURF
122 %token tEXTENDED tEYEP tFBM tFBMBUMP tFOCALDIST tFOG tFOGDECK tFOV tGLOSS tGRID
123 %token tHEIGHTFIELD tLIGHT tLIST tLOOKP tMARBLE tMAXDEPTH tMIST
124 %token tJITTER tNOJITTER tDEFINE
125 %token tOBJECT tOUTFILE tSKY tDISC tDIFFERENCE tUNION tINTERSECT
126 %token tPLANE tPOINT tPOLY tROTATE tSPOT tPRINT
127 %token tSCALE tSCREEN tSPHERE tSURFACE
128 %token tTHRESH tTRANSLATE tTRANSFORM tTRIANGLE tTRIANGLEUV tUP tEND
129 %token tTEXTURE tCHECKER tWOOD tCONTRAST tCUTOFF tCLOUD
130 %token tAMBIENT tDIFFUSE tREFLECT tTRANSP tSPECULAR tSPECPOW
131 %token tINDEX tATMOSPHERE tNOSHADOW tAREA tTRANSLU tTORUS
132 %token tEYESEP tSHADOWTRANSP tREPORT tVERBOSE tQUIET tWINDOW tCROP tSTRIPE
133 %token tMAP tUV tSPHERICAL tCYLINDRICAL tPLANAR
134 %token tIMAGE tSMOOTH tCOMPONENT tTEXTSURF tRANGE tTILE tSTARTTIME tFRAMELENGTH
135 %token tNAME tFILTER tGAUSS tBODY tSAMPLE tEXTINCT tWINDY tMOUNT
136 %token tSHUTTER tFRAMES
137 %type <c> Filename
138 %type <e> AnimExpr MExpr ParenExpr
139 %type <d> Expr Float
140 %type <v> Vector
141 %type <uv> Vec2d
142 %type <col> Color Intensity Lightdef
143 %type <text> Texturetype
144 %type <i> SurfCompName IExpr CombineOp
145 %type <atmos> EffectType
146 %type <light> LightType
147 %type <obj> PrimType Primitive TransTextObj
148 %type <obj> Csg Aggregate Object TransObj ObjType
149 %type <obj> Blob Box Cone Cylinder Disc HeightField Plane Poly
150 %type <obj> Sphere Triangle Torus AggregateType List Grid AggregateCreate
151 %type <obj> NamedObject
152 %type <surf> Surface OptSurface NamedSurf
153 %type <surf> SurfSpec ModifyNamedSurf
154 %type <map> Mapping MapMethod OptMapping
155 %type <trans> TransformType
156 %type <sym> Symtabent
157
158 %left '+' '-'
159 %left '*' '/' '%'
160 %left UMINUS
161 %right '^'
162 %%
163 Items : /* empty */
164 | Items Item
165 ;
166 Item : Eyep
167 | Lookp
168 | Up
169 | Fov
170 | Screen
171 | Window
172 | Crop
173 | Report
174 | Aperture
175 | Focaldist
176 | Eyesep
177 | Maxdepth
178 | Sample
179 | Filter
180 | Contrast
181 | Cutoff
182 | Background
183 | Shadowtransp
184 | Light
185 | SurfDef
186 | CurSurf
187 | Outfile
188 | Instance
189 | NameObject
190 | GlobalEffects
191 | Define
192 | Frames
193 | Starttime
194 | Shutter
195 | Framelength
196 | Print
197 ;
198 Instance : TransTextObj
199 {
200 if ($1) {
201 /*
202 * Add instance to current object.
203 */
204 $1->next = Defstack->obj->next;
205 Defstack->obj->next = $1;
206 }
207 }
208 TransTextObj : TransObj Textures
209 {
210 if ($$ && CurText) {
211 $$->texture = TextAppend(CurText, $$->texture);
212 }
213 CurText = (Texture *)NULL;
214 }
215 ;
216 TransObj : Object Transforms
217 {
218 $$ = $1;
219 if ($$ != (Geom *)NULL) {
220 if (TransHead) {
221 $$->trans = TransHead;
222 $$->transtail = TransTail;
223 /*
224 * We compose non-animated tranformation lists,
225 * so we're only animated if it's one long,
226 * or it's animated itself.
227 */
228 if ($$->trans->assoc || $$->trans->next)
229 /* geometry is animated...*/
230 $$->animtrans = TRUE;
231 }
232 }
233 }
234 ;
235 Object : ObjType
236 {
237 if ($$)
238 StatsAddRep($$);
239 }
240 | NamedObject
241 ;
242 ObjType : Primitive
243 | Aggregate
244 ;
245 Primitive : PrimType
246 {
247 if ($$)
248 $$->prims = 1; /* one primitive */
249 }
250 ;
251 PrimType : Plane
252 | Sphere
253 | Box
254 | Triangle
255 | Cylinder
256 | Cone
257 | Poly
258 | HeightField
259 | Disc
260 | Torus
261 | Blob
262 ;
263 NameObject : tNAME tSTRING TransTextObj
264 {
265 if ($3) {
266 $3->name = $2;
267 GeomAddToDefined($3);
268 }
269 };
270 Aggdefs : Aggdefs Aggdef
271 |
272 ;
273 Aggdef : Instance
274 | SurfDef
275 | CurSurf
276 | NameObject
277 ;
278 Textures : Textures Texture
279 |
280 ;
281 Texture : tTEXTURE Texturetype Transforms
282 {
283 if ($2 != (Texture *)NULL) {
284 /*
285 * Set transformation information.
286 */
287 if (TransHead) {
288 $2->trans = TransHead;
289 /*
290 * We compose non-animated tranformation lists,
291 * so we're only animated if it's one long,
292 * or it's animated itself.
293 */
294 if ($2->trans->assoc || $2->trans->next)
295 /* texture transformation is animated...*/
296 $2->animtrans = TRUE;
297 }
298 /*
299 * Walk to the end of list of textures and
300 * append new texture. This is done so that
301 * textures are applied in the expected order.
302 */
303 CurText = TextAppend($2, CurText);
304 }
305 }
306 ;
307 Texturetype : tCHECKER Surface
308 {
309 $$ = TextCheckerCreate($2);
310 }
311 | tBLOTCH Expr Surface
312 {
313 $$ = TextBlotchCreate($2, $3);
314 }
315 | tBUMP Expr
316 {
317 $$ = TextBumpCreate($2);
318 }
319 | tMARBLE
320 {
321 $$ = TextMarbleCreate((char *)NULL);
322 }
323 | tMARBLE Filename
324 {
325 $$ = TextMarbleCreate($2);
326 }
327 | tFBM Expr Expr Expr Expr IExpr Expr
328 {
329 $$ = TextFBmCreate($2, $3, $4, $5, $6, $7,
330 (char *)NULL);
331 }
332 | tFBM Expr Expr Expr Expr IExpr Expr Filename
333 {
334 $$ = TextFBmCreate($2, $3, $4, $5, $6, $7, $8);
335 }
336 | tFBMBUMP Expr Expr Expr Expr IExpr
337 {
338 $$ = TextFBmBumpCreate($2, $3, $4, $5, $6);
339 }
340 | tWOOD
341 {
342 $$ = TextWoodCreate();
343 }
344 | tGLOSS Expr
345 {
346 $$ = TextGlossCreate($2);
347 }
348 | tCLOUD Expr Expr Expr IExpr Expr Expr Expr
349 {
350 $$ = TextCloudCreate($2, $3, $4, $5, $6, $7, $8);
351 }
352 | tSKY Expr Expr Expr IExpr Expr Expr
353 {
354 $$ = TextSkyCreate($2, $3, $4, $5, $6, $7);
355 }
356 | ImageText
357 {
358 /*
359 * Image texturing has so many options
360 * that specification is keyword-based.
361 */
362 if (Imagetext->image == (Image *)NULL)
363 $$ = (Texture *)NULL;
364 else
365 $$ = TextCreate(Imagetext, ImageTextApply);
366 Imagetext = (ImageText *)NULL;
367 }
368 | tSTRIPE Surface Expr Expr OptMapping
369 {
370 $$ = TextStripeCreate($2, $3, $4, $5);
371 }
372 | tWINDY Expr Expr Expr Expr IExpr Expr Expr Expr
373 {
374 $$ = TextWindyCreate($2, $3, $4, $5, $6, $7, $8, $9);
375 }
376 | tMOUNT Filename Expr Expr
377 {
378 $$ = TextMountCreate($2, $3, $4);
379 }
380 ;
381 ImageText : ImageTextType ImageTextOptions
382 ;
383 ImageTextType : tIMAGE Filename
384 {
385 Imagetext = ImageTextCreate($2);
386 }
387 ;
388 ImageTextOptions: ImageTextOptions ImageTextOption
389 | /* EMPTY */
390 ;
391 ImageTextOption: tCOMPONENT SurfCompName
392 {
393 /* set texture to modify given component */
394 ImageTextSetComponent(Imagetext, $2);
395 }
396 | tTILE Expr Expr
397 {
398 Imagetext->tileu = $2;
399 Imagetext->tilev = $3;
400 }
401 | tTEXTSURF Surface
402 {
403 Imagetext->surf = $2;
404 }
405 | tRANGE Expr Expr
406 {
407 Imagetext->hi = $2;
408 Imagetext->lo = $3;
409 }
410 | tSMOOTH
411 {
412 Imagetext->smooth = TRUE;
413 }
414 | Mapping
415 {
416 Imagetext->mapping = $1;
417 };
418 NamedObject : tOBJECT Surface tSTRING
419 {
420 Geom *otmp;
421 /*
422 * Create an instance of the named object.
423 */
424 otmp = GeomGetNamed($3);
425 if (otmp == (Geom *)NULL)
426 RLerror(RL_PANIC,
427 "There is no object named \"%s\".", $3);
428 $$ = GeomInstanceCreate(otmp);
429 $$->surf = $2;
430 $$->prims = otmp->prims;
431 }
432 | tOBJECT tSTRING
433 {
434 Geom *otmp;
435
436 otmp = GeomGetNamed($2);
437 if (otmp == (Geom *)NULL)
438 RLerror(RL_PANIC,
439 "There is no object named \"%s\".", $2);
440 $$ = GeomInstanceCreate(otmp);
441 $$->surf = CurSurf->surf;
442 $$->prims = otmp->prims;
443 };
444 Transforms : Transforms PostTransform
445 | /* empty */
446 {
447 TransHead = TransTail = (Trans *)NULL;
448 };
449 PostTransform : TransformType
450 {
451 if (TransHead == (Trans *)NULL) {
452 /* we're the list, head and tail */
453 TransHead = TransTail = $1;
454 } else {
455 if ($1->animated || TransTail->animated) {
456 /* new tail */
457 $1->prev = TransTail;
458 TransTail->next = $1;
459 TransTail = $1;
460 } else {
461 /* collapse with tail */
462 TransCompose(TransTail, $1, TransTail);
463 TransFree($1);
464 }
465 }
466 }
467 ;
468 TransformType : tSCALE AnimExpr AnimExpr AnimExpr
469 {
470 $$ = TransScaleCreate();
471 TransScaleSetX($$, $2);
472 TransScaleSetY($$, $3);
473 TransScaleSetZ($$, $4);
474 if (!$$->animated)
475 TransPropagate($$);
476
477 }
478 | tTRANSLATE AnimExpr AnimExpr AnimExpr
479 {
480 $$ = TransTranslateCreate();
481 TransTranslateSetX($$, $2);
482 TransTranslateSetY($$, $3);
483 TransTranslateSetZ($$, $4);
484 if (!$$->animated)
485 TransPropagate($$);
486 }
487 | tROTATE AnimExpr AnimExpr AnimExpr AnimExpr
488 {
489 $$ = TransRotateCreate();
490 TransRotateSetX($$, $2);
491 TransRotateSetY($$, $3);
492 TransRotateSetZ($$, $4);
493 TransRotateSetTheta($$, $5);
494 if (!$$->animated)
495 TransPropagate($$);
496 }
497 | tTRANSFORM AnimExpr AnimExpr AnimExpr
498 AnimExpr AnimExpr AnimExpr
499 AnimExpr AnimExpr AnimExpr
500 {
501 $$ = TransXformCreate();
502 TransXformSetX0($$, $2);
503 TransXformSetY0($$, $3);
504 TransXformSetZ0($$, $4);
505 TransXformSetX1($$, $5);
506 TransXformSetY1($$, $6);
507 TransXformSetZ1($$, $7);
508 TransXformSetX2($$, $8);
509 TransXformSetY2($$, $9);
510 TransXformSetZ2($$, $10);
511 if (!$$->animated)
512 TransPropagate($$);
513 }
514 | tTRANSFORM AnimExpr AnimExpr AnimExpr
515 AnimExpr AnimExpr AnimExpr
516 AnimExpr AnimExpr AnimExpr
517 AnimExpr AnimExpr AnimExpr
518 {
519 $$ = TransXformCreate();
520 TransXformSetX0($$, $2);
521 TransXformSetY0($$, $3);
522 TransXformSetZ0($$, $4);
523 TransXformSetX1($$, $5);
524 TransXformSetY1($$, $6);
525 TransXformSetZ1($$, $7);
526 TransXformSetX2($$, $8);
527 TransXformSetY2($$, $9);
528 TransXformSetZ2($$, $10);
529 TransXformSetXt($$, $11);
530 TransXformSetYt($$, $12);
531 TransXformSetZt($$, $13);
532 if (!$$->animated)
533 TransPropagate($$);
534 };
535 Eyep : tEYEP Vector Transforms
536 {
537 Camera.pos = $2;
538 /*
539 * Eye can be transformed...
540 if (CurMatrix) {
541 PointTransform(&Camera.pos, CurMatrix);
542 free((voidstar)CurMatrix);
543 CurMatrix = (Matrix*)NULL;
544 }
545 */
546 }
547 ;
548 Lookp : tLOOKP Vector
549 {
550 Camera.lookp = $2;
551 }
552 ;
553 Up : tUP Vector
554 {
555 Camera.up = $2;
556 }
557 ;
558 Fov : tFOV Expr Expr
559 {
560 Camera.hfov = $2;
561 Camera.vfov = $3;
562 }
563 | tFOV Expr
564 {
565 Camera.hfov = $2;
566 Camera.vfov = UNSET;
567 }
568 ;
569 Sample : tSAMPLE IExpr tJITTER
570 {
571 if (!Options.samples_set)
572 Options.samples = $2;
573 if (!Options.jitter_set)
574 Options.jitter = TRUE;
575 }
576 | tSAMPLE IExpr tNOJITTER
577 {
578 if (!Options.samples_set)
579 Options.samples = $2;
580 if (!Options.jitter_set)
581 Options.jitter = FALSE;
582 }
583 | tSAMPLE IExpr
584 {
585 if (!Options.samples_set)
586 Options.samples = $2;
587 }
588 ;
589 Filter : tFILTER tBOX Expr
590 {
591 Options.gaussian = FALSE;
592 Options.filterwidth = $3;
593 }
594 | tFILTER tBOX
595 {
596 Options.gaussian = FALSE;
597 }
598 | tFILTER tGAUSS Expr
599 {
600 Options.gaussian = TRUE;
601 Options.filterwidth = $3;
602 }
603 | tFILTER tGAUSS
604 {
605 Options.gaussian = TRUE;
606 };
607 Starttime : tSTARTTIME Expr
608 {
609 Options.starttime = $2;
610 };
611 Frames : tFRAMES IExpr
612 {
613 if (!Options.totalframes_set)
614 Options.totalframes = $2;
615 };
616 Framelength : tFRAMELENGTH Expr
617 {
618 Options.framelength = $2;
619 };
620 Shutter : tSHUTTER Expr
621 {
622 Options.shutterspeed = $2;
623 };
624 Contrast : tCONTRAST Expr Expr Expr
625 {
626 if (!Options.contrast_set) {
627 Options.contrast.r = $2;
628 Options.contrast.g = $3;
629 Options.contrast.b = $4;
630 }
631 }
632 ;
633 Cutoff : tCUTOFF Intensity
634 {
635 if (!Options.cutoff_set)
636 Options.cutoff = $2;
637 }
638 ;
639 Screen : tSCREEN IExpr IExpr
640 {
641 if (!Options.resolution_set) {
642 Screen.xres = $2;
643 Screen.yres = $3;
644 }
645 }
646 ;
647 Window : tWINDOW IExpr IExpr IExpr IExpr
648 {
649 if (!Options.window_set) {
650 Options.window[LOW][X] = $2;
651 Options.window[HIGH][X] = $3;
652 Options.window[LOW][Y] = $4;
653 Options.window[HIGH][Y] = $5;
654 /*
655 * We must let ViewingSetup know
656 * that a window has been defined.
657 */
658 Options.window_set = TRUE;
659 }
660 }
661 ;
662 Crop : tCROP Expr Expr Expr Expr
663 {
664 if (!Options.crop_set) {
665 Options.crop[LOW][X] = $2;
666 Options.crop[HIGH][X] = $3;
667 Options.crop[LOW][Y] = $4;
668 Options.crop[HIGH][Y] = $5;
669 }
670 }
671 ;
672 Report : tREPORT Verbose Quiet IExpr Filename
673 {
674 if (!Options.freq_set)
675 Options.report_freq = $4;
676 if (Options.statsname == (char *)NULL)
677 Options.statsname = strsave($5);
678 }
679 | tREPORT Verbose Quiet IExpr
680 {
681 if (!Options.freq_set)
682 Options.report_freq = $4;
683 }
684 | tREPORT Verbose Quiet Filename
685 {
686 if (Options.statsname == (char *)NULL)
687 Options.statsname = strsave($4);
688 }
689 | tREPORT Verbose Quiet
690 ;
691 Verbose : tVERBOSE
692 { Options.verbose = TRUE; }
693 |
694 ;
695 Quiet : tQUIET
696 { Options.quiet = TRUE; }
697 |
698 ;
699 Aperture : tAPERTURE Expr
700 {
701 Camera.aperture = $2;
702 }
703 ;
704 Focaldist : tFOCALDIST Expr
705 {
706 Camera.focaldist = $2;
707 }
708 ;
709 Eyesep : tEYESEP Expr
710 {
711 if (!Options.eyesep_set)
712 Options.eyesep = $2;
713 }
714 ;
715 Maxdepth : tMAXDEPTH IExpr
716 {
717 if (!Options.maxdepth_set)
718 Options.maxdepth = $2;
719 }
720 ;
721 Background : tBACKGROUND Color
722 {
723 Screen.background = $2;
724 }
725 ;
726 Shadowtransp : tSHADOWTRANSP
727 {
728 Options.shadowtransp = !Options.shadowtransp;
729 }
730 ;
731 Light : LightType
732 {
733 LightAddToDefined($1);
734 }
735 | LightType tNOSHADOW
736 {
737 $1->shadow = FALSE;
738 LightAddToDefined($1);
739 }
740 | tLIGHT Intensity tAMBIENT
741 {
742 Options.ambient = $2;
743 }
744 | Lightdef tAREA Vector Vector IExpr Vector IExpr
745 {
746 extern void AreaLightCreate();
747 /* Area light is strange in that the
748 * Creation routine does the installation.
749 */
750 AreaLightCreate(&$1, &$3, &$4, $5, &$6, $7, TRUE);
751 }
752 | Lightdef tAREA Vector Vector IExpr Vector IExpr tNOSHADOW
753 {
754 extern void AreaLightCreate();
755 /* Area light is strange in that the
756 * Creation routine does the installation.
757 */
758 AreaLightCreate(&$1, &$3, &$4, $5, &$6, $7, FALSE);
759 };
760 LightType : Lightdef tPOINT Vector
761 {
762 $$ = LightPointCreate(&$1, &$3);
763 }
764 | Lightdef tDIRECTIONAL Vector
765 {
766 $$ = LightInfiniteCreate(&$1, &$3);
767 }
768 | Lightdef tEXTENDED Expr Vector
769 {
770 $$ = LightExtendedCreate(&$1, $3, &$4);
771 }
772 | Lightdef tSPOT Vector Vector Expr
773 {
774 $$ = LightSpotCreate(&$1, &$3, &$4, $5, 0., 0.);
775 }
776 | Lightdef tSPOT Vector Vector Expr Expr Expr
777 {
778 /* light <intens> spot from <to> coef inner_rad
779 outer_rad */
780 $$ = LightSpotCreate(&$1, &$3, &$4, $5, $6, $7);
781 };
782 Lightdef : tLIGHT Intensity
783 {
784 $$ = $2;
785 }
786 ;
787 CurSurf : tAPPLYSURF Surface
788 {
789 CurSurf->surf = $2;
790 }
791 ;
792 OptSurface : Surface
793 | /* EMPTY */
794 {
795 $$ = CurSurf->surf;
796 }
797 ;
798 Surface : NamedSurf
799 | ModifyNamedSurf
800 | SurfSpec
801 ;
802 NamedSurf : tSTRING
803 {
804 $$ = SurfaceGetNamed($1);
805 /*
806 * Free up memory allocated for surf name.
807 * We bother doing this because for large models
808 * converted from 3.0, surfnames this can account
809 * for lots o' bytes.
810 */
811 free((voidstar)$1);
812 }
813 | tCURSURF
814 {
815 extern Surface DefaultSurface;
816
817 if (CurSurf->surf)
818 $$ = CurSurf->surf;
819 else
820 $$ = &DefaultSurface;
821 }
822 ;
823 ModifyNamedSurf : CopyNamedSurf SurfComponent SurfComponents
824 {
825 $$ = tmpsurf;
826 tmpsurf = (Surface *)NULL;
827 }
828 | CopyCurSurf SurfComponent SurfComponents
829 {
830 $$ = tmpsurf;
831 tmpsurf = (Surface *)NULL;
832 }
833 ;
834 CopyNamedSurf : tSTRING
835 {
836 tmpsurf = SurfaceCopy(SurfaceGetNamed($1));
837 }
838 ;
839 CopyCurSurf : tCURSURF
840 {
841 extern Surface DefaultSurface;
842 if (CurSurf->surf)
843 tmpsurf = SurfaceCopy(CurSurf->surf);
844 else
845 tmpsurf = SurfaceCopy(&DefaultSurface);
846 }
847 ;
848 SurfSpec : SurfComponent SurfComponents
849 {
850 $$ = tmpsurf;
851 tmpsurf = (Surface *)NULL;
852 }
853 ;
854 SurfDef : tSURFACE tSTRING Surface
855 {
856 tmpsurf = SurfaceCopy($3);
857 tmpsurf->name = strsave($2);
858 SurfaceAddToDefined(tmpsurf);
859 tmpsurf = (Surface *)NULL;
860 }
861 | tSURFACE tSTRING
862 {
863 /* black surface */
864 tmpsurf = SurfaceCreate();
865 tmpsurf->name = strsave($2);
866 SurfaceAddToDefined(tmpsurf);
867 tmpsurf = (Surface *)NULL;
868 }
869 ;
870 SurfComponents : SurfComponents SurfComponent
871 | /* EMPTY */
872 ;
873 SurfComponent : Ambient
874 | Diffuse
875 | Specular
876 | Specpow
877 | Body
878 | Reflect
879 | Transp
880 | Extinct
881 | Index
882 | Translu
883 | Noshadow
884 ;
885 Ambient : tAMBIENT Color
886 {
887 if (tmpsurf == (Surface *)NULL)
888 tmpsurf = SurfaceCreate();
889 tmpsurf->amb = $2;
890 }
891 ;
892 Diffuse : tDIFFUSE Color
893 {
894 if (tmpsurf == (Surface *)NULL)
895 tmpsurf = SurfaceCreate();
896 tmpsurf->diff = $2;
897 }
898 ;
899 Specular : tSPECULAR Color
900 {
901 if (tmpsurf == (Surface *)NULL)
902 tmpsurf = SurfaceCreate();
903 tmpsurf->spec = $2;
904 }
905 ;
906 Body : tBODY Color
907 {
908 if (tmpsurf == (Surface *)NULL)
909 tmpsurf = SurfaceCreate();
910 tmpsurf->body = $2;
911 };
912 Extinct : tEXTINCT Expr
913 {
914 if (tmpsurf == (Surface *)NULL)
915 tmpsurf = SurfaceCreate();
916 tmpsurf->statten = $2;
917 };
918 Specpow : tSPECPOW Expr
919 {
920 if (tmpsurf == (Surface *)NULL)
921 tmpsurf = SurfaceCreate();
922 tmpsurf->srexp = $2;
923 }
924 ;
925 Reflect : tREFLECT Expr
926 {
927 if (tmpsurf == (Surface *)NULL)
928 tmpsurf = SurfaceCreate();
929 tmpsurf->reflect = $2;
930 }
931 ;
932 Transp : tTRANSP Expr
933 {
934 if (tmpsurf == (Surface *)NULL)
935 tmpsurf = SurfaceCreate();
936 tmpsurf->transp = $2;
937 }
938 ;
939 Index : tINDEX Expr
940 {
941 if (tmpsurf == (Surface *)NULL)
942 tmpsurf = SurfaceCreate();
943 tmpsurf->index = $2;
944 }
945 ;
946 Translu : tTRANSLU Expr Color Expr
947 {
948 if (tmpsurf == (Surface *)NULL)
949 tmpsurf = SurfaceCreate();
950 tmpsurf->translucency = $2;
951 tmpsurf->translu = $3;
952 tmpsurf->stexp = $4;
953 }
954 ;
955 Noshadow : tNOSHADOW
956 {
957 if (tmpsurf == (Surface *)NULL)
958 tmpsurf = SurfaceCreate();
959 tmpsurf->noshadow = TRUE;
960 }
961 ;
962 HeightField : tHEIGHTFIELD Surface Filename
963 {
964 $$ = GeomHfCreate($3);
965 if ($$)
966 $$->surf = $2;
967 }
968 | tHEIGHTFIELD Filename
969 {
970 $$ = GeomHfCreate($2);
971 }
972 ;
973 Poly : tPOLY OptSurface Polypoints
974 {
975 $$ = GeomPolygonCreate(Polypoints, Npoints,
976 Options.flipnorm);
977 if ($$)
978 $$->surf = $2;
979 Polypoints = (PointList *)NULL;
980 Npoints = 0;
981 }
982 ;
983 Polypoints : /* empty */
984 | Polypoints Polypoint
985 ;
986 Polypoint : Vector
987 {
988 PointList *ptmp;
989
990 ptmp = (PointList *)Malloc(sizeof(PointList));
991 ptmp->vec = $1;
992 ptmp->next = Polypoints;
993 Polypoints = ptmp;
994 Npoints++;
995 }
996 ;
997 Aggregate : AggregateDef
998 {
999 if (Defstack->obj) {
1000 /*
1001 * Set object texture to current texture.
1002 */
1003 Defstack->obj->texture = CurText;
1004 }
1005 CurText = (Texture *)NULL;
1006 /*
1007 * Pop topmost object on stack.
1008 */
1009 $$ = Defstack->obj;
1010 Defstack = GeomStackPop(Defstack);
1011 /* Pop current surface */
1012 CurSurf = SurfPop(CurSurf);
1013 /* Make current default surf aggregate's default */
1014 $$->surf = CurSurf->surf;
1015 }
1016 ;
1017 AggregateDef : AggregateCreate Aggdefs tEND
1018 {
1019 /* Convert aggregate, pop stacks, etc. */
1020 if ($1) {
1021 if (Defstack->obj->next == (Geom *)NULL) {
1022 RLerror(RL_WARN,
1023 "Null object defined.\n");
1024 Defstack->obj = (Geom *)NULL;
1025 } else {
1026 /*
1027 * Convert the linked list of objects
1028 * associated with the topmost object
1029 * to the appropriate aggregate type.
1030 */
1031 Defstack->obj->prims=AggregateConvert(
1032 Defstack->obj,
1033 Defstack->obj->next);
1034 /*
1035 * Make sure conversion worked OK.
1036 */
1037 if (Defstack->obj->prims <= 0)
1038 Defstack->obj = (Geom *)NULL;
1039 }
1040 }
1041 }
1042 ;
1043 AggregateCreate : AggregateType
1044 {
1045 if ($1) {
1046 Defstack = GeomStackPush($1, Defstack);
1047 CurSurf = SurfPush((Surface *)NULL, CurSurf);
1048 }
1049 };
1050 AggregateType : List
1051 | Grid
1052 | Csg
1053 ;
1054 List : tLIST
1055 {
1056 $$ = GeomListCreate();
1057 }
1058 ;
1059 Grid : tGRID IExpr IExpr IExpr
1060 {
1061 $$ = GeomGridCreate($2, $3, $4);
1062 }
1063 ;
1064 Csg : CombineOp
1065 {
1066 $$ = GeomCsgCreate($1);
1067 Options.csg = TRUE;
1068 }
1069 ;
1070 CombineOp : tUNION
1071 {
1072 $$ = CSG_UNION;
1073 }
1074 | tINTERSECT
1075 {
1076 $$ = CSG_INTERSECT;
1077 }
1078 | tDIFFERENCE
1079 {
1080 $$ = CSG_DIFFERENCE;
1081 }
1082 ;
1083 Cone : tCONE OptSurface Expr Vector Expr Vector
1084 {
1085 if (equal($3, $5)) {
1086 /* It's really a cylinder */
1087 $$ = GeomCylinderCreate($3, &$4, &$6);
1088 } else
1089 $$ = GeomConeCreate($3, &$4, $5, &$6);
1090 if ($$)
1091 $$->surf = $2;
1092 }
1093 ;
1094 Cylinder : tCYL OptSurface Expr Vector Vector
1095 {
1096 $$ = GeomCylinderCreate($3, &$4, &$5);
1097 if ($$)
1098 $$->surf = $2;
1099 }
1100 ;
1101 Sphere : tSPHERE OptSurface Expr Vector
1102 {
1103 $$ = GeomSphereCreate($3, &($4));
1104 if ($$)
1105 $$->surf = $2;
1106 }
1107 ;
1108 Disc : tDISC OptSurface Expr Vector Vector
1109 {
1110 $$ = GeomDiscCreate($3, &($4), &($5));
1111 if ($$)
1112 $$->surf = $2;
1113 }
1114 ;
1115 Box : tBOX OptSurface Vector Vector
1116 {
1117 $$ = GeomBoxCreate(&$3, &$4);
1118 if ($$)
1119 $$->surf = $2;
1120 }
1121 ;
1122 Triangle : tTRIANGLE OptSurface Vector Vector Vector
1123 {
1124 $$ = GeomTriangleCreate(FLATTRI, &($3), &($4), &($5),
1125 (Vector *)NULL, (Vector *)NULL, (Vector *)NULL,
1126 (Vec2d *)NULL, (Vec2d *)NULL, (Vec2d *)NULL,
1127 Options.flipnorm);
1128 if ($$)
1129 $$->surf = $2;
1130 }
1131 | tTRIANGLE OptSurface Vector Vector
1132 Vector Vector
1133 Vector Vector
1134 {
1135 $$ = GeomTriangleCreate(PHONGTRI, &($3), &($5),
1136 &($7), &($4), &($6), &($8),
1137 (Vec2d *)NULL, (Vec2d *)NULL, (Vec2d *)NULL,
1138 Options.flipnorm);
1139 if ($$)
1140 $$->surf = $2;
1141 }
1142 | tTRIANGLEUV OptSurface Vector Vector Vec2d
1143 Vector Vector Vec2d
1144 Vector Vector Vec2d
1145 {
1146 $$ = GeomTriangleCreate(PHONGTRI, &($3), &($6), &($9),
1147 &($4), &($7), &($10),
1148 &($5), &($8), &($11),
1149 Options.flipnorm);
1150 if ($$)
1151 $$->surf = $2;
1152 }
1153 ;
1154 Plane : tPLANE OptSurface Vector Vector
1155 {
1156 $$ = GeomPlaneCreate(&($3), &($4));
1157 if ($$)
1158 $$->surf = $2;
1159 }
1160 ;
1161 Torus : tTORUS OptSurface Expr Expr Vector Vector
1162 {
1163 $$ = GeomTorusCreate($3, $4, &($5), &($6));
1164 if ($$)
1165 $$->surf = $2;
1166 }
1167 ;
1168 Blob : tBLOB OptSurface Expr MetaPoints
1169 {
1170 $$ = GeomBlobCreate($3, Metapoints, Npoints);
1171 if ($$)
1172 $$->surf = $2;
1173 Metapoints = (MetaList *)NULL;
1174 Npoints = 0;
1175 }
1176 ;
1177 MetaPoints : /* empty */
1178 | MetaPoints MetaPoint
1179 ;
1180 MetaPoint : Expr Expr Expr Expr Expr
1181 {
1182 Metapoint = (MetaList *)Malloc(sizeof(MetaList));
1183 Metapoint->mvec.c0 = $1;
1184 Metapoint->mvec.rs = $2;
1185 Metapoint->mvec.x = $3;
1186 Metapoint->mvec.y = $4;
1187 Metapoint->mvec.z = $5;
1188 Metapoint->next = Metapoints;
1189 Metapoints = Metapoint;
1190 Npoints++;
1191 }
1192 ;
1193 Outfile : tOUTFILE Filename
1194 {
1195 if (Options.imgname != (char *)NULL)
1196 /* Already set on command line. */
1197 RLerror(RL_WARN,
1198 "Ignoring output file name \"%s\".\n",
1199 $2);
1200 else
1201 Options.imgname = strsave($2);
1202 }
1203 ;
1204 GlobalEffects : tATMOSPHERE Effects
1205 {
1206 AtmosEffects = CurEffect;
1207 CurEffect = (Atmosphere *)NULL;
1208 }
1209 | tATMOSPHERE IExpr Effects
1210 {
1211 if ($2 <= 0.)
1212 RLerror(RL_PANIC,
1213 "Index of refraction must be positive.\n");
1214 TopMedium.index = $2;
1215 AtmosEffects = CurEffect;
1216 CurEffect = (Atmosphere *)NULL;
1217 }
1218 ;
1219 Effects : Effects Effect
1220 |
1221 ;
1222 Effect : EffectType
1223 {
1224 $1->next = CurEffect;
1225 CurEffect = $1;
1226 }
1227 ;
1228 EffectType : tMIST Color Color Expr Expr
1229 {
1230 $$ = AtmosMistCreate(&($2), &($3), $4, $5);
1231 }
1232 | tFOG Color Color
1233 {
1234 $$ = AtmosFogCreate(&($2), &($3));
1235 }
1236 | tFOGDECK Expr Expr Vector Expr IExpr Color Color
1237 {
1238 $$ = AtmosFogdeckCreate($2, $3, &$4, $5, $6, &$7, &$8);
1239 }
1240 ;
1241 Color : Expr Expr Expr
1242 {
1243 $$.r = $1;
1244 $$.g = $2;
1245 $$.b = $3;
1246 }
1247 ;
1248 Vector : Expr Expr Expr
1249 {
1250 $$.x = $1;
1251 $$.y = $2;
1252 $$.z = $3;
1253 }
1254 ;
1255 Vec2d : Expr Expr
1256 {
1257 $$.u = $1;
1258 $$.v = $2;
1259 }
1260 ;
1261 OptMapping : Mapping
1262 | /* EMPTY */
1263 {
1264 $$ = UVMappingCreate();
1265 }
1266 ;
1267 Mapping : tMAP MapMethod
1268 {
1269 $$ = $2;
1270 }
1271 ;
1272 MapMethod : tUV
1273 {
1274 $$ = UVMappingCreate();
1275 }
1276 | tSPHERICAL
1277 {
1278 $$ = SphereMappingCreate((Vector *)NULL,
1279 (Vector *)NULL, (Vector *)NULL);
1280 }
1281 | tSPHERICAL Vector Vector Vector
1282 {
1283 /* origin up uaxis */
1284 $$ = SphereMappingCreate(&$2, &$3, &$4);
1285 }
1286 | tCYLINDRICAL
1287 {
1288 $$ = CylMappingCreate((Vector *)NULL,
1289 (Vector *)NULL, (Vector *)NULL);
1290 }
1291 | tCYLINDRICAL Vector Vector Vector
1292 {
1293 /* origin up uaxis */
1294 $$ = CylMappingCreate(&$2, &$3, &$4);
1295 }
1296 | tPLANAR
1297 {
1298 $$ = LinearMappingCreate((Vector *)NULL,
1299 (Vector *)NULL, (Vector *)NULL);
1300 }
1301 | tPLANAR Vector Vector Vector
1302 {
1303 /* origin up uaxis */
1304 $$ = LinearMappingCreate(&$2, &$3, &$4);
1305 }
1306 ;
1307 SurfCompName : tAMBIENT
1308 {
1309 $$ = AMBIENT;
1310 }
1311 | tDIFFUSE
1312 {
1313 $$ = DIFFUSE;
1314 }
1315 | tBODY
1316 {
1317 $$ = BODY;
1318 }
1319 | tSPECULAR
1320 {
1321 $$ = SPECULAR;
1322 }
1323 | tREFLECT
1324 {
1325 $$ = REFLECT;
1326 }
1327 | tTRANSP
1328 {
1329 $$ = TRANSP;
1330 }
1331 | tSPECPOW
1332 {
1333 $$ = SPECPOW;
1334 }
1335 | tBUMP
1336 {
1337 $$ = BUMP;
1338 }
1339 | tINDEX
1340 {
1341 $$ = INDEX;
1342 }
1343 ;
1344 Intensity : Expr
1345 { $$.r = $$.g = $$.b = $1; }
1346 | Color
1347 ;
1348 Print : tPRINT Expr
1349 {
1350 fprintf(stderr,"%f\n",$2);
1351 }
1352 Define : tDEFINE tSTRING AnimExpr
1353 {
1354 SymtabAddEntry($2, $3->type, $3, NULL, $3->timevary, 0);
1355 };
1356 IExpr : Expr
1357 { $$ = (int)$1; }
1358 ;
1359 Expr : Float
1360 | ParenExpr
1361 {
1362 if (!$1->timevary) {
1363 $$ = ExprEval($1);
1364 } else {
1365 RLerror(RL_PANIC, "Illegal expression use.\n");
1366 }
1367 }
1368 ;
1369 AnimExpr : Float
1370 {
1371 $$ = ExprReuseFloatCreate($1);
1372 }
1373 | ParenExpr
1374 ;
1375 ParenExpr : '(' MExpr ')'
1376 {
1377 $$ = $2;
1378 };
1379 MExpr : tFLOAT
1380 {
1381 $$ = ExprFloatCreate($1, FALSE);
1382 }
1383 | tSTRING
1384 {
1385 $$ = ExprFloatSymtabFind($1);
1386 }
1387 | Symtabent '(' MExpr ')'
1388 {
1389 $$ = ExprResolve1($3, $1->value.fp, $1->timevary);
1390 }
1391 | Symtabent '(' MExpr ',' MExpr ')'
1392 {
1393 $$ = ExprResolve2($3, $5,
1394 $1->value.fp,
1395 $1->timevary);
1396 }
1397 | Symtabent '(' MExpr ',' MExpr ',' MExpr ')'
1398 {
1399 $$ = ExprResolve3($3, $5, $7,
1400 $1->value.fp,
1401 $1->timevary);
1402 }
1403 | Symtabent '(' MExpr ',' MExpr ',' MExpr ',' MExpr ')'
1404 {
1405 $$ = ExprResolve4($3, $5, $7, $9,
1406 $1->value.fp,
1407 $1->timevary);
1408 }
1409 | Symtabent
1410 '(' MExpr ',' MExpr ',' MExpr ',' MExpr ',' MExpr ')'
1411 {
1412 $$ = ExprResolve5($3, $5, $7, $9, $11,
1413 $1->value.fp,
1414 $1->timevary);
1415 }
1416 | '(' MExpr ')'
1417 {
1418 $$ = $2;
1419 }
1420 | MExpr '+' MExpr
1421 {
1422 $$ = ExprResolve2($1, $3, SumExpr, FALSE);
1423 }
1424 | MExpr '-' MExpr
1425 {
1426 $$ = ExprResolve2($1, $3, DiffExpr, FALSE);
1427 }
1428 | MExpr '*' MExpr
1429 {
1430 $$ = ExprResolve2($1, $3, MultExpr, FALSE);
1431 }
1432 | MExpr '/' MExpr
1433 {
1434 $$ = ExprResolve2($1, $3, DivideExpr, FALSE);
1435 }
1436 | MExpr '%' MExpr
1437 {
1438 $$ = ExprResolve2($1, $3, ModExpr, FALSE);
1439 }
1440 | '-' MExpr %prec UMINUS
1441 {
1442 $$ = ExprResolve1($2, NegateExpr, FALSE);
1443 }
1444 | '+' MExpr %prec UMINUS
1445 {
1446 $$ = $2;
1447 }
1448 | MExpr '^' MExpr
1449 {
1450 $$ = ExprResolve2($1, $3, pow, FALSE);
1451 } ;
1452 Float : tFLOAT
1453 | '-' tFLOAT
1454 { $$ = -$2; }
1455 | '+' tFLOAT
1456 { $$ = $2; };
1457 Filename : tSTRING
1458 | tFILENAME
1459 ;
1460 Symtabent : tSTRING
1461 {
1462 $$ = SymtabBuiltinFind($1);
1463 };
1464 %%
1465 /*
1466 * Issue error message containing filename and line number, and exit.
1467 */
1468 /*VARARGS1*/
yyerror(s,pat1,pat2)1469 yyerror(s, pat1, pat2)
1470 char *s, *pat1, *pat2;
1471 {
1472 fprintf(stderr,"%s: Error: %s: line %d: ", Options.progname,
1473 yyfilename, yylineno);
1474 fprintf(stderr, s, pat1, pat2);
1475 if (*s && s[strlen(s) -1] != '\n')
1476 /* YACC doesn't put newlines on error messages. */
1477 fprintf(stderr,"\n");
1478 fflush(stderr);
1479 exit(1);
1480 }
1481
1482 Geom *
NewAggregate(obj)1483 NewAggregate(obj)
1484 Geom *obj;
1485 {
1486 obj->name = Defstack->obj->name;
1487 obj->next = Defstack->obj->next;
1488 return obj;
1489 }
1490