smooth view transformations, set the smoothview value to about 250 and the view anima...
authorCampbell Barton <ideasman42@gmail.com>
Mon, 9 Apr 2007 11:15:23 +0000 (11:15 +0000)
committerCampbell Barton <ideasman42@gmail.com>
Mon, 9 Apr 2007 11:15:23 +0000 (11:15 +0000)
source/blender/include/BSE_drawview.h
source/blender/makesdna/DNA_userdef_types.h
source/blender/src/editview.c
source/blender/src/space.c
source/blender/src/toets.c
source/blender/src/view.c

index 6e6128591739de80209980ddd45826e643807613..1283ba4fdca72eff0019626bf3f59a0ffd63dd91 100644 (file)
@@ -78,5 +78,8 @@ int play_anim(int mode);
 
 void make_axis_color(char *col, char *col2, char axis);
 
+/* SMOOTHVIEW */
+void smooth_view(struct View3D *v3d, float *ofs, float *quat, float *dist);
+
 #endif /* BSE_DRAWVIEW_H */
 
index d486f8eae5f2ddf7770e809f2c15a722d5bff5e7..6d2f9411ebfe514db972d6863c6a2548008de4c9 100644 (file)
@@ -179,6 +179,8 @@ typedef struct UserDef {
        char versemaster[160];
        char verseuser[160];
        short recent_files;             /* maximum number of recently used files to remember  */
+       short smooth_viewtx;    /* miliseconds to spend spinning the view */
+       char pad[6];
 } UserDef;
 
 extern UserDef U; /* from usiblender.c !!!! */
index 6dfdd3cf1c0f98999f48810777b7f5364dc62a32..225854b1fff9c3e48befd1a7cca266072f38c406 100644 (file)
@@ -2058,6 +2058,10 @@ void view3d_border_zoom(void)
        short val;
        float dvec[3], vb[2], xscale, yscale, scale;
        
+       /* SMOOTHVIEW */
+       float new_dist;
+       float new_ofs[3];
+       
        /* doesn't work fine for perspective */
        if(G.vd->persp==1)
                return;
@@ -2069,12 +2073,18 @@ void view3d_border_zoom(void)
                vb[0] = G.vd->area->winx;
                vb[1] = G.vd->area->winy;
                
+               new_dist = G.vd->dist;
+               new_ofs[0] = G.vd->ofs[0];
+               new_ofs[1] = G.vd->ofs[1];
+               new_ofs[2] = G.vd->ofs[2];
+               
                /* convert the drawn rectangle into 3d space */
-               initgrabz(-G.vd->ofs[0], -G.vd->ofs[1], -G.vd->ofs[2]);
+               initgrabz(-new_ofs[0], -new_ofs[1], -new_ofs[2]);
+               
                window_to_3d(dvec, (rect.xmin+rect.xmax-vb[0])/2, (rect.ymin+rect.ymax-vb[1])/2);
                
                /* center the view to the center of the rectangle */
-               VecSubf(G.vd->ofs, G.vd->ofs, dvec);
+               VecSubf(new_ofs, new_ofs, dvec);
                
                /* work out the ratios, so that everything selected fits when we zoom */
                xscale = ((rect.xmax-rect.xmin)/vb[0]);
@@ -2082,7 +2092,10 @@ void view3d_border_zoom(void)
                scale = (xscale >= yscale)?xscale:yscale;
                
                /* zoom in as required, or as far as we can go */
-               G.vd->dist = ((G.vd->dist*scale) >= 0.001*G.vd->grid)? G.vd->dist*scale:0.001*G.vd->grid;
+               new_dist = ((new_dist*scale) >= 0.001*G.vd->grid)? new_dist*scale:0.001*G.vd->grid;
+               
+               smooth_view(G.vd, new_ofs, NULL, &new_dist);
+               
        }
 }
 
