~ubuntu-branches/ubuntu/gutsy/blender/gutsy-security

« back to all changes in this revision

Viewing changes to source/blender/src/view.c

  • Committer: Bazaar Package Importer
  • Author(s): Florian Ernst
  • Date: 2005-11-06 12:40:03 UTC
  • mfrom: (1.1.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20051106124003-3pgs7tcg5rox96xg
Tags: 2.37a-1.1
* Non-maintainer upload.
* Split out parts of 01_SConstruct_debian.dpatch again: root_build_dir
  really needs to get adjusted before the clean target runs - closes: #333958,
  see #288882 for reference

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/**
2
 
 * $Id: view.c,v 1.25 2004/04/07 16:09:22 ton Exp $
 
2
 * $Id: view.c,v 1.46 2005/06/05 13:50:21 theeth Exp $
3
3
 *
4
4
 * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
5
5
 *
41
41
 
42
42
#ifdef WIN32
43
43
#include <io.h>
44
 
#include "BLI_winstuff.h"
45
44
#else
46
45
#include <unistd.h>
47
46
#endif   
76
75
#include "BSE_drawview.h"       /* For inner_play_anim_loop */
77
76
 
78
77
#include "BDR_drawobject.h"     /* For draw_object */
 
78
#include "BDR_editface.h"       /* For minmax_tface */
79
79
 
80
80
#include "mydevice.h"
81
81
#include "blendef.h"
82
82
 
83
83
/* Modules used */
84
 
#include "render.h"
 
84
#include "render.h"             /* R. stuff for ogl view render */
85
85
 
86
86
#define TRACKBALLSIZE  (1.1)
87
87
#define BL_NEAR_CLIP 0.001
88
88
 
 
89
 
 
90
/* local prototypes ----------*/
 
91
void setcameratoview3d(void); /* windows.c & toets.c */
 
92
 
89
93
void persp_general(int a)
90
94
{
91
95
        /* for all window types, not 3D */
174
178
        Mat4MulVec4fl(G.vd->persmat, vec4);
175
179
 
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]);
178
182
                
179
183
                if( fx>0 && fx<curarea->winx) {
180
184
                
181
 
                        fy= (curarea->winy/2)+(curarea->winy/2)*vec4[1]/vec4[3];
 
185
                        fy= (curarea->winy/2)*(1 + vec4[1]/vec4[3]);
182
186
                        
183
187
                        if(fy>0.0 && fy< (float)curarea->winy) {
184
 
                                adr[0]= floor(fx+0.5); 
185
 
                                adr[1]= floor(fy+0.5);
 
188
                                adr[0]= floor(fx); 
 
189
                                adr[1]= floor(fy);
 
190
                        }
 
191
                }
 
192
        }
 
193
}
 
194
 
 
195
void project_int(float *vec, int *adr)
 
196
{
 
197
        float fx, fy, vec4[4];
 
198
 
 
199
        adr[0]= 2140000000.0f;
 
200
        VECCOPY(vec4, vec);
 
201
        vec4[3]= 1.0;
 
202
        
 
203
        Mat4MulVec4fl(G.vd->persmat, vec4);
 
204
 
 
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]);
 
207
                
 
208
                if( fx>-2140000000.0f && fx<2140000000.0f) {
 
209
                        fy= (curarea->winy/2)*(1 + vec4[1]/vec4[3]);
 
210
                        
 
211
                        if(fy>-2140000000.0f && fy<2140000000.0f) {
 
212
                                adr[0]= floor(fx); 
 
213
                                adr[1]= floor(fy);
186
214
                        }
187
215
                }
188
216
        }
199
227
        Mat4MulVec4fl(G.vd->persmat, vec4);
200
228
 
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]);
203
231
                
204
232
                if( fx>-32700 && fx<32700) {
205
233
                
206
 
                        fy= (curarea->winy/2)+(curarea->winy/2)*vec4[1]/vec4[3];
 
234
                        fy= (curarea->winy/2)*(1 + vec4[1]/vec4[3]);
207
235
                        
208
236
                        if(fy>-32700.0 && fy<32700.0) {
209
 
                                adr[0]= floor(fx+0.5); 
210
 
                                adr[1]= floor(fy+0.5);
 
237
                                adr[0]= floor(fx); 
 
238
                                adr[1]= floor(fy);
211
239
                        }
212
240
                }
213
241
        }
