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:
@@ -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;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user