~ubuntu-branches/ubuntu/intrepid/blender/intrepid-updates

« back to all changes in this revision

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

  • Committer: Bazaar Package Importer
  • Author(s): Cyril Brulebois
  • Date: 2008-08-08 02:45:40 UTC
  • mfrom: (12.1.14 intrepid)
  • Revision ID: james.westby@ubuntu.com-20080808024540-kkjp7ekfivzhuw3l
Tags: 2.46+dfsg-4
* Fix python syntax warning in import_dxf.py, which led to nasty output
  in installation/upgrade logs during byte-compilation, using a patch
  provided by the script author (Closes: #492280):
   - debian/patches/45_fix_python_syntax_warning

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/**
2
 
 * $Id: view.c,v 1.69 2006/07/19 11:28:48 ton Exp $
 
2
 * $Id: view.c 14885 2008-05-18 16:00:13Z lukep $
3
3
 *
4
 
 * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
 
4
 * ***** BEGIN GPL LICENSE BLOCK *****
5
5
 *
6
6
 * This program is free software; you can redistribute it and/or
7
7
 * modify it under the terms of the GNU General Public License
8
8
 * as published by the Free Software Foundation; either version 2
9
 
 * of the License, or (at your option) any later version. The Blender
10
 
 * Foundation also sells licenses for use in proprietary software under
11
 
 * the Blender License.  See http://www.blender.org/BL/ for information
12
 
 * about this.
 
9
 * of the License, or (at your option) any later version.
13
10
 *
14
11
 * This program is distributed in the hope that it will be useful,
15
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
29
26
 *
30
27
 * Contributor(s): none yet.
31
28
 *
32
 
 * ***** END GPL/BL DUAL LICENSE BLOCK *****
 
29
 * ***** END GPL LICENSE BLOCK *****
33
30
 */
34
31
 
35
32
#include <math.h>
61
58
#include "DNA_userdef_types.h"
62
59
#include "DNA_view3d_types.h"
63
60
 
 
61
#include "BKE_action.h"
64
62
#include "BKE_anim.h"
65
63
#include "BKE_global.h"
66
64
#include "BKE_main.h"
67
65
#include "BKE_object.h"
 
66
#include "BKE_sculpt.h"
68
67
#include "BKE_utildefines.h"
69
68
 
 
69
#include "BIF_transform.h"
 
70
#include "BIF_editparticle.h"
70
71
#include "BIF_gl.h"
 
72
#include "BIF_previewrender.h"
 
73
#include "BIF_mywindow.h"
 
74
#include "BIF_retopo.h"
71
75
#include "BIF_space.h"
72
 
#include "BIF_mywindow.h"
73
 
#include "BIF_previewrender.h"
74
76
#include "BIF_screen.h"
75
77
#include "BIF_toolbox.h"
76
78
 
80
82
 
81
83
#include "BDR_drawobject.h"     /* For draw_object */
82
84
#include "BDR_editface.h"       /* For minmax_tface */
 
85
#include "BDR_sculptmode.h"
83
86
 
84
87
#include "mydevice.h"
85
88
#include "blendef.h"
 
89
#include "transform.h"
 
90
 
 
91
#include "PIL_time.h" /* smoothview */
 
92
#include <float.h>
86
93
 
87
94
#define TRACKBALLSIZE  (1.1)
88
95
#define BL_NEAR_CLIP 0.001
147
154
         * (accounting for near zero values)
148
155
         * */
149
156
        if (G.vd->zfac < 1.e-6f && G.vd->zfac > -1.e-6f) G.vd->zfac = 1.0f;
 
157
        
 
158
        /* Negative zfac means x, y, z was behind the camera (in perspective).
 
159
         * This gives flipped directions, so revert back to ok default case.
 
160
         */
 
161
        if (G.vd->zfac < 0.0f) G.vd->zfac = 1.0f;
150
162
}
151
163
 
152
164
void window_to_3d(float *vec, short mx, short my)
360
372
        float vec[4], min, max;
361
373
        int a, flag= -1, fl;
362
374
        
363
 
        if(bb==0) return 1;
 
375
        if(bb==NULL) return 1;
 
376
        if(bb->flag & OB_BB_DISABLED) return 1;
364
377
        
365
378
        Mat4MulMat4(mat, obmat, G.vd->persmat);
366
379
 
462
475
        
463
476
        radius= TRACKBALLSIZE;
464
477
        
465
 
        /* normalise x and y */
 
478
        /* normalize x and y */
466
479
        x= (area->xmax + area->xmin)/2 -mval[0];
467
480
        x/= (float)((area->xmax - area->xmin)/2);
468
481
        y= (area->ymax + area->ymin)/2 -mval[1];
504
517
        
505
518
        radius= TRACKBALLSIZE;
506
519
        
507
 
        /* x en y normaliseren */
 
520
        /* x en y normalizeren */
508
521
        x= (area->xmax + area->xmin)/2 -mval[0];
509
522
        x/= (float)((area->xmax - area->xmin)/4);
510
523
        y= (area->ymax + area->ymin)/2 -mval[1];
525
538
 
526
539
}
527
540
 
 
541
 
 
542
// ndof scaling will be moved to user setting.
 
543
// In the mean time this is just a place holder.
 
544
 
 
545
// Note: scaling in the plugin and ghostwinlay.c
 
546
// should be removed. With driver default setting,
 
547
// each axis returns approx. +-200 max deflection.
 
548
 
 
549
// The values I selected are based on the older
 
550
// polling i/f. With event i/f, the sensistivity
 
551
// can be increased for improved response from
 
552
// small deflections of the device input.
 
553
 
 
554
 
 
555
// lukep notes : i disagree on the range.
 
556
// the normal 3Dconnection driver give +/-400
 
557
// on defaut range in other applications
 
558
// and up to +/- 1000 if set to maximum
 
559
// because i remove the scaling by delta,
 
560
// which was a bad idea as it depend of the system
 
561
// speed and os, i changed the scaling values, but 
 
562
// those are still not ok
 
563
 
 
564
 
 
565
float ndof_axis_scale[6] = {
 
566
        +0.01,  // Tx
 
567
        +0.01,  // Tz
 
568
        +0.01,  // Ty
 
569
        +0.0015,        // Rx
 
570
        +0.0015,        // Rz
 
571
        +0.0015 // Ry
 
572
};
 
573
 
 
574
// statics for controlling G.vd->dist corrections.
 
575
// viewmoveNDOF zeros and adjusts G.vd->ofs.
 
576
// viewmove restores based on dz_flag state.
 
577
 
 
578
int dz_flag = 0;
 
579
float m_dist;
 
580
 
 
581
void viewmoveNDOFfly(int mode)
 
