Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJulian Eisel <eiseljulian@gmail.com>2017-04-11 22:05:23 +0300
committerJulian Eisel <eiseljulian@gmail.com>2017-04-11 22:25:22 +0300
commit3c51b670c51d0aa47394f33c96a02362404e975d (patch)
treeafb8c4af26bb6654ff7722047acedde313f7f15f
parentc87925469bff43faec4e83d1601aef72c5990f48 (diff)
Make interactions in HMD view work nicely
This should make any interactions in HMD views work like users would expect. Talking about things like selecting, using tools, placing 3D cursor, ... Same goes for HMD mirror views, their interactions should work fine now. I'm not so happy how we pass info about HMD state to ED_view3d_draw_depth and ED_view3d_draw_depth_gpencil, would like to figure out a nicer way to do that. Also continuous grab works a bit glitchy.
-rw-r--r--intern/ghost/GHOST_C-api.h5
-rw-r--r--intern/ghost/intern/GHOST_C-api.cpp47
-rw-r--r--source/blender/editors/curve/editcurve_paint.c4
-rw-r--r--source/blender/editors/gpencil/gpencil_edit.c4
-rw-r--r--source/blender/editors/gpencil/gpencil_paint.c17
-rw-r--r--source/blender/editors/gpencil/gpencil_utils.c3
-rw-r--r--source/blender/editors/include/ED_view3d.h7
-rw-r--r--source/blender/editors/interface/interface_eyedropper.c3
-rw-r--r--source/blender/editors/screen/area.c27
-rw-r--r--source/blender/editors/sculpt_paint/paint_image_proj.c3
-rw-r--r--source/blender/editors/space_view3d/view3d_draw.c215
-rw-r--r--source/blender/editors/space_view3d/view3d_edit.c26
-rw-r--r--source/blender/editors/space_view3d/view3d_intern.h18
-rw-r--r--source/blender/editors/space_view3d/view3d_view.c18
-rw-r--r--source/blender/windowmanager/WM_api.h4
-rw-r--r--source/blender/windowmanager/intern/wm_device.c28
-rw-r--r--source/blender/windowmanager/intern/wm_event_system.c90
-rw-r--r--source/blender/windowmanager/intern/wm_operators.c7
-rw-r--r--source/blender/windowmanager/intern/wm_stereo.c26
-rw-r--r--source/blender/windowmanager/intern/wm_window.c14
-rw-r--r--source/blender/windowmanager/wm.h1
-rw-r--r--source/blender/windowmanager/wm_event_system.h2
22 files changed, 399 insertions, 170 deletions
diff --git a/intern/ghost/GHOST_C-api.h b/intern/ghost/GHOST_C-api.h
index dd204cf34f0..1eeb0fda3e8 100644
--- a/intern/ghost/GHOST_C-api.h
+++ b/intern/ghost/GHOST_C-api.h
@@ -946,10 +946,11 @@ extern const char *GHOST_HMDgetVendorName(int index);
extern float GHOST_HMDgetDeviceIPD(void);
extern void GHOST_HMDsetDeviceIPD(float value);
extern float GHOST_HMDgetLensHorizontalSeparation(void);
+extern float GHOST_HMDgetProjectionZNear(void);
+extern float GHOST_HMDgetProjectionZFar(void);
+extern float GHOST_HMDgetScreenHorizontalSize(void);
extern void GHOST_HMDgetLeftModelviewMatrix(float r_mat[4][4]);
extern void GHOST_HMDgetRightModelviewMatrix(float r_mat[4][4]);
-extern void GHOST_HMDgetLeftProjectionMatrix(float r_mat[4][4]);
-extern void GHOST_HMDgetRightProjectionMatrix(float r_mat[4][4]);
extern void* GHOST_HMDgetDistortionParameters(void);
#ifdef __cplusplus
diff --git a/intern/ghost/intern/GHOST_C-api.cpp b/intern/ghost/intern/GHOST_C-api.cpp
index 5d5fb5226b7..28b1bbcd50d 100644
--- a/intern/ghost/intern/GHOST_C-api.cpp
+++ b/intern/ghost/intern/GHOST_C-api.cpp
@@ -1041,56 +1041,67 @@ float GHOST_HMDgetLensHorizontalSeparation()
#endif
}
-#ifndef WITH_OPENHMD
-static void ghost_UnitMat(float r_mat[4][4])
+float GHOST_HMDgetProjectionZNear()
{
- r_mat[0][0] = r_mat[1][1] = r_mat[2][2] = r_mat[3][3] = 1.0f;
- r_mat[0][1] = r_mat[0][2] = r_mat[0][3] = 0.0f;
- r_mat[1][0] = r_mat[1][2] = r_mat[1][3] = 0.0f;
- r_mat[2][0] = r_mat[2][1] = r_mat[2][3] = 0.0f;
- r_mat[3][0] = r_mat[3][1] = r_mat[3][2] = 0.0f;
-}
+#ifdef WITH_OPENHMD
+ GHOST_ISystem *system = GHOST_ISystem::getSystem();
+ GHOST_OpenHMDManager *ohmd = system->getOpenHMDManager();
+ return ohmd->getProjectionZNear();
+#else
+ return -1.0f;
#endif
+}
-void GHOST_HMDgetLeftModelviewMatrix(float r_mat[4][4])
+float GHOST_HMDgetProjectionZFar()
{
#ifdef WITH_OPENHMD
GHOST_ISystem *system = GHOST_ISystem::getSystem();
GHOST_OpenHMDManager *ohmd = system->getOpenHMDManager();
- ohmd->getLeftEyeGLModelviewMatrix(r_mat);
+ return ohmd->getProjectionZFar();
#else
- ghost_UnitMat(r_mat);
+ return -1.0f;
#endif
}
-void GHOST_HMDgetRightModelviewMatrix(float r_mat[4][4])
+float GHOST_HMDgetScreenHorizontalSize()
{
#ifdef WITH_OPENHMD
GHOST_ISystem *system = GHOST_ISystem::getSystem();
GHOST_OpenHMDManager *ohmd = system->getOpenHMDManager();
- ohmd->getRightEyeGLModelviewMatrix(r_mat);
+ return ohmd->getScreenHorizontalSize();
#else
- ghost_UnitMat(r_mat);
+ return -1.0f;
#endif
}
-void GHOST_HMDgetLeftProjectionMatrix(float r_mat[4][4])
+#ifndef WITH_OPENHMD
+static void ghost_UnitMat(float r_mat[4][4])
+{
+ r_mat[0][0] = r_mat[1][1] = r_mat[2][2] = r_mat[3][3] = 1.0f;
+ r_mat[0][1] = r_mat[0][2] = r_mat[0][3] = 0.0f;
+ r_mat[1][0] = r_mat[1][2] = r_mat[1][3] = 0.0f;
+ r_mat[2][0] = r_mat[2][1] = r_mat[2][3] = 0.0f;
+ r_mat[3][0] = r_mat[3][1] = r_mat[3][2] = 0.0f;
+}
+#endif
+
+void GHOST_HMDgetLeftModelviewMatrix(float r_mat[4][4])
{
#ifdef WITH_OPENHMD
GHOST_ISystem *system = GHOST_ISystem::getSystem();
GHOST_OpenHMDManager *ohmd = system->getOpenHMDManager();
- ohmd->getLeftEyeGLProjectionMatrix(r_mat);
+ ohmd->getLeftEyeGLModelviewMatrix(r_mat);
#else
ghost_UnitMat(r_mat);
#endif
}
-void GHOST_HMDgetRightProjectionMatrix(float r_mat[4][4])
+void GHOST_HMDgetRightModelviewMatrix(float r_mat[4][4])
{
#ifdef WITH_OPENHMD
GHOST_ISystem *system = GHOST_ISystem::getSystem();
GHOST_OpenHMDManager *ohmd = system->getOpenHMDManager();
- ohmd->getRightEyeGLProjectionMatrix(r_mat);
+ ohmd->getRightEyeGLModelviewMatrix(r_mat);
#else
ghost_UnitMat(r_mat);
#endif
diff --git a/source/blender/editors/curve/editcurve_paint.c b/source/blender/editors/curve/editcurve_paint.c
index 34e026a3ef4..a6015550e97 100644
--- a/source/blender/editors/curve/editcurve_paint.c
+++ b/source/blender/editors/curve/editcurve_paint.c
@@ -1162,12 +1162,14 @@ static int curve_draw_invoke(bContext *C, wmOperator *op, const wmEvent *event)
if ((cps->depth_mode == CURVE_PAINT_PROJECT_SURFACE) &&
(v3d->drawtype > OB_WIRE))
{
+ const bool is_hmd_view = WM_window_is_hmd_view(CTX_wm_manager(C), CTX_wm_window(C));
+
view3d_get_transformation(cdd->vc.ar, cdd->vc.rv3d, NULL, &cdd->mats);
/* needed or else the draw matrix can be incorrect */
view3d_operator_needs_opengl(C);
- ED_view3d_autodist_init(cdd->vc.scene, cdd->vc.ar, cdd->vc.v3d, 0);
+ ED_view3d_autodist_init(cdd->vc.scene, cdd->vc.ar, cdd->vc.v3d, 0, is_hmd_view);
if (cdd->vc.rv3d->depths) {
cdd->vc.rv3d->depths->damaged = true;
diff --git a/source/blender/editors/gpencil/gpencil_edit.c b/source/blender/editors/gpencil/gpencil_edit.c
index 601a86b97cb..90c89e9c250 100644
--- a/source/blender/editors/gpencil/gpencil_edit.c
+++ b/source/blender/editors/gpencil/gpencil_edit.c
@@ -2010,8 +2010,10 @@ static int gp_strokes_reproject_exec(bContext *C, wmOperator *op)
/* init autodist for geometry projection */
if (mode == GP_REPROJECT_SURFACE) {
+ const bool is_hmd_view = WM_window_is_hmd_view(CTX_wm_manager(C), CTX_wm_window(C));
+
view3d_region_operator_needs_opengl(CTX_wm_window(C), gsc.ar);
- ED_view3d_autodist_init(scene, gsc.ar, CTX_wm_view3d(C), 0);
+ ED_view3d_autodist_init(scene, gsc.ar, CTX_wm_view3d(C), 0, is_hmd_view);
}
// TODO: For deforming geometry workflow, create new frames?
diff --git a/source/blender/editors/gpencil/gpencil_paint.c b/source/blender/editors/gpencil/gpencil_paint.c
index 5879306b06c..8e890d97342 100644
--- a/source/blender/editors/gpencil/gpencil_paint.c
+++ b/source/blender/editors/gpencil/gpencil_paint.c
@@ -113,7 +113,8 @@ typedef enum eGPencil_PaintFlags {
*/
typedef struct tGPsdata {
Scene *scene; /* current scene from context */
-
+
+ wmWindowManager *wm; /* window manager where painting originated */
wmWindow *win; /* window where painting originated */
ScrArea *sa; /* area where painting originated */
ARegion *ar; /* region where painting originated */
@@ -634,9 +635,12 @@ static short gp_stroke_addpoint(tGPsdata *p, const int mval[2], float pressure,
*/
if (gpencil_project_check(p)) {
View3D *v3d = p->sa->spacedata.first;
+ const bool is_hmd_view = WM_window_is_hmd_view(p->wm, p->win);
view3d_region_operator_needs_opengl(p->win, p->ar);
- ED_view3d_autodist_init(p->scene, p->ar, v3d, (p->gpd->flag & GP_DATA_DEPTH_STROKE) ? 1 : 0);
+ ED_view3d_autodist_init(p->scene, p->ar, v3d,
+ (p->gpd->flag & GP_DATA_DEPTH_STROKE) ? 1 : 0,
+ is_hmd_view);
}
/* convert screen-coordinates to appropriate coordinates (and store them) */
@@ -1236,9 +1240,10 @@ static void gp_stroke_doeraser(tGPsdata *p)
if (p->sa->spacetype == SPACE_VIEW3D) {
if (p->flags & GP_PAINTFLAG_V3D_ERASER_DEPTH) {
View3D *v3d = p->sa->spacedata.first;
+ const bool is_hmd_view = WM_window_is_hmd_view(p->wm, p->win);
view3d_region_operator_needs_opengl(p->win, p->ar);
- ED_view3d_autodist_init(p->scene, p->ar, v3d, 0);
+ ED_view3d_autodist_init(p->scene, p->ar, v3d, 0, is_hmd_view);
}
}
@@ -1390,8 +1395,9 @@ static bool gp_session_initdata(bContext *C, tGPsdata *p)
return 0;
}
- /* pass on current scene and window */
+ /* pass on context info */
p->scene = CTX_data_scene(C);
+ p->wm = CTX_wm_manager(C);
p->win = CTX_wm_window(C);
unit_m4(p->imat);
@@ -1799,10 +1805,11 @@ static void gp_paint_strokeend(tGPsdata *p)
*/
if (gpencil_project_check(p)) {
View3D *v3d = p->sa->spacedata.first;
+ const bool is_hmd_view = WM_window_is_hmd_view(p->wm, p->win);
/* need to restore the original projection settings before packing up */
view3d_region_operator_needs_opengl(p->win, p->ar);
- ED_view3d_autodist_init(p->scene, p->ar, v3d, (p->gpd->flag & GP_DATA_DEPTH_STROKE) ? 1 : 0);
+ ED_view3d_autodist_init(p->scene, p->ar, v3d, (p->gpd->flag & GP_DATA_DEPTH_STROKE) ? 1 : 0, is_hmd_view);
}
/* check if doing eraser or not */
diff --git a/source/blender/editors/gpencil/gpencil_utils.c b/source/blender/editors/gpencil/gpencil_utils.c
index 76e85f20c36..fa726e98f50 100644
--- a/source/blender/editors/gpencil/gpencil_utils.c
+++ b/source/blender/editors/gpencil/gpencil_utils.c
@@ -523,12 +523,13 @@ void gp_point_conversion_init(bContext *C, GP_SpaceConversion *r_gsc)
Scene *scene = CTX_data_scene(C);
View3D *v3d = (View3D *)CTX_wm_space_data(C);
RegionView3D *rv3d = ar->regiondata;
+ const bool is_hmd_view = WM_window_is_hmd_view(CTX_wm_manager(C), CTX_wm_window(C));
/* init 3d depth buffers */
view3d_operator_needs_opengl(C);
view3d_region_operator_needs_opengl(win, ar);
- ED_view3d_autodist_init(scene, ar, v3d, 0);
+ ED_view3d_autodist_init(scene, ar, v3d, 0, is_hmd_view);
/* for camera view set the subrect */
if (rv3d->persp == RV3D_CAMOB) {
diff --git a/source/blender/editors/include/ED_view3d.h b/source/blender/editors/include/ED_view3d.h
index 8658a542ade..ebb32e9dc1f 100644
--- a/source/blender/editors/include/ED_view3d.h
+++ b/source/blender/editors/include/ED_view3d.h
@@ -291,10 +291,13 @@ unsigned int ED_view3d_backbuf_sample(struct ViewContext *vc, int x, int y);
bool ED_view3d_autodist(
struct Scene *scene, struct ARegion *ar, struct View3D *v3d,
const int mval[2], float mouse_worldloc[3],
- const bool alphaoverride, const float fallback_depth_pt[3]);
+ const bool alphaoverride, const bool is_hmd_view,
+ const float fallback_depth_pt[3]);
/* only draw so ED_view3d_autodist_simple can be called many times after */
-void ED_view3d_autodist_init(struct Scene *scene, struct ARegion *ar, struct View3D *v3d, int mode);
+void ED_view3d_autodist_init(
+ struct Scene *scene, struct ARegion *ar, struct View3D *v3d,
+ int mode, bool is_hmd_view);
bool ED_view3d_autodist_simple(struct ARegion *ar, const int mval[2], float mouse_worldloc[3], int margin, float *force_depth);
bool ED_view3d_autodist_depth(struct ARegion *ar, const int mval[2], int margin, float *depth);
bool ED_view3d_autodist_depth_seg(struct ARegion *ar, const int mval_sta[2], const int mval_end[2], int margin, float *depth);
diff --git a/source/blender/editors/interface/interface_eyedropper.c b/source/blender/editors/interface/interface_eyedropper.c
index f3859154dfb..9d00ffa3c40 100644
--- a/source/blender/editors/interface/interface_eyedropper.c
+++ b/source/blender/editors/interface/interface_eyedropper.c
@@ -888,6 +888,7 @@ static void depthdropper_depth_sample_pt(bContext *C, DepthDropper *ddr, int mx,
Scene *scene = win->screen->scene;
UnitSettings *unit = &scene->unit;
const bool do_split = (unit->flag & USER_UNIT_OPT_SPLIT) != 0;
+ const bool is_hmd_view = WM_window_is_hmd_view(CTX_wm_manager(C), win);
ScrArea *area_prev = CTX_wm_area(C);
ARegion *ar_prev = CTX_wm_region(C);
@@ -915,7 +916,7 @@ static void depthdropper_depth_sample_pt(bContext *C, DepthDropper *ddr, int mx,
view3d_operator_needs_opengl(C);
- if (ED_view3d_autodist(scene, ar, v3d, mval, co, true, NULL)) {
+ if (ED_view3d_autodist(scene, ar, v3d, mval, co, true, is_hmd_view, NULL)) {
const float mval_center_fl[2] = {
(float)ar->winx / 2,
(float)ar->winy / 2};
diff --git a/source/blender/editors/screen/area.c b/source/blender/editors/screen/area.c
index 6ba90bd947e..35c97ff070c 100644
--- a/source/blender/editors/screen/area.c
+++ b/source/blender/editors/screen/area.c
@@ -473,34 +473,40 @@ void ED_region_set(const bContext *C, ARegion *ar)
ED_region_pixelspace(ar);
}
-static void region_draw_view_setup(wmWindowManager *wm, wmWindow *win, ARegion *ar, bool is_popup)
+static void region_draw_view_setup(wmWindowManager *wm, wmWindow *win, ARegion *ar)
{
#ifdef WITH_INPUT_HMD
- if (!(wm->hmd_view.hmd_win == win && win->screen->is_hmd_running) || is_popup) {
+ if (ar->regiontype == RGN_TYPE_TEMPORARY) {
/* pass */
}
- else if ((wm->hmd_view.hmd_win == win) && win->screen->is_hmd_running) {
+ else if (!WM_window_is_hmd_view(wm, win)) {
+ /* pass */
+ }
+ else {
ar->winx /= 2;
ar->winrct.xmax -= ar->winx;
wm_subwindow_rect_set(win, ar->swinid, &ar->winrct);
}
#else
- UNUSED_VARS(wm, win, ar, is_popup);
+ UNUSED_VARS(wm, win, ar);
#endif
}
-static void region_draw_view_reset(wmWindowManager *wm, wmWindow *win, ARegion *ar, bool is_popup)
+static void region_draw_view_reset(wmWindowManager *wm, wmWindow *win, ARegion *ar)
{
#ifdef WITH_INPUT_HMD
- if (!(wm->hmd_view.hmd_win == win && win->screen->is_hmd_running) || is_popup) {
+ if (ar->regiontype == RGN_TYPE_TEMPORARY) {
/* pass */
}
- else if ((wm->hmd_view.hmd_win == win) && win->screen->is_hmd_running) {
+ else if (!WM_window_is_hmd_view(wm, win)) {
+ /* pass */
+ }
+ else {
ar->winrct.xmax += ar->winx;
ar->winx *= 2;
wm_subwindow_rect_set(win, ar->swinid, &ar->winrct);
}
#else
- UNUSED_VARS(wm, win, ar, is_popup);
+ UNUSED_VARS(wm, win, ar);
#endif
}
@@ -511,14 +517,13 @@ void ED_region_do_draw(bContext *C, ARegion *ar)
wmWindow *win = CTX_wm_window(C);
ScrArea *sa = CTX_wm_area(C);
ARegionType *at = ar->type;
- const bool is_popup = ar == CTX_wm_menu(C);
bool scissor_pad;
/* see BKE_spacedata_draw_locks() */
if (at->do_lock)
return;
- region_draw_view_setup(wm, win, ar, is_popup);
+ region_draw_view_setup(wm, win, ar);
/* if no partial draw rect set, full rect */
if (ar->drawrct.xmin == ar->drawrct.xmax) {
@@ -580,7 +585,7 @@ void ED_region_do_draw(bContext *C, ARegion *ar)
}
}
- region_draw_view_reset(wm, win, ar, is_popup);
+ region_draw_view_reset(wm, win, ar);
}
/* **********************************
diff --git a/source/blender/editors/sculpt_paint/paint_image_proj.c b/source/blender/editors/sculpt_paint/paint_image_proj.c
index d0f1cc99b8d..04ef1774663 100644
--- a/source/blender/editors/sculpt_paint/paint_image_proj.c
+++ b/source/blender/editors/sculpt_paint/paint_image_proj.c
@@ -5021,10 +5021,11 @@ void paint_proj_stroke(
ARegion *ar = CTX_wm_region(C);
float *cursor = ED_view3d_cursor3d_get(scene, v3d);
int mval_i[2] = {(int)pos[0], (int)pos[1]};
+ const bool is_hmd_view = WM_window_is_hmd_view(CTX_wm_manager(C), CTX_wm_window(C));
view3d_operator_needs_opengl(C);
- if (!ED_view3d_autodist(scene, ar, v3d, mval_i, cursor, false, NULL))
+ if (!ED_view3d_autodist(scene, ar, v3d, mval_i, cursor, false, is_hmd_view, NULL))
return;
ED_region_tag_redraw(ar);
diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c
index 1c5890388e5..22f13c1edf6 100644
--- a/source/blender/editors/space_view3d/view3d_draw.c
+++ b/source/blender/editors/space_view3d/view3d_draw.c
@@ -2366,17 +2366,29 @@ float view3d_depth_near(ViewDepths *d)
return far == far_real ? FLT_MAX : far;
}
-void ED_view3d_draw_depth_gpencil(Scene *scene, ARegion *ar, View3D *v3d)
+void ED_view3d_draw_depth_gpencil(Scene *scene, ARegion *ar, View3D *v3d, bool is_hmd_view)
{
short zbuf = v3d->zbuf;
RegionView3D *rv3d = ar->regiondata;
- view3d_winmatrix_set(ar, v3d, NULL);
- view3d_viewmatrix_set(scene, v3d, rv3d); /* note: calls BKE_object_where_is_calc for camera... */
+#ifdef WITH_INPUT_HMD
+ wmWindowManager *wm = G.main->wm.first;
+ if (is_hmd_view) {
+ view3d_hmd_view_setup(scene, v3d, ar);
+ }
+ else if (view3d_is_hmd_view_mirror(wm, v3d, rv3d)) {
+ view3d_hmd_view_setup_mirrored(wm, scene, ar, NULL);
+ }
+ else
+#endif
+ {
+ view3d_winmatrix_set(ar, v3d, NULL);
+ view3d_viewmatrix_set(scene, v3d, rv3d); /* note: calls BKE_object_where_is_calc for camera... */
- mul_m4_m4m4(rv3d->persmat, rv3d->winmat, rv3d->viewmat);
- invert_m4_m4(rv3d->persinv, rv3d->persmat);
- invert_m4_m4(rv3d->viewinv, rv3d->viewmat);
+ mul_m4_m4m4(rv3d->persmat, rv3d->winmat, rv3d->viewmat);
+ invert_m4_m4(rv3d->persinv, rv3d->persmat);
+ invert_m4_m4(rv3d->viewinv, rv3d->viewmat);
+ }
glClear(GL_DEPTH_BUFFER_BIT);
@@ -2391,9 +2403,12 @@ void ED_view3d_draw_depth_gpencil(Scene *scene, ARegion *ar, View3D *v3d)
v3d->zbuf = zbuf;
+#ifdef WITH_INPUT_HMD
+ UNUSED_VARS(is_hmd_view);
+#endif
}
-void ED_view3d_draw_depth(Scene *scene, ARegion *ar, View3D *v3d, bool alphaoverride)
+void ED_view3d_draw_depth(Scene *scene, ARegion *ar, View3D *v3d, bool alphaoverride, bool is_hmd_view)
{
RegionView3D *rv3d = ar->regiondata;
Base *base;
@@ -2409,14 +2424,26 @@ void ED_view3d_draw_depth(Scene *scene, ARegion *ar, View3D *v3d, bool alphaover
v3d->flag &= ~V3D_SELECT_OUTLINE;
U.glalphaclip = alphaoverride ? 0.5f : glalphaclip; /* not that nice but means we wont zoom into billboards */
U.obcenter_dia = 0;
-
- view3d_winmatrix_set(ar, v3d, NULL);
- view3d_viewmatrix_set(scene, v3d, rv3d); /* note: calls BKE_object_where_is_calc for camera... */
-
- mul_m4_m4m4(rv3d->persmat, rv3d->winmat, rv3d->viewmat);
- invert_m4_m4(rv3d->persinv, rv3d->persmat);
- invert_m4_m4(rv3d->viewinv, rv3d->viewmat);
-
+
+#ifdef WITH_INPUT_HMD
+ wmWindowManager *wm = G.main->wm.first;
+ if (is_hmd_view) {
+ view3d_hmd_view_setup(scene, v3d, ar);
+ }
+ else if (view3d_is_hmd_view_mirror(wm, v3d, rv3d)) {
+ view3d_hmd_view_setup_mirrored(wm, scene, ar, NULL);
+ }
+ else
+#endif
+ {
+ view3d_winmatrix_set(ar, v3d, NULL);
+ view3d_viewmatrix_set(scene, v3d, rv3d); /* note: calls BKE_object_where_is_calc for camera... */
+
+ mul_m4_m4m4(rv3d->persmat, rv3d->winmat, rv3d->viewmat);
+ invert_m4_m4(rv3d->persinv, rv3d->persmat);
+ invert_m4_m4(rv3d->viewinv, rv3d->viewmat);
+ }
+
glClear(GL_DEPTH_BUFFER_BIT);
glLoadMatrixf(rv3d->viewmat);
@@ -2515,6 +2542,10 @@ void ED_view3d_draw_depth(Scene *scene, ARegion *ar, View3D *v3d, bool alphaover
U.glalphaclip = glalphaclip;
v3d->flag = flag;
U.obcenter_dia = obcenter_dia;
+
+#ifndef WITH_INPUT_HMD
+ UNUSED_VARS(is_hmd_view);
+#endif
}
void ED_view3d_draw_select_loop(
@@ -3723,18 +3754,71 @@ static bool view3d_stereo3d_active(const bContext *C, Scene *scene, View3D *v3d,
#ifdef WITH_INPUT_HMD
+enum HMDViewMatrixType {
+ HMD_MATRIX_LEFT_EYE,
+ HMD_MATRIX_RIGHT_EYE,
+ /* Calculate matrix for the center of both eyes. It's used for
+ * interactions like selecting and drawing mirrored view. */
+ HMD_MATRIX_CENTER,
+};
+
static bool view3d_is_hmd_view(wmWindowManager *wm, wmWindow *win)
{
return ((wm->hmd_view.hmd_win == win) && (wm->hmd_view.hmd_win->screen->is_hmd_running));
}
-static void view3d_hmd_view_calc_matrices_from_device(const View3D *v3d, const RegionView3D *rv3d, const bool is_left,
- float r_modelviewmat[4][4], float r_projectionmat[4][4])
+bool view3d_is_hmd_view_mirror(const wmWindowManager *wm, const View3D *v3d, const RegionView3D *rv3d)
+{
+ return wm->hmd_view.hmd_win &&
+ wm->hmd_view.hmd_win->screen->is_hmd_running &&
+ (v3d->flag3 & V3D_SHOW_HMD_MIRROR) &&
+ RV3D_IS_LOCKED_SHARED(rv3d);
+}
+
+static void view3d_hmd_calc_projection_matrix_from_device(
+ ARegion *region, View3D *v3d,
+ const rcti *viewplane_rect, enum HMDViewMatrixType mat_type,
+ float r_projectionmat[4][4])
+{
+ /* Usually we could/should get projection matrix directly from HMD driver, but we caculate
+ * them ourselves for two reasons:
+ * * For selecting, viewplane_rect has to be used for view-plane clipping.
+ * * OpenHMD doesn't allow us to set custom screen dimensions, it always uses device ones. */
+
+ const float v3d_znear = v3d->near;
+ const float v3d_zfar = v3d->far;
+ const float hmd_znear = WM_device_HMD_projection_z_near_get();
+ const float hmd_zfar = WM_device_HMD_projection_z_far_get();
+
+ v3d->near = hmd_znear;
+ v3d->far = hmd_zfar;
+
+ view3d_winmatrix_set(region, v3d, viewplane_rect);
+ glGetFloatv(GL_PROJECTION_MATRIX, (float *)r_projectionmat);
+
+ if (mat_type != HMD_MATRIX_CENTER) {
+ /* calculate lens offset in [-1, 1] range to apply onto projection matrix.
+ * This follows logic of OpenHMD */
+ const float lens_sep = WM_device_HMD_lens_horizontal_separation_get();
+ const float hsize = WM_device_HMD_screen_horizontal_size_get();
+ const float proj_offset = 1 - ((2 * lens_sep) / hsize);
+
+ /* apply lens separation (IPD is applied onto modelview matrix) */
+ BLI_assert(IN_RANGE_INCL(proj_offset, -1.0f, 1.0f));
+ translate_m4(r_projectionmat, (mat_type == HMD_MATRIX_LEFT_EYE) ? proj_offset : -proj_offset, 0, 0);
+ }
+
+ v3d->near = v3d_znear;
+ v3d->far = v3d_zfar;
+}
+
+static void view3d_hmd_calc_modelview_matrix_from_device(
+ const View3D *v3d, const RegionView3D *rv3d, enum HMDViewMatrixType mat_type,
+ float r_modelviewmat[4][4])
{
float hmd_modelviewmat[4][4];
- WM_device_HMD_modelview_matrix_get(is_left, hmd_modelviewmat);
- WM_device_HMD_projection_matrix_get(is_left, r_projectionmat);
+ WM_device_HMD_modelview_matrix_get(mat_type == HMD_MATRIX_LEFT_EYE, hmd_modelviewmat);
if (rv3d->persp == RV3D_CAMOB && v3d->camera) {
float v3d_modelviewmat[4][4], hmd_modelviewmat_tmp[4][4];
@@ -3759,12 +3843,16 @@ static void view3d_hmd_view_calc_matrices_from_device(const View3D *v3d, const R
mul_m4_m4m4(r_modelviewmat, r_modelviewmat, v3d_rotmat); /* now, apply viewrotation after scaling */
translate_m4(r_modelviewmat, rv3d->ofs[0], rv3d->ofs[1], rv3d->ofs[2]);
}
- /* apply IPD offset */
- add_v3_v3(r_modelviewmat[3], hmd_modelviewmat[3]);
+
+ if (mat_type != HMD_MATRIX_CENTER) {
+ /* apply IPD offset (lens separation is applied onto projection matrix) */
+ add_v3_v3(r_modelviewmat[3], hmd_modelviewmat[3]);
+ }
}
-static void view3d_hmd_view_get_matrices(
- View3D *v3d, RegionView3D *rv3d, const bool is_left,
+static void view3d_hmd_get_matrices(
+ ARegion *region, View3D *v3d, RegionView3D *rv3d,
+ const rcti *viewplane_rect, enum HMDViewMatrixType mat_type,
float r_modelviewmat[4][4], float r_projectionmat[4][4])
{
const bool has_device = U.hmd_settings.device > -1;
@@ -3775,59 +3863,72 @@ static void view3d_hmd_view_get_matrices(
copy_m4_m4(r_projectionmat, rv3d->winmat);
}
else if (use_device_rot) {
- view3d_hmd_view_calc_matrices_from_device(v3d, rv3d, is_left, r_modelviewmat, r_projectionmat);
+ view3d_hmd_calc_modelview_matrix_from_device(v3d, rv3d, mat_type, r_modelviewmat);
+ view3d_hmd_calc_projection_matrix_from_device(region, v3d, viewplane_rect, mat_type, r_projectionmat);
}
else {
- const float shiftx = WM_device_HMD_lens_horizontal_separation_get();
-
- WM_device_HMD_projection_matrix_get(is_left, r_projectionmat);
+ view3d_hmd_calc_projection_matrix_from_device(region, v3d, viewplane_rect, mat_type, r_projectionmat);
copy_m4_m4(r_modelviewmat, rv3d->viewmat);
- /* apply ipd and lens shift */
- r_modelviewmat[3][0] += (shiftx * 0.5f) * (is_left ? 1.0f : -1.0f);
+
+ if (mat_type != HMD_MATRIX_CENTER) {
+ const float ipd = WM_device_HMD_IPD_get();
+ /* apply IPD */
+ r_modelviewmat[3][0] += (ipd * 0.5f) * ((mat_type == HMD_MATRIX_LEFT_EYE) ? 1.0f : -1.0f);
+ }
}
}
-static void view3d_hmd_view_setup(Scene *scene, View3D *v3d, ARegion *ar)
+static void view3d_hmd_view_setup_ex(
+ Scene *scene, View3D *v3d, RegionView3D *rv3d, ARegion *region,
+ const rcti *viewplane_rect, enum HMDViewMatrixType mat_type)
{
- RegionView3D *rv3d = ar->regiondata;
- const bool is_left = v3d->multiview_eye == STEREO_LEFT_ID;
float projmat[4][4];
float modelviewmat[4][4];
+ /* note that rv3d might not equal region->regiondata! */
+
/* update 3d view matrices before applying matrices from HMD */
view3d_viewmatrix_set(scene, v3d, rv3d);
- view3d_winmatrix_set(ar, v3d, NULL);
+ view3d_winmatrix_set(region, v3d, NULL);
- view3d_hmd_view_get_matrices(v3d, rv3d, is_left, modelviewmat, projmat);
+ view3d_hmd_get_matrices(region, v3d, rv3d, viewplane_rect, mat_type, modelviewmat, projmat);
/* setup view with adjusted matrices */
- view3d_main_region_setup_view(scene, v3d, ar, modelviewmat, projmat);
+ view3d_main_region_setup_view(scene, v3d, region, modelviewmat, projmat);
}
-static void view3d_hmd_view_mirrored_setup(wmWindowManager *wm, Scene *scene, View3D *v3d, ARegion *ar)
+void view3d_hmd_view_setup(Scene *scene, View3D *v3d, ARegion *region)
{
- wmWindow *hmd_win = wm->hmd_view.hmd_win;
- ScrArea *sa = hmd_win->screen->areabase.first;
- View3D *v3d_hmd = sa->spacedata.first;
- ARegion *ar_hmd = BKE_area_find_region_type(sa, RGN_TYPE_WINDOW);
- RegionView3D *rv3d_hmd = ar_hmd->regiondata;
- const bool is_left = v3d->multiview_eye == STEREO_LEFT_ID;
- float projmat[4][4];
- float modelviewmat[4][4];
+ enum HMDViewMatrixType mat_type = (v3d->multiview_eye == STEREO_LEFT_ID) ?
+ HMD_MATRIX_LEFT_EYE : HMD_MATRIX_RIGHT_EYE;
- /* we calculate a modelviewmatrix (viewmatrix) based on HMD device and
- * HMD view, but use the projection matrix (winmatrix) from this v3d */
+ BLI_assert(ELEM(v3d->multiview_eye, STEREO_LEFT_ID, STEREO_RIGHT_ID));
+ view3d_hmd_view_setup_ex(scene, v3d, region->regiondata, region, NULL, mat_type);
+}
- BLI_assert(sa->spacetype == SPACE_VIEW3D);
- /* update 3d view matrices before applying matrices from HMD */
- view3d_viewmatrix_set(scene, v3d_hmd, rv3d_hmd);
- view3d_winmatrix_set(ar, v3d, NULL);
+/**
+ * Version of #view3d_hmd_view_setup for setting up an HMD view for interaction, not drawing. Basically
+ * this means we ignore HMD lens separation and IPD, we calculate a matrix for the eye center.
+ *
+ * \param viewplane: Optional for picking (can be NULL).
+ */
+void view3d_hmd_view_setup_interaction(Scene *scene, View3D *v3d, ARegion *region, const rcti *viewplane_rect)
+{
+ view3d_hmd_view_setup_ex(scene, v3d, region->regiondata, region, viewplane_rect, HMD_MATRIX_CENTER);
+}
- view3d_hmd_view_get_matrices(v3d_hmd, rv3d_hmd, is_left, modelviewmat, projmat);
+/*
+ * \param viewplane: Optional for picking (can be NULL).
+ */
+void view3d_hmd_view_setup_mirrored(wmWindowManager *wm, Scene *scene, ARegion *region, const rcti *viewplane_rect)
+{
+ wmWindow *hmd_win = wm->hmd_view.hmd_win;
+ ScrArea *sa = hmd_win->screen->areabase.first;
+ View3D *v3d_hmd = sa->spacedata.first;
+ ARegion *region_hmd = BKE_area_find_region_type(sa, RGN_TYPE_WINDOW);
- /* setup view with adjusted matrices */
- view3d_main_region_setup_view(scene, v3d, ar, modelviewmat, NULL);
+ view3d_hmd_view_setup_ex(scene, v3d_hmd, region_hmd->regiondata, region, viewplane_rect, HMD_MATRIX_CENTER);
}
#endif /* WITH_INPUT_HMD */
@@ -3949,12 +4050,8 @@ static void view3d_main_region_draw_objects(
if (view3d_is_hmd_view(wm, win)) {
view3d_hmd_view_setup(scene, v3d, ar);
}
- else if (wm->hmd_view.hmd_win &&
- wm->hmd_view.hmd_win->screen->is_hmd_running &&
- (v3d->flag3 & V3D_SHOW_HMD_MIRROR) &&
- RV3D_IS_LOCKED_SHARED(rv3d))
- {
- view3d_hmd_view_mirrored_setup(wm, scene, v3d, ar);
+ else if (view3d_is_hmd_view_mirror(wm, v3d, rv3d)) {
+ view3d_hmd_view_setup_mirrored(wm, scene, ar, NULL);
}
else
#else
diff --git a/source/blender/editors/space_view3d/view3d_edit.c b/source/blender/editors/space_view3d/view3d_edit.c
index 29ec8c81e6d..01119bc7d33 100644
--- a/source/blender/editors/space_view3d/view3d_edit.c
+++ b/source/blender/editors/space_view3d/view3d_edit.c
@@ -733,13 +733,15 @@ static void viewops_data_create_ex(bContext *C, wmOperator *op, const wmEvent *e
else if (use_orbit_zbuf) {
Scene *scene = CTX_data_scene(C);
float fallback_depth_pt[3];
+ const bool is_hmd_view = WM_window_is_hmd_view(CTX_wm_manager(C), CTX_wm_window(C));
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)))
+ event->mval, vod->dyn_ofs,
+ true, is_hmd_view, fallback_depth_pt)))
{
if (rv3d->is_persp) {
float my_origin[3]; /* original G.vd->ofs */
@@ -3277,12 +3279,13 @@ static int viewcenter_pick_invoke(bContext *C, wmOperator *op, const wmEvent *ev
if (rv3d) {
float new_ofs[3];
const int smooth_viewtx = WM_operator_smooth_viewtx_get(op);
+ const bool is_hmd_view = WM_window_is_hmd_view(CTX_wm_manager(C), CTX_wm_window(C));
ED_view3d_smooth_view_force_finish(C, v3d, ar);
view3d_operator_needs_opengl(C);
- if (ED_view3d_autodist(scene, ar, v3d, event->mval, new_ofs, false, NULL)) {
+ if (ED_view3d_autodist(scene, ar, v3d, event->mval, new_ofs, false, is_hmd_view, NULL)) {
/* pass */
}
else {
@@ -3543,6 +3546,7 @@ static int view3d_zoom_border_exec(bContext *C, wmOperator *op)
Scene *scene = CTX_data_scene(C);
int gesture_mode;
const int smooth_viewtx = WM_operator_smooth_viewtx_get(op);
+ const bool is_hmd_view = WM_window_is_hmd_view(CTX_wm_manager(C), CTX_wm_window(C));
/* Zooms in on a border drawn by the user */
rcti rect;
@@ -3571,7 +3575,7 @@ static int view3d_zoom_border_exec(bContext *C, wmOperator *op)
/* Get Z Depths, needed for perspective, nice for ortho */
bgl_get_mats(&mats);
- ED_view3d_draw_depth(scene, ar, v3d, true);
+ ED_view3d_draw_depth(scene, ar, v3d, true, is_hmd_view);
{
/* avoid allocating the whole depth buffer */
@@ -4697,9 +4701,12 @@ void ED_view3d_cursor3d_position(bContext *C, float fp[3], const int mval[2])
}
if (U.uiflag & USER_ZBUF_CURSOR) { /* maybe this should be accessed some other way */
+ const bool is_hmd_view = WM_window_is_hmd_view(CTX_wm_manager(C), CTX_wm_window(C));
+
view3d_operator_needs_opengl(C);
- if (ED_view3d_autodist(scene, ar, v3d, mval, fp, true, NULL))
+ if (ED_view3d_autodist(scene, ar, v3d, mval, fp, true, is_hmd_view, NULL)) {
depth_used = true;
+ }
}
if (depth_used == false) {
@@ -4915,7 +4922,8 @@ static float view_autodist_depth_margin(ARegion *ar, const int mval[2], int marg
bool ED_view3d_autodist(
Scene *scene, ARegion *ar, View3D *v3d,
const int mval[2], float mouse_worldloc[3],
- const bool alphaoverride, const float fallback_depth_pt[3])
+ const bool alphaoverride, const bool is_hmd_view,
+ const float fallback_depth_pt[3])
{
bglMats mats; /* ZBuffer depth vars */
float depth_close;
@@ -4925,7 +4933,7 @@ bool ED_view3d_autodist(
bool depth_ok = false;
/* Get Z Depths, needed for perspective, nice for ortho */
- ED_view3d_draw_depth(scene, ar, v3d, alphaoverride);
+ ED_view3d_draw_depth(scene, ar, v3d, alphaoverride, is_hmd_view);
/* call after in case settings have been modified since last drawing, see: T47089 */
bgl_get_mats(&mats);
@@ -4960,15 +4968,15 @@ bool ED_view3d_autodist(
}
}
-void ED_view3d_autodist_init(Scene *scene, ARegion *ar, View3D *v3d, int mode)
+void ED_view3d_autodist_init(Scene *scene, ARegion *ar, View3D *v3d, int mode, bool is_hmd_view)
{
/* Get Z Depths, needed for perspective, nice for ortho */
switch (mode) {
case 0:
- ED_view3d_draw_depth(scene, ar, v3d, true);
+ ED_view3d_draw_depth(scene, ar, v3d, true, is_hmd_view);
break;
case 1:
- ED_view3d_draw_depth_gpencil(scene, ar, v3d);
+ ED_view3d_draw_depth_gpencil(scene, ar, v3d, is_hmd_view);
break;
}
}
diff --git a/source/blender/editors/space_view3d/view3d_intern.h b/source/blender/editors/space_view3d/view3d_intern.h
index c2b8d1f8bda..62f5d7bcbbe 100644
--- a/source/blender/editors/space_view3d/view3d_intern.h
+++ b/source/blender/editors/space_view3d/view3d_intern.h
@@ -195,19 +195,31 @@ void draw_sim_debug_data(Scene *scene, View3D *v3d, ARegion *ar);
/* view3d_draw.c */
void view3d_main_region_draw(const struct bContext *C, struct ARegion *ar);
-void ED_view3d_draw_depth(Scene *scene, struct ARegion *ar, View3D *v3d, bool alphaoverride);
-void ED_view3d_draw_depth_gpencil(Scene *scene, ARegion *ar, View3D *v3d);
+void ED_view3d_draw_depth(Scene *scene, struct ARegion *ar, View3D *v3d, bool alphaoverride, bool is_hmd_view);
+void ED_view3d_draw_depth_gpencil(Scene *scene, ARegion *ar, View3D *v3d, bool is_hmd_view);
void ED_view3d_draw_select_loop(
ViewContext *vc, Scene *scene, View3D *v3d, ARegion *ar,
bool use_obedit_skip, bool use_nearest);
-void ED_view3d_after_add(ListBase *lb, Base *base, const short dflag);\
+void ED_view3d_after_add(ListBase *lb, Base *base, const short dflag);
void circf(float x, float y, float rad);
void circ(float x, float y, float rad);
void view3d_update_depths_rect(struct ARegion *ar, struct ViewDepths *d, struct rcti *rect);
float view3d_depth_near(struct ViewDepths *d);
+void view3d_hmd_view_setup(
+ Scene *scene, View3D *v3d, ARegion *ar);
+void view3d_hmd_view_setup_interaction(
+ Scene *scene, View3D *v3d, ARegion *region,
+ const struct rcti *viewplane_rect);
+void view3d_hmd_view_setup_mirrored(
+ struct wmWindowManager *wm, Scene *scene, ARegion *region,
+ const struct rcti *viewplane_rect);
+bool view3d_is_hmd_view_mirror(
+ const struct wmWindowManager *wm, const View3D *v3d,
+ const RegionView3D *rv3d);
+
/* view3d_select.c */
void VIEW3D_OT_select(struct wmOperatorType *ot);
void VIEW3D_OT_select_circle(struct wmOperatorType *ot);
diff --git a/source/blender/editors/space_view3d/view3d_view.c b/source/blender/editors/space_view3d/view3d_view.c
index b5e504d8536..d8883179b09 100644
--- a/source/blender/editors/space_view3d/view3d_view.c
+++ b/source/blender/editors/space_view3d/view3d_view.c
@@ -1195,9 +1195,21 @@ int view3d_opengl_select(
G.f |= G_PICKSEL;
- view3d_winmatrix_set(ar, v3d, &rect);
- mul_m4_m4m4(vc->rv3d->persmat, vc->rv3d->winmat, vc->rv3d->viewmat);
-
+#ifdef WITH_INPUT_HMD
+ wmWindowManager *wm = G.main->wm.first;
+ if (WM_window_is_hmd_view(wm, vc->win)) {
+ view3d_hmd_view_setup_interaction(scene, v3d, ar, &rect);
+ }
+ else if (view3d_is_hmd_view_mirror(wm, v3d, vc->rv3d)) {
+ view3d_hmd_view_setup_mirrored(wm, scene, ar, &rect);
+ }
+ else
+#endif
+ {
+ view3d_winmatrix_set(ar, v3d, &rect);
+ mul_m4_m4m4(vc->rv3d->persmat, vc->rv3d->winmat, vc->rv3d->viewmat);
+ }
+
if (v3d->drawtype > OB_WIRE) {
v3d->zbuf = true;
glEnable(GL_DEPTH_TEST);
diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h
index 966ce77ec3e..8a0d78ac63d 100644
--- a/source/blender/windowmanager/WM_api.h
+++ b/source/blender/windowmanager/WM_api.h
@@ -538,10 +538,12 @@ const char *WM_device_HMD_vendor_get(int index) ATTR_WARN_UNUSED_RESULT;
float WM_device_HMD_IPD_get(void) ATTR_WARN_UNUSED_RESULT;
void WM_device_HMD_IPD_set(float value);
float WM_device_HMD_lens_horizontal_separation_get(void) ATTR_WARN_UNUSED_RESULT;
+float WM_device_HMD_projection_z_near_get(void);
+float WM_device_HMD_projection_z_far_get(void);
+float WM_device_HMD_screen_horizontal_size_get(void);
/* Utils */
void WM_device_HMD_state_set(const int device, const bool enable);
void WM_device_HMD_modelview_matrix_get(const bool is_left, float r_modelviewmat[4][4]) ATTR_NONNULL();
-void WM_device_HMD_projection_matrix_get(const bool is_left, float r_projmat[4][4]) ATTR_NONNULL();
void *WM_device_HMD_distortion_parameters_get(void);
#endif /* WITH_INPUT_HMD */
diff --git a/source/blender/windowmanager/intern/wm_device.c b/source/blender/windowmanager/intern/wm_device.c
index c7bc1916e5c..98d6ab25210 100644
--- a/source/blender/windowmanager/intern/wm_device.c
+++ b/source/blender/windowmanager/intern/wm_device.c
@@ -98,6 +98,21 @@ float WM_device_HMD_lens_horizontal_separation_get(void)
return GHOST_HMDgetLensHorizontalSeparation();
}
+float WM_device_HMD_projection_z_near_get(void)
+{
+ return GHOST_HMDgetProjectionZNear();
+}
+
+float WM_device_HMD_projection_z_far_get(void)
+{
+ return GHOST_HMDgetProjectionZFar();
+}
+
+float WM_device_HMD_screen_horizontal_size_get(void)
+{
+ return GHOST_HMDgetScreenHorizontalSize();
+}
+
/* ------ Utilities ------ */
/**
@@ -128,19 +143,6 @@ void WM_device_HMD_modelview_matrix_get(const bool is_left, float r_modelviewmat
}
}
-void WM_device_HMD_projection_matrix_get(const bool is_left, float r_projmat[4][4])
-{
- if (U.hmd_settings.device == -1) {
- unit_m4(r_projmat);
- }
- else if (is_left) {
- GHOST_HMDgetLeftProjectionMatrix(r_projmat);
- }
- else {
- GHOST_HMDgetRightProjectionMatrix(r_projmat);
- }
-}
-
void* WM_device_HMD_distortion_parameters_get(void)
{
return GHOST_HMDgetDistortionParameters();
diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c
index f30544ace64..aa8d397e081 100644
--- a/source/blender/windowmanager/intern/wm_event_system.c
+++ b/source/blender/windowmanager/intern/wm_event_system.c
@@ -78,6 +78,7 @@
#include "WM_types.h"
#include "wm.h"
#include "wm_window.h"
+#include "wm_subwindow.h"
#include "wm_event_system.h"
#include "wm_event_types.h"
@@ -997,6 +998,47 @@ static void wm_region_mouse_co(bContext *C, wmEvent *event)
}
}
+static void wm_handler_screens_setup(wmWindowManager *wm)
+{
+#ifdef WITH_INPUT_HMD
+ wmWindow *hmd_win = wm->hmd_view.hmd_win;
+
+ if (hmd_win && WM_window_is_hmd_view(wm, hmd_win)) {
+ ScrArea *area = hmd_win->screen->areabase.first;
+ ARegion *region = BKE_area_find_region_type(area, RGN_TYPE_WINDOW);
+
+ BLI_assert(BLI_listbase_count_ex(&hmd_win->screen->areabase, 2) == 1);
+
+ region->winx /= 2;
+ region->winrct.xmax -= region->winx;
+ /* for operators using GL */
+ wm_subwindow_rect_set(hmd_win, region->swinid, &region->winrct);
+ }
+#else
+ UNUSED_VARS(wm);
+#endif
+}
+static void wm_handler_screens_reset(wmWindowManager *wm)
+{
+#ifdef WITH_INPUT_HMD
+ wmWindow *hmd_win = wm->hmd_view.hmd_win;
+
+ if (hmd_win && WM_window_is_hmd_view(wm, hmd_win)) {
+ ScrArea *area = hmd_win->screen->areabase.first;
+ ARegion *region = BKE_area_find_region_type(area, RGN_TYPE_WINDOW);
+
+ BLI_assert(BLI_listbase_count_ex(&hmd_win->screen->areabase, 2) == 1);
+
+ region->winrct.xmax += region->winx;
+ region->winx *= 2;
+ /* for operators using GL */
+ wm_subwindow_rect_set(hmd_win, region->swinid, &region->winrct);
+ }
+#else
+ UNUSED_VARS(wm);
+#endif
+}
+
#if 1 /* may want to disable operator remembering previous state for testing */
bool WM_operator_last_properties_init(wmOperator *op)
{
@@ -1083,6 +1125,8 @@ static int wm_operator_invoke(
bContext *C, wmOperatorType *ot, wmEvent *event,
PointerRNA *properties, ReportList *reports, const bool poll_only)
{
+ wmWindowManager *wm = CTX_wm_manager(C);
+ wmWindow *win = CTX_wm_window(C);
int retval = OPERATOR_PASS_THROUGH;
/* this is done because complicated setup is done to call this function that is better not duplicated */
@@ -1090,7 +1134,6 @@ static int wm_operator_invoke(
return WM_operator_poll(C, ot);
if (WM_operator_poll(C, ot)) {
- wmWindowManager *wm = CTX_wm_manager(C);
wmOperator *op = wm_operator_create(wm, ot, properties, reports); /* if reports == NULL, they'll be initialized */
const bool is_nested_call = (wm->op_undo_depth != 0);
@@ -1101,6 +1144,9 @@ static int wm_operator_invoke(
WM_operator_last_properties_init(op);
}
+ /* this is only done for op execution right now, maybe should do for poll calls too. */
+ wm_handler_screens_setup(wm);
+
if ((G.debug & G_DEBUG_HANDLERS) && ((event == NULL) || (event->type != MOUSEMOVE))) {
printf("%s: handle evt %d win %d op %s\n",
__func__, event ? event->type : 0, CTX_wm_screen(C)->subwinactive, ot->idname);
@@ -1202,7 +1248,7 @@ static int wm_operator_invoke(
}
}
- WM_cursor_grab_enable(CTX_wm_window(C), wrap, false, bounds);
+ WM_cursor_grab_enable(win, wrap, false, bounds);
}
/* cancel UI handlers, typically tooltips that can hang around
@@ -1214,6 +1260,7 @@ static int wm_operator_invoke(
else {
WM_operator_free(op);
}
+ wm_handler_screens_reset(wm);
}
return retval;
@@ -1691,9 +1738,10 @@ static int wm_handler_operator_call(bContext *C, ListBase *handlers, wmEventHand
bool dbl_click_disabled = false;
wm_handler_op_context(C, handler, event);
+ wm_handler_screens_setup(wm);
wm_region_mouse_co(C, event);
wm_event_modalkeymap(C, op, event, &dbl_click_disabled);
-
+
if (ot->flag & OPTYPE_UNDO)
wm->op_undo_depth++;
@@ -1730,6 +1778,7 @@ static int wm_handler_operator_call(bContext *C, ListBase *handlers, wmEventHand
WM_operator_free(op);
handler->op = NULL;
}
+ wm_handler_screens_reset(wm);
/* putting back screen context, reval can pass trough after modal failures! */
if ((retval & OPERATOR_PASS_THROUGH) || wm_event_always_pass(event)) {
@@ -3175,6 +3224,40 @@ static void wm_event_add_mousemove(wmWindow *win, const wmEvent *event)
}
}
+/**
+ * If needed, this adjusts \a r_mouse_xy so that drawn cursor and handled mouse position are matching visually.
+*/
+void wm_event_mouse_offset_apply(wmWindow *win, int *r_mouse_xy)
+{
+ /* XXX G.main */
+ if (WM_window_is_hmd_view(G.main->wm.first, win)) {
+ 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;
+ }
+ }
+ else if (!WM_stereo3d_enabled(win, false)) {
+ /* pass */
+ }
+ else 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;
+ }
+}
+
/* windows store own event queues, no bContext here */
/* time is in 1000s of seconds, from ghost */
void wm_event_add_ghostevent(wmWindowManager *wm, wmWindow *win, int type, int UNUSED(time), void *customdata)
@@ -3199,7 +3282,6 @@ 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);
diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c
index 2ff5c40212b..23da0311df4 100644
--- a/source/blender/windowmanager/intern/wm_operators.c
+++ b/source/blender/windowmanager/intern/wm_operators.c
@@ -4215,10 +4215,6 @@ static void hmd_session_cursor_draw(bContext *C, int mx, int my, void *UNUSED(cu
}
WM_cursor_modal_set(win, CURSOR_NONE);
- if (mx > (win->sizex / 2)) {
- mx -= win->sizex / 2;
- }
-
qobj = gluNewQuadric();
UI_ThemeColor(TH_TEXT_HI);
@@ -4356,6 +4352,9 @@ static int hmd_session_refresh_invoke(bContext *C, wmOperator *UNUSED(op), const
/* Actually the only thing we have to do is ensuring a redraw, we'll then
* get the modelview/projection matrices from HMD device when drawing */
ED_area_tag_redraw(sa);
+ /* Make sure running modal operators can update their drawing for changed
+ * view (without having to listen to HMD transform event themselves) */
+ WM_event_add_mousemove(C);
/* Tag mirrored 3D views for redraw too */
for (wmWindow *win = wm->windows.first; win; win = win->next) {
diff --git a/source/blender/windowmanager/intern/wm_stereo.c b/source/blender/windowmanager/intern/wm_stereo.c
index c3faf29dce4..78a83b4878f 100644
--- a/source/blender/windowmanager/intern/wm_stereo.c
+++ b/source/blender/windowmanager/intern/wm_stereo.c
@@ -346,32 +346,6 @@ 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;
diff --git a/source/blender/windowmanager/intern/wm_window.c b/source/blender/windowmanager/intern/wm_window.c
index 2ae69f81aa0..cb3e491780d 100644
--- a/source/blender/windowmanager/intern/wm_window.c
+++ b/source/blender/windowmanager/intern/wm_window.c
@@ -863,12 +863,18 @@ int wm_window_fullscreen_toggle_exec(bContext *C, wmOperator *UNUSED(op))
void wm_cursor_position_from_ghost(wmWindow *win, int *x, int *y)
{
float fac = GHOST_GetNativePixelSize(win->ghostwin);
+ int xy[2] = {*x, *y};
- GHOST_ScreenToClient(win->ghostwin, *x, *y, x, y);
- *x *= fac;
+ GHOST_ScreenToClient(win->ghostwin, xy[0], xy[1], &xy[0], &xy[1]);
+ xy[0] *= fac;
- *y = (win->sizey - 1) - *y;
- *y *= fac;
+ xy[1] = (win->sizey - 1) - xy[1];
+ xy[1] *= fac;
+
+ wm_event_mouse_offset_apply(win, xy);
+
+ *x = xy[0];
+ *y = xy[1];
}
void wm_cursor_position_to_ghost(wmWindow *win, int *x, int *y)
diff --git a/source/blender/windowmanager/wm.h b/source/blender/windowmanager/wm.h
index a5a4ad850f2..a8e1bb1835f 100644
--- a/source/blender/windowmanager/wm.h
+++ b/source/blender/windowmanager/wm.h
@@ -78,7 +78,6 @@ void wm_autosave_location(char *filepath);
/* wm_stereo.c */
void wm_method_draw_stereo3d(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);
diff --git a/source/blender/windowmanager/wm_event_system.h b/source/blender/windowmanager/wm_event_system.h
index efc01b1f8a8..ac87b55f163 100644
--- a/source/blender/windowmanager/wm_event_system.h
+++ b/source/blender/windowmanager/wm_event_system.h
@@ -89,6 +89,8 @@ void wm_event_add_ghostevent (wmWindowManager *wm, wmWindow *win, int typ
void wm_event_do_notifiers (bContext *C);
+void wm_event_mouse_offset_apply(wmWindow *win, int *r_mouse_xy);
+
/* wm_keymap.c */
/* wm_dropbox.c */