static double l_psize(char *nm) /* compute pixel size in steradians */ { static unsigned long ltick[MAXINP]; static double psize[MAXINP]; FVECT dir0, org, dirx, diry; RREAL locx[2], locy[2]; double d; int fn; register int i; d = argument(1); if (d <= -0.5 || d >= nfiles+0.5) { errno = EDOM; return(0.0); } if (d < 0.5) return((double)nfiles); fn = d - 0.5; if (ltick[fn] != eclock) { /* need to compute? */ psize[fn] = 0.0; if (input[fn].vw.type == 0) errno = EDOM; else if (input[fn].vw.type != VT_PAR && funvalue(vray[6], 1, &d) >= -FTINY) { for (i = 0; i < 3; i++) dir0[i] = funvalue(vray[3+i], 1, &d); pix2loc(locx, &input[fn].rs, xscan+1, ymax-1-yscan); pix2loc(locy, &input[fn].rs, xscan, ymax-yscan); if (viewray(org, dirx, &input[fn].vw, locx[0], locx[1]) >= -FTINY && viewray(org, diry, &input[fn].vw, locy[0], locy[1]) >= -FTINY) { /* approximate solid angle */ for (i = 0; i < 3; i++) { dirx[i] -= dir0[i]; diry[i] -= dir0[i]; } fcross(dir0, dirx, diry); psize[fn] = VLEN(dir0); } } ltick[fn] = eclock; } return(psize[fn]); }
/* Interpolate and output a BSDF function using Klems basis */ static void eval_function(char *funame) { ANGLE_BASIS *abp = get_basis(kbasis); int assignD = (fundefined(funame) < 6); FILE *ofp = open_component_file(CIE_Y); double iovec[6]; double sum; int i, j, n; initurand(npsamps); for (j = 0; j < abp->nangles; j++) { /* run through directions */ for (i = 0; i < abp->nangles; i++) { sum = 0; for (n = npsamps; n--; ) { /* average over patches */ if (output_orient > 0) fo_getvec(iovec+3, j+(n+frandom())/npsamps, abp); else bo_getvec(iovec+3, j+(n+frandom())/npsamps, abp); if (input_orient > 0) fi_getvec(iovec, i+urand(n), abp); else bi_getvec(iovec, i+urand(n), abp); if (assignD) { varset("Dx", '=', -iovec[3]); varset("Dy", '=', -iovec[4]); varset("Dz", '=', -iovec[5]); ++eclock; } sum += funvalue(funame, 6, iovec); } fprintf(ofp, "\t%.3e\n", sum/npsamps); } fputc('\n', ofp); prog_show((j+1.)/abp->nangles); } prog_done(); if (fclose(ofp)) { fprintf(stderr, "%s: error writing Y output\n", progname); exit(1); } }
/* Interpolate and output a BSDF function using Klems basis */ static void eval_function(char *funame) { ANGLE_BASIS *abp = get_basis(kbasis); int assignD = (fundefined(funame) < 6); double iovec[6]; double sum; int i, j, n; initurand(npsamps); data_prologue(); /* begin output */ for (j = 0; j < abp->nangles; j++) { /* run through directions */ for (i = 0; i < abp->nangles; i++) { sum = 0; for (n = npsamps; n--; ) { /* average over patches */ if (output_orient > 0) fo_getvec(iovec+3, j+(n+frandom())/npsamps, abp); else bo_getvec(iovec+3, j+(n+frandom())/npsamps, abp); if (input_orient > 0) fi_getvec(iovec, i+urand(n), abp); else bi_getvec(iovec, i+urand(n), abp); if (assignD) { varset("Dx", '=', -iovec[3]); varset("Dy", '=', -iovec[4]); varset("Dz", '=', -iovec[5]); ++eclock; } sum += funvalue(funame, 6, iovec); } printf("\t%.3e\n", sum/npsamps); } putchar('\n'); } data_epilogue(); /* finish output */ }
static void dirbrdf( /* compute source contribution */ COLOR cval, /* returned coefficient */ void *nnp, /* material data */ FVECT ldir, /* light source direction */ double omega /* light source size */ ) { BRDFDAT *np = nnp; double ldot; double dtmp; COLOR ctmp; FVECT ldx; static double vldx[5], pt[MAXDIM]; char **sa; int i; #define lddx (vldx+1) setcolor(cval, 0.0, 0.0, 0.0); ldot = DOT(np->pnorm, ldir); if (ldot <= FTINY && ldot >= -FTINY) return; /* too close to grazing */ if (ldot < 0.0 ? np->trans <= FTINY : np->trans >= 1.0-FTINY) return; /* wrong side */ if (ldot > 0.0) { /* * Compute and add diffuse reflected component to returned * color. The diffuse reflected component will always be * modified by the color of the material. */ copycolor(ctmp, np->rdiff); dtmp = ldot * omega / PI; scalecolor(ctmp, dtmp); addcolor(cval, ctmp); } else { /* * Diffuse transmitted component. */ copycolor(ctmp, np->tdiff); dtmp = -ldot * omega / PI; scalecolor(ctmp, dtmp); addcolor(cval, ctmp); } if (ldot > 0.0 ? np->rspec <= FTINY : np->tspec <= FTINY) return; /* diffuse only */ /* set up function */ setbrdfunc(np); sa = np->mp->oargs.sarg; errno = 0; /* transform light vector */ multv3(ldx, ldir, funcxf.xfm); for (i = 0; i < 3; i++) lddx[i] = ldx[i]/funcxf.sca; lddx[3] = omega; /* compute BRTDF */ if (np->mp->otype == MAT_BRTDF) { if (sa[6][0] == '0') /* special case */ colval(ctmp,RED) = 0.0; else colval(ctmp,RED) = funvalue(sa[6], 4, lddx); if (sa[7][0] == '0') colval(ctmp,GRN) = 0.0; else if (!strcmp(sa[7],sa[6])) colval(ctmp,GRN) = colval(ctmp,RED); else colval(ctmp,GRN) = funvalue(sa[7], 4, 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], 4, lddx); dtmp = bright(ctmp); } else if (np->dp == NULL) { dtmp = funvalue(sa[0], 4, lddx); setcolor(ctmp, dtmp, dtmp, dtmp); } else { for (i = 0; i < np->dp->nd; i++) pt[i] = funvalue(sa[3+i], 4, lddx); vldx[0] = datavalue(np->dp, pt); dtmp = funvalue(sa[0], 5, vldx); setcolor(ctmp, dtmp, dtmp, dtmp); } if ((errno == EDOM) | (errno == ERANGE)) { objerror(np->mp, WARNING, "compute error"); return; } if (dtmp <= FTINY) return; if (ldot > 0.0) { /* * Compute reflected non-diffuse component. */ if ((np->mp->otype == MAT_MFUNC) | (np->mp->otype == MAT_MDATA)) multcolor(ctmp, np->mcolor); dtmp = ldot * omega * np->rspec; scalecolor(ctmp, dtmp); addcolor(cval, ctmp); } else { /* * Compute transmitted non-diffuse component. */ if ((np->mp->otype == MAT_TFUNC) | (np->mp->otype == MAT_TDATA)) multcolor(ctmp, np->mcolor); dtmp = -ldot * omega * np->tspec; scalecolor(ctmp, dtmp); addcolor(cval, ctmp); } #undef lddx }