--- ray/src/hd/holo.c 1997/11/06 16:37:45 3.3 +++ ray/src/hd/holo.c 1997/12/18 09:33:12 3.10 @@ -23,9 +23,7 @@ static int wg1[6] = {2,2,0,0,1,1}; hdcompgrid(hp) /* compute derived grid vector and index */ register HOLO *hp; { - FVECT AxB; double d; - register FLOAT *v; register int i, j; /* initialize depth map */ if (hd_depthmap[0] < 1.) { @@ -38,22 +36,13 @@ register HOLO *hp; } /* compute grid coordinate vectors */ for (i = 0; i < 3; i++) { - fcross(AxB, hp->xv[(i+1)%3], v=hp->xv[(i+2)%3]); - VCOPY(hp->wn[i], AxB); + fcross(hp->wn[i], hp->xv[(i+1)%3], hp->xv[(i+2)%3]); if (normalize(hp->wn[i]) == 0.) error(USER, "degenerate holodeck section"); hp->wo[i<<1] = DOT(hp->wn[i],hp->orig); - hp->wo[i<<1|1] = hp->wo[i<<1] + DOT(hp->wn[i],hp->xv[i]); - fcross(hp->gv[i][0], v, AxB); - d = DOT(v,v) / DOT(hp->gv[i][0],hp->gv[i][0]) * - hp->grid[(i+1)%3]; - for (j = 0; j < 3; j++) - hp->gv[i][0][j] *= d; - fcross(hp->gv[i][1], AxB, v=hp->xv[(i+1)%3]); - d = DOT(v,v) / DOT(hp->gv[i][1],hp->gv[i][1]) * - hp->grid[(i+2)%3]; - for (j = 0; j < 3; j++) - hp->gv[i][1][j] *= d; + d = DOT(hp->wn[i],hp->xv[i]); + hp->wo[i<<1|1] = hp->wo[i<<1] + d; + hp->wg[i] = (double)hp->grid[i] / d; } /* compute linear depth range */ hp->tlin = VLEN(hp->xv[0]) + VLEN(hp->xv[1]) + VLEN(hp->xv[2]); @@ -178,16 +167,45 @@ register GCOORD gc[2]; } -hdlseg(lseg, hp, i) /* compute line segment for beam */ +hdcell(cp, hp, gc) /* compute cell coordinates */ +register FVECT cp[4]; /* returned (may be passed as FVECT cp[2][2]) */ +register HOLO *hp; +register GCOORD *gc; +{ + register FLOAT *v; + double d; + /* compute common component */ + VCOPY(cp[0], hp->orig); + if (gc->w & 1) { + v = hp->xv[gc->w>>1]; + cp[0][0] += v[0]; cp[0][1] += v[1]; cp[0][2] += v[2]; + } + v = hp->xv[wg0[gc->w]]; + d = (double)gc->i[0] / hp->grid[wg0[gc->w]]; + VSUM(cp[0], cp[0], v, d); + v = hp->xv[wg1[gc->w]]; + d = (double)gc->i[1] / hp->grid[wg1[gc->w]]; + VSUM(cp[0], cp[0], v, d); + /* compute x1 sums */ + v = hp->xv[wg0[gc->w]]; + d = 1.0 / hp->grid[wg0[gc->w]]; + VSUM(cp[1], cp[0], v, d); + VSUM(cp[3], cp[0], v, d); + /* compute y1 sums */ + v = hp->xv[wg1[gc->w]]; + d = 1.0 / hp->grid[wg1[gc->w]]; + VSUM(cp[2], cp[0], v, d); + VSUM(cp[3], cp[3], v, d); +} + + +hdlseg(lseg, hp, gc) /* compute line segment for beam */ register int lseg[2][3]; register HOLO *hp; -int i; +GCOORD gc[2]; { - GCOORD gc[2]; register int k; - if (!hdbcoord(gc, hp, i)) /* compute grid coordinates */ - return(0); for (k = 0; k < 2; k++) { /* compute end points */ lseg[k][gc[k].w>>1] = gc[k].w&1 ? hp->grid[gc[k].w>>1]-1 : 0 ; lseg[k][wg0[gc[k].w]] = gc[k].i[0]; @@ -216,32 +234,58 @@ double d; } +hdgrid(gp, hp, wp) /* compute grid coordinates */ +FVECT gp; /* returned */ +register HOLO *hp; +FVECT wp; +{ + FVECT vt; + + vt[0] = wp[0] - hp->orig[0]; + vt[1] = wp[1] - hp->orig[1]; + vt[2] = wp[2] - hp->orig[2]; + gp[0] = DOT(vt, hp->wn[0]) * hp->wg[0]; + gp[1] = DOT(vt, hp->wn[1]) * hp->wg[1]; + gp[2] = DOT(vt, hp->wn[2]) * hp->wg[2]; +} + + +hdworld(wp, hp, gp) /* compute world coordinates */ +register FVECT wp; +register HOLO *hp; +FVECT gp; +{ + register double d; + + d = gp[0]/hp->grid[0]; + VSUM(wp, hp->orig, hp->xv[0], d); + + d = gp[1]/hp->grid[1]; + VSUM(wp, wp, hp->xv[1], d); + + d = gp[2]/hp->grid[2]; + VSUM(wp, wp, hp->xv[2], d); +} + + double hdray(ro, rd, hp, gc, r) /* compute ray within a beam */ FVECT ro, rd; /* returned */ -register HOLO *hp; -register GCOORD gc[2]; +HOLO *hp; +GCOORD gc[2]; BYTE r[2][2]; { - FVECT p[2]; - register int i; - register FLOAT *v; - double d; + FVECT cp[4], p[2]; + register int i, j; + double d0, d1; /* compute entry and exit points */ for (i = 0; i < 2; i++) { - VCOPY(p[i], hp->orig); - if (gc[i].w & 1) { - v = hp->xv[gc[i].w>>1]; - p[i][0] += *v++; p[i][1] += *v++; p[i][2] += *v; - } - d = ( gc[i].i[0] + (1./256.)*(r[i][0]+.5) ) / - hp->grid[wg0[gc[i].w]]; - v = hp->xv[wg0[gc[i].w]]; - p[i][0] += d * *v++; p[i][1] += d * *v++; p[i][2] += d * *v; - d = (gc[i].i[1] + (1./256.)*(r[i][1]+.5)) / - hp->grid[wg1[gc[i].w]]; - v = hp->xv[wg1[gc[i].w]]; - p[i][0] += d * *v++; p[i][1] += d * *v++; p[i][2] += d * *v; + hdcell(cp, hp, gc+i); + d0 = (1./256.)*(r[i][0]+.5); + d1 = (1./256.)*(r[i][1]+.5); + for (j = 0; j < 3; j++) + p[i][j] = (1.-d0-d1)*cp[0][j] + + d0*cp[1][j] + d1*cp[2][j]; } VCOPY(ro, p[0]); /* assign ray origin and direction */ rd[0] = p[1][0] - p[0][0]; @@ -252,9 +296,10 @@ BYTE r[2][2]; double -hdinter(gc, r, hp, ro, rd) /* compute ray intersection with section */ +hdinter(gc, r, ed, hp, ro, rd) /* compute ray intersection with section */ register GCOORD gc[2]; /* returned */ BYTE r[2][2]; /* returned */ +double *ed; /* returned (optional) */ register HOLO *hp; FVECT ro, rd; /* rd should be normalized */ { @@ -304,24 +349,19 @@ FVECT ro, rd; /* rd should be normalized */ vt[0] = p[i][0] - hp->orig[0]; vt[1] = p[i][1] - hp->orig[1]; vt[2] = p[i][2] - hp->orig[2]; - if (gc[i].w & 1) { - v = hp->xv[gc[i].w>>1]; - vt[0] -= *v++; vt[1] -= *v++; vt[2] -= *v; - } - v = hp->gv[gc[i].w>>1][0]; - d = DOT(vt, v); + v = hp->wn[wg0[gc[i].w]]; + d = DOT(vt, v) * hp->wg[wg0[gc[i].w]]; if (d < 0. || (gc[i].i[0] = d) >= hp->grid[wg0[gc[i].w]]) return(FHUGE); /* outside wall */ r[i][0] = 256. * (d - gc[i].i[0]); - v = hp->gv[gc[i].w>>1][1]; - d = DOT(vt, v); + v = hp->wn[wg1[gc[i].w]]; + d = DOT(vt, v) * hp->wg[wg1[gc[i].w]]; if (d < 0. || (gc[i].i[1] = d) >= hp->grid[wg1[gc[i].w]]) return(FHUGE); /* outside wall */ r[i][1] = 256. * (d - gc[i].i[1]); } - /* return distance from entry point */ - vt[0] = ro[0] - p[0][0]; - vt[1] = ro[1] - p[0][1]; - vt[2] = ro[2] - p[0][2]; - return(DOT(vt,rd)); + + if (ed != NULL) /* assign distance to exit point */ + *ed = t1; + return(t0); /* return distance to entry point */ }