50 |
|
or 0 if absorbed and $*%&ed. Analogon to rayparticipate(). */ |
51 |
|
{ |
52 |
|
int i; |
53 |
< |
RREAL cosTheta, cosPhi, du, dv; |
53 |
> |
RREAL xi1, cosTheta, phi, du, dv; |
54 |
|
const float cext = colorAvg(ray -> cext), |
55 |
< |
albedo = colorAvg(ray -> albedo); |
55 |
> |
albedo = colorAvg(ray -> albedo), |
56 |
> |
gecc = ray -> gecc, gecc2 = sqr(gecc); |
57 |
|
FVECT u, v; |
58 |
|
COLOR cvext; |
59 |
|
|
61 |
|
ray -> rmax = -log(pmapRandom(mediumState)) / cext; |
62 |
|
|
63 |
|
while (!localhit(ray, &thescene)) { |
64 |
+ |
if (!incube(&thescene, ray -> rop)) { |
65 |
+ |
/* Terminate photon if it has leaked from the scene */ |
66 |
+ |
#ifdef DEBUG_PMAP |
67 |
+ |
fprintf(stderr, |
68 |
+ |
"Volume photon leaked from scene at [%.3f %.3f %.3f]\n", |
69 |
+ |
ray -> rop [0], ray -> rop [1], ray -> rop [2]); |
70 |
+ |
#endif |
71 |
+ |
return 0; |
72 |
+ |
} |
73 |
+ |
|
74 |
|
setcolor(cvext, exp(-ray -> rmax * ray -> cext [0]), |
75 |
|
exp(-ray -> rmax * ray -> cext [1]), |
76 |
|
exp(-ray -> rmax * ray -> cext [2])); |
99 |
|
scalecolor(ray -> rcol, 1 / albedo); |
100 |
|
|
101 |
|
/* Scatter photon */ |
102 |
< |
cosTheta = ray -> gecc <= FTINY ? 2 * pmapRandom(scatterState) - 1 |
103 |
< |
: 1 / (2 * ray -> gecc) * |
104 |
< |
(1 + ray -> gecc * ray -> gecc - |
105 |
< |
(1 - ray -> gecc * ray -> gecc) / |
106 |
< |
(1 - ray -> gecc + 2 * ray -> gecc * |
107 |
< |
pmapRandom(scatterState))); |
108 |
< |
|
109 |
< |
cosPhi = cos(2 * PI * pmapRandom(scatterState)); |
110 |
< |
du = dv = sqrt(1 - cosTheta * cosTheta); /* sin(theta) */ |
111 |
< |
du *= cosPhi; |
112 |
< |
dv *= sqrt(1 - cosPhi * cosPhi); /* sin(phi) */ |
102 |
> |
xi1 = pmapRandom(scatterState); |
103 |
> |
cosTheta = ray -> gecc <= FTINY |
104 |
> |
? 2 * xi1 - 1 |
105 |
> |
: 0.5 / gecc * |
106 |
> |
(1 + gecc2 - sqr((1 - gecc2) / |
107 |
> |
(1 + gecc * (2 * xi1 - 1)))); |
108 |
> |
|
109 |
> |
phi = 2 * PI * pmapRandom(scatterState); |
110 |
> |
du = dv = sqrt(1 - sqr(cosTheta)); /* sin(theta) */ |
111 |
> |
du *= cos(phi); |
112 |
> |
dv *= sin(phi); |
113 |
|
|
114 |
|
/* Get axes u & v perpendicular to photon direction */ |
115 |
|
i = 0; |
123 |
|
for (i = 0; i < 3; i++) |
124 |
|
ray -> rdir [i] = du * u [i] + dv * v [i] + |
125 |
|
cosTheta * ray -> rdir [i]; |
126 |
+ |
|
127 |
|
ray -> rlvl++; |
128 |
|
ray -> rmax = -log(pmapRandom(mediumState)) / cext; |
129 |
|
} |
130 |
< |
|
130 |
> |
|
131 |
> |
/* Passed through medium until intersecting local object */ |
132 |
|
setcolor(cvext, exp(-ray -> rot * ray -> cext [0]), |
133 |
|
exp(-ray -> rot * ray -> cext [1]), |
134 |
|
exp(-ray -> rot * ray -> cext [2])); |
135 |
|
|
136 |
|
/* Modify ray color and normalise */ |
137 |
|
multcolor(ray -> rcol, cvext); |
138 |
< |
colorNorm(ray -> rcol); |
139 |
< |
|
127 |
< |
/* Passed through medium */ |
138 |
> |
colorNorm(ray -> rcol); |
139 |
> |
|
140 |
|
return 1; |
141 |
|
} |
142 |
|
|