26 |
|
|
27 |
|
#define GAMMA 2.2 /* default gamma correction */ |
28 |
|
|
29 |
< |
#define MOVPCT 10 /* percent distance to move */ |
29 |
> |
#define MOVPCT 7 /* percent distance to move /frame */ |
30 |
|
#define MOVDIR(b) ((b)==Button1 ? 1 : (b)==Button2 ? 0 : -1) |
31 |
+ |
#define MOVDEG (-5) /* degrees to orbit CW/down /frame */ |
32 |
+ |
#define MOVORB(s) ((s)&ShiftMask ? 1 : (s)&ControlMask ? -1 : 0) |
33 |
|
|
34 |
|
#define MINWIDTH 480 /* minimum graphics window width */ |
35 |
|
#define MINHEIGHT 400 /* minimum graphics window height */ |
200 |
|
} |
201 |
|
|
202 |
|
|
203 |
+ |
int |
204 |
|
dev_view(nv) /* assign new driver view */ |
205 |
|
VIEW *nv; |
206 |
|
{ |
207 |
+ |
if (nv->type == VT_PAR || /* check view legality */ |
208 |
+ |
nv->horiz > 160. || nv->vert > 160.) { |
209 |
+ |
error(COMMAND, "illegal view type/angle"); |
210 |
+ |
nv->type = VT_PER; |
211 |
+ |
nv->horiz = odev.v.horiz; |
212 |
+ |
nv->vert = odev.v.vert; |
213 |
+ |
return(0); |
214 |
+ |
} |
215 |
+ |
if (nv->vfore > FTINY) { |
216 |
+ |
error(COMMAND, "cannot handle fore clipping"); |
217 |
+ |
nv->vfore = 0.; |
218 |
+ |
return(0); |
219 |
+ |
} |
220 |
|
if (nv != &odev.v) { |
221 |
|
if (!FEQ(nv->horiz,odev.v.horiz) || /* resize window? */ |
222 |
|
!FEQ(nv->vert,odev.v.vert)) { |
223 |
+ |
int dw = DisplayWidth(ourdisplay,ourscreen); |
224 |
+ |
int dh = DisplayHeight(ourdisplay,ourscreen); |
225 |
+ |
|
226 |
+ |
dw -= 25; /* for window frame */ |
227 |
+ |
dh -= 100; |
228 |
|
odev.hres = 2.*VIEWDIST/pwidth * |
229 |
|
tan(PI/180./2.*nv->horiz); |
230 |
|
odev.vres = 2.*VIEWDIST/pheight * |
231 |
|
tan(PI/180./2.*nv->vert); |
232 |
+ |
if (odev.hres > dw) { |
233 |
+ |
odev.vres = dw * odev.vres / odev.hres; |
234 |
+ |
odev.hres = dw; |
235 |
+ |
} |
236 |
+ |
if (odev.vres > dh) { |
237 |
+ |
odev.hres = dh * odev.hres / odev.vres; |
238 |
+ |
odev.vres = dh; |
239 |
+ |
} |
240 |
|
XResizeWindow(ourdisplay, gwind, odev.hres, odev.vres); |
241 |
|
} |
242 |
|
copystruct(&odev.v, nv); |
243 |
|
} |
244 |
|
qtReplant(); |
245 |
+ |
return(1); |
246 |
|
} |
247 |
|
|
248 |
|
|
470 |
|
|
471 |
|
|
472 |
|
static |
473 |
< |
moveview(dx, dy, move) /* move our view */ |
474 |
< |
int dx, dy, move; |
473 |
> |
moveview(dx, dy, mov, orb) /* move our view */ |
474 |
> |
int dx, dy, mov, orb; |
475 |
|
{ |
476 |
|
VIEW nv; |
477 |
+ |
FVECT v1; |
478 |
|
double d; |
479 |
< |
register int i, li; |
479 |
> |
register int li; |
480 |
|
/* start with old view */ |
481 |
|
copystruct(&nv, &odev.v); |
482 |
|
/* change view direction */ |
483 |
< |
if (move) { |
483 |
> |
if (mov | orb) { |
484 |
|
if ((li = qtFindLeaf(dx, dy)) < 0) |
485 |
|
return(0); /* not on window */ |
486 |
< |
for (i = 0; i < 3; i++) |
456 |
< |
nv.vdir[i] = qtL.wp[li][i] - nv.vp[i]; |
486 |
> |
VSUM(nv.vdir, qtL.wp[li], nv.vp, -1.); |
487 |
|
} else { |
488 |
|
if (viewray(nv.vp, nv.vdir, &odev.v, |
489 |
|
(dx+.5)/odev.hres, (dy+.5)/odev.vres) < -FTINY) |
490 |
|
return(0); /* outside view */ |
491 |
|
} |
492 |
< |
/* move viewpoint */ |
493 |
< |
if (move > 0) |
494 |
< |
for (i = 0; i < 3; i++) |
495 |
< |
nv.vp[i] += MOVPCT/100. * nv.vdir[i]; |
496 |
< |
else if (move < 0) |
497 |
< |
for (i = 0; i < 3; i++) |
498 |
< |
nv.vp[i] -= MOVPCT/100. * nv.vdir[i]; |
499 |
< |
if (move && headlocked) { |
500 |
< |
d = 0; /* bring head back to same height */ |
501 |
< |
for (i = 0; i < 3; i++) |
502 |
< |
d += odev.v.vup[i] * (odev.v.vp[i] - nv.vp[i]); |
503 |
< |
for (i = 0; i < 3; i++) |
474 |
< |
nv.vp[i] += d * odev.v.vup[i]; |
492 |
> |
if (orb && mov) { /* orbit left/right */ |
493 |
> |
spinvector(nv.vdir, nv.vdir, nv.vup, MOVDEG*PI/180.*mov); |
494 |
> |
VSUM(nv.vp, qtL.wp[li], nv.vdir, -1.); |
495 |
> |
} else if (orb) { /* orbit up/down */ |
496 |
> |
fcross(v1, nv.vdir, nv.vup); |
497 |
> |
if (normalize(v1) == 0.) |
498 |
> |
return(0); |
499 |
> |
spinvector(nv.vdir, nv.vdir, v1, MOVDEG*PI/180.*orb); |
500 |
> |
VSUM(nv.vp, qtL.wp[li], nv.vdir, -1.); |
501 |
> |
} else if (mov) { /* move forward/backward */ |
502 |
> |
d = MOVPCT/100. * mov; |
503 |
> |
VSUM(nv.vp, nv.vp, nv.vdir, d); |
504 |
|
} |
505 |
+ |
if (!mov ^ !orb && headlocked) { /* restore head height */ |
506 |
+ |
VSUM(v1, odev.v.vp, nv.vp, -1.); |
507 |
+ |
d = DOT(v1, odev.v.vup); |
508 |
+ |
VSUM(nv.vp, nv.vp, odev.v.vup, d); |
509 |
+ |
} |
510 |
|
if (setview(&nv) != NULL) |
511 |
|
return(0); /* illegal view */ |
512 |
|
dev_view(&nv); |
519 |
|
getmove(ebut) /* get view change */ |
520 |
|
XButtonPressedEvent *ebut; |
521 |
|
{ |
522 |
< |
int whichbutton = ebut->button; |
522 |
> |
int movdir = MOVDIR(ebut->button); |
523 |
> |
int movorb = MOVORB(ebut->state); |
524 |
|
int oldnodesiz = qtMinNodesiz; |
525 |
|
Window rootw, childw; |
526 |
|
int rootx, rooty, wx, wy; |
536 |
|
&rootx, &rooty, &wx, &wy, &statemask)) |
537 |
|
break; /* on another screen */ |
538 |
|
|
539 |
< |
if (!moveview(wx, odev.vres-1-wy, MOVDIR(whichbutton))) { |
539 |
> |
if (!moveview(wx, odev.vres-1-wy, movdir, movorb)) { |
540 |
|
sleep(1); |
541 |
|
continue; |
542 |
|
} |
545 |
|
draw_grids(); |
546 |
|
} |
547 |
|
if (!(inpresflags & DEV_NEWVIEW)) { /* do final motion */ |
548 |
< |
whichbutton = levptr(XButtonReleasedEvent)->button; |
548 |
> |
movdir = MOVDIR(levptr(XButtonReleasedEvent)->button); |
549 |
|
wx = levptr(XButtonReleasedEvent)->x; |
550 |
|
wy = levptr(XButtonReleasedEvent)->y; |
551 |
< |
moveview(wx, odev.vres-1-wy, MOVDIR(whichbutton)); |
551 |
> |
moveview(wx, odev.vres-1-wy, movdir, movorb); |
552 |
|
} |
553 |
|
dev_flush(); |
554 |
|
|
572 |
|
return; |
573 |
|
case 'H': /* turn off height motion lock */ |
574 |
|
headlocked = 0; |
575 |
+ |
return; |
576 |
+ |
case 'l': /* retrieve last view */ |
577 |
+ |
inpresflags |= DEV_LASTVIEW; |
578 |
|
return; |
579 |
|
case CTRL('S'): |
580 |
|
case 'p': /* pause computation */ |