ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/hd/rhdisp2.c
Revision: 3.29
Committed: Fri Dec 18 11:56:10 1998 UTC (25 years, 4 months ago) by gwlarson
Content type: text/plain
Branch: MAIN
Changes since 3.28: +21 -10 lines
Log Message:
created new ogl driver with direct geometry rendering

File Contents

# User Rev Content
1 gregl 3.17 /* Copyright (c) 1998 Silicon Graphics, Inc. */
2 gregl 3.1
3     #ifndef lint
4     static char SCCSid[] = "$SunId$ SGI";
5     #endif
6    
7     /*
8 gregl 3.2 * Holodeck beam tracking for display process
9 gregl 3.1 */
10    
11     #include "rholo.h"
12     #include "rhdisp.h"
13     #include "rhdriver.h"
14 gwlarson 3.25 #include "random.h"
15 gregl 3.1
16 gregl 3.9 #ifndef MAXDIST
17 gregl 3.14 #define MAXDIST 42 /* maximum distance outside section */
18 gregl 3.9 #endif
19 gwlarson 3.25 #ifndef NVSAMPS
20 gwlarson 3.28 #define NVSAMPS 16384 /* number of ray samples per view */
21 gwlarson 3.25 #endif
22 gwlarson 3.26 #ifndef MEYERNG
23 gwlarson 3.28 #define MEYERNG 0.1 /* target mean eye range (rel. to grid) */
24 gwlarson 3.26 #endif
25     #ifndef MAXTODO
26 gwlarson 3.25 #define MAXTODO 3 /* maximum sections to look at */
27 gwlarson 3.26 #endif
28     #ifndef MAXDRAT
29     #define MAXDRAT 3.0 /* maximum distance ratio btwn. cand. sect. */
30     #endif
31 gwlarson 3.20
32 gregl 3.1 #define CBEAMBLK 1024 /* cbeam allocation block size */
33    
34     static struct beamcomp {
35 gwlarson 3.22 int hd; /* holodeck section number */
36 gwlarson 3.24 int bi; /* beam index */
37 gwlarson 3.21 int4 nr; /* number of samples desired */
38 gregl 3.1 } *cbeam = NULL; /* current beam list */
39    
40 gwlarson 3.26 VIEWPOINT cureye; /* current eye position */
41    
42 gregl 3.1 static int ncbeams = 0; /* number of sorted beams in cbeam */
43     static int xcbeams = 0; /* extra (unregistered) beams past ncbeams */
44     static int maxcbeam = 0; /* size of cbeam array */
45    
46    
47     int
48     newcbeam() /* allocate new entry at end of cbeam array */
49     {
50     int i;
51    
52     if ((i = ncbeams + xcbeams++) >= maxcbeam) { /* grow array */
53     maxcbeam += CBEAMBLK;
54     if (cbeam == NULL)
55     cbeam = (struct beamcomp *)malloc(
56     maxcbeam*sizeof(struct beamcomp) );
57     else
58     cbeam = (struct beamcomp *)realloc( (char *)cbeam,
59     maxcbeam*sizeof(struct beamcomp) );
60     if (cbeam == NULL)
61     error(SYSTEM, "out of memory in newcbeam");
62     }
63     return(i);
64     }
65    
66    
67     int
68     cbeamcmp(cb1, cb2) /* compare two cbeam entries for sort: keep orphans */
69     register struct beamcomp *cb1, *cb2;
70     {
71     register int c;
72    
73     if ((c = cb1->bi - cb2->bi)) /* sort on beam index first */
74     return(c);
75     return(cb1->hd - cb2->hd); /* use hd to resolve matches */
76     }
77    
78    
79     int
80     cbeamcmp2(cb1, cb2) /* compare two cbeam entries for sort: no orphans */
81     register struct beamcomp *cb1, *cb2;
82     {
83     register int c;
84    
85 gwlarson 3.22 if (!cb1->nr) /* put orphans at the end, unsorted */
86     return(cb2->nr);
87     if (!cb2->nr)
88 gregl 3.15 return(-1);
89 gregl 3.1 if ((c = cb1->bi - cb2->bi)) /* sort on beam index first */
90     return(c);
91     return(cb1->hd - cb2->hd); /* use hd to resolve matches */
92     }
93    
94    
95     int
96     findcbeam(hd, bi) /* find the specified beam in our sorted list */
97     int hd, bi;
98     {
99     struct beamcomp cb;
100     register struct beamcomp *p;
101    
102     if (ncbeams <= 0)
103     return(-1);
104 gwlarson 3.22 cb.hd = hd; cb.bi = bi; cb.nr = 0;
105 gregl 3.1 p = (struct beamcomp *)bsearch((char *)&cb, (char *)cbeam, ncbeams,
106     sizeof(struct beamcomp), cbeamcmp);
107     if (p == NULL)
108     return(-1);
109     return(p - cbeam);
110     }
111    
112    
113     int
114     getcbeam(hd, bi) /* get the specified beam, allocating as necessary */
115     register int hd;
116     int bi;
117     {
118     register int n;
119     /* first, look in sorted list */
120     if ((n = findcbeam(hd, bi)) >= 0)
121     return(n);
122     /* linear search through xcbeams to be sure */
123     for (n = ncbeams+xcbeams; n-- > ncbeams; )
124     if (cbeam[n].bi == bi && cbeam[n].hd == hd)
125     return(n);
126     /* check legality */
127     if (hd < 0 | hd >= HDMAX || hdlist[hd] == NULL)
128     error(INTERNAL, "illegal holodeck number in getcbeam");
129     if (bi < 1 | bi > nbeams(hdlist[hd]))
130     error(INTERNAL, "illegal beam index in getcbeam");
131     n = newcbeam(); /* allocate and assign */
132 gwlarson 3.22 cbeam[n].nr = 0; cbeam[n].hd = hd; cbeam[n].bi = bi;
133 gregl 3.1 return(n);
134     }
135    
136    
137     cbeamsort(adopt) /* sort our beam list, possibly turning out orphans */
138     int adopt;
139     {
140     register int i;
141    
142     if (!(ncbeams += xcbeams))
143     return;
144     xcbeams = 0;
145     qsort((char *)cbeam, ncbeams, sizeof(struct beamcomp),
146     adopt ? cbeamcmp : cbeamcmp2);
147     if (adopt)
148     return;
149     for (i = ncbeams; i--; ) /* identify orphans */
150 gwlarson 3.22 if (cbeam[i].nr)
151 gregl 3.1 break;
152     xcbeams = ncbeams - ++i; /* put orphans after ncbeams */
153     ncbeams = i;
154     }
155    
156    
157 gwlarson 3.21 cbeamop(op, bl, n) /* update beams on server list */
158 gregl 3.4 int op;
159 gregl 3.1 register struct beamcomp *bl;
160     int n;
161     {
162     register PACKHEAD *pa;
163     register int i;
164    
165     if (n <= 0)
166     return;
167     pa = (PACKHEAD *)malloc(n*sizeof(PACKHEAD));
168     if (pa == NULL)
169 gwlarson 3.21 error(SYSTEM, "out of memory in cbeamop");
170 gregl 3.1 for (i = 0; i < n; i++) {
171     pa[i].hd = bl[i].hd;
172     pa[i].bi = bl[i].bi;
173 gwlarson 3.21 pa[i].nr = bl[i].nr;
174 gregl 3.16 pa[i].nc = 0;
175 gregl 3.1 }
176 gregl 3.4 serv_request(op, n*sizeof(PACKHEAD), (char *)pa);
177 gregl 3.1 free((char *)pa);
178     }
179    
180    
181 gwlarson 3.29 static int
182 gwlarson 3.25 comptodo(tdl, vw) /* compute holodeck sections in view */
183     int tdl[MAXTODO+1];
184     VIEW *vw;
185 gregl 3.1 {
186 gwlarson 3.25 int n = 0;
187     FVECT gp, dv;
188     double dist2[MAXTODO+1], thisdist2;
189     register int i, j;
190     /* find closest MAXTODO sections */
191     for (i = 0; hdlist[i]; i++) {
192     hdgrid(gp, hdlist[i], vw->vp);
193     for (j = 0; j < 3; j++)
194     if (gp[j] < 0.)
195     dv[j] = -gp[j];
196     else if (gp[j] > hdlist[i]->grid[j])
197     dv[j] = gp[j] - hdlist[i]->grid[j];
198     else
199     dv[j] = 0.;
200     thisdist2 = DOT(dv,dv);
201     for (j = n; j > 0 && thisdist2 < dist2[j-1]; j--) {
202     tdl[j] = tdl[j-1];
203     dist2[j] = dist2[j-1];
204 gregl 3.1 }
205 gwlarson 3.25 tdl[j] = i;
206     dist2[j] = thisdist2;
207     if (n < MAXTODO)
208     n++;
209 gregl 3.1 }
210 gwlarson 3.25 /* watch for bad move */
211     if (n && dist2[0] > MAXDIST*MAXDIST) {
212 gregl 3.10 error(COMMAND, "move past outer limits");
213 gregl 3.9 return(0);
214     }
215 gwlarson 3.25 /* avoid big differences */
216     for (j = 1; j < n; j++)
217     if (dist2[j] > MAXDRAT*MAXDRAT*dist2[j-1])
218     n = j;
219     tdl[n] = -1;
220     return(n);
221 gregl 3.1 }
222    
223    
224 gwlarson 3.29 int
225 gwlarson 3.25 addview(hd, vw, hres, vres) /* add view for section */
226     int hd;
227     VIEW *vw;
228     int hres, vres;
229 gregl 3.1 {
230 gwlarson 3.29 int sampquant, samptot = 0;
231 gwlarson 3.25 int h, v, shr, svr;
232 gregl 3.1 GCOORD gc[2];
233 gwlarson 3.25 FVECT rorg, rdir;
234     /* compute sampling grid */
235     if (hres|vres && hres*vres <= NVSAMPS) {
236     shr = hres; svr = vres;
237     sampquant = 1;
238 gregl 3.5 } else {
239 gwlarson 3.25 shr = sqrt(NVSAMPS/viewaspect(vw)) + .5;
240     svr = (NVSAMPS + shr/2)/shr;
241     sampquant = (hres*vres + shr*svr/2)/(shr*svr);
242 gregl 3.5 }
243 gwlarson 3.25 /* intersect sample rays with section */
244     for (v = svr; v--; )
245     for (h = shr; h--; ) {
246     if (viewray(rorg, rdir, vw, (v+frandom())/svr,
247     (h+frandom())/shr) < -FTINY)
248     continue;
249     if (hdinter(gc, NULL, NULL, hdlist[hd], rorg, rdir)
250     >= FHUGE)
251     continue;
252     cbeam[getcbeam(hd,hdbindex(hdlist[hd],gc))].nr +=
253     sampquant;
254 gwlarson 3.29 samptot += sampquant;
255 gregl 3.1 }
256 gwlarson 3.29 return(samptot);
257 gregl 3.1 }
258    
259    
260 gwlarson 3.24 beam_init(fresh) /* clear beam list for new view(s) */
261     int fresh;
262 gregl 3.1 {
263 gwlarson 3.21 register int i;
264 gwlarson 3.24
265     if (fresh) /* discard old beams? */
266     ncbeams = xcbeams = 0;
267     else /* else clear sample requests */
268     for (i = ncbeams+xcbeams; i--; )
269     cbeam[i].nr = 0;
270 gwlarson 3.26 cureye.rng = 0.;
271 gregl 3.1 }
272    
273    
274 gwlarson 3.29 int *
275 gwlarson 3.21 beam_view(vn, hr, vr) /* add beam view (if advisable) */
276     VIEW *vn;
277     int hr, vr;
278 gregl 3.4 {
279 gwlarson 3.29 static int todo[MAXTODO+1];
280     int n;
281 gwlarson 3.26 double hdgsiz, d;
282     register HOLO *hp;
283     register int i;
284 gwlarson 3.29 /* find nearby sections */
285     if (!(n = comptodo(todo, vn)))
286     return(NULL);
287 gwlarson 3.21 /* sort our list */
288     cbeamsort(1);
289 gwlarson 3.29 /* add view to flagged sections */
290 gwlarson 3.26 for (i = 0; i < n; i++)
291 gwlarson 3.29 if (!addview(todo[i], vn, hr, vr)) { /* whoops! */
292     register int j;
293     n--; /* delete from list */
294     for (j = i--; j <= n; j++)
295     todo[j] = todo[j+1];
296     }
297     if (!n || MEYERNG <= FTINY || vn->type == VT_PAR)
298     return(todo);
299 gwlarson 3.27 hdgsiz = 0.; /* compute mean grid size */
300 gwlarson 3.26 for (i = 0; i < n; i++) {
301     hp = hdlist[todo[i]];
302 gwlarson 3.27 hdgsiz += 1./3. / VLEN(hp->wg[0]) +
303     1./3. / VLEN(hp->wg[1]) +
304     1./3. / VLEN(hp->wg[2]) ;
305 gwlarson 3.26 }
306 gwlarson 3.27 hdgsiz /= (double)n;
307 gwlarson 3.26 /* add to current eye position */
308     if (cureye.rng <= FTINY) {
309     VCOPY(cureye.vpt, vn->vp);
310     cureye.rng = MEYERNG * hdgsiz;
311     } else if ((d = sqrt(dist2(vn->vp,cureye.vpt))) + MEYERNG*hdgsiz >
312     cureye.rng) {
313     for (i = 3; i--; )
314     cureye.vpt[i] = 0.5*(cureye.vpt[i] + vn->vp[i]);
315     cureye.rng = 0.5*(cureye.rng + MEYERNG*hdgsiz + d);
316     }
317 gwlarson 3.29 return(todo);
318 gregl 3.4 }
319    
320    
321 gwlarson 3.21 int
322     beam_sync(all) /* update beam list on server */
323     int all;
324 gregl 3.1 {
325 gwlarson 3.26 /* set new eye position */
326     serv_request(DR_VIEWPOINT, sizeof(VIEWPOINT), (char *)&cureye);
327 gwlarson 3.24 /* sort list (put orphans at end) */
328     cbeamsort(all < 0);
329 gwlarson 3.26 /* send beam request */
330 gwlarson 3.21 if (all)
331     cbeamop(DR_NEWSET, cbeam, ncbeams);
332     else
333     cbeamop(DR_ADJSET, cbeam, ncbeams+xcbeams);
334 gregl 3.1 xcbeams = 0; /* truncate our list */
335 gwlarson 3.21 return(ncbeams);
336 gregl 3.1 }