ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/common/rglinst.c
Revision: 3.13
Committed: Fri Nov 14 17:22:06 2003 UTC (20 years, 5 months ago) by schorsch
Content type: text/plain
Branch: MAIN
Changes since 3.12: +7 -4 lines
Log Message:
Reduced compile warnings, and other compatibility fixes.

File Contents

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