ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/cv/rad2mgf.c
Revision: 2.11
Committed: Thu Apr 13 15:33:48 1995 UTC (29 years ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.10: +36 -15 lines
Log Message:
added commenting of unsupported Radiance primitives

File Contents

# Content
1 /* Copyright (c) 1994 Regents of the University of California */
2
3 #ifndef lint
4 static char SCCSid[] = "$SunId$ LBL";
5 #endif
6
7 /*
8 * Convert Radiance scene description to MGF
9 */
10
11 #include <stdio.h>
12 #include <math.h>
13 #include <string.h>
14 #include "fvect.h"
15 #include "object.h"
16 #include "color.h"
17 #include "lookup.h"
18
19 #define PI 3.14159265358979323846
20
21 #define C_1SIDEDTHICK 0.005
22
23 int o_face(), o_cone(), o_sphere(), o_ring(), o_cylinder();
24 int o_instance(), o_illum();
25 int o_plastic(), o_metal(), o_glass(), o_dielectric(),
26 o_mirror(), o_trans(), o_light();
27
28 extern void free();
29 extern char *malloc();
30
31 LUTAB rmats = LU_SINIT(free,NULL); /* defined material table */
32
33 LUTAB rdispatch = LU_SINIT(NULL,NULL); /* function dispatch table */
34
35 char curmat[80]; /* current material */
36 char curobj[128] = "Untitled"; /* current object name */
37
38 double unit_mult = 1.; /* units multiplier */
39
40 #define hasmult (unit_mult < .999 || unit_mult > 1.001)
41
42 /*
43 * Stuff for tracking and reusing vertices:
44 */
45
46 char VKFMT[] = "%+16.9e %+16.9e %+16.9e";
47 #define VKLEN 64
48
49 #define mkvkey(k,v) sprintf(k, VKFMT, (v)[0], (v)[1], (v)[2])
50
51 #define NVERTS 256
52
53 long vclock; /* incremented at each vertex request */
54
55 struct vert {
56 long lused; /* when last used (0 if unassigned) */
57 FVECT p; /* track point position only */
58 } vert[NVERTS]; /* our vertex cache */
59
60 LUTAB vertab = LU_SINIT(free,NULL); /* our vertex lookup table */
61
62
63 main(argc, argv)
64 int argc;
65 char **argv;
66 {
67 int i;
68
69 for (i = 1; i < argc && argv[i][0] == '-'; i++)
70 switch (argv[i][1]) {
71 case 'd': /* units */
72 switch (argv[i][2]) {
73 case 'm': /* meters */
74 unit_mult = 1.;
75 break;
76 case 'c': /* centimeters */
77 unit_mult = .01;
78 break;
79 case 'f': /* feet */
80 unit_mult = 12.*.0254;
81 break;
82 case 'i': /* inches */
83 unit_mult = .0254;
84 break;
85 default:
86 goto unkopt;
87 }
88 break;
89 default:
90 goto unkopt;
91 }
92 init();
93 if (i >= argc)
94 rad2mgf(NULL);
95 else
96 for ( ; i < argc; i++)
97 rad2mgf(argv[i]);
98 uninit();
99 exit(0);
100 unkopt:
101 fprintf(stderr, "Usage: %s [-d{m|c|f|i}] file ..\n", argv[0]);
102 exit(1);
103 }
104
105
106 rad2mgf(inp) /* convert a Radiance file to MGF */
107 char *inp;
108 {
109 #define mod buf
110 #define typ (buf+128)
111 #define id (buf+256)
112 #define alias (buf+384)
113 char buf[512];
114 FUNARGS fa;
115 register FILE *fp;
116 register int c;
117
118 if (inp == NULL) {
119 inp = "standard input";
120 fp = stdin;
121 } else if (inp[0] == '!') {
122 if ((fp = popen(inp+1, "r")) == NULL) {
123 fputs(inp, stderr);
124 fputs(": cannot execute\n", stderr);
125 exit(1);
126 }
127 } else if ((fp = fopen(inp, "r")) == NULL) {
128 fputs(inp, stderr);
129 fputs(": cannot open\n", stderr);
130 exit(1);
131 }
132 printf("# Begin conversion from: %s\n", inp);
133 while ((c = getc(fp)) != EOF)
134 switch (c) {
135 case ' ': /* white space */
136 case '\t':
137 case '\n':
138 case '\r':
139 case '\f':
140 break;
141 case '#': /* comment */
142 if (fgets(buf, sizeof(buf), fp) != NULL)
143 printf("# %s", buf);
144 break;
145 case '!': /* inline command */
146 ungetc(c, fp);
147 fgetline(buf, sizeof(buf), fp);
148 rad2mgf(buf);
149 break;
150 default: /* Radiance primitive */
151 ungetc(c, fp);
152 if (fscanf(fp, "%s %s %s", mod, typ, id) != 3) {
153 fputs(inp, stderr);
154 fputs(": unexpected EOF\n", stderr);
155 exit(1);
156 }
157 if (!strcmp(typ, "alias")) {
158 strcpy(alias, "EOF");
159 fscanf(fp, "%s", alias);
160 newmat(id, alias);
161 } else {
162 if (!readfargs(&fa, fp)) {
163 fprintf(stderr,
164 "%s: bad argument syntax for %s \"%s\"\n",
165 inp, typ, id);
166 exit(1);
167 }
168 cvtprim(inp, mod, typ, id, &fa);
169 freefargs(&fa);
170 }
171 break;
172 }
173 printf("# End conversion from: %s\n", inp);
174 if (inp[0] == '!')
175 pclose(fp);
176 else
177 fclose(fp);
178 #undef mod
179 #undef typ
180 #undef id
181 #undef alias
182 }
183
184
185 cvtprim(inp, mod, typ, id, fa) /* process Radiance primitive */
186 char *inp, *mod, *typ, *id;
187 FUNARGS *fa;
188 {
189 int (*df)();
190
191 df = (int (*)())lu_find(&rdispatch, typ)->data;
192 if (df != NULL) { /* convert */
193 if ((*df)(mod, typ, id, fa) < 0) {
194 fprintf(stderr, "%s: bad %s \"%s\"\n", typ, id);
195 exit(1);
196 }
197 } else { /* unsupported */
198 o_unsupported(mod, typ, id, fa);
199 if (lu_find(&rmats, mod)->data != NULL) /* make alias */
200 newmat(id, mod);
201 }
202 }
203
204
205 newmat(id, alias) /* add a modifier to the alias list */
206 char *id;
207 char *alias;
208 {
209 register LUENT *lp, *lpa;
210
211 if (alias != NULL) { /* look up alias */
212 if ((lpa = lu_find(&rmats, alias)) == NULL)
213 goto memerr;
214 if (lpa->data == NULL)
215 alias = NULL; /* doesn't exist! */
216 }
217 if ((lp = lu_find(&rmats, id)) == NULL) /* look up material */
218 goto memerr;
219 if (alias != NULL && lp->data == lpa->key)
220 return; /* alias set already */
221 if (lp->data == NULL) { /* allocate material */
222 if ((lp->key = (char *)malloc(strlen(id)+1)) == NULL)
223 goto memerr;
224 strcpy(lp->key, id);
225 }
226 if (alias == NULL) { /* set this material */
227 lp->data = lp->key;
228 printf("m %s =\n", id);
229 } else { /* set this alias */
230 lp->data = lpa->key;
231 printf("m %s = %s\n", id, alias);
232 }
233 strcpy(curmat, id);
234 return;
235 memerr:
236 fputs("Out of memory in newmat!\n", stderr);
237 exit(1);
238 }
239
240
241 setmat(id) /* set material to this one */
242 char *id;
243 {
244 if (!strcmp(id, curmat)) /* already set? */
245 return;
246 if (!strcmp(id, VOIDID)) /* cannot set */
247 return;
248 printf("m %s\n", id);
249 strcpy(curmat, id);
250 }
251
252
253 setobj(id) /* set object name to this one */
254 char *id;
255 {
256 register char *cp, *cp2;
257 char *end = NULL;
258 int diff = 0;
259 /* use all but final suffix */
260 for (cp = id; *cp; cp++)
261 if (*cp == '.')
262 end = cp;
263 if (end == NULL)
264 end = cp;
265 /* copy to current object */
266 for (cp = id, cp2 = curobj; cp < end; *cp2++ = *cp++)
267 diff += *cp != *cp2;
268 if (!diff && !*cp2)
269 return;
270 *cp2 = '\0';
271 fputs("o\no ", stdout);
272 puts(curobj);
273 }
274
275
276 init() /* initialize dispatch table and output */
277 {
278 lu_init(&vertab, NVERTS);
279 lu_init(&rdispatch, 22);
280 add2dispatch("polygon", o_face);
281 add2dispatch("cone", o_cone);
282 add2dispatch("cup", o_cone);
283 add2dispatch("sphere", o_sphere);
284 add2dispatch("bubble", o_sphere);
285 add2dispatch("cylinder", o_cylinder);
286 add2dispatch("tube", o_cylinder);
287 add2dispatch("ring", o_ring);
288 add2dispatch("instance", o_instance);
289 add2dispatch("plastic", o_plastic);
290 add2dispatch("plastic2", o_plastic);
291 add2dispatch("metal", o_metal);
292 add2dispatch("metal2", o_metal);
293 add2dispatch("glass", o_glass);
294 add2dispatch("dielectric", o_dielectric);
295 add2dispatch("trans", o_trans);
296 add2dispatch("trans2", o_trans);
297 add2dispatch("mirror", o_mirror);
298 add2dispatch("light", o_light);
299 add2dispatch("spotlight", o_light);
300 add2dispatch("glow", o_light);
301 add2dispatch("illum", o_illum);
302 puts("# The following was converted from RADIANCE scene input");
303 if (hasmult)
304 printf("xf -s %.4e\n", unit_mult);
305 printf("o %s\n", curobj);
306 }
307
308
309 uninit() /* mark end of MGF file */
310 {
311 puts("o");
312 if (hasmult)
313 puts("xf");
314 puts("# End of data converted from RADIANCE scene input");
315 lu_done(&rdispatch);
316 lu_done(&rmats);
317 lu_done(&vertab);
318 }
319
320
321 clrverts() /* clear vertex table */
322 {
323 register int i;
324
325 lu_done(&vertab);
326 for (i = 0; i < NVERTS; i++)
327 vert[i].lused = 0;
328 lu_init(&vertab, NVERTS);
329 }
330
331
332 add2dispatch(name, func) /* add function to dispatch table */
333 char *name;
334 int (*func)();
335 {
336 register LUENT *lp;
337
338 lp = lu_find(&rdispatch, name);
339 if (lp->key != NULL) {
340 fputs(name, stderr);
341 fputs(": duplicate dispatch entry!\n", stderr);
342 exit(1);
343 }
344 lp->key = name;
345 lp->data = (char *)func;
346 }
347
348
349 char *
350 getvertid(vname, vp) /* get/set vertex ID for this point */
351 char *vname;
352 FVECT vp;
353 {
354 static char vkey[VKLEN];
355 register LUENT *lp;
356 register int i, vndx;
357
358 vclock++; /* increment counter */
359 mkvkey(vkey, vp);
360 if ((lp = lu_find(&vertab, vkey)) == NULL)
361 goto memerr;
362 if (lp->data == NULL) { /* allocate new vertex entry */
363 if (lp->key != NULL) /* reclaim deleted entry */
364 vertab.ndel--;
365 else {
366 if ((lp->key = (char *)malloc(VKLEN)) == NULL)
367 goto memerr;
368 strcpy(lp->key, vkey);
369 }
370 vndx = 0; /* find oldest vertex */
371 for (i = 1; i < NVERTS; i++)
372 if (vert[i].lused < vert[vndx].lused)
373 vndx = i;
374 if (vert[vndx].lused) { /* free old entry first */
375 mkvkey(vkey, vert[vndx].p);
376 lu_delete(&vertab, vkey);
377 }
378 VCOPY(vert[vndx].p, vp); /* assign it */
379 printf("v v%d =\n\tp %.15g %.15g %.15g\n", /* print it */
380 vndx, vp[0], vp[1], vp[2]);
381 lp->data = (char *)&vert[vndx]; /* set it */
382 } else
383 vndx = (struct vert *)lp->data - vert;
384 vert[vndx].lused = vclock; /* record this use */
385 sprintf(vname, "v%d", vndx);
386 return(vname);
387 memerr:
388 fputs("Out of memory in getvertid!\n", stderr);
389 exit(1);
390 }
391
392
393 int
394 o_unsupported(mod, typ, id, fa) /* mark unsupported primitive */
395 char *mod, *typ, *id;
396 FUNARGS *fa;
397 {
398 register int i;
399
400 fputs("\n# Unsupported RADIANCE primitive:\n", stdout);
401 printf("# %s %s %s", mod, typ, id);
402 printf("\n# %d", fa->nsargs);
403 for (i = 0; i < fa->nsargs; i++)
404 printf(" %s", fa->sarg[i]);
405 #ifdef IARGS
406 printf("\n# %d", fa->niargs);
407 for (i = 0; i < fa->niargs; i++)
408 printf(" %ld", fa->iarg[i]);
409 #else
410 fputs("\n# 0", stdout);
411 #endif
412 printf("\n# %d", fa->nfargs);
413 for (i = 0; i < fa->nfargs; i++)
414 printf(" %g", fa->farg[i]);
415 fputs("\n\n", stdout);
416 return(0);
417 }
418
419
420 int
421 o_face(mod, typ, id, fa) /* print out a polygon */
422 char *mod, *typ, *id;
423 FUNARGS *fa;
424 {
425 char entbuf[512];
426 register char *cp;
427 register int i;
428
429 if (fa->nfargs < 9 | fa->nfargs % 3)
430 return(-1);
431 setmat(mod);
432 setobj(id);
433 cp = entbuf;
434 *cp++ = 'f';
435 for (i = 0; i < fa->nfargs; i += 3) {
436 *cp++ = ' ';
437 getvertid(cp, fa->farg + i);
438 while (*cp)
439 cp++;
440 }
441 puts(entbuf);
442 return(0);
443 }
444
445
446 int
447 o_cone(mod, typ, id, fa) /* print out a cone */
448 char *mod, *typ, *id;
449 register FUNARGS *fa;
450 {
451 char v1[6], v2[6];
452
453 if (fa->nfargs != 8)
454 return(-1);
455 setmat(mod);
456 setobj(id);
457 getvertid(v1, fa->farg);
458 getvertid(v2, fa->farg + 3);
459 if (typ[1] == 'u') /* cup -> inverted cone */
460 printf("cone %s %.12g %s %.12g\n",
461 v1, -fa->farg[6], v2, -fa->farg[7]);
462 else
463 printf("cone %s %.12g %s %.12g\n",
464 v1, fa->farg[6], v2, fa->farg[7]);
465 return(0);
466 }
467
468
469 int
470 o_sphere(mod, typ, id, fa) /* print out a sphere */
471 char *mod, *typ, *id;
472 register FUNARGS *fa;
473 {
474 char cent[6];
475
476 if (fa->nfargs != 4)
477 return(-1);
478 setmat(mod);
479 setobj(id);
480 printf("sph %s %.12g\n", getvertid(cent, fa->farg),
481 typ[0]=='b' ? -fa->farg[3] : fa->farg[3]);
482 return(0);
483 }
484
485
486 int
487 o_cylinder(mod, typ, id, fa) /* print out a cylinder */
488 char *mod, *typ, *id;
489 register FUNARGS *fa;
490 {
491 char v1[6], v2[6];
492
493 if (fa->nfargs != 7)
494 return(-1);
495 setmat(mod);
496 setobj(id);
497 getvertid(v1, fa->farg);
498 getvertid(v2, fa->farg + 3);
499 printf("cyl %s %.12g %s\n", v1,
500 typ[0]=='t' ? -fa->farg[6] : fa->farg[6], v2);
501 return(0);
502 }
503
504
505 int
506 o_ring(mod, typ, id, fa) /* print out a ring */
507 char *mod, *typ, *id;
508 register FUNARGS *fa;
509 {
510 if (fa->nfargs != 8)
511 return(-1);
512 setmat(mod);
513 setobj(id);
514 printf("v cent =\n\tp %.12g %.12g %.12g\n",
515 fa->farg[0], fa->farg[1], fa->farg[2]);
516 printf("\tn %.12g %.12g %.12g\n",
517 fa->farg[3], fa->farg[4], fa->farg[5]);
518 if (fa->farg[6] < fa->farg[7])
519 printf("ring cent %.12g %.12g\n",
520 fa->farg[6], fa->farg[7]);
521 else
522 printf("ring cent %.12g %.12g\n",
523 fa->farg[7], fa->farg[6]);
524 return(0);
525 }
526
527
528 int
529 o_instance(mod, typ, id, fa) /* convert an instance */
530 char *mod, *typ, *id;
531 FUNARGS *fa;
532 {
533 register int i;
534 register char *cp;
535 char *start = NULL, *end = NULL;
536 /*
537 * We don't really know how to do this, so we just create
538 * a reference to an undefined MGF file and it's the user's
539 * responsibility to create this file and put the appropriate
540 * stuff into it.
541 */
542 if (fa->nsargs < 1)
543 return(-1);
544 setmat(mod); /* only works if surfaces are void */
545 setobj(id);
546 for (cp = fa->sarg[0]; *cp; cp++) /* construct MGF file name */
547 if (*cp == '/')
548 start = cp+1;
549 else if (*cp == '.')
550 end = cp;
551 if (start == NULL)
552 start = fa->sarg[0];
553 if (end == NULL || start >= end)
554 end = cp;
555 fputs("i ", stdout); /* print include entity */
556 for (cp = start; cp < end; cp++)
557 putchar(*cp);
558 fputs(".mgf", stdout); /* add MGF suffix */
559 for (i = 1; i < fa->nsargs; i++) { /* add transform */
560 putchar(' ');
561 fputs(fa->sarg[i], stdout);
562 }
563 putchar('\n');
564 clrverts(); /* vertex id's no longer reliable */
565 return(0);
566 }
567
568
569 int
570 o_illum(mod, typ, id, fa) /* convert an illum material */
571 char *mod, *typ, *id;
572 FUNARGS *fa;
573 {
574 if (fa->nsargs == 1 && strcmp(fa->sarg[0], VOIDID)) {
575 newmat(id, fa->sarg[0]); /* just create alias */
576 return(0);
577 }
578 /* else create invisible material */
579 newmat(id, NULL);
580 puts("\tts 1 0");
581 return(0);
582 }
583
584
585 int
586 o_plastic(mod, typ, id, fa) /* convert a plastic material */
587 char *mod, *typ, *id;
588 register FUNARGS *fa;
589 {
590 COLOR cxyz, rrgb;
591 double d;
592
593 if (fa->nfargs != (typ[7]=='2' ? 6 : 5))
594 return(-1);
595 newmat(id, NULL);
596 rrgb[0] = fa->farg[0]; rrgb[1] = fa->farg[1]; rrgb[2] = fa->farg[2];
597 rgb_cie(cxyz, rrgb);
598 puts("\tc"); /* put diffuse component */
599 d = cxyz[0] + cxyz[1] + cxyz[2];
600 if (d > FTINY)
601 printf("\t\tcxy %.4f %.4f\n", cxyz[0]/d, cxyz[1]/d);
602 printf("\trd %.4f\n", cxyz[1]*(1. - fa->farg[3]));
603 if (fa->farg[3] > FTINY) { /* put specular component */
604 puts("\tc");
605 printf("\trs %.4f %.4f\n", fa->farg[3],
606 typ[7]=='2' ? .5*(fa->farg[4] + fa->farg[5]) :
607 fa->farg[4]);
608 }
609 return(0);
610 }
611
612
613 int
614 o_metal(mod, typ, id, fa) /* convert a metal material */
615 char *mod, *typ, *id;
616 register FUNARGS *fa;
617 {
618 COLOR cxyz, rrgb;
619 double d;
620
621 if (fa->nfargs != (typ[5]=='2' ? 6 : 5))
622 return(-1);
623 newmat(id, NULL);
624 rrgb[0] = fa->farg[0]; rrgb[1] = fa->farg[1]; rrgb[2] = fa->farg[2];
625 rgb_cie(cxyz, rrgb);
626 puts("\tc"); /* put diffuse component */
627 d = cxyz[0] + cxyz[1] + cxyz[2];
628 if (d > FTINY)
629 printf("\t\tcxy %.4f %.4f\n", cxyz[0]/d, cxyz[1]/d);
630 printf("\trd %.4f\n", cxyz[1]*(1. - fa->farg[3]));
631 /* put specular component */
632 printf("\trs %.4f %.4f\n", cxyz[1]*fa->farg[3],
633 typ[5]=='2' ? .5*(fa->farg[4] + fa->farg[5]) :
634 fa->farg[4]);
635 return(0);
636 }
637
638
639 int
640 o_glass(mod, typ, id, fa) /* convert a glass material */
641 char *mod, *typ, *id;
642 register FUNARGS *fa;
643 {
644 COLOR cxyz, rrgb, trgb;
645 double nrfr = 1.52, F, d;
646 register int i;
647
648 if (fa->nfargs != 3 && fa->nfargs != 4)
649 return(-1);
650 newmat(id, NULL);
651 if (fa->nfargs == 4)
652 nrfr = fa->farg[3];
653 printf("\tir %f 0\n", nrfr);
654 F = (1. - nrfr)/(1. + nrfr); /* use normal incidence */
655 F *= F;
656 for (i = 0; i < 3; i++) {
657 trgb[i] = fa->farg[i] * (1. - F)*(1. - F) /
658 (1. - F*F*fa->farg[i]*fa->farg[i]);
659 rrgb[i] = F * (1. + (1. - 2.*F)*fa->farg[i]) /
660 (1. - F*F*fa->farg[i]*fa->farg[i]);
661 }
662 rgb_cie(cxyz, rrgb); /* put reflected component */
663 puts("\tc");
664 d = cxyz[0] + cxyz[1] + cxyz[2];
665 if (d > FTINY)
666 printf("\t\tcxy %.4f %.4f\n", cxyz[0]/d, cxyz[1]/d);
667 printf("\trs %.4f 0\n", cxyz[1]);
668 rgb_cie(cxyz, trgb); /* put transmitted component */
669 puts("\tc");
670 d = cxyz[0] + cxyz[1] + cxyz[2];
671 if (d > FTINY)
672 printf("\t\tcxy %.4f %.4f\n", cxyz[0]/d, cxyz[1]/d);
673 printf("\tts %.4f 0\n", cxyz[1]);
674 return(0);
675 }
676
677
678 int
679 o_dielectric(mod, typ, id, fa) /* convert a dielectric material */
680 char *mod, *typ, *id;
681 register FUNARGS *fa;
682 {
683 COLOR cxyz, trgb;
684 double F, d;
685 register int i;
686
687 if (fa->nfargs != 5)
688 return(-1);
689 newmat(id, NULL);
690 F = (1. - fa->farg[3])/(1. + fa->farg[3]); /* normal incidence */
691 F *= F;
692 for (i = 0; i < 3; i++)
693 trgb[i] = (1. - F)*pow(fa->farg[i], C_1SIDEDTHICK/unit_mult);
694 printf("\tir %f 0\n", fa->farg[3]); /* put index of refraction */
695 printf("\tsides 1\n");
696 puts("\tc"); /* put reflected component */
697 printf("\trs %.4f 0\n", F);
698 rgb_cie(cxyz, trgb); /* put transmitted component */
699 puts("\tc");
700 d = cxyz[0] + cxyz[1] + cxyz[2];
701 if (d > FTINY)
702 printf("\t\tcxy %.4f %.4f\n", cxyz[0]/d, cxyz[1]/d);
703 printf("\tts %.4f 0\n", cxyz[1]);
704 return(0);
705 }
706
707
708 int
709 o_mirror(mod, typ, id, fa) /* convert a mirror material */
710 char *mod, *typ, *id;
711 register FUNARGS *fa;
712 {
713 COLOR cxyz, rrgb;
714 double d;
715
716 if (fa->nsargs == 1) { /* use alternate material */
717 newmat(id, fa->sarg[0]);
718 return(0);
719 }
720 if (fa->nfargs != 3)
721 return(-1);
722 newmat(id, NULL);
723 rrgb[0] = fa->farg[0]; rrgb[1] = fa->farg[1]; rrgb[2] = fa->farg[2];
724 rgb_cie(cxyz, rrgb);
725 puts("\tc"); /* put specular component */
726 d = cxyz[0] + cxyz[1] + cxyz[2];
727 if (d > FTINY)
728 printf("\t\tcxy %.4f %.4f\n", cxyz[0]/d, cxyz[1]/d);
729 printf("\trs %.4f 0\n", cxyz[1]);
730 return(0);
731 }
732
733
734 int
735 o_trans(mod, typ, id, fa) /* convert a trans material */
736 char *mod, *typ, *id;
737 register FUNARGS *fa;
738 {
739 COLOR cxyz, rrgb;
740 double rough, trans, tspec, d;
741
742 if (typ[4] == '2') { /* trans2 */
743 if (fa->nfargs != 8)
744 return(-1);
745 rough = .5*(fa->farg[4] + fa->farg[5]);
746 trans = fa->farg[6];
747 tspec = fa->farg[7];
748 } else { /* trans */
749 if (fa->nfargs != 7)
750 return(-1);
751 rough = fa->farg[4];
752 trans = fa->farg[5];
753 tspec = fa->farg[6];
754 }
755 newmat(id, NULL);
756 rrgb[0] = fa->farg[0]; rrgb[1] = fa->farg[1]; rrgb[2] = fa->farg[2];
757 rgb_cie(cxyz, rrgb);
758 puts("\tc"); /* put transmitted diffuse */
759 d = cxyz[0] + cxyz[1] + cxyz[2];
760 if (d > FTINY)
761 printf("\t\tcxy %.4f %.4f\n", cxyz[0]/d, cxyz[1]/d);
762 printf("\ttd %.4f\n", cxyz[1]*trans*(1. - fa->farg[3])*(1. - tspec));
763 /* put transmitted specular */
764 printf("\tts %.4f %.4f\n", cxyz[1]*trans*tspec*(1. - fa->farg[3]), rough);
765 /* put reflected diffuse */
766 printf("\trd %.4f\n", cxyz[1]*(1. - fa->farg[3])*(1. - trans));
767 puts("\tc"); /* put reflected specular */
768 printf("\trs %.4f %.4f\n", fa->farg[3], rough);
769 return(0);
770 }
771
772
773 int
774 o_light(mod, typ, id, fa) /* convert a light type */
775 char *mod, *typ, *id;
776 register FUNARGS *fa;
777 {
778 COLOR cxyz, rrgb;
779 double d;
780
781 if (fa->nfargs < 3)
782 return(-1);
783 newmat(id, NULL);
784 rrgb[0] = fa->farg[0]; rrgb[1] = fa->farg[1]; rrgb[2] = fa->farg[2];
785 rgb_cie(cxyz, rrgb);
786 d = cxyz[0] + cxyz[1] + cxyz[2];
787 puts("\tc");
788 if (d > FTINY)
789 printf("\t\tcxy %.4f %.4f\n", cxyz[0]/d, cxyz[1]/d);
790 printf("\ted %.4g\n", cxyz[1]*(PI*WHTEFFICACY));
791 return(0);
792 }