From af3f7db4ec3b75043c8aa1e5332145e8910c0849 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sat, 29 Apr 2017 03:13:49 +1000 Subject: Fix T51324: Auto-Depth fails rotating out of camera --- source/blender/editors/space_view3d/view3d_edit.c | 116 ++++++++++++++-------- 1 file changed, 76 insertions(+), 40 deletions(-) (limited to 'source/blender') diff --git a/source/blender/editors/space_view3d/view3d_edit.c b/source/blender/editors/space_view3d/view3d_edit.c index f07727f8118..f712c790663 100644 --- a/source/blender/editors/space_view3d/view3d_edit.c +++ b/source/blender/editors/space_view3d/view3d_edit.c @@ -85,6 +85,8 @@ #include "view3d_intern.h" /* own include */ +static bool view3d_ensure_persp(struct View3D *v3d, ARegion *ar); + bool ED_view3d_offset_lock_check(const View3D *v3d, const RegionView3D *rv3d) { return (rv3d->persp != RV3D_CAMOB) && (v3d->ob_centre_cursor || v3d->ob_centre); @@ -697,16 +699,69 @@ static bool view3d_orbit_calc_center(bContext *C, float r_dyn_ofs[3]) return is_set; } +enum eViewOpsOrbit { + VIEWOPS_ORBIT_DEFAULT = 0, + VIEWOPS_ORBIT_SELECT = 1, + VIEWOPS_ORBIT_DEPTH = 2, +}; + +static enum eViewOpsOrbit viewops_orbit_mode_ex(bool use_select, bool use_depth) +{ + if (use_select) { + return VIEWOPS_ORBIT_SELECT; + } + else if (use_depth) { + return VIEWOPS_ORBIT_DEPTH; + } + else { + return VIEWOPS_ORBIT_DEFAULT; + } +} + +static enum eViewOpsOrbit viewops_orbit_mode(void) +{ + return viewops_orbit_mode_ex( + (U.uiflag & USER_ORBIT_SELECTION) != 0, + (U.uiflag & USER_ZBUF_ORBIT) != 0); +} + /** * Calculate the values for #ViewOpsData */ -static void viewops_data_create_ex(bContext *C, wmOperator *op, const wmEvent *event, - const bool use_orbit_select, - const bool use_orbit_zbuf) +static void viewops_data_create_ex( + bContext *C, wmOperator *op, const wmEvent *event, + bool switch_from_camera, enum eViewOpsOrbit orbit_mode) { ViewOpsData *vod = op->customdata; RegionView3D *rv3d = vod->rv3d; + /* we need the depth info before changing any viewport options */ + if (orbit_mode == VIEWOPS_ORBIT_DEPTH) { + float fallback_depth_pt[3]; + + view3d_operator_needs_opengl(C); /* needed for zbuf drawing */ + + negate_v3_v3(fallback_depth_pt, rv3d->ofs); + + vod->use_dyn_ofs = ED_view3d_autodist( + vod->scene, vod->ar, vod->v3d, + event->mval, vod->dyn_ofs, true, fallback_depth_pt); + } + else { + vod->use_dyn_ofs = false; + } + + if (switch_from_camera) { + /* switch from camera view when: */ + if (view3d_ensure_persp(vod->v3d, vod->ar)) { + /* If we're switching from camera view to the perspective one, + * need to tag viewport update, so camera vuew and borders + * are properly updated. + */ + ED_region_tag_redraw(vod->ar); + } + } + /* set the view from the camera, if view locking is enabled. * we may want to make this optional but for now its needed always */ ED_view3d_camera_lock_init(vod->v3d, vod->rv3d); @@ -718,10 +773,9 @@ static void viewops_data_create_ex(bContext *C, wmOperator *op, const wmEvent *e vod->origx = vod->oldx = event->x; vod->origy = vod->oldy = event->y; vod->origkey = event->type; /* the key that triggered the operator. */ - vod->use_dyn_ofs = false; copy_v3_v3(vod->ofs, rv3d->ofs); - if (use_orbit_select) { + if (orbit_mode == VIEWOPS_ORBIT_SELECT) { vod->use_dyn_ofs = true; @@ -729,17 +783,8 @@ static void viewops_data_create_ex(bContext *C, wmOperator *op, const wmEvent *e negate_v3(vod->dyn_ofs); } - else if (use_orbit_zbuf) { - Scene *scene = CTX_data_scene(C); - float fallback_depth_pt[3]; - - view3d_operator_needs_opengl(C); /* needed for zbuf drawing */ - - negate_v3_v3(fallback_depth_pt, rv3d->ofs); - - if ((vod->use_dyn_ofs = ED_view3d_autodist(scene, vod->ar, vod->v3d, - event->mval, vod->dyn_ofs, true, fallback_depth_pt))) - { + else if (orbit_mode == VIEWOPS_ORBIT_DEPTH) { + if (vod->use_dyn_ofs) { if (rv3d->is_persp) { float my_origin[3]; /* original G.vd->ofs */ float my_pivot[3]; /* view */ @@ -808,12 +853,10 @@ static void viewops_data_create_ex(bContext *C, wmOperator *op, const wmEvent *e rv3d->rflag |= RV3D_NAVIGATING; } -static void viewops_data_create(bContext *C, wmOperator *op, const wmEvent *event) +static void viewops_data_create(bContext *C, wmOperator *op, const wmEvent *event, bool switch_from_camera) { - viewops_data_create_ex( - C, op, event, - (U.uiflag & USER_ORBIT_SELECTION) != 0, - (U.uiflag & USER_ZBUF_ORBIT) != 0); + enum eViewOpsOrbit orbit_mode = viewops_orbit_mode(); + viewops_data_create_ex(C, op, event, switch_from_camera, orbit_mode); } static void viewops_data_free(bContext *C, wmOperator *op) @@ -1219,16 +1262,7 @@ static int viewrotate_invoke(bContext *C, wmOperator *op, const wmEvent *event) ED_view3d_smooth_view_force_finish(C, vod->v3d, vod->ar); - /* switch from camera view when: */ - if (view3d_ensure_persp(vod->v3d, vod->ar)) { - /* If we're switching from camera view to the perspective one, - * need to tag viewport update, so camera vuew and borders - * are properly updated. - */ - ED_region_tag_redraw(vod->ar); - } - - viewops_data_create(C, op, event); + viewops_data_create(C, op, event, true); if (ELEM(event->type, MOUSEPAN, MOUSEROTATE)) { /* Rotate direction we keep always same */ @@ -1637,8 +1671,9 @@ static int ndof_orbit_invoke(bContext *C, wmOperator *op, const wmEvent *event) const wmNDOFMotionData *ndof = event->customdata; viewops_data_alloc(C, op); - viewops_data_create_ex(C, op, event, - (U.uiflag & USER_ORBIT_SELECTION) != 0, false); + viewops_data_create_ex( + C, op, event, + viewops_orbit_mode_ex((U.uiflag & USER_ORBIT_SELECTION) != 0, false), false); vod = op->customdata; ED_view3d_smooth_view_force_finish(C, vod->v3d, vod->ar); @@ -1705,8 +1740,9 @@ static int ndof_orbit_zoom_invoke(bContext *C, wmOperator *op, const wmEvent *ev const wmNDOFMotionData *ndof = event->customdata; viewops_data_alloc(C, op); - viewops_data_create_ex(C, op, event, - (U.uiflag & USER_ORBIT_SELECTION) != 0, false); + viewops_data_create_ex( + C, op, event, + viewops_orbit_mode_ex((U.uiflag & USER_ORBIT_SELECTION) != 0, false), false); vod = op->customdata; @@ -2020,7 +2056,7 @@ static int viewmove_invoke(bContext *C, wmOperator *op, const wmEvent *event) /* makes op->customdata */ viewops_data_alloc(C, op); - viewops_data_create(C, op, event); + viewops_data_create(C, op, event, false); vod = op->customdata; ED_view3d_smooth_view_force_finish(C, vod->v3d, vod->ar); @@ -2501,7 +2537,7 @@ static int viewzoom_invoke(bContext *C, wmOperator *op, const wmEvent *event) /* makes op->customdata */ viewops_data_alloc(C, op); - viewops_data_create(C, op, event); + viewops_data_create(C, op, event, false); vod = op->customdata; ED_view3d_smooth_view_force_finish(C, vod->v3d, vod->ar); @@ -2774,7 +2810,7 @@ static int viewdolly_invoke(bContext *C, wmOperator *op, const wmEvent *event) ED_region_tag_redraw(vod->ar); } - viewops_data_create(C, op, event); + viewops_data_create(C, op, event, false); /* if one or the other zoom position aren't set, set from event */ @@ -4298,7 +4334,7 @@ static int viewroll_invoke(bContext *C, wmOperator *op, const wmEvent *event) else { /* makes op->customdata */ viewops_data_alloc(C, op); - viewops_data_create(C, op, event); + viewops_data_create(C, op, event, false); vod = op->customdata; ED_view3d_smooth_view_force_finish(C, vod->v3d, vod->ar); @@ -4375,7 +4411,7 @@ static int viewpan_invoke(bContext *C, wmOperator *op, const wmEvent *event) else if (pandir == V3D_VIEW_PANDOWN) { y = 25; } viewops_data_alloc(C, op); - viewops_data_create(C, op, event); + viewops_data_create(C, op, event, false); ViewOpsData *vod = op->customdata; viewmove_apply(vod, vod->oldx + x, vod->oldy + y); -- cgit v1.2.3