ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/common/rglmat.c
Revision: 3.2
Committed: Sat Feb 22 02:07:22 2003 UTC (21 years, 2 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 3.1: +72 -9 lines
Log Message:
Changes and check-in for 3.5 release
Includes new source files and modifications not recorded for many years
See ray/doc/notes/ReleaseNotes for notes between 3.1 and 3.5 release

File Contents

# User Rev Content
1 gwlarson 3.1 #ifndef lint
2 greg 3.2 static const char RCSid[] = "$Id$";
3 gwlarson 3.1 #endif
4     /*
5     * Routines for Radiance -> OpenGL materials.
6     */
7    
8 greg 3.2 /* ====================================================================
9     * The Radiance Software License, Version 1.0
10     *
11     * Copyright (c) 1990 - 2002 The Regents of the University of California,
12     * through Lawrence Berkeley National Laboratory. All rights reserved.
13     *
14     * Redistribution and use in source and binary forms, with or without
15     * modification, are permitted provided that the following conditions
16     * are met:
17     *
18     * 1. Redistributions of source code must retain the above copyright
19     * notice, this list of conditions and the following disclaimer.
20     *
21     * 2. Redistributions in binary form must reproduce the above copyright
22     * notice, this list of conditions and the following disclaimer in
23     * the documentation and/or other materials provided with the
24     * distribution.
25     *
26     * 3. The end-user documentation included with the redistribution,
27     * if any, must include the following acknowledgment:
28     * "This product includes Radiance software
29     * (http://radsite.lbl.gov/)
30     * developed by the Lawrence Berkeley National Laboratory
31     * (http://www.lbl.gov/)."
32     * Alternately, this acknowledgment may appear in the software itself,
33     * if and wherever such third-party acknowledgments normally appear.
34     *
35     * 4. The names "Radiance," "Lawrence Berkeley National Laboratory"
36     * and "The Regents of the University of California" must
37     * not be used to endorse or promote products derived from this
38     * software without prior written permission. For written
39     * permission, please contact [email protected].
40     *
41     * 5. Products derived from this software may not be called "Radiance",
42     * nor may "Radiance" appear in their name, without prior written
43     * permission of Lawrence Berkeley National Laboratory.
44     *
45     * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
46     * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
47     * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
48     * DISCLAIMED. IN NO EVENT SHALL Lawrence Berkeley National Laboratory OR
49     * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
50     * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
51     * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
52     * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
53     * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
54     * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
55     * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
56     * SUCH DAMAGE.
57     * ====================================================================
58     *
59     * This software consists of voluntary contributions made by many
60     * individuals on behalf of Lawrence Berkeley National Laboratory. For more
61     * information on Lawrence Berkeley National Laboratory, please see
62     * <http://www.lbl.gov/>.
63     */
64    
65 gwlarson 3.1 #include "radogl.h"
66    
67     int domats = 1; /* are we doing materials? */
68    
69     LUTAB mtab = LU_SINIT(free,freemtl);
70    
71    
72 greg 3.2 void
73 gwlarson 3.1 rgl_matclear() /* clean up materials */
74     {
75     lu_done(&mtab);
76     domats = 1;
77     }
78    
79    
80     MATREC *
81     getmatp(nam) /* find material record for modifier name */
82     char *nam;
83     {
84     register LUENT *lup;
85    
86     if (nam == NULL)
87     return(NULL);
88     if ((lup = lu_find(&mtab, nam)) == NULL)
89     return(NULL);
90     return((MATREC *)lup->data);
91     }
92    
93    
94 greg 3.2 int
95 gwlarson 3.1 o_default(o) /* default object is non-material modifier */
96     register OBJREC *o;
97     {
98     register LUENT *lup;
99     #ifdef DEBUG
100     if (o->otype >= 0 && !ismodifier(o->otype))
101     error(CONSISTENCY, "o_default handed non-modifier");
102     #endif
103     /* find name in lookup table */
104     if ((lup = lu_find(&mtab, o->oname)) == NULL)
105     goto memerr;
106     if (lup->key == NULL) { /* new entry? */
107     lup->key = (char *)malloc(strlen(o->oname)+1);
108     if (lup->key == NULL)
109     goto memerr;
110     strcpy(lup->key, o->oname);
111     } else if (lup->data != NULL)
112 greg 3.2 freemtl((MATREC *)lup->data);
113 gwlarson 3.1 if ((lup->data = o->os) != NULL) /* make material reference */
114     ((MATREC *)lup->data)->nlinks++;
115     return;
116     memerr:
117     error(SYSTEM, "out of memory in o_default");
118     }
119    
120    
121     MATREC *
122     newmaterial(nam) /* get an entry for a new material */
123     char *nam;
124     {
125     register LUENT *lup;
126     /* look it up (assign entry) */
127     if ((lup = lu_find(&mtab, nam)) == NULL)
128     goto memerr;
129     if (lup->key == NULL) { /* new entry? */
130     lup->key = (char *)malloc(strlen(nam)+1);
131     if (lup->key == NULL)
132     goto memerr;
133     strcpy(lup->key, nam);
134     } else if (lup->data != NULL)
135 greg 3.2 freemtl((MATREC *)lup->data);
136 gwlarson 3.1 lup->data = (char *)malloc(sizeof(MATREC));
137     if (lup->data == NULL)
138     goto memerr;
139     ((MATREC *)lup->data)->nlinks = 1;
140     return((MATREC *)lup->data);
141     memerr:
142     error(SYSTEM, "out of memory in newmaterial");
143     }
144    
145    
146 greg 3.2 void
147 gwlarson 3.1 freemtl(mp) /* free a material */
148     register MATREC *mp;
149     {
150     if (!--mp->nlinks)
151 greg 3.2 free((void *)mp);
152 gwlarson 3.1 }
153    
154    
155 greg 3.2 int
156 gwlarson 3.1 m_normal(o) /* compute normal material parameters */
157     register OBJREC *o;
158     {
159     register MATREC *m;
160     /* check arguments */
161     if (o->oargs.nfargs != (o->otype == MAT_TRANS ? 7 : 5))
162     objerror(o, USER, "bad # of real arguments");
163     /* allocate/insert material */
164     m = newmaterial(o->oname);
165     /* assign parameters */
166     setcolor(m->u.m.ambdiff, o->oargs.farg[0],
167     o->oargs.farg[1], o->oargs.farg[2]);
168     if ((m->type = o->otype) == MAT_METAL)
169     copycolor(m->u.m.specular, m->u.m.ambdiff);
170     else
171     setcolor(m->u.m.specular, 1., 1., 1.);
172     scalecolor(m->u.m.specular, o->oargs.farg[3]);
173     scalecolor(m->u.m.ambdiff, 1.-o->oargs.farg[3]);
174     if (m->type == MAT_TRANS) {
175     scalecolor(m->u.m.specular, 1.-o->oargs.farg[5]);
176     scalecolor(m->u.m.ambdiff, 1.-o->oargs.farg[5]);
177     }
178     if (o->oargs.farg[4] <= FTINY)
179     m->u.m.specexp = MAXSPECEXP;
180     else
181     m->u.m.specexp = 2./(o->oargs.farg[4]*o->oargs.farg[4]);
182     if (m->u.m.specexp > MAXSPECEXP)
183     m->u.m.specexp = MAXSPECEXP;
184     }
185    
186    
187 greg 3.2 int
188 gwlarson 3.1 m_aniso(o) /* anisotropic material */
189     register OBJREC *o;
190     {
191     register MATREC *m;
192     /* check arguments */
193     if (o->oargs.nfargs < (o->otype == MAT_TRANS2 ? 8 : 6))
194     objerror(o, USER, "bad # of real arguments");
195     /* allocate/insert material */
196     m = newmaterial(o->oname);
197     /* assign parameters */
198     setcolor(m->u.m.ambdiff, o->oargs.farg[0],
199     o->oargs.farg[1], o->oargs.farg[2]);
200     if ((m->type = o->otype) == MAT_METAL2)
201     copycolor(m->u.m.specular, m->u.m.ambdiff);
202     else
203     setcolor(m->u.m.specular, 1., 1., 1.);
204     scalecolor(m->u.m.specular, o->oargs.farg[3]);
205     scalecolor(m->u.m.ambdiff, 1.-o->oargs.farg[3]);
206     if (m->type == MAT_TRANS2) {
207     scalecolor(m->u.m.specular, 1.-o->oargs.farg[6]);
208     scalecolor(m->u.m.ambdiff, 1.-o->oargs.farg[6]);
209     }
210     if (o->oargs.farg[4]*o->oargs.farg[5] <= FTINY*FTINY)
211     m->u.m.specexp = MAXSPECEXP;
212     else
213     m->u.m.specexp = 2./(o->oargs.farg[4]*o->oargs.farg[5]);
214     if (m->u.m.specexp > MAXSPECEXP)
215     m->u.m.specexp = MAXSPECEXP;
216     }
217    
218    
219 greg 3.2 int
220 gwlarson 3.1 m_glass(o) /* glass material (hopeless) */
221     OBJREC *o;
222     {
223     register MATREC *m;
224    
225     m = newmaterial(o->oname);
226     m->type = o->otype;
227     setcolor(m->u.m.ambdiff, 0., 0., 0.);
228     setcolor(m->u.m.specular, .08, .08, .08);
229     m->u.m.specexp = MAXSPECEXP;
230     }
231    
232    
233 greg 3.2 int
234 gwlarson 3.1 m_brdf(o) /* convert functional material */
235     register OBJREC *o;
236     {
237     register MATREC *m;
238     /* check arguments */
239     if (o->oargs.nfargs < (o->otype == MAT_TFUNC ? 6 : 4))
240     objerror(o, USER, "bad # of real arguments");
241     /* allocate/insert material */
242     m = newmaterial(o->oname);
243     /* assign parameters */
244     setcolor(m->u.m.ambdiff, o->oargs.farg[0],
245     o->oargs.farg[1], o->oargs.farg[2]);
246     if ((m->type = o->otype) == MAT_MFUNC)
247     copycolor(m->u.m.specular, m->u.m.ambdiff);
248     else
249     setcolor(m->u.m.specular, 1., 1., 1.);
250     scalecolor(m->u.m.specular, o->oargs.farg[3]);
251     scalecolor(m->u.m.ambdiff, 1.-o->oargs.farg[3]);
252     if (m->type == MAT_TFUNC) {
253     scalecolor(m->u.m.specular, 1.-o->oargs.farg[4]);
254     scalecolor(m->u.m.ambdiff, 1.-o->oargs.farg[4]);
255     }
256     m->u.m.specexp = UNKSPECEXP;
257     }
258    
259    
260 greg 3.2 int
261 gwlarson 3.1 m_brdf2(o) /* convert advanced functional material */
262     register OBJREC *o;
263     {
264     register MATREC *m;
265    
266     if (o->oargs.nfargs < 9)
267     objerror(o, USER, "bad # of real arguments");
268     m = newmaterial(o->oname);
269     m->type = o->otype;
270     /* assign average diffuse front+back */
271     setcolor(m->u.m.ambdiff, (o->oargs.farg[0]+o->oargs.farg[3])*.5,
272     (o->oargs.farg[1]+o->oargs.farg[4])*.5,
273     (o->oargs.farg[2]+o->oargs.farg[5])*.5);
274     /* guess the rest */
275     setcolor(m->u.m.specular, .1, .1, .1);
276     m->u.m.specexp = UNKSPECEXP;
277     }
278    
279    
280 greg 3.2 int
281 gwlarson 3.1 m_light(o) /* convert light type */
282     register OBJREC *o;
283     {
284     FVECT v;
285     register MATREC *m;
286    
287     if (o->oargs.nfargs < (o->otype == MAT_SPOT ? 7 : 3))
288     objerror(o, USER, "bad # of real arguments");
289     m = newmaterial(o->oname);
290     setcolor(m->u.l.emission, o->oargs.farg[0],
291     o->oargs.farg[1], o->oargs.farg[2]);
292     if ((m->type = o->otype) == MAT_SPOT) {
293     if ((m->u.l.spotang = o->oargs.farg[3]/2.) > 90.)
294     m->u.l.spotang = 180.;
295     v[0] = o->oargs.farg[4];
296     v[1] = o->oargs.farg[5];
297     v[2] = o->oargs.farg[6];
298     if (normalize(v) == 0.)
299     objerror(o, USER, "illegal direction");
300     VCOPY(m->u.l.spotdir, v);
301     } else {
302     m->u.l.spotang = 180.;
303     m->u.l.spotdir[0] = m->u.l.spotdir[1] = 0.;
304     m->u.l.spotdir[2] = -1.;
305     }
306     }
307    
308    
309 greg 3.2 int
310 gwlarson 3.1 m_mirror(o) /* convert mirror type */
311     register OBJREC *o;
312     {
313     register MATREC *m;
314    
315     if (o->oargs.nfargs != 3)
316     objerror(o, USER, "bad # real arguments");
317     m = newmaterial(o->oname);
318     m->type = o->otype;
319     setcolor(m->u.m.ambdiff, 0., 0., 0.);
320     setcolor(m->u.m.specular, o->oargs.farg[0],
321     o->oargs.farg[1], o->oargs.farg[2]);
322     m->u.m.specexp = MAXSPECEXP;
323     }
324    
325    
326 greg 3.2 int
327 gwlarson 3.1 m_prism(o) /* convert prism type */
328     register OBJREC *o;
329     {
330     register MATREC *m;
331     /* can't really deal with this type */
332     m = newmaterial(o->oname);
333     m->type = o->otype;
334     setcolor(m->u.m.ambdiff, 0.2, 0.2, 0.2);
335     setcolor(m->u.m.specular, 0.1, 0.1, 0.1);
336     m->u.m.specexp = UNKSPECEXP;
337     }