Back to index

radiance  4R0+20100331
vwrays.c
Go to the documentation of this file.
00001 #ifndef lint
00002 static const char    RCSid[] = "$Id: vwrays.c,v 3.14 2009/06/22 00:12:04 greg Exp $";
00003 #endif
00004 /*
00005  * Compute rays corresponding to a given picture or view.
00006  */
00007 
00008 #include "platform.h"
00009 #include "standard.h"
00010 #include "random.h"
00011 #include "view.h"
00012 
00013 typedef void putfunc(FVECT ro, FVECT rd);
00014 static putfunc puta;
00015 static putfunc putf;
00016 static putfunc putd;
00017 static void pix2rays(FILE *fp);
00018 static void putrays(void);
00019 
00020 static putfunc *putr = puta;
00021 
00022 VIEW   vw = STDVIEW;
00023 
00024 RESOLU rs = {PIXSTANDARD, 512, 512};
00025 
00026 double pa = 1.;
00027 
00028 double  pj = 0.;
00029 
00030 int    zfd = -1;
00031 
00032 int    fromstdin = 0;
00033 
00034 char   *progname;
00035 
00036 
00037 int
00038 main(
00039        int    argc,
00040        char   *argv[]
00041 )
00042 {
00043        char   *err;
00044        int    rval, getdim = 0;
00045        register int  i;
00046 
00047        progname = argv[0];
00048        if (argc < 2)
00049               goto userr;
00050        for (i = 1; i < argc && argv[i][0] == '-'; i++)
00051               switch (argv[i][1]) {
00052               case 'f':                   /* output format */
00053                      switch (argv[i][2]) {
00054                      case 'a':                   /* ASCII */
00055                             putr = puta;
00056                             break;
00057                      case 'f':                   /* float */
00058                             putr = putf;
00059                             SET_FILE_BINARY(stdout);
00060                             break;
00061                      case 'd':                   /* double */
00062                             putr = putd;
00063                             SET_FILE_BINARY(stdout);
00064                             break;
00065                      default:
00066                             goto userr;
00067                      }
00068                      break;
00069               case 'v':                   /* view file or option */
00070                      if (argv[i][2] == 'f') {
00071                             rval = viewfile(argv[++i], &vw, NULL);
00072                             if (rval <= 0) {
00073                                    fprintf(stderr,
00074                                           "%s: no view in file\n",
00075                                                  argv[i]);
00076                                    exit(1);
00077                             }
00078                             break;
00079                      }
00080                      rval = getviewopt(&vw, argc-i, argv+i);
00081                      if (rval < 0)
00082                             goto userr;
00083                      i += rval;
00084                      break;
00085               case 'd':                   /* report dimensions only */
00086                      getdim++;
00087                      break;
00088               case 'x':                   /* x resolution */
00089                      rs.xr = atoi(argv[++i]);
00090                      if (rs.xr <= 0) {
00091                             fprintf(stderr, "%s: bad x resolution\n",
00092                                           progname);
00093                             exit(1);
00094                      }
00095                      break;
00096               case 'y':                   /* y resolution */
00097                      rs.yr = atoi(argv[++i]);
00098                      if (rs.yr <= 0) {
00099                             fprintf(stderr, "%s: bad y resolution\n",
00100                                           progname);
00101                             exit(1);
00102                      }
00103                      break;
00104               case 'p':                   /* pixel aspect or jitter */
00105                      if (argv[i][2] == 'a')
00106                             pa = atof(argv[++i]);
00107                      else if (argv[i][2] == 'j')
00108                             pj= atof(argv[++i]);
00109                      else
00110                             goto userr;
00111                      break;
00112               case 'i':                   /* get pixels from stdin */
00113                      fromstdin = 1;
00114                      break;
00115               default:
00116                      goto userr;
00117               }
00118        if ((i > argc) | (i+2 < argc))
00119               goto userr;
00120        if (i < argc) {
00121               rval = viewfile(argv[i], &vw, &rs);
00122               if (rval <= 0) {
00123                      fprintf(stderr, "%s: no view in picture\n", argv[i]);
00124                      exit(1);
00125               }
00126               if (i+1 < argc) {
00127                      zfd = open(argv[i+1], O_RDONLY);
00128                      if (zfd < 0) {
00129                             fprintf(stderr,
00130                                    "%s: cannot open depth buffer\n",
00131                                           argv[i+1]);
00132                             exit(1);
00133                      }
00134               }
00135        }
00136        if ((err = setview(&vw)) != NULL) {
00137               fprintf(stderr, "%s: %s\n", progname, err);
00138               exit(1);
00139        }
00140        if (i == argc)
00141               normaspect(viewaspect(&vw), &pa, &rs.xr, &rs.yr);
00142        if (getdim) {
00143               printf("-x %d -y %d -ld%c\n", rs.xr, rs.yr,
00144                             vw.vaft > FTINY ? '+' : '-');
00145               exit(0);
00146        }
00147        if (fromstdin)
00148               pix2rays(stdin);
00149        else
00150               putrays();
00151        exit(0);
00152 userr:
00153        fprintf(stderr,
00154        "Usage: %s [ -i -f{a|f|d} | -d ] { view opts .. | picture [zbuf] }\n",
00155                      progname);
00156        exit(1);
00157 }
00158 
00159 
00160 static void
00161 jitterloc(
00162        RREAL  loc[2]
00163 )
00164 {
00165        if (pj > FTINY) {
00166               loc[0] += pj*(.5 - frandom())/rs.xr;
00167               loc[1] += pj*(.5 - frandom())/rs.yr;
00168        }
00169 }
00170 
00171 
00172 static void
00173 pix2rays(
00174        FILE *fp
00175 )
00176 {
00177        static FVECT  rorg, rdir;
00178        float  zval;
00179        double px, py;
00180        RREAL  loc[2];
00181        int    pp[2];
00182        double d;
00183        register int  i;
00184 
00185        while (fscanf(fp, "%lf %lf", &px, &py) == 2) {
00186               px += .5; py += .5;
00187               loc[0] = px/rs.xr; loc[1] = py/rs.yr;
00188               if (zfd >= 0) {
00189                      loc2pix(pp, &rs, loc[0], loc[1]);
00190                      if (lseek(zfd,
00191                             (pp[1]*scanlen(&rs)+pp[0])*sizeof(float),
00192                                           SEEK_SET) < 0 ||
00193                                    read(zfd, &zval, sizeof(float))
00194                                           < sizeof(float)) {
00195                             fprintf(stderr, "%s: depth buffer read error\n",
00196                                           progname);
00197                             exit(1);
00198                      }
00199               }
00200               jitterloc(loc);
00201               d = viewray(rorg, rdir, &vw, loc[0], loc[1]);
00202               if (d < -FTINY)
00203                      rorg[0] = rorg[1] = rorg[2] =
00204                      rdir[0] = rdir[1] = rdir[2] = 0.;
00205               else if (zfd >= 0)
00206                      for (i = 0; i < 3; i++) {
00207                             rorg[i] += rdir[i]*zval;
00208                             rdir[i] = -rdir[i];
00209                      }
00210               else if (d > FTINY) {
00211                      rdir[0] *= d; rdir[1] *= d; rdir[2] *= d;
00212               }
00213               (*putr)(rorg, rdir);
00214        }
00215        if (!feof(fp)) {
00216               fprintf(stderr, "%s: expected px py on input\n", progname);
00217               exit(1);
00218        }
00219 }
00220 
00221 
00222 static void
00223 putrays(void)
00224 {
00225        RREAL  loc[2];
00226        FVECT  rorg, rdir;
00227        float  *zbuf = NULL;
00228        int    sc;
00229        double d;
00230        register int  si, i;
00231 
00232        if (zfd >= 0) {
00233               zbuf = (float *)malloc(scanlen(&rs)*sizeof(float));
00234               if (zbuf == NULL) {
00235                      fprintf(stderr, "%s: not enough memory\n", progname);
00236                      exit(1);
00237               }
00238        }
00239        for (sc = 0; sc < numscans(&rs); sc++) {
00240               if (zfd >= 0) {
00241                      if (read(zfd, zbuf, scanlen(&rs)*sizeof(float)) <
00242                                    scanlen(&rs)*sizeof(float)) {
00243                             fprintf(stderr, "%s: depth buffer read error\n",
00244                                           progname);
00245                             exit(1);
00246                      }
00247               }
00248               for (si = 0; si < scanlen(&rs); si++) {
00249                      pix2loc(loc, &rs, si, sc);
00250                      jitterloc(loc);
00251                      d = viewray(rorg, rdir, &vw, loc[0], loc[1]);
00252                      if (d < -FTINY)
00253                             rorg[0] = rorg[1] = rorg[2] =
00254                             rdir[0] = rdir[1] = rdir[2] = 0.;
00255                      else if (zfd >= 0)
00256                             for (i = 0; i < 3; i++) {
00257                                    rorg[i] += rdir[i]*zbuf[si];
00258                                    rdir[i] = -rdir[i];
00259                             }
00260                      else if (d > FTINY) {
00261                             rdir[0] *= d; rdir[1] *= d; rdir[2] *= d;
00262                      }
00263                      (*putr)(rorg, rdir);
00264               }
00265        }
00266        if (zfd >= 0)
00267               free((void *)zbuf);
00268 }
00269 
00270 
00271 static void
00272 puta(         /* put out ray in ASCII format */
00273        FVECT  ro,
00274        FVECT  rd
00275 )
00276 {
00277        printf("%.5e %.5e %.5e %.5e %.5e %.5e\n",
00278                      ro[0], ro[1], ro[2],
00279                      rd[0], rd[1], rd[2]);
00280 }
00281 
00282 
00283 static void
00284 putf(         /* put out ray in float format */
00285        FVECT  ro,
00286        FVECT  rd
00287 )
00288 {
00289        float v[6];
00290 
00291        v[0] = ro[0]; v[1] = ro[1]; v[2] = ro[2];
00292        v[3] = rd[0]; v[4] = rd[1]; v[5] = rd[2];
00293        fwrite(v, sizeof(float), 6, stdout);
00294 }
00295 
00296 
00297 static void
00298 putd(         /* put out ray in double format */
00299        FVECT  ro,
00300        FVECT  rd
00301 )
00302 {
00303        double v[6];
00304 
00305        v[0] = ro[0]; v[1] = ro[1]; v[2] = ro[2];
00306        v[3] = rd[0]; v[4] = rd[1]; v[5] = rd[2];
00307        fwrite(v, sizeof(double), 6, stdout);
00308 }