582
{
 
583
    int i;
 
584
    float phi;
 
585
    float dval[7];
 
586
        // static fval[6] for low pass filter; device input vector is dval[6]
 
587
        static float fval[6];
 
588
    float tvec[3],rvec[3];
 
589
    float q1[4];
 
590
        float mat[3][3];
 
591
        float upvec[3];
 
592
 
 
593
 
 
594
    /*----------------------------------------------------
 
595
         * sometimes this routine is called from headerbuttons
 
596
     * viewmove needs to refresh the screen
 
597
     */
 
598
        areawinset(curarea->win);
 
599
 
 
600
 
 
601
        // fetch the current state of the ndof device
 
602
        getndof(dval);
 
603
 
 
604
        if (G.vd->ndoffilter)
 
605
                filterNDOFvalues(fval);
 
606
 
 
607
//      for(i=0;i<7;i++) printf("%f ",dval[i]);
 
608
//              printf("\n");
 
609
 
 
610
 
 
611
        // Scale input values
 
612
 
 
613
//      if(dval[6] == 0) return; // guard against divide by zero
 
614
 
 
615
        for(i=0;i<6;i++) {
 
616
 
 
617
                // user scaling
 
618
                dval[i] = dval[i] * ndof_axis_scale[i];
 
619
 
 
620
                // non-linear scaling
 
621
                if(dval[i]<0.0f)
 
622
                        dval[i] = -1.0f * dval[i] * dval[i];
 
623
                else
 
624
                        dval[i] = dval[i] * dval[i];
 
625
        }
 
626
 
 
627
 
 
628
        // low pass filter with zero crossing reset
 
629
 
 
630
        for(i=0;i<6;i++) {
 
631
                if((dval[i] * fval[i]) >= 0)
 
632
                        dval[i] = (fval[i] * 15 + dval[i]) / 16;
 
633
                else
 
634
                        fval[i] = 0;
 
635
        }
 
636
 
 
637
 
 
638
        // force perspective mode. This is a hack and is
 
639
        // incomplete. It doesn't actually effect the view
 
640
        // until the first draw and doesn't update the menu
 
641
        // to reflect persp mode.
 
642
 
 
643
        G.vd->persp = V3D_PERSP;
 
644
 
 
645
 
 
646
        // Correct the distance jump if G.vd->dist != 0
 
647
 
 
648
        // This is due to a side effect of the original
 
649
        // mouse view rotation code. The rotation point is
 
650
        // set a distance in front of the viewport to
 
651
        // make rotating with the mouse look better.
 
652
        // The distance effect is written at a low level
 
653
        // in the view management instead of the mouse
 
654
        // view function. This means that all other view
 
655
        // movement devices must subtract this from their
 
656
        // view transformations.
 
657
 
 
658
        if(G.vd->dist != 0.0) {
 
659
                dz_flag = 1;
 
660
                m_dist = G.vd->dist;
 
661
                upvec[0] = upvec[1] = 0;
 
662
                upvec[2] = G.vd->dist;
 
663
                Mat3CpyMat4(mat, G.vd->viewinv);
 
664
                Mat3MulVecfl(mat, upvec);
 
665
                VecSubf(G.vd->ofs, G.vd->ofs, upvec);
 
666
                G.vd->dist = 0.0;
 
667
        }
 
668
 
 
669
 
 
670
        // Apply rotation
 
671
 
 
672
        rvec[0] = -dval[3];
 
673
        rvec[1] = -dval[4];
 
674
        rvec[2] = dval[5];
 
675
 
 
676
        // rotate device x and y by view z
 
677
 
 
678
        Mat3CpyMat4(mat, G.vd->viewinv);
 
679
        mat[2][2] = 0.0f;
 
680
        Mat3MulVecfl(mat, rvec);
 
681
 
 
682
        // rotate the view
 
683
 
 
684
        phi = Normalize(rvec);
 
685
        if(phi != 0) {
 
686
                VecRotToQuat(rvec,phi,q1);
 
687
                QuatMul(G.vd->viewquat, G.vd->viewquat, q1);
 
688
        }
 
689
 
 
690
 
 
691
        // Apply translation
 
692
 
 
693
        tvec[0] = dval[0];
 
694
        tvec[1] = dval[1];
 
695
        tvec[2] = -dval[2];
 
696
 
 
697
        // the next three lines rotate the x and y translation coordinates
 
698
        // by the current z axis angle
 
699
 
 
700
        Mat3CpyMat4(mat, G.vd->viewinv);
 
701
        mat[2][2] = 0.0f;
 
702
        Mat3MulVecfl(mat, tvec);
 
703
 
 
704
        // translate the view
 
705
 
 
706
        VecSubf(G.vd->ofs, G.vd->ofs, tvec);
 
707
 
 
708
 
 
709
        /*----------------------------------------------------
 
710
     * refresh the screen
 
711
     */
 
712
    scrarea_do_windraw(curarea);
 
713
    screen_swapbuffers();
 
714
 
 
715
        // update render preview window
 
716
 
 
717
        BIF_view3d_previewrender_signal(curarea, PR_DBASE|PR_DISPRECT);
 
718
}
 
719
 