index 73fc627ebe63b8146187a0dca07c0d4b7627b067..bd403f878c19221f74cdca28c79768b3d0713be2 100644 (file)
@@ -1331,10 +1331,12 @@ static void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
                                                G.vd->camdx= G.vd->camdy= 0.0;
                                        else {
                                                /*non camera center*/
+                                               float new_ofs[3];
                                                curs= give_cursor();
-                                               G.vd->ofs[0]= -curs[0];
-                                               G.vd->ofs[1]= -curs[1];
-                                               G.vd->ofs[2]= -curs[2];
+                                               new_ofs[0]= -curs[0];
+                                               new_ofs[1]= -curs[1];
+                                               new_ofs[2]= -curs[2];
+                                               smooth_view(G.vd, new_ofs, NULL, NULL);
                                        }
                                }
                                doredraw= 1;
@@ -1734,10 +1736,12 @@ static void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
                                                G.vd->camdx= G.vd->camdy= 0.0;
                                        else {
                                                /*non camera center*/
+                                               float new_ofs[3];
                                                curs= give_cursor();
-                                               G.vd->ofs[0]= -curs[0];
-                                               G.vd->ofs[1]= -curs[1];
-                                               G.vd->ofs[2]= -curs[2];
+                                               new_ofs[0]= -curs[0];
+                                               new_ofs[1]= -curs[1];
+                                               new_ofs[2]= -curs[2];
+                                               smooth_view(G.vd, new_ofs, NULL, NULL);
                                        }
                                        scrarea_queue_winredraw(curarea);
                                }
@@ -3328,7 +3332,12 @@ void drawinfospace(ScrArea *sa, void *spacedata)
                        (xpos+edgsp+(3*mpref)+(4*midsp)),y1,(mpref),buth,
                        &U.pad_rot_angle, 0, 90, 0, 0,
                        "The rotation step for numerical pad keys (2 4 6 8)");
-
+               
+        uiDefButS(block, NUM, B_DRAWINFO, "Smooth View:",
+                       (xpos+edgsp+(4*mpref)+(5*midsp)),y1,(mpref),buth,
+                       &U.smooth_viewtx, 0, 1000, 0, 0,
+                       "The time to animate the view in miliseconds, zero to disable");
+               
                uiDefBut(block, LABEL,0,"Select with:",
                        (xpos+(2*edgsp)+(3*mpref)+(3*midsp)),y6label,mpref,buth,
                        0, 0, 0, 0, 0, "");
index 87b76a084fe7da587a7b39a1ed37fbbc2e362eb6..63c4d764d74bddf69831dde5082fc8fe6f1a11a7 100644 (file)
@@ -127,6 +127,8 @@ void persptoetsen(unsigned short event)
        static int perspo=1;
        int preview3d_event= 1;
        
+       float new_quat[4], new_dist;
+       
        if(event==PADENTER) {
                if (G.qual == LR_SHIFTKEY) {
                        view3d_set_1_to_1_viewborder(G.vd);
@@ -134,7 +136,8 @@ void persptoetsen(unsigned short event)
                        if (G.vd->persp==2) {
                                G.vd->camzoom= 0;
                        } else {
-                               G.vd->dist= 10.0;
+                               new_dist = 10.0;
+                               smooth_view(G.vd, NULL, NULL, &new_dist);
                        }
                }
        }
