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.3 by greg, Wed May 20 12:58:31 2015 UTC vs.
Revision 2.11 by rschregle, Mon Aug 14 21:12:10 2017 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 +   #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 +
44     #include "ray.h"  
45     #include "pmaptype.h"
46 +   #include "paths.h"
47     #include "lookup.h"
48 +   #include <stdint.h>
49  
50  
51 <   /* Define PMAP_FLOAT_FLUX to store photon flux as floats instead of
24 <    * compact RGBE, which was found to improve accuracy in analytical
25 <    * validation. */
26 <   #ifdef PMAP_FLOAT_FLUX
27 <      #define setPhotonFlux(p,f) copycolor((p) -> flux, f)
28 <      #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)
32 <   #endif
33 <
34 <
51 >  
52     /* Primary photon ray for light source contributions */
53     typedef struct {
54 <      short srcIdx;               /* Index of emitting light source */
55 <      float dir [3], pos [3];     /* Incident dir & hit point */
54 >      int16    srcIdx;              /* Index of emitting light source */
55 >                                    /* !!! REDUCED FROM 32 BITS !!! */
56 >      int32    dir;                 /* Encoded ray direction */
57 > #ifdef PMAP_PRIMARYPOS      
58 >      float    pos [3];             /* Hit point */
59 > #endif      
60     } PhotonPrimary;
61        
62 <   #define photonSrcIdx(pm, p) ((pm) -> primary [(p) -> primary].srcIdx)
62 >   #define photonSrcIdx(pm, p)      ((pm)->primaries[(p)->primary].srcIdx)
63  
64 +
65 +
66 +   /* Photon primary ray index type and limit */
67 +   typedef  uint32            PhotonPrimaryIdx;      
68 +   #define  PMAP_MAXPRIMARY   UINT32_MAX
69 +
70 +   /* Macros for photon's generating subprocess field */
71 + #ifdef PMAP_OOC
72 +   #define  PMAP_PROCBITS  7
73 + #else            
74 +   #define  PMAP_PROCBITS  5  
75 + #endif
76 +   #define  PMAP_MAXPROC         (1 << PMAP_PROCBITS)
77 +   #define  PMAP_GETRAYPROC(r)   ((r) -> crtype >> 8)
78 +   #define  PMAP_SETRAYPROC(r,p) ((r) -> crtype |= p << 8)
79 +
80 +   /* Tolerance for photon normal check during lookups */
81 +   #define  PMAP_NORM_TOL  0.02
82    
44   typedef struct {
45      float pos [3];                 /* Photon position */
46      signed char norm [3];          /* Surface normal at pos (incident
47                                        direction for volume photons) */
48      char flags;                    /* Bit 0-1: kd-tree discriminator axis,
49                                        Bit 2:   caustic photon */
50      #ifdef PMAP_FLOAT_FLUX
51         COLOR flux;
52      #else
53         COLR flux;                  /* Photon flux */
54      #endif
83  
56      unsigned primary;              /* Index to primary ray */
57   } Photon;
84    
85 <   /* Photon flag bitmasks and manipulation macros */
86 <   #define PMAP_DISCR_BIT 3
87 <   #define PMAP_CAUST_BIT 4
88 <   #define photonDiscr(p)       ((p).flags & PMAP_DISCR_BIT)
89 <   #define setPhotonDiscr(p, d) ((p).flags = ((p).flags & ~PMAP_DISCR_BIT) | \
90 <                                              ((d) & PMAP_DISCR_BIT))
85 >   typedef struct {
86 >      float                pos [3];       /* Photon position */
87 >      signed char          norm [3];      /* Surface normal at pos (incident
88 >                                             direction for volume photons) */
89 >      union {
90 >         struct {
91 > #ifndef PMAP_OOC
92 >            unsigned char  discr    : 2;  /* kd-tree discriminator axis */
93 > #endif            
94 >            unsigned char  caustic  : 1;  /* Specularly scattered (=caustic) */
95 >            
96 >            /* Photon's generating subprocess index, used for primary ray
97 >             * index linearisation when building contrib pmaps; note this is
98 >             * reduced for kd-tree to accommodate the discriminator field */
99 >            unsigned char  proc  : PMAP_PROCBITS;
100 >         };
101 >        
102 >         unsigned char     flags;
103 >      };
104 >      
105 > #ifdef PMAP_FLOAT_FLUX
106 >      COLOR                flux;          
107 > #else
108 >      COLR                 flux;          
109 > #endif
110 >      PhotonPrimaryIdx     primary;       /* Index to primary ray */
111 >   } Photon;
112  
66   /* Photon map type tests */
67   #define isGlobalPmap(p)    ((p) -> type == PMAP_TYPE_GLOBAL)
68   #define isCausticPmap(p)   ((p) -> type == PMAP_TYPE_CAUSTIC)
69   #define isContribPmap(p)   ((p) -> type == PMAP_TYPE_CONTRIB)
70   #define isVolumePmap(p)    ((p) -> type == PMAP_TYPE_VOLUME)
113  
114    
115 <   /* Queue node for photon lookups */
116 <   typedef struct {                  
117 <      Photon *photon;
118 <      float dist;
119 <   } PhotonSQNode;
115 >   /* Define PMAP_FLOAT_FLUX to store photon flux as floats instead of
116 >    * compact RGBE, which was found to improve accuracy in analytical
117 >    * validation. */
118 > #ifdef PMAP_FLOAT_FLUX
119 >   #define setPhotonFlux(p,f) copycolor((p) -> flux, f)
120 >   #define getPhotonFlux(p,f) copycolor(f, (p) -> flux)
121 > #else
122 >   #define setPhotonFlux(p,f) setcolr((p)->flux, (f)[0], (f)[1], (f)[2])
123 >   #define getPhotonFlux(p,f) colr_color(f, (p) -> flux)
124 > #endif
125  
126 +  
127     /* Bias compensation history node */
128     typedef struct {                  
129        COLOR irrad;
130        float weight;
131 <   } PhotonBCNode;
131 >   } PhotonBiasCompNode;
132  
133  
134 <   struct PhotonMap;                 /* Forward declarations */
134 >   /* Forward declaration */
135 >   struct PhotonMap;
136 >  
137 >  
138 >   /* Define search queue and underlying data struct types */
139 > #ifdef PMAP_OOC
140 >   #include "pmapooc.h"
141 > #else
142 >   #include "pmapkdt.h"
143 > #endif
144  
145 +
146 +   /* Mean size of heapfile write buffer, in number of photons */
147 +   #define PMAP_HEAPBUFSIZE   1e6
148 +  
149 +   /* Mean idle time between heap locking attempts, in usec */
150 +   #define PMAP_HEAPBUFSLEEP  2e6
151 +  
152 +   /* Temporary filename for photon heaps */
153 +   #define PMAP_TMPFNAME      TEMPLATE
154 +   #define PMAP_TMPFNLEN      (TEMPLEN + 1)
155 +
156 +
157     typedef struct PhotonMap {
158 <      PhotonMapType type;            /* See pmaptype.h */
159 <      char *fileName;                /* Photon map file */
91 <      Photon *heap;                  /* Photon k-d tree as linear array */
92 <      PhotonSQNode *squeue;          /* Search queue */
93 <      PhotonBCNode *biasCompHist;    /* Bias compensation history */      
94 <      char lookupFlags;              /* Flags passed to findPhotons() */
158 >      PhotonMapType  type;             /* See pmaptype.h */
159 >      char           *fileName;        /* Photon map file */
160        
96      unsigned long distribTarget,   /* Num stored specified by user */
97                    heapSize,
98                    heapSizeInc,
99                    heapEnd,         /* Num actually stored in heap */
100                    numDensity,      /* Num density estimates */
101                    totalGathered,   /* Total photons gathered */
102                    numLookups,      /* Counters for short photon lookups */
103                    numShortLookups;
104                    
105      unsigned minGather,            /* Specified min/max photons per */
106               maxGather,            /* density estimate */
107               squeueSize,
108               squeueEnd,
109               minGathered,          /* Min/max photons actually gathered */
110               maxGathered,          /* per density estimate */
111               shortLookupPct;       /* Percentage of short lookups (for
112                                        statistics output */
113              
114                                     /* NOTE: All distances are SQUARED */
115      float maxDist,                 /* Max search radius during NN search */
116            maxDist0,                /* Initial value for above */
117            maxDistLimit,            /* Hard limit for above */
118            CoGdist,                 /* Avg distance to centre of gravity */
119            maxPos [3], minPos [3],  /* Max & min photon positions */
120            distribRatio,            /* Probability of photon storage */
121            gatherTolerance,         /* Fractional deviation from minGather/
122                                        maxGather for short lookup */
123            minError, maxError,      /* Min/max/rms density estimate error */
124            rmsError;
125            
126      FVECT CoG;                     /* Centre of gravity (avg photon pos) */
127      COLOR photonFlux;              /* Average photon flux */
128      unsigned short randState [3];  /* Local RNG state */
161        
162 <      void (*lookup)(struct PhotonMap*, RAY*, COLOR);  
163 <                                     /* Callback for type-specific photon
164 <                                      * lookup (usually density estimate) */
162 >      /* ================================================================
163 >       * PRE/POST-BUILD STORAGE
164 >       * ================================================================ */
165 >      FILE           *heap;            /* Unsorted photon heap prior to
166 >                                          construction of store */
167 >      char           heapFname [sizeof(PMAP_TMPFNAME)];      
168 >      Photon         *heapBuf;         /* Write buffer for above */
169 >      unsigned long  heapBufLen,       /* Current & max size of heapBuf */
170 >                     heapBufSize;
171 >      PhotonStorage  store;            /* Photon storage in space
172 >                                          subdividing data struct */            
173 >      
174 >      /* ================================================================
175 >       * PHOTON DISTRIBUTION STUFF
176 >       * ================================================================ */
177 >      unsigned long  distribTarget,    /* Num stored specified by user */
178 >                     numPhotons;       /* Num actually stored */
179 >      float          distribRatio;     /* Probability of photon storage */
180 >      COLOR          photonFlux;       /* Average photon flux */
181 >      unsigned short randState [3];    /* Local RNG state */
182  
183 <      PhotonPrimary *primary;        /* Primary photon rays & associated
184 <                                        counters */
185 <      unsigned primarySize, primaryEnd;
186 <              
187 <      LUTAB *srcContrib;             /* lookup table for source contribs */
183 >
184 >      /* ================================================================
185 >       * PHOTON LOOKUP STUFF
186 >       * ================================================================ */
187 >      union {                          /* Flags passed to findPhotons() */
188 >         char        lookupCaustic : 1;
189 >         char        lookupFlags;
190 >      };
191 >      
192 >      PhotonSearchQueue squeue;        /* Search queue for photon lookups */
193 >      unsigned       minGather,        /* Specified min/max photons per */
194 >                     maxGather;        /* density estimate */
195 >                                      
196 >                                       /* NOTE: All distances are SQUARED */
197 >      float          maxDist2,         /* Max search radius */
198 >                     maxDist0,         /* Initial value for above */
199 >                     maxDist2Limit,    /* Hard limit for above */
200 >                     gatherTolerance;  /* Fractional deviation from minGather/
201 >                                          maxGather for short lookup */
202 >      void (*lookup)(struct PhotonMap*,
203 >                     RAY*, COLOR);     /* Callback for type-specific photon
204 >                                        * lookup (usually density estimate) */                                          
205 >
206 >                    
207 >      /* ================================================================
208 >       * BIAS COMPENSATION STUFF
209 >       * ================================================================ */      
210 >      PhotonBiasCompNode   *biasCompHist;    /* Bias compensation history */
211 >      
212 >
213 >      /* ================================================================
214 >       * STATISTIX
215 >       * ================================================================ */            
216 >      unsigned long  totalGathered,    /* Total photons gathered */
217 >                     numDensity,       /* Num density estimates */
218 >                     numLookups,       /* Counters for short photon lookups */
219 >                     numShortLookups;
220 >                    
221 >      unsigned       minGathered,      /* Min/max photons actually gathered */
222 >                     maxGathered,      /* per density estimate */
223 >                     shortLookupPct;   /* % of short lookups for stats */                                          
224 >                    
225 >      float          minError,         /* Min/max/rms density estimate error */
226 >                     maxError,
227 >                     rmsError,
228 >                     CoGdist,          /* Avg distance to centre of gravity */
229 >                     maxPos [3],       /* Max & min photon positions */
230 >                     minPos [3];
231 >                    
232 >      FVECT          CoG;              /* Centre of gravity (avg photon pos) */
233 >                    
234 >      
235 >      /* ================================================================
236 >       * PHOTON CONTRIB/COEFF STUFF
237 >       * ================================================================ */
238 >      PhotonPrimary  *primaries,    /* Photon primary array for rendering */
239 >                     lastPrimary;   /* Current primary for photon distrib */
240 >      PhotonPrimaryIdx  numPrimary;    /* Number of primary rays */
241 >      LUTAB             *srcContrib;   /* Lookup table for source contribs */
242     } PhotonMap;
243  
244  
245  
246     /* Photon maps by type (see PhotonMapType) */
247 <   extern PhotonMap *photonMaps [];
247 >   extern PhotonMap  *photonMaps [];
248  
249     /* Macros for specific photon map types */
250 <   #define globalPmap            (photonMaps [PMAP_TYPE_GLOBAL])
251 <   #define preCompPmap           (photonMaps [PMAP_TYPE_PRECOMP])
252 <   #define causticPmap           (photonMaps [PMAP_TYPE_CAUSTIC])
253 <   #define volumePmap            (photonMaps [PMAP_TYPE_VOLUME])
254 <   #define directPmap            (photonMaps [PMAP_TYPE_DIRECT])
255 <   #define contribPmap           (photonMaps [PMAP_TYPE_CONTRIB])
250 >   #define globalPmap         (photonMaps [PMAP_TYPE_GLOBAL])
251 >   #define preCompPmap        (photonMaps [PMAP_TYPE_PRECOMP])
252 >   #define causticPmap        (photonMaps [PMAP_TYPE_CAUSTIC])
253 >   #define volumePmap         (photonMaps [PMAP_TYPE_VOLUME])
254 >   #define directPmap         (photonMaps [PMAP_TYPE_DIRECT])
255 >   #define contribPmap        (photonMaps [PMAP_TYPE_CONTRIB])
256  
257 +   /* Photon map type tests */
258 +   #define isGlobalPmap(p)    ((p) -> type == PMAP_TYPE_GLOBAL)
259 +   #define isCausticPmap(p)   ((p) -> type == PMAP_TYPE_CAUSTIC)
260 +   #define isContribPmap(p)   ((p) -> type == PMAP_TYPE_CONTRIB)
261 +   #define isVolumePmap(p)    ((p) -> type == PMAP_TYPE_VOLUME)
262  
263  
264 +
265     void initPhotonMap (PhotonMap *pmap, PhotonMapType t);
266     /* Initialise empty photon map of specified type */
267  
268 <   const PhotonPrimary* addPhotonPrimary (PhotonMap *pmap, const RAY *ray);
160 <   /* Add primary ray for emitted photon and save light source index, origin
161 <    * on source, and emitted direction; used by contrib photons */
162 <
163 <   const Photon* addPhoton (PhotonMap *pmap, const RAY *ray);
268 >   int newPhoton (PhotonMap *pmap, const RAY *ray);
269     /* Create new photon with ray's direction, intersection point, and flux,
270 <      and add to photon map subject to acceptance probability pmap ->
271 <      distribRatio for global density control; if the photon is rejected,
272 <      NULL is returned. The flux is scaled by ray -> rweight and
273 <      1 / pmap -> distribRatio. */
270 >      and append to unsorted photon heap pmap -> heap. The photon is
271 >      accepted with probability pmap -> distribRatio for global density
272 >      control; if the photon is rejected, -1 is returned, else 0.  The flux
273 >      is scaled by ray -> rweight and 1 / pmap -> distribRatio. */
274  
275 <   void balancePhotons (PhotonMap *pmap, double *photonFlux);
276 <   /* Build a balanced kd-tree as heap to guarantee logarithmic search
172 <    * times. This must be called prior to performing photon search with
173 <    * findPhotons().
174 <    * PhotonFlux is the flux scaling factor per photon averaged over RGB. In
175 <    * the case of a contribution photon map, this is an array with a
176 <    * separate factor specific to each light source due to non-uniform
177 <    * photon emission; Otherwise it is referenced as a scalar value. Flux is
178 <    * not scaled if photonFlux == NULL. */
275 >   void initPhotonHeap (PhotonMap *pmap);
276 >   /* Open photon heap file */
277  
278 <   void buildHeap (Photon *heap, unsigned long *heapIdx,
279 <                   unsigned long *heapXdi, const float min [3],
280 <                   const float max [3], unsigned long left,
281 <                   unsigned long right, unsigned long root);
282 <   /* Recursive part of balancePhotons(..); builds heap from subarray
283 <    * defined by indices left and right. */
284 <      
278 >   void flushPhotonHeap (PhotonMap *pmap);
279 >   /* Flush photon heap buffa pmap -> heapBuf to heap file pmap -> heap;
280 >    * used by newPhoton() and to finalise heap in distribPhotons(). */
281 >
282 >   void buildPhotonMap (PhotonMap *pmap, double *photonFlux,
283 >                        PhotonPrimaryIdx *primaryOfs, unsigned nproc);
284 >   /* Postpress unsorted photon heap pmap -> heap and build underlying data
285 >    * structure pmap -> store.  This is prerequisite to photon lookups with
286 >    * findPhotons(). */
287 >    
288 >   /* PhotonFlux is the flux per photon averaged over RGB; this is
289 >    * multiplied with each photon's flux during the postprocess.  In the
290 >    * case of a contribution photon map, this is an array with a separate
291 >    * flux specific to each light source due to non-uniform photon emission;
292 >    * Otherwise it is referenced as a scalar value.  Flux is not scaled if
293 >    * photonFlux == NULL.  */
294 >
295 >   /* Photon map construction may be parallelised if nproc > 1, if
296 >    * supported. The heap is destroyed on return.  */
297 >    
298 >   /* PrimaryOfs is an array of index offsets for the primaries in pmap ->
299 >    * primaries generated by each of the nproc subprocesses during contrib
300 >    * photon distribution (see distribPhotonContrib()).  These offsets are
301 >    * used to linearise the photon primary indices in the postprocess.  This
302 >    * linearisation is skipped if primaryOfs == NULL.  */
303 >
304     void findPhotons (PhotonMap* pmap, const RAY *ray);
305 <   /* Find pmap -> squeueSize closest photons to ray -> rop with similar
305 >   /* Find pmap -> squeue.len closest photons to ray -> rop with similar
306        normal. For volume photons ray -> rorg is used and the normal is
307        ignored (being the incident direction in this case). Found photons
308 <      are placed in pmap -> squeue, with pmap -> squeueEnd being the number
309 <      actually found. */
308 >      are placed search queue starting with the furthest photon at pmap ->
309 >      squeue.node, and pmap -> squeue.tail being the number actually found. */
310  
311 <   Photon *find1Photon (PhotonMap *pmap, const RAY *ray);
311 >   void find1Photon (PhotonMap *pmap, const RAY *ray, Photon *photon);
312     /* Finds single closest photon to ray -> rop with similar normal.
313        Returns NULL if none found. */
314  
315 +   void getPhoton (PhotonMap *pmap, PhotonIdx idx, Photon *photon);
316 +   /* Retrieve photon referenced by idx from pmap -> store */
317 +
318 +   Photon *getNearestPhoton (const PhotonSearchQueue *squeue, PhotonIdx idx);
319 +   /* Retrieve photon from NN search queue after calling findPhotons() */
320 +  
321 +   PhotonIdx firstPhoton (const PhotonMap *pmap);
322 +   /* Index to first photon, to be passed to getPhoton(). Indices to
323 +    * subsequent photons can be optained via increment operator (++) */
324 +    
325     void deletePhotons (PhotonMap*);
326     /* Free dem mammaries... */
327  

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines