[Bf-blender-cvs] [b3c156927a] HMD_viewport: Mirror mode support (sync HMD viewpoint with regular 3D view)

Julian Eisel noreply at git.blender.org
Sun Mar 5 17:20:15 CET 2017


Commit: b3c156927a33b6ff91fb8b5960909b85df80fceb
Author: Julian Eisel
Date:   Sun Mar 5 01:29:17 2017 +0100
Branches: HMD_viewport
https://developer.blender.org/rBb3c156927a33b6ff91fb8b5960909b85df80fceb

Mirror mode support (sync HMD viewpoint with regular 3D view)

Adds option "Mirror HMD View" to the HMD panel in the 3D view.

In this implementation we update/redraw the mirrored 3D views with the
HMD view, which can actually cause some extra slowdown (drawing the
viewport at least once more). We decided that this would be the best
solution for now, as the other option would be opening a separate window
showing the mirrored result, which is a bit too much against the
non-overlapping paradigma IMHO.
We could also draw the HMD view into some buffer and reuse this for
mirrored displays, but that would mess up projection matrices.
In Blender 2.8 we'll probably be able to use multi-threaded drawing
anyway, for which this would be the perfect use case.

3D View regions mirroring the HMD view are locked, for quadview we only
use the non-locked region for mirroring.

===================================================================

M	release/scripts/startup/bl_ui/space_view3d.py
M	source/blender/editors/screen/screen_ops.c
M	source/blender/editors/space_view3d/space_view3d.c
M	source/blender/editors/space_view3d/view3d_draw.c
M	source/blender/makesdna/DNA_view3d_types.h
M	source/blender/makesrna/intern/rna_space.c
M	source/blender/windowmanager/intern/wm_event_system.c
M	source/blender/windowmanager/intern/wm_operators.c

===================================================================

diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py
index 0df5d07850..3bcfb9a1f6 100644
--- a/release/scripts/startup/bl_ui/space_view3d.py
+++ b/release/scripts/startup/bl_ui/space_view3d.py
@@ -3400,6 +3400,7 @@ class VIEW3D_PT_view3d_hmd_view(Panel):
         layout = self.layout
 
         wm = context.window_manager
+        view = context.space_data
 
         session_running = wm.is_hmd_session_running
         text_win = "Close HMD Window" if wm.has_hmd_window else "Open HMD Window"
@@ -3409,6 +3410,7 @@ class VIEW3D_PT_view3d_hmd_view(Panel):
         row = layout.row(align=True)
         row.operator("wm.hmd_view_toggle", text=text_win)
         row.operator("wm.hmd_session_run", text=text_run, icon=icon_run)
+        layout.prop(view, "use_hmd_mirror")
 
         layout.prop(wm, "hmd_view_shade", text="Shading")
 
diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c
index 895521af79..afc05354b3 100644
--- a/source/blender/editors/screen/screen_ops.c
+++ b/source/blender/editors/screen/screen_ops.c
@@ -3076,14 +3076,16 @@ static int region_quadview_exec(bContext *C, wmOperator *op)
 			}
 
 			rv3d->viewlock_quad = RV3D_VIEWLOCK_INIT;
-			rv3d->viewlock = 0;
+			/* allow keeping the LOCKED_SHARED flag */
+			rv3d->viewlock = RV3D_IS_LOCKED_SHARED(rv3d) ? RV3D_LOCKED_SHARED : 0;
 			rv3d->rflag &= ~RV3D_CLIPPING;
 
 			/* accumulate locks, incase they're mixed */
 			for (ar_iter = sa->regionbase.first; ar_iter; ar_iter = ar_iter->next) {
 				if (ar_iter->regiontype == RGN_TYPE_WINDOW) {
 					RegionView3D *rv3d_iter = ar_iter->regiondata;
-					rv3d->viewlock_quad |= rv3d_iter->viewlock;
+					rv3d->viewlock_quad |= (RV3D_IS_LOCKED_SHARED(rv3d_iter)) ?
+					                        (rv3d_iter->viewlock & ~RV3D_LOCKED_SHARED) : rv3d_iter->viewlock;
 				}
 			}
 		}
