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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines