Index: source/blender/include/BSE_drawview.h =================================================================== RCS file: /cvsroot/bf-blender/blender/source/blender/include/BSE_drawview.h,v retrieving revision 1.19 diff -u -p -u -r1.19 BSE_drawview.h --- source/blender/include/BSE_drawview.h 1 Jan 2007 09:41:10 -0000 1.19 +++ source/blender/include/BSE_drawview.h 16 Mar 2007 02:28:22 -0000 @@ -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: source/blender/makesdna/DNA_userdef_types.h =================================================================== RCS file: /cvsroot/bf-blender/blender/source/blender/makesdna/DNA_userdef_types.h,v retrieving revision 1.64 diff -u -p -u -r1.64 DNA_userdef_types.h --- source/blender/makesdna/DNA_userdef_types.h 3 Jan 2007 05:50:16 -0000 1.64 +++ source/blender/makesdna/DNA_userdef_types.h 16 Mar 2007 02:28:22 -0000 @@ -178,7 +178,7 @@ typedef struct UserDef { short rvibright; /* rotating view icon brightness */ char versemaster[160]; char verseuser[160]; - short pad; + short smooth_viewtx; } UserDef; extern UserDef U; /* from usiblender.c !!!! */ Index: source/blender/src/editview.c =================================================================== RCS file: /cvsroot/bf-blender/blender/source/blender/src/editview.c,v retrieving revision 1.131 diff -u -p -u -r1.131 editview.c --- source/blender/src/editview.c 6 Mar 2007 03:39:15 -0000 1.131 +++ source/blender/src/editview.c 16 Mar 2007 02:28:22 -0000 @@ -2056,6 +2056,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; @@ -2067,12 +2071,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]); @@ -2080,7 +2090,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: source/blender/src/space.c =================================================================== RCS file: /cvsroot/bf-blender/blender/source/blender/src/space.c,v retrieving revision 1.455 diff -u -p -u -r1.455 space.c --- source/blender/src/space.c 13 Mar 2007 16:15:59 -0000 1.455 +++ source/blender/src/space.c 16 Mar 2007 02:28:22 -0000 @@ -1284,11 +1284,14 @@ static void winqreadview3dspace(ScrArea /* center the camera offset */ G.vd->camdx= G.vd->camdy= 0.0; else { + float new_ofs[3]; + /*non camera center*/ 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; @@ -1661,10 +1664,13 @@ static void winqreadview3dspace(ScrArea 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); } @@ -2363,7 +2369,7 @@ static void winqreadview3dspace(ScrArea } break; case PADPERIOD: /* '.' */ - if(G.qual==0) + if(G.qual==0) centreview(); break; @@ -3248,6 +3254,13 @@ void drawinfospace(ScrArea *sa, void *sp (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)+(4*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, Index: source/blender/src/toets.c =================================================================== RCS file: /cvsroot/bf-blender/blender/source/blender/src/toets.c,v retrieving revision 1.99 diff -u -p -u -r1.99 toets.c --- source/blender/src/toets.c 13 Mar 2007 11:54:53 -0000 1.99 +++ source/blender/src/toets.c 16 Mar 2007 02:28:22 -0000 @@ -127,6 +127,8 @@ void persptoetsen(unsigned short event) static int perspo=1; int preview3d_event= 1; + float new_quat[4]; + if(event==PADENTER) { if (G.qual == LR_SHIFTKEY) { view3d_set_1_to_1_viewborder(G.vd); @@ -149,28 +151,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 +220,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: source/blender/src/view.c =================================================================== RCS file: /cvsroot/bf-blender/blender/source/blender/src/view.c,v retrieving revision 1.78 diff -u -p -u -r1.78 view.c --- source/blender/src/view.c 7 Feb 2007 11:25:56 -0000 1.78 +++ source/blender/src/view.c 16 Mar 2007 02:28:22 -0000 @@ -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 centreview() /* like a localview wi 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 centreview() /* like a localview wi 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 centre) @@ -1458,21 +1467,24 @@ void view3d_home(int centre) 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); } @@ -1498,5 +1510,110 @@ void view3d_align_axis_to_vector(View3D v3d->view= 0; 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); + Normalise(vec1); + Normalise(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; + }