--- ray/src/hd/rhcopy.c 1997/12/18 10:03:29 3.2 +++ ray/src/hd/rhcopy.c 1998/01/07 09:23:02 3.5 @@ -12,6 +12,8 @@ static char SCCSid[] = "$SunId$ SGI"; #include "view.h" #include "resolu.h" +int checkdepth = 1; /* check depth (!-f option)? */ +int checkrepeats = 0; /* check for repeats (-c option)? */ int frompicz; /* input from pictures & depth-buffers? */ int noutsects; /* number of output sections */ char obstr, unobstr; /* flag pointer values */ @@ -26,28 +28,41 @@ char *argv[]; int i; progname = argv[0]; - if (argc < 4) + frompicz = -1; + for (i = 2; i < argc && argv[i][0] == '-'; i++) + switch (argv[i][1]) { + case 'c': + checkrepeats = 1; + break; + case 'f': + checkdepth = 0; + break; + case 'h': + frompicz = 0; + break; + case 'p': + frompicz = 1; + break; + default: + goto userr; + } + if (i >= argc || frompicz < 0) goto userr; - if (!strcmp(argv[2], "-h")) - frompicz = 0; - else if (!strcmp(argv[2], "-pz")) - frompicz = 1; - else + if (frompicz && (argc-i)%2) goto userr; - if (frompicz && (argc-3)%2) - goto userr; noutsects = openholo(argv[1], 1); if (frompicz) - for (i = 3; i < argc; i += 2) + for ( ; i < argc; i += 2) addpicz(argv[i], argv[i+1]); else - for (i = 3; i < argc; i++) + for ( ; i < argc; i++) addholo(argv[i]); quit(0); userr: - fprintf(stderr, "Usage: %s output.hdk -h inp1.hdk ..\n", progname); - fprintf(stderr, " Or: %s output.hdk -pz inp1.pic inp1.zbf ..\n", + fprintf(stderr, "Usage: %s output.hdk [-c][-f] -h inp1.hdk ..\n", progname); + fprintf(stderr, " Or: %s output.hdk [-c][-f] -pz inp1.pic inp1.zbf ..\n", + progname); exit(1); } @@ -91,7 +106,7 @@ int append; FILE *fp; int fd; int hflags = 0; - int4 nextloc; + long nextloc; int n; /* open holodeck file */ if ((fp = fopen(fname, append ? "r+" : "r")) == NULL) { @@ -109,7 +124,7 @@ int append; nextloc = ftell(fp); /* get stdio position */ fclose(fp); /* done with stdio */ for (n = 0; nextloc > 0L; n++) { /* initialize each section */ - lseek(fd, (long)nextloc, 0); + lseek(fd, nextloc, 0); read(fd, (char *)&nextloc, sizeof(nextloc)); hdinit(fd, NULL)->priv = hflags&H_OBST ? &obstr : hflags&H_OBSF ? &unobstr : (char *)NULL; @@ -127,11 +142,13 @@ FVECT ro, rd; double d; COLR cv; { - int sn; + int sn, bi, n; register HOLO *hp; GCOORD gc[2]; BYTE rr[2][2]; + BEAM *bp; double d0, d1; + unsigned dc; register RAYVAL *rv; /* check each output section */ for (sn = noutsects; sn--; ) { @@ -139,16 +156,30 @@ COLR cv; d0 = hdinter(gc, rr, &d1, hp, ro, rd); if (d <= d0 || d1 < -0.001) continue; /* missed section */ - if (hp->priv == &obstr && d0 < -0.001) - continue; /* ray starts too late */ - if (hp->priv == &unobstr && d < 0.999*d1) - continue; /* ray ends too soon */ - /* should we check for duplicates? */ - rv = hdnewrays(hp, hdbindex(hp, gc), 1); + if (checkdepth) { /* check depth */ + if (hp->priv == &obstr && d0 < -0.001) + continue; /* ray starts too late */ + if (hp->priv == &unobstr && d < 0.999*d1) + continue; /* ray ends too soon */ + } + dc = hdcode(hp, d-d0); + bi = hdbindex(hp, gc); /* check for duplicates */ + if (checkrepeats && (bp = hdgetbeam(hp, bi)) != NULL) { + for (n = bp->nrm, rv = hdbray(bp); n--; rv++) + if (rv->d == dc && + rv->r[0][0] == rr[0][0] && + rv->r[0][1] == rr[0][1] && + rv->r[1][0] == rr[1][0] && + rv->r[1][1] == rr[1][1]) + break; + if (n >= 0) + continue; /* found a matching ray */ + } + rv = hdnewrays(hp, bi, 1); + rv->d = dc; rv->r[0][0] = rr[0][0]; rv->r[0][1] = rr[0][1]; rv->r[1][0] = rr[1][0]; rv->r[1][1] = rr[1][1]; copycolr(rv->v, cv); - rv->d = hdcode(hp, d-d0); } } @@ -159,18 +190,27 @@ char *hdf; int fd; register HOLO *hp; register BEAM *bp; + register HDBEAMI *hbl; GCOORD gc[2]; FVECT ro, rd; double d; int i, j; register int k; - - openholo(hdf, 0); /* open the holodeck for reading */ + /* open the holodeck for reading */ + openholo(hdf, 0); fd = hdlist[noutsects]->fd; /* remember the file handle */ while ((hp = hdlist[noutsects]) != NULL) { /* load each section */ - for (j = nbeams(hp); j > 0; j--) /* load each beam */ - if ((bp = hdgetbeam(hp, j)) != NULL) { - hdbcoord(gc, hp, j); + hbl = (HDBEAMI *)malloc(nbeams(hp)*sizeof(HDBEAMI)); + if (hbl == NULL) + error(SYSTEM, "out of memory in addholo"); + for (j = nbeams(hp); j > 0; j--) { /* sort the beams */ + hbl[j].h = hp; + hbl[j].b = j; + } + qsort((char *)hbl, nbeams(hp), sizeof(HDBEAMI), hdfilord); + for (j = 0; j < nbeams(hp); j++) /* load each beam */ + if ((bp = hdgetbeam(hp, hbl[j].b)) != NULL) { + hdbcoord(gc, hp, hbl[j].b); for (k = bp->nrm; k--; ) { d = hdray(ro, rd, hp, gc, hdbray(bp)[k].r); @@ -181,8 +221,9 @@ char *hdf; d = hddepth(hp, hdbray(bp)[k].d) - d; addray(ro, rd, d, hdbray(bp)[k].v); } - hdfreebeam(hp, j); /* free the beam */ + hdfreebeam(hp, hbl[j].b); /* free beam */ } + free((char *)hbl); /* free beam list */ hddone(hp); /* free the section */ } close(fd); /* close the file */