23 |
|
#include "pmapdiag.h" |
24 |
|
#include "rcontrib.h" |
25 |
|
#include "otypes.h" |
26 |
+ |
#include "otspecial.h" |
27 |
|
|
28 |
|
|
28 |
– |
|
29 |
|
static void setPmapContribParams (PhotonMap *pmap, LUTAB *srcContrib) |
30 |
|
/* Set parameters for light source contributions */ |
31 |
|
{ |
107 |
|
{ |
108 |
|
unsigned i; |
109 |
|
PhotonSearchQueueNode *sqn; |
110 |
< |
float r, invArea; |
110 |
> |
float r2, invArea; |
111 |
|
RREAL rayCoeff [3]; |
112 |
|
Photon *photon; |
113 |
< |
static char warn = 1; |
113 |
> |
static char warnPos = 1, warnDir = 1; |
114 |
|
|
115 |
|
setcolor(irrad, 0, 0, 0); |
116 |
|
|
140 |
|
return; |
141 |
|
} |
142 |
|
|
143 |
< |
/* Average (squared) radius between furthest two photons to improve |
144 |
< |
* accuracy and get inverse search area 1 / (PI * r^2), with extra |
145 |
< |
* normalisation factor 1 / PI for ambient calculation */ |
143 |
> |
/* Average radius^2 between furthest two photons to improve accuracy and |
144 |
> |
* get inverse search area 1 / (PI * r^2), with extra normalisation |
145 |
> |
* factor 1 / PI for ambient calculation */ |
146 |
|
sqn = pmap -> squeue.node + 1; |
147 |
< |
r = max(sqn -> dist2, (sqn + 1) -> dist2); |
148 |
< |
r = 0.25 * (pmap -> maxDist2 + r + 2 * sqrt(pmap -> maxDist2 * r)); |
149 |
< |
invArea = 1 / (PI * PI * r); |
147 |
> |
r2 = max(sqn -> dist2, (sqn + 1) -> dist2); |
148 |
> |
r2 = 0.25 * (pmap -> maxDist2 + r2 + 2 * sqrt(pmap -> maxDist2 * r2)); |
149 |
> |
invArea = 1 / (PI * PI * r2); |
150 |
|
|
151 |
|
/* Skip the extra photon */ |
152 |
|
for (i = 1 ; i < pmap -> squeue.tail; i++, sqn++) { |
158 |
|
scalecolor(flux, invArea); |
159 |
|
#ifdef PMAP_EPANECHNIKOV |
160 |
|
/* Apply Epanechnikov kernel to photon flux based on photon distance */ |
161 |
< |
scalecolor(flux, 2 * (1 - sqn -> dist2 / r)); |
161 |
> |
scalecolor(flux, 2 * (1 - sqn -> dist2 / r2)); |
162 |
|
#endif |
163 |
|
addcolor(irrad, flux); |
164 |
|
|
188 |
|
#else |
189 |
|
/* No primary hitpoints; set dummy ray origin and warn once */ |
190 |
|
srcRay.rorg [0] = srcRay.rorg [1] = srcRay.rorg [2] = 0; |
191 |
< |
if (warn) { |
192 |
< |
error(WARNING, "no photon primary hitpoints for bin evaluation;" |
193 |
< |
" using dummy (0,0,0) !"); |
194 |
< |
warn = 0; |
191 |
> |
if (warnPos) { |
192 |
> |
error(WARNING, |
193 |
> |
"no photon primary hitpoints for bin evaluation; " |
194 |
> |
"using dummy (0,0,0)! Recompile with -DPMAP_CBDM."); |
195 |
> |
warnPos = 0; |
196 |
|
} |
197 |
|
#endif |
198 |
+ |
#ifdef PMAP_PRIMARYDIR |
199 |
|
decodedir(srcRay.rdir, primary -> dir); |
200 |
+ |
#else |
201 |
+ |
/* No primary incident direction; set dummy and warn once */ |
202 |
+ |
if (warnDir) { |
203 |
+ |
error(WARNING, |
204 |
+ |
"no photon primary directions for bin evaluation; " |
205 |
+ |
"using dummy (0,0,0)! Recompile with -DPMAP_CBDM."); |
206 |
+ |
warnDir = 0; |
207 |
+ |
} |
208 |
+ |
srcRay.rdir [0] = srcRay.rdir [1] = srcRay.rdir [2] = 0; |
209 |
+ |
#endif |
210 |
|
|
211 |
|
if (!(sp->sflags & SDISTANT |
212 |
|
? sourcehit(&srcRay) |