diff options
author | Ton Roosendaal <ton@blender.org> | 2008-12-26 21:15:46 +0300 |
---|---|---|
committer | Ton Roosendaal <ton@blender.org> | 2008-12-26 21:15:46 +0300 |
commit | 6086c31fd3c0c008a2fd98314c57d7ffc5405e1d (patch) | |
tree | f593a9261413614e4de27cd55bf0e40dd5b6482e /source/blender | |
parent | ce733db5cb6b79c63a3a320c97cc986351b27176 (diff) |
2.5
Brought back 'smooth view'. Took some hours to untangle it all,
code was spread all over, instead of localized in 1 call. Tsk!
Still not perfect, but at least more in control. For the hackers;
check void smooth_view() in view3d_view.c, here all 3d view
stuff should be handled, so it can optionally use animating.
For the users: 'smooth view' now plays at a maximum of 30 hz,
and doesn't block anymore. So even slow animated views remain
responsive if you press many numpad keys.
Diffstat (limited to 'source/blender')
-rw-r--r-- | source/blender/blenloader/intern/readfile.c | 2 | ||||
-rw-r--r-- | source/blender/editors/space_view3d/view3d_edit.c | 167 | ||||
-rw-r--r-- | source/blender/editors/space_view3d/view3d_header.c | 30 | ||||
-rw-r--r-- | source/blender/editors/space_view3d/view3d_intern.h | 5 | ||||
-rw-r--r-- | source/blender/editors/space_view3d/view3d_ops.c | 3 | ||||
-rw-r--r-- | source/blender/editors/space_view3d/view3d_view.c | 366 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_view3d_types.h | 6 | ||||
-rw-r--r-- | source/blender/windowmanager/intern/wm_event_system.c | 3 |
8 files changed, 285 insertions, 297 deletions
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index cc4a2d800b9..2ef315d6841 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -4248,6 +4248,8 @@ static void direct_link_screen(FileData *fd, bScreen *sc) v3d->clipbb= newdataadr(fd, v3d->clipbb); v3d->retopo_view_data= NULL; v3d->properties_storage= NULL; + v3d->sms= NULL; + v3d->smooth_timer= NULL; } else if (sl->spacetype==SPACE_OOPS) { SpaceOops *soops= (SpaceOops*) sl; diff --git a/source/blender/editors/space_view3d/view3d_edit.c b/source/blender/editors/space_view3d/view3d_edit.c index 75abc27ce73..8b7da3e24dc 100644 --- a/source/blender/editors/space_view3d/view3d_edit.c +++ b/source/blender/editors/space_view3d/view3d_edit.c @@ -724,24 +724,13 @@ static int viewhome_exec(bContext *C, wmOperator *op) /* was view3d_home() in 2. new_dist*= size; } - if (v3d->persp==V3D_CAMOB && v3d->camera) { - /* switch out of camera view */ - float orig_lens= v3d->lens; - + if (v3d->persp==V3D_CAMOB) { v3d->persp= V3D_PERSP; - v3d->dist= 0.0; - view_settings_from_ob(v3d->camera, v3d->ofs, NULL, NULL, &v3d->lens); - smooth_view(v3d, new_ofs, NULL, &new_dist, &orig_lens); /* TODO - this dosnt work yet */ - - } else { - if(v3d->persp==V3D_CAMOB) v3d->persp= V3D_PERSP; - smooth_view(v3d, new_ofs, NULL, &new_dist, NULL); /* TODO - this dosnt work yet */ + smooth_view(C, NULL, v3d->camera, new_ofs, NULL, &new_dist, NULL); } } // XXX BIF_view3d_previewrender_signal(curarea, PR_DBASE|PR_DISPRECT); - ED_region_tag_redraw(ar); - return OPERATOR_FINISHED; } @@ -861,24 +850,16 @@ static int viewcenter_exec(bContext *C, wmOperator *op) /* like a localview with v3d->cursor[1]= -new_ofs[1]; v3d->cursor[2]= -new_ofs[2]; - if (v3d->persp==V3D_CAMOB && v3d->camera) { - float orig_lens= v3d->lens; - - v3d->persp=V3D_PERSP; - v3d->dist= 0.0f; - view_settings_from_ob(v3d->camera, v3d->ofs, NULL, NULL, &v3d->lens); - smooth_view(v3d, new_ofs, NULL, &new_dist, &orig_lens); - } else { - if(v3d->persp==V3D_CAMOB) - v3d->persp= V3D_PERSP; - - smooth_view(v3d, new_ofs, NULL, &new_dist, NULL); + if (v3d->persp==V3D_CAMOB) { + v3d->persp= V3D_PERSP; + smooth_view(C, v3d->camera, NULL, new_ofs, NULL, &new_dist, NULL); + } + else { + smooth_view(C, NULL, NULL, new_ofs, NULL, &new_dist, NULL); } // XXX BIF_view3d_previewrender_signal(curarea, PR_DBASE|PR_DISPRECT); - ED_region_tag_redraw(ar); - return OPERATOR_FINISHED; } void VIEW3D_OT_viewcenter(wmOperatorType *ot) @@ -914,56 +895,47 @@ static EnumPropertyItem prop_view_items[] = { {V3D_VIEW_PANDOWN, "PANDOWN", "Pan Down", "Pan the view Down"}, {0, NULL, NULL, NULL}}; -static void axis_set_view(View3D *v3d, float q1, float q2, float q3, float q4, short view, int perspo) +static void axis_set_view(bContext *C, View3D *v3d, float q1, float q2, float q3, float q4, short view, int perspo) { float new_quat[4]; new_quat[0]= q1; new_quat[1]= q2; new_quat[2]= q3; new_quat[3]= q4; v3d->view=0; - + v3d->view= view; + if (v3d->persp==V3D_CAMOB && v3d->camera) { - /* Is this switching from a camera view ? */ - float orig_ofs[3]; - float orig_lens= v3d->lens; - VECCOPY(orig_ofs, v3d->ofs); - view_settings_from_ob(v3d->camera, v3d->ofs, v3d->viewquat, &v3d->dist, &v3d->lens); - if (U.uiflag & USER_AUTOPERSP) v3d->persp= V3D_ORTHO; else if(v3d->persp==V3D_CAMOB) v3d->persp= perspo; - smooth_view(v3d, orig_ofs, new_quat, NULL, &orig_lens); - } else { + smooth_view(C, v3d->camera, NULL, v3d->ofs, new_quat, NULL, NULL); + } + else { if (U.uiflag & USER_AUTOPERSP) v3d->persp= V3D_ORTHO; else if(v3d->persp==V3D_CAMOB) v3d->persp= perspo; - smooth_view(v3d, NULL, new_quat, NULL, NULL); + smooth_view(C, NULL, NULL, NULL, new_quat, NULL, NULL); } - v3d->view= view; + } + static int viewnumpad_exec(bContext *C, wmOperator *op) { ScrArea *sa= CTX_wm_area(C); ARegion *ar= CTX_wm_region(C); View3D *v3d= sa->spacedata.first; Scene *scene= CTX_data_scene(C); - Object *act_cam_orig=NULL; - float phi, si, q1[4], vec[3]; static int perspo=V3D_PERSP; - float orig_ofs[3]; int viewnum; viewnum = RNA_enum_get(op->ptr, "viewnum"); /* Use this to test if we started out with a camera */ - if (v3d->persp == V3D_CAMOB) - act_cam_orig = v3d->camera; - /* Indicate that this view is inverted, * but only if it actually _was_ inverted (jobbe) */ if (viewnum == V3D_VIEW_BOTTOM || viewnum == V3D_VIEW_BACK || viewnum == V3D_VIEW_LEFT) @@ -973,50 +945,36 @@ static int viewnumpad_exec(bContext *C, wmOperator *op) switch (viewnum) { case V3D_VIEW_BOTTOM : - axis_set_view(v3d,0.0, -1.0, 0.0, 0.0, 7, perspo); + axis_set_view(C, v3d, 0.0, -1.0, 0.0, 0.0, 7, perspo); break; case V3D_VIEW_BACK: - axis_set_view(v3d,0.0, 0.0, (float)-cos(M_PI/4.0), (float)-cos(M_PI/4.0), 1, perspo); + axis_set_view(C, v3d, 0.0, 0.0, (float)-cos(M_PI/4.0), (float)-cos(M_PI/4.0), 1, perspo); break; case V3D_VIEW_LEFT: - axis_set_view(v3d,0.5, -0.5, 0.5, 0.5, 3, perspo); + axis_set_view(C, v3d, 0.5, -0.5, 0.5, 0.5, 3, perspo); break; case V3D_VIEW_TOP: - axis_set_view(v3d,1.0, 0.0, 0.0, 0.0, 7, perspo); + axis_set_view(C, v3d, 1.0, 0.0, 0.0, 0.0, 7, perspo); break; case V3D_VIEW_FRONT: - axis_set_view(v3d,(float)cos(M_PI/4.0), (float)-sin(M_PI/4.0), 0.0, 0.0, 1, perspo); + axis_set_view(C, v3d, (float)cos(M_PI/4.0), (float)-sin(M_PI/4.0), 0.0, 0.0, 1, perspo); break; case V3D_VIEW_RIGHT: - axis_set_view(v3d,0.5, -0.5, -0.5, -0.5, 3, perspo); + axis_set_view(C, v3d, 0.5, -0.5, -0.5, -0.5, 3, perspo); break; case V3D_VIEW_PERSPORTHO: - if (U.smooth_viewtx) { - if(v3d->persp==V3D_PERSP) { v3d->persp=V3D_ORTHO; - } else if (act_cam_orig) { - /* were from a camera view */ - float orig_dist= v3d->dist; - float orig_lens= v3d->lens; - VECCOPY(orig_ofs, v3d->ofs); - v3d->persp=V3D_PERSP; - v3d->dist= 0.0; - - view_settings_from_ob(act_cam_orig, v3d->ofs, NULL, NULL, &v3d->lens); - smooth_view(v3d, orig_ofs, NULL, &orig_dist, &orig_lens); - } else { - v3d->persp=V3D_PERSP; - } - } else { - if(v3d->persp==V3D_PERSP) v3d->persp=V3D_ORTHO; - else v3d->persp=V3D_PERSP; - } + if(v3d->persp!=V3D_ORTHO) + v3d->persp=V3D_ORTHO; + else v3d->persp=V3D_PERSP; + + ED_region_tag_redraw(ar); break; case V3D_VIEW_CAMERA: @@ -1027,48 +985,36 @@ static int viewnumpad_exec(bContext *C, wmOperator *op) QUATCOPY(v3d->lviewquat, v3d->viewquat); v3d->lview= v3d->view; v3d->lpersp= v3d->persp; - } - else{ - /* return to settings of last view */ - - axis_set_view(v3d,v3d->lviewquat[0], v3d->lviewquat[1], v3d->lviewquat[2], v3d->lviewquat[3], v3d->lview, v3d->lpersp); - } + #if 0 - if(G.qual==LR_ALTKEY) { - if(oldcamera && is_an_active_object(oldcamera)) { - v3d->camera= oldcamera; + if(G.qual==LR_ALTKEY) { + if(oldcamera && is_an_active_object(oldcamera)) { + v3d->camera= oldcamera; + } + handle_view3d_lock(); } - handle_view3d_lock(); - } #endif - - if(BASACT) { - /* check both G.vd as G.scene cameras */ - if((v3d->camera==NULL || scene->camera==NULL) && OBACT->type==OB_CAMERA) { - v3d->camera= OBACT; - /*handle_view3d_lock();*/ + + if(BASACT) { + /* check both G.vd as G.scene cameras */ + if((v3d->camera==NULL || scene->camera==NULL) && OBACT->type==OB_CAMERA) { + v3d->camera= OBACT; + /*handle_view3d_lock();*/ + } + } + + if(v3d->camera==NULL) { + v3d->camera= scene_find_camera(scene); + /*handle_view3d_lock();*/ } - } - - if(v3d->camera==0) { - v3d->camera= scene_find_camera(scene); - /*handle_view3d_lock();*/ - } - if(v3d->camera && (v3d->camera != act_cam_orig)) { v3d->persp= V3D_CAMOB; - v3d->view= 0; - - } else if (U.smooth_viewtx) { - /* move 3d view to camera view */ - float orig_lens = v3d->lens; - VECCOPY(orig_ofs, v3d->ofs); - - if (act_cam_orig) - view_settings_from_ob(act_cam_orig, v3d->ofs, v3d->viewquat, &v3d->dist, &v3d->lens); - - smooth_view_to_camera(v3d); - VECCOPY(v3d->ofs, orig_ofs); - v3d->lens = orig_lens; + smooth_view(C, NULL, v3d->camera, v3d->ofs, v3d->viewquat, &v3d->dist, &v3d->lens); + + } + else{ + /* return to settings of last view */ + /* does smooth_view too */ + axis_set_view(C, v3d, v3d->lviewquat[0], v3d->lviewquat[1], v3d->lviewquat[2], v3d->lviewquat[3], v3d->lview, v3d->lpersp); } break; @@ -1104,6 +1050,7 @@ static int viewnumpad_exec(bContext *C, wmOperator *op) QuatMul(v3d->viewquat, v3d->viewquat, q1); v3d->view= 0; } + ED_region_tag_redraw(ar); } break; @@ -1122,6 +1069,7 @@ static int viewnumpad_exec(bContext *C, wmOperator *op) v3d->ofs[1]+= vec[1]; v3d->ofs[2]+= vec[2]; + ED_region_tag_redraw(ar); break; default : @@ -1130,9 +1078,6 @@ static int viewnumpad_exec(bContext *C, wmOperator *op) if(v3d->persp != V3D_CAMOB) perspo= v3d->persp; - - WM_event_add_notifier(C, WM_NOTE_WINDOW_REDRAW, 0, NULL); - return OPERATOR_FINISHED; } @@ -1416,7 +1361,7 @@ void view3d_border_zoom(Scene *scene, ARegion *ar, View3D *v3d) new_dist = ((new_dist*scale) >= 0.001*v3d->grid)? new_dist*scale:0.001*v3d->grid; } - smooth_view(v3d, new_ofs, NULL, &new_dist, NULL); + smooth_view(NULL, NULL, NULL, new_ofs, NULL, &new_dist, NULL); // XXX } diff --git a/source/blender/editors/space_view3d/view3d_header.c b/source/blender/editors/space_view3d/view3d_header.c index dac80f09646..deb8c29d3e6 100644 --- a/source/blender/editors/space_view3d/view3d_header.c +++ b/source/blender/editors/space_view3d/view3d_header.c @@ -259,30 +259,12 @@ static void do_view3d_view_camerasmenu(bContext *C, void *arg, int event) if (v3d->camera == base->object && v3d->persp==V3D_CAMOB) return; - if (U.smooth_viewtx) { - /* move 3d view to camera view */ - float orig_ofs[3], orig_lens = v3d->lens; - VECCOPY(orig_ofs, v3d->ofs); - - if (v3d->camera && v3d->persp==V3D_CAMOB) - view_settings_from_ob(v3d->camera, v3d->ofs, v3d->viewquat, &v3d->dist, &v3d->lens); - - v3d->camera = base->object; - handle_view3d_lock(); - v3d->persp= V3D_CAMOB; - v3d->view= 0; - - smooth_view_to_camera(v3d); - - /* restore values */ - VECCOPY(v3d->ofs, orig_ofs); - v3d->lens = orig_lens; - } else { - v3d->camera= base->object; - handle_view3d_lock(); - v3d->persp= V3D_CAMOB; - v3d->view= 0; - } + /* XXX handle smooth view */ + v3d->camera= base->object; + handle_view3d_lock(); + v3d->persp= V3D_CAMOB; + v3d->view= 0; + break; } } diff --git a/source/blender/editors/space_view3d/view3d_intern.h b/source/blender/editors/space_view3d/view3d_intern.h index e0b674678a6..a36a04cf6be 100644 --- a/source/blender/editors/space_view3d/view3d_intern.h +++ b/source/blender/editors/space_view3d/view3d_intern.h @@ -118,6 +118,8 @@ void VIEW3D_OT_borderselect(struct wmOperatorType *ot); void VIEW3D_OT_circle_select(struct wmOperatorType *ot); /* view3d_view.c */ +void VIEW3D_OT_smoothview(struct wmOperatorType *ot); + void view3d_operator_needs_opengl(const struct bContext *C); void viewline(ARegion *ar, View3D *v3d, short mval[2], float ray_start[3], float ray_end[3]); void viewray(ARegion *ar, View3D *v3d, short mval[2], float ray_start[3], float ray_normal[3]); @@ -152,8 +154,7 @@ void centerview(ARegion *ar, View3D *v3d); void view3d_align_axis_to_vector(View3D *v3d, int axisidx, float vec[3]); -void smooth_view(View3D *v3d, float *ofs, float *quat, float *dist, float *lens); -void smooth_view_to_camera(View3D *v3d); +void smooth_view(struct bContext *C, Object *, Object *, float *ofs, float *quat, float *dist, float *lens); void setwinmatrixview3d(View3D *v3d, int winx, int winy, rctf *rect); /* rect: for picking */ void setviewmatrixview3d(View3D *v3d); diff --git a/source/blender/editors/space_view3d/view3d_ops.c b/source/blender/editors/space_view3d/view3d_ops.c index 75b4cea0bb9..0e3e2c73fe9 100644 --- a/source/blender/editors/space_view3d/view3d_ops.c +++ b/source/blender/editors/space_view3d/view3d_ops.c @@ -71,6 +71,7 @@ void view3d_operatortypes(void) WM_operatortype_append(VIEW3D_OT_borderselect); WM_operatortype_append(VIEW3D_OT_clipping); WM_operatortype_append(VIEW3D_OT_circle_select); + WM_operatortype_append(VIEW3D_OT_smoothview); } void view3d_keymap(wmWindowManager *wm) @@ -82,6 +83,8 @@ void view3d_keymap(wmWindowManager *wm) WM_keymap_verify_item(keymap, "VIEW3D_OT_viewzoom", MIDDLEMOUSE, KM_PRESS, KM_CTRL, 0); WM_keymap_verify_item(keymap, "VIEW3D_OT_viewcenter", PADPERIOD, KM_PRESS, 0, 0); + WM_keymap_verify_item(keymap, "VIEW3D_OT_smoothview", TIMER1, KM_ANY, KM_ANY, 0); + RNA_int_set(WM_keymap_add_item(keymap, "VIEW3D_OT_viewzoom", PADPLUSKEY, KM_PRESS, 0, 0)->ptr, "delta", 1); RNA_int_set(WM_keymap_add_item(keymap, "VIEW3D_OT_viewzoom", PADMINUS, KM_PRESS, 0, 0)->ptr, "delta", -1); RNA_int_set(WM_keymap_add_item(keymap, "VIEW3D_OT_viewzoom", WHEELUPMOUSE, KM_ANY, 0, 0)->ptr, "delta", 1); diff --git a/source/blender/editors/space_view3d/view3d_view.c b/source/blender/editors/space_view3d/view3d_view.c index 7c2f5a7d5ab..9b5b2cf6211 100644 --- a/source/blender/editors/space_view3d/view3d_view.c +++ b/source/blender/editors/space_view3d/view3d_view.c @@ -64,6 +64,7 @@ #include "BIF_gl.h" #include "WM_api.h" +#include "WM_types.h" #include "ED_screen.h" @@ -77,6 +78,8 @@ #define BL_NEAR_CLIP 0.001 + + /* use this call when executing an operator, event system doesn't set for each event the opengl drawing context */ @@ -105,6 +108,201 @@ float *give_cursor(Scene *scene, View3D *v3d) else return scene->cursor; } +/* ****************** smooth view operator ****************** */ + +struct SmoothViewStore { + float orig_dist, new_dist; + float orig_lens, new_lens; + float orig_quat[4], new_quat[4]; + float orig_ofs[3], new_ofs[3]; + + int to_camera, orig_view; + + double time_allowed; +}; + +/* will start timer if appropriate */ +/* the arguments are the desired situation */ +void smooth_view(bContext *C, Object *oldcamera, Object *camera, float *ofs, float *quat, float *dist, float *lens) +{ + View3D *v3d= (View3D *)CTX_wm_space_data(C); + struct SmoothViewStore sms; + + /* initialize sms */ + VECCOPY(sms.new_ofs, v3d->ofs); + QUATCOPY(sms.new_quat, v3d->viewquat); + sms.new_dist= v3d->dist; + sms.new_lens= v3d->lens; + sms.to_camera= 0; + + /* store the options we want to end with */ + if(ofs) VECCOPY(sms.new_ofs, ofs); + if(quat) QUATCOPY(sms.new_quat, quat); + if(dist) sms.new_dist= *dist; + if(lens) sms.new_lens= *lens; + + if (camera) { + view_settings_from_ob(camera, sms.new_ofs, sms.new_quat, &sms.new_dist, &sms.new_lens); + sms.to_camera= 1; /* restore view3d values in end */ + } + + if (C && U.smooth_viewtx) { + int changed = 0; /* zero means no difference */ + + if (sms.new_dist != v3d->dist) + changed = 1; + if (sms.new_lens != v3d->lens) + changed = 1; + + if ((sms.new_ofs[0]!=v3d->ofs[0]) || + (sms.new_ofs[1]!=v3d->ofs[1]) || + (sms.new_ofs[2]!=v3d->ofs[2]) ) + changed = 1; + + if ((sms.new_quat[0]!=v3d->viewquat[0]) || + (sms.new_quat[1]!=v3d->viewquat[1]) || + (sms.new_quat[2]!=v3d->viewquat[2]) || + (sms.new_quat[3]!=v3d->viewquat[3]) ) + changed = 1; + + /* The new view is different from the old one + * so animate the view */ + if (changed) { + + sms.time_allowed= (double)U.smooth_viewtx / 1000.0; + + /* 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, sms.new_quat); + VECCOPY(vec2, sms.orig_quat); + Normalize(vec1); + Normalize(vec2); + /* scale the time allowed by the rotation */ + sms.time_allowed *= NormalizedVecAngle2(vec1, vec2)/(M_PI/2); + } + + /* original values */ + if (oldcamera) { + sms.orig_dist= v3d->dist; // below function does weird stuff with it... + view_settings_from_ob(oldcamera, sms.orig_ofs, sms.orig_quat, &sms.orig_dist, &sms.orig_lens); + } + else { + VECCOPY(sms.orig_ofs, v3d->ofs); + QUATCOPY(sms.orig_quat, v3d->viewquat); + sms.orig_dist= v3d->dist; + sms.orig_lens= v3d->lens; + } + /* grid draw as floor */ + sms.orig_view= v3d->view; + v3d->view= 0; + + /* ensure it shows correct */ + if(sms.to_camera) v3d->persp= V3D_PERSP; + + /* keep track of running timer! */ + if(v3d->sms==NULL) + v3d->sms= MEM_mallocN(sizeof(struct SmoothViewStore), "smoothview v3d"); + *v3d->sms= sms; + if(v3d->smooth_timer) + WM_event_remove_window_timer(CTX_wm_window(C), v3d->smooth_timer); + /* TIMER1 is hardcoded in keymap */ + v3d->smooth_timer= WM_event_add_window_timer(CTX_wm_window(C), TIMER1, 1.0/30.0); /* max 30 frs/sec */ + + return; + } + } + + /* if we get here nothing happens */ + if(sms.to_camera==0) { + VECCOPY(v3d->ofs, sms.new_ofs); + QUATCOPY(v3d->viewquat, sms.new_quat); + v3d->dist = sms.new_dist; + v3d->lens = sms.new_lens; + } + ED_region_tag_redraw(CTX_wm_region(C)); +} + +/* only meant for timer usage */ +static int view3d_smoothview_invoke(bContext *C, wmOperator *op, wmEvent *event) +{ + View3D *v3d= (View3D *)CTX_wm_space_data(C); + struct SmoothViewStore *sms= v3d->sms; + double step, step_inv; + + /* escape if not our timer */ + if(v3d->smooth_timer==NULL || v3d->smooth_timer!=event->customdata) + return OPERATOR_PASS_THROUGH; + + step = (v3d->smooth_timer->duration)/sms->time_allowed; + + /* end timer */ + if(step >= 1.0f) { + + /* if we went to camera, store the original */ + if(sms->to_camera) { + v3d->persp= V3D_CAMOB; + VECCOPY(v3d->ofs, sms->orig_ofs); + QUATCOPY(v3d->viewquat, sms->orig_quat); + v3d->dist = sms->orig_dist; + v3d->lens = sms->orig_lens; + } + else { + VECCOPY(v3d->ofs, sms->new_ofs); + QUATCOPY(v3d->viewquat, sms->new_quat); + v3d->dist = sms->new_dist; + v3d->lens = sms->new_lens; + } + v3d->view= sms->orig_view; + + MEM_freeN(v3d->sms); + v3d->sms= NULL; + + WM_event_remove_window_timer(CTX_wm_window(C), v3d->smooth_timer); + v3d->smooth_timer= NULL; + } + else { + int i; + + /* ease in/out */ + if (step < 0.5) step = (float)pow(step*2, 2)/2; + else step = (float)1-(pow(2*(1-step),2)/2); + + step_inv = 1.0-step; + + for (i=0; i<3; i++) + v3d->ofs[i] = sms->new_ofs[i]*step + sms->orig_ofs[i]*step_inv; + + QuatInterpol(v3d->viewquat, sms->orig_quat, sms->new_quat, step); + + v3d->dist = sms->new_dist*step + sms->orig_dist*step_inv; + v3d->lens = sms->new_lens*step + sms->orig_lens*step_inv; + } + + ED_region_tag_redraw(CTX_wm_region(C)); + + return OPERATOR_FINISHED; +} + +void VIEW3D_OT_smoothview(wmOperatorType *ot) +{ + + /* identifiers */ + ot->name= "Smooth View"; + ot->idname= "VIEW3D_OT_smoothview"; + + /* api callbacks */ + ot->invoke= view3d_smoothview_invoke; + + ot->poll= ED_operator_areaactive; +} + +/* ********************************** */ + /* create intersection coordinates in view Z direction at mouse coordinates */ void viewline(ARegion *ar, View3D *v3d, short mval[2], float ray_start[3], float ray_end[3]) { @@ -599,7 +797,7 @@ void setwinmatrixview3d(View3D *v3d, int winx, int winy, rctf *rect) /* rect: f /* Gets the lens and clipping values from a camera of lamp type object */ -static void object_view_settings(Object *ob, float *lens, float *clipsta, float *clipend) +static void object_lens_clip_settings(Object *ob, float *lens, float *clipsta, float *clipend) { if (!ob) return; @@ -620,6 +818,9 @@ static void object_view_settings(Object *ob, float *lens, float *clipsta, float if (clipsta) *clipsta= cam->clipsta; if (clipend) *clipend= cam->clipend; } + else { + if (lens) *lens= 35.0f; + } } @@ -664,7 +865,7 @@ void view_settings_from_ob(Object *ob, float *ofs, float *quat, float *dist, flo /* Lens */ if (lens) - object_view_settings(ob, lens, NULL, NULL); + object_lens_clip_settings(ob, lens, NULL, NULL); } @@ -698,13 +899,13 @@ void obmat_to_viewmat(View3D *v3d, Object *ob, short smooth) v3d->dist= 0.0; view_settings_from_ob(v3d->camera, v3d->ofs, NULL, NULL, &v3d->lens); - smooth_view(v3d, orig_ofs, new_quat, &orig_dist, &orig_lens); + smooth_view(NULL, NULL, NULL, orig_ofs, new_quat, &orig_dist, &orig_lens); // XXX v3d->persp=V3D_CAMOB; /* just to be polite, not needed */ } else { Mat3ToQuat(tmat, new_quat); - smooth_view(v3d, NULL, new_quat, NULL, NULL); + smooth_view(NULL, NULL, NULL, NULL, new_quat, NULL, NULL); // XXX } } else { Mat3ToQuat(tmat, v3d->viewquat); @@ -1096,163 +1297,10 @@ void view3d_align_axis_to_vector(View3D *v3d, int axisidx, float vec[3]) v3d->persp= V3D_PERSP; v3d->dist= 0.0; view_settings_from_ob(v3d->camera, v3d->ofs, NULL, NULL, &v3d->lens); - smooth_view(v3d, orig_ofs, new_quat, &orig_dist, &orig_lens); + smooth_view(NULL, NULL, NULL, orig_ofs, new_quat, &orig_dist, &orig_lens); // XXX } else { if (v3d->persp==V3D_CAMOB) v3d->persp= V3D_PERSP; /* switch out of camera mode */ - smooth_view(v3d, NULL, new_quat, NULL, NULL); + smooth_view(NULL, NULL, NULL, NULL, new_quat, NULL, NULL); // XXX } } - - -/* SMOOTHVIEW */ -void smooth_view(View3D *v3d, float *ofs, float *quat, float *dist, float *lens) -{ - /* View Animation enabled */ - if (U.smooth_viewtx) { - int i; - char changed = 0; - float step = 0.0, step_inv; - float orig_dist; - float orig_lens; - 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 (lens) { - if ((*lens) != v3d->lens) - 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 the 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; - orig_lens = v3d->lens; - - 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 = (float)pow(step*2, 2)/2; - else step = (float)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); - - if (lens) - v3d->lens = ((*lens)*step) + (orig_lens*step_inv); - - /*redraw the view*/ - // scrarea_do_windraw(ar); - // 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; - if (lens) - v3d->lens = *lens; - -} - -/* For use with smooth view -* -* the current view is unchanged, blend between the current view and the -* camera view -* */ -void smooth_view_to_camera(View3D *v3d) -{ - if (!U.smooth_viewtx || !v3d->camera || v3d->persp != V3D_CAMOB) { - return; - } else { - Object *ob = v3d->camera; - - float orig_ofs[3]; - float orig_dist=v3d->dist; - float orig_lens=v3d->lens; - float new_dist=0.0; - float new_lens=35.0; - float new_quat[4]; - float new_ofs[3]; - - VECCOPY(orig_ofs, v3d->ofs); - - view_settings_from_ob(ob, new_ofs, new_quat, NULL, &new_lens); - - v3d->persp= V3D_PERSP; - smooth_view(v3d, new_ofs, new_quat, &new_dist, &new_lens); - VECCOPY(v3d->ofs, orig_ofs); - v3d->lens= orig_lens; - v3d->dist = orig_dist; /* restore the dist */ - - v3d->camera = ob; - v3d->persp= V3D_CAMOB; - } -} - - diff --git a/source/blender/makesdna/DNA_view3d_types.h b/source/blender/makesdna/DNA_view3d_types.h index 3d053625308..e819ce8a7cd 100644 --- a/source/blender/makesdna/DNA_view3d_types.h +++ b/source/blender/makesdna/DNA_view3d_types.h @@ -41,6 +41,8 @@ struct BoundBox; struct RenderInfo; struct RetopoViewData; struct bGPdata; +struct SmoothViewStore; +struct wmTimer; /* This is needed to not let VC choke on near and far... old * proprietary MS extensions... */ @@ -143,6 +145,10 @@ typedef struct View3D { void *properties_storage; /* Nkey panel stores stuff here, not in file */ struct bGPdata *gpd; /* Grease-Pencil Data (annotation layers) */ + /* animated smooth view */ + struct SmoothViewStore *sms; + struct wmTimer *smooth_timer; + /* last view */ float lviewquat[4]; short lpersp, lview; diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c index ff9e135b83c..eeda0226dd9 100644 --- a/source/blender/windowmanager/intern/wm_event_system.c +++ b/source/blender/windowmanager/intern/wm_event_system.c @@ -44,6 +44,7 @@ #include "BKE_context.h" #include "BKE_idprop.h" #include "BKE_global.h" +#include "BKE_utildefines.h" #include "ED_screen.h" #include "ED_space_api.h" @@ -504,7 +505,7 @@ static int wm_eventmatch(wmEvent *winevent, wmKeymapItem *kmi) static int wm_event_always_pass(wmEvent *event) { /* some events we always pass on, to ensure proper communication */ - return (event->type == TIMER); + return ELEM4(event->type, TIMER, TIMER0, TIMER1, TIMER2); } /* Warning: this function removes a modal handler, when finished */ |