From b16e72ff4e29fc4fb781ec67b087b072f2ecba69 Mon Sep 17 00:00:00 2001 From: Grant Commodore Date: Mon, 29 Apr 2024 17:36:16 +0000 Subject: [PATCH 1/6] Adds multiview to CubeXr --- include/ppx/application.h | 15 +++++++ include/ppx/xr_component.h | 8 +++- projects/cube_xr/CMakeLists.txt | 2 +- projects/cube_xr/CubeXr.cpp | 38 +++++++++++++----- projects/cube_xr/CubeXr.h | 9 +++++ src/ppx/xr_component.cpp | 71 ++++++++++++++++++++++++++++++--- 6 files changed, 123 insertions(+), 20 deletions(-) diff --git a/include/ppx/application.h b/include/ppx/application.h index 74c9384cb..9494f6460 100644 --- a/include/ppx/application.h +++ b/include/ppx/application.h @@ -389,6 +389,21 @@ class Application { return GetSwapchain(mUISwapchainIndex); } + + ppx::float4x4 GetViewProjectionMatrix(uint32_t viewIndex, float nearZ, float farZ) + { + ppx::float4x4 viewProjectionMatrix(1); + viewProjectionMatrix = mXrComponent.GetViewProjectionMatrix(viewIndex, nearZ, farZ); + return viewProjectionMatrix; + } + + uint32_t GetCurrentViewIndex() const + { + uint32_t current_view_index = 0; + current_view_index = (IsXrEnabled() ? mXrComponent.GetCurrentViewIndex() : 0); + + return current_view_index; + } #else // Alias for UI component in non-XR contexts. grfx::SwapchainPtr GetUISwapchain() const diff --git a/include/ppx/xr_component.h b/include/ppx/xr_component.h index 1ff2a51ba..82905a93f 100644 --- a/include/ppx/xr_component.h +++ b/include/ppx/xr_component.h @@ -217,8 +217,12 @@ class XrComponent // The values for the frustum planes will be sent to the OpenXR runtime // as part of the frame depth info submission, and the caller must ensure // that the values do not change within a frame. - void SetFrustumPlanes(float nearZ, float farZ); - XrPosef GetPoseForCurrentView() const; + glm::mat4 GetViewProjectionMatrix(uint32_t viewIndex, float nearZ, float farZ); + glm::mat4 GetProjectionMatrixForViewAndSetFrustumPlanes(uint32_t viewIndex, float nearZ, float farZ); + glm::mat4 GetProjectionMatrixForCurrentViewAndSetFrustumPlanes(float nearZ, float farZ); + glm::mat4 GetViewMatrix(uint32_t viewIndex) const; + glm::mat4 GetViewMatrixForCurrentView() const; + XrPosef GetPoseForCurrentView() const; std::optional GetUIAimState() const { return mImguiAimState; } std::optional GetUIClickState() const { return mImguiClickState; } diff --git a/projects/cube_xr/CMakeLists.txt b/projects/cube_xr/CMakeLists.txt index 272af3bc7..558ff4a0d 100644 --- a/projects/cube_xr/CMakeLists.txt +++ b/projects/cube_xr/CMakeLists.txt @@ -19,4 +19,4 @@ add_samples_for_all_apis( "CubeXr.h" "CubeXr.cpp" "main.cpp" - SHADER_DEPENDENCIES "shader_vertex_colors") + SHADER_DEPENDENCIES "shader_vertex_colors_multi") diff --git a/projects/cube_xr/CubeXr.cpp b/projects/cube_xr/CubeXr.cpp index c614c8960..dc1c343c5 100644 --- a/projects/cube_xr/CubeXr.cpp +++ b/projects/cube_xr/CubeXr.cpp @@ -31,6 +31,11 @@ void CubeXrApp::Config(ppx::ApplicationSettings& settings) settings.grfx.swapchain.depthFormat = grfx::FORMAT_D32_FLOAT; settings.grfx.pacedFrameRate = 0; settings.xr.enable = true; + settings.xr.enableDebugCapture = false; + settings.xr.enableMultiView = true; +#if PPX_ANDROID + settings.xr.enable = true; +#endif } void CubeXrApp::Setup() @@ -38,7 +43,7 @@ void CubeXrApp::Setup() // Uniform buffer { grfx::BufferCreateInfo bufferCreateInfo = {}; - bufferCreateInfo.size = PPX_MINIMUM_UNIFORM_BUFFER_SIZE; + bufferCreateInfo.size = std::max(sizeof(UniformBufferData), (uint64_t)PPX_MINIMUM_UNIFORM_BUFFER_SIZE); bufferCreateInfo.usageFlags.bits.uniformBuffer = true; bufferCreateInfo.memoryUsage = grfx::MEMORY_USAGE_CPU_TO_GPU; @@ -68,12 +73,12 @@ void CubeXrApp::Setup() // Pipeline { - std::vector bytecode = LoadShader("basic/shaders", "VertexColors.vs"); + std::vector bytecode = LoadShader("basic/shaders", "VertexColorsMulti.vs"); PPX_ASSERT_MSG(!bytecode.empty(), "VS shader bytecode load failed"); grfx::ShaderModuleCreateInfo shaderCreateInfo = {static_cast(bytecode.size()), bytecode.data()}; PPX_CHECKED_CALL(GetDevice()->CreateShaderModule(&shaderCreateInfo, &mVS)); - bytecode = LoadShader("basic/shaders", "VertexColors.ps"); + bytecode = LoadShader("basic/shaders", "VertexColorsMulti.ps"); PPX_ASSERT_MSG(!bytecode.empty(), "PS shader bytecode load failed"); shaderCreateInfo = {static_cast(bytecode.size()), bytecode.data()}; PPX_CHECKED_CALL(GetDevice()->CreateShaderModule(&shaderCreateInfo, &mPS)); @@ -103,6 +108,8 @@ void CubeXrApp::Setup() gpCreateInfo.outputState.renderTargetFormats[0] = GetSwapchain()->GetColorFormat(); gpCreateInfo.outputState.depthStencilFormat = GetSwapchain()->GetDepthFormat(); gpCreateInfo.pPipelineInterface = mPipelineInterface; + gpCreateInfo.multiViewState.viewMask = GetXrComponent().GetDefaultViewMask(); + gpCreateInfo.multiViewState.correlationMask = GetXrComponent().GetDefaultViewMask(); PPX_CHECKED_CALL(GetDevice()->CreateGraphicsPipeline(&gpCreateInfo, &mPipeline)); } @@ -269,20 +276,29 @@ void CubeXrApp::Render() // Update uniform buffer. { float t = GetElapsedSeconds(); - float4x4 P = glm::perspective(glm::radians(60.0f), GetWindowAspect(), 0.001f, 10000.0f); - float4x4 V = glm::lookAt(float3(0, 0, 0), float3(0, 0, 1), float3(0, 1, 0)); + float4x4 M = glm::translate(float3(0, 0, -3)) * glm::rotate(t, float3(0, 0, 1)) * glm::rotate(t, float3(0, 1, 0)) * glm::rotate(t, float3(1, 0, 0)); if (IsXrEnabled()) { - const Camera& camera = GetXrComponent().GetCamera(); - P = camera.GetProjectionMatrix(); - V = camera.GetViewMatrix(); + frame.uniform_buffer_data.M[0] = GetViewProjectionMatrix(0, 0.001f, 10000.0f) * M; + frame.uniform_buffer_data.M[1] = GetViewProjectionMatrix(1, 0.001f, 10000.0f) * M; + } + else { + const Camera& camera = GetXrComponent().GetCamera(); + float4x4 P = camera.GetProjectionMatrix(); + float4x4 V = camera.GetViewMatrix(); + frame.uniform_buffer_data.M[0] = frame.uniform_buffer_data.M[1] = P * V * M; + } + + // If multiview is active, we have one render pass with Left/Right poses loaded. + // If not multiview, this entire render call will happen again, and we switch to current view index. + + if (!GetXrComponent().IsMultiView()) { + frame.uniform_buffer_data.M[0] = frame.uniform_buffer_data.M[GetCurrentViewIndex()]; } - float4x4 M = glm::translate(float3(0, 0, -3)) * glm::rotate(t, float3(0, 0, 1)) * glm::rotate(t, float3(0, 1, 0)) * glm::rotate(t, float3(1, 0, 0)); - float4x4 mat = P * V * M; void* pData = nullptr; PPX_CHECKED_CALL(mUniformBuffer->MapMemory(0, &pData)); - memcpy(pData, &mat, sizeof(mat)); + memcpy(pData, &frame.uniform_buffer_data, sizeof(frame.uniform_buffer_data)); mUniformBuffer->UnmapMemory(); } diff --git a/projects/cube_xr/CubeXr.h b/projects/cube_xr/CubeXr.h index fa4a159fc..83a21a8e3 100644 --- a/projects/cube_xr/CubeXr.h +++ b/projects/cube_xr/CubeXr.h @@ -28,6 +28,13 @@ class CubeXrApp virtual void Render() override; private: + struct UniformBufferData + { + // Pose of each Cube + // One for each eye, but second only used in multi-view + ppx::float4x4 M[2]; + }; + struct PerFrame { grfx::CommandBufferPtr cmd; @@ -36,6 +43,8 @@ class CubeXrApp grfx::SemaphorePtr renderCompleteSemaphore; grfx::FencePtr renderCompleteFence; + UniformBufferData uniform_buffer_data = {}; + // XR UI per frame elements. grfx::CommandBufferPtr uiCmd; grfx::FencePtr uiRenderCompleteFence; diff --git a/src/ppx/xr_component.cpp b/src/ppx/xr_component.cpp index c5b5202be..2a49bb692 100644 --- a/src/ppx/xr_component.cpp +++ b/src/ppx/xr_component.cpp @@ -838,14 +838,38 @@ bool XrComponent::RemoveLayer(LayerRef layerRef) return mLayers.erase(layerRef); } -XrPosef XrComponent::GetPoseForCurrentView() const +glm::mat4 XrComponent::GetViewMatrix(uint32_t viewIndex) const +{ + PPX_ASSERT_MSG((viewIndex < mViews.size()), "Invalid view index!"); + const XrView& view = mViews[viewIndex]; + const XrPosef& pose = view.pose; + // OpenXR is using right handed system which is the same as Vulkan + glm::quat quat = glm::quat(pose.orientation.w, pose.orientation.x, pose.orientation.y, pose.orientation.z); + glm::mat4 rotation = glm::mat4_cast(quat); + glm::vec3 position = glm::vec3(pose.position.x, pose.position.y, pose.position.z); + glm::mat4 translation = glm::translate(glm::mat4(1.f), position); + glm::mat4 view_glm = translation * rotation; + glm::mat4 view_glm_inv = glm::inverse(view_glm); + return view_glm_inv; +} + +glm::mat4 XrComponent::GetViewMatrixForCurrentView() const { PPX_ASSERT_MSG((mCurrentViewIndex < mViews.size()), "Invalid view index!"); - return mViews[mCurrentViewIndex].pose; + return GetViewMatrix(mCurrentViewIndex); +} + +glm::mat4 XrComponent::GetProjectionMatrixForCurrentViewAndSetFrustumPlanes(float nearZ, float farZ) +{ + return GetProjectionMatrixForViewAndSetFrustumPlanes(mCurrentViewIndex, nearZ, farZ); } -void XrComponent::SetFrustumPlanes(float nearZ, float farZ) +glm::mat4 XrComponent::GetProjectionMatrixForViewAndSetFrustumPlanes(uint32_t viewIndex, float nearZ, float farZ) { + PPX_ASSERT_MSG((mCurrentViewIndex < mViews.size()), "Invalid view index!"); + const XrView& view = mViews[viewIndex]; + const XrFovf& fov = view.fov; + // Save near and far plane values so that they can be referenced // in EndFrame(), as part of the depth layer info submission. // They can only be set once per frame. @@ -854,9 +878,44 @@ void XrComponent::SetFrustumPlanes(float nearZ, float farZ) mNearPlaneForFrame = nearZ; mFarPlaneForFrame = farZ; - for (XrCamera& camera : mCameras) { - camera.SetFrustumPlanes(nearZ, farZ); - } + const float tan_left = tanf(fov.angleLeft); + const float tan_right = tanf(fov.angleRight); + const float tan_down = tanf(fov.angleDown); + const float tan_up = tanf(fov.angleUp); + + const float tan_width = tan_right - tan_left; + const float tan_height = (tan_up - tan_down); + + const float a00 = 2 / tan_width; + const float a11 = 2 / tan_height; + + const float a20 = (tan_right + tan_left) / tan_width; + const float a21 = (tan_up + tan_down) / tan_height; + const float a22 = -farZ / (farZ - nearZ); + + const float a32 = -(farZ * nearZ) / (farZ - nearZ); + + // clang-format off + const float mat[16] = { + a00, 0, 0, 0, + 0, a11, 0, 0, + a20, a21, a22, -1, + 0, 0, a32, 0, + }; + // clang-format on + + return glm::make_mat4(mat); +} + +glm::mat4 XrComponent::GetViewProjectionMatrix(uint32_t viewIndex, float nearZ, float farZ) +{ + return GetProjectionMatrixForViewAndSetFrustumPlanes(viewIndex, nearZ, farZ) * GetViewMatrix(viewIndex); +} + +XrPosef XrComponent::GetPoseForCurrentView() const +{ + PPX_ASSERT_MSG((mCurrentViewIndex < mViews.size()), "Invalid view index!"); + return mViews[mCurrentViewIndex].pose; } uint32_t XrComponent::GetDefaultViewMask() const From dce56554c0b7464ca5eb32da7e2084c66cffd65f Mon Sep 17 00:00:00 2001 From: Grant Commodore Date: Thu, 20 Jun 2024 21:08:39 +0000 Subject: [PATCH 2/6] Removes redundant xr setting, utilizes xr_component for viewProjectionMatrix and currentViewIndex --- include/ppx/application.h | 15 --------------- projects/cube_xr/CubeXr.cpp | 24 +++++++++++------------- 2 files changed, 11 insertions(+), 28 deletions(-) diff --git a/include/ppx/application.h b/include/ppx/application.h index 9494f6460..74c9384cb 100644 --- a/include/ppx/application.h +++ b/include/ppx/application.h @@ -389,21 +389,6 @@ class Application { return GetSwapchain(mUISwapchainIndex); } - - ppx::float4x4 GetViewProjectionMatrix(uint32_t viewIndex, float nearZ, float farZ) - { - ppx::float4x4 viewProjectionMatrix(1); - viewProjectionMatrix = mXrComponent.GetViewProjectionMatrix(viewIndex, nearZ, farZ); - return viewProjectionMatrix; - } - - uint32_t GetCurrentViewIndex() const - { - uint32_t current_view_index = 0; - current_view_index = (IsXrEnabled() ? mXrComponent.GetCurrentViewIndex() : 0); - - return current_view_index; - } #else // Alias for UI component in non-XR contexts. grfx::SwapchainPtr GetUISwapchain() const diff --git a/projects/cube_xr/CubeXr.cpp b/projects/cube_xr/CubeXr.cpp index dc1c343c5..a6aee3e5a 100644 --- a/projects/cube_xr/CubeXr.cpp +++ b/projects/cube_xr/CubeXr.cpp @@ -31,11 +31,7 @@ void CubeXrApp::Config(ppx::ApplicationSettings& settings) settings.grfx.swapchain.depthFormat = grfx::FORMAT_D32_FLOAT; settings.grfx.pacedFrameRate = 0; settings.xr.enable = true; - settings.xr.enableDebugCapture = false; settings.xr.enableMultiView = true; -#if PPX_ANDROID - settings.xr.enable = true; -#endif } void CubeXrApp::Setup() @@ -208,11 +204,13 @@ void CubeXrApp::Setup() void CubeXrApp::Render() { - PerFrame& frame = mPerFrame[0]; - uint32_t imageIndex = UINT32_MAX; - uint32_t currentViewIndex = 0; + PerFrame& frame = mPerFrame[0]; + uint32_t imageIndex = UINT32_MAX; + uint32_t currentViewIndex = 0; + XrComponent& xrComponent = GetXrComponent(); + if (IsXrEnabled()) { - currentViewIndex = GetXrComponent().GetCurrentViewIndex(); + currentViewIndex = xrComponent.GetCurrentViewIndex(); } // Render UI into a different composition layer. @@ -279,11 +277,11 @@ void CubeXrApp::Render() float4x4 M = glm::translate(float3(0, 0, -3)) * glm::rotate(t, float3(0, 0, 1)) * glm::rotate(t, float3(0, 1, 0)) * glm::rotate(t, float3(1, 0, 0)); if (IsXrEnabled()) { - frame.uniform_buffer_data.M[0] = GetViewProjectionMatrix(0, 0.001f, 10000.0f) * M; - frame.uniform_buffer_data.M[1] = GetViewProjectionMatrix(1, 0.001f, 10000.0f) * M; + frame.uniform_buffer_data.M[0] = xrComponent.GetViewProjectionMatrix(0, 0.001f, 10000.0f) * M; + frame.uniform_buffer_data.M[1] = xrComponent.GetViewProjectionMatrix(1, 0.001f, 10000.0f) * M; } else { - const Camera& camera = GetXrComponent().GetCamera(); + const Camera& camera = xrComponent.GetCamera(); float4x4 P = camera.GetProjectionMatrix(); float4x4 V = camera.GetViewMatrix(); frame.uniform_buffer_data.M[0] = frame.uniform_buffer_data.M[1] = P * V * M; @@ -292,8 +290,8 @@ void CubeXrApp::Render() // If multiview is active, we have one render pass with Left/Right poses loaded. // If not multiview, this entire render call will happen again, and we switch to current view index. - if (!GetXrComponent().IsMultiView()) { - frame.uniform_buffer_data.M[0] = frame.uniform_buffer_data.M[GetCurrentViewIndex()]; + if (!xrComponent.IsMultiView()) { + frame.uniform_buffer_data.M[0] = frame.uniform_buffer_data.M[IsXrEnabled() ? xrComponent.GetCurrentViewIndex() : 0]; } void* pData = nullptr; From ca84ca9f13e677f5b113cf5a7defd742ef4e6f49 Mon Sep 17 00:00:00 2001 From: Grant Commodore Date: Tue, 9 Jul 2024 21:20:09 +0000 Subject: [PATCH 3/6] Adds multiview knob flag --- include/ppx/application.h | 2 ++ projects/cube_xr/CubeXr.cpp | 1 - src/ppx/application.cpp | 6 ++++++ 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/include/ppx/application.h b/include/ppx/application.h index 74c9384cb..d83d80d68 100644 --- a/include/ppx/application.h +++ b/include/ppx/application.h @@ -89,6 +89,7 @@ struct StandardOptions #if defined(PPX_BUILD_XR) std::shared_ptr>> pXrUiResolution; std::shared_ptr>> pXrRequiredExtensions; + std::shared_ptr> pXrEnableMultiview; #endif std::shared_ptr>> pAssetsPaths; @@ -211,6 +212,7 @@ struct ApplicationSettings #if defined(PPX_BUILD_XR) std::pair xrUiResolution = std::make_pair(0, 0); std::vector xrRequiredExtensions = {}; + bool xrEnableMultiview = false; #endif } standardKnobsDefaultValue; }; diff --git a/projects/cube_xr/CubeXr.cpp b/projects/cube_xr/CubeXr.cpp index a6aee3e5a..ad46db76d 100644 --- a/projects/cube_xr/CubeXr.cpp +++ b/projects/cube_xr/CubeXr.cpp @@ -31,7 +31,6 @@ void CubeXrApp::Config(ppx::ApplicationSettings& settings) settings.grfx.swapchain.depthFormat = grfx::FORMAT_D32_FLOAT; settings.grfx.pacedFrameRate = 0; settings.xr.enable = true; - settings.xr.enableMultiView = true; } void CubeXrApp::Setup() diff --git a/src/ppx/application.cpp b/src/ppx/application.cpp index d91b7f88e..6859754c3 100644 --- a/src/ppx/application.cpp +++ b/src/ppx/application.cpp @@ -682,6 +682,10 @@ void Application::InitStandardKnobs() "to the base extensions. Any required extensions that are not supported by the " "target system will cause the application to immediately exit."); mStandardOpts.pXrRequiredExtensions->SetFlagParameters(""); + + GetKnobManager().InitKnob(&mStandardOpts.pXrEnableMultiview, "xr-multiview-enabled", mSettings.standardKnobsDefaultValue.xrEnableMultiview); + mStandardOpts.pXrEnableMultiview->SetFlagDescription( + "Specify whether or not multiview should be enabled for the application."); #endif GetKnobManager().InitKnob(&mStandardOpts.pShadingRateMode, "shading-rate-mode", ""); @@ -933,6 +937,8 @@ void Application::UpdateStandardSettings() mSettings.xr.uiWidth = resolution.first; mSettings.xr.uiHeight = resolution.second; } + + mSettings.xr.enableMultiView = mStandardOpts.pXrEnableMultiview->GetValue(); #endif // Disable ImGui in headless or deterministic mode. From 7ab283d25e8c346ab540f7fedfb671a181528924 Mon Sep 17 00:00:00 2001 From: Grant Commodore Date: Thu, 25 Jul 2024 21:50:45 +0000 Subject: [PATCH 4/6] Renames multiview knob flag --- src/ppx/application.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ppx/application.cpp b/src/ppx/application.cpp index 6859754c3..d37849656 100644 --- a/src/ppx/application.cpp +++ b/src/ppx/application.cpp @@ -683,7 +683,7 @@ void Application::InitStandardKnobs() "target system will cause the application to immediately exit."); mStandardOpts.pXrRequiredExtensions->SetFlagParameters(""); - GetKnobManager().InitKnob(&mStandardOpts.pXrEnableMultiview, "xr-multiview-enabled", mSettings.standardKnobsDefaultValue.xrEnableMultiview); + GetKnobManager().InitKnob(&mStandardOpts.pXrEnableMultiview, "xr-enable-multiview", mSettings.standardKnobsDefaultValue.xrEnableMultiview); mStandardOpts.pXrEnableMultiview->SetFlagDescription( "Specify whether or not multiview should be enabled for the application."); #endif From 10c46c28bbff8ebd9cfec8d152753b5ca801bfc1 Mon Sep 17 00:00:00 2001 From: Grant Commodore Date: Thu, 25 Jul 2024 22:59:39 +0000 Subject: [PATCH 5/6] Removes enable multiview from ApplicationSettings --- include/ppx/application.h | 5 ----- src/ppx/application.cpp | 6 ++---- 2 files changed, 2 insertions(+), 9 deletions(-) diff --git a/include/ppx/application.h b/include/ppx/application.h index d83d80d68..ed6bbb8f1 100644 --- a/include/ppx/application.h +++ b/include/ppx/application.h @@ -120,11 +120,6 @@ struct ApplicationSettings { bool enable = false; - // Multiview will create one swapchain with layers per view - // One Application::Render then should use multiview shaders - // to render to both layers, as opposed to non multiview - // where there is one swapchain per view, each with a ::Render - bool enableMultiView = false; // Whether to create depth swapchains in addition to color swapchains, // and submit the depth info to the runtime as an additional layer. bool enableDepthSwapchain = false; diff --git a/src/ppx/application.cpp b/src/ppx/application.cpp index d37849656..891bb95f8 100644 --- a/src/ppx/application.cpp +++ b/src/ppx/application.cpp @@ -162,7 +162,7 @@ Result Application::InitializeGrfxDevice() ci.pVulkanDeviceFeatures = nullptr; ci.supportShadingRateMode = mSettings.grfx.device.supportShadingRateMode; #if defined(PPX_BUILD_XR) - ci.multiView = IsXrEnabled() && mSettings.xr.enableMultiView; + ci.multiView = IsXrEnabled() && mStandardOpts.pXrEnableMultiview->GetValue(); ci.pXrComponent = IsXrEnabled() ? &mXrComponent : nullptr; #endif @@ -937,8 +937,6 @@ void Application::UpdateStandardSettings() mSettings.xr.uiWidth = resolution.first; mSettings.xr.uiHeight = resolution.second; } - - mSettings.xr.enableMultiView = mStandardOpts.pXrEnableMultiview->GetValue(); #endif // Disable ImGui in headless or deterministic mode. @@ -979,7 +977,7 @@ void Application::InitializeXRComponentBeforeGrfxDeviceInit() createInfo.enableDebug = mSettings.grfx.enableDebug; createInfo.enableQuadLayer = mSettings.enableImGui; createInfo.enableDepthSwapchain = mSettings.xr.enableDepthSwapchain; - createInfo.enableMultiView = mSettings.xr.enableMultiView; + createInfo.enableMultiView = mStandardOpts.pXrEnableMultiview->GetValue(); const auto resolution = mStandardOpts.pResolution->GetValue(); const bool hasResolutionFlag = (resolution.first > 0 && resolution.second > 0); if (hasResolutionFlag) { From d3c7e60864d9d883ff5254c403fa704ae4e65577 Mon Sep 17 00:00:00 2001 From: Grant Date: Wed, 11 Sep 2024 23:15:09 +0000 Subject: [PATCH 6/6] Removes added xrcomponent functions, simplifies cubexr update uniform buffer --- include/ppx/xr_component.h | 8 ++--- projects/cube_xr/CubeXr.cpp | 7 ++-- src/ppx/xr_component.cpp | 71 ++++--------------------------------- 3 files changed, 13 insertions(+), 73 deletions(-) diff --git a/include/ppx/xr_component.h b/include/ppx/xr_component.h index 82905a93f..1ff2a51ba 100644 --- a/include/ppx/xr_component.h +++ b/include/ppx/xr_component.h @@ -217,12 +217,8 @@ class XrComponent // The values for the frustum planes will be sent to the OpenXR runtime // as part of the frame depth info submission, and the caller must ensure // that the values do not change within a frame. - glm::mat4 GetViewProjectionMatrix(uint32_t viewIndex, float nearZ, float farZ); - glm::mat4 GetProjectionMatrixForViewAndSetFrustumPlanes(uint32_t viewIndex, float nearZ, float farZ); - glm::mat4 GetProjectionMatrixForCurrentViewAndSetFrustumPlanes(float nearZ, float farZ); - glm::mat4 GetViewMatrix(uint32_t viewIndex) const; - glm::mat4 GetViewMatrixForCurrentView() const; - XrPosef GetPoseForCurrentView() const; + void SetFrustumPlanes(float nearZ, float farZ); + XrPosef GetPoseForCurrentView() const; std::optional GetUIAimState() const { return mImguiAimState; } std::optional GetUIClickState() const { return mImguiClickState; } diff --git a/projects/cube_xr/CubeXr.cpp b/projects/cube_xr/CubeXr.cpp index ad46db76d..f51d3c651 100644 --- a/projects/cube_xr/CubeXr.cpp +++ b/projects/cube_xr/CubeXr.cpp @@ -276,8 +276,11 @@ void CubeXrApp::Render() float4x4 M = glm::translate(float3(0, 0, -3)) * glm::rotate(t, float3(0, 0, 1)) * glm::rotate(t, float3(0, 1, 0)) * glm::rotate(t, float3(1, 0, 0)); if (IsXrEnabled()) { - frame.uniform_buffer_data.M[0] = xrComponent.GetViewProjectionMatrix(0, 0.001f, 10000.0f) * M; - frame.uniform_buffer_data.M[1] = xrComponent.GetViewProjectionMatrix(1, 0.001f, 10000.0f) * M; + xrComponent.SetCurrentViewIndex(0); + frame.uniform_buffer_data.M[0] = xrComponent.GetCamera().GetViewProjectionMatrix() * M; + + xrComponent.SetCurrentViewIndex(1); + frame.uniform_buffer_data.M[1] = xrComponent.GetCamera().GetViewProjectionMatrix() * M; } else { const Camera& camera = xrComponent.GetCamera(); diff --git a/src/ppx/xr_component.cpp b/src/ppx/xr_component.cpp index 2a49bb692..c5b5202be 100644 --- a/src/ppx/xr_component.cpp +++ b/src/ppx/xr_component.cpp @@ -838,38 +838,14 @@ bool XrComponent::RemoveLayer(LayerRef layerRef) return mLayers.erase(layerRef); } -glm::mat4 XrComponent::GetViewMatrix(uint32_t viewIndex) const -{ - PPX_ASSERT_MSG((viewIndex < mViews.size()), "Invalid view index!"); - const XrView& view = mViews[viewIndex]; - const XrPosef& pose = view.pose; - // OpenXR is using right handed system which is the same as Vulkan - glm::quat quat = glm::quat(pose.orientation.w, pose.orientation.x, pose.orientation.y, pose.orientation.z); - glm::mat4 rotation = glm::mat4_cast(quat); - glm::vec3 position = glm::vec3(pose.position.x, pose.position.y, pose.position.z); - glm::mat4 translation = glm::translate(glm::mat4(1.f), position); - glm::mat4 view_glm = translation * rotation; - glm::mat4 view_glm_inv = glm::inverse(view_glm); - return view_glm_inv; -} - -glm::mat4 XrComponent::GetViewMatrixForCurrentView() const +XrPosef XrComponent::GetPoseForCurrentView() const { PPX_ASSERT_MSG((mCurrentViewIndex < mViews.size()), "Invalid view index!"); - return GetViewMatrix(mCurrentViewIndex); -} - -glm::mat4 XrComponent::GetProjectionMatrixForCurrentViewAndSetFrustumPlanes(float nearZ, float farZ) -{ - return GetProjectionMatrixForViewAndSetFrustumPlanes(mCurrentViewIndex, nearZ, farZ); + return mViews[mCurrentViewIndex].pose; } -glm::mat4 XrComponent::GetProjectionMatrixForViewAndSetFrustumPlanes(uint32_t viewIndex, float nearZ, float farZ) +void XrComponent::SetFrustumPlanes(float nearZ, float farZ) { - PPX_ASSERT_MSG((mCurrentViewIndex < mViews.size()), "Invalid view index!"); - const XrView& view = mViews[viewIndex]; - const XrFovf& fov = view.fov; - // Save near and far plane values so that they can be referenced // in EndFrame(), as part of the depth layer info submission. // They can only be set once per frame. @@ -878,44 +854,9 @@ glm::mat4 XrComponent::GetProjectionMatrixForViewAndSetFrustumPlanes(uint32_t vi mNearPlaneForFrame = nearZ; mFarPlaneForFrame = farZ; - const float tan_left = tanf(fov.angleLeft); - const float tan_right = tanf(fov.angleRight); - const float tan_down = tanf(fov.angleDown); - const float tan_up = tanf(fov.angleUp); - - const float tan_width = tan_right - tan_left; - const float tan_height = (tan_up - tan_down); - - const float a00 = 2 / tan_width; - const float a11 = 2 / tan_height; - - const float a20 = (tan_right + tan_left) / tan_width; - const float a21 = (tan_up + tan_down) / tan_height; - const float a22 = -farZ / (farZ - nearZ); - - const float a32 = -(farZ * nearZ) / (farZ - nearZ); - - // clang-format off - const float mat[16] = { - a00, 0, 0, 0, - 0, a11, 0, 0, - a20, a21, a22, -1, - 0, 0, a32, 0, - }; - // clang-format on - - return glm::make_mat4(mat); -} - -glm::mat4 XrComponent::GetViewProjectionMatrix(uint32_t viewIndex, float nearZ, float farZ) -{ - return GetProjectionMatrixForViewAndSetFrustumPlanes(viewIndex, nearZ, farZ) * GetViewMatrix(viewIndex); -} - -XrPosef XrComponent::GetPoseForCurrentView() const -{ - PPX_ASSERT_MSG((mCurrentViewIndex < mViews.size()), "Invalid view index!"); - return mViews[mCurrentViewIndex].pose; + for (XrCamera& camera : mCameras) { + camera.SetFrustumPlanes(nearZ, farZ); + } } uint32_t XrComponent::GetDefaultViewMask() const