Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

OpenVR and OpenXR symmetric and other projection matrix options #196

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
57cb0e2
naive symmetric projection for OpenVR
mrbelowski Feb 14, 2024
5f337cf
WIP OpenXR symmetric projection
mrbelowski Feb 14, 2024
d75110e
first cut of OpenXR symmetric projection matrices - desparately needs…
mrbelowski Feb 14, 2024
d79e5e7
tweak a calculation the looked upside down (but is hard to tell with …
mrbelowski Feb 14, 2024
5738af3
WIP
mrbelowski Feb 15, 2024
8cb868a
more WIP - reworked bounds and FOV calculations to reduce mess; still…
mrbelowski Feb 15, 2024
4d77aa5
wip
mrbelowski Feb 15, 2024
5edfab1
wip
mrbelowski Feb 15, 2024
9d61170
corrected various calculations; added mirrored projections
mrbelowski Feb 15, 2024
57a8b38
add option to grow the render target to accommodate projection croppi…
mrbelowski Feb 15, 2024
6dc0f16
revert commit hash change
mrbelowski Feb 15, 2024
91d8f35
fix memory leak; first part of changes following PR comments
mrbelowski Feb 15, 2024
4a099e2
more tidy up - cache the results of the eye projection and texture bo…
mrbelowski Feb 16, 2024
27a133c
Merge branch 'master' into open-vr-and-openxr-symmetric-projection
mrbelowski Feb 16, 2024
6a837bc
Merge branch 'master' into open-vr-and-openxr-symmetric-projection
mrbelowski Feb 16, 2024
95961a3
only get the eye positions once per framework sync
mrbelowski Feb 16, 2024
ea3a631
Merge branch 'open-vr-and-openxr-symmetric-projection' of github.com:…
mrbelowski Feb 17, 2024
bfd2c5a
ensure changes to near clipping plane trigger eye matrix derivation; …
mrbelowski Feb 17, 2024
ed11d9a
Merge branch 'master' into open-vr-and-openxr-symmetric-projection
mrbelowski Feb 20, 2024
540b526
fix incorrect vertical matched for openVR
mrbelowski Feb 20, 2024
9bbc6f6
Merge branch 'master' into open-vr-and-openxr-symmetric-projection
mrbelowski Feb 25, 2024
ec952e0
Merge branch 'master' into open-vr-and-openxr-symmetric-projection
praydog Mar 20, 2024
1a320c6
Remove unused CommitHash.hpp
praydog Mar 20, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions src/mods/VR.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2533,6 +2533,15 @@ void VR::on_draw_sidebar_entry(std::string_view name) {
m_compatibility_skip_pip->draw("Skip PostInitProperties");
m_sceneview_compatibility_mode->draw("SceneView Compatibility Mode");
m_extreme_compat_mode->draw("Extreme Compatibility Mode");

// changes to any of these options should trigger a regeneration of the eye projection matrices
const auto horizontal_projection_changed = m_horizontal_projection_override->draw("Horizontal Projection");
const auto vertical_projection_changed = m_vertical_projection_override->draw("Vertical Projection");
const auto scale_render = m_grow_rectangle_for_projection_cropping->draw("Scale Render Target");
const auto scale_render_changed = get_runtime()->is_modifying_eye_texture_scale != scale_render;
get_runtime()->is_modifying_eye_texture_scale = scale_render;
get_runtime()->should_recalculate_eye_projections = horizontal_projection_changed || vertical_projection_changed || scale_render_changed;

ImGui::TreePop();
}

Expand Down
52 changes: 48 additions & 4 deletions src/mods/VR.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,18 @@ class VR : public Mod {
GESTURE_HEAD_RIGHT,
};

enum HORIZONTAL_PROJECTION_OVERRIDE : int32_t {
HORIZONTAL_DEFAULT,
HORIZONTAL_SYMMETRIC,
HORIZONTAL_MIRROR
};

enum VERTICAL_PROJECTION_OVERRIDE : int32_t {
VERTICAL_DEFAULT,
VERTICAL_SYMMETRIC,
VERTICAL_MATCHED
};

static const inline std::string s_action_pose = "/actions/default/in/Pose";
static const inline std::string s_action_grip_pose = "/actions/default/in/GripPose";
static const inline std::string s_action_trigger = "/actions/default/in/Trigger";
Expand Down Expand Up @@ -102,6 +114,11 @@ class VR : public Mod {
};
}

