1 |
/* RCSid $Id$ */ |
2 |
/* |
3 |
================================================================== |
4 |
Photon map data structures and kd-tree handling |
5 |
|
6 |
Roland Schregle (roland.schregle@{hslu.ch, gmail.com}) |
7 |
(c) Fraunhofer Institute for Solar Energy Systems, |
8 |
(c) Lucerne University of Applied Sciences and Arts, |
9 |
supported by the Swiss National Science Foundation (SNSF, #147053) |
10 |
================================================================== |
11 |
|
12 |
$Id: pmapdata.h,v 2.7 2015/07/29 18:54:20 rschregle Exp $ |
13 |
*/ |
14 |
|
15 |
|
16 |
#ifndef PMAPDATA_H |
17 |
#define PMAPDATA_H |
18 |
|
19 |
#include "ray.h" |
20 |
#include "pmaptype.h" |
21 |
#include "lookup.h" |
22 |
|
23 |
|
24 |
/* Define PMAP_FLOAT_FLUX to store photon flux as floats instead of |
25 |
* compact RGBE, which was found to improve accuracy in analytical |
26 |
* validation. */ |
27 |
#ifdef PMAP_FLOAT_FLUX |
28 |
#define setPhotonFlux(p,f) copycolor((p) -> flux, f) |
29 |
#define getPhotonFlux(p,f) copycolor(f, (p) -> flux) |
30 |
#else |
31 |
#define setPhotonFlux(p,f) setcolr((p)->flux, (f)[0], (f)[1], (f)[2]) |
32 |
#define getPhotonFlux(p,f) colr_color(f, (p) -> flux) |
33 |
#endif |
34 |
|
35 |
|
36 |
/* Primary photon ray for light source contributions */ |
37 |
typedef struct { |
38 |
int32 srcIdx; /* Index of emitting light source */ |
39 |
int32 dir; /* Encoded ray direction */ |
40 |
float pos [3]; /* Hit point */ |
41 |
} PhotonPrimary; |
42 |
|
43 |
#define photonSrcIdx(pm, p) ((pm) -> primary [(p) -> primary].srcIdx) |
44 |
|
45 |
|
46 |
typedef struct { |
47 |
float pos [3]; /* Photon position */ |
48 |
signed char norm [3]; /* Surface normal at pos (incident |
49 |
direction for volume photons) */ |
50 |
char flags; /* Bit 0-1: kd-tree discriminator axis, |
51 |
Bit 2: caustic photon */ |
52 |
#ifdef PMAP_FLOAT_FLUX |
53 |
COLOR flux; |
54 |
#else |
55 |
COLR flux; /* Photon flux */ |
56 |
#endif |
57 |
|
58 |
uint32 primary; /* Index to primary ray */ |
59 |
} Photon; |
60 |
|
61 |
/* Photon flag bitmasks and manipulation macros */ |
62 |
#define PMAP_DISCR_BIT 3 |
63 |
#define PMAP_CAUST_BIT 4 |
64 |
#define photonDiscr(p) ((p).flags & PMAP_DISCR_BIT) |
65 |
#define setPhotonDiscr(p, d) ((p).flags = ((p).flags & ~PMAP_DISCR_BIT) | \ |
66 |
((d) & PMAP_DISCR_BIT)) |
67 |
|
68 |
/* Photon map type tests */ |
69 |
#define isGlobalPmap(p) ((p) -> type == PMAP_TYPE_GLOBAL) |
70 |
#define isCausticPmap(p) ((p) -> type == PMAP_TYPE_CAUSTIC) |
71 |
#define isContribPmap(p) ((p) -> type == PMAP_TYPE_CONTRIB) |
72 |
#define isVolumePmap(p) ((p) -> type == PMAP_TYPE_VOLUME) |
73 |
|
74 |
|
75 |
/* Queue node for photon lookups */ |
76 |
typedef struct { |
77 |
Photon *photon; |
78 |
float dist; |
79 |
} PhotonSQNode; |
80 |
|
81 |
/* Bias compensation history node */ |
82 |
typedef struct { |
83 |
COLOR irrad; |
84 |
float weight; |
85 |
} PhotonBCNode; |
86 |
|
87 |
|
88 |
struct PhotonMap; /* Forward declarations */ |
89 |
|
90 |
typedef struct PhotonMap { |
91 |
PhotonMapType type; /* See pmaptype.h */ |
92 |
char *fileName; /* Photon map file */ |
93 |
Photon *heap; /* Photon k-d tree as linear array */ |
94 |
PhotonSQNode *squeue; /* Search queue */ |
95 |
PhotonBCNode *biasCompHist; /* Bias compensation history */ |
96 |
char lookupFlags; /* Flags passed to findPhotons() */ |
97 |
|
98 |
unsigned long distribTarget, /* Num stored specified by user */ |
99 |
heapSize, |
100 |
heapSizeInc, |
101 |
heapEnd, /* Num actually stored in heap */ |
102 |
numDensity, /* Num density estimates */ |
103 |
totalGathered, /* Total photons gathered */ |
104 |
numLookups, /* Counters for short photon lookups */ |
105 |
numShortLookups; |
106 |
|
107 |
unsigned minGather, /* Specified min/max photons per */ |
108 |
maxGather, /* density estimate */ |
109 |
squeueSize, |
110 |
squeueEnd, |
111 |
minGathered, /* Min/max photons actually gathered */ |
112 |
maxGathered, /* per density estimate */ |
113 |
shortLookupPct; /* Percentage of short lookups (for |
114 |
statistics output */ |
115 |
|
116 |
/* NOTE: All distances are SQUARED */ |
117 |
float maxDist, /* Max search radius during NN search */ |
118 |
maxDist0, /* Initial value for above */ |
119 |
maxDistLimit, /* Hard limit for above */ |
120 |
CoGdist, /* Avg distance to centre of gravity */ |
121 |
maxPos [3], minPos [3], /* Max & min photon positions */ |
122 |
distribRatio, /* Probability of photon storage */ |
123 |
gatherTolerance, /* Fractional deviation from minGather/ |
124 |
maxGather for short lookup */ |
125 |
minError, maxError, /* Min/max/rms density estimate error */ |
126 |
rmsError; |
127 |
|
128 |
FVECT CoG; /* Centre of gravity (avg photon pos) */ |
129 |
COLOR photonFlux; /* Average photon flux */ |
130 |
unsigned short randState [3]; /* Local RNG state */ |
131 |
|
132 |
void (*lookup)(struct PhotonMap*, RAY*, COLOR); |
133 |
/* Callback for type-specific photon |
134 |
* lookup (usually density estimate) */ |
135 |
|
136 |
PhotonPrimary *primary; /* Primary photon rays & associated |
137 |
counters */ |
138 |
unsigned primarySize, primaryEnd; |
139 |
|
140 |
LUTAB *srcContrib; /* lookup table for source contribs */ |
141 |
} PhotonMap; |
142 |
|
143 |
|
144 |
|
145 |
/* Photon maps by type (see PhotonMapType) */ |
146 |
extern PhotonMap *photonMaps []; |
147 |
|
148 |
/* Macros for specific photon map types */ |
149 |
#define globalPmap (photonMaps [PMAP_TYPE_GLOBAL]) |
150 |
#define preCompPmap (photonMaps [PMAP_TYPE_PRECOMP]) |
151 |
#define causticPmap (photonMaps [PMAP_TYPE_CAUSTIC]) |
152 |
#define volumePmap (photonMaps [PMAP_TYPE_VOLUME]) |
153 |
#define directPmap (photonMaps [PMAP_TYPE_DIRECT]) |
154 |
#define contribPmap (photonMaps [PMAP_TYPE_CONTRIB]) |
155 |
|
156 |
|
157 |
|
158 |
void initPhotonMap (PhotonMap *pmap, PhotonMapType t); |
159 |
/* Initialise empty photon map of specified type */ |
160 |
|
161 |
const PhotonPrimary* addPhotonPrimary (PhotonMap *pmap, const RAY *ray); |
162 |
/* Add primary ray for emitted photon and save light source index, origin |
163 |
* on source, and emitted direction; used by contrib photons */ |
164 |
|
165 |
const Photon* addPhoton (PhotonMap *pmap, const RAY *ray); |
166 |
/* Create new photon with ray's direction, intersection point, and flux, |
167 |
and add to photon map subject to acceptance probability pmap -> |
168 |
distribRatio for global density control; if the photon is rejected, |
169 |
NULL is returned. The flux is scaled by ray -> rweight and |
170 |
1 / pmap -> distribRatio. */ |
171 |
|
172 |
void balancePhotons (PhotonMap *pmap, double *photonFlux); |
173 |
/* Build a balanced kd-tree as heap to guarantee logarithmic search |
174 |
* times. This must be called prior to performing photon search with |
175 |
* findPhotons(). |
176 |
* PhotonFlux is the flux scaling factor per photon averaged over RGB. In |
177 |
* the case of a contribution photon map, this is an array with a |
178 |
* separate factor specific to each light source due to non-uniform |
179 |
* photon emission; Otherwise it is referenced as a scalar value. Flux is |
180 |
* not scaled if photonFlux == NULL. */ |
181 |
|
182 |
void buildHeap (Photon *heap, unsigned long *heapIdx, |
183 |
unsigned long *heapXdi, const float min [3], |
184 |
const float max [3], unsigned long left, |
185 |
unsigned long right, unsigned long root); |
186 |
/* Recursive part of balancePhotons(..); builds heap from subarray |
187 |
* defined by indices left and right. */ |
188 |
|
189 |
void findPhotons (PhotonMap* pmap, const RAY *ray); |
190 |
/* Find pmap -> squeueSize closest photons to ray -> rop with similar |
191 |
normal. For volume photons ray -> rorg is used and the normal is |
192 |
ignored (being the incident direction in this case). Found photons |
193 |
are placed in pmap -> squeue, with pmap -> squeueEnd being the number |
194 |
actually found. */ |
195 |
|
196 |
Photon *find1Photon (PhotonMap *pmap, const RAY *ray); |
197 |
/* Finds single closest photon to ray -> rop with similar normal. |
198 |
Returns NULL if none found. */ |
199 |
|
200 |
void deletePhotons (PhotonMap*); |
201 |
/* Free dem mammaries... */ |
202 |
|
203 |
#endif |