ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/rt/pmcontrib2.c
Revision: 2.2
Committed: Fri Sep 30 16:51:46 2016 UTC (8 years, 7 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.1: +2 -4 lines
Log Message:
Removed Unix-only includes I sloppily copied into Windows module

File Contents

# User Rev Content
1 greg 2.1 #ifndef lint
2 greg 2.2 static const char RCSid[] = "$Id: pmcontrib2.c,v 2.1 2016/09/29 21:51:58 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.2 $Id: pmcontrib2.c,v 2.1 2016/09/29 21:51:58 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    
27    
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     /* Adjust density estimate bandwidth if lower than modifier
85     * count, otherwise contributions are missing */
86     error(WARNING, "contrib density estimate bandwidth too low, "
87     "adjusting to modifier count");
88     contribPmap -> maxGather = numSrcContrib;
89     }
90    
91     /* Sanity check */
92     checkPmapContribs(contribPmap, srcContrib);
93     }
94     }
95    
96    
97    
98     void photonContrib (PhotonMap *pmap, RAY *ray, COLOR irrad)
99     /* Sum up light source contributions from photons in pmap->srcContrib */
100     {
101     unsigned i;
102     PhotonSearchQueueNode *sqn;
103     float r, invArea;
104     RREAL rayCoeff [3];
105     Photon *photon;
106     static char warn = 1;
107    
108     setcolor(irrad, 0, 0, 0);
109    
110     if (!pmap -> maxGather)
111     return;
112    
113     /* Ignore sources */
114     if (ray -> ro && islight(objptr(ray -> ro -> omod) -> otype))
115     return;
116    
117     /* Get cumulative path coefficient up to photon lookup point */
118     raycontrib(rayCoeff, ray, PRIMARY);
119    
120     /* Lookup photons */
121     pmap -> squeue.tail = 0;
122     findPhotons(pmap, ray);
123    
124     /* Need at least 2 photons */
125     if (pmap -> squeue.tail < 2) {
126     #ifdef PMAP_NONEFOUND
127     sprintf(errmsg, "no photons found on %s at (%.3f, %.3f, %.3f)",
128     ray -> ro ? ray -> ro -> oname : "<null>",
129     ray -> rop [0], ray -> rop [1], ray -> rop [2]);
130     error(WARNING, errmsg);
131     #endif
132    
133     return;
134     }
135    
136     /* Average (squared) radius between furthest two photons to improve
137     * accuracy and get inverse search area 1 / (PI * r^2), with extra
138     * normalisation factor 1 / PI for ambient calculation */
139     sqn = pmap -> squeue.node + 1;
140     r = max(sqn -> dist2, (sqn + 1) -> dist2);
141     r = 0.25 * (pmap -> maxDist2 + r + 2 * sqrt(pmap -> maxDist2 * r));
142     invArea = 1 / (PI * PI * r);
143    
144     /* Skip the extra photon */
145     for (i = 1 ; i < pmap -> squeue.tail; i++, sqn++) {
146     COLOR flux;
147    
148     /* Get photon's contribution to density estimate */
149     photon = getNearestPhoton(&pmap -> squeue, sqn -> idx);
150     getPhotonFlux(photon, flux);
151     scalecolor(flux, invArea);
152     #ifdef PMAP_EPANECHNIKOV
153     /* Apply Epanechnikov kernel to photon flux based on photon distance */
154     scalecolor(flux, 2 * (1 - sqn -> dist2 / r));
155     #endif
156     addcolor(irrad, flux);
157    
158     if (pmap -> srcContrib) {
159     const PhotonPrimary *primary = pmap -> primaries +
160     photon -> primary;
161     const SRCREC *sp = &source [primary -> srcIdx];
162     OBJREC *srcMod = findmaterial(sp -> so);
163     MODCONT *srcContrib = (MODCONT*)lu_find(pmap -> srcContrib,
164     srcMod -> oname) -> data;
165     double srcBinReal;
166     int srcBin;
167     RAY srcRay;
168    
169     if (!srcContrib)
170     continue;
171    
172     /* Photon's emitting light source has modifier whose contributions
173     * are sought */
174     if (srcContrib -> binv -> type != NUM) {
175     /* Use intersection function to set shadow ray parameters if
176     * it's not simply a constant */
177     rayorigin(&srcRay, SHADOW, NULL, NULL);
178     srcRay.rsrc = primary -> srcIdx;
179     #ifdef PMAP_PRIMARYPOS
180     VCOPY(srcRay.rorg, primary -> pos);
181     #else
182     /* No primary hitpoints; set dummy ray origin and warn once */
183     srcRay.rorg [0] = srcRay.rorg [1] = srcRay.rorg [2] = 0;
184     if (warn) {
185     error(WARNING, "no photon primary hitpoints for bin evaluation;"
186     " using dummy (0,0,0) !");
187     warn = 0;
188     }
189     #endif
190     decodedir(srcRay.rdir, primary -> dir);
191    
192     if (!(sp->sflags & SDISTANT
193     ? sourcehit(&srcRay)
194     : (*ofun[sp -> so -> otype].funp)(sp -> so, &srcRay)))
195     continue; /* XXX shouldn't happen! */
196    
197     worldfunc(RCCONTEXT, &srcRay);
198     set_eparams((char *)srcContrib -> params);
199     }
200    
201     if ((srcBinReal = evalue(srcContrib -> binv)) < -.5)
202     continue; /* silently ignore negative bins */
203    
204     if ((srcBin = srcBinReal + .5) >= srcContrib -> nbins) {
205     error(WARNING, "bad bin number (ignored)");
206     continue;
207     }
208    
209     if (!contrib) {
210     /* Ray coefficient mode; normalise by light source radiance
211     * after applying distrib pattern */
212     int j;
213    
214     raytexture(ray, srcMod -> omod);
215     setcolor(ray -> rcol, srcMod -> oargs.farg [0],
216     srcMod -> oargs.farg [1], srcMod -> oargs.farg [2]);
217     multcolor(ray -> rcol, ray -> pcol);
218     for (j = 0; j < 3; j++)
219     flux [j] = ray -> rcol [j] ? flux [j] / ray -> rcol [j] : 0;
220     }
221    
222     multcolor(flux, rayCoeff);
223     addcolor(srcContrib -> cbin [srcBin], flux);
224     }
225     }
226    
227     return;
228     }