ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/cv/rad2mgf.c
Revision: 2.10
Committed: Thu Apr 13 14:43:30 1995 UTC (28 years, 11 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.9: +37 -1 lines
Log Message:
added MGF index of refraction (ir) and dielectric support

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_source(), 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 if (lu_find(&rmats, mod)->data != NULL) /* make alias */
198 newmat(id, mod);
199 }
200
201
202 newmat(id, alias) /* add a modifier to the alias list */
203 char *id;
204 char *alias;
205 {
206 register LUENT *lp, *lpa;
207
208 if (alias != NULL) { /* look up alias */
209 if ((lpa = lu_find(&rmats, alias)) == NULL)
210 goto memerr;
211 if (lpa->data == NULL)
212 alias = NULL; /* doesn't exist! */
213 }
214 if ((lp = lu_find(&rmats, id)) == NULL) /* look up material */
215 goto memerr;
216 if (alias != NULL && lp->data == lpa->key)
217 return; /* alias set already */
218 if (lp->data == NULL) { /* allocate material */
219 if ((lp->key = (char *)malloc(strlen(id)+1)) == NULL)
220 goto memerr;
221 strcpy(lp->key, id);
222 }
223 if (alias == NULL) { /* set this material */
224 lp->data = lp->key;
225 printf("m %s =\n", id);
226 } else { /* set this alias */
227 lp->data = lpa->key;
228 printf("m %s = %s\n", id, alias);
229 }
230 strcpy(curmat, id);
231 return;
232 memerr:
233 fputs("Out of memory in newmat!\n", stderr);
234 exit(1);
235 }
236
237
238 setmat(id) /* set material to this one */
239 char *id;
240 {
241 if (!strcmp(id, curmat)) /* already set? */
242 return;
243 if (!strcmp(id, VOIDID)) /* cannot set */
244 return;
245 printf("m %s\n", id);
246 strcpy(curmat, id);
247 }
248
249
250 setobj(id) /* set object name to this one */
251 char *id;
252 {
253 register char *cp, *cp2;
254 char *end = NULL;
255 int diff = 0;
256 /* use all but final suffix */
257 for (cp = id; *cp; cp++)
258 if (*cp == '.')
259 end = cp;
260 if (end == NULL)
261 end = cp;
262 /* copy to current object */
263 for (cp = id, cp2 = curobj; cp < end; *cp2++ = *cp++)
264 diff += *cp != *cp2;
265 if (!diff && !*cp2)
266 return;
267 *cp2 = '\0';
268 fputs("o\no ", stdout);
269 puts(curobj);
270 }
271
272
273 init() /* initialize dispatch table and output */
274 {
275 lu_init(&vertab, NVERTS);
276 lu_init(&rdispatch, 22);
277 add2dispatch("polygon", o_face);
278 add2dispatch("cone", o_cone);
279 add2dispatch("cup", o_cone);
280 add2dispatch("sphere", o_sphere);
281 add2dispatch("bubble", o_sphere);
282 add2dispatch("cylinder", o_cylinder);
283 add2dispatch("tube", o_cylinder);
284 add2dispatch("ring", o_ring);
285 add2dispatch("instance", o_instance);
286 add2dispatch("plastic", o_plastic);
287 add2dispatch("plastic2", o_plastic);
288 add2dispatch("metal", o_metal);
289 add2dispatch("metal2", o_metal);
290 add2dispatch("glass", o_glass);
291 add2dispatch("dielectric", o_dielectric);
292 add2dispatch("trans", o_trans);
293 add2dispatch("trans2", o_trans);
294 add2dispatch("mirror", o_mirror);
295 add2dispatch("light", o_light);
296 add2dispatch("spotlight", o_light);
297 add2dispatch("glow", o_light);
298 add2dispatch("illum", o_illum);
299 puts("# The following was converted from Radiance scene input");
300 if (hasmult)
301 printf("xf -s %.4e\n", unit_mult);
302 printf("o %s\n", curobj);
303 }
304
305
306 uninit() /* mark end of MGF file */
307 {
308 puts("o");
309 if (hasmult)
310 puts("xf");
311 puts("# End of data converted from Radiance scene input");
312 lu_done(&rdispatch);
313 lu_done(&rmats);
314 lu_done(&vertab);
315 }
316
317
318 clrverts() /* clear vertex table */
319 {
320 register int i;
321
322 lu_done(&vertab);
323 for (i = 0; i < NVERTS; i++)
324 vert[i].lused = 0;
325 lu_init(&vertab, NVERTS);
326 }
327
328
329 add2dispatch(name, func) /* add function to dispatch table */
330 char *name;
331 int (*func)();
332 {
333 register LUENT *lp;
334
335 lp = lu_find(&rdispatch, name);
336 if (lp->key != NULL) {
337 fputs(name, stderr);
338 fputs(": duplicate dispatch entry!\n", stderr);
339 exit(1);
340 }
341 lp->key = name;
342 lp->data = (char *)func;
343 }
344
345
346 char *
347 getvertid(vname, vp) /* get/set vertex ID for this point */
348 char *vname;
349 FVECT vp;
350 {
351 static char vkey[VKLEN];
352 register LUENT *lp;
353 register int i, vndx;
354
355 vclock++; /* increment counter */
356 mkvkey(vkey, vp);
357 if ((lp = lu_find(&vertab, vkey)) == NULL)
358 goto memerr;
359 if (lp->data == NULL) { /* allocate new vertex entry */
360 if (lp->key != NULL) /* reclaim deleted entry */
361 vertab.ndel--;
362 else {
363 if ((lp->key = (char *)malloc(VKLEN)) == NULL)
364 goto memerr;
365 strcpy(lp->key, vkey);
366 }
367 vndx = 0; /* find oldest vertex */
368 for (i = 1; i < NVERTS; i++)
369 if (vert[i].lused < vert[vndx].lused)
370 vndx = i;
371 if (vert[vndx].lused) { /* free old entry first */
372 mkvkey(vkey, vert[vndx].p);
373 lu_delete(&vertab, vkey);
374 }
375 VCOPY(vert[vndx].p, vp); /* assign it */
376 printf("v v%d =\n\tp %.15g %.15g %.15g\n", /* print it */
377 vndx, vp[0], vp[1], vp[2]);
378 lp->data = (char *)&vert[vndx]; /* set it */
379 } else
380 vndx = (struct vert *)lp->data - vert;
381 vert[vndx].lused = vclock; /* record this use */
382 sprintf(vname, "v%d", vndx);
383 return(vname);
384 memerr:
385 fputs("Out of memory in getvertid!\n", stderr);
386 exit(1);
387 }
388
389
390 int
391 o_face(mod, typ, id, fa) /* print out a polygon */
392 char *mod, *typ, *id;
393 FUNARGS *fa;
394 {
395 char entbuf[512];
396 register char *cp;
397 register int i;
398
399 if (fa->nfargs < 9 | fa->nfargs % 3)
400 return(-1);
401 setmat(mod);
402 setobj(id);
403 cp = entbuf;
404 *cp++ = 'f';
405 for (i = 0; i < fa->nfargs; i += 3) {
406 *cp++ = ' ';
407 getvertid(cp, fa->farg + i);
408 while (*cp)
409 cp++;
410 }
411 puts(entbuf);
412 return(0);
413 }
414
415
416 int
417 o_cone(mod, typ, id, fa) /* print out a cone */
418 char *mod, *typ, *id;
419 register FUNARGS *fa;
420 {
421 char v1[6], v2[6];
422
423 if (fa->nfargs != 8)
424 return(-1);
425 setmat(mod);
426 setobj(id);
427 getvertid(v1, fa->farg);
428 getvertid(v2, fa->farg + 3);
429 if (typ[1] == 'u') /* cup -> inverted cone */
430 printf("cone %s %.12g %s %.12g\n",
431 v1, -fa->farg[6], v2, -fa->farg[7]);
432 else
433 printf("cone %s %.12g %s %.12g\n",
434 v1, fa->farg[6], v2, fa->farg[7]);
435 return(0);
436 }
437
438
439 int
440 o_sphere(mod, typ, id, fa) /* print out a sphere */
441 char *mod, *typ, *id;
442 register FUNARGS *fa;
443 {
444 char cent[6];
445
446 if (fa->nfargs != 4)
447 return(-1);
448 setmat(mod);
449 setobj(id);
450 printf("sph %s %.12g\n", getvertid(cent, fa->farg),
451 typ[0]=='b' ? -fa->farg[3] : fa->farg[3]);
452 return(0);
453 }
454
455
456 int
457 o_cylinder(mod, typ, id, fa) /* print out a cylinder */
458 char *mod, *typ, *id;
459 register FUNARGS *fa;
460 {
461 char v1[6], v2[6];
462
463 if (fa->nfargs != 7)
464 return(-1);
465 setmat(mod);
466 setobj(id);
467 getvertid(v1, fa->farg);
468 getvertid(v2, fa->farg + 3);
469 printf("cyl %s %.12g %s\n", v1,
470 typ[0]=='t' ? -fa->farg[6] : fa->farg[6], v2);
471 return(0);
472 }
473
474
475 int
476 o_ring(mod, typ, id, fa) /* print out a ring */
477 char *mod, *typ, *id;
478 register FUNARGS *fa;
479 {
480 if (fa->nfargs != 8)
481 return(-1);
482 setmat(mod);
483 setobj(id);
484 printf("v cent =\n\tp %.12g %.12g %.12g\n",
485 fa->farg[0], fa->farg[1], fa->farg[2]);
486 printf("\tn %.12g %.12g %.12g\n",
487 fa->farg[3], fa->farg[4], fa->farg[5]);
488 if (fa->farg[6] < fa->farg[7])
489 printf("ring cent %.12g %.12g\n",
490 fa->farg[6], fa->farg[7]);
491 else
492 printf("ring cent %.12g %.12g\n",
493 fa->farg[7], fa->farg[6]);
494 return(0);
495 }
496
497
498 int
499 o_instance(mod, typ, id, fa) /* convert an instance */
500 char *mod, *typ, *id;
501 FUNARGS *fa;
502 {
503 register int i;
504 register char *cp;
505 char *start = NULL, *end = NULL;
506 /*
507 * We don't really know how to do this, so we just create
508 * a reference to an undefined MGF file and it's the user's
509 * responsibility to create this file and put the appropriate
510 * stuff into it.
511 */
512 if (fa->nsargs < 1)
513 return(-1);
514 setmat(mod); /* only works if surfaces are void */
515 setobj(id);
516 for (cp = fa->sarg[0]; *cp; cp++) /* construct MGF file name */
517 if (*cp == '/')
518 start = cp+1;
519 else if (*cp == '.')
520 end = cp;
521 if (start == NULL)
522 start = fa->sarg[0];
523 if (end == NULL || start >= end)
524 end = cp;
525 fputs("i ", stdout); /* print include entity */
526 for (cp = start; cp < end; cp++)
527 putchar(*cp);
528 fputs(".mgf", stdout); /* add MGF suffix */
529 for (i = 1; i < fa->nsargs; i++) { /* add transform */
530 putchar(' ');
531 fputs(fa->sarg[i], stdout);
532 }
533 putchar('\n');
534 clrverts(); /* vertex id's no longer reliable */
535 return(0);
536 }
537
538
539 int
540 o_source(mod, typ, id, fa) /* convert a source */
541 char *mod, *typ, *id;
542 FUNARGS *fa;
543 {
544 return(0); /* there is no MGF equivalent! */
545 }
546
547
548 int
549 o_illum(mod, typ, id, fa) /* convert an illum material */
550 char *mod, *typ, *id;
551 FUNARGS *fa;
552 {
553 if (fa->nsargs == 1 && strcmp(fa->sarg[0], VOIDID)) {
554 newmat(id, fa->sarg[0]); /* just create alias */
555 return(0);
556 }
557 /* else create invisible material */
558 newmat(id, NULL);
559 puts("\tts 1 0");
560 return(0);
561 }
562
563
564 int
565 o_plastic(mod, typ, id, fa) /* convert a plastic material */
566 char *mod, *typ, *id;
567 register FUNARGS *fa;
568 {
569 COLOR cxyz, rrgb;
570 double d;
571
572 if (fa->nfargs != (typ[7]=='2' ? 6 : 5))
573 return(-1);
574 newmat(id, NULL);
575 rrgb[0] = fa->farg[0]; rrgb[1] = fa->farg[1]; rrgb[2] = fa->farg[2];
576 rgb_cie(cxyz, rrgb);
577 puts("\tc"); /* put diffuse component */
578 d = cxyz[0] + cxyz[1] + cxyz[2];
579 if (d > FTINY)
580 printf("\t\tcxy %.4f %.4f\n", cxyz[0]/d, cxyz[1]/d);
581 printf("\trd %.4f\n", cxyz[1]*(1. - fa->farg[3]));
582 if (fa->farg[3] > FTINY) { /* put specular component */
583 puts("\tc");
584 printf("\trs %.4f %.4f\n", fa->farg[3],
585 typ[7]=='2' ? .5*(fa->farg[4] + fa->farg[5]) :
586 fa->farg[4]);
587 }
588 return(0);
589 }
590
591
592 int
593 o_metal(mod, typ, id, fa) /* convert a metal material */
594 char *mod, *typ, *id;
595 register FUNARGS *fa;
596 {
597 COLOR cxyz, rrgb;
598 double d;
599
600 if (fa->nfargs != (typ[5]=='2' ? 6 : 5))
601 return(-1);
602 newmat(id, NULL);
603 rrgb[0] = fa->farg[0]; rrgb[1] = fa->farg[1]; rrgb[2] = fa->farg[2];
604 rgb_cie(cxyz, rrgb);
605 puts("\tc"); /* put diffuse component */
606 d = cxyz[0] + cxyz[1] + cxyz[2];
607 if (d > FTINY)
608 printf("\t\tcxy %.4f %.4f\n", cxyz[0]/d, cxyz[1]/d);
609 printf("\trd %.4f\n", cxyz[1]*(1. - fa->farg[3]));
610 /* put specular component */
611 printf("\trs %.4f %.4f\n", cxyz[1]*fa->farg[3],
612 typ[5]=='2' ? .5*(fa->farg[4] + fa->farg[5]) :
613 fa->farg[4]);
614 return(0);
615 }
616
617
618 int
619 o_glass(mod, typ, id, fa) /* convert a glass material */
620 char *mod, *typ, *id;
621 register FUNARGS *fa;
622 {
623 COLOR cxyz, rrgb, trgb;
624 double nrfr = 1.52, F, d;
625 register int i;
626
627 if (fa->nfargs != 3 && fa->nfargs != 4)
628 return(-1);
629 newmat(id, NULL);
630 if (fa->nfargs == 4)
631 nrfr = fa->farg[3];
632 printf("\tir %f 0\n", nrfr);
633 F = (1. - nrfr)/(1. + nrfr); /* use normal incidence */
634 F *= F;
635 for (i = 0; i < 3; i++) {
636 trgb[i] = fa->farg[i] * (1. - F)*(1. - F) /
637 (1. - F*F*fa->farg[i]*fa->farg[i]);
638 rrgb[i] = F * (1. + (1. - 2.*F)*fa->farg[i]) /
639 (1. - F*F*fa->farg[i]*fa->farg[i]);
640 }
641 rgb_cie(cxyz, rrgb); /* put reflected component */
642 puts("\tc");
643 d = cxyz[0] + cxyz[1] + cxyz[2];
644 if (d > FTINY)
645 printf("\t\tcxy %.4f %.4f\n", cxyz[0]/d, cxyz[1]/d);
646 printf("\trs %.4f 0\n", cxyz[1]);
647 rgb_cie(cxyz, trgb); /* put transmitted component */
648 puts("\tc");
649 d = cxyz[0] + cxyz[1] + cxyz[2];
650 if (d > FTINY)
651 printf("\t\tcxy %.4f %.4f\n", cxyz[0]/d, cxyz[1]/d);
652 printf("\tts %.4f 0\n", cxyz[1]);
653 return(0);
654 }
655
656
657 int
658 o_dielectric(mod, typ, id, fa) /* convert a dielectric material */
659 char *mod, *typ, *id;
660 register FUNARGS *fa;
661 {
662 COLOR cxyz, trgb;
663 double F, d;
664 register int i;
665
666 if (fa->nfargs != 5)
667 return(-1);
668 newmat(id, NULL);
669 F = (1. - fa->farg[3])/(1. + fa->farg[3]); /* normal incidence */
670 F *= F;
671 for (i = 0; i < 3; i++)
672 trgb[i] = (1. - F)*pow(fa->farg[i], C_1SIDEDTHICK/unit_mult);
673 printf("\tir %f 0\n", fa->farg[3]); /* put index of refraction */
674 printf("\tsides 1\n");
675 puts("\tc"); /* put reflected component */
676 printf("\trs %.4f 0\n", F);
677 rgb_cie(cxyz, trgb); /* put transmitted component */
678 puts("\tc");
679 d = cxyz[0] + cxyz[1] + cxyz[2];
680 if (d > FTINY)
681 printf("\t\tcxy %.4f %.4f\n", cxyz[0]/d, cxyz[1]/d);
682 printf("\tts %.4f 0\n", cxyz[1]);
683 return(0);
684 }
685
686
687 int
688 o_mirror(mod, typ, id, fa) /* convert a mirror material */
689 char *mod, *typ, *id;
690 register FUNARGS *fa;
691 {
692 COLOR cxyz, rrgb;
693 double d;
694
695 if (fa->nsargs == 1) { /* use alternate material */
696 newmat(id, fa->sarg[0]);
697 return(0);
698 }
699 if (fa->nfargs != 3)
700 return(-1);
701 newmat(id, NULL);
702 rrgb[0] = fa->farg[0]; rrgb[1] = fa->farg[1]; rrgb[2] = fa->farg[2];
703 rgb_cie(cxyz, rrgb);
704 puts("\tc"); /* put specular component */
705 d = cxyz[0] + cxyz[1] + cxyz[2];
706 if (d > FTINY)
707 printf("\t\tcxy %.4f %.4f\n", cxyz[0]/d, cxyz[1]/d);
708 printf("\trs %.4f 0\n", cxyz[1]);
709 return(0);
710 }
711
712
713 int
714 o_trans(mod, typ, id, fa) /* convert a trans material */
715 char *mod, *typ, *id;
716 register FUNARGS *fa;
717 {
718 COLOR cxyz, rrgb;
719 double rough, trans, tspec, d;
720
721 if (typ[4] == '2') { /* trans2 */
722 if (fa->nfargs != 8)
723 return(-1);
724 rough = .5*(fa->farg[4] + fa->farg[5]);
725 trans = fa->farg[6];
726 tspec = fa->farg[7];
727 } else { /* trans */
728 if (fa->nfargs != 7)
729 return(-1);
730 rough = fa->farg[4];
731 trans = fa->farg[5];
732 tspec = fa->farg[6];
733 }
734 newmat(id, NULL);
735 rrgb[0] = fa->farg[0]; rrgb[1] = fa->farg[1]; rrgb[2] = fa->farg[2];
736 rgb_cie(cxyz, rrgb);
737 puts("\tc"); /* put transmitted diffuse */
738 d = cxyz[0] + cxyz[1] + cxyz[2];
739 if (d > FTINY)
740 printf("\t\tcxy %.4f %.4f\n", cxyz[0]/d, cxyz[1]/d);
741 printf("\ttd %.4f\n", cxyz[1]*trans*(1. - fa->farg[3])*(1. - tspec));
742 /* put transmitted specular */
743 printf("\tts %.4f %.4f\n", cxyz[1]*trans*tspec*(1. - fa->farg[3]), rough);
744 /* put reflected diffuse */
745 printf("\trd %.4f\n", cxyz[1]*(1. - fa->farg[3])*(1. - trans));
746 puts("\tc"); /* put reflected specular */
747 printf("\trs %.4f %.4f\n", fa->farg[3], rough);
748 return(0);
749 }
750
751
752 int
753 o_light(mod, typ, id, fa) /* convert a light type */
754 char *mod, *typ, *id;
755 register FUNARGS *fa;
756 {
757 COLOR cxyz, rrgb;
758 double d;
759
760 if (fa->nfargs < 3)
761 return(-1);
762 newmat(id, NULL);
763 rrgb[0] = fa->farg[0]; rrgb[1] = fa->farg[1]; rrgb[2] = fa->farg[2];
764 rgb_cie(cxyz, rrgb);
765 d = cxyz[0] + cxyz[1] + cxyz[2];
766 puts("\tc");
767 if (d > FTINY)
768 printf("\t\tcxy %.4f %.4f\n", cxyz[0]/d, cxyz[1]/d);
769 printf("\ted %.4g\n", cxyz[1]*(PI*WHTEFFICACY));
770 return(0);
771 }