ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/rt/pmapdata.h
Revision: 2.14
Committed: Wed Apr 8 15:14:21 2020 UTC (4 years, 1 month ago) by rschregle
Content type: text/plain
Branch: MAIN
CVS Tags: rad5R4, rad5R3, HEAD
Changes since 2.13: +6 -5 lines
Log Message:
Fixed est00pid bug in single photon lookups that returned junk when none found, added code to detect and handle (ignore).

File Contents

# User Rev Content
1 rschregle 2.14 /* RCSid $Id: pmapdata.h,v 2.13 2018/12/07 20:02:40 rschregle Exp $ */
2 rschregle 2.10
3 greg 2.1 /*
4 rschregle 2.10 =========================================================================
5     Photon map types and interface to nearest neighbour lookups in underlying
6     point cloud data structure.
7    
8     The default data structure is an in-core kd-tree (see pmapkdt.{h,c}).
9     This can be overriden with the PMAP_OOC compiletime switch, which enables
10     an out-of-core octree (see oococt.{h,c}).
11    
12     Defining PMAP_FLOAT_FLUX stores photon flux as floats rather than packed
13     RGBE for greater precision; this may be necessary when the flux differs
14     significantly in individual colour channels, e.g. with highly saturated
15     colours.
16 greg 2.1
17     Roland Schregle (roland.schregle@{hslu.ch, gmail.com})
18     (c) Fraunhofer Institute for Solar Energy Systems,
19 rschregle 2.2 (c) Lucerne University of Applied Sciences and Arts,
20 rschregle 2.10 supported by the Swiss National Science Foundation (SNSF, #147053)
21     =========================================================================
22 greg 2.1
23 rschregle 2.14 $Id: pmapdata.h,v 2.13 2018/12/07 20:02:40 rschregle Exp $
24 greg 2.1 */
25    
26    
27 rschregle 2.10
28 greg 2.1 #ifndef PMAPDATA_H
29     #define PMAPDATA_H
30    
31 rschregle 2.13 #ifndef NIX
32     #if defined(_WIN32) || defined(_WIN64)
33     #define NIX 0
34     #else
35     #define NIX 1
36     #endif
37     #endif
38 rschregle 2.11
39     #if (defined(PMAP_OOC) && !NIX)
40     #error "OOC currently only supported on NIX -- tuff luck."
41     #endif
42    
43 rschregle 2.13 #ifdef PMAP_CBDM
44     /* Enable photon primary hitpoints and incident directions (see struct
45     * PhotonPrimary below). Note this will increase the size of photon
46     * primaries 9-fold (10-fold after alignment)!!! */
47     #define PMAP_PRIMARYPOS
48     #define PMAP_PRIMARYDIR
49     #endif
50 rschregle 2.11
51 rschregle 2.13 #include "ray.h"
52 greg 2.1 #include "pmaptype.h"
53 rschregle 2.11 #include "paths.h"
54 greg 2.1 #include "lookup.h"
55 rschregle 2.10 #include <stdint.h>
56 greg 2.1
57    
58 rschregle 2.10
59 greg 2.1 /* Primary photon ray for light source contributions */
60     typedef struct {
61 rschregle 2.10 int16 srcIdx; /* Index of emitting light source */
62     /* !!! REDUCED FROM 32 BITS !!! */
63 rschregle 2.13 #ifdef PMAP_PRIMARYDIR
64 rschregle 2.10 int32 dir; /* Encoded ray direction */
65 rschregle 2.13 #endif
66     #ifdef PMAP_PRIMARYPOS
67 rschregle 2.10 float pos [3]; /* Hit point */
68 rschregle 2.13 #endif
69 greg 2.1 } PhotonPrimary;
70    
71 rschregle 2.10 #define photonSrcIdx(pm, p) ((pm)->primaries[(p)->primary].srcIdx)
72    
73    
74    
75     /* Photon primary ray index type and limit */
76 rschregle 2.13 typedef uint32 PhotonPrimaryIdx;
77 rschregle 2.10 #define PMAP_MAXPRIMARY UINT32_MAX
78    
79     /* Macros for photon's generating subprocess field */
80 rschregle 2.11 #ifdef PMAP_OOC
81 rschregle 2.10 #define PMAP_PROCBITS 7
82 rschregle 2.13 #else
83     #define PMAP_PROCBITS 5
84 rschregle 2.10 #endif
85     #define PMAP_MAXPROC (1 << PMAP_PROCBITS)
86     #define PMAP_GETRAYPROC(r) ((r) -> crtype >> 8)
87     #define PMAP_SETRAYPROC(r,p) ((r) -> crtype |= p << 8)
88    
89     /* Tolerance for photon normal check during lookups */
90     #define PMAP_NORM_TOL 0.02
91    
92 greg 2.1
93    
94     typedef struct {
95 rschregle 2.10 float pos [3]; /* Photon position */
96     signed char norm [3]; /* Surface normal at pos (incident
97     direction for volume photons) */
98     union {
99     struct {
100     #ifndef PMAP_OOC
101     unsigned char discr : 2; /* kd-tree discriminator axis */
102     #endif
103     unsigned char caustic : 1; /* Specularly scattered (=caustic) */
104    
105     /* Photon's generating subprocess index, used for primary ray
106     * index linearisation when building contrib pmaps; note this is
107     * reduced for kd-tree to accommodate the discriminator field */
108     unsigned char proc : PMAP_PROCBITS;
109     };
110    
111     unsigned char flags;
112     };
113    
114     #ifdef PMAP_FLOAT_FLUX
115 rschregle 2.13 COLOR flux;
116 rschregle 2.10 #else
117 rschregle 2.13 COLR flux;
118 rschregle 2.10 #endif
119     PhotonPrimaryIdx primary; /* Index to primary ray */
120     } Photon;
121    
122 greg 2.1
123    
124 rschregle 2.10 /* Define PMAP_FLOAT_FLUX to store photon flux as floats instead of
125     * compact RGBE, which was found to improve accuracy in analytical
126     * validation. */
127     #ifdef PMAP_FLOAT_FLUX
128     #define setPhotonFlux(p,f) copycolor((p) -> flux, f)
129     #define getPhotonFlux(p,f) copycolor(f, (p) -> flux)
130     #else
131     #define setPhotonFlux(p,f) setcolr((p)->flux, (f)[0], (f)[1], (f)[2])
132     #define getPhotonFlux(p,f) colr_color(f, (p) -> flux)
133     #endif
134 greg 2.1
135    
136     /* Bias compensation history node */
137 rschregle 2.13 typedef struct {
138 greg 2.1 COLOR irrad;
139     float weight;
140 rschregle 2.10 } PhotonBiasCompNode;
141    
142 greg 2.1
143 rschregle 2.10 /* Forward declaration */
144     struct PhotonMap;
145    
146    
147     /* Define search queue and underlying data struct types */
148     #ifdef PMAP_OOC
149     #include "pmapooc.h"
150     #else
151     #include "pmapkdt.h"
152     #endif
153 greg 2.1
154    
155 rschregle 2.11 /* Mean size of heapfile write buffer, in number of photons */
156     #define PMAP_HEAPBUFSIZE 1e6
157    
158     /* Mean idle time between heap locking attempts, in usec */
159     #define PMAP_HEAPBUFSLEEP 2e6
160    
161     /* Temporary filename for photon heaps */
162     #define PMAP_TMPFNAME TEMPLATE
163     #define PMAP_TMPFNLEN (TEMPLEN + 1)
164    
165    
166 greg 2.1 typedef struct PhotonMap {
167 rschregle 2.10 PhotonMapType type; /* See pmaptype.h */
168     char *fileName; /* Photon map file */
169    
170    
171     /* ================================================================
172     * PRE/POST-BUILD STORAGE
173     * ================================================================ */
174     FILE *heap; /* Unsorted photon heap prior to
175     construction of store */
176 rschregle 2.11 char heapFname [sizeof(PMAP_TMPFNAME)];
177 rschregle 2.10 Photon *heapBuf; /* Write buffer for above */
178     unsigned long heapBufLen, /* Current & max size of heapBuf */
179     heapBufSize;
180 rschregle 2.11 PhotonStorage store; /* Photon storage in space
181 rschregle 2.13 subdividing data struct */
182 rschregle 2.10
183     /* ================================================================
184     * PHOTON DISTRIBUTION STUFF
185     * ================================================================ */
186     unsigned long distribTarget, /* Num stored specified by user */
187     numPhotons; /* Num actually stored */
188     float distribRatio; /* Probability of photon storage */
189     COLOR photonFlux; /* Average photon flux */
190     unsigned short randState [3]; /* Local RNG state */
191    
192    
193     /* ================================================================
194     * PHOTON LOOKUP STUFF
195     * ================================================================ */
196     union { /* Flags passed to findPhotons() */
197     char lookupCaustic : 1;
198     char lookupFlags;
199     };
200    
201     PhotonSearchQueue squeue; /* Search queue for photon lookups */
202     unsigned minGather, /* Specified min/max photons per */
203     maxGather; /* density estimate */
204    
205     /* NOTE: All distances are SQUARED */
206     float maxDist2, /* Max search radius */
207     maxDist0, /* Initial value for above */
208     maxDist2Limit, /* Hard limit for above */
209     gatherTolerance; /* Fractional deviation from minGather/
210     maxGather for short lookup */
211     void (*lookup)(struct PhotonMap*,
212     RAY*, COLOR); /* Callback for type-specific photon
213     * lookup (usually density estimate) */
214    
215    
216     /* ================================================================
217     * BIAS COMPENSATION STUFF
218 rschregle 2.13 * ================================================================ */
219 rschregle 2.10 PhotonBiasCompNode *biasCompHist; /* Bias compensation history */
220    
221    
222     /* ================================================================
223     * STATISTIX
224 rschregle 2.13 * ================================================================ */
225 rschregle 2.10 unsigned long totalGathered, /* Total photons gathered */
226     numDensity, /* Num density estimates */
227     numLookups, /* Counters for short photon lookups */
228     numShortLookups;
229    
230     unsigned minGathered, /* Min/max photons actually gathered */
231     maxGathered, /* per density estimate */
232     shortLookupPct; /* % of short lookups for stats */
233    
234     float minError, /* Min/max/rms density estimate error */
235     maxError,
236     rmsError,
237     CoGdist, /* Avg distance to centre of gravity */
238     maxPos [3], /* Max & min photon positions */
239     minPos [3];
240    
241     FVECT CoG; /* Centre of gravity (avg photon pos) */
242    
243    
244     /* ================================================================
245     * PHOTON CONTRIB/COEFF STUFF
246     * ================================================================ */
247     PhotonPrimary *primaries, /* Photon primary array for rendering */
248     lastPrimary; /* Current primary for photon distrib */
249     PhotonPrimaryIdx numPrimary; /* Number of primary rays */
250     LUTAB *srcContrib; /* Lookup table for source contribs */
251 greg 2.1 } PhotonMap;
252    
253    
254    
255     /* Photon maps by type (see PhotonMapType) */
256 rschregle 2.10 extern PhotonMap *photonMaps [];
257 greg 2.1
258     /* Macros for specific photon map types */
259 rschregle 2.10 #define globalPmap (photonMaps [PMAP_TYPE_GLOBAL])
260     #define preCompPmap (photonMaps [PMAP_TYPE_PRECOMP])
261     #define causticPmap (photonMaps [PMAP_TYPE_CAUSTIC])
262     #define volumePmap (photonMaps [PMAP_TYPE_VOLUME])
263     #define directPmap (photonMaps [PMAP_TYPE_DIRECT])
264     #define contribPmap (photonMaps [PMAP_TYPE_CONTRIB])
265    
266     /* Photon map type tests */
267     #define isGlobalPmap(p) ((p) -> type == PMAP_TYPE_GLOBAL)
268     #define isCausticPmap(p) ((p) -> type == PMAP_TYPE_CAUSTIC)
269     #define isContribPmap(p) ((p) -> type == PMAP_TYPE_CONTRIB)
270     #define isVolumePmap(p) ((p) -> type == PMAP_TYPE_VOLUME)
271 greg 2.1
272    
273    
274     void initPhotonMap (PhotonMap *pmap, PhotonMapType t);
275     /* Initialise empty photon map of specified type */
276    
277 rschregle 2.10 int newPhoton (PhotonMap *pmap, const RAY *ray);
278     /* Create new photon with ray's direction, intersection point, and flux,
279     and append to unsorted photon heap pmap -> heap. The photon is
280     accepted with probability pmap -> distribRatio for global density
281     control; if the photon is rejected, -1 is returned, else 0. The flux
282     is scaled by ray -> rweight and 1 / pmap -> distribRatio. */
283    
284     void initPhotonHeap (PhotonMap *pmap);
285     /* Open photon heap file */
286    
287     void flushPhotonHeap (PhotonMap *pmap);
288     /* Flush photon heap buffa pmap -> heapBuf to heap file pmap -> heap;
289     * used by newPhoton() and to finalise heap in distribPhotons(). */
290    
291     void buildPhotonMap (PhotonMap *pmap, double *photonFlux,
292     PhotonPrimaryIdx *primaryOfs, unsigned nproc);
293     /* Postpress unsorted photon heap pmap -> heap and build underlying data
294     * structure pmap -> store. This is prerequisite to photon lookups with
295     * findPhotons(). */
296    
297     /* PhotonFlux is the flux per photon averaged over RGB; this is
298     * multiplied with each photon's flux during the postprocess. In the
299     * case of a contribution photon map, this is an array with a separate
300     * flux specific to each light source due to non-uniform photon emission;
301     * Otherwise it is referenced as a scalar value. Flux is not scaled if
302     * photonFlux == NULL. */
303    
304     /* Photon map construction may be parallelised if nproc > 1, if
305     * supported. The heap is destroyed on return. */
306    
307     /* PrimaryOfs is an array of index offsets for the primaries in pmap ->
308     * primaries generated by each of the nproc subprocesses during contrib
309     * photon distribution (see distribPhotonContrib()). These offsets are
310     * used to linearise the photon primary indices in the postprocess. This
311     * linearisation is skipped if primaryOfs == NULL. */
312 greg 2.1
313     void findPhotons (PhotonMap* pmap, const RAY *ray);
314 rschregle 2.10 /* Find pmap -> squeue.len closest photons to ray -> rop with similar
315 greg 2.1 normal. For volume photons ray -> rorg is used and the normal is
316     ignored (being the incident direction in this case). Found photons
317 rschregle 2.10 are placed search queue starting with the furthest photon at pmap ->
318     squeue.node, and pmap -> squeue.tail being the number actually found. */
319 greg 2.1
320 rschregle 2.14 Photon *find1Photon (PhotonMap *pmap, const RAY *ray, Photon *photon);
321     /* Find single closest photon to ray -> rop with similar normal.
322     Return NULL if none found, else the supplied Photon* buffer,
323     indicating that it contains a valid photon. */
324 greg 2.1
325 rschregle 2.10 void getPhoton (PhotonMap *pmap, PhotonIdx idx, Photon *photon);
326     /* Retrieve photon referenced by idx from pmap -> store */
327    
328     Photon *getNearestPhoton (const PhotonSearchQueue *squeue, PhotonIdx idx);
329     /* Retrieve photon from NN search queue after calling findPhotons() */
330    
331     PhotonIdx firstPhoton (const PhotonMap *pmap);
332     /* Index to first photon, to be passed to getPhoton(). Indices to
333     * subsequent photons can be optained via increment operator (++) */
334    
335 greg 2.1 void deletePhotons (PhotonMap*);
336     /* Free dem mammaries... */
337    
338     #endif