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; |
171 |
|
|
172 |
|
if (v == NULL) |
173 |
|
return -1; |
174 |
< |
if ((v[2] < 0) | (v[2] > 1.)) |
174 |
> |
if ((v[2] < 0) | (v[2] > 1.00001)) |
175 |
|
return -1; |
176 |
|
pol = 180.0/M_PI*Acos(v[2]); |
177 |
|
azi = 180.0/M_PI*atan2(v[1], v[0]); |
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; |
295 |
|
mBSDF_color(float coef[], const SDMat *dp, int i, int o) |
296 |
|
{ |
297 |
|
C_COLOR cxy; |
298 |
+ |
double d; |
299 |
|
|
300 |
< |
coef[0] = mBSDF_value(dp, i, o); |
300 |
> |
coef[0] = mBSDF_value(dp, o, i); |
301 |
> |
/* position-specific perturbation */ |
302 |
> |
d = 2*dp->ninc/(i + .22545) + 4*dp->nout/(o + .70281); |
303 |
> |
d -= (int)d; |
304 |
> |
coef[0] *= 1. + 6e-4*(d - .5); |
305 |
|
if (dp->chroma == NULL) |
306 |
|
return 1; /* grayscale */ |
307 |
|
|
308 |
< |
c_decodeChroma(&cxy, dp->chroma[o*dp->ninc + i]); |
308 |
> |
c_decodeChroma(&cxy, mBSDF_chroma(dp,o,i)); |
309 |
|
c_toSharpRGB(&cxy, coef[0], coef); |
310 |
|
coef[0] *= mtx_RGB_coef[0]; |
311 |
|
coef[1] *= mtx_RGB_coef[1]; |
388 |
|
for (i = dp->ninc; i--; ) { |
389 |
|
double hemi = .0; |
390 |
|
for (o = dp->nout; o--; ) |
391 |
< |
hemi += ohma[o] * mBSDF_value(dp, i, o); |
391 |
> |
hemi += ohma[o] * mBSDF_value(dp, o, i); |
392 |
|
if (hemi > df->maxHemi) |
393 |
|
df->maxHemi = hemi; |
394 |
|
} |
524 |
|
if (rowinc) { |
525 |
|
int r = i/dp->nout; |
526 |
|
int c = i - r*dp->nout; |
527 |
< |
mBSDF_value(dp,r,c) = val; |
527 |
> |
mBSDF_value(dp,c,r) = val; |
528 |
|
} else |
529 |
|
dp->bsdf[i] = val; |
530 |
|
sdata = sdnext; |
598 |
|
subtract_min(C_COLOR *cs, SDMat *sm) |
599 |
|
{ |
600 |
|
const int ncomp = 1 + 2*(sm->chroma != NULL); |
601 |
< |
float min_coef[3], coef[3]; |
601 |
> |
float min_coef[3], ymin, coef[3]; |
602 |
|
int i, o, c; |
603 |
|
|
604 |
|
min_coef[0] = min_coef[1] = min_coef[2] = FHUGE; |
609 |
|
if (coef[c] < min_coef[c]) |
610 |
|
min_coef[c] = coef[c]; |
611 |
|
} |
612 |
+ |
ymin = 0; |
613 |
|
for (c = ncomp; c--; ) |
614 |
< |
if (min_coef[c] > FTINY) |
615 |
< |
break; |
608 |
< |
if (c < 0) |
614 |
> |
ymin += min_coef[c]; |
615 |
> |
if (ymin <= .01/M_PI) /* not worth bothering about? */ |
616 |
|
return .0; |
617 |
|
if (ncomp == 1) { /* subtract grayscale minimum */ |
618 |
|
for (i = sm->ninc*sm->nout; i--; ) |
619 |
< |
sm->bsdf[i] -= min_coef[0]; |
619 |
> |
sm->bsdf[i] -= ymin; |
620 |
|
*cs = c_dfcolor; |
621 |
< |
return min_coef[0]*M_PI; |
621 |
> |
return M_PI*ymin; |
622 |
|
} |
623 |
|
/* else subtract colored minimum */ |
624 |
|
for (i = 0; i < sm->ninc; i++) |
629 |
|
coef[c] = (coef[c] - min_coef[c]) / |
630 |
|
mtx_RGB_coef[c]; |
631 |
|
if (c_fromSharpRGB(coef, &cxy) > 1e-5) |
632 |
< |
sm->chroma[o*sm->ninc + i] = c_encodeChroma(&cxy); |
633 |
< |
mBSDF_value(sm,i,o) -= min_coef[0]+min_coef[1]+min_coef[2]; |
632 |
> |
mBSDF_chroma(sm,o,i) = c_encodeChroma(&cxy); |
633 |
> |
mBSDF_value(sm,o,i) -= ymin; |
634 |
|
} |
635 |
|
/* return colored minimum */ |
636 |
|
for (i = 3; i--; ) |
637 |
|
coef[i] = min_coef[i]/mtx_RGB_coef[i]; |
638 |
|
c_fromSharpRGB(coef, cs); |
639 |
|
|
640 |
< |
return (min_coef[0]+min_coef[1]+min_coef[2])*M_PI; |
640 |
> |
return M_PI*ymin; |
641 |
|
} |
642 |
|
|
643 |
|
/* Extract and separate diffuse portion of BSDF & convert color */ |
654 |
|
/* subtract minimum value */ |
655 |
|
dv->cieY = subtract_min(&dv->spec, (SDMat *)df->comp[0].dist); |
656 |
|
df->maxHemi -= dv->cieY; /* adjust maximum hemispherical */ |
657 |
< |
/* make sure everything is set */ |
658 |
< |
c_ccvt(&dv->spec, C_CSXY+C_CSSPEC); |
657 |
> |
|
658 |
> |
c_ccvt(&dv->spec, C_CSXY); /* make sure (x,y) is set */ |
659 |
|
return df; |
660 |
|
} |
661 |
|
|
714 |
|
/* separate diffuse components */ |
715 |
|
sd->rf = extract_diffuse(&sd->rLambFront, sd->rf); |
716 |
|
sd->rb = extract_diffuse(&sd->rLambBack, sd->rb); |
717 |
< |
if (sd->tf != NULL) |
718 |
< |
sd->tf = extract_diffuse(&sd->tLamb, sd->tf); |
719 |
< |
if (sd->tb != NULL) |
720 |
< |
sd->tb = extract_diffuse(&sd->tLamb, sd->tb); |
717 |
> |
sd->tf = extract_diffuse(&sd->tLambFront, sd->tf); |
718 |
> |
if (sd->tb != NULL) { |
719 |
> |
sd->tb = extract_diffuse(&sd->tLambBack, sd->tb); |
720 |
> |
if (sd->tf == NULL) |
721 |
> |
sd->tLambFront = sd->tLambBack; |
722 |
> |
} else if (sd->tf != NULL) |
723 |
> |
sd->tLambBack = sd->tLambFront; |
724 |
|
/* return success */ |
725 |
|
return SDEnone; |
726 |
|
} |
727 |
|
|
728 |
|
/* Get Matrix BSDF value */ |
729 |
|
static int |
730 |
< |
SDgetMtxBSDF(float coef[SDmaxCh], const FVECT outVec, |
731 |
< |
const FVECT inVec, SDComponent *sdc) |
730 |
> |
SDgetMtxBSDF(float coef[SDmaxCh], const FVECT inVec, |
731 |
> |
const FVECT outVec, SDComponent *sdc) |
732 |
|
{ |
733 |
|
const SDMat *dp; |
734 |
|
int i_ndx, o_ndx; |
813 |
|
cmtab[0] = .0; |
814 |
|
for (o = 0; o < cd->calen; o++) { |
815 |
|
if (rev) |
816 |
< |
cmtab[o+1] = mBSDF_value(dp, o, cd->indx) * |
816 |
> |
cmtab[o+1] = mBSDF_value(dp, cd->indx, o) * |
817 |
|
(*dp->ib_ohm)(o, dp->ib_priv); |
818 |
|
else |
819 |
< |
cmtab[o+1] = mBSDF_value(dp, cd->indx, o) * |
819 |
> |
cmtab[o+1] = mBSDF_value(dp, o, cd->indx) * |
820 |
|
(*dp->ob_ohm)(o, dp->ob_priv); |
821 |
|
cmtab[o+1] += cmtab[o]; |
822 |
|
} |
859 |
|
reverse = 1; |
860 |
|
} |
861 |
|
cdlast = NULL; /* check for it in cache list */ |
862 |
+ |
/* PLACE MUTEX LOCK HERE FOR THREAD-SAFE */ |
863 |
|
for (cd = (SDMatCDst *)sdc->cdList; cd != NULL; |
864 |
|
cdlast = cd, cd = cd->next) |
865 |
|
if (cd->indx == myCD.indx && (cd->calen == myCD.calen) & |
883 |
|
cd->next = (SDMatCDst *)sdc->cdList; |
884 |
|
sdc->cdList = (SDCDst *)cd; |
885 |
|
} |
886 |
+ |
/* END MUTEX LOCK */ |
887 |
|
return (SDCDst *)cd; /* ready to go */ |
888 |
|
} |
889 |
|
|
916 |
|
} |
917 |
|
|
918 |
|
/* Fixed resolution BSDF methods */ |
919 |
< |
SDFunc SDhandleMtx = { |
919 |
> |
const SDFunc SDhandleMtx = { |
920 |
|
&SDgetMtxBSDF, |
921 |
|
&SDqueryMtxProjSA, |
922 |
|
&SDgetMtxCDist, |