From 130601a1cd47c95bd383c535dbadfce7a0de8f31 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Thomas=20M=C3=BCller?= <tmueller@nvidia.com>
Date: Tue, 7 Feb 2023 10:33:05 +0100
Subject: [PATCH] VR: add toggle for hidden area masking & add Python bindings

---
 include/neural-graphics-primitives/testbed.h |  3 ++-
 src/openxr_hmd.cu                            |  2 +-
 src/python_api.cu                            |  2 ++
 src/testbed.cu                               | 14 ++++++++------
 4 files changed, 13 insertions(+), 8 deletions(-)

diff --git a/include/neural-graphics-primitives/testbed.h b/include/neural-graphics-primitives/testbed.h
index 4490d0b..af403d8 100644
--- a/include/neural-graphics-primitives/testbed.h
+++ b/include/neural-graphics-primitives/testbed.h
@@ -607,7 +607,8 @@ public:
 
 	std::unique_ptr<OpenXRHMD> m_hmd;
 	OpenXRHMD::FrameInfoPtr m_vr_frame_info;
-	bool m_vr_depth_reproject = false;
+	bool m_vr_use_depth_reproject = false;
+	bool m_vr_use_hidden_area_mask = true;
 
 	void set_n_views(size_t n_views);
 
diff --git a/src/openxr_hmd.cu b/src/openxr_hmd.cu
index a60ad43..e394f07 100644
--- a/src/openxr_hmd.cu
+++ b/src/openxr_hmd.cu
@@ -167,7 +167,7 @@ OpenXRHMD::OpenXRHMD(wl_display* display) {
 	// tlog::success() << " "
 	// 	<< " depth=" << (m_supports_composition_layer_depth ? "true" : "false")
 	// 	<< " mask=" << (m_supports_hidden_area_mask ? "true" : "false")
-	// 	<< " eye=" << (m_supports_hidden_area_mask ? "true" : "false")
+	// 	<< " eye=" << (m_supports_eye_tracking ? "true" : "false")
 	// 	;
 }
 
diff --git a/src/python_api.cu b/src/python_api.cu
index 951d795..bca3621 100644
--- a/src/python_api.cu
+++ b/src/python_api.cu
@@ -379,6 +379,8 @@ PYBIND11_MODULE(pyngp, m) {
 		.def("is_shift_down", [](py::object& obj) { return ImGui::GetIO().KeyMods & ImGuiKeyModFlags_Shift; })
 		.def("is_super_down", [](py::object& obj) { return ImGui::GetIO().KeyMods & ImGuiKeyModFlags_Super; })
 		.def("screenshot", &Testbed::screenshot, "Takes a screenshot of the current window contents.", py::arg("linear")=true)
+		.def_readwrite("vr_use_hidden_area_mask", &Testbed::m_vr_use_hidden_area_mask)
+		.def_readwrite("vr_use_depth_reproject", &Testbed::m_vr_use_depth_reproject)
 #endif
 		.def("want_repl", &Testbed::want_repl, "returns true if the user clicked the 'I want a repl' button")
 		.def("frame", &Testbed::frame, py::call_guard<py::gil_scoped_release>(), "Process a single frame. Renders if a window was previously created.")
diff --git a/src/testbed.cu b/src/testbed.cu
index 70aa0bc..e442bd0 100644
--- a/src/testbed.cu
+++ b/src/testbed.cu
@@ -931,7 +931,6 @@ void Testbed::imgui() {
 		} else {
 			if (ImGui::Button("Disconnect from VR/AR headset")) {
 				m_hmd.reset();
-				m_vr_frame_info = nullptr;
 				update_vr_performance_settings();
 			} else if (ImGui::TreeNodeEx("VR/AR settings", ImGuiTreeNodeFlags_DefaultOpen)) {
 				static int blend_mode_idx = 0;
@@ -948,7 +947,11 @@ void Testbed::imgui() {
 					ImGui::Checkbox("Multi-GPU rendering (one per eye)", &m_use_aux_devices);
 				}
 
-				accum_reset |= ImGui::Checkbox("Depth-based reprojection", &m_vr_depth_reproject);
+				accum_reset |= ImGui::Checkbox("Depth-based reprojection", &m_vr_use_depth_reproject);
+				if (ImGui::Checkbox("Mask hidden display areas", &m_vr_use_hidden_area_mask)) {
+					accum_reset = true;
+					set_all_devices_dirty();
+				}
 				accum_reset |= ImGui::Checkbox("Foveated rendering", &m_foveated_rendering) && !m_dlss;
 				if (m_foveated_rendering) {
 					accum_reset |= ImGui::SliderFloat("Maximum foveation", &m_foveated_rendering_max_scaling, 1.0f, 16.0f, "%.01f", ImGuiSliderFlags_Logarithmic | ImGuiSliderFlags_NoRoundToFormat) && !m_dlss;
@@ -1654,7 +1657,6 @@ void Testbed::draw_visualizations(ImDrawList* list, const Matrix<float, 3, 4>& c
 
 		ImGuizmo::SetRect(0, 0, io.DisplaySize.x, io.DisplaySize.y);
 
-		static bool manipulating = false;
 		static Eigen::Matrix4f matrix = Eigen::Matrix4f::Identity();
 		static Eigen::Matrix4f world2view_guizmo = Eigen::Matrix4f::Identity();
 
@@ -2085,7 +2087,7 @@ void Testbed::begin_vr_frame_and_handle_vr_input() {
 
 			// Fix up weirdness in the rendering pipeline
 			m_views[i].relative_focal_length[(m_fov_axis+1)%2] *= (float)view_resolution[(m_fov_axis+1)%2] / (float)view_resolution[m_fov_axis];
-			m_views[i].render_buffer->set_hidden_area_mask(views[i].hidden_area_mask);
+			m_views[i].render_buffer->set_hidden_area_mask(m_vr_use_hidden_area_mask ? views[i].hidden_area_mask : nullptr);
 
 			// Render each view on a different GPU (if available)
 			m_views[i].device = m_use_aux_devices ? &m_devices.at(i % m_devices.size()) : &primary_device();
@@ -3181,8 +3183,8 @@ bool Testbed::frame() {
 			return false;
 		}
 
-		begin_vr_frame_and_handle_vr_input();
 		handle_user_input();
+		begin_vr_frame_and_handle_vr_input();
 	}
 #endif
 
@@ -3268,7 +3270,7 @@ bool Testbed::frame() {
 		// Far and near planes are intentionally reversed, because we map depth inversely
 		// to z. I.e. a window-space depth of 1 refers to the near plane and a depth of 0
 		// to the far plane. This results in much better numeric precision.
-		m_hmd->end_frame(m_vr_frame_info, m_ndc_zfar / m_scale, m_ndc_znear / m_scale, m_vr_depth_reproject);
+		m_hmd->end_frame(m_vr_frame_info, m_ndc_zfar / m_scale, m_ndc_znear / m_scale, m_vr_use_depth_reproject);
 	}
 #endif
 
-- 
GitLab