ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/common/rglinst.c
Revision: 3.15
Committed: Tue May 25 22:04:13 2004 UTC (19 years, 11 months ago) by greg
Content type: text/plain
Branch: MAIN
CVS Tags: rad3R7P2, rad3R7P1, rad4R0, rad3R6, rad3R6P1, rad3R8, rad3R9
Changes since 3.14: +2 -2 lines
Log Message:
Added const modifier to key and other parameters in lookup.h

File Contents

# User Rev Content
1 gwlarson 3.1 #ifndef lint
2 greg 3.15 static const char RCSid[] = "$Id: rglinst.c,v 3.14 2004/05/25 06:30:46 greg 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 greg 3.14 buildoctlist(lp, p) /* build octree list */
93 greg 3.15 const LUENT *lp;
94 greg 3.14 void *p;
95 gwlarson 3.1 {
96     int old_dolights = dolights, old_domats = domats;
97     register OCTINST *op = (OCTINST *)lp->data;
98    
99     domats = !op->localmatl; /* do materials only if needed */
100     dolights = 0; /* never do light sources */
101     glNewList(op->listid, GL_COMPILE);
102     loadoct(op->octfile); /* load objects into display list */
103     surfclean(); /* clean up */
104     glEndList();
105     dolights = old_dolights; /* restore */
106     domats = old_domats;
107     return(1); /* return success */
108     }
109    
110    
111     int
112     loadoctrees() /* load octrees we've saved up */
113     {
114 gwlarson 3.2 int levelsleft = MAXLEVEL;
115 gwlarson 3.1 int nocts = 0;
116     LUTAB looptab;
117     /* loop through new octree references */
118     while (ottab.tsiz) {
119 gwlarson 3.2 if (!levelsleft--)
120     error(USER, "too many octree levels -- instance loop?");
121 schorsch 3.12 looptab = ottab;
122 gwlarson 3.1 ottab.tsiz = 0;
123 greg 3.14 nocts += lu_doall(&looptab, buildoctlist, NULL);
124 gwlarson 3.1 lu_done(&looptab);
125     }
126     return(nocts);
127     }
128    
129    
130     static OCTINST *
131     getoct(name) /* get/assign octree list id */
132     char *name;
133     {
134     char *path;
135     register LUENT *lp;
136     register OCTINST *op;
137    
138     if ((lp = lu_find(&ottab, name)) == NULL)
139     goto memerr;
140     if (lp->key == NULL) {
141     lp->key = (char *)malloc(strlen(name)+1);
142     if (lp->key == NULL)
143     goto memerr;
144     strcpy(lp->key, name);
145     }
146     if ((op = (OCTINST *)lp->data) == NULL) {
147 greg 3.8 path = getpath(name, getrlibpath(), R_OK);
148 gwlarson 3.1 if (path == NULL) {
149     sprintf(errmsg, "cannot find octree \"%s\"", name);
150     error(USER, errmsg);
151     }
152     op = (OCTINST *)(lp->data = (char *)malloc(sizeof(OCTINST)));
153     strcpy(op->octfile, path);
154     checkoct(op->octfile, op->cent);
155     op->listid = newglist();
156     op->localmatl = ~0;
157     }
158     return(op);
159     memerr:
160     error(SYSTEM, "out of memory in getoct");
161 schorsch 3.13 return NULL; /* pro forma return */
162 gwlarson 3.1 }
163    
164    
165     double
166     checkoct(fname, cent) /* check octree file for validity */
167     char *fname;
168     FVECT cent;
169     {
170     char sbuf[64];
171     FILE *fp = infp;
172     char *fn = infn;
173     double siz = 0.;
174     register int i;
175    
176     if ((infp = fopen(infn=fname, "r")) == NULL) {
177     sprintf(errmsg, "cannot open octree file \"%s\"", fname);
178     error(SYSTEM, errmsg);
179     }
180 schorsch 3.9 SET_FILE_BINARY(infp);
181 gwlarson 3.1 /* get header */
182     if (checkheader(infp, OCTFMT, NULL) < 0)
183     octerror(USER, "not an octree");
184     /* check format */
185     if ((objsize = ogetint(2)-OCTMAGIC) <= 0 ||
186     objsize > MAXOBJSIZ || objsize > sizeof(long))
187 schorsch 3.11 octerror(USER, "incompatible octree format");
188 gwlarson 3.1 if (cent != NULL) { /* get boundaries (compute center) */
189     for (i = 0; i < 3; i++)
190     cent[i] = atof(ogetstr(sbuf));
191     siz = atof(ogetstr(sbuf))*.5;
192     cent[0] += siz; cent[1] += siz; cent[2] += siz;
193     } else { /* get size (radius) only */
194     for (i = 0; i < 3; i++)
195     ogetstr(sbuf);
196     siz = atof(ogetstr(sbuf))*.5;
197     }
198     fclose(infp);
199     infp = fp;
200     infn = fn;
201     return(siz);
202     }
203    
204    
205 greg 3.5 int
206 gwlarson 3.1 loadoct(fname) /* read in objects from octree */
207     char *fname;
208     {
209     OBJECT fnobjects;
210     char sbuf[256];
211     int nf;
212     register int i;
213     long m;
214    
215     infn = fname;
216     infp = fopen(fname, "r"); /* assume already checked */
217 schorsch 3.9 SET_FILE_BINARY(infp);
218 gwlarson 3.1 /* skip header */
219     getheader(infp, NULL, NULL);
220     /* get format */
221     objsize = ogetint(2)-OCTMAGIC;
222     /* skip boundaries */
223     for (i = 0; i < 4; i++)
224     ogetstr(sbuf);
225     nf = 0; /* load object files */
226     while (*ogetstr(sbuf)) {
227     rgl_load(sbuf);
228     nf++;
229     }
230     /* get number of objects */
231     fnobjects = m = ogetint(objsize);
232     if (fnobjects != m)
233     octerror(USER, "too many objects");
234    
235     if (nf == 0) {
236     skiptree();
237     for (i = 0; *ogetstr(sbuf); i++)
238     if ((otypmap[i] = otype(sbuf)) < 0) {
239     sprintf(errmsg, "unknown type \"%s\"", sbuf);
240     octerror(WARNING, errmsg);
241     }
242     lu_init(&imtab, 1000); nobjects = 0;
243     while (loadobj() != OVOID)
244     ;
245     lu_done(&imtab);
246     if (nobjects != fnobjects)
247     octerror(USER, "inconsistent object count");
248     }
249     fclose(infp);
250     return(nf);
251     }
252    
253    
254     static char *
255     ogetstr(s) /* get null-terminated string */
256     char *s;
257     {
258     extern char *getstr();
259    
260     if (getstr(s, infp) == NULL)
261     octerror(USER, "truncated octree");
262     return(s);
263     }
264    
265    
266     static long
267     ogetint(siz) /* get a siz-byte integer */
268     int siz;
269     {
270     extern long getint();
271     register long r;
272    
273     r = getint(siz, infp);
274     if (feof(infp))
275     octerror(USER, "truncated octree");
276     return(r);
277     }
278    
279    
280     static double
281     ogetflt() /* get a floating point number */
282     {
283     extern double getflt();
284     double r;
285    
286     r = getflt(infp);
287     if (feof(infp))
288     octerror(USER, "truncated octree");
289     return(r);
290     }
291    
292    
293 greg 3.5 static void
294 gwlarson 3.1 skiptree() /* skip octree on input */
295     {
296     register int i;
297    
298     switch (getc(infp)) {
299     case OT_EMPTY:
300     return;
301     case OT_FULL:
302     for (i = ogetint(objsize)*objsize; i-- > 0; )
303     if (getc(infp) == EOF)
304     octerror(USER, "truncated octree");
305     return;
306     case OT_TREE:
307     for (i = 0; i < 8; i++)
308     skiptree();
309     return;
310     case EOF:
311     octerror(USER, "truncated octree");
312     default:
313     octerror(USER, "damaged octree");
314     }
315     }
316    
317    
318 greg 3.5 static int
319 gwlarson 3.1 loadobj() /* get next object */
320     {
321     static OBJREC ob;
322     char idbuf[MAXSTR], sbuf[MAXSTR];
323     register LUENT *lep;
324     register int i;
325     register long m;
326     /* get type */
327     i = ogetint(1);
328     if (i == -1)
329     return(OVOID); /* terminator */
330     if ((ob.otype = otypmap[i]) < 0)
331     octerror(USER, "reference to unknown type");
332     /* get modifier */
333     if ((m = ogetint(objsize)) != OVOID && (OBJECT)m != m)
334     octerror(USER, "too many objects");
335     if ((ob.omod = m) != OVOID && domats) {
336     if ((lep = lu_find(&imtab, (char *)m)) == NULL)
337     goto memerr;
338     ob.os = lep->data;
339     } else
340     ob.os = NULL;
341     /* get name id */
342     ob.oname = ogetstr(idbuf);
343     /* get string arguments */
344 schorsch 3.13 if ((ob.oargs.nsargs = ogetint(2))) {
345 gwlarson 3.1 ob.oargs.sarg = (char **)malloc
346     (ob.oargs.nsargs*sizeof(char *));
347     if (ob.oargs.sarg == NULL)
348     goto memerr;
349     for (i = 0; i < ob.oargs.nsargs; i++)
350     ob.oargs.sarg[i] = savestr(ogetstr(sbuf));
351     } else
352     ob.oargs.sarg = NULL;
353     /* get integer arguments */
354     #ifdef IARGS
355     if (ob.oargs.niargs = ogetint(2)) {
356     ob.oargs.iarg = (long *)malloc
357     (ob.oargs.niargs*sizeof(long));
358     if (ob.oargs.iarg == NULL)
359     goto memerr;
360     for (i = 0; i < ob.oargs.niargs; i++)
361     ob.oargs.iarg[i] = ogetint(4);
362     } else
363     ob.oargs.iarg = NULL;
364     #endif
365     /* get real arguments */
366 schorsch 3.13 if ((ob.oargs.nfargs = ogetint(2))) {
367 schorsch 3.10 ob.oargs.farg = (RREAL *)malloc
368     (ob.oargs.nfargs*sizeof(RREAL));
369 gwlarson 3.1 if (ob.oargs.farg == NULL)
370     goto memerr;
371     for (i = 0; i < ob.oargs.nfargs; i++)
372     ob.oargs.farg[i] = ogetflt();
373     } else
374     ob.oargs.farg = NULL;
375     /* process object */
376     (*ofun[ob.otype].funp)(&ob);
377     /* record material if modifier */
378     if (ismodifier(ob.otype)) {
379     if ((lep = lu_find(&imtab, (char *)nobjects)) == NULL)
380     goto memerr;
381     lep->key = (char *)nobjects;
382     lep->data = (char *)getmatp(ob.oname);
383     }
384     freefargs(&ob.oargs); /* free arguments */
385     return(nobjects++); /* return object id */
386     memerr:
387     error(SYSTEM, "out of memory in loadobj");
388 schorsch 3.13 return OVOID; /* pro forma return */
389 gwlarson 3.1 }
390    
391    
392 greg 3.5 static void
393 gwlarson 3.1 octerror(etyp, msg) /* octree error */
394     int etyp;
395     char *msg;
396     {
397     char msgbuf[128];
398    
399     sprintf(msgbuf, "(%s): %s", infn, msg);
400     error(etyp, msgbuf);
401     }