| 132 |
|
free(ptr); |
| 133 |
|
} |
| 134 |
|
|
| 135 |
+ |
/* compute square of real value */ |
| 136 |
+ |
static double sq(double x) { return x*x; } |
| 137 |
+ |
|
| 138 |
|
/* Get vector for this angle basis index (front exiting) */ |
| 139 |
|
int |
| 140 |
|
fo_getvec(FVECT v, double ndxr, void *p) |
| 144 |
|
double randX = ndxr - ndx; |
| 145 |
|
double rx[2]; |
| 146 |
|
int li; |
| 147 |
< |
double pol, azi, d; |
| 147 |
> |
double azi, d; |
| 148 |
|
|
| 149 |
|
if ((ndxr < 0) | (ndx >= ab->nangles)) |
| 150 |
|
return RC_FAIL; |
| 151 |
|
for (li = 0; ndx >= ab->lat[li].nphis; li++) |
| 152 |
|
ndx -= ab->lat[li].nphis; |
| 153 |
|
SDmultiSamp(rx, 2, randX); |
| 154 |
< |
pol = M_PI/180.*( (1.-rx[0])*ab->lat[li].tmin + |
| 155 |
< |
rx[0]*ab->lat[li+1].tmin ); |
| 154 |
> |
d = (1. - rx[0])*sq(cos(M_PI/180.*ab->lat[li].tmin)) + |
| 155 |
> |
rx[0]*sq(cos(M_PI/180.*ab->lat[li+1].tmin)); |
| 156 |
> |
v[2] = d = sqrt(d); /* cos(pol) */ |
| 157 |
|
azi = 2.*M_PI*(ndx + rx[1] - .5)/ab->lat[li].nphis; |
| 154 |
– |
v[2] = d = cos(pol); |
| 158 |
|
d = sqrt(1. - d*d); /* sin(pol) */ |
| 159 |
|
v[0] = cos(azi)*d; |
| 160 |
|
v[1] = sin(azi)*d; |
| 187 |
|
return ndx; |
| 188 |
|
} |
| 189 |
|
|
| 187 |
– |
/* compute square of real value */ |
| 188 |
– |
static double sq(double x) { return x*x; } |
| 189 |
– |
|
| 190 |
|
/* Get projected solid angle for this angle basis index (universal) */ |
| 191 |
|
double |
| 192 |
|
io_getohm(int ndx, void *p) |
| 193 |
|
{ |
| 194 |
+ |
static void *last_p = NULL; |
| 195 |
|
static int last_li = -1; |
| 196 |
|
static double last_ohm; |
| 197 |
|
ANGLE_BASIS *ab = (ANGLE_BASIS *)p; |
| 202 |
|
return -1.; |
| 203 |
|
for (li = 0; ndx >= ab->lat[li].nphis; li++) |
| 204 |
|
ndx -= ab->lat[li].nphis; |
| 205 |
< |
if (li == last_li) /* cached latitude? */ |
| 205 |
> |
if ((p == last_p) & (li == last_li)) /* cached latitude? */ |
| 206 |
|
return last_ohm; |
| 207 |
+ |
last_p = p; |
| 208 |
|
last_li = li; |
| 209 |
|
theta = M_PI/180. * ab->lat[li].tmin; |
| 210 |
|
theta1 = M_PI/180. * ab->lat[li+1].tmin; |
| 300 |
|
if (dp->chroma == NULL) |
| 301 |
|
return 1; /* grayscale */ |
| 302 |
|
|
| 303 |
< |
c_decodeChroma(&cxy, dp->chroma[o*dp->ninc + i]); |
| 303 |
> |
c_decodeChroma(&cxy, mBSDF_chroma(dp,i,o)); |
| 304 |
|
c_toSharpRGB(&cxy, coef[0], coef); |
| 305 |
|
coef[0] *= mtx_RGB_coef[0]; |
| 306 |
|
coef[1] *= mtx_RGB_coef[1]; |
| 593 |
|
subtract_min(C_COLOR *cs, SDMat *sm) |
| 594 |
|
{ |
| 595 |
|
const int ncomp = 1 + 2*(sm->chroma != NULL); |
| 596 |
< |
float min_coef[3], coef[3]; |
| 596 |
> |
float min_coef[3], ymin, coef[3]; |
| 597 |
|
int i, o, c; |
| 598 |
|
|
| 599 |
|
min_coef[0] = min_coef[1] = min_coef[2] = FHUGE; |
| 604 |
|
if (coef[c] < min_coef[c]) |
| 605 |
|
min_coef[c] = coef[c]; |
| 606 |
|
} |
| 607 |
+ |
ymin = 0; |
| 608 |
|
for (c = ncomp; c--; ) |
| 609 |
< |
if (min_coef[c] > FTINY) |
| 610 |
< |
break; |
| 608 |
< |
if (c < 0) |
| 609 |
> |
ymin += min_coef[c]; |
| 610 |
> |
if (ymin <= .01/M_PI) /* not worth bothering about? */ |
| 611 |
|
return .0; |
| 612 |
|
if (ncomp == 1) { /* subtract grayscale minimum */ |
| 613 |
|
for (i = sm->ninc*sm->nout; i--; ) |
| 614 |
< |
sm->bsdf[i] -= min_coef[0]; |
| 614 |
> |
sm->bsdf[i] -= ymin; |
| 615 |
|
*cs = c_dfcolor; |
| 616 |
< |
return min_coef[0]*M_PI; |
| 616 |
> |
return M_PI*ymin; |
| 617 |
|
} |
| 618 |
|
/* else subtract colored minimum */ |
| 619 |
|
for (i = 0; i < sm->ninc; i++) |
| 624 |
|
coef[c] = (coef[c] - min_coef[c]) / |
| 625 |
|
mtx_RGB_coef[c]; |
| 626 |
|
if (c_fromSharpRGB(coef, &cxy) > 1e-5) |
| 627 |
< |
sm->chroma[o*sm->ninc + i] = c_encodeChroma(&cxy); |
| 628 |
< |
mBSDF_value(sm,i,o) -= min_coef[0]+min_coef[1]+min_coef[2]; |
| 627 |
> |
mBSDF_chroma(sm,i,o) = c_encodeChroma(&cxy); |
| 628 |
> |
mBSDF_value(sm,i,o) -= ymin; |
| 629 |
|
} |
| 630 |
|
/* return colored minimum */ |
| 631 |
|
for (i = 3; i--; ) |
| 632 |
|
coef[i] = min_coef[i]/mtx_RGB_coef[i]; |
| 633 |
|
c_fromSharpRGB(coef, cs); |
| 634 |
|
|
| 635 |
< |
return (min_coef[0]+min_coef[1]+min_coef[2])*M_PI; |
| 635 |
> |
return M_PI*ymin; |
| 636 |
|
} |
| 637 |
|
|
| 638 |
|
/* Extract and separate diffuse portion of BSDF & convert color */ |
| 649 |
|
/* subtract minimum value */ |
| 650 |
|
dv->cieY = subtract_min(&dv->spec, (SDMat *)df->comp[0].dist); |
| 651 |
|
df->maxHemi -= dv->cieY; /* adjust maximum hemispherical */ |
| 652 |
< |
/* make sure everything is set */ |
| 653 |
< |
c_ccvt(&dv->spec, C_CSXY+C_CSSPEC); |
| 652 |
> |
|
| 653 |
> |
c_ccvt(&dv->spec, C_CSXY); /* make sure (x,y) is set */ |
| 654 |
|
return df; |
| 655 |
|
} |
| 656 |
|
|
| 851 |
|
reverse = 1; |
| 852 |
|
} |
| 853 |
|
cdlast = NULL; /* check for it in cache list */ |
| 854 |
+ |
/* PLACE MUTEX LOCK HERE FOR THREAD-SAFE */ |
| 855 |
|
for (cd = (SDMatCDst *)sdc->cdList; cd != NULL; |
| 856 |
|
cdlast = cd, cd = cd->next) |
| 857 |
|
if (cd->indx == myCD.indx && (cd->calen == myCD.calen) & |
| 875 |
|
cd->next = (SDMatCDst *)sdc->cdList; |
| 876 |
|
sdc->cdList = (SDCDst *)cd; |
| 877 |
|
} |
| 878 |
+ |
/* END MUTEX LOCK */ |
| 879 |
|
return (SDCDst *)cd; /* ready to go */ |
| 880 |
|
} |
| 881 |
|
|
| 908 |
|
} |
| 909 |
|
|
| 910 |
|
/* Fixed resolution BSDF methods */ |
| 911 |
< |
SDFunc SDhandleMtx = { |
| 911 |
> |
const SDFunc SDhandleMtx = { |
| 912 |
|
&SDgetMtxBSDF, |
| 913 |
|
&SDqueryMtxProjSA, |
| 914 |
|
&SDgetMtxCDist, |