ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/rt/pmcontrib2.c
Revision: 2.6
Committed: Sun Nov 19 00:43:00 2023 UTC (6 months, 1 week ago) by greg
Content type: text/plain
Branch: MAIN
CVS Tags: HEAD
Changes since 2.5: +5 -5 lines
Log Message:
fix: temporary patch to get photon map to compile

File Contents

# User Rev Content
1 greg 2.1 #ifndef lint
2 greg 2.6 static const char RCSid[] = "$Id: pmcontrib2.c,v 2.5 2018/11/08 00:54:07 greg Exp $";
3 greg 2.1 #endif
4    
5     /*
6     ======================================================================
7     Photon map support for using light source contributions
8    
9     Roland Schregle (roland.schregle@{hslu.ch, gmail.com})
10     (c) Lucerne University of Applied Sciences and Arts,
11     supported by the Swiss National Science Foundation (SNSF, #147053)
12     ======================================================================
13    
14 greg 2.6 $Id: pmcontrib2.c,v 2.5 2018/11/08 00:54:07 greg Exp $
15 greg 2.1 */
16    
17    
18     #include "pmapcontrib.h"
19     #include "pmapmat.h"
20     #include "pmapsrc.h"
21     #include "pmaprand.h"
22     #include "pmapio.h"
23     #include "pmapdiag.h"
24     #include "rcontrib.h"
25     #include "otypes.h"
26 greg 2.5 #include "otspecial.h"
27 greg 2.1
28    
29     static void setPmapContribParams (PhotonMap *pmap, LUTAB *srcContrib)
30     /* Set parameters for light source contributions */
31     {
32     /* Set light source modifier list and appropriate callback to extract
33     * their contributions from the photon map */
34     if (pmap) {
35     pmap -> srcContrib = srcContrib;
36     pmap -> lookup = photonContrib;
37     /* Ensure we get all requested photon contribs during lookups */
38     pmap -> gatherTolerance = 1.0;
39     }
40     }
41    
42    
43    
44     static void checkPmapContribs (const PhotonMap *pmap, LUTAB *srcContrib)
45     /* Check modifiers for light source contributions */
46     {
47     const PhotonPrimary *primary = pmap -> primaries;
48     PhotonPrimaryIdx i, found = 0;
49     OBJREC *srcMod;
50    
51     /* Make sure at least one of the modifiers is actually in the pmap,
52     * otherwise findPhotons() winds up in an infinite loop! */
53     for (i = pmap -> numPrimary; i; --i, ++primary) {
54     if (primary -> srcIdx < 0 || primary -> srcIdx >= nsources)
55     error(INTERNAL, "invalid light source index in photon map");
56    
57     srcMod = findmaterial(source [primary -> srcIdx].so);
58     if ((MODCONT*)lu_find(srcContrib, srcMod -> oname) -> data)
59     ++found;
60     }
61    
62     if (!found)
63     error(USER, "modifiers not in photon map");
64     }
65    
66    
67    
68     void initPmapContrib (LUTAB *srcContrib, unsigned numSrcContrib)
69     {
70     unsigned t;
71    
72     for (t = 0; t < NUM_PMAP_TYPES; t++)
73     if (photonMaps [t] && t != PMAP_TYPE_CONTRIB) {
74     sprintf(errmsg, "%s photon map does not support contributions",
75     pmapName [t]);
76     error(USER, errmsg);
77     }
78    
79     /* Get params */
80     setPmapContribParams(contribPmap, srcContrib);
81    
82     if (contribPhotonMapping) {
83     if (contribPmap -> maxGather < numSrcContrib) {
84 rschregle 2.3 #if 0
85 greg 2.1 /* Adjust density estimate bandwidth if lower than modifier
86     * count, otherwise contributions are missing */
87     error(WARNING, "contrib density estimate bandwidth too low, "
88     "adjusting to modifier count");
89     contribPmap -> maxGather = numSrcContrib;
90 rschregle 2.3 #else
91     /* Warn if density estimate bandwidth is lower than modifier
92     * count, since some contributions will be missing */
93     error(WARNING, "photon density estimate bandwidth too low,"
94     " contributions may be underestimated");
95     #endif
96 greg 2.1 }
97    
98     /* Sanity check */
99     checkPmapContribs(contribPmap, srcContrib);
100     }
101     }
102    
103    
104    
105     void photonContrib (PhotonMap *pmap, RAY *ray, COLOR irrad)
106     /* Sum up light source contributions from photons in pmap->srcContrib */
107     {
108     unsigned i;
109     PhotonSearchQueueNode *sqn;
110 rschregle 2.4 float r2, invArea;
111 greg 2.6 SCOLOR rayCoeff;
112 greg 2.1 Photon *photon;
113 rschregle 2.4 static char warnPos = 1, warnDir = 1;
114 greg 2.1
115     setcolor(irrad, 0, 0, 0);
116    
117     if (!pmap -> maxGather)
118     return;
119    
120     /* Ignore sources */
121     if (ray -> ro && islight(objptr(ray -> ro -> omod) -> otype))
122     return;
123    
124     /* Get cumulative path coefficient up to photon lookup point */
125     raycontrib(rayCoeff, ray, PRIMARY);
126    
127     /* Lookup photons */
128     pmap -> squeue.tail = 0;
129     findPhotons(pmap, ray);
130    
131     /* Need at least 2 photons */
132     if (pmap -> squeue.tail < 2) {
133     #ifdef PMAP_NONEFOUND
134     sprintf(errmsg, "no photons found on %s at (%.3f, %.3f, %.3f)",
135     ray -> ro ? ray -> ro -> oname : "<null>",
136     ray -> rop [0], ray -> rop [1], ray -> rop [2]);
137     error(WARNING, errmsg);
138     #endif
139    
140     return;
141     }
142    
143 rschregle 2.4 /* 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 greg 2.1 sqn = pmap -> squeue.node + 1;
147 rschregle 2.4 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 greg 2.1
151     /* Skip the extra photon */
152     for (i = 1 ; i < pmap -> squeue.tail; i++, sqn++) {
153     COLOR flux;
154    
155     /* Get photon's contribution to density estimate */
156     photon = getNearestPhoton(&pmap -> squeue, sqn -> idx);
157     getPhotonFlux(photon, flux);
158     scalecolor(flux, invArea);
159     #ifdef PMAP_EPANECHNIKOV
160     /* Apply Epanechnikov kernel to photon flux based on photon distance */
161 rschregle 2.4 scalecolor(flux, 2 * (1 - sqn -> dist2 / r2));
162 greg 2.1 #endif
163     addcolor(irrad, flux);
164    
165     if (pmap -> srcContrib) {
166     const PhotonPrimary *primary = pmap -> primaries +
167     photon -> primary;
168     const SRCREC *sp = &source [primary -> srcIdx];
169     OBJREC *srcMod = findmaterial(sp -> so);
170     MODCONT *srcContrib = (MODCONT*)lu_find(pmap -> srcContrib,
171     srcMod -> oname) -> data;
172     double srcBinReal;
173     int srcBin;
174     RAY srcRay;
175    
176     if (!srcContrib)
177     continue;
178    
179     /* Photon's emitting light source has modifier whose contributions
180     * are sought */
181     if (srcContrib -> binv -> type != NUM) {
182     /* Use intersection function to set shadow ray parameters if
183     * it's not simply a constant */
184     rayorigin(&srcRay, SHADOW, NULL, NULL);
185     srcRay.rsrc = primary -> srcIdx;
186     #ifdef PMAP_PRIMARYPOS
187     VCOPY(srcRay.rorg, primary -> pos);
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 rschregle 2.4 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 greg 2.1 }
197     #endif
198 rschregle 2.4 #ifdef PMAP_PRIMARYDIR
199 greg 2.1 decodedir(srcRay.rdir, primary -> dir);
200 rschregle 2.4 #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 greg 2.1
211     if (!(sp->sflags & SDISTANT
212     ? sourcehit(&srcRay)
213     : (*ofun[sp -> so -> otype].funp)(sp -> so, &srcRay)))
214     continue; /* XXX shouldn't happen! */
215    
216     worldfunc(RCCONTEXT, &srcRay);
217     set_eparams((char *)srcContrib -> params);
218     }
219    
220     if ((srcBinReal = evalue(srcContrib -> binv)) < -.5)
221     continue; /* silently ignore negative bins */
222    
223     if ((srcBin = srcBinReal + .5) >= srcContrib -> nbins) {
224     error(WARNING, "bad bin number (ignored)");
225     continue;
226     }
227    
228     if (!contrib) {
229     /* Ray coefficient mode; normalise by light source radiance
230     * after applying distrib pattern */
231     int j;
232    
233     raytexture(ray, srcMod -> omod);
234     setcolor(ray -> rcol, srcMod -> oargs.farg [0],
235     srcMod -> oargs.farg [1], srcMod -> oargs.farg [2]);
236     multcolor(ray -> rcol, ray -> pcol);
237     for (j = 0; j < 3; j++)
238     flux [j] = ray -> rcol [j] ? flux [j] / ray -> rcol [j] : 0;
239     }
240    
241 greg 2.6 multscolor(flux, rayCoeff);
242     saddcolor(mcbin(srcContrib,srcBin), flux);
243 greg 2.1 }
244     }
245    
246     return;
247     }