--- ray/src/rt/m_brdf.c 1991/06/18 08:59:55 1.11 +++ ray/src/rt/m_brdf.c 1992/10/14 12:30:54 2.4 @@ -14,6 +14,8 @@ static char SCCSid[] = "$SunId$ LBL"; #include "otypes.h" +#include "func.h" + /* * Arguments to this material include the color and specularity. * String arguments include the reflection function and files. @@ -58,9 +60,6 @@ static char SCCSid[] = "$SunId$ LBL"; * CrP, CgP, CbP - perturbed material color */ -extern double funvalue(), varvalue(); -extern XF funcxf; - typedef struct { OBJREC *mp; /* material pointer */ RAY *pr; /* intersected ray */ @@ -86,7 +85,7 @@ double omega; /* light source size */ double dtmp; COLOR ctmp; FVECT ldx; - double pt[MAXDIM]; + double lddx[3], pt[MAXDIM]; register char **sa; register int i; @@ -128,33 +127,35 @@ double omega; /* light source size */ /* transform light vector */ multv3(ldx, ldir, funcxf.xfm); for (i = 0; i < 3; i++) - ldx[i] /= funcxf.sca; + lddx[i] = ldx[i]/funcxf.sca; /* compute BRTDF */ if (np->mp->otype == MAT_BRTDF) { - colval(ctmp,RED) = funvalue(sa[6], 3, ldx); + colval(ctmp,RED) = funvalue(sa[6], 3, lddx); if (!strcmp(sa[7],sa[6])) colval(ctmp,GRN) = colval(ctmp,RED); else - colval(ctmp,GRN) = funvalue(sa[7], 3, ldx); + colval(ctmp,GRN) = funvalue(sa[7], 3, lddx); if (!strcmp(sa[8],sa[6])) colval(ctmp,BLU) = colval(ctmp,RED); else if (!strcmp(sa[8],sa[7])) colval(ctmp,BLU) = colval(ctmp,GRN); else - colval(ctmp,BLU) = funvalue(sa[8], 3, ldx); + colval(ctmp,BLU) = funvalue(sa[8], 3, lddx); dtmp = bright(ctmp); } else if (np->dp == NULL) { - dtmp = funvalue(sa[0], 3, ldx); + dtmp = funvalue(sa[0], 3, lddx); setcolor(ctmp, dtmp, dtmp, dtmp); } else { for (i = 0; i < np->dp->nd; i++) - pt[i] = funvalue(sa[3+i], 3, ldx); + pt[i] = funvalue(sa[3+i], 3, lddx); dtmp = datavalue(np->dp, pt); dtmp = funvalue(sa[0], 1, &dtmp); setcolor(ctmp, dtmp, dtmp, dtmp); } - if (errno) - goto computerr; + if (errno) { + objerror(np->mp, WARNING, "compute error"); + return; + } if (dtmp <= FTINY) return; if (ldot > 0.0) { @@ -176,10 +177,6 @@ double omega; /* light source size */ scalecolor(ctmp, dtmp); addcolor(cval, ctmp); } - return; -computerr: - objerror(np->mp, WARNING, "compute error"); - return; } @@ -191,7 +188,8 @@ register RAY *r; BRDFDAT nd; double transtest, transdist; COLOR ctmp; - double dtmp; + double dtmp, tspect, rspecr; + MFUNC *mf; register int i; /* check arguments */ switch (m->otype) { @@ -238,44 +236,41 @@ register RAY *r; multcolor(nd.mcolor, r->pcol); /* modify material color */ transtest = 0; /* load auxiliary files */ - if (m->otype == MAT_PDATA || m->otype == MAT_MDATA - || m->otype == MAT_TDATA) { + if (hasdata(m->otype)) { nd.dp = getdata(m->oargs.sarg[1]); - for (i = 3; i < m->oargs.nsargs; i++) - if (m->oargs.sarg[i][0] == '-') - break; - if (i-3 != nd.dp->nd) - objerror(m, USER, "dimension error"); - if (!fundefined(m->oargs.sarg[3])) - loadfunc(m->oargs.sarg[2]); + i = (1 << nd.dp->nd) - 1; + mf = getfunc(m, 2, i<<3, 0); } else if (m->otype == MAT_BRTDF) { nd.dp = NULL; - if (!fundefined(m->oargs.sarg[7])) - loadfunc(m->oargs.sarg[9]); + mf = getfunc(m, 9, 0x3f, 0); } else { nd.dp = NULL; - if (!fundefined(m->oargs.sarg[0])) - loadfunc(m->oargs.sarg[1]); + mf = getfunc(m, 1, 0, 0); } /* set special variables */ setbrdfunc(&nd); /* compute transmitted ray */ + tspect = 0.; if (m->otype == MAT_BRTDF && nd.tspec > FTINY) { RAY sr; errno = 0; - setcolor(ctmp, varvalue(m->oargs.sarg[0]), - varvalue(m->oargs.sarg[1]), - varvalue(m->oargs.sarg[2])); - scalecolor(ctmp, nd.tspec); + setcolor(ctmp, evalue(mf->ep[3]), + evalue(mf->ep[4]), + evalue(mf->ep[5])); + scalecolor(ctmp, nd.trans); if (errno) objerror(m, WARNING, "compute error"); - else if ((dtmp = bright(ctmp)) > FTINY && - rayorigin(&sr, r, TRANS, dtmp) == 0) { - if (DOT(r->pert,r->pert) > FTINY*FTINY) { + else if ((tspect = bright(ctmp)) > FTINY && + rayorigin(&sr, r, TRANS, tspect) == 0) { + if (!(r->crtype & SHADOW) && + DOT(r->pert,r->pert) > FTINY*FTINY) { for (i = 0; i < 3; i++) /* perturb direction */ sr.rdir[i] = r->rdir[i] - .75*r->pert[i]; - normalize(sr.rdir); + if (normalize(sr.rdir) == 0.0) { + objerror(m, WARNING, "illegal perturbation"); + VCOPY(sr.rdir, r->rdir); + } } else { VCOPY(sr.rdir, r->rdir); transtest = 2; @@ -290,17 +285,17 @@ register RAY *r; if (r->crtype & SHADOW) /* the rest is shadow */ return; /* compute reflected ray */ + rspecr = 0.; if (m->otype == MAT_BRTDF && nd.rspec > FTINY) { RAY sr; errno = 0; - setcolor(ctmp, varvalue(m->oargs.sarg[3]), - varvalue(m->oargs.sarg[4]), - varvalue(m->oargs.sarg[5])); - scalecolor(ctmp, nd.rspec); + setcolor(ctmp, evalue(mf->ep[0]), + evalue(mf->ep[1]), + evalue(mf->ep[2])); if (errno) objerror(m, WARNING, "compute error"); - else if ((dtmp = bright(ctmp)) > FTINY && - rayorigin(&sr, r, REFLECTED, dtmp) == 0) { + else if ((rspecr = bright(ctmp)) > FTINY && + rayorigin(&sr, r, REFLECTED, rspecr) == 0) { for (i = 0; i < 3; i++) sr.rdir[i] = r->rdir[i] + 2.0*nd.pdot*nd.pnorm[i]; @@ -310,22 +305,16 @@ register RAY *r; } } /* compute ambient */ - if (nd.rdiff > FTINY) { + if ((dtmp = 1.0-nd.trans-rspecr) > FTINY) { ambient(ctmp, r); - if (m->otype == MAT_BRTDF) - scalecolor(ctmp, nd.rdiff); - else - scalecolor(ctmp, 1.0-nd.trans); + scalecolor(ctmp, dtmp); multcolor(ctmp, nd.mcolor); /* modified by material color */ addcolor(r->rcol, ctmp); /* add to returned color */ } - if (nd.tdiff > FTINY) { /* from other side */ + if ((dtmp = nd.trans-tspect) > FTINY) { /* from other side */ flipsurface(r); ambient(ctmp, r); - if (m->otype == MAT_BRTDF) - scalecolor(ctmp, nd.tdiff); - else - scalecolor(ctmp, nd.trans); + scalecolor(ctmp, dtmp); multcolor(ctmp, nd.mcolor); addcolor(r->rcol, ctmp); flipsurface(r);