405
433
void viewmove(int mode)
406
434
{
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;
409
437
        int firsttime=1;
410
438
        short mvalball[2], mval[2], mvalo[2];
411
439
        
412
440
        /* sometimes this routine is called from headerbuttons */
413
441
        areawinset(curarea->win);
414
 
        curarea->head_swap= 0;
415
442
        
416
443
        initgrabz(-G.vd->ofs[0], -G.vd->ofs[1], -G.vd->ofs[2]);
417
444
        
420
447
        getmouseco_sc(mvalo);           /* work with screen coordinates because of trackball function */
421
448
        mvalball[0]= mvalo[0];                  /* needed for turntable to work */
422
449
        mvalball[1]= mvalo[1];
 
450
        dist0= G.vd->dist;
423
451
        
424
452
        calctrackballvec(&curarea->winrct, mvalo, firstvec);
425
453
 
428
456
        while(TRUE) {
429
457
                getmouseco_sc(mval);
430
458
                
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)) {
432
461
                        
433
462
                        if(firsttime) {
 
463
                                
434
464
                                firsttime= 0;
435
465
                                /* are we translating, rotating or zooming? */
436
466
                                if(mode==0) {
447
477
 
448
478
 
449
479
                        if(mode==0) {   /* view rotate */
450
 
                        
451
 
                                /* if turntable method, we don't change mvalball[0] */
452
 
                        
453
 
                                if(U.flag & USER_TRACKBALL) mvalball[0]= mval[0];
 
480
                                if (U.uiflag & USER_AUTOPERSP) G.vd->persp= 1;
 
481
 
 
482
                                if (U.flag & USER_TRACKBALL) mvalball[0]= mval[0];
454
483
                                mvalball[1]= mval[1];
455
484
                                
456
485
                                calctrackballvec(&curarea->winrct, mvalball, newvec);
459
488
                                
460
489
                                si= sqrt(dvec[0]*dvec[0]+ dvec[1]*dvec[1]+ dvec[2]*dvec[2]);
461
490
                                si/= (2.0*TRACKBALLSIZE);
462
 
                                
463
 
                                /* is there an acceptable solution? (180 degrees limitor) */
464
 
                                if(si<1.0) {
 
491
                        
 
492
                                if (U.flag & USER_TRACKBALL) {
465
493
                                        Crossf(q1+1, firstvec, newvec);
466
 
 
 
494
        
467
495
                                        Normalise(q1+1);
468
 
                
469
 
                                        phi= asin(si);
470
496
        
 
497
                                        /* Allow for rotation beyond the interval
 
498
                                         * [-pi, pi] */
 
499
                                        while (si > 1.0)
 
500
                                                si -= 2.0;
 
501
                
 
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
 
506
                                         * dragged. */
 
507
                                        phi = si * M_PI / 2.0;
 
508
                
471
509
                                        si= sin(phi);
472
510
                                        q1[0]= cos(phi);
473
511
                                        q1[1]*= si;
474
512
                                        q1[2]*= si;
475
 
                                        q1[3]*= si;
476
 
                                        
 
513
                                        q1[3]*= si;                                             
477
514
                                        QuatMul(G.vd->viewquat, q1, oldquat);
478
 
 
479
 
                                        if( (U.flag & USER_TRACKBALL)==0 ) {
480
 
                                        
481
 
                                                /* rotate around z-axis (mouse x moves)  */
482
 
                                                
483
 
                                                phi= 2*(mval[0]-mvalball[0]);
484
 
                                                phi/= (float)curarea->winx;
485
 
                                                si= sin(phi);
486
 
                                                q1[0]= cos(phi);
487
 
                                                q1[1]= q1[2]= 0.0;
488
 
                                                q1[3]= si;
489
 
                                                
490
 
                                                QuatMul(G.vd->viewquat, G.vd->viewquat, q1);
491
 
                                        }
 
515
                                } else {
 
516
                                        /* New turntable view code by John Aughey */
 
517
 
 
518
                                        float m[3][3];
 
519
                                        float m_inv[3][3];
 
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;
 
526
 
 
527
                                        /* Get the 3x3 matrix and its inverse from the quaternion */
 
528
                                        QuatToMat3(G.vd->viewquat, m);
 
529
                                        Mat3Inv(m_inv,m);
 
530
 
 
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);
 
534
 
 
535
                                        /* Perform the up/down rotation */
 
536
                                        phi = sensitivity * -(mval[1] - mvalo[1]);
 
537
                                        si = sin(phi);
 
538
                                        q1[0] = cos(phi);
 
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);
 
543
 
 
544
                                        /* Perform the orbital rotation */
 
545
                                        phi = sensitivity * (mval[0] - mvalo[0]);
 
546
                                        q1[0] = cos(phi);
 
547
                                        q1[1] = q1[2] = 0.0;
 
548
                                        q1[3] = sin(phi);
 
549
                                        QuatMul(G.vd->viewquat, G.vd->viewquat, q1);
492
550
                                }
493
551
                        }
494
552
                        else if(mode==1) {      /* translate */
509
567
                                }
510
568
                        }
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) {
 
571
                                        // oldstyle zoom
 
572
                                        G.vd->dist*= 1.0+(float)(mvalo[0]-mval[0]+mvalo[1]-mval[1])/1000.0;
 
573
                                }
 
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
 
