--- ray/src/common/bsdf_m.c 2011/02/24 20:14:26 3.8 +++ ray/src/common/bsdf_m.c 2011/04/20 14:44:05 3.11 @@ -1,5 +1,5 @@ #ifndef lint -static const char RCSid[] = "$Id: bsdf_m.c,v 3.8 2011/02/24 20:14:26 greg Exp $"; +static const char RCSid[] = "$Id: bsdf_m.c,v 3.11 2011/04/20 14:44:05 greg Exp $"; #endif /* * bsdf_m.c @@ -81,12 +81,12 @@ static int nabases = 3; /* current number of defined b static int fequal(double a, double b) { - if (b != .0) + if (b != 0) a = a/b - 1.; return (a <= 1e-6) & (a >= -1e-6); } -/* returns the name of the given tag */ +/* Returns the name of the given tag */ #ifdef ezxml_name #undef ezxml_name static char * @@ -98,7 +98,7 @@ ezxml_name(ezxml_t xml) } #endif -/* returns the given tag's character content or empty string if none */ +/* Returns the given tag's character content or empty string if none */ #ifdef ezxml_txt #undef ezxml_txt static char * @@ -159,14 +159,16 @@ SDnewMatrix(int ni, int no) /* get vector for this angle basis index (front exiting) */ static int -fo_getvec(FVECT v, int ndx, double randX, void *p) +fo_getvec(FVECT v, double ndxr, void *p) { - ANGLE_BASIS *ab = (ANGLE_BASIS *)p; + ANGLE_BASIS *ab = (ANGLE_BASIS *)p; + int ndx = (int)ndxr; + double randX = ndxr - ndx; double rx[2]; int li; double pol, azi, d; - if ((ndx < 0) | (ndx >= ab->nangles)) + if ((ndxr < 0) | (ndx >= ab->nangles)) return RC_FAIL; for (li = 0; ndx >= ab->lat[li].nphis; li++) ndx -= ab->lat[li].nphis; @@ -185,13 +187,13 @@ fo_getvec(FVECT v, int ndx, double randX, void *p) static int fo_getndx(const FVECT v, void *p) { - ANGLE_BASIS *ab = (ANGLE_BASIS *)p; + ANGLE_BASIS *ab = (ANGLE_BASIS *)p; int li, ndx; double pol, azi, d; if (v == NULL) return -1; - if ((v[2] < .0) | (v[2] > 1.0)) + if ((v[2] < 0) | (v[2] > 1.)) return -1; pol = 180.0/M_PI*acos(v[2]); azi = 180.0/M_PI*atan2(v[1], v[0]); @@ -237,9 +239,9 @@ io_getohm(int ndx, void *p) /* get vector for this angle basis index (back incident) */ static int -bi_getvec(FVECT v, int ndx, double randX, void *p) +bi_getvec(FVECT v, double ndxr, void *p) { - if (!fo_getvec(v, ndx, randX, p)) + if (!fo_getvec(v, ndxr, p)) return RC_FAIL; v[0] = -v[0]; @@ -264,9 +266,9 @@ bi_getndx(const FVECT v, void *p) /* get vector for this angle basis index (back exiting) */ static int -bo_getvec(FVECT v, int ndx, double randX, void *p) +bo_getvec(FVECT v, double ndxr, void *p) { - if (!fo_getvec(v, ndx, randX, p)) + if (!fo_getvec(v, ndxr, p)) return RC_FAIL; v[2] = -v[2]; @@ -289,9 +291,9 @@ bo_getndx(const FVECT v, void *p) /* get vector for this angle basis index (front incident) */ static int -fi_getvec(FVECT v, int ndx, double randX, void *p) +fi_getvec(FVECT v, double ndxr, void *p) { - if (!fo_getvec(v, ndx, randX, p)) + if (!fo_getvec(v, ndxr, p)) return RC_FAIL; v[0] = -v[0]; @@ -418,10 +420,11 @@ load_bsdf_data(SDData *sd, ezxml_t wdb, int rowinc) sdata = ezxml_txt(ezxml_child(wdb, "WavelengthDataDirection")); /* * Remember that front and back are reversed from WINDOW 6 orientations + * Favor their "Front" (incoming light) since that's more often valid */ - if ((tfront = !strcasecmp(sdata, "Transmission Back")) || - (sd->tf == NULL && - !strcasecmp(sdata, "Transmission Front"))) { + tfront = !strcasecmp(sdata, "Transmission Back"); + if (!strcasecmp(sdata, "Transmission Front") || + tfront & (sd->tf == NULL)) { if (sd->tf != NULL) SDfreeSpectralDF(sd->tf); if ((sd->tf = SDnewSpectralDF(1)) == NULL) @@ -504,7 +507,7 @@ load_bsdf_data(SDData *sd, ezxml_t wdb, int rowinc) df->comp[0].dist = dp; df->comp[0].func = &SDhandleMtx; /* read BSDF data */ - sdata = ezxml_txt(ezxml_child(wdb,"ScatteringData")); + sdata = ezxml_txt(ezxml_child(wdb,"ScatteringData")); if (!sdata || !*sdata) { sprintf(SDerrorDetail, "Missing BSDF ScatteringData in '%s'", sd->name); @@ -648,16 +651,23 @@ SDgetMtxBSDF(float coef[SDmaxCh], const FVECT outVec, /* Query solid angle for vector */ static SDError -SDqueryMtxProjSA(double *psa, const FVECT vec, int qflags, const void *dist) +SDqueryMtxProjSA(double *psa, const FVECT v1, const RREAL *v2, + int qflags, const void *dist) { const SDMat *dp = (const SDMat *)dist; double inc_psa, out_psa; /* check arguments */ - if ((psa == NULL) | (vec == NULL) | (dp == NULL)) + if ((psa == NULL) | (v1 == NULL) | (dp == NULL)) return SDEargument; + if (v2 == NULL) + v2 = v1; /* get projected solid angles */ - inc_psa = mBSDF_incohm(dp, mBSDF_incndx(dp, vec)); - out_psa = mBSDF_outohm(dp, mBSDF_outndx(dp, vec)); + out_psa = mBSDF_outohm(dp, mBSDF_outndx(dp, v1)); + inc_psa = mBSDF_incohm(dp, mBSDF_incndx(dp, v2)); + if ((out_psa <= 0) & (inc_psa <= 0)) { + inc_psa = mBSDF_outohm(dp, mBSDF_outndx(dp, v2)); + out_psa = mBSDF_incohm(dp, mBSDF_incndx(dp, v1)); + } switch (qflags) { /* record based on flag settings */ case SDqueryVal: @@ -676,14 +686,14 @@ SDqueryMtxProjSA(double *psa, const FVECT vec, int qfl psa[1] = out_psa; /* fall through */ case SDqueryMin: - if ((inc_psa > .0) & (inc_psa < psa[0])) + if ((inc_psa > 0) & (inc_psa < psa[0])) psa[0] = inc_psa; - if ((out_psa > .0) & (out_psa < psa[0])) + if ((out_psa > 0) & (out_psa < psa[0])) psa[0] = out_psa; break; } /* make sure it's legal */ - return (psa[0] <= .0) ? SDEinternal : SDEnone; + return (psa[0] <= 0) ? SDEinternal : SDEnone; } /* Compute new cumulative distribution from BSDF */ @@ -795,7 +805,7 @@ SDsampMtxCDist(FVECT outVec, double randX, const SDCDs randX = (randX*maxval - mcd->carr[ilower]) / (double)(mcd->carr[iupper] - mcd->carr[ilower]); /* convert index to vector */ - if ((*mcd->ob_vec)(outVec, i, randX, mcd->ob_priv)) + if ((*mcd->ob_vec)(outVec, i+randX, mcd->ob_priv)) return SDEnone; strcpy(SDerrorDetail, "BSDF sampling fault"); return SDEinternal;