diff --git a/source/blender/editors/space_view3d/view3d_navigate.cc b/source/blender/editors/space_view3d/view3d_navigate.cc index 6bcdac4cc0d..349454ba4e3 100644 --- a/source/blender/editors/space_view3d/view3d_navigate.cc +++ b/source/blender/editors/space_view3d/view3d_navigate.cc @@ -75,6 +75,10 @@ const char *viewops_operator_idname_get(eV3D_OpMode nav_type) return "VIEW3D_OT_ndof_orbit"; case V3D_OP_MODE_NDOF_ORBIT_ZOOM: return "VIEW3D_OT_ndof_orbit_zoom"; + case V3D_OP_MODE_NDOF_PAN: + return "VIEW3D_OT_ndof_pan"; + case V3D_OP_MODE_NDOF_ALL: + return "VIEW3D_OT_ndof_all"; #endif case V3D_OP_MODE_NONE: break; @@ -186,9 +190,18 @@ static int view3d_navigation_invoke_generic(bContext *C, return viewrotate_invoke_impl(vod, event); case V3D_OP_MODE_MOVE: return viewmove_invoke_impl(vod, event); - case V3D_OP_MODE_VIEW_PAN: { + case V3D_OP_MODE_VIEW_PAN: return viewpan_invoke_impl(vod, ptr); - } +#ifdef WITH_INPUT_NDOF + case V3D_OP_MODE_NDOF_ORBIT: + return ndof_orbit_invoke_impl(C, vod, event); + case V3D_OP_MODE_NDOF_ORBIT_ZOOM: + return ndof_orbit_zoom_invoke_impl(C, vod, event); + case V3D_OP_MODE_NDOF_PAN: + return ndof_pan_invoke_impl(C, vod, event); + case V3D_OP_MODE_NDOF_ALL: + return ndof_all_invoke_impl(C, vod, event); +#endif default: break; } @@ -530,7 +543,7 @@ static void viewops_data_init_context(bContext *C, ViewOpsData *vod) vod->rv3d = static_cast(vod->region->regiondata); } -static void viewops_data_state_capture(ViewOpsData *vod) +static void viewops_data_state_capture(ViewOpsData *vod, const bool calc_dist) { Depsgraph *depsgraph = vod->depsgraph; View3D *v3d = vod->v3d; @@ -539,7 +552,7 @@ static void viewops_data_state_capture(ViewOpsData *vod) /* Set the view from the camera, if view locking is enabled. * we may want to make this optional but for now its needed always. * NOTE: This changes the value of `rv3d->dist`. */ - ED_view3d_camera_lock_init(depsgraph, v3d, rv3d); + ED_view3d_camera_lock_init_ex(depsgraph, v3d, rv3d, calc_dist); copy_v3_v3(vod->init.ofs, rv3d->ofs); copy_v3_v3(vod->init.ofs_lock, rv3d->ofs_lock); @@ -635,6 +648,7 @@ static void viewops_data_init_navigation(bContext *C, RegionView3D *rv3d = vod->rv3d; eViewOpsFlag viewops_flag = viewops_flag_from_prefs(); + bool calc_rv3d_dist = true; if (use_cursor_init) { viewops_flag |= VIEWOPS_FLAG_USE_MOUSE_INIT; @@ -653,7 +667,10 @@ static void viewops_data_init_navigation(bContext *C, #ifdef WITH_INPUT_NDOF case V3D_OP_MODE_NDOF_ORBIT: case V3D_OP_MODE_NDOF_ORBIT_ZOOM: + case V3D_OP_MODE_NDOF_PAN: + case V3D_OP_MODE_NDOF_ALL: viewops_flag &= ~VIEWOPS_FLAG_DEPTH_NAVIGATE; + calc_rv3d_dist = false; break; #endif default: @@ -693,7 +710,7 @@ static void viewops_data_init_navigation(bContext *C, vod->use_dyn_ofs = false; } - viewops_data_state_capture(vod); + viewops_data_state_capture(vod, calc_rv3d_dist); if (viewops_flag & VIEWOPS_FLAG_PERSP_ENSURE) { if (ED_view3d_persp_ensure(depsgraph, vod->v3d, vod->region)) { @@ -2074,6 +2091,8 @@ static int view3d_navigation_invoke( #ifdef WITH_INPUT_NDOF case V3D_OP_MODE_NDOF_ORBIT: case V3D_OP_MODE_NDOF_ORBIT_ZOOM: + case V3D_OP_MODE_NDOF_PAN: + case V3D_OP_MODE_NDOF_ALL: #endif case V3D_OP_MODE_NONE: break; diff --git a/source/blender/editors/space_view3d/view3d_navigate.h b/source/blender/editors/space_view3d/view3d_navigate.h index 4c5383a1e4d..52f1223285d 100644 --- a/source/blender/editors/space_view3d/view3d_navigate.h +++ b/source/blender/editors/space_view3d/view3d_navigate.h @@ -44,12 +44,14 @@ typedef enum eV3D_OpMode { #ifdef WITH_INPUT_NDOF V3D_OP_MODE_NDOF_ORBIT, V3D_OP_MODE_NDOF_ORBIT_ZOOM, + V3D_OP_MODE_NDOF_PAN, + V3D_OP_MODE_NDOF_ALL, #endif } eV3D_OpMode; #ifndef WITH_INPUT_NDOF # define V3D_OP_MODE_LEN V3D_OP_MODE_DOLLY + 1 #else -# define V3D_OP_MODE_LEN V3D_OP_MODE_NDOF_ORBIT_ZOOM + 1 +# define V3D_OP_MODE_LEN V3D_OP_MODE_NDOF_ALL + 1 #endif enum eV3D_OpPropFlag { @@ -272,6 +274,11 @@ void VIEW3D_OT_move(struct wmOperatorType *ot); #ifdef WITH_INPUT_NDOF struct wmNDOFMotionData; +int ndof_orbit_invoke_impl(bContext *C, ViewOpsData *vod, const wmEvent *event); +int ndof_orbit_zoom_invoke_impl(bContext *C, ViewOpsData *vod, const wmEvent *event); +int ndof_pan_invoke_impl(bContext *C, ViewOpsData *vod, const wmEvent *event); +int ndof_all_invoke_impl(bContext *C, ViewOpsData *vod, const wmEvent *event); + /** * Called from both fly mode and walk mode, */ diff --git a/source/blender/editors/space_view3d/view3d_navigate_ndof.c b/source/blender/editors/space_view3d/view3d_navigate_ndof.c index ea4becbade7..e3a7e8ef8fc 100644 --- a/source/blender/editors/space_view3d/view3d_navigate_ndof.c +++ b/source/blender/editors/space_view3d/view3d_navigate_ndof.c @@ -356,14 +356,11 @@ void view3d_ndof_fly(const wmNDOFMotionData *ndof, * 2D orthographic style NDOF navigation within the camera view. * Support navigating the camera view instead of leaving the camera-view and navigating in 3D. */ -static int view3d_ndof_cameraview_pan_zoom(bContext *C, const wmEvent *event) +static int view3d_ndof_cameraview_pan_zoom(ViewOpsData *vod, const wmNDOFMotionData *ndof) { - const wmNDOFMotionData *ndof = event->customdata; - View3D *v3d = CTX_wm_view3d(C); - ARegion *region = CTX_wm_region(C); - RegionView3D *rv3d = region->regiondata; - - ED_view3d_smooth_view_force_finish(C, v3d, region); + View3D *v3d = vod->v3d; + ARegion *region = vod->region; + RegionView3D *rv3d = vod->rv3d; if (v3d->camera && (rv3d->persp == RV3D_CAMOB) && (v3d->flag2 & V3D_LOCK_CAMERA) == 0) { /* pass */ @@ -423,32 +420,22 @@ static int view3d_ndof_cameraview_pan_zoom(bContext *C, const wmEvent *event) /** \name NDOF Orbit/Translate Operator * \{ */ -static int ndof_orbit_invoke(bContext *C, wmOperator *op, const wmEvent *event) +int ndof_orbit_invoke_impl(bContext *C, ViewOpsData *vod, const wmEvent *event) { if (event->type != NDOF_MOTION) { return OPERATOR_CANCELLED; } - const Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C); - ViewOpsData *vod; - View3D *v3d; - RegionView3D *rv3d; + const Depsgraph *depsgraph = vod->depsgraph; + View3D *v3d = vod->v3d; + RegionView3D *rv3d = vod->rv3d; char xform_flag = 0; const wmNDOFMotionData *ndof = event->customdata; - vod = op->customdata = viewops_data_create(C, event, V3D_OP_MODE_NDOF_ORBIT, false); - - ED_view3d_smooth_view_force_finish(C, vod->v3d, vod->region); - - v3d = vod->v3d; - rv3d = vod->rv3d; - /* off by default, until changed later this function */ rv3d->rot_angle = 0.0f; - ED_view3d_camera_lock_init_ex(depsgraph, v3d, rv3d, false); - if (ndof->progress != P_FINISHING) { const bool has_rotation = ndof_has_rotate(ndof, rv3d); /* if we can't rotate, fallback to translate (locked axis views) */ @@ -475,18 +462,24 @@ static int ndof_orbit_invoke(bContext *C, wmOperator *op, const wmEvent *event) ED_region_tag_redraw(vod->region); - viewops_data_free(C, op->customdata); - op->customdata = NULL; - return OPERATOR_FINISHED; } +static int ndof_orbit_invoke(bContext *C, wmOperator *op, const wmEvent *event) +{ + if (event->type != NDOF_MOTION) { + return OPERATOR_CANCELLED; + } + + return view3d_navigate_invoke_impl(C, op, event, V3D_OP_MODE_NDOF_ORBIT); +} + void VIEW3D_OT_ndof_orbit(wmOperatorType *ot) { /* identifiers */ ot->name = "NDOF Orbit View"; ot->description = "Orbit the view using the 3D mouse"; - ot->idname = "VIEW3D_OT_ndof_orbit"; + ot->idname = viewops_operator_idname_get(V3D_OP_MODE_NDOF_ORBIT); /* api callbacks */ ot->invoke = ndof_orbit_invoke; @@ -502,39 +495,28 @@ void VIEW3D_OT_ndof_orbit(wmOperatorType *ot) /** \name NDOF Orbit/Zoom Operator * \{ */ -static int ndof_orbit_zoom_invoke(bContext *C, wmOperator *op, const wmEvent *event) +int ndof_orbit_zoom_invoke_impl(bContext *C, ViewOpsData *vod, const wmEvent *event) { if (event->type != NDOF_MOTION) { return OPERATOR_CANCELLED; } + const wmNDOFMotionData *ndof = event->customdata; + if (U.ndof_flag & NDOF_CAMERA_PAN_ZOOM) { - const int camera_retval = view3d_ndof_cameraview_pan_zoom(C, event); + const int camera_retval = view3d_ndof_cameraview_pan_zoom(vod, ndof); if (camera_retval != OPERATOR_PASS_THROUGH) { return camera_retval; } } - const Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C); - ViewOpsData *vod; - View3D *v3d; - RegionView3D *rv3d; + View3D *v3d = vod->v3d; + RegionView3D *rv3d = vod->rv3d; char xform_flag = 0; - const wmNDOFMotionData *ndof = event->customdata; - - vod = op->customdata = viewops_data_create(C, event, V3D_OP_MODE_NDOF_ORBIT_ZOOM, false); - - ED_view3d_smooth_view_force_finish(C, vod->v3d, vod->region); - - v3d = vod->v3d; - rv3d = vod->rv3d; - /* off by default, until changed later this function */ rv3d->rot_angle = 0.0f; - ED_view3d_camera_lock_init_ex(depsgraph, v3d, rv3d, false); - if (ndof->progress == P_FINISHING) { /* pass */ } @@ -587,7 +569,7 @@ static int ndof_orbit_zoom_invoke(bContext *C, wmOperator *op, const wmEvent *ev } } - ED_view3d_camera_lock_sync(depsgraph, v3d, rv3d); + ED_view3d_camera_lock_sync(vod->depsgraph, v3d, rv3d); if (xform_flag) { ED_view3d_camera_lock_autokey( v3d, rv3d, C, xform_flag & HAS_ROTATE, xform_flag & HAS_TRANSLATE); @@ -595,18 +577,24 @@ static int ndof_orbit_zoom_invoke(bContext *C, wmOperator *op, const wmEvent *ev ED_region_tag_redraw(vod->region); - viewops_data_free(C, op->customdata); - op->customdata = NULL; - return OPERATOR_FINISHED; } +static int ndof_orbit_zoom_invoke(bContext *C, wmOperator *op, const wmEvent *event) +{ + if (event->type != NDOF_MOTION) { + return OPERATOR_CANCELLED; + } + + return view3d_navigate_invoke_impl(C, op, event, V3D_OP_MODE_NDOF_ORBIT_ZOOM); +} + void VIEW3D_OT_ndof_orbit_zoom(wmOperatorType *ot) { /* identifiers */ ot->name = "NDOF Orbit View with Zoom"; ot->description = "Orbit and zoom the view using the 3D mouse"; - ot->idname = "VIEW3D_OT_ndof_orbit_zoom"; + ot->idname = viewops_operator_idname_get(V3D_OP_MODE_NDOF_ORBIT_ZOOM); /* api callbacks */ ot->invoke = ndof_orbit_zoom_invoke; @@ -622,23 +610,25 @@ void VIEW3D_OT_ndof_orbit_zoom(wmOperatorType *ot) /** \name NDOF Pan/Zoom Operator * \{ */ -static int ndof_pan_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *event) +int ndof_pan_invoke_impl(bContext *C, ViewOpsData *vod, const wmEvent *event) { if (event->type != NDOF_MOTION) { return OPERATOR_CANCELLED; } + const wmNDOFMotionData *ndof = event->customdata; + if (U.ndof_flag & NDOF_CAMERA_PAN_ZOOM) { - const int camera_retval = view3d_ndof_cameraview_pan_zoom(C, event); + const int camera_retval = view3d_ndof_cameraview_pan_zoom(vod, ndof); if (camera_retval != OPERATOR_PASS_THROUGH) { return camera_retval; } } - const Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C); - View3D *v3d = CTX_wm_view3d(C); - RegionView3D *rv3d = CTX_wm_region_view3d(C); - const wmNDOFMotionData *ndof = event->customdata; + const Depsgraph *depsgraph = vod->depsgraph; + View3D *v3d = vod->v3d; + RegionView3D *rv3d = vod->rv3d; + ARegion *region = vod->region; char xform_flag = 0; const bool has_translate = ndof_has_translate(ndof, v3d, rv3d); @@ -654,8 +644,7 @@ static int ndof_pan_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *e ED_view3d_camera_lock_init_ex(depsgraph, v3d, rv3d, false); if (ndof->progress != P_FINISHING) { - ScrArea *area = CTX_wm_area(C); - ARegion *region = CTX_wm_region(C); + ScrArea *area = vod->area; if (has_translate || has_zoom) { view3d_ndof_pan_zoom(ndof, area, region, has_translate, has_zoom); @@ -668,17 +657,26 @@ static int ndof_pan_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *e ED_view3d_camera_lock_autokey(v3d, rv3d, C, false, xform_flag & HAS_TRANSLATE); } - ED_region_tag_redraw(CTX_wm_region(C)); + ED_region_tag_redraw(region); return OPERATOR_FINISHED; } +static int ndof_pan_invoke(bContext *C, wmOperator *op, const wmEvent *event) +{ + if (event->type != NDOF_MOTION) { + return OPERATOR_CANCELLED; + } + + return view3d_navigate_invoke_impl(C, op, event, V3D_OP_MODE_NDOF_PAN); +} + void VIEW3D_OT_ndof_pan(wmOperatorType *ot) { /* identifiers */ ot->name = "NDOF Pan View"; ot->description = "Pan the view with the 3D mouse"; - ot->idname = "VIEW3D_OT_ndof_pan"; + ot->idname = viewops_operator_idname_get(V3D_OP_MODE_NDOF_PAN); /* api callbacks */ ot->invoke = ndof_pan_invoke; @@ -697,7 +695,7 @@ void VIEW3D_OT_ndof_pan(wmOperatorType *ot) /** * wraps #ndof_orbit_zoom but never restrict to orbit. */ -static int ndof_all_invoke(bContext *C, wmOperator *op, const wmEvent *event) +int ndof_all_invoke_impl(bContext *C, ViewOpsData *vod, const wmEvent *event) { /* weak!, but it works */ const int ndof_flag = U.ndof_flag; @@ -705,19 +703,28 @@ static int ndof_all_invoke(bContext *C, wmOperator *op, const wmEvent *event) U.ndof_flag &= ~NDOF_MODE_ORBIT; - ret = ndof_orbit_zoom_invoke(C, op, event); + ret = ndof_orbit_zoom_invoke_impl(C, vod, event); U.ndof_flag = ndof_flag; return ret; } +static int ndof_all_invoke(bContext *C, wmOperator *op, const wmEvent *event) +{ + if (event->type != NDOF_MOTION) { + return OPERATOR_CANCELLED; + } + + return view3d_navigate_invoke_impl(C, op, event, V3D_OP_MODE_NDOF_ALL); +} + void VIEW3D_OT_ndof_all(wmOperatorType *ot) { /* identifiers */ ot->name = "NDOF Transform View"; ot->description = "Pan and rotate the view with the 3D mouse"; - ot->idname = "VIEW3D_OT_ndof_all"; + ot->idname = viewops_operator_idname_get(V3D_OP_MODE_NDOF_ALL); /* api callbacks */ ot->invoke = ndof_all_invoke;