101 |
|
FVECT vsrc, vsmp, vjit; |
102 |
|
double tomega; |
103 |
|
double sf, tsr, sd[2]; |
104 |
< |
COLOR csmp; |
104 |
> |
COLOR csmp, cdiff; |
105 |
> |
double diffY; |
106 |
|
SDValue sv; |
107 |
|
SDError ec; |
108 |
|
int i; |
109 |
|
/* transform source direction */ |
110 |
|
if (SDmapDir(vsrc, ndp->toloc, ldir) != SDEnone) |
111 |
|
return(0); |
112 |
+ |
/* will discount diffuse portion */ |
113 |
+ |
switch ((vsrc[2] > 0)<<1 | (ndp->vray[2] > 0)) { |
114 |
+ |
case 3: |
115 |
+ |
if (ndp->sd->rf == NULL) |
116 |
+ |
return(0); /* all diffuse */ |
117 |
+ |
sv = ndp->sd->rLambFront; |
118 |
+ |
break; |
119 |
+ |
case 0: |
120 |
+ |
if (ndp->sd->rb == NULL) |
121 |
+ |
return(0); /* all diffuse */ |
122 |
+ |
sv = ndp->sd->rLambBack; |
123 |
+ |
break; |
124 |
+ |
default: |
125 |
+ |
if ((ndp->sd->tf == NULL) & (ndp->sd->tb == NULL)) |
126 |
+ |
return(0); /* all diffuse */ |
127 |
+ |
sv = ndp->sd->tLamb; |
128 |
+ |
break; |
129 |
+ |
} |
130 |
+ |
if ((sv.cieY *= 1./PI) > FTINY) { |
131 |
+ |
diffY = sv.cieY; |
132 |
+ |
cvt_sdcolor(cdiff, &sv); |
133 |
+ |
} else { |
134 |
+ |
diffY = .0; |
135 |
+ |
setcolor(cdiff, .0, .0, .0); |
136 |
+ |
} |
137 |
|
/* assign number of samples */ |
138 |
|
ec = SDsizeBSDF(&tomega, ndp->vray, vsrc, SDqueryMin, ndp->sd); |
139 |
|
if (ec) |
140 |
|
goto baderror; |
141 |
|
/* check indirect over-counting */ |
142 |
|
if (ndp->thick != 0 && ndp->pr->crtype & (SPECULAR|AMBIENT) |
143 |
< |
&& vsrc[2] > 0 ^ ndp->vray[2] > 0) { |
143 |
> |
&& (vsrc[2] > 0) ^ (ndp->vray[2] > 0)) { |
144 |
|
double dx = vsrc[0] + ndp->vray[0]; |
145 |
|
double dy = vsrc[1] + ndp->vray[1]; |
146 |
|
if (dx*dx + dy*dy <= omega+tomega) |
173 |
|
ec = SDevalBSDF(&sv, vjit, vsmp, ndp->sd); |
174 |
|
if (ec) |
175 |
|
goto baderror; |
176 |
< |
if (sv.cieY <= FTINY) /* worth using? */ |
177 |
< |
continue; |
176 |
> |
if (sv.cieY - diffY <= FTINY) { |
177 |
> |
addcolor(cval, cdiff); |
178 |
> |
continue; /* no specular part */ |
179 |
> |
} |
180 |
|
cvt_sdcolor(csmp, &sv); |
181 |
< |
addcolor(cval, csmp); /* average it in */ |
181 |
> |
addcolor(cval, csmp); /* else average it in */ |
182 |
|
++ok; |
183 |
|
} |
184 |
+ |
if (!ok) { |
185 |
+ |
setcolor(cval, .0, .0, .0); |
186 |
+ |
return(0); /* no valid specular samples */ |
187 |
+ |
} |
188 |
|
sf = 1./(double)nsamp; |
189 |
|
scalecolor(cval, sf); |
190 |
< |
return(ok); |
190 |
> |
/* subtract diffuse contribution */ |
191 |
> |
for (i = 3*(diffY > FTINY); i--; ) |
192 |
> |
if ((colval(cval,i) -= colval(cdiff,i)) < .0) |
193 |
> |
colval(cval,i) = .0; |
194 |
> |
return(1); |
195 |
|
baderror: |
196 |
|
objerror(ndp->mp, USER, transSDError(ec)); |
197 |
|
return(0); /* gratis return */ |
384 |
|
continue; /* Russian roulette victim */ |
385 |
|
} |
386 |
|
/* need to offset origin? */ |
387 |
< |
if (ndp->thick != 0 && ndp->pr->rod > 0 ^ vsmp[2] > 0) |
387 |
> |
if (ndp->thick != 0 && (ndp->pr->rod > 0) ^ (vsmp[2] > 0)) |
388 |
|
VSUM(sr.rorg, sr.rorg, ndp->pr->ron, -ndp->thick); |
389 |
|
rayvalue(&sr); /* send & evaluate sample */ |
390 |
|
multcolor(sr.rcol, sr.rcoef); |