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

# Content
1 #ifndef lint
2 static const char RCSid[] = "$Id$";
3 #endif
4 /*
5 * Routines for mirror material supporting virtual light sources
6 */
7
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 #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 static int mir_proj(), mirrorproj();
84
85 VSMATERIAL mirror_vs = {mir_proj, 1};
86
87
88 int
89 m_mirror(m, r) /* shade mirrored ray */
90 register OBJREC *m;
91 register RAY *r;
92 {
93 COLOR mcolor;
94 RAY nr;
95 int rpure = 1;
96 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 /* check for substitute material */
101 if (m->oargs.nsargs > 0 &&
102 (r->rsrc < 0 || source[r->rsrc].so != r->ro)) {
103 if (!strcmp(m->oargs.sarg[0], VOIDID)) {
104 raytrans(r);
105 return(1);
106 }
107 return(rayshade(r, lastmod(objndx(m), m->oargs.sarg[0])));
108 }
109 /* check for bad source ray */
110 if (r->rsrc >= 0 && source[r->rsrc].so != r->ro)
111 return(1);
112
113 if (r->rod < 0.) /* back is black */
114 return(1);
115 /* 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 nr.rsrc = source[r->rsrc].sa.sv.sn;
130 } else { /* ordinary reflection */
131 FVECT pnorm;
132 double pdot;
133
134 if (rayorigin(&nr, r, REFLECTED, bright(mcolor)) < 0)
135 return(1);
136 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 /* check for penetration */
143 if (rpure || DOT(nr.rdir, r->ron) <= FTINY)
144 for (i = 0; i < 3; i++)
145 nr.rdir[i] = r->rdir[i] + 2.*r->rod*r->ron[i];
146 }
147 rayvalue(&nr);
148 multcolor(nr.rcol, mcolor);
149 addcolor(r->rcol, nr.rcol);
150 if (rpure && r->ro != NULL && isflat(r->ro->otype))
151 r->rt = r->rot + nr.rt;
152 return(1);
153 }
154
155
156 static int
157 mir_proj(pm, o, s, n) /* compute a mirror's projection */
158 MAT4 pm;
159 register OBJREC *o;
160 SRCREC *s;
161 int n;
162 {
163 FVECT nv, sc;
164 double od;
165 register int i, j;
166 /* get surface normal and offset */
167 od = getplaneq(nv, o);
168 /* 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 return(0);
179 /* everything OK -- compute projection */
180 mirrorproj(pm, nv, od);
181 return(1);
182 }
183
184
185 static int
186 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 for (j = 0; j < 3; j++) {
195 for (i = 0; i < 3; i++)
196 m[i][j] -= 2.*nv[i]*nv[j];
197 m[3][j] = 2.*offs*nv[j];
198 }
199 }