ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/common/rglinst.c
Revision: 3.11
Committed: Sat Jul 12 09:55:13 2003 UTC (20 years, 9 months ago) by schorsch
Content type: text/plain
Branch: MAIN
Changes since 3.10: +15 -10 lines
Log Message:
Fixed incorrect octerror() call found by Randolph Fritz.
Added prototypes and all necessary includes.

File Contents

# Content
1 #ifndef lint
2 static const char RCSid[] = "$Id: rglinst.c,v 3.10 2003/06/26 00:58:09 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 "resolu.h"
16 #include "radogl.h"
17 #include "octree.h"
18
19 #define MAXLEVEL 16 /* maximum instance hierarchy level */
20
21 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 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
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 static unsigned long imhash(mod) char *mod; {return((unsigned long)mod);}
42 static LUTAB imtab = {imhash,NULL,NULL,NULL,0,NULL,0};
43
44 static LUTAB ottab = LU_SINIT(free,free);
45
46
47 int
48 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 setmaterial((MATREC *)o->os, ot->cent, 0);
77 /* call the assigned list */
78 glCallList(ot->listid);
79
80 if (o->oargs.nsargs > 1) { /* end transform */
81 glMatrixMode(GL_MODELVIEW);
82 glPopMatrix();
83 glPopAttrib();
84 }
85 rgl_checkerr("creating instance");
86 return(0);
87 }
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 int levelsleft = MAXLEVEL;
113 int nocts = 0;
114 LUTAB looptab;
115 /* loop through new octree references */
116 while (ottab.tsiz) {
117 if (!levelsleft--)
118 error(USER, "too many octree levels -- instance loop?");
119 copystruct(&looptab, &ottab);
120 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 path = getpath(name, getrlibpath(), R_OK);
146 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 SET_FILE_BINARY(infp);
178 /* 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 octerror(USER, "incompatible octree format");
185 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 int
203 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 SET_FILE_BINARY(infp);
215 /* 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 static void
291 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 static int
316 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 ob.oargs.farg = (RREAL *)malloc
365 (ob.oargs.nfargs*sizeof(RREAL));
366 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 static void
389 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 }