ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/px/pinterp.c
Revision: 1.31
Committed: Fri Dec 21 17:20:07 1990 UTC (33 years, 4 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 1.30: +0 -1 lines
Log Message:
minor compiler complaints

File Contents

# Content
1 #ifndef lint
2 static char SCCSid[] = "$SunId$ LBL";
3 #endif
4
5 /*
6 * Interpolate and extrapolate pictures with different view parameters.
7 *
8 * Greg Ward 09Dec89
9 */
10
11 #include "standard.h"
12
13 #include <fcntl.h>
14
15 #include "view.h"
16
17 #include "color.h"
18
19 #ifndef BSD
20 #define vfork fork
21 #endif
22
23 #define pscan(y) (ourpict+(y)*hresolu)
24 #define zscan(y) (ourzbuf+(y)*hresolu)
25
26 #define F_FORE 1 /* fill foreground */
27 #define F_BACK 2 /* fill background */
28
29 #define PACKSIZ 42 /* calculation packet size */
30
31 #define RTCOM "rtrace -h -ovl -fff %s"
32
33 #define ABS(x) ((x)>0?(x):-(x))
34
35 struct position {int x,y; float z;};
36
37 VIEW ourview = STDVIEW; /* desired view */
38 int hresolu = 512; /* horizontal resolution */
39 int vresolu = 512; /* vertical resolution */
40 double pixaspect = 1.0; /* pixel aspect ratio */
41
42 double zeps = .02; /* allowed z epsilon */
43
44 COLR *ourpict; /* output picture */
45 float *ourzbuf; /* corresponding z-buffer */
46
47 char *progname;
48
49 int fillo = F_FORE|F_BACK; /* selected fill options */
50 int fillsamp = 0; /* sample separation (0 == inf) */
51 extern int backfill(), rcalfill(); /* fill functions */
52 int (*fillfunc)() = backfill; /* selected fill function */
53 COLR backcolr = BLKCOLR; /* background color */
54 double backz = 0.0; /* background z value */
55 int normdist = 1; /* normalized distance? */
56 double ourexp = -1; /* output picture exposure */
57
58 VIEW theirview = STDVIEW; /* input view */
59 int gotview; /* got input view? */
60 int thresolu, tvresolu; /* input resolution */
61 double theirexp; /* input picture exposure */
62 double theirs2ours[4][4]; /* transformation matrix */
63 int hasmatrix = 0; /* has transformation matrix */
64
65 int childpid = -1; /* id of fill process */
66 FILE *psend, *precv; /* pipes to/from fill calculation */
67 int queue[PACKSIZ][2]; /* pending pixels */
68 int queuesiz; /* number of pixels pending */
69
70
71 main(argc, argv) /* interpolate pictures */
72 int argc;
73 char *argv[];
74 {
75 #define check(olen,narg) if (argv[i][olen] || narg >= argc-i) goto badopt
76 extern double atof();
77 int gotvfile = 0;
78 char *zfile = NULL;
79 char *err;
80 int i, rval;
81
82 progname = argv[0];
83
84 for (i = 1; i < argc && argv[i][0] == '-'; i++) {
85 rval = getviewopt(&ourview, argc-i, argv+i);
86 if (rval >= 0) {
87 i += rval;
88 continue;
89 }
90 switch (argv[i][1]) {
91 case 't': /* threshold */
92 check(2,1);
93 zeps = atof(argv[++i]);
94 break;
95 case 'n': /* dist. normalized? */
96 check(2,0);
97 normdist = !normdist;
98 break;
99 case 'f': /* fill type */
100 switch (argv[i][2]) {
101 case '0': /* none */
102 check(3,0);
103 fillo = 0;
104 break;
105 case 'f': /* foreground */
106 check(3,0);
107 fillo = F_FORE;
108 break;
109 case 'b': /* background */
110 check(3,0);
111 fillo = F_BACK;
112 break;
113 case 'a': /* all */
114 check(3,0);
115 fillo = F_FORE|F_BACK;
116 break;
117 case 's': /* sample */
118 check(3,1);
119 fillsamp = atoi(argv[++i]);
120 break;
121 case 'c': /* color */
122 check(3,3);
123 fillfunc = backfill;
124 setcolr(backcolr, atof(argv[i+1]),
125 atof(argv[i+2]), atof(argv[i+3]));
126 i += 3;
127 break;
128 case 'z': /* z value */
129 check(3,1);
130 fillfunc = backfill;
131 backz = atof(argv[++i]);
132 break;
133 case 'r': /* rtrace */
134 check(3,1);
135 fillfunc = rcalfill;
136 calstart(RTCOM, argv[++i]);
137 break;
138 default:
139 goto badopt;
140 }
141 break;
142 case 'z': /* z file */
143 check(2,1);
144 zfile = argv[++i];
145 break;
146 case 'x': /* x resolution */
147 check(2,1);
148 hresolu = atoi(argv[++i]);
149 break;
150 case 'y': /* y resolution */
151 check(2,1);
152 vresolu = atoi(argv[++i]);
153 break;
154 case 'p': /* pixel aspect */
155 check(2,1);
156 pixaspect = atof(argv[++i]);
157 break;
158 case 'v': /* view file */
159 if (argv[i][2] != 'f')
160 goto badopt;
161 check(3,1);
162 gotvfile = viewfile(argv[++i], &ourview, 0, 0);
163 if (gotvfile < 0) {
164 perror(argv[i]);
165 exit(1);
166 } else if (gotvfile == 0) {
167 fprintf(stderr, "%s: bad view file\n",
168 argv[i]);
169 exit(1);
170 }
171 break;
172 default:
173 badopt:
174 fprintf(stderr, "%s: command line error at '%s'\n",
175 progname, argv[i]);
176 goto userr;
177 }
178 }
179 /* check arguments */
180 if ((argc-i)%2)
181 goto userr;
182 /* set view */
183 if (err = setview(&ourview)) {
184 fprintf(stderr, "%s: %s\n", progname, err);
185 exit(1);
186 }
187 normaspect(viewaspect(&ourview), &pixaspect, &hresolu, &vresolu);
188 /* allocate frame */
189 ourpict = (COLR *)malloc(hresolu*vresolu*sizeof(COLR));
190 ourzbuf = (float *)calloc(hresolu*vresolu,sizeof(float));
191 if (ourpict == NULL || ourzbuf == NULL)
192 syserror();
193 /* get input */
194 for ( ; i < argc; i += 2)
195 addpicture(argv[i], argv[i+1]);
196 /* fill in spaces */
197 if (fillo&F_BACK)
198 backpicture(fillfunc, fillsamp);
199 else
200 fillpicture(fillfunc);
201 /* close calculation */
202 caldone();
203 /* add to header */
204 printargs(argc, argv, stdout);
205 if (gotvfile) {
206 fputs(VIEWSTR, stdout);
207 fprintview(&ourview, stdout);
208 putc('\n', stdout);
209 }
210 if (pixaspect < .99 || pixaspect > 1.01)
211 fputaspect(pixaspect, stdout);
212 if (ourexp > 0 && (ourexp < .995 || ourexp > 1.005))
213 fputexpos(ourexp, stdout);
214 putc('\n', stdout);
215 /* write picture */
216 writepicture();
217 /* write z file */
218 if (zfile != NULL)
219 writedistance(zfile);
220
221 exit(0);
222 userr:
223 fprintf(stderr,
224 "Usage: %s [view opts][-t eps][-z zout][-fT][-n] pfile zspec ..\n",
225 progname);
226 exit(1);
227 #undef check
228 }
229
230
231 headline(s) /* process header string */
232 char *s;
233 {
234 static char *altname[] = {VIEWSTR,"rpict","rview","pinterp",NULL};
235 register char **an;
236
237 putc('\t', stdout);
238 fputs(s, stdout);
239
240 if (isexpos(s)) {
241 theirexp *= exposval(s);
242 return;
243 }
244 for (an = altname; *an != NULL; an++)
245 if (!strncmp(*an, s, strlen(*an))) {
246 if (sscanview(&theirview, s+strlen(*an)) > 0)
247 gotview++;
248 break;
249 }
250 }
251
252
253 addpicture(pfile, zspec) /* add picture to output */
254 char *pfile, *zspec;
255 {
256 extern double atof();
257 FILE *pfp;
258 int zfd;
259 char *err;
260 COLR *scanin;
261 float *zin;
262 struct position *plast;
263 int y;
264 /* open picture file */
265 if ((pfp = fopen(pfile, "r")) == NULL) {
266 perror(pfile);
267 exit(1);
268 }
269 /* get header with exposure and view */
270 theirexp = 1.0;
271 gotview = 0;
272 printf("%s:\n", pfile);
273 getheader(pfp, headline);
274 if (!gotview || fgetresolu(&thresolu, &tvresolu, pfp)
275 != (YMAJOR|YDECR)) {
276 fprintf(stderr, "%s: picture view error\n", pfile);
277 exit(1);
278 }
279 if (ourexp <= 0)
280 ourexp = theirexp;
281 else if (ABS(theirexp-ourexp) > .01*ourexp)
282 fprintf(stderr, "%s: different exposure (warning)\n", pfile);
283 if (err = setview(&theirview)) {
284 fprintf(stderr, "%s: %s\n", pfile, err);
285 exit(1);
286 }
287 /* compute transformation */
288 hasmatrix = pixform(theirs2ours, &theirview, &ourview);
289 /* allocate scanlines */
290 scanin = (COLR *)malloc(thresolu*sizeof(COLR));
291 zin = (float *)malloc(thresolu*sizeof(float));
292 plast = (struct position *)calloc(thresolu, sizeof(struct position));
293 if (scanin == NULL || zin == NULL || plast == NULL)
294 syserror();
295 /* get z specification or file */
296 if ((zfd = open(zspec, O_RDONLY)) == -1) {
297 double zvalue;
298 register int x;
299 if (!isfloat(zspec) || (zvalue = atof(zspec)) <= 0.0) {
300 perror(zspec);
301 exit(1);
302 }
303 for (x = 0; x < thresolu; x++)
304 zin[x] = zvalue;
305 }
306 /* load image */
307 for (y = tvresolu-1; y >= 0; y--) {
308 if (freadcolrs(scanin, thresolu, pfp) < 0) {
309 fprintf(stderr, "%s: read error\n", pfile);
310 exit(1);
311 }
312 if (zfd != -1 && read(zfd,(char *)zin,thresolu*sizeof(float))
313 < thresolu*sizeof(float)) {
314 fprintf(stderr, "%s: read error\n", zspec);
315 exit(1);
316 }
317 addscanline(y, scanin, zin, plast);
318 }
319 /* clean up */
320 free((char *)scanin);
321 free((char *)zin);
322 free((char *)plast);
323 fclose(pfp);
324 if (zfd != -1)
325 close(zfd);
326 }
327
328
329 pixform(xfmat, vw1, vw2) /* compute view1 to view2 matrix */
330 register double xfmat[4][4];
331 register VIEW *vw1, *vw2;
332 {
333 double m4t[4][4];
334
335 if (vw1->type != VT_PER && vw1->type != VT_PAR)
336 return(0);
337 if (vw2->type != VT_PER && vw2->type != VT_PAR)
338 return(0);
339 setident4(xfmat);
340 xfmat[0][0] = vw1->hvec[0];
341 xfmat[0][1] = vw1->hvec[1];
342 xfmat[0][2] = vw1->hvec[2];
343 xfmat[1][0] = vw1->vvec[0];
344 xfmat[1][1] = vw1->vvec[1];
345 xfmat[1][2] = vw1->vvec[2];
346 xfmat[2][0] = vw1->vdir[0];
347 xfmat[2][1] = vw1->vdir[1];
348 xfmat[2][2] = vw1->vdir[2];
349 xfmat[3][0] = vw1->vp[0];
350 xfmat[3][1] = vw1->vp[1];
351 xfmat[3][2] = vw1->vp[2];
352 setident4(m4t);
353 m4t[0][0] = vw2->hvec[0]/vw2->hn2;
354 m4t[1][0] = vw2->hvec[1]/vw2->hn2;
355 m4t[2][0] = vw2->hvec[2]/vw2->hn2;
356 m4t[3][0] = -DOT(vw2->vp,vw2->hvec)/vw2->hn2;
357 m4t[0][1] = vw2->vvec[0]/vw2->vn2;
358 m4t[1][1] = vw2->vvec[1]/vw2->vn2;
359 m4t[2][1] = vw2->vvec[2]/vw2->vn2;
360 m4t[3][1] = -DOT(vw2->vp,vw2->vvec)/vw2->vn2;
361 m4t[0][2] = vw2->vdir[0];
362 m4t[1][2] = vw2->vdir[1];
363 m4t[2][2] = vw2->vdir[2];
364 m4t[3][2] = -DOT(vw2->vp,vw2->vdir);
365 multmat4(xfmat, xfmat, m4t);
366 return(1);
367 }
368
369
370 addscanline(y, pline, zline, lasty) /* add scanline to output */
371 int y;
372 COLR *pline;
373 float *zline;
374 struct position *lasty; /* input/output */
375 {
376 extern double sqrt();
377 FVECT pos;
378 struct position lastx, newpos;
379 register int x;
380
381 lastx.z = 0;
382 for (x = thresolu-1; x >= 0; x--) {
383 pos[0] = (x+.5)/thresolu;
384 pos[1] = (y+.5)/tvresolu;
385 pos[2] = zline[x];
386 if (movepixel(pos) < 0) {
387 lasty[x].z = lastx.z = 0; /* mark invalid */
388 continue;
389 }
390 newpos.x = pos[0] * hresolu;
391 newpos.y = pos[1] * vresolu;
392 newpos.z = zline[x];
393 /* add pixel to our image */
394 if (pos[0] >= 0 && newpos.x < hresolu
395 && pos[1] >= 0 && newpos.y < vresolu) {
396 addpixel(&newpos, &lastx, &lasty[x], pline[x], pos[2]);
397 lasty[x].x = lastx.x = newpos.x;
398 lasty[x].y = lastx.y = newpos.y;
399 lasty[x].z = lastx.z = newpos.z;
400 } else
401 lasty[x].z = lastx.z = 0; /* mark invalid */
402 }
403 }
404
405
406 addpixel(p0, p1, p2, pix, z) /* fill in pixel parallelogram */
407 struct position *p0, *p1, *p2;
408 COLR pix;
409 double z;
410 {
411 double zt = 2.*zeps*p0->z; /* threshold */
412 int s1x, s1y, s2x, s2y; /* step sizes */
413 int l1, l2, c1, c2; /* side lengths and counters */
414 int p1isy; /* p0p1 along y? */
415 int x1, y1; /* p1 position */
416 register int x, y; /* final position */
417
418 /* compute vector p0p1 */
419 if (fillo&F_FORE && ABS(p1->z-p0->z) <= zt) {
420 s1x = p1->x - p0->x;
421 s1y = p1->y - p0->y;
422 l1 = ABS(s1x);
423 if (p1isy = (ABS(s1y) > l1))
424 l1 = ABS(s1y);
425 } else {
426 l1 = s1x = s1y = 1;
427 p1isy = -1;
428 }
429 /* compute vector p0p2 */
430 if (fillo&F_FORE && ABS(p2->z-p0->z) <= zt) {
431 s2x = p2->x - p0->x;
432 s2y = p2->y - p0->y;
433 if (p1isy == 1)
434 l2 = ABS(s2x);
435 else {
436 l2 = ABS(s2y);
437 if (p1isy != 0 && ABS(s2x) > l2)
438 l2 = ABS(s2x);
439 }
440 } else
441 l2 = s2x = s2y = 1;
442 /* fill the parallelogram */
443 for (c1 = l1; c1-- > 0; ) {
444 x1 = p0->x + c1*s1x/l1;
445 y1 = p0->y + c1*s1y/l1;
446 for (c2 = l2; c2-- > 0; ) {
447 x = x1 + c2*s2x/l2;
448 if (x < 0 || x >= hresolu)
449 continue;
450 y = y1 + c2*s2y/l2;
451 if (y < 0 || y >= vresolu)
452 continue;
453 if (zscan(y)[x] <= 0 || zscan(y)[x]-z
454 > zeps*zscan(y)[x]) {
455 zscan(y)[x] = z;
456 copycolr(pscan(y)[x], pix);
457 }
458 }
459 }
460 }
461
462
463 movepixel(pos) /* reposition image point */
464 FVECT pos;
465 {
466 FVECT pt, direc;
467
468 if (hasmatrix) {
469 pos[0] += theirview.hoff - .5;
470 pos[1] += theirview.voff - .5;
471 if (theirview.type == VT_PER) {
472 if (normdist) /* adjust for eye-ray distance */
473 pos[2] /= sqrt( 1.
474 + pos[0]*pos[0]*theirview.hn2
475 + pos[1]*pos[1]*theirview.vn2 );
476 pos[0] *= pos[2];
477 pos[1] *= pos[2];
478 }
479 multp3(pos, pos, theirs2ours);
480 if (pos[2] <= 0)
481 return(-1);
482 if (ourview.type == VT_PER) {
483 pos[0] /= pos[2];
484 pos[1] /= pos[2];
485 }
486 pos[0] += .5 - ourview.hoff;
487 pos[1] += .5 - ourview.voff;
488 return(0);
489 }
490 if (viewray(pt, direc, &theirview, pos[0], pos[1]) < 0)
491 return(-1);
492 pt[0] += direc[0]*pos[2];
493 pt[1] += direc[1]*pos[2];
494 pt[2] += direc[2]*pos[2];
495 viewpixel(&pos[0], &pos[1], &pos[2], &ourview, pt);
496 if (pos[2] <= 0)
497 return(-1);
498 return(0);
499 }
500
501
502 backpicture(fill, samp) /* background fill algorithm */
503 int (*fill)();
504 int samp;
505 {
506 int *yback, xback;
507 int y;
508 register int x, i;
509 /* get back buffer */
510 yback = (int *)malloc(hresolu*sizeof(int));
511 if (yback == NULL)
512 syserror();
513 for (x = 0; x < hresolu; x++)
514 yback[x] = -2;
515 /*
516 * Xback and yback are the pixel locations of suitable
517 * background values in each direction.
518 * A value of -2 means unassigned, and -1 means
519 * that there is no suitable background in this direction.
520 */
521 /* fill image */
522 for (y = 0; y < vresolu; y++) {
523 xback = -2;
524 for (x = 0; x < hresolu; x++)
525 if (zscan(y)[x] <= 0) { /* empty pixel */
526 /*
527 * First, find background from above or below.
528 * (farthest assigned pixel)
529 */
530 if (yback[x] == -2) {
531 for (i = y+1; i < vresolu; i++)
532 if (zscan(i)[x] > 0)
533 break;
534 if (i < vresolu
535 && (y <= 0 || zscan(y-1)[x] < zscan(i)[x]))
536 yback[x] = i;
537 else
538 yback[x] = y-1;
539 }
540 /*
541 * Next, find background from left or right.
542 */
543 if (xback == -2) {
544 for (i = x+1; i < hresolu; i++)
545 if (zscan(y)[i] > 0)
546 break;
547 if (i < hresolu
548 && (x <= 0 || zscan(y)[x-1] < zscan(y)[i]))
549 xback = i;
550 else
551 xback = x-1;
552 }
553 /*
554 * If we have no background for this pixel,
555 * use the given fill function.
556 */
557 if (xback < 0 && yback[x] < 0)
558 goto fillit;
559 /*
560 * Compare, and use the background that is
561 * farther, unless one of them is next to us.
562 * If the background is too distant, call
563 * the fill function.
564 */
565 if ( yback[x] < 0
566 || (xback >= 0 && ABS(x-xback) <= 1)
567 || ( ABS(y-yback[x]) > 1
568 && zscan(yback[x])[x]
569 < zscan(y)[xback] ) ) {
570 if (samp > 0 && ABS(x-xback) >= samp)
571 goto fillit;
572 copycolr(pscan(y)[x],pscan(y)[xback]);
573 zscan(y)[x] = zscan(y)[xback];
574 } else {
575 if (samp > 0 && ABS(y-yback[x]) > samp)
576 goto fillit;
577 copycolr(pscan(y)[x],pscan(yback[x])[x]);
578 zscan(y)[x] = zscan(yback[x])[x];
579 }
580 continue;
581 fillit:
582 (*fill)(x,y);
583 if (fill == rcalfill) { /* use it */
584 clearqueue();
585 xback = x;
586 yback[x] = y;
587 }
588 } else { /* full pixel */
589 yback[x] = -2;
590 xback = -2;
591 }
592 }
593 free((char *)yback);
594 }
595
596
597 fillpicture(fill) /* paint in empty pixels using fill */
598 int (*fill)();
599 {
600 register int x, y;
601
602 for (y = 0; y < vresolu; y++)
603 for (x = 0; x < hresolu; x++)
604 if (zscan(y)[x] <= 0)
605 (*fill)(x,y);
606 }
607
608
609 writepicture() /* write out picture */
610 {
611 int y;
612
613 fputresolu(YMAJOR|YDECR, hresolu, vresolu, stdout);
614 for (y = vresolu-1; y >= 0; y--)
615 if (fwritecolrs(pscan(y), hresolu, stdout) < 0)
616 syserror();
617 }
618
619
620 writedistance(fname) /* write out z file */
621 char *fname;
622 {
623 extern double sqrt();
624 int donorm = normdist && ourview.type == VT_PER;
625 int fd;
626 int y;
627 float *zout;
628
629 if ((fd = open(fname, O_WRONLY|O_CREAT|O_TRUNC, 0666)) == -1) {
630 perror(fname);
631 exit(1);
632 }
633 if (donorm
634 && (zout = (float *)malloc(hresolu*sizeof(float))) == NULL)
635 syserror();
636 for (y = vresolu-1; y >= 0; y--) {
637 if (donorm) {
638 double vx, yzn2;
639 register int x;
640 yzn2 = (y+.5)/vresolu + ourview.voff - .5;
641 yzn2 = 1. + yzn2*yzn2*ourview.vn2;
642 for (x = 0; x < hresolu; x++) {
643 vx = (x+.5)/hresolu + ourview.hoff - .5;
644 zout[x] = zscan(y)[x]
645 * sqrt(vx*vx*ourview.hn2 + yzn2);
646 }
647 } else
648 zout = zscan(y);
649 if (write(fd, (char *)zout, hresolu*sizeof(float))
650 < hresolu*sizeof(float)) {
651 perror(fname);
652 exit(1);
653 }
654 }
655 if (donorm)
656 free((char *)zout);
657 close(fd);
658 }
659
660
661 isfloat(s) /* see if string is floating number */
662 register char *s;
663 {
664 for ( ; *s; s++)
665 if ((*s < '0' || *s > '9') && *s != '.' && *s != '-'
666 && *s != 'e' && *s != 'E' && *s != '+')
667 return(0);
668 return(1);
669 }
670
671
672 backfill(x, y) /* fill pixel with background */
673 int x, y;
674 {
675 register BYTE *dest = pscan(y)[x];
676
677 copycolr(dest, backcolr);
678 zscan(y)[x] = backz;
679 }
680
681
682 calstart(prog, args) /* start fill calculation */
683 char *prog, *args;
684 {
685 char combuf[512];
686 int p0[2], p1[2];
687
688 if (childpid != -1) {
689 fprintf(stderr, "%s: too many calculations\n", progname);
690 exit(1);
691 }
692 sprintf(combuf, prog, args);
693 if (pipe(p0) < 0 || pipe(p1) < 0)
694 syserror();
695 if ((childpid = vfork()) == 0) { /* fork calculation */
696 close(p0[1]);
697 close(p1[0]);
698 if (p0[0] != 0) {
699 dup2(p0[0], 0);
700 close(p0[0]);
701 }
702 if (p1[1] != 1) {
703 dup2(p1[1], 1);
704 close(p1[1]);
705 }
706 execl("/bin/sh", "sh", "-c", combuf, 0);
707 perror("/bin/sh");
708 _exit(127);
709 }
710 if (childpid == -1)
711 syserror();
712 close(p0[0]);
713 close(p1[1]);
714 if ((psend = fdopen(p0[1], "w")) == NULL)
715 syserror();
716 if ((precv = fdopen(p1[0], "r")) == NULL)
717 syserror();
718 queuesiz = 0;
719 }
720
721
722 caldone() /* done with calculation */
723 {
724 int pid;
725
726 if (childpid == -1)
727 return;
728 clearqueue();
729 fclose(psend);
730 fclose(precv);
731 while ((pid = wait(0)) != -1 && pid != childpid)
732 ;
733 childpid = -1;
734 }
735
736
737 rcalfill(x, y) /* fill with ray-calculated pixel */
738 int x, y;
739 {
740 if (queuesiz >= PACKSIZ) /* flush queue if needed */
741 clearqueue();
742 /* add position to queue */
743 queue[queuesiz][0] = x;
744 queue[queuesiz][1] = y;
745 queuesiz++;
746 }
747
748
749 clearqueue() /* process queue */
750 {
751 FVECT orig, dir;
752 float fbuf[6];
753 register int i;
754
755 for (i = 0; i < queuesiz; i++) {
756 viewray(orig, dir, &ourview,
757 (queue[i][0]+.5)/hresolu,
758 (queue[i][1]+.5)/vresolu);
759 fbuf[0] = orig[0]; fbuf[1] = orig[1]; fbuf[2] = orig[2];
760 fbuf[3] = dir[0]; fbuf[4] = dir[1]; fbuf[5] = dir[2];
761 fwrite((char *)fbuf, sizeof(float), 6, psend);
762 }
763 /* flush output and get results */
764 fbuf[3] = fbuf[4] = fbuf[5] = 0.0; /* mark */
765 fwrite((char *)fbuf, sizeof(float), 6, psend);
766 if (fflush(psend) == EOF)
767 syserror();
768 for (i = 0; i < queuesiz; i++) {
769 if (fread((char *)fbuf, sizeof(float), 4, precv) < 4) {
770 fprintf(stderr, "%s: read error in clearqueue\n",
771 progname);
772 exit(1);
773 }
774 if (ourexp > 0 && ourexp != 1.0) {
775 fbuf[0] *= ourexp;
776 fbuf[1] *= ourexp;
777 fbuf[2] *= ourexp;
778 }
779 setcolr(pscan(queue[i][1])[queue[i][0]],
780 fbuf[0], fbuf[1], fbuf[2]);
781 zscan(queue[i][1])[queue[i][0]] = fbuf[3];
782 }
783 queuesiz = 0;
784 }
785
786
787 syserror() /* report error and exit */
788 {
789 perror(progname);
790 exit(1);
791 }