ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/common/cone.c
Revision: 2.5
Committed: Sat Feb 22 02:07:22 2003 UTC (21 years, 2 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.4: +61 -7 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.5 static const char RCSid[] = "$Id$";
3 greg 1.1 #endif
4     /*
5     * cone.c - routines for making cones
6 greg 2.5 */
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 greg 1.1 *
59 greg 2.5 * 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 greg 1.1 */
64    
65     #include "standard.h"
66    
67     #include "object.h"
68    
69     #include "otypes.h"
70    
71     #include "cone.h"
72    
73     /*
74     * In general, a cone may be any one of a cone, a cylinder, a ring,
75     * a cup (inverted cone), or a tube (inverted cylinder).
76     * Most cones are specified with a starting point and radius and
77     * an ending point and radius. In the cases of a cylinder or tube,
78     * only one radius is needed. In the case of a ring, a normal direction
79     * is specified instead of a second endpoint.
80     *
81     * mtype (cone|cup) name
82     * 0
83     * 0
84     * 8 P0x P0y P0z P1x P1y P1z R0 R1
85     *
86     * mtype (cylinder|tube) name
87     * 0
88     * 0
89     * 7 P0x P0y P0z P1x P1y P1z R
90     *
91     * mtype ring name
92     * 0
93     * 0
94     * 8 Px Py Pz Nx Ny Nz R0 R1
95     */
96    
97    
98     CONE *
99     getcone(o, getxf) /* get cone structure */
100     register OBJREC *o;
101     int getxf;
102     {
103 greg 1.4 int sgn0, sgn1;
104 greg 1.1 register CONE *co;
105    
106     if ((co = (CONE *)o->os) == NULL) {
107    
108     co = (CONE *)malloc(sizeof(CONE));
109     if (co == NULL)
110     error(SYSTEM, "out of memory in makecone");
111    
112     co->ca = o->oargs.farg;
113     /* get radii */
114 greg 2.2 if (o->otype == OBJ_CYLINDER | o->otype == OBJ_TUBE) {
115 greg 1.1 if (o->oargs.nfargs != 7)
116     goto argcerr;
117 greg 1.4 if (co->ca[6] < -FTINY) {
118     objerror(o, WARNING, "negative radius");
119     o->otype = o->otype == OBJ_CYLINDER ?
120     OBJ_TUBE : OBJ_CYLINDER;
121     co->ca[6] = -co->ca[6];
122     } else if (co->ca[6] <= FTINY)
123 greg 1.1 goto raderr;
124 greg 2.2 co->p0 = 0; co->p1 = 3;
125 greg 1.1 co->r0 = co->r1 = 6;
126     } else {
127     if (o->oargs.nfargs != 8)
128     goto argcerr;
129 greg 1.4 if (co->ca[6] < -FTINY) sgn0 = -1;
130     else if (co->ca[6] > FTINY) sgn0 = 1;
131     else sgn0 = 0;
132     if (co->ca[7] < -FTINY) sgn1 = -1;
133     else if (co->ca[7] > FTINY) sgn1 = 1;
134     else sgn1 = 0;
135     if (sgn0+sgn1 == 0)
136 greg 1.1 goto raderr;
137 greg 2.2 if (sgn0 < 0 | sgn1 < 0) {
138 greg 1.4 objerror(o, o->otype==OBJ_RING?USER:WARNING,
139     "negative radii");
140     o->otype = o->otype == OBJ_CONE ?
141     OBJ_CUP : OBJ_CONE;
142     }
143     co->ca[6] = co->ca[6]*sgn0;
144     co->ca[7] = co->ca[7]*sgn1;
145 greg 2.2 if (co->ca[7] - co->ca[6] > FTINY) {
146 greg 1.4 if (o->otype == OBJ_RING)
147 greg 2.2 co->p0 = co->p1 = 0;
148     else {
149     co->p0 = 0; co->p1 = 3;
150     }
151     co->r0 = 6; co->r1 = 7;
152     } else if (co->ca[6] - co->ca[7] > FTINY) {
153     if (o->otype == OBJ_RING)
154     co->p0 = co->p1 = 0;
155     else {
156     co->p0 = 3; co->p1 = 0;
157     }
158     co->r0 = 7; co->r1 = 6;
159     } else {
160     if (o->otype == OBJ_RING)
161 greg 1.4 goto raderr;
162     o->otype = o->otype == OBJ_CONE ?
163     OBJ_CYLINDER : OBJ_TUBE;
164     o->oargs.nfargs = 7;
165 greg 2.2 co->p0 = 0; co->p1 = 3;
166     co->r0 = co->r1 = 6;
167 greg 1.4 }
168 greg 1.1 }
169     /* get axis orientation */
170 greg 2.2 if (o->otype == OBJ_RING)
171 greg 1.1 VCOPY(co->ad, o->oargs.farg+3);
172 greg 2.2 else {
173     co->ad[0] = CO_P1(co)[0] - CO_P0(co)[0];
174     co->ad[1] = CO_P1(co)[1] - CO_P0(co)[1];
175     co->ad[2] = CO_P1(co)[2] - CO_P0(co)[2];
176 greg 1.1 }
177     co->al = normalize(co->ad);
178     if (co->al == 0.0)
179     objerror(o, USER, "zero orientation");
180     /* compute axis and side lengths */
181     if (o->otype == OBJ_RING) {
182     co->al = 0.0;
183 greg 2.2 co->sl = CO_R1(co) - CO_R0(co);
184     } else if (o->otype == OBJ_CONE | o->otype == OBJ_CUP) {
185 greg 1.1 co->sl = co->ca[7] - co->ca[6];
186     co->sl = sqrt(co->sl*co->sl + co->al*co->al);
187 greg 2.2 } else { /* OBJ_CYLINDER or OBJ_TUBE */
188 greg 1.1 co->sl = co->al;
189     }
190     co->tm = NULL;
191 greg 1.2 o->os = (char *)co;
192 greg 1.1 }
193     if (getxf && co->tm == NULL)
194     conexform(co);
195     return(co);
196    
197     argcerr:
198     objerror(o, USER, "bad # arguments");
199     raderr:
200     objerror(o, USER, "illegal radii");
201     }
202    
203    
204 greg 2.5 void
205 greg 1.1 freecone(o) /* free memory associated with cone */
206     OBJREC *o;
207     {
208     register CONE *co = (CONE *)o->os;
209    
210 greg 2.4 if (co == NULL)
211 greg 1.5 return;
212 greg 1.1 if (co->tm != NULL)
213 greg 2.5 free((void *)co->tm);
214     free((void *)co);
215 greg 1.1 o->os = NULL;
216     }
217    
218    
219 greg 2.5 void
220 greg 1.1 conexform(co) /* get cone transformation matrix */
221     register CONE *co;
222     {
223 greg 1.6 MAT4 m4;
224 greg 1.1 register double d;
225     register int i;
226    
227 greg 2.2 co->tm = (FLOAT (*)[4])malloc(sizeof(MAT4));
228 greg 1.1 if (co->tm == NULL)
229     error(SYSTEM, "out of memory in conexform");
230    
231     /* translate to origin */
232     setident4(co->tm);
233     if (co->r0 == co->r1)
234     d = 0.0;
235     else
236 greg 2.2 d = CO_R0(co) / (CO_R1(co) - CO_R0(co));
237 greg 1.1 for (i = 0; i < 3; i++)
238 greg 2.2 co->tm[3][i] = d*(CO_P1(co)[i] - CO_P0(co)[i])
239     - CO_P0(co)[i];
240 greg 1.1
241     /* rotate to positive z-axis */
242     setident4(m4);
243     d = co->ad[1]*co->ad[1] + co->ad[2]*co->ad[2];
244     if (d <= FTINY*FTINY) {
245     m4[0][0] = 0.0;
246     m4[0][2] = co->ad[0];
247     m4[2][0] = -co->ad[0];
248     m4[2][2] = 0.0;
249     } else {
250     d = sqrt(d);
251     m4[0][0] = d;
252     m4[1][0] = -co->ad[0]*co->ad[1]/d;
253     m4[2][0] = -co->ad[0]*co->ad[2]/d;
254     m4[1][1] = co->ad[2]/d;
255     m4[2][1] = -co->ad[1]/d;
256     m4[0][2] = co->ad[0];
257     m4[1][2] = co->ad[1];
258     m4[2][2] = co->ad[2];
259     }
260     multmat4(co->tm, co->tm, m4);
261    
262     /* scale z-axis */
263 greg 2.2 if (co->p0 != co->p1 & co->r0 != co->r1) {
264     setident4(m4);
265     m4[2][2] = (CO_R1(co) - CO_R0(co)) / co->al;
266     multmat4(co->tm, co->tm, m4);
267 greg 1.1 }
268     }