ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/common/rglinst.c
Revision: 3.1
Committed: Tue Jun 9 11:18:35 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     * Routines for reading instances and converting to OpenGL.
9     */
10    
11     #include "radogl.h"
12     #include "octree.h"
13    
14     typedef struct {
15     int listid; /* our list id */
16     short localmatl; /* uses local material only */
17     FVECT cent; /* center of octree cube */
18     char octfile[256]; /* octree file path */
19     } OCTINST; /* octree to instantiate */
20    
21     OBJECT nobjects; /* number of objects loaded so far */
22    
23     extern int free();
24    
25     static double ogetflt();
26     static long ogetint();
27     static char *ogetstr();
28     static int loadobj(), octerror(), skiptree();
29     static OCTINST *getoct();
30    
31     static char *infn; /* input file name */
32     static FILE *infp; /* input file stream */
33     static int objsize; /* size of stored OBJECT's */
34     static short otypmap[NUMOTYPE+8]; /* object type map */
35    
36     static long imhash(mod) char *mod; {return((long)mod);}
37     static LUTAB imtab = {imhash,NULL,NULL,NULL,0,NULL,0};
38    
39     static LUTAB ottab = LU_SINIT(free,free);
40    
41    
42     o_instance(o) /* convert instance to list call */
43     register OBJREC *o;
44     {
45     XF xfs;
46     register OCTINST *ot;
47     /* set up */
48     if (o->oargs.nsargs < 1)
49     objerror(o, USER, "missing octree");
50     setmaterial(NULL, NULL, 0);
51     /* put out transform (if any) */
52     if (o->oargs.nsargs > 1) {
53     if (xf(&xfs, o->oargs.nsargs-1, o->oargs.sarg+1) !=
54     o->oargs.nsargs-1)
55     objerror(o, USER, "bad transform");
56     glPushAttrib(GL_TRANSFORM_BIT);
57     if (xfs.sca < 1.-FTINY | xfs.sca > 1.+FTINY)
58     glEnable(GL_NORMALIZE);
59     glMatrixMode(GL_MODELVIEW);
60     glPushMatrix();
61     /* matrix order works out to same */
62     #ifdef SMLFLT
63     glMultMatrixf((GLfloat *)xfs.xfm);
64     #else
65     glMultMatrixd((GLdouble *)xfs.xfm);
66     #endif
67     }
68     ot = getoct(o->oargs.sarg[0]); /* get octree reference */
69     if (ot->localmatl &= o->os != NULL) /* set material */
70     setmaterial(o->os, ot->cent, 0);
71     /* call the assigned list */
72     glCallList(ot->listid);
73    
74     if (o->oargs.nsargs > 1) { /* end transform */
75     glPopMatrix();
76     glPopAttrib();
77     }
78     rgl_checkerr("creating instance");
79     }
80    
81    
82     static int
83     buildoctlist(lp) /* build octree list */
84     LUENT *lp;
85     {
86     int old_dolights = dolights, old_domats = domats;
87     register OCTINST *op = (OCTINST *)lp->data;
88    
89     domats = !op->localmatl; /* do materials only if needed */
90     dolights = 0; /* never do light sources */
91     glNewList(op->listid, GL_COMPILE);
92     loadoct(op->octfile); /* load objects into display list */
93     surfclean(); /* clean up */
94     glEndList();
95     dolights = old_dolights; /* restore */
96     domats = old_domats;
97     return(1); /* return success */
98     }
99    
100    
101     int
102     loadoctrees() /* load octrees we've saved up */
103     {
104     int nocts = 0;
105     LUTAB looptab;
106     /* loop through new octree references */
107     while (ottab.tsiz) {
108     copystruct(&looptab, &ottab);
109     ottab.tsiz = 0;
110     nocts += lu_doall(&looptab, buildoctlist);
111     lu_done(&looptab);
112     }
113     return(nocts);
114     }
115    
116    
117     static OCTINST *
118     getoct(name) /* get/assign octree list id */
119     char *name;
120     {
121     extern char *getpath(), *getlibpath();
122     char *path;
123     register LUENT *lp;
124     register OCTINST *op;
125    
126     if ((lp = lu_find(&ottab, name)) == NULL)
127     goto memerr;
128     if (lp->key == NULL) {
129     lp->key = (char *)malloc(strlen(name)+1);
130     if (lp->key == NULL)
131     goto memerr;
132     strcpy(lp->key, name);
133     }
134     if ((op = (OCTINST *)lp->data) == NULL) {
135     path = getpath(name, getlibpath(), R_OK);
136     if (path == NULL) {
137     sprintf(errmsg, "cannot find octree \"%s\"", name);
138     error(USER, errmsg);
139     }
140     op = (OCTINST *)(lp->data = (char *)malloc(sizeof(OCTINST)));
141     strcpy(op->octfile, path);
142     checkoct(op->octfile, op->cent);
143     op->listid = newglist();
144     op->localmatl = ~0;
145     }
146     return(op);
147     memerr:
148     error(SYSTEM, "out of memory in getoct");
149     }
150    
151    
152     double
153     checkoct(fname, cent) /* check octree file for validity */
154     char *fname;
155     FVECT cent;
156     {
157     char sbuf[64];
158     FILE *fp = infp;
159     char *fn = infn;
160     double siz = 0.;
161     register int i;
162    
163     if ((infp = fopen(infn=fname, "r")) == NULL) {
164     sprintf(errmsg, "cannot open octree file \"%s\"", fname);
165     error(SYSTEM, errmsg);
166     }
167     #ifdef MSDOS
168     setmode(fileno(infp), O_BINARY);
169     #endif
170     /* get header */
171     if (checkheader(infp, OCTFMT, NULL) < 0)
172     octerror(USER, "not an octree");
173     /* check format */
174     if ((objsize = ogetint(2)-OCTMAGIC) <= 0 ||
175     objsize > MAXOBJSIZ || objsize > sizeof(long))
176     octerror("incompatible octree format");
177     if (cent != NULL) { /* get boundaries (compute center) */
178     for (i = 0; i < 3; i++)
179     cent[i] = atof(ogetstr(sbuf));
180     siz = atof(ogetstr(sbuf))*.5;
181     cent[0] += siz; cent[1] += siz; cent[2] += siz;
182     } else { /* get size (radius) only */
183     for (i = 0; i < 3; i++)
184     ogetstr(sbuf);
185     siz = atof(ogetstr(sbuf))*.5;
186     }
187     fclose(infp);
188     infp = fp;
189     infn = fn;
190     return(siz);
191     }
192    
193    
194     loadoct(fname) /* read in objects from octree */
195     char *fname;
196     {
197     OBJECT fnobjects;
198     char sbuf[256];
199     int nf;
200     register int i;
201     long m;
202    
203     infn = fname;
204     infp = fopen(fname, "r"); /* assume already checked */
205     #ifdef MSDOS
206     setmode(fileno(infp), O_BINARY);
207     #endif
208     /* skip header */
209     getheader(infp, NULL, NULL);
210     /* get format */
211     objsize = ogetint(2)-OCTMAGIC;
212     /* skip boundaries */
213     for (i = 0; i < 4; i++)
214     ogetstr(sbuf);
215     nf = 0; /* load object files */
216     while (*ogetstr(sbuf)) {
217     rgl_load(sbuf);
218     nf++;
219     }
220     /* get number of objects */
221     fnobjects = m = ogetint(objsize);
222     if (fnobjects != m)
223     octerror(USER, "too many objects");
224    
225     if (nf == 0) {
226     skiptree();
227     for (i = 0; *ogetstr(sbuf); i++)
228     if ((otypmap[i] = otype(sbuf)) < 0) {
229     sprintf(errmsg, "unknown type \"%s\"", sbuf);
230     octerror(WARNING, errmsg);
231     }
232     lu_init(&imtab, 1000); nobjects = 0;
233     while (loadobj() != OVOID)
234     ;
235     lu_done(&imtab);
236     if (nobjects != fnobjects)
237     octerror(USER, "inconsistent object count");
238     }
239     fclose(infp);
240     return(nf);
241     }
242    
243    
244     static char *
245     ogetstr(s) /* get null-terminated string */
246     char *s;
247     {
248     extern char *getstr();
249    
250     if (getstr(s, infp) == NULL)
251     octerror(USER, "truncated octree");
252     return(s);
253     }
254    
255    
256     static long
257     ogetint(siz) /* get a siz-byte integer */
258     int siz;
259     {
260     extern long getint();
261     register long r;
262    
263     r = getint(siz, infp);
264     if (feof(infp))
265     octerror(USER, "truncated octree");
266     return(r);
267     }
268    
269    
270     static double
271     ogetflt() /* get a floating point number */
272     {
273     extern double getflt();
274     double r;
275    
276     r = getflt(infp);
277     if (feof(infp))
278     octerror(USER, "truncated octree");
279     return(r);
280     }
281    
282    
283     static
284     skiptree() /* skip octree on input */
285     {
286     register int i;
287    
288     switch (getc(infp)) {
289     case OT_EMPTY:
290     return;
291     case OT_FULL:
292     for (i = ogetint(objsize)*objsize; i-- > 0; )
293     if (getc(infp) == EOF)
294     octerror(USER, "truncated octree");
295     return;
296     case OT_TREE:
297     for (i = 0; i < 8; i++)
298     skiptree();
299     return;
300     case EOF:
301     octerror(USER, "truncated octree");
302     default:
303     octerror(USER, "damaged octree");
304     }
305     }
306    
307    
308     static
309     loadobj() /* get next object */
310     {
311     static OBJREC ob;
312     char idbuf[MAXSTR], sbuf[MAXSTR];
313     register LUENT *lep;
314     register int i;
315     register long m;
316     /* get type */
317     i = ogetint(1);
318     if (i == -1)
319     return(OVOID); /* terminator */
320     if ((ob.otype = otypmap[i]) < 0)
321     octerror(USER, "reference to unknown type");
322     /* get modifier */
323     if ((m = ogetint(objsize)) != OVOID && (OBJECT)m != m)
324     octerror(USER, "too many objects");
325     if ((ob.omod = m) != OVOID && domats) {
326     if ((lep = lu_find(&imtab, (char *)m)) == NULL)
327     goto memerr;
328     ob.os = lep->data;
329     } else
330     ob.os = NULL;
331     /* get name id */
332     ob.oname = ogetstr(idbuf);
333     /* get string arguments */
334     if (ob.oargs.nsargs = ogetint(2)) {
335     ob.oargs.sarg = (char **)malloc
336     (ob.oargs.nsargs*sizeof(char *));
337     if (ob.oargs.sarg == NULL)
338     goto memerr;
339     for (i = 0; i < ob.oargs.nsargs; i++)
340     ob.oargs.sarg[i] = savestr(ogetstr(sbuf));
341     } else
342     ob.oargs.sarg = NULL;
343     /* get integer arguments */
344     #ifdef IARGS
345     if (ob.oargs.niargs = ogetint(2)) {
346     ob.oargs.iarg = (long *)malloc
347     (ob.oargs.niargs*sizeof(long));
348     if (ob.oargs.iarg == NULL)
349     goto memerr;
350     for (i = 0; i < ob.oargs.niargs; i++)
351     ob.oargs.iarg[i] = ogetint(4);
352     } else
353     ob.oargs.iarg = NULL;
354     #endif
355     /* get real arguments */
356     if (ob.oargs.nfargs = ogetint(2)) {
357     ob.oargs.farg = (FLOAT *)malloc
358     (ob.oargs.nfargs*sizeof(FLOAT));
359     if (ob.oargs.farg == NULL)
360     goto memerr;
361     for (i = 0; i < ob.oargs.nfargs; i++)
362     ob.oargs.farg[i] = ogetflt();
363     } else
364     ob.oargs.farg = NULL;
365     /* process object */
366     (*ofun[ob.otype].funp)(&ob);
367     /* record material if modifier */
368     if (ismodifier(ob.otype)) {
369     if ((lep = lu_find(&imtab, (char *)nobjects)) == NULL)
370     goto memerr;
371     lep->key = (char *)nobjects;
372     lep->data = (char *)getmatp(ob.oname);
373     }
374     freefargs(&ob.oargs); /* free arguments */
375     return(nobjects++); /* return object id */
376     memerr:
377     error(SYSTEM, "out of memory in loadobj");
378     }
379    
380    
381     static
382     octerror(etyp, msg) /* octree error */
383     int etyp;
384     char *msg;
385     {
386     char msgbuf[128];
387    
388     sprintf(msgbuf, "(%s): %s", infn, msg);
389     error(etyp, msgbuf);
390     }