577
                                        
 
578
                                        ctr[0] = (curarea->winrct.xmax + curarea->winrct.xmin)/2;
 
579
                                        ctr[1] = (curarea->winrct.ymax + curarea->winrct.ymin)/2;
 
580
                                        
 
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;
 
583
                                        
 
584
                                        G.vd->dist= dist0 * ((float)len2/len1);
 
585
                                }
 
586
                                else {  /* USER_ZOOM_DOLLY */
 
587
                                        float len1 = (curarea->winrct.ymax - mval[1]) + 5;
 
588
                                        float len2 = (curarea->winrct.ymax - mvalo[1]) + 5;
 
589
                                        
 
590
                                        G.vd->dist= dist0 * (2.0*((len2/len1)-1.0) + 1.0);
 
591
                                }
513
592
                                
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;
517
596
                                
518
 
                                mval[1]= mvalo[1]; /* keeps zooming that way */
 
597
                                mval[1]= mvalo[1]; /* preserve first value */
519
598
                                mval[0]= mvalo[0];
520
599
                        }
521
600
                        
529
608
                        screen_swapbuffers();
530
609
                }
531
610
                else {
 
611
                        short val;
 
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);
 
615
                        
532
616
                        BIF_wait_for_statechange();
533
617
                }
534
618
                
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;
537
621
        }
538
 
 
539
 
        curarea->head_swap= WIN_FRONT_OK;
540
622
}
541
623
 
542
624
short v3d_windowmode=0;
543
625
 
 
626
/* important to not set windows active in here, can be renderwin for example */
544
627
void setwinmatrixview3d(rctf *rect)             /* rect: for picking */
545
628
{
546
629
        Camera *cam=0;
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;
549
632
        short orth;
550
633
        
551
634
        lens= G.vd->lens;       
574
657
                                lens= cam->lens;
575
658
                                near= cam->clipsta;
576
659
                                far= cam->clipend;
577
 
                                
578
 
                                if(cam->type==CAM_ORTHO) {
579
 
                                        lens*= 100.0;
580
 
                                        near= (near+1.0)*100.0; /* otherwise zbuffer troubles. a Patch! */
581
 
                                        far*= 100.0;
582
 
                                }
583
660
                        }
584
661
                }
585
662
        }
586
663
        
587
 
        if(v3d_windowmode) {
 
664
        if(v3d_windowmode) { // hackish
588
665
                winx= R.rectx;
589
666
                winy= R.recty;
590
667
        }
593
670
                winy= curarea->winy;
594
671
        }
595
672
        
596
 
        if(winx>winy) d= 0.015625*winx*lens;
597
 
        else d= 0.015625*winy*lens;
598
 
        
599
 
        dfac= near/d;
600
 
 
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;
604
 
                
605
676
                x2= -x1;
606
677
 
607
678
                if(winx>winy) y1= -winy*G.vd->dist/winx;
608
679
                else y1= -G.vd->dist;
 
680
                y2= -y1;
609
681
                
610
 
                y2= -y1;
 
682
                near= -far;
611
683
                orth= 1;
612
684
        }
613
685
        else {
617
689
                }
618
690
                else fac= 2.0;
619
691
                
620
 
                x1= -dfac*(winx/fac);
621
 
                x2= -x1;
622
 
                y1= -dfac*(winy/fac);
623
 
                y2= -y1;
624
 
 
625
 
                orth= 0;
 
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;
 
696
                        
 
697
                        if(winx>winy) x1= -dfac;
 
698
                        else x1= -winx*dfac/winy;
 
699
                        x2= -x1;
 
700
                        
 
701
                        if(winx>winy) y1= -winy*dfac/winx;
 
702
                        else y1= -dfac;
 
703
                        y2= -y1;
 
704
                        orth= 1;
 
705
                }
 
706
                else {
 
707
                        float dfac;
 
708
                        
 
709
                        if(winx>winy) dfac= 64.0/(fac*winx*lens);
 
710
                        else dfac= 64.0/(fac*winy*lens);
 
711
                        
 
712
                        x1= - near*winx*dfac;
 
713
                        x2= -x1;
 
714
                        y1= - near*winy*dfac;
 
715
                        y2= -y1;
 
716
                        orth= 0;
 
717
                }
626
718
        }
627
719
 
628
720
        if(rect) {              /* picking */
641
733
        }
642
734
        else {
643
735
                if(v3d_windowmode) {
644
 
                        if(orth) i_ortho(x1, x2, y1, y2, -far, far, R.winmat);
645
 
                        else {
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);
648
 
                        }
 
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);
649
738
                }
