15 |
|
|
16 |
|
COLORV * distarr = NULL; /* distribution array */ |
17 |
|
int distsiz = 0; |
18 |
+ |
COLORV * direct_discount = NULL; /* amount to take off direct */ |
19 |
|
|
19 |
– |
|
20 |
|
void |
21 |
|
newdist( /* allocate & clear distribution array */ |
22 |
|
int siz |
41 |
|
} |
42 |
|
|
43 |
|
|
44 |
+ |
static void |
45 |
+ |
new_discount() /* allocate space for direct contrib. record */ |
46 |
+ |
{ |
47 |
+ |
if (distsiz <= 0) |
48 |
+ |
return; |
49 |
+ |
direct_discount = (COLORV *)calloc(distsiz, sizeof(COLOR)); |
50 |
+ |
if (direct_discount == NULL) |
51 |
+ |
error(SYSTEM, "out of memory in new_discount"); |
52 |
+ |
} |
53 |
+ |
|
54 |
+ |
|
55 |
+ |
static void |
56 |
+ |
done_discount() /* clear off direct contrib. record */ |
57 |
+ |
{ |
58 |
+ |
if (direct_discount == NULL) |
59 |
+ |
return; |
60 |
+ |
free((void *)direct_discount); |
61 |
+ |
direct_discount = NULL; |
62 |
+ |
} |
63 |
+ |
|
64 |
+ |
|
65 |
|
int |
66 |
|
process_ray( /* process a ray result or report error */ |
67 |
|
RAY *r, |
79 |
|
multcolor(r->rcol, r->rcoef); /* in case it's a source ray */ |
80 |
|
colp = &distarr[r->rno * 3]; |
81 |
|
addcolor(colp, r->rcol); |
82 |
+ |
if (r->rsrc >= 0 && /* remember source contrib. */ |
83 |
+ |
direct_discount != NULL) { |
84 |
+ |
colp = &direct_discount[r->rno * 3]; |
85 |
+ |
addcolor(colp, r->rcol); |
86 |
+ |
} |
87 |
|
return(1); |
88 |
|
} |
89 |
|
|
153 |
|
d = 5.*FTINY; |
154 |
|
for (i = 3; i--; ) |
155 |
|
sr.rorg[i] += d*nrm[i]; |
156 |
+ |
samplendx++; /* increment sample counter */ |
157 |
|
if (!srcray(&sr, NULL, &si)) |
158 |
|
break; /* end of sources */ |
159 |
|
/* index direction */ |
170 |
|
} else { |
171 |
|
if (v[2] >= -FTINY) |
172 |
|
continue; /* only sample transmission */ |
173 |
< |
d = 1.0 - v[2]*v[2]; |
174 |
< |
i = d*nalt; |
175 |
< |
d = atan2(-v[1], -v[0])/(2.*PI); |
149 |
< |
if (d < 0.0) d += 1.0; |
150 |
< |
j = d*nazi + 0.5; |
151 |
< |
if (j >= nazi) j = 0; |
152 |
< |
sr.rno = i*nazi + j; |
153 |
< |
d = nalt*nazi/PI; |
173 |
> |
v[0] = -v[0]; v[1] = -v[1]; v[2] = -v[2]; |
174 |
> |
sr.rno = flatindex(v, nalt, nazi); |
175 |
> |
d = nalt*nazi*(1./PI) * v[2]; |
176 |
|
} |
177 |
|
d *= si.dom; /* solid angle correction */ |
178 |
|
scalecolor(sr.rcoef, d); |
244 |
|
dv[2] = sqrt(1. - alt); |
245 |
|
} |
246 |
|
|
247 |
+ |
int |
248 |
+ |
flatindex( /* compute index for hemispherical direction */ |
249 |
+ |
FVECT dv, |
250 |
+ |
int nalt, |
251 |
+ |
int nazi |
252 |
+ |
) |
253 |
+ |
{ |
254 |
+ |
double d; |
255 |
+ |
int i, j; |
256 |
+ |
|
257 |
+ |
d = 1.0 - dv[2]*dv[2]; |
258 |
+ |
i = d*nalt; |
259 |
+ |
d = atan2(dv[1], dv[0]) * (0.5/PI); |
260 |
+ |
if (d < 0.0) d += 1.0; |
261 |
+ |
j = d*nazi + 0.5; |
262 |
+ |
if (j >= nazi) j = 0; |
263 |
+ |
return(i*nazi + j); |
264 |
+ |
} |
265 |
|
|
266 |
+ |
|
267 |
|
int |
268 |
|
my_default( /* default illum action */ |
269 |
|
OBJREC *ob, |
391 |
|
raysamp(dim[1], org, dir); |
392 |
|
} |
393 |
|
/* add in direct component? */ |
394 |
< |
if (!directvis && il->flags & IL_LIGHT) { |
394 |
> |
if (!directvis && (il->flags & IL_LIGHT || il->sd != NULL)) { |
395 |
|
MAT4 ixfm; |
396 |
|
if (il->sd == NULL) { |
397 |
|
for (i = 3; i--; ) { |
402 |
|
} |
403 |
|
ixfm[3][0] = ixfm[3][1] = ixfm[3][2] = 0.; |
404 |
|
ixfm[3][3] = 1.; |
405 |
< |
} else if (!invmat4(ixfm, xfm)) |
406 |
< |
objerror(ob, INTERNAL, "cannot invert BSDF transform"); |
405 |
> |
} else { |
406 |
> |
if (!invmat4(ixfm, xfm)) |
407 |
> |
objerror(ob, INTERNAL, |
408 |
> |
"cannot invert BSDF transform"); |
409 |
> |
if (!(il->flags & IL_LIGHT)) |
410 |
> |
new_discount(); |
411 |
> |
} |
412 |
|
dim[0] = random(); |
413 |
|
nallow = 10*il->nsamps; |
414 |
|
for (i = 0; i < il->nsamps; i++) { |
438 |
|
nalt = sqrt(il->sd->nout/PI) + .5; |
439 |
|
nazi = PI*nalt + .5; |
440 |
|
redistribute(il->sd, nalt, nazi, u, v, fa->norm, xfm); |
441 |
+ |
done_discount(); |
442 |
+ |
if (!il->sampdens) |
443 |
+ |
il->sampdens = nalt*nazi/PI + .999; |
444 |
|
} |
445 |
|
/* write out the face and its distribution */ |
446 |
|
if (average(il, distarr, n)) { |
599 |
|
raysamp(dim[1], org, dir); |
600 |
|
} |
601 |
|
/* add in direct component? */ |
602 |
< |
if (!directvis && il->flags & IL_LIGHT) { |
602 |
> |
if (!directvis && (il->flags & IL_LIGHT || il->sd != NULL)) { |
603 |
|
MAT4 ixfm; |
604 |
|
if (il->sd == NULL) { |
605 |
|
for (i = 3; i--; ) { |
610 |
|
} |
611 |
|
ixfm[3][0] = ixfm[3][1] = ixfm[3][2] = 0.; |
612 |
|
ixfm[3][3] = 1.; |
613 |
< |
} else if (!invmat4(ixfm, xfm)) |
614 |
< |
objerror(ob, INTERNAL, "cannot invert BSDF transform"); |
613 |
> |
} else { |
614 |
> |
if (!invmat4(ixfm, xfm)) |
615 |
> |
objerror(ob, INTERNAL, |
616 |
> |
"cannot invert BSDF transform"); |
617 |
> |
if (!(il->flags & IL_LIGHT)) |
618 |
> |
new_discount(); |
619 |
> |
} |
620 |
|
dim[0] = random(); |
621 |
|
for (i = 0; i < il->nsamps; i++) { |
622 |
|
/* randomize location */ |
639 |
|
nalt = sqrt(il->sd->nout/PI) + .5; |
640 |
|
nazi = PI*nalt + .5; |
641 |
|
redistribute(il->sd, nalt, nazi, u, v, co->ad, xfm); |
642 |
+ |
done_discount(); |
643 |
+ |
if (!il->sampdens) |
644 |
+ |
il->sampdens = nalt*nazi/PI + .999; |
645 |
|
} |
646 |
|
/* write out the ring and its distribution */ |
647 |
|
if (average(il, distarr, n)) { |