diff options
author | Campbell Barton <ideasman42@gmail.com> | 2013-09-20 05:24:00 +0400 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2013-09-20 05:24:00 +0400 |
commit | 9d8a6b493b400b224aadc4878699cf4fbc10f8a5 (patch) | |
tree | 22d47dad788c4c83d099856a6a6d5f7052f1f2ed /source | |
parent | 83efcb2d050e9a0f0077f812b5964c5492903395 (diff) |
fix [#36773] Dolly breaks in quad view
more of a usability issue then a bug, now dolly switches out of camera view, like view-rotate does.
Diffstat (limited to 'source')
-rw-r--r-- | source/blender/editors/space_view3d/view3d_edit.c | 125 |
1 files changed, 82 insertions, 43 deletions
diff --git a/source/blender/editors/space_view3d/view3d_edit.c b/source/blender/editors/space_view3d/view3d_edit.c index 5686c500270..bf0f38d9ae6 100644 --- a/source/blender/editors/space_view3d/view3d_edit.c +++ b/source/blender/editors/space_view3d/view3d_edit.c @@ -182,6 +182,27 @@ bool ED_view3d_camera_lock_sync(View3D *v3d, RegionView3D *rv3d) } } +/** + * For viewport operators that exit camera persp. + * + * \note This differs from simply setting ``rv3d->persp = persp`` because it + * sets the ``ofs`` and ``dist`` values of the viewport so it matches the camera, + * otherwise switching out of camera view may jump to a different part of the scene. + */ +static void view3d_persp_switch_from_camera(View3D *v3d, RegionView3D *rv3d, const char persp) +{ + BLI_assert(rv3d->persp == RV3D_CAMOB); + BLI_assert(persp != RV3D_CAMOB); + + if (v3d->camera) { + rv3d->dist = ED_view3d_offset_distance(v3d->camera->obmat, rv3d->ofs, VIEW3D_DIST_FALLBACK); + ED_view3d_from_object(v3d->camera, rv3d->ofs, rv3d->viewquat, &rv3d->dist, NULL); + } + + if (!ED_view3d_camera_lock_check(v3d, rv3d)) { + rv3d->persp = persp; + } +} /* ********************* box view support ***************** */ @@ -378,6 +399,7 @@ void ED_view3d_quadview_update(ScrArea *sa, ARegion *ar, bool do_clip) /* ************************** init for view ops **********************************/ typedef struct ViewOpsData { + /* context pointers (assigned by viewops_data_alloc) */ ScrArea *sa; ARegion *ar; View3D *v3d; @@ -435,10 +457,17 @@ static void calctrackballvec(const rcti *rect, int mx, int my, float vec[3]) } -static void viewops_data_create(bContext *C, wmOperator *op, const wmEvent *event) +/* -------------------------------------------------------------------- */ +/* ViewOpsData */ + +/** \name Generic View Operator Custom-Data. + * \{ */ + +/** + * Allocate and fill in context pointers for #ViewOpsData + */ +static void viewops_data_alloc(bContext *C, wmOperator *op) { - static float lastofs[3] = {0, 0, 0}; - RegionView3D *rv3d; ViewOpsData *vod = MEM_callocN(sizeof(ViewOpsData), "viewops data"); /* store data */ @@ -446,7 +475,17 @@ static void viewops_data_create(bContext *C, wmOperator *op, const wmEvent *even vod->sa = CTX_wm_area(C); vod->ar = CTX_wm_region(C); vod->v3d = vod->sa->spacedata.first; - vod->rv3d = rv3d = vod->ar->regiondata; + vod->rv3d = vod->ar->regiondata; +} + +/** + * Calculate the values for #ViewOpsData + */ +static void viewops_data_create(bContext *C, wmOperator *op, const wmEvent *event) +{ + ViewOpsData *vod = op->customdata; + static float lastofs[3] = {0, 0, 0}; + RegionView3D *rv3d = vod->rv3d; /* set the view from the camera, if view locking is enabled. * we may want to make this optional but for now its needed always */ @@ -589,6 +628,8 @@ static void viewops_data_free(bContext *C, wmOperator *op) if (p && (p->flags & PAINT_FAST_NAVIGATE)) ED_region_tag_redraw(ar); } +/** \} */ + /* ************************** viewrotate **********************************/ @@ -941,37 +982,27 @@ static int viewrotate_modal(bContext *C, wmOperator *op, const wmEvent *event) static int viewrotate_invoke(bContext *C, wmOperator *op, const wmEvent *event) { ViewOpsData *vod; - RegionView3D *rv3d; /* makes op->customdata */ + viewops_data_alloc(C, op); viewops_data_create(C, op, event); vod = op->customdata; - rv3d = vod->rv3d; - if (rv3d->viewlock) { /* poll should check but in some cases fails, see poll func for details */ + if (vod->rv3d->viewlock) { /* poll should check but in some cases fails, see poll func for details */ viewops_data_free(C, op); return OPERATOR_PASS_THROUGH; } /* switch from camera view when: */ - if (rv3d->persp != RV3D_PERSP) { + if (vod->rv3d->persp != RV3D_PERSP) { if (U.uiflag & USER_AUTOPERSP) { if (!ED_view3d_camera_lock_check(vod->v3d, vod->rv3d)) { - rv3d->persp = RV3D_PERSP; + vod->rv3d->persp = RV3D_PERSP; } } - else if (rv3d->persp == RV3D_CAMOB) { - - /* changed since 2.4x, use the camera view */ - if (vod->v3d->camera) { - rv3d->dist = ED_view3d_offset_distance(vod->v3d->camera->obmat, rv3d->ofs, VIEW3D_DIST_FALLBACK); - ED_view3d_from_object(vod->v3d->camera, rv3d->ofs, rv3d->viewquat, &rv3d->dist, NULL); - } - - if (!ED_view3d_camera_lock_check(vod->v3d, vod->rv3d)) { - rv3d->persp = rv3d->lpersp; - } + else if (vod->rv3d->persp == RV3D_CAMOB) { + view3d_persp_switch_from_camera(vod->v3d, vod->rv3d, vod->rv3d->lpersp); } ED_region_tag_redraw(vod->ar); } @@ -983,7 +1014,7 @@ static int viewrotate_invoke(bContext *C, wmOperator *op, const wmEvent *event) else viewrotate_apply(vod, event->prevx, event->prevy); - ED_view3d_depth_tag_update(rv3d); + ED_view3d_depth_tag_update(vod->rv3d); viewops_data_free(C, op); @@ -992,7 +1023,7 @@ static int viewrotate_invoke(bContext *C, wmOperator *op, const wmEvent *event) else if (event->type == MOUSEROTATE) { /* MOUSEROTATE performs orbital rotation, so y axis delta is set to 0 */ viewrotate_apply(vod, event->prevx, event->y); - ED_view3d_depth_tag_update(rv3d); + ED_view3d_depth_tag_update(vod->rv3d); viewops_data_free(C, op); @@ -1170,6 +1201,7 @@ static int ndof_orbit_invoke(bContext *C, wmOperator *op, const wmEvent *event) ED_view3d_camera_lock_init(v3d, rv3d); + viewops_data_alloc(C, op); viewops_data_create(C, op, event); vod = op->customdata; @@ -1254,6 +1286,7 @@ static int ndof_orbit_zoom_invoke(bContext *C, wmOperator *op, const wmEvent *ev rv3d->rot_angle = 0.f; /* off by default, until changed later this function */ + viewops_data_alloc(C, op); viewops_data_create(C, op, event); vod = op->customdata; @@ -1446,6 +1479,7 @@ static int ndof_all_invoke(bContext *C, wmOperator *op, const wmEvent *event) View3D *v3d = CTX_wm_view3d(C); wmNDOFMotionData *ndof = (wmNDOFMotionData *) event->customdata; + viewops_data_alloc(C, op); viewops_data_create(C, op, event); vod = op->customdata; rv3d = vod->rv3d; @@ -1644,6 +1678,7 @@ static int viewmove_invoke(bContext *C, wmOperator *op, const wmEvent *event) ViewOpsData *vod; /* makes op->customdata */ + viewops_data_alloc(C, op); viewops_data_create(C, op, event); vod = op->customdata; @@ -2010,6 +2045,7 @@ static int viewzoom_invoke(bContext *C, wmOperator *op, const wmEvent *event) ViewOpsData *vod; /* makes op->customdata */ + viewops_data_alloc(C, op); viewops_data_create(C, op, event); vod = op->customdata; @@ -2227,9 +2263,30 @@ static int viewdolly_invoke(bContext *C, wmOperator *op, const wmEvent *event) VIEW3D_OP_OFS_LOCK_TEST(C, op); /* makes op->customdata */ - viewops_data_create(C, op, event); + viewops_data_alloc(C, op); vod = op->customdata; + if (vod->rv3d->viewlock) { /* poll should check but in some cases fails, see poll func for details */ + viewops_data_free(C, op); + return OPERATOR_PASS_THROUGH; + } + + /* needs to run before 'viewops_data_create' so the backup 'rv3d->ofs' is correct */ + /* switch from camera view when: */ + if (vod->rv3d->persp != RV3D_PERSP) { + if (vod->rv3d->persp == RV3D_CAMOB) { + /* ignore rv3d->lpersp because dolly only makes sense in perspective mode */ + view3d_persp_switch_from_camera(vod->v3d, vod->rv3d, RV3D_PERSP); + } + else { + vod->rv3d->persp = RV3D_PERSP; + } + ED_region_tag_redraw(vod->ar); + } + + viewops_data_create(C, op, event); + + /* if one or the other zoom position aren't set, set from event */ if (!RNA_struct_property_is_set(op->ptr, "mx") || !RNA_struct_property_is_set(op->ptr, "my")) { RNA_int_set(op->ptr, "mx", event->x); @@ -2274,25 +2331,6 @@ static int viewdolly_invoke(bContext *C, wmOperator *op, const wmEvent *event) return OPERATOR_FINISHED; } -/* like ED_operator_region_view3d_active but check its not in ortho view */ -static int viewdolly_poll(bContext *C) -{ - RegionView3D *rv3d = CTX_wm_region_view3d(C); - - if (rv3d) { - if (rv3d->persp == RV3D_PERSP) { - return 1; - } - else { - View3D *v3d = CTX_wm_view3d(C); - if (ED_view3d_camera_lock_check(v3d, rv3d)) { - return 1; - } - } - } - return 0; -} - static int viewdolly_cancel(bContext *C, wmOperator *op) { viewops_data_free(C, op); @@ -2311,7 +2349,7 @@ void VIEW3D_OT_dolly(wmOperatorType *ot) ot->invoke = viewdolly_invoke; ot->exec = viewdolly_exec; ot->modal = viewdolly_modal; - ot->poll = viewdolly_poll; + ot->poll = ED_operator_region_view3d_active; ot->cancel = viewdolly_cancel; /* flags */ @@ -3703,6 +3741,7 @@ static int viewroll_invoke(bContext *C, wmOperator *op, const wmEvent *event) ViewOpsData *vod; /* makes op->customdata */ + viewops_data_alloc(C, op); viewops_data_create(C, op, event); vod = op->customdata; |