ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/rt/pmapdata.h
(Generate patch)

Comparing ray/src/rt/pmapdata.h (file contents):
Revision 2.7 by rschregle, Wed Jul 29 18:54:20 2015 UTC vs.
Revision 2.14 by rschregle, Wed Apr 8 15:14:21 2020 UTC

# Line 1 | Line 1
1 + /* RCSid $Id$ */
2 +
3   /*
4 <   ==================================================================
5 <   Photon map data structures and kd-tree handling  
4 >   =========================================================================
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 +
17     Roland Schregle (roland.schregle@{hslu.ch, gmail.com})
18     (c) Fraunhofer Institute for Solar Energy Systems,
19     (c) Lucerne University of Applied Sciences and Arts,
20 <   supported by the Swiss National Science Foundation (SNSF, #147053)
21 <   ==================================================================
20 >       supported by the Swiss National Science Foundation (SNSF, #147053)
21 >   =========================================================================
22    
23     $Id$
24   */
25  
26  
27 +
28   #ifndef PMAPDATA_H
29     #define PMAPDATA_H
30  
31 <   #include "ray.h"  
32 <   #include "pmaptype.h"
33 <   #include "lookup.h"
31 >   #ifndef NIX
32 >      #if defined(_WIN32) || defined(_WIN64)
33 >         #define NIX 0
34 >      #else
35 >         #define NIX 1
36 >      #endif
37 >   #endif
38  
39 +   #if (defined(PMAP_OOC) && !NIX)
40 +      #error "OOC currently only supported on NIX -- tuff luck."
41 +   #endif
42  
43 <   /* Define PMAP_FLOAT_FLUX to store photon flux as floats instead of
44 <    * compact RGBE, which was found to improve accuracy in analytical
45 <    * validation. */
46 <   #ifdef PMAP_FLOAT_FLUX
47 <      #define setPhotonFlux(p,f) copycolor((p) -> flux, f)
48 <      #define getPhotonFlux(p,f) copycolor(f, (p) -> flux)
29 <   #else
30 <      #define setPhotonFlux(p,f) setcolr((p)->flux, (f)[0], (f)[1], (f)[2])
31 <      #define getPhotonFlux(p,f) colr_color(f, (p) -> flux)
43 >   #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  
51 +   #include "ray.h"
52 +   #include "pmaptype.h"
53 +   #include "paths.h"
54 +   #include "lookup.h"
55 +   #include <stdint.h>
56  
57 +
58 +  
59     /* Primary photon ray for light source contributions */
60     typedef struct {
61 <      int32 srcIdx;               /* Index of emitting light source */
62 <      int32 dir;                  /* Encoded ray direction */
63 <      float pos [3];              /* Hit point */
61 >      int16    srcIdx;              /* Index of emitting light source */
62 >                                    /* !!! REDUCED FROM 32 BITS !!! */
63 > #ifdef PMAP_PRIMARYDIR
64 >      int32    dir;                 /* Encoded ray direction */
65 > #endif
66 > #ifdef PMAP_PRIMARYPOS
67 >      float    pos [3];             /* Hit point */
68 > #endif
69     } PhotonPrimary;
70        
71 <   #define photonSrcIdx(pm, p) ((pm) -> primary [(p) -> primary].srcIdx)
71 >   #define photonSrcIdx(pm, p)      ((pm)->primaries[(p)->primary].srcIdx)
72  
73 +
74 +
75 +   /* Photon primary ray index type and limit */
76 +   typedef  uint32            PhotonPrimaryIdx;
77 +   #define  PMAP_MAXPRIMARY   UINT32_MAX
78 +
79 +   /* Macros for photon's generating subprocess field */
80 + #ifdef PMAP_OOC
81 +   #define  PMAP_PROCBITS  7
82 + #else
83 +   #define  PMAP_PROCBITS  5
84 + #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    
45   typedef struct {
46      float pos [3];                 /* Photon position */
47      signed char norm [3];          /* Surface normal at pos (incident
48                                        direction for volume photons) */
49      char flags;                    /* Bit 0-1: kd-tree discriminator axis,
50                                        Bit 2:   caustic photon */
51      #ifdef PMAP_FLOAT_FLUX
52         COLOR flux;
53      #else
54         COLR flux;                  /* Photon flux */
55      #endif
92  
57      uint32 primary;              /* Index to primary ray */
58   } Photon;
93    
94 <   /* Photon flag bitmasks and manipulation macros */
95 <   #define PMAP_DISCR_BIT 3
96 <   #define PMAP_CAUST_BIT 4
97 <   #define photonDiscr(p)       ((p).flags & PMAP_DISCR_BIT)
98 <   #define setPhotonDiscr(p, d) ((p).flags = ((p).flags & ~PMAP_DISCR_BIT) | \
99 <                                              ((d) & PMAP_DISCR_BIT))
94 >   typedef struct {
95 >      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 >      COLOR                flux;
116 > #else
117 >      COLR                 flux;
118 > #endif
119 >      PhotonPrimaryIdx     primary;       /* Index to primary ray */
120 >   } Photon;
121  
67   /* Photon map type tests */
68   #define isGlobalPmap(p)    ((p) -> type == PMAP_TYPE_GLOBAL)
69   #define isCausticPmap(p)   ((p) -> type == PMAP_TYPE_CAUSTIC)
70   #define isContribPmap(p)   ((p) -> type == PMAP_TYPE_CONTRIB)
71   #define isVolumePmap(p)    ((p) -> type == PMAP_TYPE_VOLUME)
122  
123    
124 <   /* Queue node for photon lookups */
125 <   typedef struct {                  
126 <      Photon *photon;
127 <      float dist;
128 <   } PhotonSQNode;
124 >   /* 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  
135 +  
136     /* Bias compensation history node */
137 <   typedef struct {                  
137 >   typedef struct {
138        COLOR irrad;
139        float weight;
140 <   } PhotonBCNode;
140 >   } PhotonBiasCompNode;
141  
142  
143 <   struct PhotonMap;                 /* Forward declarations */
143 >   /* 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  
154 +
155 +   /* 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     typedef struct PhotonMap {
167 <      PhotonMapType type;            /* See pmaptype.h */
168 <      char *fileName;                /* Photon map file */
92 <      Photon *heap;                  /* Photon k-d tree as linear array */
93 <      PhotonSQNode *squeue;          /* Search queue */
94 <      PhotonBCNode *biasCompHist;    /* Bias compensation history */      
95 <      char lookupFlags;              /* Flags passed to findPhotons() */
167 >      PhotonMapType  type;             /* See pmaptype.h */
168 >      char           *fileName;        /* Photon map file */
169        
97      unsigned long distribTarget,   /* Num stored specified by user */
98                    heapSize,
99                    heapSizeInc,
100                    heapEnd,         /* Num actually stored in heap */
101                    numDensity,      /* Num density estimates */
102                    totalGathered,   /* Total photons gathered */
103                    numLookups,      /* Counters for short photon lookups */
104                    numShortLookups;
105                    
106      unsigned minGather,            /* Specified min/max photons per */
107               maxGather,            /* density estimate */
108               squeueSize,
109               squeueEnd,
110               minGathered,          /* Min/max photons actually gathered */
111               maxGathered,          /* per density estimate */
112               shortLookupPct;       /* Percentage of short lookups (for
113                                        statistics output */
114              
115                                     /* NOTE: All distances are SQUARED */
116      float maxDist,                 /* Max search radius during NN search */
117            maxDist0,                /* Initial value for above */
118            maxDistLimit,            /* Hard limit for above */
119            CoGdist,                 /* Avg distance to centre of gravity */
120            maxPos [3], minPos [3],  /* Max & min photon positions */
121            distribRatio,            /* Probability of photon storage */
122            gatherTolerance,         /* Fractional deviation from minGather/
123                                        maxGather for short lookup */
124            minError, maxError,      /* Min/max/rms density estimate error */
125            rmsError;
126            
127      FVECT CoG;                     /* Centre of gravity (avg photon pos) */
128      COLOR photonFlux;              /* Average photon flux */
129      unsigned short randState [3];  /* Local RNG state */
170        
171 <      void (*lookup)(struct PhotonMap*, RAY*, COLOR);  
172 <                                     /* Callback for type-specific photon
173 <                                      * lookup (usually density estimate) */
171 >      /* ================================================================
172 >       * PRE/POST-BUILD STORAGE
173 >       * ================================================================ */
174 >      FILE           *heap;            /* Unsorted photon heap prior to
175 >                                          construction of store */
176 >      char           heapFname [sizeof(PMAP_TMPFNAME)];      
177 >      Photon         *heapBuf;         /* Write buffer for above */
178 >      unsigned long  heapBufLen,       /* Current & max size of heapBuf */
179 >                     heapBufSize;
180 >      PhotonStorage  store;            /* Photon storage in space
181 >                                          subdividing data struct */
182 >      
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 <      PhotonPrimary *primary;        /* Primary photon rays & associated
193 <                                        counters */
194 <      unsigned primarySize, primaryEnd;
195 <              
196 <      LUTAB *srcContrib;             /* lookup table for source contribs */
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 >       * ================================================================ */
219 >      PhotonBiasCompNode   *biasCompHist;    /* Bias compensation history */
220 >      
221 >
222 >      /* ================================================================
223 >       * STATISTIX
224 >       * ================================================================ */
225 >      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     } PhotonMap;
252  
253  
254  
255     /* Photon maps by type (see PhotonMapType) */
256 <   extern PhotonMap *photonMaps [];
256 >   extern PhotonMap  *photonMaps [];
257  
258     /* Macros for specific photon map types */
259 <   #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])
259 >   #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  
272  
273 +
274     void initPhotonMap (PhotonMap *pmap, PhotonMapType t);
275     /* Initialise empty photon map of specified type */
276  
277 <   const PhotonPrimary* addPhotonPrimary (PhotonMap *pmap, const RAY *ray);
161 <   /* Add primary ray for emitted photon and save light source index, origin
162 <    * on source, and emitted direction; used by contrib photons */
163 <
164 <   const Photon* addPhoton (PhotonMap *pmap, const RAY *ray);
277 >   int newPhoton (PhotonMap *pmap, const RAY *ray);
278     /* Create new photon with ray's direction, intersection point, and flux,
279 <      and add to photon map subject to acceptance probability pmap ->
280 <      distribRatio for global density control; if the photon is rejected,
281 <      NULL is returned. The flux is scaled by ray -> rweight and
282 <      1 / pmap -> distribRatio. */
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 balancePhotons (PhotonMap *pmap, double *photonFlux);
285 <   /* Build a balanced kd-tree as heap to guarantee logarithmic search
173 <    * times. This must be called prior to performing photon search with
174 <    * findPhotons().
175 <    * PhotonFlux is the flux scaling factor per photon averaged over RGB. In
176 <    * the case of a contribution photon map, this is an array with a
177 <    * separate factor specific to each light source due to non-uniform
178 <    * photon emission; Otherwise it is referenced as a scalar value. Flux is
179 <    * not scaled if photonFlux == NULL. */
284 >   void initPhotonHeap (PhotonMap *pmap);
285 >   /* Open photon heap file */
286  
287 <   void buildHeap (Photon *heap, unsigned long *heapIdx,
288 <                   unsigned long *heapXdi, const float min [3],
289 <                   const float max [3], unsigned long left,
290 <                   unsigned long right, unsigned long root);
291 <   /* Recursive part of balancePhotons(..); builds heap from subarray
292 <    * defined by indices left and right. */
293 <      
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 >
313     void findPhotons (PhotonMap* pmap, const RAY *ray);
314 <   /* Find pmap -> squeueSize closest photons to ray -> rop with similar
314 >   /* Find pmap -> squeue.len closest photons to ray -> rop with similar
315        normal. For volume photons ray -> rorg is used and the normal is
316        ignored (being the incident direction in this case). Found photons
317 <      are placed in pmap -> squeue, with pmap -> squeueEnd being the number
318 <      actually found. */
317 >      are placed search queue starting with the furthest photon at pmap ->
318 >      squeue.node, and pmap -> squeue.tail being the number actually found. */
319  
320 <   Photon *find1Photon (PhotonMap *pmap, const RAY *ray);
321 <   /* Finds single closest photon to ray -> rop with similar normal.
322 <      Returns NULL if none found. */
320 >   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  
325 +   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     void deletePhotons (PhotonMap*);
336     /* Free dem mammaries... */
337  

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines