Compare commits

...

5 Commits

Author SHA1 Message Date
f07f069ce2 Add signal for end of tablet input to x11 and cocoa. 2021-07-09 00:03:45 -07:00
237cecade9 Defer mouse centering until mouse have moved. 2021-07-08 22:48:58 -07:00
f2e3af68be Cleanup: Swap defines for static const in walk and fly mode. 2021-07-08 14:51:21 -07:00
b1e9024081 Fix T83930 and Fix T84659: Walk navigation tablet bugs.
Fixes T83930, allowing walk navigation to continue without jumping back
after repositioning pen.

Fixes T84659, allow walk navigation to start (for Windows Ink) from
keyboard shortcut when pen is in use.

Maniphest Tasks: T84659, T83930

Differential Revision: https://developer.blender.org/D11651
2021-07-08 14:51:21 -07:00
4568577703 Supply tablet data in mouse fallback for Wintab cursor movement. 2021-07-08 13:06:26 -07:00
5 changed files with 85 additions and 64 deletions

View File

@@ -1446,6 +1446,18 @@ GHOST_TSuccess GHOST_SystemCocoa::handleTabletEvent(void *eventPtr, short eventT
break;
}
}
else {
/* Send mouse event to signal end of tablet tracking to operators. */
int32_t x, y;
if (getCursorPosition(x, y)) {
pushEvent(new GHOST_EventCursor([event timestamp] * 1000,
GHOST_kEventCursorMove,
window,
x,
y,
GHOST_TABLET_DATA_NONE));
}
}
break;
default:

View File

@@ -1003,9 +1003,8 @@ void GHOST_SystemWin32::processWintabEvent(GHOST_WindowWin32 *window)
int x = GET_X_LPARAM(pos);
int y = GET_Y_LPARAM(pos);
/* TODO supply tablet data */
system->pushEvent(new GHOST_EventCursor(
system->getMilliSeconds(), GHOST_kEventCursorMove, window, x, y, GHOST_TABLET_DATA_NONE));
system->getMilliSeconds(), GHOST_kEventCursorMove, window, x, y, wt->getLastTabletData()));
}
}
@@ -1597,6 +1596,17 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam,
}
else {
wt->leaveRange();
/* Send mouse event to signal end of tablet tracking to operators. */
DWORD msgPos = ::GetMessagePos();
int x = GET_X_LPARAM(msgPos);
int y = GET_Y_LPARAM(msgPos);
event = new GHOST_EventCursor(system->getMilliSeconds(),
GHOST_kEventCursorMove,
window,
x,
y,
GHOST_TABLET_DATA_NONE);
}
}
eventHandled = true;
@@ -1636,6 +1646,18 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam,
/* Reset pointer pen info if pen device has left tracking range. */
if (pointerInfo.pointerType == PT_PEN) {
window->resetPointerPenInfo();
/* Send mouse event to signal end of tablet tracking to operators. */
DWORD msgPos = ::GetMessagePos();
int x = GET_X_LPARAM(msgPos);
int y = GET_Y_LPARAM(msgPos);
event = new GHOST_EventCursor(system->getMilliSeconds(),
GHOST_kEventCursorMove,
window,
x,
y,
GHOST_TABLET_DATA_NONE);
eventHandled = true;
}
break;

View File

@@ -943,6 +943,13 @@ void GHOST_SystemX11::processEvent(XEvent *xe)
if (!any_proximity) {
// printf("proximity disable\n");
window->GetTabletData().Active = GHOST_kTabletModeNone;
/* Send mouse event to signal end of tablet tracking to operators. */
int32_t x, y;
if (getCursorPosition(x, y)) {
pushEvent(new GHOST_EventCursor(
getMilliSeconds(), GHOST_kEventCursorMove, window, x, y, GHOST_TABLET_DATA_NONE));
}
}
}
#endif /* WITH_X11_XINPUT */
@@ -1558,6 +1565,13 @@ void GHOST_SystemX11::processEvent(XEvent *xe)
}
else if (xe->type == xtablet.ProxOutEvent) {
window->GetTabletData().Active = GHOST_kTabletModeNone;
/* Send mouse event to signal end of tablet tracking to operators. */
int32_t x, y;
if (getCursorPosition(x, y)) {
pushEvent(new GHOST_EventCursor(
getMilliSeconds(), GHOST_kEventCursorMove, window, x, y, GHOST_TABLET_DATA_NONE));
}
}
}
#endif // WITH_X11_XINPUT

