ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/hd/rhdisp2.c
Revision: 3.28
Committed: Thu Dec 10 10:45:55 1998 UTC (25 years, 4 months ago) by gwlarson
Content type: text/plain
Branch: MAIN
Changes since 3.27: +2 -2 lines
Log Message:
created "frame" command to focus calculation

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 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 addview(hd, vw, hres, vres) /* add view for section */
225 int hd;
226 VIEW *vw;
227 int hres, vres;
228 {
229 int sampquant;
230 int h, v, shr, svr;
231 GCOORD gc[2];
232 FVECT rorg, rdir;
233 /* compute sampling grid */
234 if (hres|vres && hres*vres <= NVSAMPS) {
235 shr = hres; svr = vres;
236 sampquant = 1;
237 } else {
238 shr = sqrt(NVSAMPS/viewaspect(vw)) + .5;
239 svr = (NVSAMPS + shr/2)/shr;
240 sampquant = (hres*vres + shr*svr/2)/(shr*svr);
241 }
242 /* intersect sample rays with section */
243 for (v = svr; v--; )
244 for (h = shr; h--; ) {
245 if (viewray(rorg, rdir, vw, (v+frandom())/svr,
246 (h+frandom())/shr) < -FTINY)
247 continue;
248 if (hdinter(gc, NULL, NULL, hdlist[hd], rorg, rdir)
249 >= FHUGE)
250 continue;
251 cbeam[getcbeam(hd,hdbindex(hdlist[hd],gc))].nr +=
252 sampquant;
253 }
254 }
255
256
257 beam_init(fresh) /* clear beam list for new view(s) */
258 int fresh;
259 {
260 register int i;
261
262 if (fresh) /* discard old beams? */
263 ncbeams = xcbeams = 0;
264 else /* else clear sample requests */
265 for (i = ncbeams+xcbeams; i--; )
266 cbeam[i].nr = 0;
267 cureye.rng = 0.;
268 }
269
270
271 beam_view(vn, hr, vr) /* add beam view (if advisable) */
272 VIEW *vn;
273 int hr, vr;
274 {
275 int todo[MAXTODO+1], n;
276 double hdgsiz, d;
277 register HOLO *hp;
278 register int i;
279 /* sort our list */
280 cbeamsort(1);
281 /* add view to nearby sections */
282 if (!(n = comptodo(todo, vn)))
283 return(0);
284 for (i = 0; i < n; i++)
285 addview(todo[i], vn, hr, vr);
286 if (MEYERNG <= FTINY || vn->type == VT_PAR)
287 return(1);
288 hdgsiz = 0.; /* compute mean grid size */
289 for (i = 0; i < n; i++) {
290 hp = hdlist[todo[i]];
291 hdgsiz += 1./3. / VLEN(hp->wg[0]) +
292 1./3. / VLEN(hp->wg[1]) +
293 1./3. / VLEN(hp->wg[2]) ;
294 }
295 hdgsiz /= (double)n;
296 /* add to current eye position */
297 if (cureye.rng <= FTINY) {
298 VCOPY(cureye.vpt, vn->vp);
299 cureye.rng = MEYERNG * hdgsiz;
300 } else if ((d = sqrt(dist2(vn->vp,cureye.vpt))) + MEYERNG*hdgsiz >
301 cureye.rng) {
302 for (i = 3; i--; )
303 cureye.vpt[i] = 0.5*(cureye.vpt[i] + vn->vp[i]);
304 cureye.rng = 0.5*(cureye.rng + MEYERNG*hdgsiz + d);
305 }
306 return(1);
307 }
308
309
310 int
311 beam_sync(all) /* update beam list on server */
312 int all;
313 {
314 /* set new eye position */
315 serv_request(DR_VIEWPOINT, sizeof(VIEWPOINT), (char *)&cureye);
316 /* sort list (put orphans at end) */
317 cbeamsort(all < 0);
318 /* send beam request */
319 if (all)
320 cbeamop(DR_NEWSET, cbeam, ncbeams);
321 else
322 cbeamop(DR_ADJSET, cbeam, ncbeams+xcbeams);
323 xcbeams = 0; /* truncate our list */
324 return(ncbeams);
325 }