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

# Content
1 /* Copyright (c) 1998 Silicon Graphics, Inc. */
2
3 #ifndef lint
4 static char SCCSid[] = "$SunId$ SGI";
5 #endif
6
7 /*
8 * Holodeck beam tracking for display process
9 */
10
11 #include "rholo.h"
12 #include "rhdisp.h"
13 #include "rhdriver.h"
14 #include "random.h"
15
16 #ifndef MAXDIST
17 #define MAXDIST 42 /* maximum distance outside section */
18 #endif
19 #ifndef NVSAMPS
20 #define NVSAMPS 16384 /* number of ray samples per view */
21 #endif
22 #ifndef MEYERNG
23 #define MEYERNG 0.1 /* target mean eye range (rel. to grid) */
24 #endif
25 #ifndef MAXTODO
26 #define MAXTODO 3 /* maximum sections to look at */
27 #endif
28 #ifndef MAXDRAT
29 #define MAXDRAT 3.0 /* maximum distance ratio btwn. cand. sect. */
30 #endif
31
32 #define CBEAMBLK 1024 /* cbeam allocation block size */
33
34 static struct beamcomp {
35 int hd; /* holodeck section number */
36 int bi; /* beam index */
37 int4 nr; /* number of samples desired */
38 } *cbeam = NULL; /* current beam list */
39
40 VIEWPOINT cureye; /* current eye position */
41
42 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 if (!cb1->nr) /* put orphans at the end, unsorted */
86 return(cb2->nr);
87 if (!cb2->nr)
88 return(-1);
89 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 cb.hd = hd; cb.bi = bi; cb.nr = 0;
105 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 cbeam[n].nr = 0; cbeam[n].hd = hd; cbeam[n].bi = bi;
133 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 if (cbeam[i].nr)
151 break;
152 xcbeams = ncbeams - ++i; /* put orphans after ncbeams */
153 ncbeams = i;
154 }
155
156
157 cbeamop(op, bl, n) /* update beams on server list */
158 int op;
159 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 error(SYSTEM, "out of memory in cbeamop");
170 for (i = 0; i < n; i++) {
171 pa[i].hd = bl[i].hd;
172 pa[i].bi = bl[i].bi;
173 pa[i].nr = bl[i].nr;
174 pa[i].nc = 0;
175 }
176 serv_request(op, n*sizeof(PACKHEAD), (char *)pa);
177 free((char *)pa);
178 }
179
180
181 static int
182 comptodo(tdl, vw) /* compute holodeck sections in view */
183 int tdl[MAXTODO+1];
184 VIEW *vw;
185 {
186 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 }
205 tdl[j] = i;
206 dist2[j] = thisdist2;
207 if (n < MAXTODO)
208 n++;
209 }
210 /* watch for bad move */
211 if (n && dist2[0] > MAXDIST*MAXDIST) {
212 error(COMMAND, "move past outer limits");
213 return(0);
214 }
215 /* 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 }
222
223
224 int
225 addview(hd, vw, hres, vres) /* add view for section */
226 int hd;
227 VIEW *vw;
228 int hres, vres;
229 {
230 int sampquant, samptot = 0;
231 int h, v, shr, svr;
232 GCOORD gc[2];
233 FVECT rorg, rdir;
234 /* compute sampling grid */
235 if (hres|vres && hres*vres <= NVSAMPS) {
236 shr = hres; svr = vres;
237 sampquant = 1;
238 } else {
239 shr = sqrt(NVSAMPS/viewaspect(vw)) + .5;
240 svr = (NVSAMPS + shr/2)/shr;
241 sampquant = (hres*vres + shr*svr/2)/(shr*svr);
242 }
243 /* 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 samptot += sampquant;
255 }
256 return(samptot);
257 }
258
259
260 beam_init(fresh) /* clear beam list for new view(s) */
261 int fresh;
262 {
263 register int i;
264
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 cureye.rng = 0.;
271 }
272
273
274 int *
275 beam_view(vn, hr, vr) /* add beam view (if advisable) */
276 VIEW *vn;
277 int hr, vr;
278 {
279 static int todo[MAXTODO+1];
280 int n;
281 double hdgsiz, d;
282 register HOLO *hp;
283 register int i;
284 /* find nearby sections */
285 if (!(n = comptodo(todo, vn)))
286 return(NULL);
287 /* sort our list */
288 cbeamsort(1);
289 /* add view to flagged sections */
290 for (i = 0; i < n; i++)
291 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 hdgsiz = 0.; /* compute mean grid size */
300 for (i = 0; i < n; i++) {
301 hp = hdlist[todo[i]];
302 hdgsiz += 1./3. / VLEN(hp->wg[0]) +
303 1./3. / VLEN(hp->wg[1]) +
304 1./3. / VLEN(hp->wg[2]) ;
305 }
306 hdgsiz /= (double)n;
307 /* 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 return(todo);
318 }
319
320
321 int
322 beam_sync(all) /* update beam list on server */
323 int all;
324 {
325 /* set new eye position */
326 serv_request(DR_VIEWPOINT, sizeof(VIEWPOINT), (char *)&cureye);
327 /* sort list (put orphans at end) */
328 cbeamsort(all < 0);
329 /* send beam request */
330 if (all)
331 cbeamop(DR_NEWSET, cbeam, ncbeams);
332 else
333 cbeamop(DR_ADJSET, cbeam, ncbeams+xcbeams);
334 xcbeams = 0; /* truncate our list */
335 return(ncbeams);
336 }