ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/common/rglinst.c
Revision: 3.12
Committed: Mon Jul 21 22:30:17 2003 UTC (20 years, 9 months ago) by schorsch
Content type: text/plain
Branch: MAIN
Changes since 3.11: +2 -2 lines
Log Message:
Eliminated copystruct() macro, which is unnecessary in ANSI.
Reduced ambiguity warnings for nested if/if/else clauses.

File Contents

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