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

File Contents

# Content
1 /* RCSid $Id: pmapdata.h,v 2.13 2018/12/07 20:02:40 rschregle Exp $ */
2
3 /*
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 =========================================================================
22
23 $Id: pmapdata.h,v 2.13 2018/12/07 20:02:40 rschregle Exp $
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 #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 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)->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
92
93
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
122
123
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 {
138 COLOR irrad;
139 float weight;
140 } PhotonBiasCompNode;
141
142
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 */
169
170
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
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 [];
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])
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 int newPhoton (PhotonMap *pmap, const RAY *ray);
278 /* Create new photon with ray's direction, intersection point, and flux,
279 and append to unsorted photon heap pmap -> heap. The photon is
280 accepted with probability pmap -> distribRatio for global density
281 control; if the photon is rejected, -1 is returned, else 0. The flux
282 is scaled by ray -> rweight and 1 / pmap -> distribRatio. */
283
284 void initPhotonHeap (PhotonMap *pmap);
285 /* Open photon heap file */
286
287 void flushPhotonHeap (PhotonMap *pmap);
288 /* Flush photon heap buffa pmap -> heapBuf to heap file pmap -> heap;
289 * used by newPhoton() and to finalise heap in distribPhotons(). */
290
291 void buildPhotonMap (PhotonMap *pmap, double *photonFlux,
292 PhotonPrimaryIdx *primaryOfs, unsigned nproc);
293 /* Postpress unsorted photon heap pmap -> heap and build underlying data
294 * structure pmap -> store. This is prerequisite to photon lookups with
295 * findPhotons(). */
296
297 /* PhotonFlux is the flux per photon averaged over RGB; this is
298 * multiplied with each photon's flux during the postprocess. In the
299 * case of a contribution photon map, this is an array with a separate
300 * flux specific to each light source due to non-uniform photon emission;
301 * Otherwise it is referenced as a scalar value. Flux is not scaled if
302 * photonFlux == NULL. */
303
304 /* Photon map construction may be parallelised if nproc > 1, if
305 * supported. The heap is destroyed on return. */
306
307 /* PrimaryOfs is an array of index offsets for the primaries in pmap ->
308 * primaries generated by each of the nproc subprocesses during contrib
309 * photon distribution (see distribPhotonContrib()). These offsets are
310 * used to linearise the photon primary indices in the postprocess. This
311 * linearisation is skipped if primaryOfs == NULL. */
312
313 void findPhotons (PhotonMap* pmap, const RAY *ray);
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 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, 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
338 #endif