ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/common/rglsurf.c
Revision: 3.1
Committed: Tue Jun 9 11:18:36 1998 UTC (25 years, 10 months ago) by gwlarson
Content type: text/plain
Branch: MAIN
Log Message:
Initial revision

File Contents

# User Rev Content
1 gwlarson 3.1 /* Copyright (c) 1998 Silicon Graphics, Inc. */
2    
3     #ifndef lint
4     static char SCCSid[] = "$SunId$ SGI";
5     #endif
6    
7     /*
8     * Convert Radiance -> OpenGL surfaces.
9     */
10    
11     #include "radogl.h"
12    
13     #ifndef NSLICES
14     #define NSLICES 18 /* number of quadric slices */
15     #endif
16     #ifndef NSTACKS
17     #define NSTACKS 10 /* number of quadric stacks */
18     #endif
19    
20     MATREC *curmat = NULL; /* current material */
21    
22     static int curpolysize = 0; /* outputting triangles/quads */
23    
24     static GLUquadricObj *gluqo; /* shared quadric object */
25     static GLUtesselator *gluto; /* shared tessallation object */
26    
27     static char *glu_rout = "unk"; /* active GLU routine */
28    
29     #define NOPOLY() if (curpolysize) {glEnd(); curpolysize = 0;} else
30    
31    
32     setmaterial(mp, cent, ispoly) /* prepare for new material */
33     register MATREC *mp;
34     FVECT cent;
35     int ispoly;
36     {
37     if (mp != curmat && domats) {
38     NOPOLY();
39     domatobj(curmat = mp, cent);
40     } else if (!ispoly)
41     NOPOLY();
42     }
43    
44    
45     double
46     polyarea(cent, norm, n, v) /* compute polygon area & normal */
47     FVECT cent, norm; /* returned center and normal */
48     int n; /* number of vertices */
49     register FVECT v[]; /* vertex list */
50     {
51     FVECT v1, v2, v3;
52     double d;
53     register int i;
54    
55     norm[0] = norm[1] = norm[2] = 0.;
56     v1[0] = v[1][0] - v[0][0];
57     v1[1] = v[1][1] - v[0][1];
58     v1[2] = v[1][2] - v[0][2];
59     for (i = 2; i < n; i++) {
60     v2[0] = v[i][0] - v[0][0];
61     v2[1] = v[i][1] - v[0][1];
62     v2[2] = v[i][2] - v[0][2];
63     fcross(v3, v1, v2);
64     norm[0] += v3[0];
65     norm[1] += v3[1];
66     norm[2] += v3[2];
67     VCOPY(v1, v2);
68     }
69     if (cent != NULL) { /* compute center also */
70     cent[0] = cent[1] = cent[2] = 0.;
71     for (i = n; i--; ) {
72     cent[0] += v[i][0];
73     cent[1] += v[i][1];
74     cent[2] += v[i][2];
75     }
76     d = 1./n;
77     cent[0] *= d; cent[1] *= d; cent[2] *= d;
78     }
79     return(normalize(norm)*.5);
80     }
81    
82    
83     static
84     glu_error(en) /* report a tessellation error as a warning */
85     GLenum en;
86     {
87     sprintf(errmsg, "GLU error %s: %s", glu_rout, gluErrorString(en));
88     error(WARNING, errmsg);
89     }
90    
91    
92     static
93     newtess() /* allocate GLU tessellation object */
94     {
95     if ((gluto = gluNewTess()) == NULL)
96     error(INTERNAL, "gluNewTess failed");
97     gluTessCallback(gluto, GLU_TESS_BEGIN, glBegin);
98     gluTessCallback(gluto, GLU_TESS_VERTEX, glVertex3dv);
99     gluTessCallback(gluto, GLU_TESS_END, glEnd);
100     gluTessCallback(gluto, GLU_TESS_ERROR, glu_error);
101     gluTessProperty(gluto, GLU_TESS_WINDING_RULE, GLU_TESS_WINDING_NONZERO);
102     }
103    
104    
105     static
106     newquadric() /* allocate GLU quadric structure */
107     {
108     if ((gluqo = gluNewQuadric()) == NULL)
109     error(INTERNAL, "gluNewQuadric failed");
110     gluQuadricDrawStyle(gluqo, GLU_FILL);
111     gluQuadricCallback(gluqo, GLU_ERROR, glu_error);
112     }
113    
114    
115     o_face(o) /* convert a face */
116     register OBJREC *o;
117     {
118     double area;
119     FVECT norm, cent;
120     register int i;
121    
122     if (o->oargs.nfargs < 9 | o->oargs.nfargs % 3)
123     objerror(o, USER, "bad # real arguments");
124     area = polyarea(cent, norm, o->oargs.nfargs/3, (FVECT *)o->oargs.farg);
125     if (area <= FTINY)
126     return;
127     if (dolights) /* check for source */
128     doflatsrc(o->os, cent, norm, area);
129     setmaterial(o->os, cent, 1); /* set material */
130     if (o->oargs.nfargs/3 != curpolysize) {
131     if (curpolysize) glEnd();
132     curpolysize = o->oargs.nfargs/3;
133     if (curpolysize == 3)
134     glBegin(GL_TRIANGLES);
135     else if (curpolysize == 4)
136     glBegin(GL_QUADS);
137     }
138     glNormal3d((GLdouble)norm[0], (GLdouble)norm[1], (GLdouble)norm[2]);
139     if (curpolysize > 4) {
140     if (gluto == NULL) newtess();
141     glu_rout = "tessellating polygon";
142     gluTessNormal(gluto, (GLdouble)norm[0],
143     (GLdouble)norm[1], (GLdouble)norm[2]);
144     gluTessBeginPolygon(gluto, NULL);
145     gluTessBeginContour(gluto);
146     #ifdef SMLFLT
147     error(INTERNAL, "bad code segment in o_face");
148     #endif
149     for (i = 0; i < curpolysize; i++)
150     gluTessVertex(gluto, (GLdouble *)(o->oargs.farg+3*i),
151     (void *)(o->oargs.farg+3*i));
152     gluTessEndContour(gluto);
153     gluTessEndPolygon(gluto);
154     curpolysize = 0;
155     } else {
156     for (i = 0; i < curpolysize; i++)
157     glVertex3d((GLdouble)o->oargs.farg[3*i],
158     (GLdouble)o->oargs.farg[3*i+1],
159     (GLdouble)o->oargs.farg[3*i+2]);
160     }
161     }
162    
163    
164     surfclean() /* clean up surface routines */
165     {
166     setmaterial(NULL, NULL, 0);
167     if (gluqo != NULL) {
168     gluDeleteQuadric(gluqo);
169     gluqo = NULL;
170     }
171     if (gluto != NULL) {
172     gluDeleteTess(gluto);
173     gluto = NULL;
174     }
175     rgl_checkerr("in surfclean");
176     }
177    
178    
179     o_sphere(o) /* convert a sphere */
180     register OBJREC *o;
181     {
182     /* check arguments */
183     if (o->oargs.nfargs != 4)
184     objerror(o, USER, "bad # real arguments");
185     if (o->oargs.farg[3] < -FTINY) {
186     o->otype = o->otype==OBJ_SPHERE ? OBJ_BUBBLE : OBJ_SPHERE;
187     o->oargs.farg[3] = -o->oargs.farg[3];
188     } else if (o->oargs.farg[3] <= FTINY)
189     return;
190     if (dolights)
191     dosphsrc(o->os, o->oargs.farg,
192     PI*o->oargs.farg[3]*o->oargs.farg[3]);
193     setmaterial(o->os, o->oargs.farg, 0);
194     if (gluqo == NULL) newquadric();
195     glu_rout = "making sphere";
196     gluQuadricOrientation(gluqo,
197     o->otype==OBJ_BUBBLE ? GLU_INSIDE : GLU_OUTSIDE);
198     gluQuadricNormals(gluqo, GLU_SMOOTH);
199     glMatrixMode(GL_MODELVIEW);
200     glPushMatrix();
201     glTranslated((GLdouble)o->oargs.farg[0], (GLdouble)o->oargs.farg[1],
202     (GLdouble)o->oargs.farg[2]);
203     gluSphere(gluqo, (GLdouble)o->oargs.farg[3], NSLICES, NSTACKS);
204     glPopMatrix();
205     rgl_checkerr("creating sphere");
206     }
207    
208    
209     o_cone(o) /* convert a cone or cylinder */
210     register OBJREC *o;
211     {
212     double x1, y1, h, d;
213     FVECT cent;
214     register int iscyl;
215    
216     iscyl = o->otype==OBJ_CYLINDER | o->otype==OBJ_TUBE;
217     if (o->oargs.nfargs != (iscyl ? 7 : 8))
218     objerror(o, "bad # real arguments");
219     if (o->oargs.farg[6] < -FTINY) {
220     o->oargs.farg[6] = -o->oargs.farg[6];
221     if (iscyl)
222     o->otype = o->otype==OBJ_CYLINDER ?
223     OBJ_TUBE : OBJ_CYLINDER;
224     else {
225     if ((o->oargs.farg[7] = -o->oargs.farg[7]) < -FTINY)
226     objerror(o, USER, "illegal radii");
227     o->otype = o->otype==OBJ_CONE ? OBJ_CUP : OBJ_CONE;
228     }
229     } else if (!iscyl && o->oargs.farg[7] < -FTINY)
230     objerror(o, USER, "illegal radii");
231     if (o->oargs.farg[6] <= FTINY && (iscyl || o->oargs.farg[7] <= FTINY))
232     return;
233     if (o->oargs.farg[6] < 0.) /* complains for tiny neg's */
234     o->oargs.farg[6] = 0.;
235     if (!iscyl && o->oargs.farg[7] < 0.)
236     o->oargs.farg[7] = 0.;
237     cent[0] = .5*(o->oargs.farg[0] + o->oargs.farg[3]);
238     cent[1] = .5*(o->oargs.farg[1] + o->oargs.farg[4]);
239     cent[2] = .5*(o->oargs.farg[2] + o->oargs.farg[5]);
240     setmaterial(o->os, cent, 0);
241     if (gluqo == NULL) newquadric();
242     glu_rout = "making cylinder";
243     gluQuadricOrientation(gluqo, o->otype==OBJ_CUP | o->otype==OBJ_TUBE ?
244     GLU_INSIDE : GLU_OUTSIDE);
245     gluQuadricNormals(gluqo, GLU_SMOOTH);
246     glMatrixMode(GL_MODELVIEW);
247     glPushMatrix();
248     /* do base translation */
249     glTranslated((GLdouble)o->oargs.farg[0], (GLdouble)o->oargs.farg[1],
250     (GLdouble)o->oargs.farg[2]);
251     /* compute height & rotation angle */
252     h = sqrt(dist2(o->oargs.farg,o->oargs.farg+3));
253     if (h <= FTINY)
254     return;
255     x1 = o->oargs.farg[1] - o->oargs.farg[4];
256     y1 = o->oargs.farg[3] - o->oargs.farg[0];
257     /* z1 = 0; */
258     d = 180./PI * asin(sqrt(x1*x1 + y1*y1) / h);
259     if (o->oargs.farg[5] < o->oargs.farg[2])
260     d = 180. - d;
261     if (d > FTINY)
262     glRotated(d, (GLdouble)x1, (GLdouble)y1, 0.);
263     gluCylinder(gluqo, o->oargs.farg[6], o->oargs.farg[iscyl ? 6 : 7],
264     h, NSLICES, 1);
265     glPopMatrix();
266     rgl_checkerr("creating cone");
267     }
268    
269    
270     o_ring(o) /* convert a ring */
271     register OBJREC *o;
272     {
273     double x1, y1, d;
274    
275     if (o->oargs.nfargs != 8)
276     objerror(o, "bad # real arguments");
277     if (o->oargs.farg[7] < o->oargs.farg[6]) {
278     register double d = o->oargs.farg[7];
279     o->oargs.farg[7] = o->oargs.farg[6];
280     o->oargs.farg[6] = d;
281     }
282     if (o->oargs.farg[6] < -FTINY)
283     objerror(o, USER, "negative radius");
284     if (o->oargs.farg[6] < 0.) /* complains for tiny neg's */
285     o->oargs.farg[6] = 0.;
286     if (o->oargs.farg[7] - o->oargs.farg[6] <= FTINY)
287     return;
288     if (dolights)
289     doflatsrc(o->os, o->oargs.farg, o->oargs.farg+3,
290     PI*(o->oargs.farg[7]*o->oargs.farg[7] -
291     o->oargs.farg[6]*o->oargs.farg[6]));
292     setmaterial(o->os, o->oargs.farg, 0);
293     if (gluqo == NULL) newquadric();
294     glu_rout = "making disk";
295     gluQuadricOrientation(gluqo, GLU_OUTSIDE);
296     gluQuadricNormals(gluqo, GLU_FLAT);
297     glMatrixMode(GL_MODELVIEW);
298     glPushMatrix();
299     glTranslated((GLdouble)o->oargs.farg[0], (GLdouble)o->oargs.farg[1],
300     (GLdouble)o->oargs.farg[2]);
301     /* compute rotation angle */
302     d = VLEN(o->oargs.farg+3);
303     if (d <= FTINY)
304     return;
305     x1 = -o->oargs.farg[4];
306     y1 = o->oargs.farg[3];
307     /* z1 = 0; */
308     d = 180./PI * asin(sqrt(x1*x1 + y1*y1) / d);
309     if (o->oargs.farg[5] < 0.)
310     d = 180. - d;
311     if (d > FTINY)
312     glRotated(d, (GLdouble)x1, (GLdouble)y1, 0.);
313     gluDisk(gluqo, o->oargs.farg[6], o->oargs.farg[7], NSLICES, 1);
314     glPopMatrix();
315     rgl_checkerr("creating ring");
316     }