528
720
void viewmove(int mode)
529
721
{
 
722
        static float lastofs[3] = {0,0,0};
530
723
        Object *ob = OBACT;
531
724
        float firstvec[3], newvec[3], dvec[3];
532
725
        float reverse, oldquat[4], q1[4], si, phi, dist0;
533
 
        float ofs[3], obofs[3];
 
726
        float ofs[3], obofs[3]= {0.0f, 0.0f, 0.0f};
534
727
        int firsttime=1;
535
 
        short mvalball[2], mval[2], mvalo[2];
 
728
        short mvalball[2], mval[2], mvalo[2], mval_area[2], mvali[2];
536
729
        short use_sel = 0;
537
730
        short preview3d_event= 1;
538
731
        
539
 
        /* 3D window may not be defined */
 
732
        // locals for dist correction
 
733
        float mat[3][3];
 
734
        float upvec[3];
 
735
 
 
736
                /* 3D window may not be defined */
540
737
        if( !G.vd ) {
541
738
                fprintf( stderr, "G.vd == NULL in viewmove()\n" );
542
739
                return;
543
740
        }
544
 
 
 
741
        
 
742
                // dist correction from other movement devices
 
743
                
 
744
        if((dz_flag)||G.vd->dist==0) {
 
745
                dz_flag = 0;
 
746
                G.vd->dist = m_dist;
 
747
                upvec[0] = upvec[1] = 0;
 
748
                upvec[2] = G.vd->dist;
 
749
                Mat3CpyMat4(mat, G.vd->viewinv);
 
750
                Mat3MulVecfl(mat, upvec);
 
751
                VecAddf(G.vd->ofs, G.vd->ofs, upvec);
 
752
        }
 
753
 
 
754
 
 
755
                
545
756
        /* sometimes this routine is called from headerbuttons */
546
757
 
547
758
        areawinset(curarea->win);
550
761
        
551
762
        QUATCOPY(oldquat, G.vd->viewquat);
552
763
        
553
 
        getmouseco_sc(mvalo);           /* work with screen coordinates because of trackball function */
554
 
        mvalball[0]= mvalo[0];                  /* needed for turntable to work */
555
 
        mvalball[1]= mvalo[1];
 
764
        getmouseco_areawin(mval_area);  /* for zoom to mouse loc */
 
765
        getmouseco_sc(mvali);           /* work with screen coordinates because of trackball function */
 
766
        mvalball[0]= mvalo[0] = mvali[0];                       /* needed for turntable to work */
 
767
        mvalball[1]= mvalo[1] = mvali[1];
556
768
        dist0= G.vd->dist;
557
769
        
558
770
        calctrackballvec(&curarea->winrct, mvalo, firstvec);
559
771
 
560
772
        /* cumultime(0); */
561
773
 
562
 
        if (ob && (U.uiflag & USER_ORBIT_SELECTION)) {
 
774
        if(!G.obedit && (G.f & G_SCULPTMODE) && ob && G.vd->pivot_last) {
 
775
                use_sel= 1;
 
776
                VecCopyf(ofs, G.vd->ofs);
 
777
 
 
778
                VecCopyf(obofs, sculpt_data()->pivot);
 
779
                Mat4MulVecfl(ob->obmat, obofs);
 
780
                obofs[0]= -obofs[0];
 
781
                obofs[1]= -obofs[1];
 
782
                obofs[2]= -obofs[2];
 
783
        }
 
784
        else if (U.uiflag & USER_ORBIT_SELECTION) {
563
785
                use_sel = 1;
 
786
                
564
787
                VECCOPY(ofs, G.vd->ofs);
565
 
 
566
 
                obofs[0] = -ob->obmat[3][0];
567
 
                obofs[1] = -ob->obmat[3][1];
568
 
                obofs[2] = -ob->obmat[3][2];
 
788
                
 
789
                /* If there's no selection, lastofs is unmodified and last value since static */
 
790
                calculateTransformCenter(V3D_CENTROID, lastofs);
 
791
                
 
792
                VECCOPY(obofs, lastofs);
 
793
                VecMulf(obofs, -1.0f);
569
794
        }
570
795
        else
571
796
                ofs[0] = ofs[1] = ofs[2] = 0.0f;
578
803
                getmouseco_sc(mval);
579
804
                
580
805
                // if playanim = alt+A, screenhandlers are for animated UI, python, etc
581
 
                if(mval[0]!=mvalo[0] || mval[1]!=mvalo[1] || (G.f & G_PLAYANIM) || do_screenhandlers(G.curscreen)) {
 
806
                if(             (mode==2 && U.viewzoom==USER_ZOOM_CONT) || /* continues zoom always update */
 
807
                                mval[0]!=mvalo[0] || mval[1]!=mvalo[1] || /* mouse moved, so update */
 
808
                                (G.f & G_PLAYANIM) || do_screenhandlers(G.curscreen)
 
809
                        ) {
582
810
                        
583
811
                        if(firsttime) {
584
812
                                
588
816
                                        if(G.vd->view!=0) scrarea_queue_headredraw(curarea);    /*for button */
589
817
                                        G.vd->view= 0;
590
818
                                }
591
 
                                if(G.vd->persp==2 && mode!=1) {
592
 
                                        float upvec[3]={0,0,0}; /* the view vector */
593
 
                                        float mat[3][3]; /* view matrix 3x3 to rotate the upvec */
594
 
                                        where_is_object(G.vd->camera);
595
 
                                        VecCopyf(G.vd->ofs, G.vd->camera->obmat[3]);
596
 
                                        VecMulf(G.vd->ofs, -1.0f); /*flip the vector*/
597
 
                                        
598
 
                                        upvec[2]= G.vd->dist;
599
 
                                        Mat3CpyMat4(mat, G.vd->viewinv);
600
 
                                        Mat3MulVecfl(mat, upvec);
601
 
                                        VecAddf(G.vd->ofs, G.vd->ofs, upvec);
602
 
                                        
603
 
                                        G.vd->persp= 1;
 
819
                                if(G.vd->persp==V3D_CAMOB && mode!=1 && G.vd->camera) {
 
820
                                        G.vd->persp= V3D_PERSP;
604
821
                                        scrarea_do_windraw(curarea);
605
822
                                        scrarea_queue_headredraw(curarea);
606
823
                                }
607
824
                        }
608
825
 
609
826
                        if(mode==0) {   /* view rotate */
610
 
                                if (U.uiflag & USER_AUTOPERSP) G.vd->persp= 1;
 
827
                                if (U.uiflag & USER_AUTOPERSP) G.vd->persp= V3D_PERSP;
611
828
 
612
829
                                if (U.flag & USER_TRACKBALL) mvalball[0]= mval[0];
613
830
                                mvalball[1]= mval[1];
622
839
                                if (U.flag & USER_TRACKBALL) {
623
840
                                        Crossf(q1+1, firstvec, newvec);
624
841
        
625
 
                                        Normalise(q1+1);
 
842
                                        Normalize(q1+1);
626
843
        
627
844
                                        /* Allow for rotation beyond the interval
628
845
                                         * [-pi, pi] */
707
924
                                }
708
925
                        }
709
926
                        else if(mode==1) {      /* translate */
710
 
                                if(G.vd->persp==2) {
 
927
                                if(G.vd->persp==V3D_CAMOB) {
711
928
                                        float max= (float)MAX2(curarea->winx, curarea->winy);
712
929
 
713
930
                                        G.vd->camdx += (mvalo[0]-mval[0])/(max);
722
939
                                }
723
940
                        }
724
941
                        else if(mode==2) {
 
942
                                float zfac=1.0;
 
943
 
 
944
                                /* use initial value (do not use mvalo (that is used to detect mouse moviments)) */
 
945
                                mvalo[0] = mvali[0];
 
946
                                mvalo[1] = mvali[1];
 
947
                                
725
948
                                if(U.viewzoom==USER_ZOOM_CONT) {
726
949
                                        // oldstyle zoom
727
 
                                        G.vd->dist*= 1.0+(float)(mvalo[0]-mval[0]+mvalo[1]-mval[1])/1000.0;
 
950
                                        zfac = 1.0+(float)(mvalo[0]-mval[0]+mvalo[1]-mval[1])/1000.0;
728
951
                                }
729
952
                                else if(U.viewzoom==USER_ZOOM_SCALE) {
730
953
                                        int ctr[2], len1, len2;
736
959
                                        len1 = (int)sqrt((ctr[0] - mval[0])*(ctr[0] - mval[0]) + (ctr[1] - mval[1])*(ctr[1] - mval[1])) + 5;
737
960
                                        len2 = (int)sqrt((ctr[0] - mvalo[0])*(ctr[0] - mvalo[0]) + (ctr[1] - mvalo[1])*(ctr[1] - mvalo[1])) + 5;
738
961
                                        
739
 
                                        G.vd->dist= dist0 * ((float)len2/len1);
 
962
                                        zfac = dist0 * ((float)len2/len1) / G.vd->dist;
740
963
                                }
741
964
                                else {  /* USER_ZOOM_DOLLY */
742
965
                                        float len1 = (curarea->winrct.ymax - mval[1]) + 5;
743
966
                                        float len2 = (curarea->winrct.ymax - mvalo[1]) + 5;
744
 
                                        
745
 
                                        G.vd->dist= dist0 * (2.0*((len2/len1)-1.0) + 1.0);
 
967
                                        zfac = dist0 * (2.0*((len2/len1)-1.0) + 1.0) / G.vd->dist;
746
968
                                }
 
969
 
 
970
                                if(zfac != 1.0 && zfac*G.vd->dist > 0.001*G.vd->grid && 
 
971
                                        zfac*G.vd->dist < 10.0*G.vd->far)
 
972
                                        view_zoom_mouseloc(zfac, mval_area);
747
973
                                
748
974
                                /* these limits are in toets.c too */
749
975
                                if(G.vd->dist<0.001*G.vd->grid) G.vd->dist= 0.001*G.vd->grid;
750
976
                                if(G.vd->dist>10.0*G.vd->far) G.vd->dist=10.0*G.vd->far;
751
977
                                
752
 
                                mval[1]= mvalo[1]; /* preserve first value */
753
 
                                mval[0]= mvalo[0];
754
 
                                
755
 
                                if(G.vd->persp==0 || G.vd->persp==2) preview3d_event= 0;
 
978
                                if(G.vd->persp==V3D_ORTHO || G.vd->persp==V3D_CAMOB) preview3d_event= 0;
756
979
                        }
757
980
                        
 
981
                        
 
982
                        
758
983
                        mvalo[0]= mval[0];
759
984
                        mvalo[1]= mval[1];
760
985
 
761
986
                        if(G.f & G_PLAYANIM) inner_play_anim_loop(0, 0);
762
987
                        if(G.f & G_SIMULATION) break;
763
988
 
 
989
                        /* If in retopo paint mode, update lines */
 
990
                        if(retopo_mesh_paint_check() && G.vd->retopo_view_data) {
 
991
                                G.vd->retopo_view_data->queue_matrix_update= 1;
 
992
                                retopo_paint_view_update(G.vd);
 
993
                        }
 
994
 
764
995
                        scrarea_do_windraw(curarea);
765
996
                        screen_swapbuffers();
766
997
                }
777
1008
                if( !(get_mbut() & (L_MOUSE|M_MOUSE))) break;
778
1009
        }
779
1010
 
 
1011
        if(G.vd->depths) G.vd->depths->damaged= 1;
 
1012
        retopo_queue_updates(G.vd);
 
1013
        allqueue(REDRAWVIEW3D, 0);
 
1014
 
780
1015
        if(preview3d_event) 
781
1016
                BIF_view3d_previewrender_signal(curarea, PR_DBASE|PR_DISPRECT);
782
1017
        else
783
1018
                BIF_view3d_previewrender_signal(curarea, PR_PROJECTED);
784
1019
 
785
1020
}
786
 
 
787
 
int get_view3d_viewplane(int winxi, int winyi, rctf *viewplane, float *clipsta, float *clipend)
 
1021
 
 
1022
void view_zoom_mouseloc(float dfac, short *mouseloc)
 
1023
{
 
1024
        if(U.uiflag & USER_ZOOM_TO_MOUSEPOS) {
 
1025
                short vb[2];
 
1026
                float dvec[3];
 
1027
                float tvec[3];
 
1028
                float tpos[3];
 
1029
                float new_dist;
 
1030
 
 
1031
                /* find the current window width and height */
 
1032
                vb[0] = G.vd->area->winx;
 
1033
                vb[1] = G.vd->area->winy;
 
1034
                
 
1035
                tpos[0] = -G.vd->ofs[0];
 
1036
                tpos[1] = -G.vd->ofs[1];
 
1037
                tpos[2] = -G.vd->ofs[2];
 
1038
 
 
1039
                /* Project cursor position into 3D space */
 
1040
                initgrabz(tpos[0], tpos[1], tpos[2]);
 
1041
                window_to_3d(dvec, mouseloc[0]-vb[0]/2, mouseloc[1]-vb[1]/2);
 
1042
 
 
1043
                /* Calculate view target position for dolly */
 
1044
                tvec[0] = -(tpos[0] + dvec[0]);
 
1045
                tvec[1] = -(tpos[1] + dvec[1]);
 
1046
                tvec[2] = -(tpos[2] + dvec[2]);
 
1047
 
 
1048
                /* Offset to target position and dolly */
 
1049
                new_dist = G.vd->dist * dfac;
 
1050
                
 
1051
                VECCOPY(G.vd->ofs, tvec);
 
1052
                G.vd->dist = new_dist;
 
1053
                
 
1054
                /* Calculate final offset */
 
1055
                dvec[0] = tvec[0] + dvec[0] * dfac;
 
1056
                dvec[1] = tvec[1] + dvec[1] * dfac;
 
1057
                dvec[2] = tvec[2] + dvec[2] * dfac;
 
1058
                
 
1059
                VECCOPY(G.vd->ofs, dvec);
 
1060
        } else {
 
1061
                G.vd->dist *= dfac;
 
1062
        }
 
1063
}
 
1064
 
 
1065
void viewmoveNDOF(int mode)
 
1066
{
 
1067
    float fval[7];
 
1068
    float dvec[3];
 
1069
    float sbadjust = 1.0f;
 
1070
    float len;
 
1071
        short use_sel = 0;
 
1072
        Object *ob = OBACT;
 
1073
    float m[3][3];
 
1074
    float m_inv[3][3];
 
1075
    float xvec[3] = {1,0,0};
 
1076
    float yvec[3] = {0,-1,0};
 
1077
    float zvec[3] = {0,0,1};
 
1078
        float phi, si;
 
1079
    float q1[4];
 
1080
    float obofs[3];
 
1081
    float reverse;
 
1082
    float diff[4];
 
1083
    float d, curareaX, curareaY;
 
1084
 
 
1085
    /* Sensitivity will control how fast the view rotates.  The value was
 
1086
     * obtained experimentally by tweaking until the author didn't get dizzy watching.
 
1087
     * Perhaps this should be a configurable user parameter. 
 
1088
     */
 
1089
    float psens = 0.005f * (float) U.ndof_pan;   /* pan sensitivity */
 
1090
    float rsens = 0.005f * (float) U.ndof_rotate;  /* rotate sensitivity */
 
1091
    float zsens = 0.3f;   /* zoom sensitivity */
 
1092
 
 
1093
    const float minZoom = -30.0f;
 
1094
    const float maxZoom = 300.0f;
 
1095
 
 
1096
        //reset view type
 
1097
        G.vd->view = 0;
 
1098
//printf("passing here \n");
 
1099
//
 
1100
        if (G.obedit==NULL && ob && !(ob->flag & OB_POSEMODE)) {
 
1101
                use_sel = 1;
 
1102
        }
 
1103
 
 
1104
    /*----------------------------------------------------
 
1105
         * sometimes this routine is called from headerbuttons
 
1106
     * viewmove needs to refresh the screen
 
1107
     */
 
1108
        areawinset(curarea->win);
 
1109
 
 
1110
    /*----------------------------------------------------
 
1111
     * record how much time has passed. clamp at 10 Hz
 
1112
     * pretend the previous frame occured at the clamped time 
 
1113
     */
 
1114
//    now = PIL_check_seconds_timer();
 
1115
 //   frametime = (now - prevTime);
 
1116
 //   if (frametime > 0.1f){        /* if more than 1/10s */
 
1117
 //       frametime = 1.0f/60.0;      /* clamp at 1/60s so no jumps when starting to move */
 
1118
//    }
 
1119
//    prevTime = now;
 
1120
 //   sbadjust *= 60 * frametime;             /* normalize ndof device adjustments to 100Hz for framerate independence */
 
1121
 
 
1122
    /* fetch the current state of the ndof device */
 
1123
    getndof(fval);
 
1124
 //           printf(" motion command %f %f %f %f %f %f %f \n", fval[0], fval[1], fval[2],
 
1125
 //                                                              fval[3], fval[4], fval[5], fval[6]);
 
1126
                        if (G.vd->ndoffilter)
 
1127
                                filterNDOFvalues(fval);
 
1128
        
 
1129
        
 
1130
        // put scaling back here, was previously in ghostwinlay
 
1131
            fval[0] = fval[0]  * (1.0f/800.0f);
 
1132
            fval[1] = fval[1]  * (1.0f/800.0f);
 
1133
            fval[2] = fval[2] * (1.0f/800.0f);
 
1134
            fval[3] = fval[3]  * 0.00005f;
 
1135
            fval[4] = fval[4]  * 0.00005f;
 
1136
            fval[5] = fval[5] * 0.00005f;
 
1137
            fval[6] = fval[6]  / 1000000.0f;
 
1138
                        
 
1139
        // scale more if not in perspective mode
 
1140
                        if (G.vd->persp == V3D_ORTHO) {
 
1141
                                fval[0] = fval[0] * 0.05f;
 
1142
                                fval[1] = fval[1] * 0.05f;
 
1143
                                fval[2] = fval[2] * 0.05f;
 
1144
                                fval[3] = fval[3] * 0.9f;
 
1145
                                fval[4] = fval[4] * 0.9f;
 
1146
                                fval[5] = fval[5] * 0.9f;
 
1147
                                zsens *= 8;
 
1148
                        }
 
1149
                        
 
1150
        
 
1151
    /* set object offset */
 
1152
        if (ob) {
 
1153
                obofs[0] = -ob->obmat[3][0];
 
1154
                obofs[1] = -ob->obmat[3][1];
 
1155
                obofs[2] = -ob->obmat[3][2];
 
1156
        }
 
1157
        else {
 
1158
                VECCOPY(obofs, G.vd->ofs);
 
1159
        }
 
1160
 
 
1161
    /* calc an adjustment based on distance from camera */
 
1162
    if (ob) {
 
1163
        VecSubf(diff, obofs, G.vd->ofs);
 
1164
        d = VecLength(diff);
 
1165
    }
 
1166
    else {
 
1167
        d = 1.0f;
 
1168
    }
 
1169
    reverse = (G.vd->persmat[2][1] < 0.0f) ? -1.0f : 1.0f;
 
1170
 
 
1171
    /*----------------------------------------------------
 
1172
     * ndof device pan 
 
1173
     */
 
1174
    psens *= 1.0f + d;
 
1175
    curareaX = sbadjust * psens * fval[0];
 
1176
    curareaY = sbadjust * psens * fval[1];
 
1177
    dvec[0] = curareaX * G.vd->persinv[0][0] + curareaY * G.vd->persinv[1][0];
 
1178
    dvec[1] = curareaX * G.vd->persinv[0][1] + curareaY * G.vd->persinv[1][1];
 
1179
    dvec[2] = curareaX * G.vd->persinv[0][2] + curareaY * G.vd->persinv[1][2];
 
1180
    VecAddf(G.vd->ofs, G.vd->ofs, dvec);
 
1181
 
 
1182
    /*----------------------------------------------------
 
1183
     * ndof device dolly 
 
1184
     */
 
1185
    len = zsens * sbadjust * fval[2];
 
1186
 
 
1187
    if (G.vd->persp==V3D_CAMOB) {
 
1188
        if(G.vd->persp==V3D_CAMOB) { /* This is stupid, please fix - TODO */
 
1189
            G.vd->camzoom+= 10.0f * -len;
 
1190
        }
 
1191
        if (G.vd->camzoom < minZoom) G.vd->camzoom = minZoom;
 
1192
        else if (G.vd->camzoom > maxZoom) G.vd->camzoom = maxZoom;
 
1193
    }
 
1194
    else if ((G.vd->dist> 0.001*G.vd->grid) && (G.vd->dist<10.0*G.vd->far)) {
 
1195
        G.vd->dist*=(1.0 + len);
 
1196
    }
 
1197
 
 
1198
 
 
1199
    /*----------------------------------------------------
 
1200
     * ndof device turntable
 
1201
     * derived from the turntable code in viewmove
 
1202
     */
 
1203
 
 
1204
    /* Get the 3x3 matrix and its inverse from the quaternion */
 
1205
    QuatToMat3(G.vd->viewquat, m);
 
1206
    Mat3Inv(m_inv,m);
 
1207
 
 
1208
    /* Determine the direction of the x vector (for rotating up and down) */
 
1209
    /* This can likely be compuated directly from the quaternion. */
 
1210
    Mat3MulVecfl(m_inv,xvec);
 
1211
    Mat3MulVecfl(m_inv,yvec);
 
1212
    Mat3MulVecfl(m_inv,zvec);
 
1213
 
 
1214
    /* Perform the up/down rotation */
 
1215
    phi = sbadjust * rsens * /*0.5f * */ fval[3]; /* spin vertically half as fast as horizontally */
 
1216
    si = sin(phi);
 
1217
    q1[0] = cos(phi);
 
1218
    q1[1] = si * xvec[0];
 
1219
    q1[2] = si * xvec[1];
 
1220
    q1[3] = si * xvec[2];
 
1221
    QuatMul(G.vd->viewquat, G.vd->viewquat, q1);
 
1222
 
 
1223
    if (use_sel) {
 
1224
        QuatConj(q1); /* conj == inv for unit quat */
 
1225
        VecSubf(G.vd->ofs, G.vd->ofs, obofs);
 
1226
        QuatMulVecf(q1, G.vd->ofs);
 
1227
        VecAddf(G.vd->ofs, G.vd->ofs, obofs);
 
1228
    }
 
1229
 
 
1230
    /* Perform the orbital rotation */
 
1231
    /* Perform the orbital rotation 
 
1232
       If the seen Up axis is parallel to the zoom axis, rotation should be
 
1233
       achieved with a pure Roll motion (no Spin) on the device. When you start 
 
1234
       to tilt, moving from Top to Side view, Spinning will increasingly become 
 
1235
       more relevant while the Roll component will decrease. When a full 
 
1236
       Side view is reached, rotations around the world's Up axis are achieved
 
1237
       with a pure Spin-only motion.  In other words the control of the spinning
 
1238
       around the world's Up axis should move from the device's Spin axis to the
 
1239
       device's Roll axis depending on the orientation of the world's Up axis 
 
1240
       relative to the screen. */
 
1241
    //phi = sbadjust * rsens * reverse * fval[4];  /* spin the knob, y axis */
 
1242
    phi = sbadjust * rsens * (yvec[2] * fval[4] + zvec[2] * fval[5]);
 
1243
    q1[0] = cos(phi);
 
1244
    q1[1] = q1[2] = 0.0;
 
1245
    q1[3] = sin(phi);
 
1246
    QuatMul(G.vd->viewquat, G.vd->viewquat, q1);
 
1247
 
 
1248
    if (use_sel) {
 
1249
        QuatConj(q1);
 
1250
        VecSubf(G.vd->ofs, G.vd->ofs, obofs);
 
1251
        QuatMulVecf(q1, G.vd->ofs);
 
1252
        VecAddf(G.vd->ofs, G.vd->ofs, obofs);
 
1253
    }
 
1254
 
 
1255
    /*----------------------------------------------------
 
1256
     * refresh the screen
 
1257
     */
 
1258
    scrarea_do_windraw(curarea);
 
1259
    screen_swapbuffers();
 
1260
}
 
1261
 
 
1262
 
 
1263
/* Gets the lens and clipping values from a camera of lamp type object */
 
1264
void object_view_settings(Object *ob, float *lens, float *clipsta, float *clipend)
 
1265
{       
 
1266
        if (!ob) return;
 
1267
        
 
1268
        if(ob->type==OB_LAMP ) {
 
1269
                Lamp *la = ob->data;
 
1270
                if (lens) {
 
1271
                        float x1, fac;
 
1272
                        fac= cos( M_PI*la->spotsize/360.0);
 
1273
                        x1= saacos(fac);
 
1274
                        *lens= 16.0*fac/sin(x1);
 
1275
                }
 
1276
                if (clipsta)    *clipsta= la->clipsta;
 
1277
                if (clipend)    *clipend= la->clipend;
 
1278
        }
 
1279
        else if(ob->type==OB_CAMERA) {
 
1280
                Camera *cam= ob->data;
 
1281
                if (lens)               *lens= cam->lens;
 
1282
                if (clipsta)    *clipsta= cam->clipsta;
 
1283
                if (clipend)    *clipend= cam->clipend;
 
1284
        }
 
1285
}
 
1286
 
 
1287
 
 
1288
int get_view3d_viewplane(int winxi, int winyi, rctf *viewplane, float *clipsta, float *clipend, float *pixsize)
788
1289
{
789
1290
        Camera *cam=NULL;
790
1291
        float lens, fac, x1, y1, x2, y2;
796
1297
        *clipsta= G.vd->near;
797
1298
        *clipend= G.vd->far;
798
1299
 
799
 
        if(G.vd->persp==2) {
800
 
                *clipsta= G.vd->near;
801
 
                *clipend= G.vd->far;
 
1300
/*      
 
1301
 * Cant use this since we need the fac and x1 values set
 
1302
 * if(G.vd->persp==V3D_CAMOB)
 
1303
                object_view_settings(G.vd->camera, &lens, &(*clipsta), &(*clipend));*/
 
1304
        
 
1305
        if(G.vd->persp==V3D_CAMOB) {
802
1306
                if(G.vd->camera) {
803
1307
                        if(G.vd->camera->type==OB_LAMP ) {
804
1308
                                Lamp *la;
821
1325
                }
822
1326
        }
823
1327
        
824
 
        if(G.vd->persp==0) {
 
1328
        if(G.vd->persp==V3D_ORTHO) {
825
1329
                if(winx>winy) x1= -G.vd->dist;
826
1330
                else x1= -winx*G.vd->dist/winy;
827
1331
                x2= -x1;
835
1339
                orth= 1;
836
1340
        }
837
1341
        else {
838
 
                if(G.vd->persp==2) {
 
1342
                /* fac for zoom, also used for camdx */
 
1343
                if(G.vd->persp==V3D_CAMOB) {
839
1344
                        fac= (1.41421+( (float)G.vd->camzoom )/50.0);
840
1345
                        fac*= fac;
841
1346
                }
869
1374
                }
870
1375
                /* cam view offset */
871
1376
                if(cam) {
872
 
                        float dx= G.vd->camdx*(x2-x1);
873
 
                        float dy= G.vd->camdy*(y2-y1);
 
1377
                        float dx= 0.5*fac*G.vd->camdx*(x2-x1);
 
1378
                        float dy= 0.5*fac*G.vd->camdy*(y2-y1);
874
1379
                        x1+= dx;
875
1380
                        x2+= dx;
876
1381
                        y1+= dy;
877
1382
                        y2+= dy;
878
1383
                }
879
1384
        }
 
1385
 
 
1386
        if(pixsize) {
 
1387
                float viewfac;
 
1388
 
 
1389
                if(orth) {
 
1390
                        viewfac= (winx >= winy)? winx: winy;
 
1391
                        *pixsize= 1.0f/viewfac;
 
1392
                }
 
1393
                else {
 
1394
                        viewfac= (((winx >= winy)? winx: winy)*lens)/32.0;
 
1395
                        *pixsize= *clipsta/viewfac;
 
1396
                }
 
1397
        }
880
1398
        
881
1399
        viewplane->xmin= x1;
882
1400
        viewplane->ymin= y1;
893
1411
        float clipsta, clipend, x1, y1, x2, y2;
894
1412
        int orth;
895
1413
        
896
 
        orth= get_view3d_viewplane(winx, winy, &viewplane, &clipsta, &clipend);
 
1414
        orth= get_view3d_viewplane(winx, winy, &viewplane, &clipsta, &clipend, NULL);
897
1415
//      printf("%d %d %f %f %f %f %f %f\n", winx, winy, viewplane.xmin, viewplane.ymin, viewplane.xmax, viewplane.ymax, clipsta, clipend);
898
1416
        x1= viewplane.xmin;
899
1417
        y1= viewplane.ymin;
925
1443
        glMatrixMode(GL_MODELVIEW);
926
1444
}
927
1445
 
928
 
void obmat_to_viewmat(Object *ob)
 
1446
void obmat_to_viewmat(Object *ob, short smooth)
929
1447
{
930
1448
        float bmat[4][4];
931
1449
        float tmat[3][3];
936
1454
        
937
1455
        /* view quat calculation, needed for add object */
938
1456
        Mat3CpyMat4(tmat, G.vd->viewmat);
939
 
        Mat3ToQuat(tmat, G.vd->viewquat);
 
1457
        if (smooth) {
 
1458
                float new_quat[4];
 
1459
                if (G.vd->persp==V3D_CAMOB && G.vd->camera) {
 
1460
                        /* were from a camera view */
 
1461
                        
 
1462
                        float orig_ofs[3];
 
1463
                        float orig_dist= G.vd->dist;
 
1464
                        float orig_lens= G.vd->lens;
 
1465
                        VECCOPY(orig_ofs, G.vd->ofs);
 
1466
                        
 
1467
                        /* Switch from camera view */
 
1468
                        Mat3ToQuat(tmat, new_quat);
 
1469
                        
 
1470
                        G.vd->persp=V3D_PERSP;
 
1471
                        G.vd->dist= 0.0;
 
1472
                        
 
1473
                        view_settings_from_ob(G.vd->camera, G.vd->ofs, NULL, NULL, &G.vd->lens);
 
1474
                        smooth_view(G.vd, orig_ofs, new_quat, &orig_dist, &orig_lens);
 
1475
                        
 
1476
                        G.vd->persp=V3D_CAMOB; /* just to be polite, not needed */
 
1477
                        
 
1478
                } else {
 
1479
                        Mat3ToQuat(tmat, new_quat);
 
1480
                        smooth_view(G.vd, NULL, new_quat, NULL, NULL);
 
1481
                }
 
1482
        } else {
 
1483
                Mat3ToQuat(tmat, G.vd->viewquat);
 
1484
        }
940
1485
}
941
1486
 
942
1487
/* dont set windows active in in here, is used by renderwin too */
943
1488
void setviewmatrixview3d()
944
1489
{
945
 
        Camera *cam;
946
 
 
947
 
        if(G.vd->persp>=2) {        /* obs/camera */
 
1490
        if(G.vd->persp==V3D_CAMOB) {        /* obs/camera */
948
1491
                if(G.vd->camera) {
949
 
                        
950
1492
                        where_is_object(G.vd->camera);  
951
 
                        obmat_to_viewmat(G.vd->camera);
952
 
                        
953
 
                        if(G.vd->camera->type==OB_CAMERA) {
954
 
                                cam= G.vd->camera->data;
955
 
                                //if(cam->type==CAM_ORTHO) G.vd->viewmat[3][2]*= 100.0;
956
 
                        }
 
1493
                        obmat_to_viewmat(G.vd->camera, 0);
957
1494
                }
958
1495
                else {
959
1496
                        QuatToMat4(G.vd->viewquat, G.vd->viewmat);
963
1500
        else {
964
1501
                
965
1502
                QuatToMat4(G.vd->viewquat, G.vd->viewmat);
966
 
                if(G.vd->persp==1) G.vd->viewmat[3][2]-= G.vd->dist;
967
 
                i_translate(G.vd->ofs[0], G.vd->ofs[1], G.vd->ofs[2], G.vd->viewmat);
 
1503
                if(G.vd->persp==V3D_PERSP) G.vd->viewmat[3][2]-= G.vd->dist;
 
1504
                if(G.vd->ob_centre) {
 
1505
                        Object *ob= G.vd->ob_centre;
 
1506
                        float vec[3];
 
1507
                        
 
1508
                        VECCOPY(vec, ob->obmat[3]);
 
1509
                        if(ob->type==OB_ARMATURE && G.vd->ob_centre_bone[0]) {
 
1510
                                bPoseChannel *pchan= get_pose_channel(ob->pose, G.vd->ob_centre_bone);
 
1511
                                if(pchan) {
 
1512
                                        VECCOPY(vec, pchan->pose_mat[3]);
 
1513
                                        Mat4MulVecfl(ob->obmat, vec);
 
1514
                                }
 
1515
                        }
 
1516
                        i_translate(-vec[0], -vec[1], -vec[2], G.vd->viewmat);
 
1517
                }
 
1518
                else i_translate(G.vd->ofs[0], G.vd->ofs[1], G.vd->ofs[2], G.vd->viewmat);
968
1519
        }
969
1520
}
970
1521
 
980
1531
        VECCOPY(ob->loc, dvec);
981
1532
        VecSubf(ob->loc, ob->loc, G.vd->ofs);
982
1533
        G.vd->viewquat[0]= -G.vd->viewquat[0];
983
 
        if (ob->transflag & OB_QUAT) {
 
1534
        /*  */
 
1535
        /*if (ob->transflag & OB_QUAT) {
984
1536
                QUATCOPY(ob->quat, G.vd->viewquat);
985
 
        } else {
 
1537
        } else {*/
986
1538
                QuatToEul(G.vd->viewquat, ob->rot);
987
 
        }
 
1539
        /*}*/
988
1540
        G.vd->viewquat[0]= -G.vd->viewquat[0];
989
1541
}
990
1542
 
991
1543
/* IGLuint-> GLuint*/
 
1544
/* Warning: be sure to account for a negative return value
 
1545
 *   This is an error, "Too many objects in select buffer"
 
1546
 *   and no action should be taken (can crash blender) if this happens
 
1547
 */
992
1548
short  view3d_opengl_select(unsigned int *buffer, unsigned int bufsize, short x1, short y1, short x2, short y2)
993
1549
{
994
1550
        rctf rect;
1040
1596
                G.vd->xray= TRUE;       // otherwise it postpones drawing
1041
1597
                for(base= G.scene->base.first; base; base= base->next) {
1042
1598
                        if(base->lay & G.vd->lay) {
1043
 
                                base->selcol= code;
1044
 
                                glLoadName(code);
1045
 
                                draw_object(base, DRAW_PICKING|DRAW_CONSTCOLOR);
1046
1599
                                
1047
 
                                /* we draw group-duplicators for selection too */
1048
 
                                if((base->object->transflag & OB_DUPLI) && base->object->dup_group) {
1049
 
                                        ListBase *lb;
1050
 
                                        DupliObject *dob;
1051
 
                                        Base tbase;
1052
 
                                        
1053
 
                                        tbase.flag= OB_FROMDUPLI;
1054
 
                                        lb= object_duplilist(G.scene, base->object);
1055
 
                                        
1056
 
                                        for(dob= lb->first; dob; dob= dob->next) {
1057
 
                                                tbase.object= dob->ob;
1058
 
                                                Mat4CpyMat4(dob->ob->obmat, dob->mat);
1059
 
                                                
1060
 
                                                draw_object(&tbase, DRAW_PICKING|DRAW_CONSTCOLOR);
1061
 
                                                
1062
 
                                                Mat4CpyMat4(dob->ob->obmat, dob->omat);
 
1600
                                if (base->object->restrictflag & OB_RESTRICT_SELECT)
 
1601
                                        base->selcol= 0;
 
1602
                                else {
 
1603
                                        base->selcol= code;
 
1604
                                        glLoadName(code);
 
1605
                                        draw_object(base, DRAW_PICKING|DRAW_CONSTCOLOR);
 
1606
                                        
 
1607
                                        /* we draw group-duplicators for selection too */
 
1608
                                        if((base->object->transflag & OB_DUPLI) && base->object->dup_group) {
 
1609
                                                ListBase *lb;
 
1610
                                                DupliObject *dob;
 
1611
                                                Base tbase;
 
1612
                                                
 
1613
                                                tbase.flag= OB_FROMDUPLI;
 
1614
                                                lb= object_duplilist(G.scene, base->object);
 
1615
                                                
 
1616
                                                for(dob= lb->first; dob; dob= dob->next) {
 
1617
                                                        tbase.object= dob->ob;
 
1618
                                                        Mat4CpyMat4(dob->ob->obmat, dob->mat);
 
1619
                                                        
 
1620
                                                        draw_object(&tbase, DRAW_PICKING|DRAW_CONSTCOLOR);
 
1621
                                                        
 
1622
                                                        Mat4CpyMat4(dob->ob->obmat, dob->omat);
 
1623
                                                }
 
1624
                                                free_object_duplilist(lb);
1063
1625
                                        }
1064
 
                                        free_object_duplilist(lb);
1065
 
                                }
1066
 
                                
1067
 
                                code++;
 
1626
                                        code++;
 
1627
                                }                               
1068
1628
                        }
1069
1629
                }
1070
1630
                G.vd->xray= FALSE;      // restore
1072
1632
        
1073
1633
        glPopName();    /* see above (pushname) */
1074
1634
        hits= glRenderMode(GL_RENDER);
1075
 
        if(hits<0) error("Too many objects in select buffer");
1076
1635
 
1077
1636
        G.f &= ~G_PICKSEL;
1078
1637
        setwinmatrixview3d(curarea->winx, curarea->winy, NULL);
1086
1645
        
1087
1646
        if(G.vd->flag & V3D_CLIPPING)
1088
1647
                view3d_clr_clipping();
1089
 
 
 
1648
        
 
1649
        if(hits<0) error("Too many objects in select buffer");
 
1650
        
1090
1651
        return hits;
1091
1652
}
1092
1653
 
1145
1706
 
1146
1707
        if(G.vd->localvd) return;
1147
1708
 
1148
 
        min[0]= min[1]= min[2]= 1.0e10;
1149
 
        max[0]= max[1]= max[2]= -1.0e10;
 
1709
        INIT_MINMAX(min, max);
1150
1710
 
1151
1711
        locallay= free_localbit();
1152
1712
 
1200
1760
                        G.vd->dist*= size;
1201
1761
                }
1202
1762
                
1203
 
                if(G.vd->persp>1) {
1204
 
                        G.vd->persp= 1;
1205
 
                        
1206
 
                }
1207
 
                G.vd->near= 0.1;
 
1763
                if (G.vd->persp==V3D_CAMOB) G.vd->persp= V3D_PERSP;
 
1764
                if (G.vd->near> 0.1) G.vd->near= 0.1;
 
1765
                
1208
1766
                G.vd->cursor[0]= -G.vd->ofs[0];
1209
1767
                G.vd->cursor[1]= -G.vd->ofs[1];
1210
1768
                G.vd->cursor[2]= -G.vd->ofs[2];
1215
1773
                scrarea_queue_winredraw(curarea);
1216
1774
        }
1217
1775
        else {
1218
 
                /* clear flags */
 
1776
                /* clear flags */ 
1219
1777
                base= FIRSTBASE;
1220
1778
                while(base) {
1221
1779
                        if( base->lay & locallay ) {
1233
1791
        BIF_view3d_previewrender_signal(curarea, PR_DBASE|PR_DISPRECT);
1234
1792
}
1235
1793
 
1236
 
void centreview()       /* like a localview without local! */
 
1794
void centerview()       /* like a localview without local! */
1237
1795
{
1238
1796
        Object *ob= OBACT;
1239
1797
        float size, min[3], max[3], afm[3];
1240
1798
        int ok=0;
1241
 
 
1242
 
        min[0]= min[1]= min[2]= 1.0e10;
1243
 
        max[0]= max[1]= max[2]= -1.0e10;
 
1799
        
 
1800
        /* SMOOTHVIEW */
 
1801
        float new_ofs[3];
 
1802
        float new_dist;
 
1803
        
 
1804
        INIT_MINMAX(min, max);
1244
1805
 
1245
1806
        if (G.f & G_WEIGHTPAINT) {
1246
1807
                /* hardcoded exception, we look for the one selected armature */
1259
1820
        
1260
1821
        
1261
1822
        if(G.obedit) {
1262
 
                minmax_verts(min, max); // ony selected
1263
 
                ok= 1;
 
1823
                ok = minmax_verts(min, max);    /* only selected */
1264
1824
        }
1265
1825
        else if(ob && (ob->flag & OB_POSEMODE)) {
1266
1826
                if(ob->pose) {
1283
1843
                        }
1284
1844
                }
1285
1845
        }
1286
 
        else if (G.f & G_FACESELECT) {
1287
 
                minmax_tface(min, max);
1288
 
                ok= 1;
 
1846
        else if (FACESEL_PAINT_TEST) {
 
1847
                ok= minmax_tface(min, max);
 
1848
        }
 
1849
        else if (G.f & G_PARTICLEEDIT) {
 
1850
                ok= PE_minmax(min, max);
1289
1851
        }
1290
1852
        else {
1291
1853
                Base *base= FIRSTBASE;
1292
1854
                while(base) {
1293
1855
                        if TESTBASE(base)  {
1294
1856
                                minmax_object(base->object, min, max);
 
1857
                                /* account for duplis */
 
1858
                                minmax_object_duplis(base->object, min, max);
 
1859
                                
1295
1860
                                ok= 1;
1296
1861
                        }
1297
1862
                        base= base->next;
1305
1870
        afm[2]= (max[2]-min[2]);
1306
1871
        size= 0.7*MAX3(afm[0], afm[1], afm[2]);
1307
1872
        
1308
 
        if(size<=0.01) size= 0.01;
1309
 
        
1310
 
        G.vd->ofs[0]= -(min[0]+max[0])/2.0;
1311
 
        G.vd->ofs[1]= -(min[1]+max[1])/2.0;
1312
 
        G.vd->ofs[2]= -(min[2]+max[2])/2.0;
1313
 
 
1314
 
        G.vd->dist= size;
1315
 
 
1316
 
        // correction for window aspect ratio
 
1873
        if(size <= G.vd->near*1.5) size= G.vd->near*1.5;
 
1874
        
 
1875
        new_ofs[0]= -(min[0]+max[0])/2.0;
 
1876
        new_ofs[1]= -(min[1]+max[1])/2.0;
 
1877
        new_ofs[2]= -(min[2]+max[2])/2.0;
 
1878
        
 
1879
        new_dist = size;
 
1880
 
 
1881
        /* correction for window aspect ratio */
1317
1882
        if(curarea->winy>2 && curarea->winx>2) {
1318
1883
                size= (float)curarea->winx/(float)curarea->winy;
1319
1884
                if(size<1.0) size= 1.0/size;
1320
 
                G.vd->dist*= size;
1321
 
        }
1322
 
        
1323
 
        if(G.vd->persp>1) {
1324
 
                G.vd->persp= 1;
1325
 
        }
1326
 
 
1327
 
        G.vd->cursor[0]= -G.vd->ofs[0];
1328
 
        G.vd->cursor[1]= -G.vd->ofs[1];
1329
 
        G.vd->cursor[2]= -G.vd->ofs[2];
1330
 
 
 
1885
                new_dist*= size;
 
1886
        }
 
1887
        
 
1888
        G.vd->cursor[0]= -new_ofs[0];
 
1889
        G.vd->cursor[1]= -new_ofs[1];
 
1890
        G.vd->cursor[2]= -new_ofs[2];
 
1891
        
 
1892
        if (G.vd->persp==V3D_CAMOB && G.vd->camera) {
 
1893
                float orig_lens= G.vd->lens;
 
1894
                
 
1895
                G.vd->persp=V3D_PERSP;
 
1896
                G.vd->dist= 0.0;
 
1897
                view_settings_from_ob(G.vd->camera, G.vd->ofs, NULL, NULL, &G.vd->lens);
 
1898
                smooth_view(G.vd, new_ofs, NULL, &new_dist, &orig_lens);
 
1899
        } else {
 
1900
                if(G.vd->persp==V3D_CAMOB)
 
1901
                        G.vd->persp= V3D_PERSP;
 
1902
                
 
1903
                smooth_view(G.vd, new_ofs, NULL, &new_dist, NULL);
 
1904
        }
1331
1905
        scrarea_queue_winredraw(curarea);
1332
1906
        BIF_view3d_previewrender_signal(curarea, PR_DBASE|PR_DISPRECT);
1333
1907
 
1392
1966
                allqueue(REDRAWVIEW3D, 0);      /* because of select */
1393
1967
                allqueue(REDRAWOOPS, 0);        /* because of select */
1394
1968
                BIF_view3d_previewrender_signal(curarea, PR_DBASE|PR_DISPRECT);
1395
 
        }
 
1969
        } 
1396
1970
}
1397
1971
 
1398
 
void view3d_home(int centre)
 
1972
void view3d_home(int center)
1399
1973
{
1400
1974
        Base *base;
1401
1975
        float size, min[3], max[3], afm[3];
1402
1976
        int ok= 1, onedone=0;
1403
1977
 
1404
 
        if(centre) {
 
1978
        if(center) {
1405
1979
                min[0]= min[1]= min[2]= 0.0;
1406
1980
                max[0]= max[1]= max[2]= 0.0;
1407
1981
        }
1408
1982
        else {
1409
 
                min[0]= min[1]= min[2]= 1.0e10;
1410
 
                max[0]= max[1]= max[2]= -1.0e10;
 
1983
                INIT_MINMAX(min, max);
1411
1984
        }
1412
1985
        
1413
 
        base= FIRSTBASE;
1414
 
        if(base==0) return;
1415
 
        while(base) {
 
1986
        for(base= FIRSTBASE; base; base= base->next) {
1416
1987
                if(base->lay & G.vd->lay) {
1417
1988
                        onedone= 1;
1418
1989
                        minmax_object(base->object, min, max);
1419
1990
                }
1420
 
                base= base->next;
1421
1991
        }
1422
1992
        if(!onedone) return;
1423
1993
        
1428
1998
        if(size==0.0) ok= 0;
1429
1999
                
1430
2000
        if(ok) {
1431
 
 
1432
 
                G.vd->ofs[0]= -(min[0]+max[0])/2.0;
1433
 
                G.vd->ofs[1]= -(min[1]+max[1])/2.0;
1434
 
                G.vd->ofs[2]= -(min[2]+max[2])/2.0;
1435
 
 
1436
 
                G.vd->dist= size;
 
2001
                float new_dist;
 
2002
                float new_ofs[3];
 
2003
                
 
2004
                new_dist = size;
 
2005
                new_ofs[0]= -(min[0]+max[0])/2.0;
 
2006
                new_ofs[1]= -(min[1]+max[1])/2.0;
 
2007
                new_ofs[2]= -(min[2]+max[2])/2.0;
1437
2008
                
1438
2009
                // correction for window aspect ratio
1439
2010
                if(curarea->winy>2 && curarea->winx>2) {
1440
2011
                        size= (float)curarea->winx/(float)curarea->winy;
1441
2012
                        if(size<1.0) size= 1.0/size;
1442
 
                        G.vd->dist*= size;
1443
 
                }
1444
 
                
1445
 
                if(G.vd->persp==2) G.vd->persp= 1;
1446
 
                
 
2013
                        new_dist*= size;
 
2014
                }
 
2015
                
 
2016
                if (G.vd->persp==V3D_CAMOB && G.vd->camera) {
 
2017
                        /* switch out of camera view */
 
2018
                        float orig_lens= G.vd->lens;
 
2019
                        
 
2020
                        G.vd->persp= V3D_PERSP;
 
2021
                        G.vd->dist= 0.0;
 
2022
                        view_settings_from_ob(G.vd->camera, G.vd->ofs, NULL, NULL, &G.vd->lens);
 
2023
                        smooth_view(G.vd, new_ofs, NULL, &new_dist, &orig_lens);
 
2024
                        
 
2025
                } else {
 
2026
                        if(G.vd->persp==V3D_CAMOB) G.vd->persp= V3D_PERSP;
 
2027
                        smooth_view(G.vd, new_ofs, NULL, &new_dist, NULL);
 
2028
                }
1447
2029
                scrarea_queue_winredraw(curarea);
1448
2030
        }
1449
2031
        BIF_view3d_previewrender_signal(curarea, PR_DBASE|PR_DISPRECT);
1453
2035
 
1454
2036
void view3d_align_axis_to_vector(View3D *v3d, int axisidx, float vec[3])
1455
2037
{
1456
 
        float alignaxis[3];
1457
 
        float norm[3], axis[3], angle;
1458
 
 
1459
 
        alignaxis[0]= alignaxis[1]= alignaxis[2]= 0.0;
1460
 
        alignaxis[axisidx]= 1.0;
1461
 
 
1462
 
        norm[0]= vec[0], norm[1]= vec[1], norm[2]= vec[2];
1463
 
        Normalise(norm);
 
2038
        float alignaxis[3] = {0.0, 0.0, 0.0};
 
2039
        float norm[3], axis[3], angle, new_quat[4];
 
2040
 
 
2041
        if(axisidx > 0) alignaxis[axisidx-1]= 1.0;
 
2042
        else alignaxis[-axisidx-1]= -1.0;
 
2043
 
 
2044
        VECCOPY(norm, vec);
 
2045
        Normalize(norm);
1464
2046
 
1465
2047
        angle= acos(Inpf(alignaxis, norm));
1466
2048
        Crossf(axis, alignaxis, norm);
1467
 
        VecRotToQuat(axis, -angle, v3d->viewquat);
 
2049
        VecRotToQuat(axis, -angle, new_quat);
1468
2050
 
1469
2051
        v3d->view= 0;
1470
 
        if (v3d->persp>=2) v3d->persp= 0; /* switch out of camera mode */
1471
 
}
1472
 
 
 
2052
        
 
2053
        if (v3d->persp==V3D_CAMOB && v3d->camera) {
 
2054
                /* switch out of camera view */
 
2055
                float orig_ofs[3];
 
2056
                float orig_dist= v3d->dist;
 
2057
                float orig_lens= v3d->lens;
 
2058
 
 
2059
                VECCOPY(orig_ofs, v3d->ofs);
 
2060
                G.vd->persp= V3D_PERSP;
 
2061
                G.vd->dist= 0.0;
 
2062
                view_settings_from_ob(v3d->camera, v3d->ofs, NULL, NULL, &v3d->lens);
 
2063
                smooth_view(G.vd, orig_ofs, new_quat, &orig_dist, &orig_lens);
 
2064
        } else {
 
2065
                if (v3d->persp==V3D_CAMOB) v3d->persp= V3D_PERSP; /* switch out of camera mode */
 
2066
                smooth_view(v3d, NULL, new_quat, NULL, NULL);
 
2067
        }
 
2068
}
 
2069
 
 
2070
 
 
2071
 
 
2072
/* SMOOTHVIEW */
 
2073
void smooth_view(View3D *v3d, float *ofs, float *quat, float *dist, float *lens)
 
2074
{
 
2075
        /* View Animation enabled */
 
2076
        if (U.smooth_viewtx) {
 
2077
                int i;
 
2078
                char changed = 0;
 
2079
                float step = 0.0, step_inv;
 
2080
                float orig_dist;
 
2081
                float orig_lens;
 
2082
                float orig_quat[4];
 
2083
                float orig_ofs[3];
 
2084
                
 
2085
                double time_allowed, time_current, time_start;
 
2086
                
 
2087
                /* if there is no difference, return */
 
2088
                changed = 0; /* zero means no difference */
 
2089
                if (dist) {
 
2090
                        if ((*dist) != v3d->dist)
 
2091
                                changed = 1;
 
2092
                }
 
2093
                
 
2094
                if (lens) {
 
2095
                        if ((*lens) != v3d->lens)
 
2096
                                changed = 1;
 
2097
                }
 
2098
                
 
2099
                if (!changed && ofs) {
 
2100
                        if ((ofs[0]!=v3d->ofs[0]) ||
 
2101
                                (ofs[1]!=v3d->ofs[1]) ||
 
2102
                                (ofs[2]!=v3d->ofs[2]) )
 
2103
                                changed = 1;
 
2104
                }
 
2105
                
 
2106
                if (!changed && quat ) {
 
2107
                        if ((quat[0]!=v3d->viewquat[0]) ||
 
2108
                                (quat[1]!=v3d->viewquat[1]) ||
 
2109
                                (quat[2]!=v3d->viewquat[2]) ||
 
2110
                                (quat[3]!=v3d->viewquat[3]) )
 
2111
                                changed = 1;
 
2112
                }
 
2113
                
 
2114
                /* The new view is different from the old one
 
2115
                 * so animate the view */
 
2116
                if (changed) {
 
2117
                        
 
2118
                        /* store original values */
 
2119
                        VECCOPY(orig_ofs,       v3d->ofs);
 
2120
                        QUATCOPY(orig_quat,     v3d->viewquat);
 
2121
                        orig_dist =                     v3d->dist;
 
2122
                        orig_lens =                     v3d->lens;
 
2123
                        
 
2124
                        time_allowed= (float)U.smooth_viewtx / 1000.0;
 
2125
                        time_current = time_start = PIL_check_seconds_timer();
 
2126
                        
 
2127
                        /* if this is view rotation only
 
2128
                         * we can decrease the time allowed by
 
2129
                         * the angle between quats 
 
2130
                         * this means small rotations wont lag */
 
2131
                         if (quat && !ofs && !dist) {
 
2132
                                float vec1[3], vec2[3];
 
2133
                                VECCOPY(vec1, quat);
 
2134
                                VECCOPY(vec2, v3d->viewquat);
 
2135
                                Normalize(vec1);
 
2136
                                Normalize(vec2);
 
2137
                                /* scale the time allowed by the rotation */
 
2138
                                time_allowed *= NormalizedVecAngle2(vec1, vec2)/(M_PI/2); 
 
2139
                         }
 
2140
                        
 
2141
                        while (time_start + time_allowed > time_current) {
 
2142
                                
 
2143
                                step =  (float)((time_current-time_start) / time_allowed);
 
2144
                                
 
2145
                                /* ease in/out */
 
2146
                                if (step < 0.5) step = pow(step*2, 2)/2;
 
2147
                                else                    step = 1-(pow(2*(1-step) ,2)/2);
 
2148
                                
 
2149
                                step_inv = 1-step;
 
2150
                                
 
2151
                                if (ofs)
 
2152
                                        for (i=0; i<3; i++)
 
2153
                                                v3d->ofs[i] = ofs[i]*step + orig_ofs[i]*step_inv;
 
2154
                                
 
2155
                                
 
2156
                                if (quat)
 
2157
                                        QuatInterpol(v3d->viewquat, orig_quat, quat, step);
 
2158
                                        
 
2159
                                if (dist)
 
2160
                                        v3d->dist = ((*dist)*step) + (orig_dist*step_inv);
 
2161
                                
 
2162
                                if (lens)
 
2163
                                        v3d->lens = ((*lens)*step) + (orig_lens*step_inv);
 
2164
                                
 
2165
                                /*redraw the view*/
 
2166
                                scrarea_do_windraw(curarea);
 
2167
                                screen_swapbuffers();
 
2168
                                
 
2169
                                time_current= PIL_check_seconds_timer();
 
2170
                        }
 
2171
                }
 
2172
        }
 
2173
        
 
2174
        /* set these values even if animation is enabled because flaot
 
2175
         * error will make then not quite accurate */
 
2176
        if (ofs)
 
2177
                VECCOPY(v3d->ofs, ofs);
 
2178
        if (quat)
 
2179
                QUATCOPY(v3d->viewquat, quat);
 
2180
        if (dist)
 
2181
                v3d->dist = *dist;
 
2182
        if (lens)
 
2183
                v3d->lens = *lens;
 
2184
        
 
2185
}
 
2186
 
 
2187
 
 
2188
 
 
2189
/* Gets the view trasnformation from a camera
 
2190
 * currently dosnt take camzoom into account
 
2191
 * 
 
2192
 * The dist is not modified for this function, if NULL its assimed zero
 
2193
 * */
 
2194
void view_settings_from_ob(Object *ob, float *ofs, float *quat, float *dist, float *lens)
 
2195
{       
 
2196
        float bmat[4][4];
 
2197
        float imat[4][4];
 
2198
        float tmat[3][3];
 
2199
        
 
2200
        if (!ob) return;
 
2201
        
 
2202
        /* Offset */
 
2203
        if (ofs) {
 
2204
                where_is_object(ob);
 
2205
                VECCOPY(ofs, ob->obmat[3]);
 
2206
                VecMulf(ofs, -1.0f); /*flip the vector*/
 
2207
        }
 
2208
        
 
2209
        /* Quat */
 
2210
        if (quat) {
 
2211
                Mat4CpyMat4(bmat, ob->obmat);
 
2212
                Mat4Ortho(bmat);
 
2213
                Mat4Invert(imat, bmat);
 
2214
                Mat3CpyMat4(tmat, imat);
 
2215
                Mat3ToQuat(tmat, quat);
 
2216
        }
 
2217
        
 
2218
        if (dist) {
 
2219
                float vec[3];
 
2220
                Mat3CpyMat4(tmat, ob->obmat);
 
2221
                
 
2222
                vec[0]= vec[1] = 0.0;
 
2223
                vec[2]= -(*dist);
 
2224
                Mat3MulVecfl(tmat, vec);
 
2225
                VecSubf(ofs, ofs, vec);
 
2226
        }
 
2227
        
 
2228
        /* Lens */
 
2229
        if (lens)
 
2230
                object_view_settings(ob, lens, NULL, NULL);
 
2231
}
 
2232
 
 
2233
/* For use with smooth view
 
2234
 * 
 
2235
 * the current view is unchanged, blend between the current view and the
 
2236
 * camera view
 
2237
 * */
 
2238
void smooth_view_to_camera(View3D *v3d)
 
2239
{
 
2240
        if (!U.smooth_viewtx || !v3d->camera || G.vd->persp != V3D_CAMOB) {
 
2241
                return;
 
2242
        } else {
 
2243
                Object *ob = v3d->camera;
 
2244
                
 
2245
                float orig_ofs[3];
 
2246
                float orig_dist=v3d->dist;
 
2247
                float orig_lens=v3d->lens;
 
2248
                float new_dist=0.0;
 
2249
                float new_lens=35.0;
 
2250
                float new_quat[4];
 
2251
                float new_ofs[3];
 
2252
                
 
2253
                VECCOPY(orig_ofs, v3d->ofs);
 
2254
                
 
2255
                view_settings_from_ob(ob, new_ofs, new_quat, NULL, &new_lens);
 
2256
                
 
2257
                G.vd->persp= V3D_PERSP;
 
2258
                smooth_view(v3d, new_ofs, new_quat, &new_dist, &new_lens);
 
2259
                VECCOPY(v3d->ofs, orig_ofs);
 
2260
                v3d->lens= orig_lens;
 
2261
                v3d->dist = orig_dist; /* restore the dist */
 
2262
                
 
2263
                v3d->camera = ob;
 
2264
                v3d->persp= V3D_CAMOB;
 
2265
        }
 
2266
}