ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/common/rglinst.c
Revision: 3.10
Committed: Thu Jun 26 00:58:09 2003 UTC (20 years, 10 months ago) by schorsch
Content type: text/plain
Branch: MAIN
Changes since 3.9: +3 -3 lines
Log Message:
Abstracted process and path handling for Windows.
Renamed FLOAT to RREAL because of conflict on Windows.
Added conditional compiles for some signal handlers.

File Contents

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