diff --git a/src/headset/openvr_headset.hpp b/src/headset/openvr_headset.hpp index f6fdd1168afd7937d33fde6e44ef6dc069b7aac2..b54930212ceb27e30cec0bc94fb94e2af7201887 100644 --- a/src/headset/openvr_headset.hpp +++ b/src/headset/openvr_headset.hpp @@ -59,19 +59,6 @@ private: private: vr::IVRSystem* system = nullptr; - glm::uvec2 resolution; - glm::vec3 stage_position = glm::vec3(0.0f); - glm::mat4 view_matrix; - glm::mat4 head_matrix; - std::array<glm::mat4, 2> head_to_eye_matrices; - std::array<glm::mat4, 2> projection_matrices; - std::array<glm::mat4, 2> controller_matrices; - - std::array<bool, 2> controller_attached; - std::array<glm::mat4, 2> controller_transforms; - std::array<glm::vec2, 2> controller_thumbsticks; - std::array<bool, BUTTON_MAX_COUNT> controller_buttons; - vr::TrackedDevicePose_t head_pose; vr::VRActionSetHandle_t controller_action_set; std::array<vr::VRActionHandle_t, 2> controller_transform_handles; @@ -81,10 +68,23 @@ private: std::array<lava::image::ptr, 2> framebuffers; lava::image::ptr framebuffer_array; + std::vector<std::string> instance_extensions; + std::vector<std::string> device_extensions; + float near_plane = 0.1f; float far_plane = 1000.0f; float movement_speed = 1.0f; - std::vector<std::string> instance_extensions; - std::vector<std::string> device_extensions; + glm::uvec2 resolution; + glm::vec3 stage_position = glm::vec3(0.0f); + glm::mat4 view_matrix; + glm::mat4 head_matrix; + std::array<glm::mat4, 2> head_to_eye_matrices; + std::array<glm::mat4, 2> projection_matrices; + std::array<glm::mat4, 2> controller_matrices; + + std::array<bool, 2> controller_attached; + std::array<glm::mat4, 2> controller_transforms; + std::array<glm::vec2, 2> controller_thumbsticks; + std::array<bool, BUTTON_MAX_COUNT> controller_buttons; }; \ No newline at end of file diff --git a/src/headset/openxr_headset.cpp b/src/headset/openxr_headset.cpp index 0b94906b457a395def2490096f4b8da7d903d6ed..f9f58ed5520fd317dc32f169f535fd329a12f1b6 100644 --- a/src/headset/openxr_headset.cpp +++ b/src/headset/openxr_headset.cpp @@ -13,6 +13,13 @@ PFN_xrGetVulkanGraphicsDeviceKHR xrGetVulkanGraphicsDeviceKHR = nullptr; OpenXRHeadset::OpenXRHeadset() { memset(&this->swapchain_indices, 0, sizeof(this->swapchain_indices)); + + this->controller_button_actions.fill(XR_NULL_HANDLE); + this->controller_thumbsticks_actions.fill(XR_NULL_HANDLE); + this->controller_transform_actions.fill(XR_NULL_HANDLE); + + this->controller_attached.fill(false); + this->controller_buttons.fill(false); } bool OpenXRHeadset::on_setup_instance(lava::frame_config& config) @@ -264,11 +271,17 @@ bool OpenXRHeadset::on_create() return false; } + if (!this->create_actions()) + { + return false; + } + return true; } void OpenXRHeadset::on_destroy() { + this->destroy_actions(); this->destroy_framebuffers(); this->destroy_swapchains(); @@ -296,6 +309,13 @@ bool OpenXRHeadset::on_update(lava::delta delta_time) return false; } + if(!this->update_actions()) + { + return false; + } + + this->update_stage(delta_time); + if (this->active) { if (!this->begin_frame()) @@ -589,6 +609,219 @@ void OpenXRHeadset::destroy_swapchains() this->swapchains.clear(); } +bool OpenXRHeadset::create_actions() +{ + XrActionSetCreateInfo action_set_info; + action_set_info.type = XR_TYPE_ACTION_SET_CREATE_INFO; + action_set_info.next = nullptr; + strncpy(action_set_info.actionSetName, "controller_actions", XR_MAX_ACTION_SET_NAME_SIZE); + strncpy(action_set_info.localizedActionSetName, "Controller Actions", XR_MAX_LOCALIZED_ACTION_SET_NAME_SIZE); + action_set_info.priority = 0; + + if (xrCreateActionSet(this->instance, &action_set_info, &this->action_set) != XR_SUCCESS) + { + lava::log()->error("OpenXR: Can't create action set!"); + + return false; + } + + std::vector<std::string> action_names = + { + "button_a", + "button_b", + "button_x", + "button_y", + "trigger_left", + "trigger_right", + }; + + std::vector<std::string> action_localized_names = + { + "Button A", + "Button B", + "Button X", + "Button Y", + "Trigger Left", + "Trigger Right", + }; + + for (uint32_t index = 0; index < action_names.size(); index++) + { + XrActionCreateInfo button_info; + button_info.type = XR_TYPE_ACTION_CREATE_INFO; + button_info.next = nullptr; + strncpy(button_info.actionName, action_names[index].c_str(), XR_MAX_ACTION_NAME_SIZE); + button_info.actionType = XR_ACTION_TYPE_BOOLEAN_INPUT; + button_info.countSubactionPaths = 0; + button_info.subactionPaths = nullptr; + strncpy(button_info.localizedActionName, action_localized_names[index].c_str(), XR_MAX_LOCALIZED_ACTION_NAME_SIZE); + + if (xrCreateAction(this->action_set, &button_info, &this->controller_button_actions[index]) != XR_SUCCESS) + { + lava::log()->error("OpenXR: Can't create action: " + action_names[index]); + + return false; + } + } + + for (uint32_t index = 0; index < 2; index++) + { + std::string thumbstick_name = (index > 0) ? "thumbstick_right" : "thumbstick_left"; + std::string thumbstick_name_localized = (index > 0) ? "Thumbstick Right" : "Thumbstick Left"; + + XrActionCreateInfo thumbstick_info; + thumbstick_info.type = XR_TYPE_ACTION_CREATE_INFO; + thumbstick_info.next = nullptr; + strncpy(thumbstick_info.actionName, thumbstick_name.c_str(), XR_MAX_ACTION_NAME_SIZE); + thumbstick_info.actionType = XR_ACTION_TYPE_VECTOR2F_INPUT; + thumbstick_info.countSubactionPaths = 0; + thumbstick_info.subactionPaths = nullptr; + strncpy(thumbstick_info.localizedActionName, thumbstick_name_localized.c_str(), XR_MAX_LOCALIZED_ACTION_NAME_SIZE); + + if (xrCreateAction(this->action_set, &thumbstick_info, &this->controller_thumbsticks_actions[index]) != XR_SUCCESS) + { + lava::log()->error("OpenXR: Can't create action: " + thumbstick_name); + + return false; + } + + std::string transform_name = (index > 0) ? "transform_right" : "transform_left"; + std::string transform_name_localized = (index > 0) ? "Transform Right" : "Transform Left"; + + XrActionCreateInfo transform_info; + transform_info.type = XR_TYPE_ACTION_CREATE_INFO; + transform_info.next = nullptr; + strncpy(transform_info.actionName, transform_name.c_str(), XR_MAX_ACTION_NAME_SIZE); + transform_info.actionType = XR_ACTION_TYPE_VECTOR2F_INPUT; + transform_info.countSubactionPaths = 0; + transform_info.subactionPaths = nullptr; + strncpy(transform_info.localizedActionName, transform_name_localized.c_str(), XR_MAX_LOCALIZED_ACTION_NAME_SIZE); + + if (xrCreateAction(this->action_set, &transform_info, &this->controller_transform_actions[index]) != XR_SUCCESS) + { + lava::log()->error("OpenXR: Can't create action: " + transform_name); + + return false; + } + } + + std::vector<XrPath> paths; + std::vector<std::string> path_strings = + { + "/user/hand/right/input/a/click", + "/user/hand/right/input/b/click", + "/user/hand/left/input/x/click", + "/user/hand/left/input/y/click", + "/user/hand/left/input/trigger/click", + "/user/hand/right/input/trigger/click", + "/user/hand/left/input/thumbstick", + "/user/hand/right/input/thumbstick", + "/user/hand/left/input/aim/pose", + "/user/hand/right/input/aim/pose", + "/interaction_profiles/htc/vive_focus3_controller" + }; + + for (uint32_t index = 0; index < path_strings.size(); index++) + { + XrPath path = XR_NULL_PATH; + + if (xrStringToPath(this->instance, path_strings[index].c_str(), &path) != XR_SUCCESS) + { + lava::log()->error("OpenXR: Can't create path for string: " + path_strings[index]); + + return false; + } + } + + std::vector<XrAction> actions = + { + this->controller_thumbsticks_actions[0], + this->controller_thumbsticks_actions[1], + this->controller_thumbsticks_actions[2], + this->controller_thumbsticks_actions[3], + this->controller_thumbsticks_actions[4], + this->controller_thumbsticks_actions[5], + this->controller_thumbsticks_actions[0], + this->controller_thumbsticks_actions[1], + this->controller_transform_actions[0], + this->controller_transform_actions[1] + }; + + std::vector<XrActionSuggestedBinding> bindings; + bindings.resize(actions.size()); + + for (uint32_t index = 0; index < this->controller_button_actions.size(); index++) + { + bindings[index].action = actions[index]; + bindings[index].binding = paths[index]; + } + + XrInteractionProfileSuggestedBinding suggested_bindings; + suggested_bindings.type = XR_TYPE_INTERACTION_PROFILE_SUGGESTED_BINDING; + suggested_bindings.next = nullptr; + suggested_bindings.interactionProfile = paths.back(); + suggested_bindings.countSuggestedBindings = bindings.size(); + suggested_bindings.suggestedBindings = bindings.data(); + + if (xrSuggestInteractionProfileBindings(this->instance, &suggested_bindings) != XR_SUCCESS) + { + lava::log()->error("OpenXR: Can't set suggested bindings"); + + return false; + } + + XrSessionActionSetsAttachInfo attach_info; + attach_info.type = XR_TYPE_SESSION_ACTION_SETS_ATTACH_INFO; + attach_info.next = nullptr; + attach_info.countActionSets = 1; + attach_info.actionSets = &this->action_set; + + if (xrAttachSessionActionSets(this->session, &attach_info) != XR_SUCCESS) + { + lava::log()->error("OpenXR: Can't attach action set to session!"); + + return false; + } + + return true; +} + +void OpenXRHeadset::destroy_actions() +{ + for (XrAction& action : this->controller_button_actions) + { + if (action != XR_NULL_HANDLE) + { + xrDestroyAction(action); + action = XR_NULL_HANDLE; + } + } + + for (XrAction& action : this->controller_transform_actions) + { + if (action != XR_NULL_HANDLE) + { + xrDestroyAction(action); + action = XR_NULL_HANDLE; + } + } + + for (XrAction& action : this->controller_thumbsticks_actions) + { + if (action != XR_NULL_HANDLE) + { + xrDestroyAction(action); + action = XR_NULL_HANDLE; + } + } + + if (this->action_set != XR_NULL_HANDLE) + { + xrDestroyActionSet(this->action_set); + this->action_set = XR_NULL_HANDLE; + } +} + bool OpenXRHeadset::poll_events() { while (true) @@ -676,6 +909,28 @@ bool OpenXRHeadset::process_event(const XrEventDataBuffer& event) return true; } +bool OpenXRHeadset::update_actions() +{ + for (uint32_t index = 0; index < this->controller_button_actions.size(); index++) + { + + } + + + xrGetActionStateBoolean(); + + xrGetActionStateVector2f(); + + xrGetActionStatePose(); + + return true; +} + +void OpenXRHeadset::update_stage(lava::delta delta_time) +{ + +} + bool OpenXRHeadset::begin_frame() { XrFrameWaitInfo wait_info; diff --git a/src/headset/openxr_headset.hpp b/src/headset/openxr_headset.hpp index 659a4cf40c852411cc68871fc6ebbfa2a570736b..19e10eaedfc669c1b833ee207204eceae5231207 100644 --- a/src/headset/openxr_headset.hpp +++ b/src/headset/openxr_headset.hpp @@ -50,9 +50,15 @@ private: bool create_swapchains(); void destroy_swapchains(); + bool create_actions(); + void destroy_actions(); + bool poll_events(); bool process_event(const XrEventDataBuffer& event); + bool update_actions(); + void update_stage(lava::delta delta_time); + bool begin_frame(); bool update_views(); bool acquire_image(FrameId frame_id); @@ -77,6 +83,11 @@ private: std::vector<XrSwapchain> swapchains; std::vector<XrView> views; + XrActionSet action_set = XR_NULL_HANDLE; + std::array<XrAction, 2> controller_transform_actions; + std::array<XrAction, 2> controller_thumbsticks_actions; + std::array<XrAction, BUTTON_MAX_COUNT> controller_button_actions; + std::array<uint32_t, 2> swapchain_indices; std::array<std::vector<VkImage>, 2> swapchain_images; std::array<lava::image::ptr, 2> framebuffers; @@ -92,8 +103,15 @@ private: float far_plane = 1000.0f; glm::uvec2 resolution; + glm::vec3 stage_position = glm::vec3(0.0f); glm::mat4 view_matrix; + glm::mat4 head_matrix; std::array<glm::mat4, 2> head_to_eye_matrices; std::array<glm::mat4, 2> projection_matrices; std::array<glm::mat4, 2> controller_matrices; + + std::array<bool, 2> controller_attached; + std::array<glm::mat4, 2> controller_transforms; + std::array<glm::vec2, 2> controller_thumbsticks; + std::array<bool, BUTTON_MAX_COUNT> controller_buttons; }; \ No newline at end of file