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.
This commit is contained in:
Campbell Barton
2013-09-20 01:24:00 +00:00
parent 83efcb2d05
commit 9d8a6b493b

View File

@@ -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;