ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/common/bsdf.h
Revision: 2.5
Committed: Fri Feb 18 02:41:55 2011 UTC (13 years, 2 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.4: +7 -1 lines
Log Message:
Minor fixes and adjustments

File Contents

# Content
1 /* RCSid $Id: bsdf.h,v 2.4 2011/02/18 00:40:25 greg Exp $ */
2 /*
3 * bsdf.h
4 *
5 * Declarations for bidirectional scattering distribution functions.
6 * Assumes <stdio.h> already included.
7 *
8 * A material is oriented in right-hand coordinate system with X-axis
9 * in the surface plane pointed to the right as seen from the front.
10 * This means the Y-axis is "up" and the Z-axis is the surface normal.
11 *
12 * BSDF vectors always oriented away from surface, even when "incident."
13 *
14 * Created by Greg Ward on 1/10/11.
15 *
16 */
17
18 #ifndef _BSDF_H_
19 #define _BSDF_H_
20
21 #include "fvect.h"
22 #include "ccolor.h"
23
24 #ifdef __cplusplus
25 extern "C" {
26 #endif
27
28 #define SDnameLn 128 /* maximum BSDF name length */
29 #define SDmaxCh 3 /* maximum # spectral channels */
30
31 /* Component flags for SDsampBSDF() and SDhemiScatter() */
32 #define SDsampR 0x1 /* include reflection */
33 #define SDsampT 0x2 /* include transmission */
34 #define SDsampS 0x3 /* include scattering (R+T) */
35 #define SDsampSp 0x4 /* include non-diffuse portion */
36 #define SDsampDf 0x8 /* include diffuse portion */
37 #define SDsampSpR 0x5 /* include non-diffuse reflection */
38 #define SDsampSpT 0x6 /* include non-diffuse transmission */
39 #define SDsampSpS 0x7 /* include non-diffuse scattering */
40 #define SDsampAll 0xF /* include everything */
41
42 /* Projected solid angle query flags fos SDsizeBSDF() */
43 #define SDqueryInc 0x1 /* query incoming vector */
44 #define SDqueryOut 0x2 /* query outgoing vector */
45 #define SDqueryMin 0x4 /* query minimum proj. solid angle */
46 #define SDqueryMax 0x8 /* query maximum proj. solid angle */
47
48 /* Error codes: normal return, out of memory, file i/o, file format, bad argument,
49 bad data, unsupported feature, internal error, unknown error */
50 typedef enum {SDEnone=0, SDEmemory, SDEfile, SDEformat, SDEargument,
51 SDEdata, SDEsupport, SDEinternal, SDEunknown} SDError;
52
53 /* English ASCII strings corresponding to ennumerated errors */
54 extern const char *SDerrorEnglish[];
55
56 /* Additional information on last error (ASCII English) */
57 extern char SDerrorDetail[];
58
59 /* Holder for BSDF value and spectral color */
60 typedef struct {
61 double cieY; /* photopic BSDF (Y) value */
62 C_COLOR spec; /* spectral and (x,y) color */
63 } SDValue;
64
65 /* Cached, encoded, cumulative distribution for one incident (solid) angle */
66 #define SD_CDIST_BASE double cTotal; \
67 struct SDCDst_s *next
68 typedef struct SDCDst_s {
69 SD_CDIST_BASE; /* base fields first */
70 /* ...encoded distribution extends struct */
71 } SDCDst;
72
73 /* Forward declaration of BSDF component */
74 typedef struct SDComp_s SDComponent;
75
76 /* Methods needed to handle BSDF components (nothing is optional) */
77 typedef const struct {
78 /* return non-diffuse BSDF */
79 int (*getBSDFs)(float coef[SDmaxCh], const FVECT outVec,
80 const FVECT inVec, const void *dist);
81 /* query non-diffuse PSA for vector */
82 SDError (*queryProjSA)(double *psa, const FVECT vec,
83 int qflags, const void *dist);
84 /* get cumulative distribution */
85 const SDCDst *(*getCDist)(const FVECT inVec, SDComponent *sdc);
86 /* sample cumulative distribution */
87 SDError (*sampCDist)(FVECT outVec, double randX,
88 const SDCDst *cdp);
89 /* free a spectral BSDF component */
90 void (*freeSC)(void *dist);
91 } SDFunc;
92
93 /* Structure to hold a spectral BSDF component (typedef SDComponent above) */
94 struct SDComp_s {
95 C_COLOR cspec[SDmaxCh]; /* component spectral bases */
96 SDFunc *func; /* methods for this component */
97 void *dist; /* loaded distribution data */
98 SDCDst *cdList; /* cumulative distribution cache */
99 };
100
101 /* Container for non-diffuse BSDF components */
102 typedef struct {
103 double minProjSA; /* minimum projected solid angle */
104 double maxHemi; /* maximum directional hemispherical */
105 int ncomp; /* number of separate components */
106 SDComponent comp[1]; /* BSDF components (extends struct) */
107 } SDSpectralDF;
108
109 /* Loaded BSDF data */
110 typedef struct {
111 char name[SDnameLn]; /* BSDF name (derived from file) */
112 char *mgf; /* geometric description (if any) */
113 float dim[3]; /* width, height, thickness (meters) */
114 SDValue rLambFront; /* diffuse front reflectance */
115 SDValue rLambBack; /* diffuse rear reflectance */
116 SDValue tLamb; /* diffuse transmission */
117 SDSpectralDF *rf, *rb, *tf; /* non-diffuse BSDF components */
118 } SDData;
119
120 /* List of loaded BSDFs */
121 extern struct SDCache_s {
122 SDData bsdf; /* BSDF data */
123 unsigned refcnt; /* how many callers are using us? */
124 struct SDCache_s /* next in cache list */
125 *next;
126 } *SDcacheList; /* Global BSDF cache */
127
128 /* BSDF cache retention preference */
129 #define SDretainNone 0 /* free unreferenced data (default) */
130 #define SDretainBSDFs 1 /* keep loaded BSDFs in cache */
131 #define SDretainAll 2 /* also keep cumulative cache data */
132
133 extern int SDretainSet; /* set to SDretainNone by default */
134
135 /*****************************************************************
136 * The following routines are less commonly used by applications.
137 */
138
139 #define SDisLoaded(sd) ((sd)->rLambFront.spec.clock != 0)
140
141 /* Report an error to the indicated stream (in English) */
142 extern SDError SDreportEnglish(SDError ec, FILE *fp);
143
144 /* Shorten file path to useable BSDF name, removing suffix */
145 extern void SDclipName(char res[SDnameLn], const char *fname);
146
147 /* Allocate new spectral distribution function */
148 extern SDSpectralDF *SDnewSpectralDF(int nc);
149
150 /* Free a spectral distribution function */
151 extern void SDfreeSpectralDF(SDSpectralDF *df);
152
153 /* Initialize an unused BSDF struct (clears to zeroes) */
154 extern void SDclearBSDF(SDData *sd);
155
156 /* Load a BSDF struct from the given file (keeps name unchanged) */
157 extern SDError SDloadFile(SDData *sd, const char *fname);
158
159 /* Free data associated with BSDF struct */
160 extern void SDfreeBSDF(SDData *sd);
161
162 /* Find writeable BSDF by name, or allocate new cache entry if absent */
163 extern SDData *SDgetCache(const char *bname);
164
165 /* Free cached cumulative distributions for BSDF component */
166 extern void SDfreeCumulativeCache(SDSpectralDF *df);
167
168 /* Sample an individual BSDF component */
169 extern SDError SDsampComponent(SDValue *sv, FVECT outVec,
170 const FVECT inVec, double randX,
171 SDComponent *sdc);
172
173 /* Convert 1-dimensional random variable to N-dimensional */
174 extern void SDmultiSamp(double t[], int n, double randX);
175
176 /* Map a [0,1]^2 square to a unit radius disk */
177 void SDsquare2disk(double ds[2], double seedx, double seedy);
178
179 /* Map point on unit disk to a unit square in [0,1]^2 range */
180 void SDdisk2square(double sq[2], double diskx, double disky);
181
182 /*****************************************************************
183 * The calls below are the ones most applications require.
184 * All directions are assumed to be unit vectors.
185 */
186
187 /* Get BSDF from cache (or load and cache it on first call) */
188 /* Report any problems to stderr and return NULL on failure */
189 extern const SDData *SDcacheFile(const char *fname);
190
191 /* Free a BSDF from our cache (clear all if NULL) */
192 extern void SDfreeCache(const SDData *sd);
193
194 /* Query projected solid angle resolution for non-diffuse BSDF direction */
195 extern SDError SDsizeBSDF(double *projSA, const FVECT vec,
196 int qflags, const SDData *sd);
197
198 /* Return BSDF for the given incident and scattered ray vectors */
199 extern SDError SDevalBSDF(SDValue *sv, const FVECT outVec,
200 const FVECT inVec, const SDData *sd);
201
202 /* Compute directional hemispherical scattering at given incident angle */
203 extern double SDdirectHemi(const FVECT inVec,
204 int sflags, const SDData *sd);
205
206 /* Sample BSDF direction based on the given random variable */
207 extern SDError SDsampBSDF(SDValue *sv, FVECT outVec,
208 const FVECT inVec, double randX,
209 int sflags, const SDData *sd);
210
211 /*****************************************************************
212 * Vector math for getting between world and local BSDF coordinates.
213 * Directions may be passed unnormalized to these routines.
214 */
215
216 /* Compute World->BSDF transform from surface normal and up (Y) vector */
217 extern SDError SDcompXform(RREAL vMtx[3][3], const FVECT sNrm,
218 const FVECT uVec);
219
220 /* Compute inverse transform */
221 extern SDError SDinvXform(RREAL iMtx[3][3], RREAL vMtx[3][3]);
222
223 /* Transform and normalize direction (column) vector */
224 extern SDError SDmapDir(FVECT resVec, RREAL vMtx[3][3],
225 const FVECT inpVec);
226
227 /* System-specific BSDF loading routine (not part of our library) */
228 extern SDData *loadBSDF(char *name);
229
230 /* System-specific BSDF error translator (not part of our library) */
231 extern char *transSDError(SDError ec);
232
233 /*################################################################*/
234 /*######### DEPRECATED DEFINITIONS AWAITING PERMANENT REMOVAL #######*/
235 /*
236 * Header for BSDF i/o and access routines
237 */
238
239 #include "mat4.h"
240 /* up directions */
241 typedef enum {
242 UDzneg=-3,
243 UDyneg=-2,
244 UDxneg=-1,
245 UDunknown=0,
246 UDxpos=1,
247 UDypos=2,
248 UDzpos=3
249 } UpDir;
250 /* BSDF coordinate calculation routines */
251 /* vectors always point away from surface */
252
253 typedef int b_vecf2(FVECT v, int n, void *cd);
254 typedef int b_ndxf2(FVECT v, void *cd);
255 typedef double b_radf2(int n, void *cd);
256
257 /* Bidirectional Scattering Distribution Function */
258 struct BSDF_data {
259 int ninc; /* number of incoming directions */
260 int nout; /* number of outgoing directions */
261 float dim[3]; /* width, height, thickness (meters) */
262 char *mgf; /* geometric description (if any) */
263 void *ib_priv; /* input basis private data */
264 b_vecf2 *ib_vec; /* get input vector from index */
265 b_ndxf2 *ib_ndx; /* get input index from vector */
266 b_radf2 *ib_ohm; /* get input radius for index */
267 void *ob_priv; /* output basis private data */
268 b_vecf2 *ob_vec; /* get output vector from index */
269 b_ndxf2 *ob_ndx; /* get output index from vector */
270 b_radf2 *ob_ohm; /* get output radius for index */
271 float *bsdf; /* scattering distribution data */
272 }; /* bidirectional scattering distrib. func. */
273
274 #define getBSDF_incvec(v,b,i) (*(b)->ib_vec)(v,i,(b)->ib_priv)
275 #define getBSDF_incndx(b,v) (*(b)->ib_ndx)(v,(b)->ib_priv)
276 #define getBSDF_incohm(b,i) (*(b)->ib_ohm)(i,(b)->ib_priv)
277 #define getBSDF_outvec(v,b,o) (*(b)->ob_vec)(v,o,(b)->ob_priv)
278 #define getBSDF_outndx(b,v) (*(b)->ob_ndx)(v,(b)->ob_priv)
279 #define getBSDF_outohm(b,o) (*(b)->ob_ohm)(o,(b)->ob_priv)
280 #define BSDF_value(b,i,o) (b)->bsdf[(o)*(b)->ninc + (i)]
281
282 extern struct BSDF_data *load_BSDF(char *fname);
283 extern void free_BSDF(struct BSDF_data *b);
284 extern int r_BSDF_incvec(FVECT v, struct BSDF_data *b, int i,
285 double rv, MAT4 xm);
286 extern int r_BSDF_outvec(FVECT v, struct BSDF_data *b, int o,
287 double rv, MAT4 xm);
288 extern int getBSDF_xfm(MAT4 xm, FVECT nrm, UpDir ud, char *xfbuf);
289
290 /*######### END DEPRECATED DEFINITIONS #######*/
291 /*################################################################*/
292
293 #ifdef __cplusplus
294 }
295 #endif
296 #endif /* ! _BSDF_H_ */