Multi-View: Map cursor coordinates to visual coordinates

When rendering multi-view in side-by-side or top-bottom mode, we squash
the UI to half of its size and draw it twice on screen. That means the
cursor coordinates used for UI interaction don't match what's visible on
screen.
This commit is a little event system hack (tm) to fix this. It has some
small glitches with cursor grabbing, but nothing to bad.
We'll also use it for viewport HMD support.

D1350, thanks for the feedback @dfelinto!
This commit is contained in:
Julian Eisel 2017-03-06 00:40:48 +01:00
parent e72af060ab
commit 80444effc6
Notes: blender-bot 2023-06-07 09:49:57 +02:00
Referenced by issue #50876, Cycles Crash - Cycles crashes before sampling when certain meshes have autosmooth enabled.
Referenced by issue #108667, Compositor workspace:  Mouse jumps back to the original position when stereoscopy is enabled
4 changed files with 31 additions and 1 deletions

View File

@ -7741,7 +7741,8 @@ static void button_activate_state(bContext *C, uiBut *but, uiHandleButtonState s
if (ui_but_is_cursor_warp(but)) {
#ifdef USE_CONT_MOUSE_CORRECT
if (data->ungrab_mval[0] != FLT_MAX) {
/* stereo3d has issues with changing cursor location so rather avoid */
if (data->ungrab_mval[0] != FLT_MAX && !WM_stereo3d_enabled(data->window, false)) {
int mouse_ungrab_xy[2];
ui_block_to_window_fl(data->region, but->block, &data->ungrab_mval[0], &data->ungrab_mval[1]);
mouse_ungrab_xy[0] = data->ungrab_mval[0];

View File

@ -3179,6 +3179,8 @@ void wm_event_add_ghostevent(wmWindowManager *wm, wmWindow *win, int type, int U
GHOST_TEventCursorData *cd = customdata;
copy_v2_v2_int(&event.x, &cd->x);
wm_stereo3d_mouse_offset_apply(win, &event.x);
event.type = MOUSEMOVE;
wm_event_add_mousemove(win, &event);
copy_v2_v2_int(&evt->x, &event.x);

View File

@ -345,6 +345,32 @@ bool WM_stereo3d_enabled(wmWindow *win, bool skip_stereo3d_check)
return true;
}
/**
* If needed, this adjusts \a r_mouse_xy so that drawn cursor and handled mouse position are matching visually.
*/
void wm_stereo3d_mouse_offset_apply(wmWindow *win, int *r_mouse_xy)
{
if (!WM_stereo3d_enabled(win, false))
return;
if (win->stereo3d_format->display_mode == S3D_DISPLAY_SIDEBYSIDE) {
const int half_x = win->sizex / 2;
/* right half of the screen */
if (r_mouse_xy[0] > half_x) {
r_mouse_xy[0] -= half_x;
}
r_mouse_xy[0] *= 2;
}
else if (win->stereo3d_format->display_mode == S3D_DISPLAY_TOPBOTTOM) {
const int half_y = win->sizey / 2;
/* upper half of the screen */
if (r_mouse_xy[1] > half_y) {
r_mouse_xy[1] -= half_y;
}
r_mouse_xy[1] *= 2;
}
}
/************************** Stereo 3D operator **********************************/
typedef struct Stereo3dData {
Stereo3dFormat stereo3d_format;

View File

@ -78,6 +78,7 @@ void wm_autosave_location(char *filepath);
/* wm_stereo.c */
void wm_method_draw_stereo3d(const bContext *C, wmWindow *win);
void wm_stereo3d_mouse_offset_apply(wmWindow *win, int *r_mouse_xy);
int wm_stereo3d_set_exec(bContext *C, wmOperator *op);
int wm_stereo3d_set_invoke(bContext *C, wmOperator *op, const wmEvent *event);
void wm_stereo3d_set_draw(bContext *C, wmOperator *op);