| 7 |  |  | 
| 8 |  | #include "platform.h" | 
| 9 |  | #include "standard.h" | 
| 10 | + | #include "random.h" | 
| 11 |  | #include "view.h" | 
| 12 |  |  | 
| 13 | < | extern int      putf(), putd(), puta(); | 
| 13 | > | typedef void putfunc(FVECT ro, FVECT rd); | 
| 14 | > | static putfunc puta; | 
| 15 | > | static putfunc putf; | 
| 16 | > | static putfunc putd; | 
| 17 | > | static void pix2rays(FILE *fp); | 
| 18 | > | static void putrays(void); | 
| 19 |  |  | 
| 20 | < | int     (*putr)() = puta; | 
| 20 | > | static putfunc *putr = puta; | 
| 21 |  |  | 
| 22 |  | VIEW    vw = STDVIEW; | 
| 23 |  |  | 
| 25 |  |  | 
| 26 |  | double  pa = 1.; | 
| 27 |  |  | 
| 28 | + | double  pj = 0.; | 
| 29 | + |  | 
| 30 |  | int     zfd = -1; | 
| 31 |  |  | 
| 32 |  | int     fromstdin = 0; | 
| 33 |  |  | 
| 34 | + | int     unbuffered = 0; | 
| 35 | + |  | 
| 36 | + | int     repeatcnt = 1; | 
| 37 | + |  | 
| 38 |  | char    *progname; | 
| 39 |  |  | 
| 40 |  |  | 
| 41 | < | main(argc, argv) | 
| 42 | < | int     argc; | 
| 43 | < | char    *argv[]; | 
| 41 | > | int | 
| 42 | > | main( | 
| 43 | > | int     argc, | 
| 44 | > | char    *argv[] | 
| 45 | > | ) | 
| 46 |  | { | 
| 47 |  | char    *err; | 
| 48 |  | int     rval, getdim = 0; | 
| 49 | < | register int    i; | 
| 49 | > | int     i; | 
| 50 |  |  | 
| 51 |  | progname = argv[0]; | 
| 52 |  | if (argc < 2) | 
| 60 |  | break; | 
| 61 |  | case 'f':                       /* float */ | 
| 62 |  | putr = putf; | 
| 63 | + | SET_FILE_BINARY(stdout); | 
| 64 |  | break; | 
| 65 |  | case 'd':                       /* double */ | 
| 66 |  | putr = putd; | 
| 67 | + | SET_FILE_BINARY(stdout); | 
| 68 |  | break; | 
| 69 |  | default: | 
| 70 |  | goto userr; | 
| 105 |  | exit(1); | 
| 106 |  | } | 
| 107 |  | break; | 
| 108 | < | case 'p':                       /* pixel aspect ratio */ | 
| 109 | < | pa = atof(argv[++i]); | 
| 108 | > | case 'c':                       /* repeat count */ | 
| 109 | > | repeatcnt = atoi(argv[++i]); | 
| 110 |  | break; | 
| 111 | + | case 'p':                       /* pixel aspect or jitter */ | 
| 112 | + | if (argv[i][2] == 'a') | 
| 113 | + | pa = atof(argv[++i]); | 
| 114 | + | else if (argv[i][2] == 'j') | 
| 115 | + | pj = atof(argv[++i]); | 
| 116 | + | else | 
| 117 | + | goto userr; | 
| 118 | + | break; | 
| 119 |  | case 'i':                       /* get pixels from stdin */ | 
| 120 |  | fromstdin = 1; | 
| 121 |  | break; | 
| 122 | + | case 'u':                       /* unbuffered output */ | 
| 123 | + | unbuffered = 1; | 
| 124 | + | break; | 
| 125 |  | default: | 
| 126 |  | goto userr; | 
| 127 |  | } | 
| 133 |  | fprintf(stderr, "%s: no view in picture\n", argv[i]); | 
| 134 |  | exit(1); | 
| 135 |  | } | 
| 136 | < | if (i+1 < argc) { | 
| 137 | < | zfd = open(argv[i+1], O_RDONLY); | 
| 138 | < | if (zfd < 0) { | 
| 112 | < | fprintf(stderr, | 
| 113 | < | "%s: cannot open depth buffer\n", | 
| 114 | < | argv[i+1]); | 
| 136 | > | if (!getdim & (i+1 < argc)) { | 
| 137 | > | zfd = open_float_depth(argv[i+1], (long)rs.xr*rs.yr); | 
| 138 | > | if (zfd < 0) | 
| 139 |  | exit(1); | 
| 116 | – | } | 
| 140 |  | } | 
| 141 |  | } | 
| 142 |  | if ((err = setview(&vw)) != NULL) { | 
| 147 |  | normaspect(viewaspect(&vw), &pa, &rs.xr, &rs.yr); | 
| 148 |  | if (getdim) { | 
| 149 |  | printf("-x %d -y %d -ld%c\n", rs.xr, rs.yr, | 
| 150 | < | vw.vaft > FTINY ? '+' : '-'); | 
| 150 | > | (i+1 == argc) & (vw.vaft > FTINY) ? '+' : '-'); | 
| 151 |  | exit(0); | 
| 152 |  | } | 
| 153 |  | if (fromstdin) | 
| 157 |  | exit(0); | 
| 158 |  | userr: | 
| 159 |  | fprintf(stderr, | 
| 160 | < | "Usage: %s [ -i -f{a|f|d} | -d ] { view opts .. | picture [zbuf] }\n", | 
| 160 | > | "Usage: %s [ -i -u -f{a|f|d} -c rept | -d ] { view opts .. | picture [zbuf] }\n", | 
| 161 |  | progname); | 
| 162 |  | exit(1); | 
| 163 |  | } | 
| 164 |  |  | 
| 165 |  |  | 
| 166 | < | pix2rays(FILE *fp) | 
| 166 | > | static void | 
| 167 | > | jitterloc( | 
| 168 | > | RREAL   loc[2] | 
| 169 | > | ) | 
| 170 |  | { | 
| 171 | + | if (pj > FTINY) { | 
| 172 | + | loc[0] += pj*(.5 - frandom())/rs.xr; | 
| 173 | + | loc[1] += pj*(.5 - frandom())/rs.yr; | 
| 174 | + | } | 
| 175 | + | } | 
| 176 | + |  | 
| 177 | + |  | 
| 178 | + | static void | 
| 179 | + | pix2rays( | 
| 180 | + | FILE *fp | 
| 181 | + | ) | 
| 182 | + | { | 
| 183 |  | static FVECT    rorg, rdir; | 
| 184 |  | float   zval; | 
| 185 |  | double  px, py; | 
| 186 | + | RREAL   loc[2]; | 
| 187 |  | int     pp[2]; | 
| 188 |  | double  d; | 
| 189 | < | register int    i; | 
| 189 | > | int     i; | 
| 190 |  |  | 
| 191 |  | while (fscanf(fp, "%lf %lf", &px, &py) == 2) { | 
| 192 | < | if (px < 0 || px >= rs.xr || | 
| 193 | < | py < 0 || py >= rs.yr) { | 
| 155 | < | fprintf(stderr, | 
| 156 | < | "%s: (x,y) pair (%.0f,%.0f) out of range\n", | 
| 157 | < | progname, px, py); | 
| 158 | < | exit(1); | 
| 159 | < | } | 
| 192 | > | px += .5; py += .5; | 
| 193 | > | loc[0] = px/rs.xr; loc[1] = py/rs.yr; | 
| 194 |  | if (zfd >= 0) { | 
| 195 | < | loc2pix(pp, &rs, px/rs.xr, py/rs.yr); | 
| 195 | > | if ((loc[0] < 0) | (loc[0] >= 1) | | 
| 196 | > | (loc[1] < 0) | (loc[1] >= 1)) { | 
| 197 | > | fprintf(stderr, "%s: input pixel outside image\n", | 
| 198 | > | progname); | 
| 199 | > | exit(1); | 
| 200 | > | } | 
| 201 | > | loc2pix(pp, &rs, loc[0], loc[1]); | 
| 202 |  | if (lseek(zfd, | 
| 203 |  | (pp[1]*scanlen(&rs)+pp[0])*sizeof(float), | 
| 204 |  | SEEK_SET) < 0 || | 
| 209 |  | exit(1); | 
| 210 |  | } | 
| 211 |  | } | 
| 212 | < | d = viewray(rorg, rdir, &vw, px/rs.xr, py/rs.yr); | 
| 212 | > | jitterloc(loc); | 
| 213 | > | d = viewray(rorg, rdir, &vw, loc[0], loc[1]); | 
| 214 |  | if (d < -FTINY) | 
| 215 |  | rorg[0] = rorg[1] = rorg[2] = | 
| 216 |  | rdir[0] = rdir[1] = rdir[2] = 0.; | 
| 223 |  | rdir[0] *= d; rdir[1] *= d; rdir[2] *= d; | 
| 224 |  | } | 
| 225 |  | (*putr)(rorg, rdir); | 
| 226 | + | if (unbuffered) | 
| 227 | + | fflush(stdout); | 
| 228 |  | } | 
| 229 |  | if (!feof(fp)) { | 
| 230 |  | fprintf(stderr, "%s: expected px py on input\n", progname); | 
| 233 |  | } | 
| 234 |  |  | 
| 235 |  |  | 
| 236 | < | putrays() | 
| 236 | > | static void | 
| 237 | > | putrays(void) | 
| 238 |  | { | 
| 239 | < | static RREAL    loc[2]; | 
| 240 | < | static FVECT    rorg, rdir; | 
| 241 | < | float   *zbuf; | 
| 239 | > | RREAL   loc[2]; | 
| 240 | > | FVECT   rorg, rdir; | 
| 241 | > | float   *zbuf = NULL; | 
| 242 |  | int     sc; | 
| 243 |  | double  d; | 
| 244 | < | register int    si, i; | 
| 244 | > | int     si, i, c; | 
| 245 |  |  | 
| 246 |  | if (zfd >= 0) { | 
| 247 |  | zbuf = (float *)malloc(scanlen(&rs)*sizeof(float)); | 
| 260 |  | } | 
| 261 |  | } | 
| 262 |  | for (si = 0; si < scanlen(&rs); si++) { | 
| 263 | + | for (c = repeatcnt; c-- > 0; ) { | 
| 264 |  | pix2loc(loc, &rs, si, sc); | 
| 265 | + | jitterloc(loc); | 
| 266 |  | d = viewray(rorg, rdir, &vw, loc[0], loc[1]); | 
| 267 |  | if (d < -FTINY) | 
| 268 |  | rorg[0] = rorg[1] = rorg[2] = | 
| 269 |  | rdir[0] = rdir[1] = rdir[2] = 0.; | 
| 270 |  | else if (zfd >= 0) | 
| 271 |  | for (i = 0; i < 3; i++) { | 
| 272 | < | rorg[i] += rdir[i]*zbuf[si]; | 
| 273 | < | rdir[i] = -rdir[i]; | 
| 272 | > | rdir[i] = -rdir[i]*zbuf[si]; | 
| 273 | > | rorg[i] -= rdir[i]; | 
| 274 |  | } | 
| 275 |  | else if (d > FTINY) { | 
| 276 |  | rdir[0] *= d; rdir[1] *= d; rdir[2] *= d; | 
| 277 |  | } | 
| 278 |  | (*putr)(rorg, rdir); | 
| 279 | + | } | 
| 280 |  | } | 
| 281 |  | } | 
| 282 |  | if (zfd >= 0) | 
| 284 |  | } | 
| 285 |  |  | 
| 286 |  |  | 
| 287 | < | puta(ro, rd)            /* put out ray in ASCII format */ | 
| 288 | < | FVECT   ro, rd; | 
| 287 | > | static void | 
| 288 | > | puta(           /* put out ray in ASCII format */ | 
| 289 | > | FVECT   ro, | 
| 290 | > | FVECT   rd | 
| 291 | > | ) | 
| 292 |  | { | 
| 293 |  | printf("%.5e %.5e %.5e %.5e %.5e %.5e\n", | 
| 294 |  | ro[0], ro[1], ro[2], | 
| 296 |  | } | 
| 297 |  |  | 
| 298 |  |  | 
| 299 | < | putf(ro, rd)            /* put out ray in float format */ | 
| 300 | < | FVECT   ro, rd; | 
| 299 | > | static void | 
| 300 | > | putf(           /* put out ray in float format */ | 
| 301 | > | FVECT   ro, | 
| 302 | > | FVECT   rd | 
| 303 | > | ) | 
| 304 |  | { | 
| 305 |  | float v[6]; | 
| 306 |  |  | 
| 307 |  | v[0] = ro[0]; v[1] = ro[1]; v[2] = ro[2]; | 
| 308 |  | v[3] = rd[0]; v[4] = rd[1]; v[5] = rd[2]; | 
| 309 | < | fwrite(v, sizeof(float), 6, stdout); | 
| 309 | > | putbinary(v, sizeof(float), 6, stdout); | 
| 310 |  | } | 
| 311 |  |  | 
| 312 |  |  | 
| 313 | < | putd(ro, rd)            /* put out ray in double format */ | 
| 314 | < | FVECT   ro, rd; | 
| 313 | > | static void | 
| 314 | > | putd(           /* put out ray in double format */ | 
| 315 | > | FVECT   ro, | 
| 316 | > | FVECT   rd | 
| 317 | > | ) | 
| 318 |  | { | 
| 319 |  | double v[6]; | 
| 320 |  |  | 
| 321 |  | v[0] = ro[0]; v[1] = ro[1]; v[2] = ro[2]; | 
| 322 |  | v[3] = rd[0]; v[4] = rd[1]; v[5] = rd[2]; | 
| 323 | < | fwrite(v, sizeof(double), 6, stdout); | 
| 323 | > | putbinary(v, sizeof(double), 6, stdout); | 
| 324 |  | } |