View File

@@ -752,10 +752,14 @@ static void flyMoveCamera(bContext *C,
static int flyApply(bContext *C, FlyInfo *fly, bool is_confirm)
{
#define FLY_ROTATE_FAC 10.0f /* more is faster */
#define FLY_ZUP_CORRECT_FAC 0.1f /* amount to correct per step */
#define FLY_ZUP_CORRECT_ACCEL 0.05f /* increase upright momentum each step */
#define FLY_SMOOTH_FAC 20.0f /* higher value less lag */
/* Higher is faster. */
static const float fly_rotate_factor = 10.0f;
/* Amount to correct per step. */
static const float fly_z_up_correct_factor = 0.1f;
/* Increase upright momentum each step. */
static const float fly_z_up_correct_accel = 0.05f;
/* Higher is less lag. */
static const float fly_smooth_factor = 20.0f;
RegionView3D *rv3d = fly->rv3d;
@@ -875,7 +879,7 @@ static int flyApply(bContext *C, FlyInfo *fly, bool is_confirm)
copy_v3_fl3(upvec, 1.0f, 0.0f, 0.0f);
mul_m3_v3(mat, upvec);
/* Rotate about the relative up vec */
axis_angle_to_quat(tmp_quat, upvec, moffset[1] * time_redraw * -FLY_ROTATE_FAC);
axis_angle_to_quat(tmp_quat, upvec, moffset[1] * time_redraw * -fly_rotate_factor);
mul_qt_qtqt(rv3d->viewquat, rv3d->viewquat, tmp_quat);
if (fly->xlock != FLY_AXISLOCK_STATE_OFF) {
@@ -908,7 +912,7 @@ static int flyApply(bContext *C, FlyInfo *fly, bool is_confirm)
}
/* Rotate about the relative up vec */
axis_angle_to_quat(tmp_quat, upvec, moffset[0] * time_redraw * FLY_ROTATE_FAC);
axis_angle_to_quat(tmp_quat, upvec, moffset[0] * time_redraw * fly_rotate_factor);
mul_qt_qtqt(rv3d->viewquat, rv3d->viewquat, tmp_quat);
if (fly->xlock != FLY_AXISLOCK_STATE_OFF) {
@@ -934,10 +938,10 @@ static int flyApply(bContext *C, FlyInfo *fly, bool is_confirm)
axis_angle_to_quat(tmp_quat,
upvec,
roll * time_redraw_clamped * fly->zlock_momentum *
FLY_ZUP_CORRECT_FAC);
fly_z_up_correct_factor);
mul_qt_qtqt(rv3d->viewquat, rv3d->viewquat, tmp_quat);
fly->zlock_momentum += FLY_ZUP_CORRECT_ACCEL;
fly->zlock_momentum += fly_z_up_correct_accel;
}
else {
/* don't check until the view rotates again */
@@ -996,7 +1000,7 @@ static int flyApply(bContext *C, FlyInfo *fly, bool is_confirm)
/* impose a directional lag */
interp_v3_v3v3(
dvec, dvec_tmp, fly->dvec_prev, (1.0f / (1.0f + (time_redraw * FLY_SMOOTH_FAC))));
dvec, dvec_tmp, fly->dvec_prev, (1.0f / (1.0f + (time_redraw * fly_smooth_factor))));
add_v3_v3(rv3d->ofs, dvec);

View File

@@ -269,9 +269,6 @@ typedef struct WalkInfo {
bool is_reversed;
#ifdef USE_TABLET_SUPPORT
/** Check if we had a cursor event before. */
bool is_cursor_first;
/** Tablet devices (we can't relocate the cursor). */
bool is_cursor_absolute;
#endif
@@ -476,7 +473,7 @@ enum {
static float base_speed = -1.0f;
static float userdef_speed = -1.0f;
static bool initWalkInfo(bContext *C, WalkInfo *walk, wmOperator *op)
static bool initWalkInfo(bContext *C, WalkInfo *walk, wmOperator *op, const wmEvent *event)
{
wmWindowManager *wm = CTX_wm_manager(C);
wmWindow *win = CTX_wm_window(C);
@@ -553,8 +550,6 @@ static bool initWalkInfo(bContext *C, WalkInfo *walk, wmOperator *op)
walk->is_reversed = ((U.walk_navigation.flag & USER_WALK_MOUSE_REVERSE) != 0);
#ifdef USE_TABLET_SUPPORT
walk->is_cursor_first = true;
walk->is_cursor_absolute = false;
#endif
@@ -588,7 +583,6 @@ static bool initWalkInfo(bContext *C, WalkInfo *walk, wmOperator *op)
walk->v3d_camera_control = ED_view3d_cameracontrol_acquire(
walk->depsgraph, walk->scene, walk->v3d, walk->rv3d);
/* center the mouse */
walk->center_mval[0] = walk->region->winx * 0.5f;
walk->center_mval[1] = walk->region->winy * 0.5f;
@@ -602,11 +596,7 @@ static bool initWalkInfo(bContext *C, WalkInfo *walk, wmOperator *op)
walk->center_mval[1] -= walk->region->winrct.ymin;
#endif
copy_v2_v2_int(walk->prev_mval, walk->center_mval);
WM_cursor_warp(win,
walk->region->winrct.xmin + walk->center_mval[0],
walk->region->winrct.ymin + walk->center_mval[1]);
copy_v2_v2_int(walk->prev_mval, event->mval);
/* remove the mouse cursor temporarily */
WM_cursor_modal_set(win, WM_CURSOR_NONE);
@@ -688,26 +678,10 @@ static void walkEvent(bContext *C, WalkInfo *walk, const wmEvent *event)
else if (ELEM(event->type, MOUSEMOVE, INBETWEEN_MOUSEMOVE)) {
#ifdef USE_TABLET_SUPPORT
if (walk->is_cursor_first) {
/* wait until we get the 'warp' event */
if ((walk->center_mval[0] == event->mval[0]) && (walk->center_mval[1] == event->mval[1])) {
walk->is_cursor_first = false;
}
else {
/* NOTE: its possible the system isn't giving us the warp event
* ideally we shouldn't have to worry about this, see: T45361 */
wmWindow *win = CTX_wm_window(C);
WM_cursor_warp(win,
walk->region->winrct.xmin + walk->center_mval[0],
walk->region->winrct.ymin + walk->center_mval[1]);
}
return;
}
if ((walk->is_cursor_absolute == false) && event->tablet.is_motion_absolute) {
walk->is_cursor_absolute = true;
if (walk->is_cursor_absolute != event->tablet.is_motion_absolute) {
walk->is_cursor_absolute = event->tablet.is_motion_absolute;
/* Reset origin of offset when switching between mouse and tablet. */
copy_v2_v2_int(walk->prev_mval, event->mval);
copy_v2_v2_int(walk->center_mval, event->mval);
}
#endif /* USE_TABLET_SUPPORT */
@@ -980,12 +954,12 @@ static float getVelocityZeroTime(const float gravity, const float velocity)
static int walkApply(bContext *C, WalkInfo *walk, bool is_confirm)
{
#define WALK_ROTATE_TABLET_FAC 8.8f /* Higher is faster, relative to region size. */
#define WALK_ROTATE_CONSTANT_FAC DEG2RAD(0.15f) /* Higher is faster, radians per-pixel. */
#define WALK_TOP_LIMIT DEG2RADF(85.0f)
#define WALK_BOTTOM_LIMIT DEG2RADF(-80.0f)
#define WALK_MOVE_SPEED base_speed
#define WALK_BOOST_FACTOR ((void)0, walk->speed_factor)
/* Higher is faster, relative to region size. */
static const float walk_rotate_tablet_factor = 8.8f;
/* Higher is faster, radians per-pixel. */
static const float walk_rotate_constant_factor = DEG2RAD(0.15f);
static const float walk_top_limit = DEG2RADF(85.0f);
static const float walk_bottom_limit = DEG2RADF(-80.0f);
RegionView3D *rv3d = walk->rv3d;
ARegion *region = walk->region;
@@ -1037,13 +1011,13 @@ static int walkApply(bContext *C, WalkInfo *walk, bool is_confirm)
walk->time_lastdraw = time_current;
/* base speed in m/s */
walk->speed = WALK_MOVE_SPEED;
walk->speed = base_speed;
if (walk->is_fast) {
walk->speed *= WALK_BOOST_FACTOR;
walk->speed *= walk->speed_factor;
}
else if (walk->is_slow) {
walk->speed *= 1.0f / WALK_BOOST_FACTOR;
walk->speed *= 1.0f / walk->speed_factor;
}
copy_m3_m4(mat, rv3d->viewinv);
@@ -1062,12 +1036,12 @@ static int walkApply(bContext *C, WalkInfo *walk, bool is_confirm)
#ifdef USE_TABLET_SUPPORT
if (walk->is_cursor_absolute) {
y /= region->winy;
y *= WALK_ROTATE_TABLET_FAC;
y *= walk_rotate_tablet_factor;
}
else
#endif
{
y *= WALK_ROTATE_CONSTANT_FAC;
y *= walk_rotate_constant_factor;
}
/* user adjustment factor */
@@ -1077,10 +1051,10 @@ static int walkApply(bContext *C, WalkInfo *walk, bool is_confirm)
/* it ranges from 90.0f to -90.0f */
angle = -asinf(rv3d->viewmat[2][2]);
if (angle > WALK_TOP_LIMIT && y > 0.0f) {
if (angle > walk_top_limit && y > 0.0f) {
y = 0.0f;
}
else if (angle < WALK_BOTTOM_LIMIT && y < 0.0f) {
else if (angle < walk_bottom_limit && y < 0.0f) {
y = 0.0f;
}
@@ -1111,12 +1085,12 @@ static int walkApply(bContext *C, WalkInfo *walk, bool is_confirm)
#ifdef USE_TABLET_SUPPORT
if (walk->is_cursor_absolute) {
x /= region->winx;
x *= WALK_ROTATE_TABLET_FAC;
x *= walk_rotate_tablet_factor;
}
else
#endif
{
x *= WALK_ROTATE_CONSTANT_FAC;
x *= walk_rotate_constant_factor;
}
/* user adjustment factor */
@@ -1219,7 +1193,7 @@ static int walkApply(bContext *C, WalkInfo *walk, bool is_confirm)
/* the distance we would fall naturally smoothly enough that we
* can manually drop the object without activating gravity */
fall_distance = time_redraw * walk->speed * WALK_BOOST_FACTOR;
fall_distance = time_redraw * walk->speed * walk->speed_factor;
if (fabsf(difference) < fall_distance) {
/* slope/stairs */
@@ -1331,11 +1305,6 @@ static int walkApply(bContext *C, WalkInfo *walk, bool is_confirm)
}
return OPERATOR_FINISHED;
#undef WALK_ROTATE_TABLET_FAC
#undef WALK_TOP_LIMIT
#undef WALK_BOTTOM_LIMIT
#undef WALK_MOVE_SPEED
#undef WALK_BOOST_FACTOR
}
#ifdef WITH_INPUT_NDOF
@@ -1384,7 +1353,7 @@ static int walk_invoke(bContext *C, wmOperator *op, const wmEvent *event)
op->customdata = walk;
if (initWalkInfo(C, walk, op) == false) {
if (initWalkInfo(C, walk, op, event) == false) {
MEM_freeN(op->customdata);
return OPERATOR_CANCELLED;
}