Transform: Support navigation from NDOF devices
This commit implements the `VIEW3D_OT_ndof_orbit`, `VIEW3D_OT_ndof_orbit_zoom`, `VIEW3D_OT_ndof_pan` and `VIEW3D_OT_ndof_all` operators to the `ED_view3d_navigation_` utility so that these operations can be used in the transform operators. Pull Request: https://projects.blender.org/blender/blender/pulls/109792
This commit is contained in:
committed by
Germano Cavalcante
parent
113004687d
commit
37d1d4cb07
@@ -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<RegionView3D *>(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;
|
||||
|
||||
@@ -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,
|
||||
*/
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user