diff options
author | Matt Ebb <matt@mke3.net> | 2007-10-09 02:17:51 +0400 |
---|---|---|
committer | Matt Ebb <matt@mke3.net> | 2007-10-09 02:17:51 +0400 |
commit | 74f744010b1adbc08a5f548f26066c82189f2655 (patch) | |
tree | 5087c9ed206683895f6fe7891618e2d8a4fe554b | |
parent | ca1ea2ce65d463a417695472ac514c8cb49425b7 (diff) |
* Patch #6877: Zoom to Mouse Position
by Fahrezal Effendi (exavolt)
This adds an additional preference to the view and controls section, which uses the mouse's position as the centre of the zoom when zooming in the 3D View with Ctrl-MMB or the mouse wheel. It's very nice for big scenes, thanks Fahrezal!
A nice todo would be to add this for 2D views as well.
-rw-r--r-- | source/blender/include/BSE_view.h | 1 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_userdef_types.h | 111 | ||||
-rw-r--r-- | source/blender/src/space.c | 69 | ||||
-rw-r--r-- | source/blender/src/toets.c | 14 | ||||
-rw-r--r-- | source/blender/src/view.c | 58 |
5 files changed, 159 insertions, 94 deletions
diff --git a/source/blender/include/BSE_view.h b/source/blender/include/BSE_view.h index 91f360338e9..4e27f9f1a81 100644 --- a/source/blender/include/BSE_view.h +++ b/source/blender/include/BSE_view.h @@ -76,6 +76,7 @@ void sdrawbox(short x1, short y1, short x2, short y2); void calctrackballvecfirst(struct rcti *area, short *mval, float *vec); void calctrackballvec(struct rcti *area, short *mval, float *vec); void viewmove(int mode); +void view_zoom_mouseloc(float dfac, short *mouseloc); int get_view3d_viewplane(int winxi, int winyi, rctf *viewplane, float *clipsta, float *clipend, float *pixsize); void setwinmatrixview3d(int winx, int winy, struct rctf *rect); diff --git a/source/blender/makesdna/DNA_userdef_types.h b/source/blender/makesdna/DNA_userdef_types.h index 7aa4dbdcf78..b4436dc69b2 100644 --- a/source/blender/makesdna/DNA_userdef_types.h +++ b/source/blender/makesdna/DNA_userdef_types.h @@ -189,23 +189,23 @@ extern UserDef U; /* from usiblender.c !!!! */ /* ***************** USERDEF ****************** */ /* flag */ -#define USER_AUTOSAVE 1 -#define USER_AUTOGRABGRID 2 -#define USER_AUTOROTGRID 4 -#define USER_AUTOSIZEGRID 8 -#define USER_SCENEGLOBAL 16 -#define USER_TRACKBALL 32 -#define USER_DUPLILINK 64 -#define USER_FSCOLLUM 128 -#define USER_MAT_ON_OB 256 -#define USER_NO_CAPSLOCK 512 -#define USER_VIEWMOVE 1024 -#define USER_TOOLTIPS 2048 -#define USER_TWOBUTTONMOUSE 4096 -#define USER_NONUMPAD 8192 -#define USER_LMOUSESELECT 16384 -#define USER_FILECOMPRESS 32768 -#define USER_SAVE_PREVIEWS 65536 +#define USER_AUTOSAVE (1 << 0) +#define USER_AUTOGRABGRID (1 << 1) +#define USER_AUTOROTGRID (1 << 2) +#define USER_AUTOSIZEGRID (1 << 3) +#define USER_SCENEGLOBAL (1 << 4) +#define USER_TRACKBALL (1 << 5) +#define USER_DUPLILINK (1 << 6) +#define USER_FSCOLLUM (1 << 7) +#define USER_MAT_ON_OB (1 << 8) +#define USER_NO_CAPSLOCK (1 << 9) +#define USER_VIEWMOVE (1 << 10) +#define USER_TOOLTIPS (1 << 11) +#define USER_TWOBUTTONMOUSE (1 << 12) +#define USER_NONUMPAD (1 << 13) +#define USER_LMOUSESELECT (1 << 14) +#define USER_FILECOMPRESS (1 << 15) +#define USER_SAVE_PREVIEWS (1 << 16) /* viewzom */ #define USER_ZOOM_CONT 0 @@ -214,51 +214,52 @@ extern UserDef U; /* from usiblender.c !!!! */ /* uiflag */ -#define USER_KEYINSERTACT 1 -#define USER_KEYINSERTOBJ 2 -#define USER_WHEELZOOMDIR 4 -#define USER_FILTERFILEEXTS 8 -#define USER_DRAWVIEWINFO 16 -#define USER_PLAINMENUS 32 // old EVTTOCONSOLE print ghost events, here for tuhopuu compat. --phase +#define USER_KEYINSERTACT (1 << 0) +#define USER_KEYINSERTOBJ (1 << 1) +#define USER_WHEELZOOMDIR (1 << 2) +#define USER_FILTERFILEEXTS (1 << 3) +#define USER_DRAWVIEWINFO (1 << 4) +#define USER_PLAINMENUS (1 << 5) // old EVTTOCONSOLE print ghost events, here for tuhopuu compat. --phase // old flag for hide pulldown was here -#define USER_FLIPFULLSCREEN 128 -#define USER_ALLWINCODECS 256 -#define USER_MENUOPENAUTO 512 -#define USER_PANELPINNED 1024 -#define USER_AUTOPERSP 2048 -#define USER_LOCKAROUND 4096 -#define USER_GLOBALUNDO 8192 -#define USER_ORBIT_SELECTION 16384 -#define USER_KEYINSERTAVAI 32768 -#define USER_HIDE_DOT 65536 -#define USER_SHOW_ROTVIEWICON 131072 -#define USER_SHOW_VIEWPORTNAME 262144 -#define USER_KEYINSERTNEED 524288 +#define USER_FLIPFULLSCREEN (1 << 7) +#define USER_ALLWINCODECS (1 << 8) +#define USER_MENUOPENAUTO (1 << 9) +#define USER_PANELPINNED (1 << 10) +#define USER_AUTOPERSP (1 << 11) +#define USER_LOCKAROUND (1 << 12) +#define USER_GLOBALUNDO (1 << 13) +#define USER_ORBIT_SELECTION (1 << 14) +#define USER_KEYINSERTAVAI (1 << 15) +#define USER_HIDE_DOT (1 << 16) +#define USER_SHOW_ROTVIEWICON (1 << 17) +#define USER_SHOW_VIEWPORTNAME (1 << 18) +#define USER_KEYINSERTNEED (1 << 19) +#define USER_ZOOM_TO_MOUSEPOS (1 << 20) /* transopts */ -#define USER_TR_TOOLTIPS 1 -#define USER_TR_BUTTONS 2 -#define USER_TR_MENUS 4 -#define USER_TR_FILESELECT 8 -#define USER_TR_TEXTEDIT 16 -#define USER_DOTRANSLATE 32 -#define USER_USETEXTUREFONT 64 -#define CONVERT_TO_UTF8 128 +#define USER_TR_TOOLTIPS (1 << 0) +#define USER_TR_BUTTONS (1 << 1) +#define USER_TR_MENUS (1 << 2) +#define USER_TR_FILESELECT (1 << 3) +#define USER_TR_TEXTEDIT (1 << 4) +#define USER_DOTRANSLATE (1 << 5) +#define USER_USETEXTUREFONT (1 << 6) +#define CONVERT_TO_UTF8 (1 << 7) /* dupflag */ -#define USER_DUP_MESH 1 -#define USER_DUP_CURVE 2 -#define USER_DUP_SURF 4 -#define USER_DUP_FONT 8 -#define USER_DUP_MBALL 16 -#define USER_DUP_LAMP 32 -#define USER_DUP_IPO 64 -#define USER_DUP_MAT 128 -#define USER_DUP_TEX 256 -#define USER_DUP_ARM 512 -#define USER_DUP_ACT 1024 +#define USER_DUP_MESH (1 << 0) +#define USER_DUP_CURVE (1 << 1) +#define USER_DUP_SURF (1 << 2) +#define USER_DUP_FONT (1 << 3) +#define USER_DUP_MBALL (1 << 4) +#define USER_DUP_LAMP (1 << 5) +#define USER_DUP_IPO (1 << 6) +#define USER_DUP_MAT (1 << 7) +#define USER_DUP_TEX (1 << 8) +#define USER_DUP_ARM (1 << 9) +#define USER_DUP_ACT (1 << 10) /* gameflags */ diff --git a/source/blender/src/space.c b/source/blender/src/space.c index 923a2ae010e..bb50674a6f9 100644 --- a/source/blender/src/space.c +++ b/source/blender/src/space.c @@ -3390,56 +3390,35 @@ void drawinfospace(ScrArea *sa, void *spacedata) uiBlockSetCol(block, TH_AUTO); /* end color */ uiBlockEndAlign(block); + uiDefButBitI(block, TOG, USER_ZOOM_TO_MOUSEPOS, B_DRAWINFO, "Zoom to Mouse Position", + (xpos+edgsp+mpref+(2*spref)+(3*midsp)),y4,mpref,buth, + &(U.uiflag), 0, 0, 0, 0, + "Zoom in towards the mouse pointer's position in the 3D view, rather than the 2D window center"); + uiDefBut(block, LABEL,0,"View rotation:", - (xpos+(2*edgsp)+mpref+(2*spref)+(2*midsp)),y4label,mpref,buth, + (xpos+(2*edgsp)+mpref+(2*spref)+(2*midsp)),y3label,mpref,buth, 0, 0, 0, 0, 0, ""); uiBlockBeginAlign(block); uiBlockSetCol(block, TH_BUT_SETTING1); /* mutually exclusive toggles, start color */ uiDefButBitI(block, TOG, USER_TRACKBALL, B_DRAWINFO, "Trackball", - (xpos+edgsp+mpref+(2*spref)+(3*midsp)),y3,(mpref/2),buth, + (xpos+edgsp+mpref+(2*spref)+(3*midsp)),y2,(mpref/2),buth, &(U.flag), 0, 0, 0, 0, "Allow the view to tumble freely when orbiting with the Middle Mouse Button"); uiDefButBitI(block, TOGN, USER_TRACKBALL, B_DRAWINFO, "Turntable", - (xpos+edgsp+mpref+(2*spref)+(3*midsp)+(mpref/2)),y3,(mpref/2),buth, + (xpos+edgsp+mpref+(2*spref)+(3*midsp)+(mpref/2)),y2,(mpref/2),buth, &(U.flag), 0, 0, 0, 0, "Use fixed up axis for orbiting with Middle Mouse Button"); uiBlockSetCol(block, TH_AUTO); /* end color */ uiDefButBitI(block, TOG, USER_AUTOPERSP, B_DRAWINFO, "Auto Perspective", - (xpos+edgsp+mpref+(2*spref)+(3*midsp)),y2,(mpref/2),buth, + (xpos+edgsp+mpref+(2*spref)+(3*midsp)),y1,(mpref/2),buth, &(U.uiflag), 0, 0, 0, 0, "Automatically switch between orthographic and perspective when changing from top/front/side views"); uiDefButBitI(block, TOG, USER_ORBIT_SELECTION, B_DRAWINFO, "Around Selection", - (xpos+edgsp+mpref+(2*spref)+(3*midsp)+(mpref/2)),y2,(mpref/2),buth, + (xpos+edgsp+mpref+(2*spref)+(3*midsp)+(mpref/2)),y1,(mpref/2),buth, &(U.uiflag), 0, 0, 0, 0, "Use selection as the orbiting center"); uiBlockEndAlign(block); - - uiBlockBeginAlign(block); - uiDefButBitI(block, TOG, USER_SHOW_ROTVIEWICON, B_DRAWINFO, "Mini Axis", - (xpos+edgsp+(2*mpref)+(2*midsp)),y1,(mpref/3),buth, - &(U.uiflag), 0, 0, 0, 0, - "Show a small rotating 3D axis in the bottom left corner of the 3D View"); - uiDefButS(block, NUM, B_DRAWINFO, "Size:", - (xpos+edgsp+(2*mpref)+(2*midsp)+(mpref/3)),y1,(mpref/3),buth, - &U.rvisize, 10, 64, 0, 0, - "The axis icon's size"); - uiDefButS(block, NUM, B_DRAWINFO, "Bright:", - (xpos+edgsp+(2*mpref)+(2*midsp)+2*(mpref/3)),y1,(mpref/3),buth, - &U.rvibright, 0, 10, 0, 0, - "The brightness of the icon"); - uiBlockEndAlign(block); - - uiDefButS(block, NUM, B_DRAWINFO, "Rotation Angle:", - (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, ""); @@ -3474,7 +3453,21 @@ void drawinfospace(ScrArea *sa, void *spacedata) &(U.flag), 0, 0, 0, 0, "Emulates Middle Mouse with Alt+LeftMouse (doesnt work with Left Mouse Select option)"); - + uiBlockBeginAlign(block); + uiDefButBitI(block, TOG, USER_SHOW_ROTVIEWICON, B_DRAWINFO, "Mini Axis", + (xpos+edgsp+(3*mpref)+(4*midsp)),y1,(mpref/3),buth, + &(U.uiflag), 0, 0, 0, 0, + "Show a small rotating 3D axis in the bottom left corner of the 3D View"); + uiDefButS(block, NUM, B_DRAWINFO, "Size:", + (xpos+edgsp+(3*mpref)+(4*midsp)+(mpref/3)),y1,(mpref/3),buth, + &U.rvisize, 10, 64, 0, 0, + "The axis icon's size"); + uiDefButS(block, NUM, B_DRAWINFO, "Bright:", + (xpos+edgsp+(3*mpref)+(4*midsp)+2*(mpref/3)),y1,(mpref/3),buth, + &U.rvibright, 0, 10, 0, 0, + "The brightness of the icon"); + uiBlockEndAlign(block); + uiDefBut(block, LABEL,0,"Middle Mouse Button:", (xpos+(2*edgsp)+(4*mpref)+(4*midsp)),y6label,mpref,buth, 0, 0, 0, 0, 0, ""); @@ -3488,6 +3481,7 @@ void drawinfospace(ScrArea *sa, void *spacedata) &(U.flag), 0, 0, 0, 0, "Default action for the Middle Mouse Button"); uiBlockSetCol(block, TH_AUTO); /* end color */ uiBlockEndAlign(block); + uiDefBut(block, LABEL,0,"Mouse Wheel:", (xpos+(2*edgsp)+(4*mpref)+(4*midsp)),y4label,mpref,buth, @@ -3502,6 +3496,17 @@ void drawinfospace(ScrArea *sa, void *spacedata) &U.wheellinescroll, 0.0, 32.0, 0, 0, "The number of lines scrolled at a time with the mouse wheel"); uiBlockEndAlign(block); + + uiBlockBeginAlign(block); + uiDefButS(block, NUM, B_DRAWINFO, "Smooth View:", + (xpos+edgsp+(4*mpref)+(5*midsp)),y2,(mpref),buth, + &U.smooth_viewtx, 0, 1000, 0, 0, + "The time to animate the view in miliseconds, zero to disable"); + uiDefButS(block, NUM, B_DRAWINFO, "Rotation Angle:", + (xpos+edgsp+(4*mpref)+(5*midsp)),y1,(mpref),buth, + &U.pad_rot_angle, 0, 90, 0, 0, + "The rotation step for numerical pad keys (2 4 6 8)"); + uiBlockEndAlign(block); uiDefBut(block, LABEL,0,"3D Transform Widget:", diff --git a/source/blender/src/toets.c b/source/blender/src/toets.c index 6cbc732b847..6464f699d1a 100644 --- a/source/blender/src/toets.c +++ b/source/blender/src/toets.c @@ -109,6 +109,9 @@ #include "BIF_poseobject.h" +#define VIEW_ZOOM_OUT_FACTOR (1.15f) +#define VIEW_ZOOM_IN_FACTOR (1.0f/VIEW_ZOOM_OUT_FACTOR) + /* ------------------------------------------------------------------------- */ static int is_an_active_object(void *ob) { @@ -156,6 +159,7 @@ void persptoetsen(unsigned short event) float phi, si, q1[4], vec[3]; static int perspo=1; int preview3d_event= 1; + short mouseloc[2]; float new_dist, orig_ofs[3]; @@ -244,14 +248,20 @@ void persptoetsen(unsigned short event) if(G.vd->persp==2) { G.vd->camzoom= MAX2(-30, G.vd->camzoom-5); } - else if(G.vd->dist<10.0*G.vd->far) G.vd->dist*=1.2f; + else if(G.vd->dist<10.0*G.vd->far) { + getmouseco_areawin(mouseloc); + view_zoom_mouseloc(VIEW_ZOOM_OUT_FACTOR, mouseloc); + } if(G.vd->persp!=1) preview3d_event= 0; } else if(event==PADPLUSKEY) { if(G.vd->persp==2) { G.vd->camzoom= MIN2(300, G.vd->camzoom+5); } - else if(G.vd->dist> 0.001*G.vd->grid) G.vd->dist*=.83333f; + else if(G.vd->dist> 0.001*G.vd->grid) { + getmouseco_areawin(mouseloc); + view_zoom_mouseloc(VIEW_ZOOM_IN_FACTOR, mouseloc); + } if(G.vd->persp!=1) preview3d_event= 0; } else if(event==PAD5) { diff --git a/source/blender/src/view.c b/source/blender/src/view.c index 9b4f65fbc81..4ddd6d71dea 100644 --- a/source/blender/src/view.c +++ b/source/blender/src/view.c @@ -543,7 +543,7 @@ void viewmove(int mode) float reverse, oldquat[4], q1[4], si, phi, dist0; float ofs[3], obofs[3]= {0.0f, 0.0f, 0.0f}; int firsttime=1; - short mvalball[2], mval[2], mvalo[2]; + short mvalball[2], mval[2], mvalo[2], mval_area[2]; short use_sel = 0; short preview3d_event= 1; @@ -561,6 +561,7 @@ void viewmove(int mode) QUATCOPY(oldquat, G.vd->viewquat); + getmouseco_areawin(mval_area); /* for zoom to mouse loc */ getmouseco_sc(mvalo); /* work with screen coordinates because of trackball function */ mvalball[0]= mvalo[0]; /* needed for turntable to work */ mvalball[1]= mvalo[1]; @@ -733,9 +734,10 @@ void viewmove(int mode) } } else if(mode==2) { + float zfac=1.0; if(U.viewzoom==USER_ZOOM_CONT) { // oldstyle zoom - G.vd->dist*= 1.0+(float)(mvalo[0]-mval[0]+mvalo[1]-mval[1])/1000.0; + zfac = 1.0+(float)(mvalo[0]-mval[0]+mvalo[1]-mval[1])/1000.0; } else if(U.viewzoom==USER_ZOOM_SCALE) { int ctr[2], len1, len2; @@ -747,14 +749,17 @@ void viewmove(int mode) len1 = (int)sqrt((ctr[0] - mval[0])*(ctr[0] - mval[0]) + (ctr[1] - mval[1])*(ctr[1] - mval[1])) + 5; len2 = (int)sqrt((ctr[0] - mvalo[0])*(ctr[0] - mvalo[0]) + (ctr[1] - mvalo[1])*(ctr[1] - mvalo[1])) + 5; - G.vd->dist= dist0 * ((float)len2/len1); + zfac = dist0 * ((float)len2/len1) / G.vd->dist; } else { /* USER_ZOOM_DOLLY */ float len1 = (curarea->winrct.ymax - mval[1]) + 5; float len2 = (curarea->winrct.ymax - mvalo[1]) + 5; - - G.vd->dist= dist0 * (2.0*((len2/len1)-1.0) + 1.0); + zfac = dist0 * (2.0*((len2/len1)-1.0) + 1.0) / G.vd->dist; } + + if(zfac != 1.0 && zfac*G.vd->dist > 0.001*G.vd->grid && + zfac*G.vd->dist < 10.0*G.vd->far) + view_zoom_mouseloc(zfac, mval_area); /* these limits are in toets.c too */ if(G.vd->dist<0.001*G.vd->grid) G.vd->dist= 0.001*G.vd->grid; @@ -804,6 +809,49 @@ void viewmove(int mode) BIF_view3d_previewrender_signal(curarea, PR_PROJECTED); } + +void view_zoom_mouseloc(float dfac, short *mouseloc) +{ + if(U.uiflag & USER_ZOOM_TO_MOUSEPOS) { + short vb[2]; + float dvec[3]; + float tvec[3]; + float tpos[3]; + float new_dist; + + /* find the current window width and height */ + vb[0] = G.vd->area->winx; + vb[1] = G.vd->area->winy; + + tpos[0] = -G.vd->ofs[0]; + tpos[1] = -G.vd->ofs[1]; + tpos[2] = -G.vd->ofs[2]; + + /* Project cursor position into 3D space */ + initgrabz(tpos[0], tpos[1], tpos[2]); + window_to_3d(dvec, mouseloc[0]-vb[0]/2, mouseloc[1]-vb[1]/2); + + /* Calculate view target position for dolly */ + tvec[0] = -(tpos[0] + dvec[0]); + tvec[1] = -(tpos[1] + dvec[1]); + tvec[2] = -(tpos[2] + dvec[2]); + + /* Offset to target position and dolly */ + new_dist = G.vd->dist * dfac; + + VECCOPY(G.vd->ofs, tvec); + G.vd->dist = new_dist; + + /* Calculate final offset */ + dvec[0] = tvec[0] + dvec[0] * dfac; + dvec[1] = tvec[1] + dvec[1] * dfac; + dvec[2] = tvec[2] + dvec[2] * dfac; + + VECCOPY(G.vd->ofs, dvec); + } else { + G.vd->dist *= dfac; + } +} /* Gets the lens and clipping values from a camera of lamp type object */ void object_view_settings(Object *ob, float *lens, float *clipsta, float *clipend) |