33 |
|
#define H_VDST 010 /* VDISTANCE= True */ |
34 |
|
#define H_SWAP 020 /* byte order is different */ |
35 |
|
|
36 |
– |
char *progname; /* global argv[0] */ |
37 |
– |
|
36 |
|
struct phead { |
37 |
|
VIEW vw; |
38 |
|
double expos; |
49 |
|
} RAYPAR; |
50 |
|
|
51 |
|
static int openholo(char *fname, int append); |
52 |
< |
static void addray(RAYPAR *rp); |
52 |
> |
static int addray(RAYPAR *rp); |
53 |
|
static int readval(RREAL *v, int n, FILE *fp); |
54 |
|
static void readrays(FILE *fp); |
55 |
|
static int writeval(RREAL *v, int n, FILE *fp); |
71 |
|
{ |
72 |
|
int i; |
73 |
|
|
74 |
< |
progname = argv[0]; |
74 |
> |
fixargv0(argv[0]); |
75 |
|
for (i = 2; i < argc && argv[i][0] == '-'; i++) |
76 |
|
switch (argv[i][1]) { |
77 |
|
case 'u': |
226 |
|
return(n); |
227 |
|
} |
228 |
|
|
229 |
< |
void |
229 |
> |
int |
230 |
|
addray( /* add a ray to our output holodeck */ |
231 |
|
RAYPAR *rp |
232 |
|
) |
239 |
|
double d0, d1; |
240 |
|
unsigned dc; |
241 |
|
RAYVAL *rv; |
242 |
+ |
int nsects = 0; |
243 |
|
/* check each output section */ |
244 |
|
for (sn = nholosects; sn--; ) { |
245 |
|
hp = hdlist[sn]; |
270 |
|
rv->r[0][0] = rr[0][0]; rv->r[0][1] = rr[0][1]; |
271 |
|
rv->r[1][0] = rr[1][0]; rv->r[1][1] = rr[1][1]; |
272 |
|
copycolr(rv->v, rp->cv); |
273 |
+ |
++nsects; |
274 |
|
} |
275 |
+ |
return nsects; |
276 |
|
} |
277 |
|
|
278 |
|
/* Read n-vector from file stream */ |
326 |
|
static void |
327 |
|
readrays(FILE *fp) |
328 |
|
{ |
329 |
+ |
unsigned long nread=0, ngood=0; |
330 |
+ |
|
331 |
|
if (iofmt != 'a') |
332 |
|
SET_FILE_BINARY(fp); |
333 |
|
#ifdef getc_unlocked |
382 |
|
if (!flags) /* got nothing, so may be normal EOF */ |
383 |
|
return; |
384 |
|
} |
385 |
+ |
++nread; |
386 |
|
if (flags & (BAD_DIR|BAD_LEN)) |
387 |
|
continue; /* just a bad ray is all -- skip */ |
388 |
|
if (!(flags & GOT_VAL)) |
400 |
|
} else |
401 |
|
goto missingData; |
402 |
|
} |
403 |
< |
addray(&ryp); /* add our ray to holodeck */ |
403 |
> |
ngood += (addray(&ryp) > 0); /* add our ray to holodeck */ |
404 |
|
} |
405 |
|
return; |
406 |
|
missingData: |
407 |
< |
sprintf(errmsg, "insufficient data in -i%s", rspec); |
407 |
> |
sprintf(errmsg, "insufficient data or read error with -i%s after %lu rays read (%lu used)", |
408 |
> |
rspec, nread, ngood); |
409 |
|
error(USER, errmsg); |
410 |
|
} |
411 |
|
|
483 |
|
return 0; /* write error? */ |
484 |
|
} |
485 |
|
|
486 |
+ |
static BEAMI *beamdir; |
487 |
+ |
|
488 |
+ |
static int |
489 |
+ |
bpcmp( /* compare beam positions on disk */ |
490 |
+ |
const void *b1p, |
491 |
+ |
const void *b2p |
492 |
+ |
) |
493 |
+ |
{ |
494 |
+ |
off_t pdif = beamdir[*(int *)b1p].fo - beamdir[*(int *)b2p].fo; |
495 |
+ |
|
496 |
+ |
if (pdif > 0L) return(1); |
497 |
+ |
if (pdif < 0L) return(-1); |
498 |
+ |
return(0); |
499 |
+ |
} |
500 |
+ |
|
501 |
|
/* Write all rays from holodeck to stream */ |
502 |
|
static void |
503 |
|
writerays(FILE *fp) |
518 |
|
#endif |
519 |
|
for (sn = 0; sn < nholosects; sn++) { /* write each holodeck section */ |
520 |
|
HOLO *hp = hdlist[sn]; |
521 |
< |
for (bi = nbeams(hp); bi > 0; bi--) { |
522 |
< |
BEAM *bp = hdgetbeam(hp, bi); |
521 |
> |
int nb = nbeams(hp); /* sort beams by file location */ |
522 |
> |
int *bq = (int *)malloc(nb*sizeof(int)); |
523 |
> |
if (!bq) |
524 |
> |
error(SYSTEM, "out of memory in writerays()"); |
525 |
> |
for (bi = nb; bi--; ) bq[bi] = bi+1; |
526 |
> |
beamdir = hp->bi; |
527 |
> |
qsort(bq, nb, sizeof(*bq), bpcmp); |
528 |
> |
for (bi = 0; bi < nb; bi++) { |
529 |
> |
BEAM *bp = hdgetbeam(hp, bq[bi]); |
530 |
|
if (!bp) /* empty beam? */ |
531 |
|
continue; |
532 |
< |
hdbcoord(gc, hp, bi); /* else write rays */ |
532 |
> |
hdbcoord(gc, hp, bq[bi]); |
533 |
|
rv = hdbray(bp); |
534 |
|
for (k = bp->nrm; k--; rv++) { |
535 |
+ |
RREAL hitd = hddepth(hp, rv->d); |
536 |
|
ryp.d = hdray(ryp.ro, ryp.rd, hp, gc, rv->r); |
537 |
< |
if (*(int *)hp->priv & H_OBSF) |
537 |
> |
if (*(int *)hp->priv & H_OBST) { |
538 |
> |
ryp.d = 0; |
539 |
> |
} else { |
540 |
> |
if (ryp.d > 0.97*hitd) |
541 |
> |
ryp.d = 0.97*hitd; |
542 |
|
VSUM(ryp.ro, ryp.ro, ryp.rd, ryp.d); |
543 |
< |
else |
544 |
< |
ryp.d = 0.; |
513 |
< |
ryp.d = hddepth(hp, rv->d) - ryp.d; |
543 |
> |
} |
544 |
> |
ryp.d = hitd - ryp.d; |
545 |
|
copycolr(ryp.cv, rv->v); |
546 |
< |
if (!write_ray(&ryp, fp)) |
546 |
> |
if (!write_ray(&ryp, fp)) { |
547 |
> |
free(bq); |
548 |
|
goto writError; |
549 |
+ |
} |
550 |
|
} |
551 |
< |
hdfreebeam(hp, bi); |
551 |
> |
hdfreebeam(hp, bq[bi]); |
552 |
|
} |
553 |
+ |
free(bq); |
554 |
|
} |
555 |
|
if (fflush(fp) != EOF) |
556 |
|
return; |
558 |
|
error(SYSTEM, "error writing holodeck rays"); |
559 |
|
} |
560 |
|
|
527 |
– |
static BEAMI *beamdir; |
528 |
– |
|
561 |
|
static int |
530 |
– |
bpcmp( /* compare beam positions on disk */ |
531 |
– |
const void *b1p, |
532 |
– |
const void *b2p |
533 |
– |
) |
534 |
– |
{ |
535 |
– |
off_t pdif = beamdir[*(int*)b1p].fo - beamdir[*(int*)b2p].fo; |
536 |
– |
|
537 |
– |
if (pdif > 0L) return(1); |
538 |
– |
if (pdif < 0L) return(-1); |
539 |
– |
return(0); |
540 |
– |
} |
541 |
– |
|
542 |
– |
static int |
562 |
|
addclump( /* transfer the given clump and free */ |
563 |
|
HOLO *hp, |
564 |
|
int *bq, |
573 |
|
BEAM *bp; |
574 |
|
/* sort based on file position */ |
575 |
|
beamdir = hp->bi; |
576 |
< |
qsort((char *)bq, nb, sizeof(*bq), bpcmp); |
576 |
> |
qsort(bq, nb, sizeof(*bq), bpcmp); |
577 |
|
/* transfer each beam */ |
578 |
|
for (i = 0; i < nb; i++) { |
579 |
|
bp = hdgetbeam(hp, bq[i]); |
755 |
|
|
756 |
|
void |
757 |
|
eputs( /* put error message to stderr */ |
758 |
< |
char *s |
758 |
> |
const char *s |
759 |
|
) |
760 |
|
{ |
761 |
|
static int midline = 0; |