@@ -149,28 +152,35 @@ void persptoetsen(unsigned short event)
                        /* G.vd->persp= 3; */
                }
                else if(event==PAD7) {
-                       G.vd->viewquat[0]= 0.0;
-                       G.vd->viewquat[1]= -1.0;
-                       G.vd->viewquat[2]= 0.0;
-                       G.vd->viewquat[3]= 0.0;
+                       new_quat[0]=0.0;
+                       new_quat[1]=-1.0;
+                       new_quat[2]=0.0;
+                       new_quat[3]=0.0;
+                       G.vd->view= 0;
+                       smooth_view(G.vd, NULL, new_quat, NULL);
                        G.vd->view= 7;
+                       
                        if (U.uiflag & USER_AUTOPERSP) G.vd->persp= 0; 
                        else if(G.vd->persp>=2) G.vd->persp= perspo;
                }
                else if(event==PAD1) {
-                       G.vd->viewquat[0]= 0.0;
-                       G.vd->viewquat[1]= 0.0;
-                       G.vd->viewquat[2]= (float)-cos(M_PI/4.0);
-                       G.vd->viewquat[3]= (float)-cos(M_PI/4.0);
+                       new_quat[0]=0.0;
+                       new_quat[1]=0.0;
+                       new_quat[2]=(float)-cos(M_PI/4.0);
+                       new_quat[3]=(float)-cos(M_PI/4.0);
+                       G.vd->view=0;
+                       smooth_view(G.vd, NULL, new_quat, NULL);
                        G.vd->view=1;
                        if (U.uiflag & USER_AUTOPERSP) G.vd->persp= 0;
                        else if(G.vd->persp>=2) G.vd->persp= perspo;
                }
                else if(event==PAD3) {
-                       G.vd->viewquat[0]= 0.5;
-                       G.vd->viewquat[1]= -0.5;
-                       G.vd->viewquat[2]= 0.5;
-                       G.vd->viewquat[3]= 0.5;
+                       new_quat[0]= 0.5;
+                       new_quat[1]=-0.5;
+                       new_quat[2]= 0.5;
+                       new_quat[3]= 0.5;
+                       G.vd->view=0;
+                       smooth_view(G.vd, NULL, new_quat, NULL);
                        G.vd->view=3;
                        if (U.uiflag & USER_AUTOPERSP) G.vd->persp= 0;
                        else if(G.vd->persp>=2) G.vd->persp= perspo;
@@ -211,28 +221,34 @@ void persptoetsen(unsigned short event)
                
 
                if(event==PAD7) {
-                       G.vd->viewquat[0]= 1.0;
-                       G.vd->viewquat[1]= 0.0;
-                       G.vd->viewquat[2]= 0.0;
-                       G.vd->viewquat[3]= 0.0;
+                       new_quat[0]=1.0;
+                       new_quat[1]=0.0;
+                       new_quat[2]=0.0;
+                       new_quat[3]=0.0;
+                       G.vd->view=0;
+                       smooth_view(G.vd, NULL, new_quat, NULL);
                        G.vd->view=7;
                        if (U.uiflag & USER_AUTOPERSP) G.vd->persp= 0;
                        else if(G.vd->persp>=2) G.vd->persp= perspo;
                }
                else if(event==PAD1) {
-                       G.vd->viewquat[0]= (float)cos(M_PI/4.0);
-                       G.vd->viewquat[1]= (float)-sin(M_PI/4.0);
-                       G.vd->viewquat[2]= 0.0;
-                       G.vd->viewquat[3]= 0.0;
+                       new_quat[0]= (float)cos(M_PI/4.0);
+                       new_quat[1]= (float)-sin(M_PI/4.0);
+                       new_quat[2]= 0.0;
+                       new_quat[3]= 0.0;
+                       G.vd->view=0;
+                       smooth_view(G.vd, NULL, new_quat, NULL);
                        G.vd->view=1;
                        if (U.uiflag & USER_AUTOPERSP) G.vd->persp= 0;
                        else if(G.vd->persp>=2) G.vd->persp= perspo;
                }
                else if(event==PAD3) {
-                       G.vd->viewquat[0]= 0.5;
-                       G.vd->viewquat[1]= -0.5;
-                       G.vd->viewquat[2]= -0.5;
-                       G.vd->viewquat[3]= -0.5;
+                       new_quat[0]= 0.5;
+                       new_quat[1]= -0.5;
+                       new_quat[2]= -0.5;
+                       new_quat[3]= -0.5;
+                       G.vd->view=0;
+                       smooth_view(G.vd, NULL, new_quat, NULL);
                        G.vd->view=3;
                        if (U.uiflag & USER_AUTOPERSP) G.vd->persp= 0;
                        else if(G.vd->persp>=2) G.vd->persp= perspo;
index 0c8f5ae66e547ce802574b5ed634bb50a7f24ced..5c36d85203abbb7363ec7f872150962c0eaf0258 100644 (file)
@@ -87,6 +87,8 @@
 #include "mydevice.h"
 #include "blendef.h"
 
+#include "PIL_time.h" /* smoothview */
+
 #define TRACKBALLSIZE  (1.1)
 #define BL_NEAR_CLIP 0.001
 
@@ -1248,7 +1250,7 @@ void initlocalview()
                scrarea_queue_winredraw(curarea);
        }
        else {
-               /* clear flags */
+               /* clear flags */ 
                base= FIRSTBASE;
                while(base) {
                        if( base->lay & locallay ) {
@@ -1271,7 +1273,12 @@ void centerview()        /* like a localview without local! */
        Object *ob= OBACT;
        float size, min[3], max[3], afm[3];
        int ok=0;
-
+       
+       /* SMOOTHVIEW */
+       float new_ofs[3];
+       float new_dist;
+       
+       
        min[0]= min[1]= min[2]= 1.0e10;
        max[0]= max[1]= max[2]= -1.0e10;
 
@@ -1340,27 +1347,29 @@ void centerview()       /* like a localview without local! */
        
        if(size<=0.01) size= 0.01;
        
-       G.vd->ofs[0]= -(min[0]+max[0])/2.0;
-       G.vd->ofs[1]= -(min[1]+max[1])/2.0;
-       G.vd->ofs[2]= -(min[2]+max[2])/2.0;
-
-       G.vd->dist= size;
+       new_ofs[0]= -(min[0]+max[0])/2.0;
+       new_ofs[1]= -(min[1]+max[1])/2.0;
+       new_ofs[2]= -(min[2]+max[2])/2.0;
+       
+       new_dist = size;
 
        // correction for window aspect ratio
        if(curarea->winy>2 && curarea->winx>2) {
                size= (float)curarea->winx/(float)curarea->winy;
                if(size<1.0) size= 1.0/size;
-               G.vd->dist*= size;
+               new_dist*= size;
        }
        
        if(G.vd->persp>1) {
                G.vd->persp= 1;
        }
-
-       G.vd->cursor[0]= -G.vd->ofs[0];
-       G.vd->cursor[1]= -G.vd->ofs[1];
-       G.vd->cursor[2]= -G.vd->ofs[2];
-
+       
+       G.vd->cursor[0]= -new_ofs[0];
+       G.vd->cursor[1]= -new_ofs[1];
+       G.vd->cursor[2]= -new_ofs[2];
+       
+       smooth_view(G.vd, new_ofs, NULL, &new_dist);
+       
        scrarea_queue_winredraw(curarea);
        BIF_view3d_previewrender_signal(curarea, PR_DBASE|PR_DISPRECT);
 
@@ -1425,7 +1434,7 @@ void endlocalview(ScrArea *sa)
                allqueue(REDRAWVIEW3D, 0);      /* because of select */
                allqueue(REDRAWOOPS, 0);        /* because of select */
                BIF_view3d_previewrender_signal(curarea, PR_DBASE|PR_DISPRECT);
-       }
+       } 
 }
 
 void view3d_home(int center)
@@ -1458,21 +1467,24 @@ void view3d_home(int center)
        if(size==0.0) ok= 0;
                
        if(ok) {
-
-               G.vd->ofs[0]= -(min[0]+max[0])/2.0;
-               G.vd->ofs[1]= -(min[1]+max[1])/2.0;
-               G.vd->ofs[2]= -(min[2]+max[2])/2.0;
-
-               G.vd->dist= size;
+               float new_dist;
+               float new_ofs[3];
+               
+               new_dist = size;
+               new_ofs[0]= -(min[0]+max[0])/2.0;
+               new_ofs[1]= -(min[1]+max[1])/2.0;
+               new_ofs[2]= -(min[2]+max[2])/2.0;
                
                // correction for window aspect ratio
                if(curarea->winy>2 && curarea->winx>2) {
                        size= (float)curarea->winx/(float)curarea->winy;
                        if(size<1.0) size= 1.0/size;
-                       G.vd->dist*= size;
+                       new_dist*= size;
                }
                
                if(G.vd->persp==2) G.vd->persp= 1;
+                
+               smooth_view(G.vd, new_ofs, NULL, &new_dist);
                
                scrarea_queue_winredraw(curarea);
        }
@@ -1500,3 +1512,108 @@ void view3d_align_axis_to_vector(View3D *v3d, int axisidx, float vec[3])
        if (v3d->persp>=2) v3d->persp= 0; /* switch out of camera mode */
 }
 