// texture bounds to tell OpenVR which parts of the submitted texture to render (default - use the whole texture).
// Will be modified to accommodate forced symmetrical eye projection
vr::VRTextureBounds_t m_right_bounds{0.0f, 0.0f, 1.0f, 1.0f};
vr::VRTextureBounds_t m_left_bounds{0.0f, 0.0f, 1.0f, 1.0f};

void on_config_load(const utility::Config& cfg, bool set_defaults) override;
void on_config_save(utility::Config& cfg) override;

Expand Down Expand Up @@ -577,6 +594,18 @@ class VR : public Mod {
return m_extreme_compat_mode->value();
}

auto get_horizontal_projection_override() const {
return m_horizontal_projection_override->value();
}

auto get_vertical_projection_override() const {
return m_vertical_projection_override->value();
}

bool should_grow_rectangle_for_projection_cropping() const {
return m_grow_rectangle_for_projection_cropping->value();
}

vrmod::D3D11Component& d3d11() {
return m_d3d11;
}
Expand Down Expand Up @@ -671,9 +700,6 @@ class VR : public Mod {
std::vector<int32_t> m_controllers{};
std::unordered_set<int32_t> m_controllers_set{};

vr::VRTextureBounds_t m_right_bounds{ 0.0f, 0.0f, 1.0f, 1.0f };
vr::VRTextureBounds_t m_left_bounds{ 0.0f, 0.0f, 1.0f, 1.0f };

glm::vec3 m_overlay_rotation{-1.550f, 0.0f, -1.330f};
glm::vec4 m_overlay_position{0.0f, 0.06f, -0.07f, 1.0f};

Expand Down Expand Up @@ -797,6 +823,18 @@ class VR : public Mod {
"Gesture (Head) + Right Joystick",
};

static const inline std::vector<std::string> s_horizontal_projection_override_names{
"Raw / default",
"Symmetrical",
"Mirrored",
};

static const inline std::vector<std::string> s_vertical_projection_override_names{
"Raw / default",
"Symmetrical",
"Matched",
};

const ModCombo::Ptr m_rendering_method{ ModCombo::create(generate_name("RenderingMethod"), s_rendering_method_names) };
const ModCombo::Ptr m_synced_afr_method{ ModCombo::create(generate_name("SyncedSequentialMethod"), s_synced_afr_method_names, 1) };
const ModToggle::Ptr m_extreme_compat_mode{ ModToggle::create(generate_name("ExtremeCompatibilityMode"), false, true) };
Expand All @@ -814,6 +852,9 @@ class VR : public Mod {
const ModToggle::Ptr m_2d_screen_mode{ ModToggle::create(generate_name("2DScreenMode"), false) };
const ModToggle::Ptr m_roomscale_movement{ ModToggle::create(generate_name("RoomscaleMovement"), false) };
const ModToggle::Ptr m_swap_controllers{ ModToggle::create(generate_name("SwapControllerInputs"), false) };
const ModCombo::Ptr m_horizontal_projection_override{ModCombo::create(generate_name("HorizontalProjectionOverride"), s_horizontal_projection_override_names)};
const ModCombo::Ptr m_vertical_projection_override{ModCombo::create(generate_name("VerticalProjectionOverride"), s_vertical_projection_override_names)};
const ModToggle::Ptr m_grow_rectangle_for_projection_cropping{ModToggle::create(generate_name("GrowRectangleForProjectionCropping"), false)};

// Snap turn settings and globals
void gamepad_snapturn(XINPUT_STATE& state);
Expand Down Expand Up @@ -952,6 +993,9 @@ class VR : public Mod {
*m_2d_screen_mode,
*m_roomscale_movement,
*m_swap_controllers,
*m_horizontal_projection_override,
*m_vertical_projection_override,
*m_grow_rectangle_for_projection_cropping,
*m_snapturn,
*m_snapturn_joystick_deadzone,
*m_snapturn_angle,
Expand Down Expand Up @@ -1134,4 +1178,4 @@ class VR : public Mod {
friend class vrmod::D3D12Component;
friend class vrmod::OverlayComponent;
friend class FFakeStereoRenderingHook;
};
};
15 changes: 9 additions & 6 deletions src/mods/vr/D3D11Component.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -559,8 +559,9 @@ vr::EVRCompositorError D3D11Component::on_frame(VR* vr) {
(void*)m_left_eye_tex.Get(), vr::TextureType_DirectX, vr::ColorSpace_Auto,
submit_pose
};

const auto e = vr::VRCompositor()->Submit(vr::Eye_Left, &left_eye, &vr->m_left_bounds, vr::EVRSubmitFlags::Submit_TextureWithPose);
const auto left_bounds = vr::VRTextureBounds_t{runtime->view_bounds[0][0], runtime->view_bounds[0][2],
runtime->view_bounds[0][1], runtime->view_bounds[0][3]};
const auto e = vr::VRCompositor()->Submit(vr::Eye_Left, &left_eye, &left_bounds, vr::EVRSubmitFlags::Submit_TextureWithPose);

if (e != vr::VRCompositorError_None) {
spdlog::error("[VR] VRCompositor failed to submit left eye: {}", (int)e);
Expand Down Expand Up @@ -710,8 +711,9 @@ vr::EVRCompositorError D3D11Component::on_frame(VR* vr) {
(void*)m_left_eye_tex.Get(), vr::TextureType_DirectX, vr::ColorSpace_Auto,
submit_pose
};

e = vr::VRCompositor()->Submit(vr::Eye_Left, &left_eye, &vr->m_left_bounds, vr::EVRSubmitFlags::Submit_TextureWithPose);
const auto left_bounds = vr::VRTextureBounds_t{runtime->view_bounds[0][0], runtime->view_bounds[0][2],
runtime->view_bounds[0][1], runtime->view_bounds[0][3]};
e = vr::VRCompositor()->Submit(vr::Eye_Left, &left_eye, &left_bounds, vr::EVRSubmitFlags::Submit_TextureWithPose);

if (e != vr::VRCompositorError_None) {
spdlog::error("[VR] VRCompositor failed to submit left eye: {}", (int)e);
Expand Down Expand Up @@ -760,8 +762,9 @@ vr::EVRCompositorError D3D11Component::on_frame(VR* vr) {
(void*)m_right_eye_tex.Get(), vr::TextureType_DirectX, vr::ColorSpace_Auto,
submit_pose
};

e = vr::VRCompositor()->Submit(vr::Eye_Right, &right_eye, &vr->m_right_bounds, vr::EVRSubmitFlags::Submit_TextureWithPose);
const auto right_bounds = vr::VRTextureBounds_t{runtime->view_bounds[1][0], runtime->view_bounds[1][2],
runtime->view_bounds[1][1], runtime->view_bounds[1][3]};
e = vr::VRCompositor()->Submit(vr::Eye_Right, &right_eye, &right_bounds, vr::EVRSubmitFlags::Submit_TextureWithPose);
runtime->frame_synced = false;

bool submitted = true;
Expand Down
15 changes: 9 additions & 6 deletions src/mods/vr/D3D12Component.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -398,8 +398,9 @@ vr::EVRCompositorError D3D12Component::on_frame(VR* vr) {
(void*)&left, vr::TextureType_DirectX12, vr::ColorSpace_Auto,
submit_pose
};

auto e = vr::VRCompositor()->Submit(vr::Eye_Left, &left_eye, &vr->m_left_bounds, vr::EVRSubmitFlags::Submit_TextureWithPose);
const auto left_bounds = vr::VRTextureBounds_t{runtime->view_bounds[0][0], runtime->view_bounds[0][2],
runtime->view_bounds[0][1], runtime->view_bounds[0][3]};
auto e = vr::VRCompositor()->Submit(vr::Eye_Left, &left_eye, &left_bounds, vr::EVRSubmitFlags::Submit_TextureWithPose);

if (e != vr::VRCompositorError_None) {
spdlog::error("[VR] VRCompositor failed to submit left eye: {}", (int)e);
Expand Down Expand Up @@ -496,8 +497,9 @@ vr::EVRCompositorError D3D12Component::on_frame(VR* vr) {
(void*)&left, vr::TextureType_DirectX12, vr::ColorSpace_Auto,
submit_pose
};

auto e = vr::VRCompositor()->Submit(vr::Eye_Left, &left_eye, &vr->m_left_bounds, vr::EVRSubmitFlags::Submit_TextureWithPose);
const auto left_bounds = vr::VRTextureBounds_t{runtime->view_bounds[0][0], runtime->view_bounds[0][2],
runtime->view_bounds[0][1], runtime->view_bounds[0][3]};
auto e = vr::VRCompositor()->Submit(vr::Eye_Left, &left_eye, &left_bounds, vr::EVRSubmitFlags::Submit_TextureWithPose);

if (e != vr::VRCompositorError_None) {
spdlog::error("[VR] VRCompositor failed to submit left eye: {}", (int)e);
Expand All @@ -521,8 +523,9 @@ vr::EVRCompositorError D3D12Component::on_frame(VR* vr) {
(void*)&right, vr::TextureType_DirectX12, vr::ColorSpace_Auto,
submit_pose
};

auto e = vr::VRCompositor()->Submit(vr::Eye_Right, &right_eye, &vr->m_right_bounds, vr::EVRSubmitFlags::Submit_TextureWithPose);
const auto right_bounds = vr::VRTextureBounds_t{runtime->view_bounds[1][0], runtime->view_bounds[1][2],
runtime->view_bounds[1][1], runtime->view_bounds[1][3]};
auto e = vr::VRCompositor()->Submit(vr::Eye_Right, &right_eye, &right_bounds, vr::EVRSubmitFlags::Submit_TextureWithPose);
runtime->frame_synced = false;

if (e != vr::VRCompositorError_None) {
Expand Down
6 changes: 6 additions & 0 deletions src/mods/vr/OverlayComponent.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -327,6 +327,8 @@ void OverlayComponent::update_slate_openvr() {

const auto is_d3d11 = g_framework->get_renderer_type() == Framework::RendererType::D3D11;

// TODO: do the sizing / scaling calculations below need to take into account non-standard VRTextureBounds_t
// when we force a symmetrical eye projection matrix?
vr::VRTextureBounds_t bounds{};
bounds.uMin = 0.0f;
bounds.uMax = 1.0f;
Expand Down Expand Up @@ -424,6 +426,8 @@ bool OverlayComponent::update_wrist_overlay_openvr() {
// so it doesn't become too intrusive during gameplay
const auto scale = m_closed_ui ? 0.25f : 1.0f;

// TODO: do the sizing / scaling calculations below need to take into account non-standard VRTextureBounds_t
// when we force a symmetrical eye projection matrix?
vr::VRTextureBounds_t bounds{};
bounds.uMin = last_window_pos.x / render_target_width ;
bounds.uMax = (last_window_pos.x + last_window_size.x) / render_target_width;
Expand Down Expand Up @@ -667,6 +671,8 @@ void OverlayComponent::update_overlay_openvr() {
vr::VROverlay()->ShowOverlay(m_overlay_handle);

// Show the entire texture
// TODO: do the sizing / scaling calculations below need to take into account non-standard VRTextureBounds_t
// when we force a symmetrical eye projection matrix?
vr::VRTextureBounds_t bounds{};
bounds.uMin = 0.0f;
bounds.uMax = 1.0f;
Expand Down
Loading