650
739
                else {
651
 
                        if(orth) myortho(x1, x2, y1, y2, -far, far);
652
 
                        else {
653
 
                                if(cam && cam->type==CAM_ORTHO) mywindow(x1, x2, y1, y2, near, far);
654
 
                                else mywindow(x1, x2, y1, y2, near, far);
655
 
                        }
 
740
                        if(orth) myortho(x1, x2, y1, y2, near, far);
 
741
                        else mywindow(x1, x2, y1, y2, near, far);
656
742
                }
657
743
        }
658
744
 
678
764
        Mat3ToQuat(tmat, G.vd->viewquat);
679
765
}
680
766
 
681
 
 
 
767
/* dont set windows active in in here, is used by renderwin too */
682
768
void setviewmatrixview3d()
683
769
{
684
770
        Camera *cam;
691
777
                        
692
778
                        if(G.vd->camera->type==OB_CAMERA) {
693
779
                                cam= G.vd->camera->data;
694
 
                                if(cam->type==CAM_ORTHO) G.vd->viewmat[3][2]*= 100.0;
 
780
                                //if(cam->type==CAM_ORTHO) G.vd->viewmat[3][2]*= 100.0;
695
781
                        }
696
782
                }
697
783
                else {
707
793
        }
708
794
}
709
795
 
710
 
void setcameratoview3d()
 
796
void setcameratoview3d(void)
711
797
{
712
798
        Object *ob;
713
799
        float dvec[3];
738
824
        
739
825
        if(x1==0 && x2==0 && y1==0 && y2==0) {
740
826
                getmouseco_areawin(mval);
741
 
                rect.xmin= mval[0]-7;
742
 
                rect.xmax= mval[0]+7;
743
 
                rect.ymin= mval[1]-7;
744
 
                rect.ymax= mval[1]+7;
 
827
                rect.xmin= mval[0]-12;  // seems to be default value for bones only now
 
828
                rect.xmax= mval[0]+12;
 
829
                rect.ymin= mval[1]-12;
 
830
                rect.ymax= mval[1]+12;
745
831
        }
746
832
        else {
747
833
                rect.xmin= x1;
785
871
        }
786
872
        glPopName();    /* see above (pushname) */
787
873
        hits= glRenderMode(GL_RENDER);
788
 
        if(hits<0) error("Too many objects in selectbuf");
 
874
        if(hits<0) error("Too many objects in select buffer");
789
875
 
790
876
        G.f &= ~G_PICKSEL;
791
877
        setwinmatrixview3d(0);
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;
894
980
        }
895
981
        
903
989
 
904
990
                G.vd->dist= size;
905
991
 
 
992
                // correction for window aspect ratio
 
993
                if(curarea->winy>2 && curarea->winx>2) {
 
994
                        size= (float)curarea->winx/(float)curarea->winy;
 
995
                        if(size<1.0) size= 1.0/size;
 
996
                        G.vd->dist*= size;
 
997
                }
 
998
                
906
999
                if(G.vd->persp>1) {
907
1000
                        G.vd->persp= 1;
908
1001
                        
950
1043
                
951
1044
                ok= 1;
952
1045
        }
 
1046
        else if (G.f & G_FACESELECT) {
 
1047
                minmax_tface(min, max);
 
1048
                ok= 1;
 
1049
        }
953
1050
        else {
954
1051
                base= FIRSTBASE;
955
1052
                while(base) {
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]);
970
1067
        
971
1068
        if(size<=0.01) size= 0.01;
972
1069
        
973
 
        
974
 
 
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;
978
1073
 
979
1074
        G.vd->dist= size;
980
1075
 
 
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;
 
1080
                G.vd->dist*= size;
 
1081
        }
 
1082
        
981
1083
        if(G.vd->persp>1) {
982
1084
                G.vd->persp= 1;
983
 
                
984
1085
        }
985
1086
 
986
1087
        G.vd->cursor[0]= -G.vd->ofs[0];
1078
1179
        afm[0]= (max[0]-min[0]);
1079
1180
        afm[1]= (max[1]-min[1]);
1080
1181
        afm[2]= (max[2]-min[2]);
1081
 
        size= MAX3(afm[0], afm[1], afm[2]);
 
1182
        size= 0.7*MAX3(afm[0], afm[1], afm[2]);
1082
1183
        if(size==0.0) ok= 0;
1083
1184
                
1084
1185
        if(ok) {
1120
1221
 
1121
1222
        v3d->view= 0;
1122
1223
        if (v3d->persp>=2) v3d->persp= 0; /* switch out of camera mode */
1123
 
}
 
 
b'\\ No newline at end of file'
 
1224
}
 
1225