ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/rt/m_direct.c
Revision: 2.8
Committed: Sat Feb 22 02:07:28 2003 UTC (21 years, 2 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.7: +63 -5 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 greg 1.1 #ifndef lint
2 greg 2.8 static const char RCSid[] = "$Id$";
3 greg 1.1 #endif
4     /*
5     * Routines for light-redirecting materials and
6     * their associated virtual light sources
7     */
8    
9 greg 2.8 /* ====================================================================
10     * The Radiance Software License, Version 1.0
11     *
12     * Copyright (c) 1990 - 2002 The Regents of the University of California,
13     * through Lawrence Berkeley National Laboratory. All rights reserved.
14     *
15     * Redistribution and use in source and binary forms, with or without
16     * modification, are permitted provided that the following conditions
17     * are met:
18     *
19     * 1. Redistributions of source code must retain the above copyright
20     * notice, this list of conditions and the following disclaimer.
21     *
22     * 2. Redistributions in binary form must reproduce the above copyright
23     * notice, this list of conditions and the following disclaimer in
24     * the documentation and/or other materials provided with the
25     * distribution.
26     *
27     * 3. The end-user documentation included with the redistribution,
28     * if any, must include the following acknowledgment:
29     * "This product includes Radiance software
30     * (http://radsite.lbl.gov/)
31     * developed by the Lawrence Berkeley National Laboratory
32     * (http://www.lbl.gov/)."
33     * Alternately, this acknowledgment may appear in the software itself,
34     * if and wherever such third-party acknowledgments normally appear.
35     *
36     * 4. The names "Radiance," "Lawrence Berkeley National Laboratory"
37     * and "The Regents of the University of California" must
38     * not be used to endorse or promote products derived from this
39     * software without prior written permission. For written
40     * permission, please contact [email protected].
41     *
42     * 5. Products derived from this software may not be called "Radiance",
43     * nor may "Radiance" appear in their name, without prior written
44     * permission of Lawrence Berkeley National Laboratory.
45     *
46     * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
47     * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
48     * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
49     * DISCLAIMED. IN NO EVENT SHALL Lawrence Berkeley National Laboratory OR
50     * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
51     * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
52     * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
53     * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
54     * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
55     * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
56     * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
57     * SUCH DAMAGE.
58     * ====================================================================
59     *
60     * This software consists of voluntary contributions made by many
61     * individuals on behalf of Lawrence Berkeley National Laboratory. For more
62     * information on Lawrence Berkeley National Laboratory, please see
63     * <http://www.lbl.gov/>.
64     */
65    
66 greg 1.1 #include "ray.h"
67    
68     #include "otypes.h"
69    
70     #include "source.h"
71    
72 greg 2.2 #include "func.h"
73    
74 greg 1.1 /*
75     * The arguments for MAT_DIRECT1 are:
76     *
77 greg 1.3 * 5+ coef1 dx1 dy1 dz1 funcfile transform..
78 greg 1.1 * 0
79     * n A1 A2 .. An
80     *
81     * The arguments for MAT_DIRECT2 are:
82     *
83 greg 1.3 * 9+ coef1 dx1 dy1 dz1 coef2 dx2 dy2 dz2 funcfile transform..
84 greg 1.1 * 0
85     * n A1 A2 .. An
86     */
87    
88    
89 greg 2.8 static int dir_proj();
90    
91 greg 1.1 VSMATERIAL direct1_vs = {dir_proj, 1};
92     VSMATERIAL direct2_vs = {dir_proj, 2};
93    
94 greg 2.2 #define getdfunc(m) ( (m)->otype == MAT_DIRECT1 ? \
95     getfunc(m, 4, 0xf, 1) : \
96     getfunc(m, 8, 0xff, 1) )
97 greg 1.1
98 greg 1.6
99 greg 2.8 int
100 greg 1.1 m_direct(m, r) /* shade redirected ray */
101     register OBJREC *m;
102     register RAY *r;
103     {
104     /* check if source ray */
105     if (r->rsrc >= 0 && source[r->rsrc].so != r->ro)
106 greg 2.4 return(1); /* got the wrong guy */
107 greg 1.1 /* compute first projection */
108     if (m->otype == MAT_DIRECT1 ||
109     (r->rsrc < 0 || source[r->rsrc].sa.sv.pn == 0))
110     redirect(m, r, 0);
111     /* compute second projection */
112     if (m->otype == MAT_DIRECT2 &&
113     (r->rsrc < 0 || source[r->rsrc].sa.sv.pn == 1))
114     redirect(m, r, 1);
115 greg 2.4 return(1);
116 greg 1.1 }
117    
118    
119 greg 2.8 int
120 greg 1.1 redirect(m, r, n) /* compute n'th ray redirection */
121     OBJREC *m;
122     RAY *r;
123     int n;
124     {
125 greg 2.2 MFUNC *mf;
126     register EPNODE **va;
127 greg 2.3 FVECT nsdir;
128 greg 1.1 RAY nr;
129     double coef;
130     register int j;
131     /* set up function */
132 greg 2.2 mf = getdfunc(m);
133     setfunc(m, r);
134 greg 2.3 /* assign direction variable */
135     if (r->rsrc >= 0) {
136     register SRCREC *sp = source + source[r->rsrc].sa.sv.sn;
137    
138     if (sp->sflags & SDISTANT)
139     VCOPY(nsdir, sp->sloc);
140     else {
141     for (j = 0; j < 3; j++)
142     nsdir[j] = sp->sloc[j] - r->rop[j];
143     normalize(nsdir);
144     }
145 greg 2.6 multv3(nsdir, nsdir, funcxf.xfm);
146     varset("DxA", '=', nsdir[0]/funcxf.sca);
147     varset("DyA", '=', nsdir[1]/funcxf.sca);
148     varset("DzA", '=', nsdir[2]/funcxf.sca);
149     } else {
150     varset("DxA", '=', 0.0);
151     varset("DyA", '=', 0.0);
152     varset("DzA", '=', 0.0);
153     }
154 greg 1.1 /* compute coefficient */
155     errno = 0;
156 greg 2.2 va = mf->ep + 4*n;
157     coef = evalue(va[0]);
158 greg 1.1 if (errno)
159     goto computerr;
160     if (coef <= FTINY || rayorigin(&nr, r, TRANS, coef) < 0)
161     return(0);
162 greg 2.2 va++; /* compute direction */
163     for (j = 0; j < 3; j++) {
164     nr.rdir[j] = evalue(va[j]);
165     if (errno)
166     goto computerr;
167     }
168     if (mf->f != &unitxf)
169     multv3(nr.rdir, nr.rdir, mf->f->xfm);
170 greg 1.4 if (r->rox != NULL)
171     multv3(nr.rdir, nr.rdir, r->rox->f.xfm);
172     if (normalize(nr.rdir) == 0.0)
173     goto computerr;
174 greg 1.1 /* compute value */
175     if (r->rsrc >= 0)
176     nr.rsrc = source[r->rsrc].sa.sv.sn;
177     rayvalue(&nr);
178     scalecolor(nr.rcol, coef);
179     addcolor(r->rcol, nr.rcol);
180 greg 2.7 if (r->ro != NULL && isflat(r->ro->otype))
181     r->rt = r->rot + nr.rt;
182 greg 1.1 return(1);
183     computerr:
184     objerror(m, WARNING, "compute error");
185     return(-1);
186     }
187    
188    
189 greg 2.8 static int
190 greg 1.1 dir_proj(pm, o, s, n) /* compute a director's projection */
191     MAT4 pm;
192     OBJREC *o;
193     SRCREC *s;
194     int n;
195     {
196     RAY tr;
197 greg 2.2 OBJREC *m;
198     MFUNC *mf;
199     EPNODE **va;
200 greg 1.1 FVECT cent, newdir, nv, h;
201 greg 2.2 double coef, olddot, newdot, od;
202 greg 1.1 register int i, j;
203     /* initialize test ray */
204     getmaxdisk(cent, o);
205     if (s->sflags & SDISTANT)
206     for (i = 0; i < 3; i++) {
207     tr.rdir[i] = -s->sloc[i];
208     tr.rorg[i] = cent[i] - tr.rdir[i];
209     }
210     else {
211     for (i = 0; i < 3; i++) {
212     tr.rdir[i] = cent[i] - s->sloc[i];
213 greg 1.2 tr.rorg[i] = s->sloc[i];
214 greg 1.1 }
215     if (normalize(tr.rdir) == 0.0)
216     return(0); /* at source! */
217     }
218     od = getplaneq(nv, o);
219     olddot = DOT(tr.rdir, nv);
220     if (olddot <= FTINY && olddot >= -FTINY)
221     return(0); /* old dir parallels plane */
222 greg 2.5 tr.rmax = 0.0;
223 greg 1.1 rayorigin(&tr, NULL, PRIMARY, 1.0);
224     if (!(*ofun[o->otype].funp)(o, &tr))
225     return(0); /* no intersection! */
226     /* compute redirection */
227 greg 2.2 m = vsmaterial(o);
228     mf = getdfunc(m);
229     setfunc(m, &tr);
230 greg 2.3 varset("DxA", '=', 0.0);
231     varset("DyA", '=', 0.0);
232     varset("DzA", '=', 0.0);
233 greg 1.1 errno = 0;
234 greg 2.2 va = mf->ep + 4*n;
235     coef = evalue(va[0]);
236 greg 1.1 if (errno)
237     goto computerr;
238 greg 2.2 if (coef <= FTINY)
239     return(0); /* insignificant */
240     va++;
241     for (i = 0; i < 3; i++) {
242     newdir[i] = evalue(va[i]);
243     if (errno)
244     goto computerr;
245     }
246     if (mf->f != &unitxf)
247     multv3(newdir, newdir, mf->f->xfm);
248 greg 1.4 /* normalization unnecessary */
249 greg 1.1 newdot = DOT(newdir, nv);
250     if (newdot <= FTINY && newdot >= -FTINY)
251     return(0); /* new dir parallels plane */
252     /* everything OK -- compute shear */
253     for (i = 0; i < 3; i++)
254 greg 1.4 h[i] = newdir[i]/newdot - tr.rdir[i]/olddot;
255 greg 1.1 setident4(pm);
256     for (j = 0; j < 3; j++) {
257     for (i = 0; i < 3; i++)
258     pm[i][j] += nv[i]*h[j];
259     pm[3][j] = -od*h[j];
260     }
261     if (newdot > 0.0 ^ olddot > 0.0) /* add mirroring */
262     for (j = 0; j < 3; j++) {
263     for (i = 0; i < 3; i++)
264     pm[i][j] -= 2.*nv[i]*nv[j];
265     pm[3][j] += 2.*od*nv[j];
266     }
267     return(1);
268     computerr:
269     objerror(m, WARNING, "projection compute error");
270     return(0);
271     }