ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/rt/rv2.c
(Generate patch)

Comparing ray/src/rt/rv2.c (file contents):
Revision 2.2 by greg, Thu Nov 21 10:10:30 1991 UTC vs.
Revision 2.38 by greg, Sat Feb 22 02:07:29 2003 UTC

# Line 1 | Line 1
1 /* Copyright (c) 1991 Regents of the University of California */
2
1   #ifndef lint
2 < static char SCCSid[] = "$SunId$ LBL";
2 > static const char       RCSid[] = "$Id$";
3   #endif
6
4   /*
5   *  rv2.c - command routines used in tracing a view.
6   *
7 < *     3/24/87
7 > *  External symbols declared in rpaint.h
8   */
9  
10 + /* ====================================================================
11 + * The Radiance Software License, Version 1.0
12 + *
13 + * Copyright (c) 1990 - 2002 The Regents of the University of California,
14 + * through Lawrence Berkeley National Laboratory.   All rights reserved.
15 + *
16 + * Redistribution and use in source and binary forms, with or without
17 + * modification, are permitted provided that the following conditions
18 + * are met:
19 + *
20 + * 1. Redistributions of source code must retain the above copyright
21 + *         notice, this list of conditions and the following disclaimer.
22 + *
23 + * 2. Redistributions in binary form must reproduce the above copyright
24 + *       notice, this list of conditions and the following disclaimer in
25 + *       the documentation and/or other materials provided with the
26 + *       distribution.
27 + *
28 + * 3. The end-user documentation included with the redistribution,
29 + *           if any, must include the following acknowledgment:
30 + *             "This product includes Radiance software
31 + *                 (http://radsite.lbl.gov/)
32 + *                 developed by the Lawrence Berkeley National Laboratory
33 + *               (http://www.lbl.gov/)."
34 + *       Alternately, this acknowledgment may appear in the software itself,
35 + *       if and wherever such third-party acknowledgments normally appear.
36 + *
37 + * 4. The names "Radiance," "Lawrence Berkeley National Laboratory"
38 + *       and "The Regents of the University of California" must
39 + *       not be used to endorse or promote products derived from this
40 + *       software without prior written permission. For written
41 + *       permission, please contact [email protected].
42 + *
43 + * 5. Products derived from this software may not be called "Radiance",
44 + *       nor may "Radiance" appear in their name, without prior written
45 + *       permission of Lawrence Berkeley National Laboratory.
46 + *
47 + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
48 + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
49 + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
50 + * DISCLAIMED.   IN NO EVENT SHALL Lawrence Berkeley National Laboratory OR
51 + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
52 + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
53 + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
54 + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
55 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
56 + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
57 + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
58 + * SUCH DAMAGE.
59 + * ====================================================================
60 + *
61 + * This software consists of voluntary contributions made by many
62 + * individuals on behalf of Lawrence Berkeley National Laboratory.   For more
63 + * information on Lawrence Berkeley National Laboratory, please see
64 + * <http://www.lbl.gov/>.
65 + */
66 +
67   #include  "ray.h"
68  
15 #include  "octree.h"
16
69   #include  "otypes.h"
70  
71   #include  "rpaint.h"
72  
21 #include  "resolu.h"
22
73   #include  <ctype.h>
74  
75 < #define  CTRL(c)        ('c'-'@')
75 > extern int  psample;                    /* pixel sample size */
76 > extern double  maxdiff;                 /* max. sample difference */
77  
78 < extern char  VersionID[];
78 > #define  CTRL(c)        ((c)-'@')
79 >
80 > #ifdef  SMLFLT
81 > #define  sscanvec(s,v)  (sscanf(s,"%f %f %f",v,v+1,v+2)==3)
82 > #else
83 > #define  sscanvec(s,v)  (sscanf(s,"%lf %lf %lf",v,v+1,v+2)==3)
84 > #endif
85 >
86 > extern char  rifname[128];              /* rad input file name */
87 >
88   extern char  *progname;
89   extern char  *octname;
90  
91  
92 + void
93   getframe(s)                             /* get a new frame */
94   char  *s;
95   {
# Line 38 | Line 99 | char  *s;
99   }
100  
101  
102 + void
103   getrepaint(s)                           /* get area and repaint */
104   char  *s;
105   {
# Line 49 | Line 111 | char  *s;
111   }
112  
113  
114 + void
115   getview(s)                              /* get/show view parameters */
116   char  *s;
117   {
# Line 58 | Line 121 | char  *s;
121          int  change = 0;
122          VIEW  nv;
123  
124 +        while (isspace(*s))
125 +                s++;
126 +        if (*s == '-') {                        /* command line parameters */
127 +                copystruct(&nv, &ourview);
128 +                if (sscanview(&nv, s))
129 +                        newview(&nv);
130 +                else
131 +                        error(COMMAND, "bad view option(s)");
132 +                return;
133 +        }
134          if (sscanf(s, "%s", buf) == 1) {        /* write parameters to a file */
135                  if ((fname = getpath(buf, NULL, 0)) == NULL ||
136                                  (fp = fopen(fname, "a")) == NULL) {
# Line 68 | Line 141 | char  *s;
141                  fputs(progname, fp);
142                  fprintview(&ourview, fp);
143                  fputs(sskip(s), fp);
144 <                fputs("\n", fp);
144 >                putc('\n', fp);
145                  fclose(fp);
146                  return;
147          }
148          sprintf(buf, "view type (%c): ", ourview.type);
149          (*dev->comout)(buf);
150          (*dev->comin)(buf, NULL);
151 <        if (buf[0] == CTRL(C)) return;
151 >        if (buf[0] == CTRL('C')) return;
152          if (buf[0] && buf[0] != ourview.type) {
153                  nv.type = buf[0];
154                  change++;
# Line 85 | Line 158 | char  *s;
158                          ourview.vp[0], ourview.vp[1], ourview.vp[2]);
159          (*dev->comout)(buf);
160          (*dev->comin)(buf, NULL);
161 <        if (buf[0] == CTRL(C)) return;
162 <        if (sscanf(buf, "%lf %lf %lf", &nv.vp[0], &nv.vp[1], &nv.vp[2]) == 3)
161 >        if (buf[0] == CTRL('C')) return;
162 >        if (sscanvec(buf, nv.vp))
163                  change++;
164          else
165                  VCOPY(nv.vp, ourview.vp);
# Line 94 | Line 167 | char  *s;
167                          ourview.vdir[0], ourview.vdir[1], ourview.vdir[2]);
168          (*dev->comout)(buf);
169          (*dev->comin)(buf, NULL);
170 <        if (buf[0] == CTRL(C)) return;
171 <        if (sscanf(buf,"%lf %lf %lf",&nv.vdir[0],&nv.vdir[1],&nv.vdir[2]) == 3)
170 >        if (buf[0] == CTRL('C')) return;
171 >        if (sscanvec(buf, nv.vdir))
172                  change++;
173          else
174                  VCOPY(nv.vdir, ourview.vdir);
# Line 103 | Line 176 | char  *s;
176                          ourview.vup[0], ourview.vup[1], ourview.vup[2]);
177          (*dev->comout)(buf);
178          (*dev->comin)(buf, NULL);
179 <        if (buf[0] == CTRL(C)) return;
180 <        if (sscanf(buf,"%lf %lf %lf",&nv.vup[0],&nv.vup[1],&nv.vup[2]) == 3)
179 >        if (buf[0] == CTRL('C')) return;
180 >        if (sscanvec(buf, nv.vup))
181                  change++;
182          else
183                  VCOPY(nv.vup, ourview.vup);
# Line 112 | Line 185 | char  *s;
185                          ourview.horiz, ourview.vert);
186          (*dev->comout)(buf);
187          (*dev->comin)(buf, NULL);
188 <        if (buf[0] == CTRL(C)) return;
188 >        if (buf[0] == CTRL('C')) return;
189          if (sscanf(buf, "%lf %lf", &nv.horiz, &nv.vert) == 2)
190                  change++;
191          else {
192                  nv.horiz = ourview.horiz; nv.vert = ourview.vert;
193          }
194 +        sprintf(buf, "fore and aft clipping plane (%.6g %.6g): ",
195 +                        ourview.vfore, ourview.vaft);
196 +        (*dev->comout)(buf);
197 +        (*dev->comin)(buf, NULL);
198 +        if (buf[0] == CTRL('C')) return;
199 +        if (sscanf(buf, "%lf %lf", &nv.vfore, &nv.vaft) == 2)
200 +                change++;
201 +        else {
202 +                nv.vfore = ourview.vfore; nv.vaft = ourview.vaft;
203 +        }
204          sprintf(buf, "view shift and lift (%.6g %.6g): ",
205                          ourview.hoff, ourview.voff);
206          (*dev->comout)(buf);
207          (*dev->comin)(buf, NULL);
208 <        if (buf[0] == CTRL(C)) return;
208 >        if (buf[0] == CTRL('C')) return;
209          if (sscanf(buf, "%lf %lf", &nv.hoff, &nv.voff) == 2)
210                  change++;
211          else {
# Line 133 | Line 216 | char  *s;
216   }
217  
218  
219 + void
220   lastview(s)                             /* return to a previous view */
221   char  *s;
222   {
# Line 143 | Line 227 | char  *s;
227  
228          if (sscanf(s, "%s", buf) == 1) {        /* get parameters from a file */
229                  copystruct(&nv, &stdview);
230 <                if ((fname = getpath(buf, NULL, 0)) == NULL ||
230 >                if ((fname = getpath(buf, "", R_OK)) == NULL ||
231                                  (success = viewfile(fname, &nv, NULL)) == -1) {
232                          sprintf(errmsg, "cannot open \"%s\"", buf);
233                          error(COMMAND, errmsg);
# Line 166 | Line 250 | char  *s;
250   }
251  
252  
253 + void
254 + saveview(s)                             /* save view to rad file */
255 + char  *s;
256 + {
257 +        char  view[64];
258 +        char  *fname;
259 +        FILE  *fp;
260 +
261 +        if (*atos(view, sizeof(view), s)) {
262 +                if (isint(view)) {
263 +                        error(COMMAND, "cannot write view by number");
264 +                        return;
265 +                }
266 +                s = sskip(s);
267 +        }
268 +        while (isspace(*s))
269 +                s++;
270 +        if (*s)
271 +                atos(rifname, sizeof(rifname), s);
272 +        else if (rifname[0] == '\0') {
273 +                error(COMMAND, "no previous rad file");
274 +                return;
275 +        }
276 +        if ((fname = getpath(rifname, NULL, 0)) == NULL ||
277 +                        (fp = fopen(fname, "a")) == NULL) {
278 +                sprintf(errmsg, "cannot open \"%s\"", rifname);
279 +                error(COMMAND, errmsg);
280 +                return;
281 +        }
282 +        fputs("view= ", fp);
283 +        fputs(view, fp);
284 +        fprintview(&ourview, fp);
285 +        putc('\n', fp);
286 +        fclose(fp);
287 + }
288 +
289 +
290 + void
291 + loadview(s)                             /* load view from rad file */
292 + char  *s;
293 + {
294 +        char  buf[512];
295 +        char  *fname;
296 +        FILE  *fp;
297 +        VIEW  nv;
298 +
299 +        strcpy(buf, "rad -n -s -V -v ");
300 +        if (sscanf(s, "%s", buf+strlen(buf)) == 1)
301 +                s = sskip(s);
302 +        else
303 +                strcat(buf, "1");
304 +        if (*s)
305 +                atos(rifname, sizeof(rifname), s);
306 +        else if (rifname[0] == '\0') {
307 +                error(COMMAND, "no previous rad file");
308 +                return;
309 +        }
310 +        if ((fname = getpath(rifname, "", R_OK)) == NULL) {
311 +                sprintf(errmsg, "cannot access \"%s\"", rifname);
312 +                error(COMMAND, errmsg);
313 +                return;
314 +        }
315 +        sprintf(buf+strlen(buf), " %s", fname);
316 +        if ((fp = popen(buf, "r")) == NULL) {
317 +                error(COMMAND, "cannot run rad");
318 +                return;
319 +        }
320 +        buf[0] = '\0';
321 +        fgets(buf, sizeof(buf), fp);
322 +        pclose(fp);
323 +        copystruct(&nv, &stdview);
324 +        if (!sscanview(&nv, buf)) {
325 +                error(COMMAND, "rad error -- no such view?");
326 +                return;
327 +        }
328 +        newview(&nv);
329 + }
330 +
331 +
332 + void
333   getaim(s)                               /* aim camera */
334   char  *s;
335   {
172        extern double  tan(), atan();
336          double  zfact;
337          VIEW  nv;
338  
# Line 178 | Line 341 | char  *s;
341          nv.type = ourview.type;
342          VCOPY(nv.vp, ourview.vp);
343          VCOPY(nv.vup, ourview.vup);
181        nv.hoff = ourview.hoff; nv.voff = ourview.voff;
344          nv.horiz = ourview.horiz; nv.vert = ourview.vert;
345 +        nv.vfore = ourview.vfore; nv.vaft = ourview.vaft;
346 +        nv.hoff = ourview.hoff; nv.voff = ourview.voff;
347          zoomview(&nv, zfact);
348          newview(&nv);
349   }
350  
351  
352 + void
353   getmove(s)                              /* move camera */
354   char  *s;
355   {
# Line 197 | Line 362 | char  *s;
362   }
363  
364  
365 + void
366   getrotate(s)                            /* rotate camera */
367   char  *s;
368   {
203        extern double  normalize(), tan(), atan();
369          VIEW  nv;
370          FVECT  v1;
371          double  angle, elev, zfact;
# Line 214 | Line 379 | char  *s;
379          VCOPY(nv.vp, ourview.vp);
380          VCOPY(nv.vup, ourview.vup);
381          nv.hoff = ourview.hoff; nv.voff = ourview.voff;
382 +        nv.vfore = ourview.vfore; nv.vaft = ourview.vaft;
383          spinvector(nv.vdir, ourview.vdir, ourview.vup, angle*(PI/180.));
384          if (elev != 0.0) {
385                  fcross(v1, nv.vdir, ourview.vup);
# Line 226 | Line 392 | char  *s;
392   }
393  
394  
395 + void
396   getpivot(s)                             /* pivot viewpoint */
397   register char  *s;
398   {
# Line 237 | Line 404 | register char  *s;
404                  error(COMMAND, "missing angle");
405                  return;
406          }
407 <        if (getinterest(sskip(sskip(s)), 0, vc, &mag) < 0)
407 >        if (getinterest(sskip2(s,2), 0, vc, &mag) < 0)
408                  return;
409          moveview(angle, elev, mag, vc);
410   }
411  
412  
413 + void
414   getexposure(s)                          /* get new exposure */
415   char  *s;
416   {
249        double  atof(), pow(), fabs();
417          char  buf[128];
418          register char  *cp;
252        register PNODE  *p;
419          RECT  r;
420          int  x, y;
421 <        double  e;
421 >        register PNODE  *p = &ptrunk;
422 >        int  adapt = 0;
423 >        double  e = 1.0;
424  
425          for (cp = s; isspace(*cp); cp++)
426                  ;
427 +        if (*cp == '@') {
428 +                adapt++;
429 +                while (isspace(*++cp))
430 +                        ;
431 +        }
432          if (*cp == '\0') {              /* normalize to point */
433                  if (dev->getcur == NULL)
434                          return;
# Line 265 | Line 438 | char  *s;
438                  r.l = r.d = 0;
439                  r.r = hresolu; r.u = vresolu;
440                  p = findrect(x, y, &ptrunk, &r, -1);
268                e = 1.0;
441          } else {
442                  if (*cp == '=') {       /* absolute setting */
443                          p = NULL;
# Line 273 | Line 445 | char  *s;
445                          for (cp++; isspace(*cp); cp++)
446                                  ;
447                          if (*cp == '\0') {      /* interactive */
448 <                                sprintf(buf, "exposure (%lf): ", exposure);
448 >                                sprintf(buf, "exposure (%f): ", exposure);
449                                  (*dev->comout)(buf);
450                                  (*dev->comin)(buf, NULL);
451                                  for (cp = buf; isspace(*cp); cp++)
# Line 281 | Line 453 | char  *s;
453                                  if (*cp == '\0')
454                                          return;
455                          }
284                } else {                /* normalize to average */
285                        p = &ptrunk;
286                        e = 1.0;
456                  }
457                  if (*cp == '+' || *cp == '-')   /* f-stops */
458                          e *= pow(2.0, atof(cp));
# Line 291 | Line 460 | char  *s;
460                          e *= atof(cp);
461          }
462          if (p != NULL) {                /* relative setting */
463 <                if (bright(p->v) <= FTINY) {
463 >                if (bright(p->v) < 1e-15) {
464                          error(COMMAND, "cannot normalize to zero");
465                          return;
466                  }
467 <                e *= 0.5 / bright(p->v);
467 >                if (adapt)
468 >                        e *= 106./pow(1.219+pow(luminance(p->v)/exposure,.4),2.5)/exposure;
469 >                else
470 >                        e *= 0.5 / bright(p->v);
471          }
472          if (e <= FTINY || fabs(1.0 - e) <= FTINY)
473                  return;
# Line 304 | Line 476 | char  *s;
476          redraw();
477   }
478  
479 + typedef union {int i; double d; COLOR C;}       *MyUptr;
480  
481 < getparam(str, dsc, typ, ptr)            /* get variable from user */
481 > int
482 > getparam(str, dsc, typ, p)              /* get variable from user */
483   char  *str, *dsc;
484   int  typ;
485 < register union {int i; double d; COLOR C;}  *ptr;
485 > void  *p;
486   {
487 <        extern char  *index();
487 >        register MyUptr  ptr = (MyUptr)p;
488          int  i0;
489          double  d0, d1, d2;
490          char  buf[48];
# Line 368 | Line 542 | register union {int i; double d; COLOR C;}  *ptr;
542   }
543  
544  
545 + void
546   setparam(s)                             /* get/set program parameter */
547   register char  *s;
548   {
374        extern int  psample;
375        extern double  maxdiff;
376        extern double  minweight;
377        extern int  maxdepth;
378        extern double  dstrsrc;
379        extern double  shadthresh;
380        extern double  shadcert;
381        extern COLOR  ambval;
382        extern double  ambacc;
383        extern double  minarad;
384        extern int  ambres;
385        extern int  ambdiv;
386        extern int  ambssamp;
387        extern int  ambounce;
388        extern int  directinvis;
389        extern double  srcsizerat;
390        extern int  do_irrad;
549          char  buf[128];
550          
551          if (s[0] == '\0') {
552                  (*dev->comout)(
553 <                        "aa ab ad ar as av b dc di dj ds dt i lr lw sp st: ");
553 >                "aa ab ad ar as av aw b dc dv dj ds dt i lr lw me ma mg ms ps pt sj st bv: ");
554                  (*dev->comin)(buf, NULL);
555                  s = buf;
556          }
# Line 400 | Line 558 | register char  *s;
558          case 'l':                       /* limit */
559                  switch (s[1]) {
560                  case 'w':                       /* weight */
561 <                        getparam(s+2, "limit weight", 'r', &minweight);
561 >                        getparam(s+2, "limit weight", 'r',
562 >                                        (void *)&minweight);
563                          break;
564                  case 'r':                       /* reflection */
565 <                        getparam(s+2, "limit reflection", 'i', &maxdepth);
565 >                        getparam(s+2, "limit reflection", 'i',
566 >                                        (void *)&maxdepth);
567                          break;
568                  default:
569                          goto badparam;
# Line 412 | Line 572 | register char  *s;
572          case 'd':                       /* direct */
573                  switch (s[1]) {
574                  case 'j':                       /* jitter */
575 <                        getparam(s+2, "direct jitter", 'r', &dstrsrc);
575 >                        getparam(s+2, "direct jitter", 'r',
576 >                                        (void *)&dstrsrc);
577                          break;
578                  case 'c':                       /* certainty */
579 <                        getparam(s+2, "direct certainty", 'r', &shadcert);
579 >                        getparam(s+2, "direct certainty", 'r',
580 >                                        (void *)&shadcert);
581                          break;
582                  case 't':                       /* threshold */
583 <                        getparam(s+2, "direct threshold", 'r', &shadthresh);
583 >                        getparam(s+2, "direct threshold", 'r',
584 >                                        (void *)&shadthresh);
585                          break;
586 <                case 'i':                       /* invisibility */
587 <                        getparam(s+2, "direct invisibility",
588 <                                        'b', &directinvis);
586 >                case 'v':                       /* visibility */
587 >                        getparam(s+2, "direct visibility", 'b',
588 >                                        (void *)&directvis);
589                          break;
590                  case 's':                       /* sampling */
591 <                        getparam(s+2, "direct sampling", 'r', &srcsizerat);
591 >                        getparam(s+2, "direct sampling", 'r',
592 >                                        (void *)&srcsizerat);
593                          break;
594                  default:
595                          goto badparam;
596                  }
597                  break;
598 <        case 'b':                       /* black and white */
599 <                getparam(s+1, "black and white", 'b', &greyscale);
598 >        case 'b':                       /* back faces or black and white */
599 >                switch (s[1]) {
600 >                case 'v':                       /* back face visibility */
601 >                        getparam(s+2, "back face visibility", 'b',
602 >                                        (void *)&backvis);
603 >                        break;
604 >                case '\0':                      /* black and white */
605 >                case ' ':
606 >                case 'y': case 'Y': case 't': case 'T': case '1': case '+':
607 >                case 'n': case 'N': case 'f': case 'F': case '0': case '-':
608 >                        getparam(s+1, "black and white", 'b',
609 >                                        (void *)&greyscale);
610 >                        break;
611 >                default:
612 >                        goto badparam;
613 >                }
614                  break;
615          case 'i':                       /* irradiance */
616 <                getparam(s+1, "irradiance", 'b', &do_irrad);
616 >                getparam(s+1, "irradiance", 'b',
617 >                                (void *)&do_irrad);
618                  break;
619          case 'a':                       /* ambient */
620                  switch (s[1]) {
621                  case 'v':                       /* value */
622 <                        getparam(s+2, "ambient value", 'C', ambval);
622 >                        getparam(s+2, "ambient value", 'C',
623 >                                        (void *)ambval);
624                          break;
625 +                case 'w':                       /* weight */
626 +                        getparam(s+2, "ambient value weight", 'i',
627 +                                        (void *)&ambvwt);
628 +                        break;
629                  case 'a':                       /* accuracy */
630 <                        getparam(s+2, "ambient accuracy", 'r', &ambacc);
630 >                        if (getparam(s+2, "ambient accuracy", 'r',
631 >                                        (void *)&ambacc))
632 >                                setambacc(ambacc);
633                          break;
634                  case 'd':                       /* divisions */
635 <                        getparam(s+2, "ambient divisions", 'i', &ambdiv);
635 >                        getparam(s+2, "ambient divisions", 'i',
636 >                                        (void *)&ambdiv);
637                          break;
638                  case 's':                       /* samples */
639 <                        getparam(s+2, "ambient super-samples", 'i', &ambssamp);
639 >                        getparam(s+2, "ambient super-samples", 'i',
640 >                                        (void *)&ambssamp);
641                          break;
642                  case 'b':                       /* bounces */
643 <                        getparam(s+2, "ambient bounces", 'i', &ambounce);
643 >                        getparam(s+2, "ambient bounces", 'i',
644 >                                        (void *)&ambounce);
645                          break;
646                  case 'r':
647 <                        if (getparam(s+2, "ambient resolution", 'i', &ambres))
648 <                                minarad = ambres > 0 ?
649 <                                                thescene.cusize/ambres : 0.0;
647 >                        if (getparam(s+2, "ambient resolution", 'i',
648 >                                        (void *)&ambres))
649 >                                setambres(ambres);
650                          break;
651                  default:
652                          goto badparam;
653                  }
654                  break;
655 <        case 's':                       /* sample */
655 >        case 'm':                       /* medium */
656                  switch (s[1]) {
657 <                case 'p':                       /* pixel */
658 <                        if (getparam(s+2, "sample pixel", 'i', &psample))
657 >                case 'e':                       /* extinction coefficient */
658 >                        getparam(s+2, "extinction coefficient", 'C',
659 >                                        (void *)cextinction);
660 >                        break;
661 >                case 'a':                       /* scattering albedo */
662 >                        getparam(s+2, "scattering albedo", 'C',
663 >                                        (void *)salbedo);
664 >                        break;
665 >                case 'g':                       /* scattering eccentricity */
666 >                        getparam(s+2, "scattering eccentricity", 'r',
667 >                                        (void *)&seccg);
668 >                        break;
669 >                case 's':                       /* sampling distance */
670 >                        getparam(s+2, "mist sampling distance", 'r',
671 >                                        (void *)&ssampdist);
672 >                        break;
673 >                default:
674 >                        goto badparam;
675 >                }
676 >                break;
677 >        case 'p':                       /* pixel */
678 >                switch (s[1]) {
679 >                case 's':                       /* sample */
680 >                        if (getparam(s+2, "pixel sample", 'i',
681 >                                        (void *)&psample))
682                                  pdepth = 0;
683                          break;
684                  case 't':                       /* threshold */
685 <                        if (getparam(s+2, "sample threshold", 'r', &maxdiff))
685 >                        if (getparam(s+2, "pixel threshold", 'r',
686 >                                        (void *)&maxdiff))
687                                  pdepth = 0;
688                          break;
689                  default:
690                          goto badparam;
691                  }
692                  break;
693 +        case 's':                       /* specular */
694 +                switch (s[1]) {
695 +                case 'j':                       /* jitter */
696 +                        getparam(s+2, "specular jitter", 'r',
697 +                                        (void *)&specjitter);
698 +                        break;
699 +                case 't':                       /* threshold */
700 +                        getparam(s+2, "specular threshold", 'r',
701 +                                        (void *)&specthresh);
702 +                        break;
703 +                default:
704 +                        goto badparam;
705 +                }
706 +                break;
707          case '\0':                      /* nothing */
708                  break;
709          default:;
# Line 489 | Line 716 | badparam:
716   }
717  
718  
719 + void
720   traceray(s)                             /* trace a single ray */
721   char  *s;
722   {
723          char  buf[128];
724          int  x, y;
725 +        OBJREC  *ino;
726          RAY  thisray;
727  
728 <        if (sscanf(s, "%lf %lf %lf %lf %lf %lf",
500 <                &thisray.rorg[0], &thisray.rorg[1], &thisray.rorg[2],
501 <                &thisray.rdir[0], &thisray.rdir[1], &thisray.rdir[2]) != 6) {
728 >        thisray.rmax = 0.0;
729  
730 +        if (!sscanvec(s, thisray.rorg) ||
731 +                        !sscanvec(sskip2(s,3), thisray.rdir)) {
732 +
733                  if (dev->getcur == NULL)
734                          return;
735                  (*dev->comout)("Pick ray\n");
736                  if ((*dev->getcur)(&x, &y) == ABORT)
737                          return;
738  
739 <                if (viewray(thisray.rorg, thisray.rdir, &ourview,
740 <                                (x+.5)/hresolu, (y+.5)/vresolu) < 0) {
739 >                if ((thisray.rmax = viewray(thisray.rorg, thisray.rdir,
740 >                        &ourview, (x+.5)/hresolu, (y+.5)/vresolu)) < -FTINY) {
741                          error(COMMAND, "not on image");
742                          return;
743                  }
# Line 524 | Line 754 | char  *s;
754          if (thisray.ro == NULL)
755                  (*dev->comout)("ray hit nothing");
756          else {
757 <                sprintf(buf, "ray hit %s %s \"%s\"",
758 <                                objptr(thisray.ro->omod)->oname,
757 >                sprintf(buf, "ray hit %s%s %s \"%s\"",
758 >                                thisray.rod < 0.0 ? "back of " : "",
759 >                                thisray.ro->omod == OVOID ? VOIDID :
760 >                                        objptr(thisray.ro->omod)->oname,
761                                  ofun[thisray.ro->otype].funame,
762                                  thisray.ro->oname);
763 +                if ((ino = objptr(thisray.robj)) != thisray.ro)
764 +                        sprintf(buf+strlen(buf), " in %s \"%s\"",
765 +                                        ofun[ino->otype].funame, ino->oname);
766                  (*dev->comout)(buf);
767                  (*dev->comin)(buf, NULL);
768                  if (thisray.rot >= FHUGE)
769                          (*dev->comout)("at infinity");
770                  else {
771 <                        sprintf(buf, "at (%.6g %.6g %.6g)", thisray.rop[0],
772 <                                        thisray.rop[1], thisray.rop[2]);
771 >                        sprintf(buf, "at (%.6g %.6g %.6g) (%.6g)",
772 >                                        thisray.rop[0], thisray.rop[1],
773 >                                        thisray.rop[2], thisray.rt);
774                          (*dev->comout)(buf);
775                  }
776                  (*dev->comin)(buf, NULL);
777 <                sprintf(buf, "value (%.5g %.5g %.5g) (%.1fL)",
777 >                sprintf(buf, "value (%.5g %.5g %.5g) (%.3gL)",
778                                  colval(thisray.rcol,RED),
779                                  colval(thisray.rcol,GRN),
780                                  colval(thisray.rcol,BLU),
# Line 549 | Line 785 | char  *s;
785   }
786  
787  
788 + void
789   writepict(s)                            /* write the picture to a file */
790   char  *s;
791   {
# Line 558 | Line 795 | char  *s;
795          COLR  *scanline;
796          int  y;
797  
798 <        if (sscanf(s, "%s", buf) != 1 && buf[0] == '\0') {
798 >        while (isspace(*s))
799 >                s++;
800 >        if (*s)
801 >                atos(buf, sizeof(buf), s);
802 >        else if (buf[0] == '\0') {
803                  error(COMMAND, "no file");
804                  return;
805          }
# Line 568 | Line 809 | char  *s;
809                  error(COMMAND, errmsg);
810                  return;
811          }
812 + #ifdef MSDOS
813 +        setmode(fileno(fp), O_BINARY);
814 + #endif
815          (*dev->comout)("writing \"");
816          (*dev->comout)(fname);
817          (*dev->comout)("\"...\n");
818                                                  /* write header */
819 +        newheader("RADIANCE", fp);
820          fputs(progname, fp);
821          fprintview(&ourview, fp);
822          if (octname != NULL)
# Line 579 | Line 824 | char  *s;
824          else
825                  putc('\n', fp);
826          fprintf(fp, "SOFTWARE= %s\n", VersionID);
827 +        fputnow(fp);
828          if (exposure != 1.0)
829                  fputexpos(exposure, fp);
830          if (dev->pixaspect != 1.0)
# Line 599 | Line 845 | char  *s;
845                  if (fwritecolrs(scanline, hresolu, fp) < 0)
846                          break;
847          }
848 <        free((char *)scanline);
848 >        free((void *)scanline);
849          if (fclose(fp) < 0)
850                  error(COMMAND, "write error");
851   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines