76
75
#include "BSE_drawview.h" /* For inner_play_anim_loop */
78
77
#include "BDR_drawobject.h" /* For draw_object */
78
#include "BDR_editface.h" /* For minmax_tface */
80
80
#include "mydevice.h"
81
81
#include "blendef.h"
84
#include "render.h" /* R. stuff for ogl view render */
86
86
#define TRACKBALLSIZE (1.1)
87
87
#define BL_NEAR_CLIP 0.001
90
/* local prototypes ----------*/
91
void setcameratoview3d(void); /* windows.c & toets.c */
89
93
void persp_general(int a)
91
95
/* for all window types, not 3D */
174
178
Mat4MulVec4fl(G.vd->persmat, vec4);
176
180
if( vec4[3]>BL_NEAR_CLIP ) { /* 0.001 is the NEAR clipping cutoff for picking */
177
fx= (curarea->winx/2)+(curarea->winx/2)*vec4[0]/vec4[3];
181
fx= (curarea->winx/2)*(1 + vec4[0]/vec4[3]);
179
183
if( fx>0 && fx<curarea->winx) {
181
fy= (curarea->winy/2)+(curarea->winy/2)*vec4[1]/vec4[3];
185
fy= (curarea->winy/2)*(1 + vec4[1]/vec4[3]);
183
187
if(fy>0.0 && fy< (float)curarea->winy) {
184
adr[0]= floor(fx+0.5);
185
adr[1]= floor(fy+0.5);
195
void project_int(float *vec, int *adr)
197
float fx, fy, vec4[4];
199
adr[0]= 2140000000.0f;
203
Mat4MulVec4fl(G.vd->persmat, vec4);
205
if( vec4[3]>BL_NEAR_CLIP ) { /* 0.001 is the NEAR clipping cutoff for picking */
206
fx= (curarea->winx/2)*(1 + vec4[0]/vec4[3]);
208
if( fx>-2140000000.0f && fx<2140000000.0f) {
209
fy= (curarea->winy/2)*(1 + vec4[1]/vec4[3]);
211
if(fy>-2140000000.0f && fy<2140000000.0f) {
199
227
Mat4MulVec4fl(G.vd->persmat, vec4);
201
229
if( vec4[3]>BL_NEAR_CLIP ) { /* 0.001 is the NEAR clipping cutoff for picking */
202
fx= (curarea->winx/2)+(curarea->winx/2)*vec4[0]/vec4[3];
230
fx= (curarea->winx/2)*(1 + vec4[0]/vec4[3]);
204
232
if( fx>-32700 && fx<32700) {
206
fy= (curarea->winy/2)+(curarea->winy/2)*vec4[1]/vec4[3];
234
fy= (curarea->winy/2)*(1 + vec4[1]/vec4[3]);
208
236
if(fy>-32700.0 && fy<32700.0) {
209
adr[0]= floor(fx+0.5);
210
adr[1]= floor(fy+0.5);
405
433
void viewmove(int mode)
407
435
float firstvec[3], newvec[3], dvec[3];
408
float oldquat[4], q1[4], si, phi;
436
float oldquat[4], q1[4], si, phi, dist0;
410
438
short mvalball[2], mval[2], mvalo[2];
412
440
/* sometimes this routine is called from headerbuttons */
413
441
areawinset(curarea->win);
414
curarea->head_swap= 0;
416
443
initgrabz(-G.vd->ofs[0], -G.vd->ofs[1], -G.vd->ofs[2]);
429
457
getmouseco_sc(mval);
431
if(mval[0]!=mvalo[0] || mval[1]!=mvalo[1] || (G.f & G_PLAYANIM)) {
459
// if playanim = alt+A, screenhandlers are for animated UI, python, etc
460
if(mval[0]!=mvalo[0] || mval[1]!=mvalo[1] || (G.f & G_PLAYANIM) || do_screenhandlers(G.curscreen)) {
435
465
/* are we translating, rotating or zooming? */
449
479
if(mode==0) { /* view rotate */
451
/* if turntable method, we don't change mvalball[0] */
453
if(U.flag & USER_TRACKBALL) mvalball[0]= mval[0];
480
if (U.uiflag & USER_AUTOPERSP) G.vd->persp= 1;
482
if (U.flag & USER_TRACKBALL) mvalball[0]= mval[0];
454
483
mvalball[1]= mval[1];
456
485
calctrackballvec(&curarea->winrct, mvalball, newvec);
460
489
si= sqrt(dvec[0]*dvec[0]+ dvec[1]*dvec[1]+ dvec[2]*dvec[2]);
461
490
si/= (2.0*TRACKBALLSIZE);
463
/* is there an acceptable solution? (180 degrees limitor) */
492
if (U.flag & USER_TRACKBALL) {
465
493
Crossf(q1+1, firstvec, newvec);
497
/* Allow for rotation beyond the interval
502
/* This relation is used instead of
503
* phi = asin(si) so that the angle
504
* of rotation is linearly proportional
505
* to the distance that the mouse is
507
phi = si * M_PI / 2.0;
477
514
QuatMul(G.vd->viewquat, q1, oldquat);
479
if( (U.flag & USER_TRACKBALL)==0 ) {
481
/* rotate around z-axis (mouse x moves) */
483
phi= 2*(mval[0]-mvalball[0]);
484
phi/= (float)curarea->winx;
490
QuatMul(G.vd->viewquat, G.vd->viewquat, q1);
516
/* New turntable view code by John Aughey */
520
float xvec[3] = {1,0,0};
521
/* Sensitivity will control how fast the viewport rotates. 0.0035 was
522
obtained experimentally by looking at viewport rotation sensitivities
523
on other modeling programs. */
524
/* Perhaps this should be a configurable user parameter. */
525
const float sensitivity = 0.0035;
527
/* Get the 3x3 matrix and its inverse from the quaternion */
528
QuatToMat3(G.vd->viewquat, m);
531
/* Determine the direction of the x vector (for rotating up and down) */
532
/* This can likely be compuated directly from the quaternion. */
533
Mat3MulVecfl(m_inv,xvec);
535
/* Perform the up/down rotation */
536
phi = sensitivity * -(mval[1] - mvalo[1]);
539
q1[1] = si * xvec[0];
540
q1[2] = si * xvec[1];
541
q1[3] = si * xvec[2];
542
QuatMul(G.vd->viewquat, G.vd->viewquat, q1);
544
/* Perform the orbital rotation */
545
phi = sensitivity * (mval[0] - mvalo[0]);
549
QuatMul(G.vd->viewquat, G.vd->viewquat, q1);
494
552
else if(mode==1) { /* translate */
511
569
else if(mode==2) {
512
G.vd->dist*= 1.0+(float)(mvalo[0]-mval[0]+mvalo[1]-mval[1])/1000.0;
570
if(U.viewzoom==USER_ZOOM_CONT) {
572
G.vd->dist*= 1.0+(float)(mvalo[0]-mval[0]+mvalo[1]-mval[1])/1000.0;
574
else if(U.viewzoom==USER_ZOOM_SCALE) {
575
int ctr[2], len1, len2;
576
// method which zooms based on how far you move the mouse
578
ctr[0] = (curarea->winrct.xmax + curarea->winrct.xmin)/2;
579
ctr[1] = (curarea->winrct.ymax + curarea->winrct.ymin)/2;
581
len1 = (int)sqrt((ctr[0] - mval[0])*(ctr[0] - mval[0]) + (ctr[1] - mval[1])*(ctr[1] - mval[1])) + 5;
582
len2 = (int)sqrt((ctr[0] - mvalo[0])*(ctr[0] - mvalo[0]) + (ctr[1] - mvalo[1])*(ctr[1] - mvalo[1])) + 5;
584
G.vd->dist= dist0 * ((float)len2/len1);
586
else { /* USER_ZOOM_DOLLY */
587
float len1 = (curarea->winrct.ymax - mval[1]) + 5;
588
float len2 = (curarea->winrct.ymax - mvalo[1]) + 5;
590
G.vd->dist= dist0 * (2.0*((len2/len1)-1.0) + 1.0);
514
593
/* these limits are in toets.c too */
515
594
if(G.vd->dist<0.001*G.vd->grid) G.vd->dist= 0.001*G.vd->grid;
516
595
if(G.vd->dist>10.0*G.vd->far) G.vd->dist=10.0*G.vd->far;
518
mval[1]= mvalo[1]; /* keeps zooming that way */
597
mval[1]= mvalo[1]; /* preserve first value */
519
598
mval[0]= mvalo[0];
529
608
screen_swapbuffers();
612
unsigned short event;
613
/* we need to empty the queue... when you do this very long it overflows */
614
while(qtest()) event= extern_qread(&val);
532
616
BIF_wait_for_statechange();
535
619
/* this in the end, otherwise get_mbut does not work on a PC... */
536
620
if( !(get_mbut() & (L_MOUSE|M_MOUSE))) break;
539
curarea->head_swap= WIN_FRONT_OK;
542
624
short v3d_windowmode=0;
626
/* important to not set windows active in here, can be renderwin for example */
544
627
void setwinmatrixview3d(rctf *rect) /* rect: for picking */
547
float d, near, far, winx = 0.0, winy = 0.0;
548
float lens, dfac, fac, x1, y1, x2, y2;
630
float near, far, winx = 0.0, winy = 0.0;
631
float lens, fac, x1, y1, x2, y2;
551
634
lens= G.vd->lens;
593
670
winy= curarea->winy;
596
if(winx>winy) d= 0.015625*winx*lens;
597
else d= 0.015625*winy*lens;
601
673
if(G.vd->persp==0) {
602
674
if(winx>winy) x1= -G.vd->dist;
603
675
else x1= -winx*G.vd->dist/winy;
607
678
if(winx>winy) y1= -winy*G.vd->dist/winx;
608
679
else y1= -G.vd->dist;
620
x1= -dfac*(winx/fac);
622
y1= -dfac*(winy/fac);
692
/* viewplane size depends... */
693
if(cam && cam->type==CAM_ORTHO) {
694
/* ortho_scale == 1 means exact 1 to 1 mapping */
695
float dfac= 2.0*cam->ortho_scale/fac;
697
if(winx>winy) x1= -dfac;
698
else x1= -winx*dfac/winy;
701
if(winx>winy) y1= -winy*dfac/winx;
709
if(winx>winy) dfac= 64.0/(fac*winx*lens);
710
else dfac= 64.0/(fac*winy*lens);
712
x1= - near*winx*dfac;
714
y1= - near*winy*dfac;
628
720
if(rect) { /* picking */
643
735
if(v3d_windowmode) {
644
if(orth) i_ortho(x1, x2, y1, y2, -far, far, R.winmat);
646
if(cam && cam->type==CAM_ORTHO) i_window(x1, x2, y1, y2, near, far, R.winmat);
647
else i_window(x1, x2, y1, y2, near, far, R.winmat);
736
if(orth) i_ortho(x1, x2, y1, y2, near, far, R.winmat);
737
else i_window(x1, x2, y1, y2, near, far, R.winmat);
651
if(orth) myortho(x1, x2, y1, y2, -far, far);
653
if(cam && cam->type==CAM_ORTHO) mywindow(x1, x2, y1, y2, near, far);
654
else mywindow(x1, x2, y1, y2, near, far);
740
if(orth) myortho(x1, x2, y1, y2, near, far);
741
else mywindow(x1, x2, y1, y2, near, far);
889
975
afm[0]= (max[0]-min[0]);
890
976
afm[1]= (max[1]-min[1]);
891
977
afm[2]= (max[2]-min[2]);
892
size= MAX3(afm[0], afm[1], afm[2]);
978
size= 0.7*MAX3(afm[0], afm[1], afm[2]);
893
979
if(size<=0.01) size= 0.01;
966
1063
afm[0]= (max[0]-min[0]);
967
1064
afm[1]= (max[1]-min[1]);
968
1065
afm[2]= (max[2]-min[2]);
969
size= MAX3(afm[0], afm[1], afm[2]);
1066
size= 0.7*MAX3(afm[0], afm[1], afm[2]);
971
1068
if(size<=0.01) size= 0.01;
975
1070
G.vd->ofs[0]= -(min[0]+max[0])/2.0;
976
1071
G.vd->ofs[1]= -(min[1]+max[1])/2.0;
977
1072
G.vd->ofs[2]= -(min[2]+max[2])/2.0;
979
1074
G.vd->dist= size;
1076
// correction for window aspect ratio
1077
if(curarea->winy>2 && curarea->winx>2) {
1078
size= (float)curarea->winx/(float)curarea->winy;
1079
if(size<1.0) size= 1.0/size;
981
1083
if(G.vd->persp>1) {
986
1087
G.vd->cursor[0]= -G.vd->ofs[0];