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

# Content
1 #ifndef lint
2 static const char RCSid[] = "$Id: rglinst.c,v 3.12 2003/07/21 22:30:17 schorsch Exp $";
3 #endif
4 /*
5 * Routines for reading instances and converting to OpenGL.
6 */
7
8 #include "copyright.h"
9
10 #include <stdio.h>
11 #include <string.h>
12 #include <time.h>
13
14 #include "platform.h"
15 #include "paths.h"
16 #include "resolu.h"
17 #include "radogl.h"
18 #include "octree.h"
19
20 #define MAXLEVEL 16 /* maximum instance hierarchy level */
21
22 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 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
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 static unsigned long imhash(mod) char *mod; {return((unsigned long)mod);}
43 static LUTAB imtab = {imhash,NULL,NULL,NULL,0,NULL,0};
44
45 static LUTAB ottab = LU_SINIT(free,free);
46
47
48 int
49 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 if ((xfs.sca < 1.-FTINY) | (xfs.sca > 1.+FTINY))
65 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 setmaterial((MATREC *)o->os, ot->cent, 0);
78 /* call the assigned list */
79 glCallList(ot->listid);
80
81 if (o->oargs.nsargs > 1) { /* end transform */
82 glMatrixMode(GL_MODELVIEW);
83 glPopMatrix();
84 glPopAttrib();
85 }
86 rgl_checkerr("creating instance");
87 return(0);
88 }
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 int levelsleft = MAXLEVEL;
114 int nocts = 0;
115 LUTAB looptab;
116 /* loop through new octree references */
117 while (ottab.tsiz) {
118 if (!levelsleft--)
119 error(USER, "too many octree levels -- instance loop?");
120 looptab = ottab;
121 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 path = getpath(name, getrlibpath(), R_OK);
147 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 return NULL; /* pro forma return */
161 }
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 SET_FILE_BINARY(infp);
180 /* 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 octerror(USER, "incompatible octree format");
187 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 int
205 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 SET_FILE_BINARY(infp);
217 /* 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 static void
293 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 static int
318 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 if ((ob.oargs.nsargs = ogetint(2))) {
344 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 if ((ob.oargs.nfargs = ogetint(2))) {
366 ob.oargs.farg = (RREAL *)malloc
367 (ob.oargs.nfargs*sizeof(RREAL));
368 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 return OVOID; /* pro forma return */
388 }
389
390
391 static void
392 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 }