Fix T51324: Auto-Depth fails rotating out of camera
authorCampbell Barton <ideasman42@gmail.com>
Fri, 28 Apr 2017 17:13:49 +0000 (03:13 +1000)
committerCampbell Barton <ideasman42@gmail.com>
Fri, 28 Apr 2017 17:21:03 +0000 (03:21 +1000)
source/blender/editors/space_view3d/view3d_edit.c

index f07727f811868cb5844a94aef8b232361fe83382..f712c7906636683126eacdc0fd17cfb403154f62 100644 (file)
@@ -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);