ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/rt/m_mirror.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 mirror material supporting virtual light sources
6     */
7    
8 greg 2.8 /* ====================================================================
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 greg 1.1 #include "ray.h"
66    
67     #include "otypes.h"
68    
69     #include "source.h"
70    
71     /*
72     * The real arguments for MAT_MIRROR are simply:
73     *
74     * 3 rrefl grefl brefl
75     *
76     * Additionally, the user may specify a single string argument
77     * which is interpreted as the name of the material to use
78     * instead of the mirror if the ray being considered is not
79     * part of the direct calculation.
80     */
81    
82    
83 greg 2.8 static int mir_proj(), mirrorproj();
84    
85 greg 1.1 VSMATERIAL mirror_vs = {mir_proj, 1};
86    
87    
88 greg 2.8 int
89 greg 1.1 m_mirror(m, r) /* shade mirrored ray */
90     register OBJREC *m;
91     register RAY *r;
92     {
93     COLOR mcolor;
94     RAY nr;
95 greg 2.6 int rpure = 1;
96 greg 1.1 register int i;
97     /* check arguments */
98     if (m->oargs.nfargs != 3 || m->oargs.nsargs > 1)
99     objerror(m, USER, "bad number of arguments");
100 greg 1.3 /* check for substitute material */
101     if (m->oargs.nsargs > 0 &&
102     (r->rsrc < 0 || source[r->rsrc].so != r->ro)) {
103 greg 2.4 if (!strcmp(m->oargs.sarg[0], VOIDID)) {
104     raytrans(r);
105     return(1);
106     }
107 gwlarson 2.7 return(rayshade(r, lastmod(objndx(m), m->oargs.sarg[0])));
108 greg 1.1 }
109 greg 1.3 /* check for bad source ray */
110     if (r->rsrc >= 0 && source[r->rsrc].so != r->ro)
111 greg 2.3 return(1);
112 greg 1.3
113 greg 1.1 if (r->rod < 0.) /* back is black */
114 greg 2.3 return(1);
115 greg 1.1 /* get modifiers */
116     raytexture(r, m->omod);
117     /* assign material color */
118     setcolor(mcolor, m->oargs.farg[0],
119     m->oargs.farg[1],
120     m->oargs.farg[2]);
121     multcolor(mcolor, r->pcol);
122     /* compute reflected ray */
123     if (r->rsrc >= 0) { /* relayed light source */
124     rayorigin(&nr, r, REFLECTED, 1.);
125     /* ignore textures */
126     for (i = 0; i < 3; i++)
127     nr.rdir[i] = r->rdir[i] + 2.*r->rod*r->ron[i];
128     /* source we're aiming for next */
129 greg 1.2 nr.rsrc = source[r->rsrc].sa.sv.sn;
130 greg 1.1 } else { /* ordinary reflection */
131     FVECT pnorm;
132     double pdot;
133    
134     if (rayorigin(&nr, r, REFLECTED, bright(mcolor)) < 0)
135 greg 2.3 return(1);
136 greg 2.6 if (DOT(r->pert,r->pert) > FTINY*FTINY) {
137     pdot = raynormal(pnorm, r); /* use textures */
138     for (i = 0; i < 3; i++)
139     nr.rdir[i] = r->rdir[i] + 2.*pdot*pnorm[i];
140     rpure = 0;
141     }
142 greg 2.2 /* check for penetration */
143 greg 2.6 if (rpure || DOT(nr.rdir, r->ron) <= FTINY)
144 greg 2.2 for (i = 0; i < 3; i++)
145     nr.rdir[i] = r->rdir[i] + 2.*r->rod*r->ron[i];
146 greg 1.1 }
147     rayvalue(&nr);
148     multcolor(nr.rcol, mcolor);
149     addcolor(r->rcol, nr.rcol);
150 greg 2.6 if (rpure && r->ro != NULL && isflat(r->ro->otype))
151     r->rt = r->rot + nr.rt;
152 greg 2.3 return(1);
153 greg 1.1 }
154    
155    
156 greg 2.8 static int
157 greg 1.1 mir_proj(pm, o, s, n) /* compute a mirror's projection */
158     MAT4 pm;
159     register OBJREC *o;
160 greg 1.2 SRCREC *s;
161 greg 1.1 int n;
162     {
163 greg 2.5 FVECT nv, sc;
164 greg 1.1 double od;
165 greg 2.5 register int i, j;
166 greg 1.1 /* get surface normal and offset */
167 greg 1.2 od = getplaneq(nv, o);
168 greg 2.5 /* check for extreme point for behind */
169     VCOPY(sc, s->sloc);
170     for (i = s->sflags & SFLAT ? SV : SW; i >= 0; i--)
171     if (DOT(nv, s->ss[i]) > 0.)
172     for (j = 0; j < 3; j++)
173     sc[j] += s->ss[i][j];
174     else
175     for (j = 0; j < 3; j++)
176     sc[j] -= s->ss[i][j];
177     if (DOT(sc, nv) <= (s->sflags & SDISTANT ? FTINY : od+FTINY))
178 greg 1.1 return(0);
179     /* everything OK -- compute projection */
180     mirrorproj(pm, nv, od);
181     return(1);
182     }
183    
184    
185 greg 2.8 static int
186 greg 1.1 mirrorproj(m, nv, offs) /* get mirror projection for surface */
187     register MAT4 m;
188     FVECT nv;
189     double offs;
190     {
191     register int i, j;
192     /* assign matrix */
193     setident4(m);
194 greg 1.2 for (j = 0; j < 3; j++) {
195     for (i = 0; i < 3; i++)
196 greg 1.1 m[i][j] -= 2.*nv[i]*nv[j];
197     m[3][j] = 2.*offs*nv[j];
198 greg 1.2 }
199 greg 1.1 }