diff --git a/source/blender/editors/space_view3d/space_view3d.c b/source/blender/editors/space_view3d/space_view3d.c
index 2614b412e6..18c03247a2 100644
--- a/source/blender/editors/space_view3d/space_view3d.c
+++ b/source/blender/editors/space_view3d/space_view3d.c
@@ -181,7 +181,12 @@ bool ED_view3d_context_user_region(bContext *C, View3D **r_v3d, ARegion **r_ar)
 
 		if (ar) {
 			RegionView3D *rv3d;
-			if ((ar->regiontype == RGN_TYPE_WINDOW) && (rv3d = ar->regiondata) && (rv3d->viewlock & RV3D_LOCKED) == 0) {
+			if ((ar->regiontype == RGN_TYPE_WINDOW) &&
+			    (rv3d = ar->regiondata) &&
+			    /* the user region may also use LOCKED_SHARED, meaning the LOCKED flag is
+			     * set but only because it's using the region data from another region */
+			    ((rv3d->viewlock & RV3D_LOCKED) == 0 || RV3D_IS_LOCKED_SHARED(rv3d)))
+			{
 				*r_v3d = v3d;
 				*r_ar = ar;
 				return true;
@@ -193,7 +198,9 @@ bool ED_view3d_context_user_region(bContext *C, View3D **r_v3d, ARegion **r_ar)
 					/* find the first unlocked rv3d */
 					if (ar->regiondata && ar->regiontype == RGN_TYPE_WINDOW) {
 						rv3d = ar->regiondata;
-						if ((rv3d->viewlock & RV3D_LOCKED) == 0) {
+						/* the user region may also use LOCKED_SHARED, meaning the LOCKED flag is
+						 * set but only because it's using the region data from another region */
+						if ((rv3d->viewlock & RV3D_LOCKED) == 0 || RV3D_IS_LOCKED_SHARED(rv3d)) {
 							ar_unlock = ar;
 							if (rv3d->persp == RV3D_PERSP || rv3d->persp == RV3D_CAMOB) {
 								ar_unlock_user = ar;
diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c
index 7840db1537..e3799d654a 100644
--- a/source/blender/editors/space_view3d/view3d_draw.c
+++ b/source/blender/editors/space_view3d/view3d_draw.c
@@ -3729,6 +3729,31 @@ static void view3d_hmd_view_setup(Scene *scene, View3D *v3d, ARegion *ar)
 	ar->winx *= 2;
 }
 
+static void view3d_hmd_view_mirrored_setup(wmWindowManager *wm, Scene *scene, View3D *v3d, ARegion *ar)
+{
+	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];
+
+	/* we calculate a modelviewmatrix (viewmatrix) based on HMD device and
+	 * HMD view, but use the projection matrix (winmatrix) from this v3d */
+
+	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);
+
+	view3d_hmd_view_get_matrices(v3d_hmd, rv3d_hmd, is_left, modelviewmat, projmat);
+
+	/* setup view with adjusted matrices */
+	view3d_main_region_setup_view(scene, v3d, ar, modelviewmat, NULL);
+}
+
 #endif /* WITH_INPUT_HMD */
 
 /* setup the view and win matrices for the multiview cameras
@@ -3825,6 +3850,7 @@ static void view3d_main_region_draw_objects(
         const bContext *C, Scene *scene, View3D *v3d,
         ARegion *ar, const char **grid_unit)
 {
+	wmWindowManager *wm = CTX_wm_manager(C);
 	wmWindow *win = CTX_wm_window(C);
 	RegionView3D *rv3d = ar->regiondata;
 	unsigned int lay_used = v3d->lay_used;
@@ -3844,10 +3870,19 @@ static void view3d_main_region_draw_objects(
 
 	/* setup the view matrix */
 #ifdef WITH_INPUT_HMD
-	if (view3d_hmd_view_active(CTX_wm_manager(C), win)) {
+	if (view3d_hmd_view_active(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
+#else
+	UNUSED_VARS(wm);
 #endif
 	if (view3d_stereo3d_active(C, scene, v3d, rv3d)) {
 		view3d_stereo3d_setup(scene, v3d, ar);
diff --git a/source/blender/makesdna/DNA_view3d_types.h b/source/blender/makesdna/DNA_view3d_types.h
index 4c243507e8..dbe71e3162 100644
--- a/source/blender/makesdna/DNA_view3d_types.h
+++ b/source/blender/makesdna/DNA_view3d_types.h
@@ -284,9 +284,13 @@ typedef struct View3D {
 #define RV3D_LOCKED			(1 << 0)
 #define RV3D_BOXVIEW		(1 << 1)
 #define RV3D_BOXCLIP		(1 << 2)
+#define RV3D_LOCKED_SHARED	(RV3D_LOCKED | (1 << 3)) /* uses viewdata from another rv3d so view manipulation is disabled. */
 /* RegionView3d->viewlock_quad */
 #define RV3D_VIEWLOCK_INIT	(1 << 7)
 
+/* check if the region is both, locked and shared */
+#define RV3D_IS_LOCKED_SHARED(rv3d) (((rv3d)->viewlock & RV3D_LOCKED_SHARED) == RV3D_LOCKED_SHARED)
+
 /* RegionView3d->view */
 #define RV3D_VIEW_USER			 0
 #define RV3D_VIEW_FRONT			 1
@@ -319,6 +323,7 @@ typedef struct View3D {
 
 /* View3d->flag3 (short) */
 #define V3D_SHOW_WORLD			(1 << 0)
+#define V3D_SHOW_HMD_MIRROR		(1 << 1)
 
 /* View3D->around */
 enum {
diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c
index 5e364a3adf..d28f4acab9 100644
--- a/source/blender/makesrna/intern/rna_space.c
+++ b/source/blender/makesrna/intern/rna_space.c
@@ -749,6 +749,28 @@ static EnumPropertyItem *rna_SpaceView3D_stereo3d_camera_itemf(bContext *UNUSED(
 		return stereo3d_camera_items;
 }
 
+#ifdef WITH_INPUT_HMD
+static void rna_SpaceView3D_use_hmd_mirror_update(bContext *C, PointerRNA *ptr, PropertyRNA *UNUSED(prop))
+{
+	View3D *v3d = (View3D *)ptr->data;
+	ScrArea *sa = CTX_wm_area(C);
+
+	BLI_assert(sa->spacetype == SPACE_VIEW3D);
+	BLI_assert(sa->spacedata.first == v3d);
+	for (ARegion *ar = sa->regionbase.first; ar; ar = ar->next) {
+		if (ar->regiontype == RGN_TYPE_WINDOW) {
+			RegionView3D *rv3d = ar->regiondata;
+			if ((v3d->flag3 & V3D_SHOW_HMD_MIRROR) && (rv3d->viewlock & RV3D_LOCKED) == 0) {
+				rv3d->viewlock |= RV3D_LOCKED_SHARED;
+			}
+			else if (((v3d->flag3 & V3D_SHOW_HMD_MIRROR) == 0) && RV3D_IS_LOCKED_SHARED(rv3d)) {
+				rv3d->viewlock &= ~RV3D_LOCKED_SHARED;
+			}
+		}
+	}
+}
+#endif
+
 /* Space Image Editor */
 
 static PointerRNA rna_SpaceImageEditor_uvedit_get(PointerRNA *ptr)
@@ -2781,6 +2803,15 @@ static void rna_def_space_view3d(BlenderRNA *brna)
 	RNA_def_property_ui_text(prop, "Volume Alpha", "Opacity (alpha) of the cameras' frustum volume");
 	RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL);
 
+#ifdef WITH_INPUT_HMD
+	prop = RNA_def_property(srna, "use_hmd_mirror", PROP_BOOLEAN, PROP_NONE);
+	RNA_def_property_boolean_sdna(prop, NULL, "flag3", V3D_SHOW_HMD_MIRROR);
+	RNA_def_property_ui_text(prop, "Mirror HMD View", "Link the orientation of this 3D View to the HMD view "
+	                         "(may slowdown viewport drawing)");
+	RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE);
+	RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, "rna_SpaceView3D_use_hmd_mirror_update");
+#endif
+
 	/* *** Animated *** */
 	RNA_define_animate_sdna(true);
 	/* region */
diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c
index 94ff3aa777..9091aa3cc0 100644
--- a/source/blender/windowmanager/intern/wm_event_system.c
+++ b/source/blender/windowmanager/intern/wm_event_system.c
@@ -411,7 +411,7 @@ void wm_event_do_notifiers(bContext *C)
 static int wm_event_always_pass(const wmEvent *event)
 {
 	/* some events we always pass on, to ensure proper communication */
-	return ISTIMER(event->type) || (event->type == WINDEACTIVATE);
+	return ISTIMER(event->type) || (ELEM(event->type, WINDEACTIVATE, EVT_HMD_TRANSFORM));
 }
 
 /* ********************* ui handler ******************* */
diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c
index 9c31b2c6dd..2a3f333e44 100644
--- a/source/blender/windowmanager/intern/wm_operators.c
+++ b/source/blender/windowmanager/intern/wm_operators.c
@@ -4199,6 +4199,28 @@ static int hmd_session_toggle_poll(bContext *C)
 	return true;
 }
 
+static void hmd_session_disable_viewlocks(wmWindowManager *wm)
+{
+	for (wmWindow *win = wm->windows.first; win; win = win->next) {
+		for (ScrArea *sa = win->screen->areabase.first; sa; sa = sa->next) {
+			if (sa->space

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list