+
+
+/* SMOOTHVIEW */
+void smooth_view(View3D *v3d, float *ofs, float *quat, float *dist)
+{
+       /* View Animation enabled */
+       if (U.smooth_viewtx) {
+               int i;
+               char changed = 0;
+               float step = 0.0, step_inv;
+               float orig_dist;
+               float orig_quat[4];
+               float orig_ofs[3];
+               
+               double time_allowed, time_current, time_start;
+               
+               /* if there is no difference, return */
+               changed = 0; /* zero means no difference */
+               if (dist) {
+                       if ((*dist) != v3d->dist)
+                               changed = 1;
+               }
+               
+               if (!changed && ofs) {
+                       if ((ofs[0]!=v3d->ofs[0]) ||
+                               (ofs[1]!=v3d->ofs[1]) ||
+                               (ofs[2]!=v3d->ofs[2]) )
+                               changed = 1;
+               }
+               
+               if (!changed && quat ) {
+                       if ((quat[0]!=v3d->viewquat[0]) ||
+                               (quat[1]!=v3d->viewquat[1]) ||
+                               (quat[2]!=v3d->viewquat[2]) ||
+                               (quat[3]!=v3d->viewquat[3]) )
+                               changed = 1;
+               }
+               
+               /* The new view is different from teh old one
+                * so animate the view */
+               if (changed) {
+                       
+                       /* store original values */
+                       VECCOPY(orig_ofs,       v3d->ofs);
+                       QUATCOPY(orig_quat,     v3d->viewquat);
+                       orig_dist =                     v3d->dist;
+                       
+                       time_allowed= (float)U.smooth_viewtx / 1000.0;
+                       time_current = time_start = PIL_check_seconds_timer();
+                       
+                       /* if this is view rotation only
+                        * we can decrease the time allowed by
+                        * the angle between quats 
+                        * this means small rotations wont lag */
+                        if (quat && !ofs && !dist) {
+                               float vec1[3], vec2[3];
+                               VECCOPY(vec1, quat);
+                               VECCOPY(vec2, v3d->viewquat);
+                               Normalize(vec1);
+                               Normalize(vec2);
+                               /* scale the time allowed by the rotation */
+                               time_allowed *= NormalizedVecAngle2(vec1, vec2)/(M_PI/2); 
+                        }
+                       
+                       while (time_start + time_allowed > time_current) {
+                               
+                               step =  (float)((time_current-time_start) / time_allowed);
+                               
+                               /* ease in/out */
+                               if (step < 0.5) step = pow(step*2, 2)/2;
+                               else                    step = 1-(pow(2*(1-step) ,2)/2);
+                               
+                               step_inv = 1-step;
+                               
+                               if (ofs)
+                                       for (i=0; i<3; i++)
+                                               v3d->ofs[i] = ofs[i]*step + orig_ofs[i]*step_inv;
+                               
+                               if (quat)
+                                       QuatInterpol(v3d->viewquat, orig_quat, quat, step);
+                                       
+                               if (dist) {
+                                       v3d->dist = ((*dist)*step) + (orig_dist*step_inv);
+                               }
+                               
+                               /*redraw the view*/
+                               scrarea_do_windraw(curarea);
+                               screen_swapbuffers();
+                               
+                               time_current= PIL_check_seconds_timer();
+                       }
+               }
+       }
+       
+       /* set these values even if animation is enabled because flaot
+        * error will make then not quite accurate */
+       if (ofs)
+               VECCOPY(v3d->ofs, ofs);
+       if (quat)
+               QUATCOPY(v3d->viewquat, quat);
+       if (dist)
+               v3d->dist = *dist;
+       
+}
+