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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines