8#include "evan/openxr/XrManageActions.hpp"
9#include "evan/openxr/XrDeviceBackend.hpp"
13 this->
getLogger().info() <<
"Initializing XrManageActions";
35evan::XrManageActions::~XrManageActions()
37 this->
getLogger().info() <<
"Destroying XrManageActions";
43std::vector<std::shared_ptr<utility::event::Event>>
46 this->
getLogger().debug() <<
"Polling actions from OpenXR runtime";
48 std::vector<std::shared_ptr<utility::event::Event>>
events;
65 _handsMotionActions->_rightHandEvent);
76 this->
getLogger().info() <<
"Creating main action set for XrManageActions";
79 std::strncpy(actionSetInfo.actionSetName,
"gameplay",
80 XR_MAX_ACTION_SET_NAME_SIZE);
81 std::strncpy(actionSetInfo.localizedActionSetName,
"Gameplay",
82 XR_MAX_LOCALIZED_ACTION_SET_NAME_SIZE);
83 actionSetInfo.priority = 0;
85 XrResult result = xrCreateActionSet(deviceBackend.
_XrInstance,
86 &actionSetInfo, &_actionSet);
87 if (result != XR_SUCCESS) {
88 this->getLogger().error() <<
"Failed to create action set: " << result;
91 this->getLogger().info()
92 <<
"Successfully created main action set for XrManageActions";
95void evan::XrManageActions::attachSessionActionSet(
96 XrDeviceBackend &deviceBackend)
98 this->getLogger().info() <<
"Attaching action set to OpenXR session";
100 XrSessionActionSetsAttachInfo attachInfo {
101 XR_TYPE_SESSION_ACTION_SETS_ATTACH_INFO
103 attachInfo.countActionSets = 1;
104 attachInfo.actionSets = &_actionSet;
107 xrAttachSessionActionSets(deviceBackend._session, &attachInfo);
108 if (result != XR_SUCCESS) {
109 this->getLogger().error() <<
"Failed to attach action sets: " << result;
112 this->getLogger().info()
113 <<
"Successfully attached action set to OpenXR session";
116void evan::XrManageActions::bindActionSets(XrDeviceBackend &deviceBackend)
118 this->getLogger().info()
119 <<
"Binding action sets to OpenXR interaction profile";
121 const auto &options = deviceBackend.getOpenXrOptions();
122 const auto &candidateProfiles = options.interactionProfileCandidates.empty()
124 : options.interactionProfileCandidates;
126 std::vector<XrActionSuggestedBinding> coreBindings {
127 { _handsMotionActions->_handAimAction,
129 "/user/hand/left/input/aim/pose") },
130 { _handsMotionActions->_handAimAction,
132 "/user/hand/right/input/aim/pose") },
134 { _handsMotionActions->_handGripAction,
136 "/user/hand/left/input/grip/pose") },
137 { _handsMotionActions->_handGripAction,
139 deviceBackend._XrInstance,
"/user/hand/right/input/grip/pose") },
141 { _manageButtonsActions->_buttonAAction->getAction(),
143 "/user/hand/right/input/a/click") },
144 { _manageButtonsActions->_buttonBAction->getAction(),
146 "/user/hand/right/input/b/click") },
147 { _manageButtonsActions->_buttonXAction->getAction(),
149 "/user/hand/left/input/x/click") },
150 { _manageButtonsActions->_buttonYAction->getAction(),
152 "/user/hand/left/input/y/click") },
154 { _manageThumbStickActions->_leftHandThumbStickActions->getAction(),
156 deviceBackend._XrInstance,
"/user/hand/left/input/thumbstick") },
157 { _manageThumbStickActions->_rightHandThumbStickActions->getAction(),
159 deviceBackend._XrInstance,
"/user/hand/right/input/thumbstick") },
166 const auto suggestForProfile =
168 const std::string &profilePath,
169 const std::vector<XrActionSuggestedBinding> &bindings) -> XrResult {
170 XrInteractionProfileSuggestedBinding suggestedBindings {
171 XR_TYPE_INTERACTION_PROFILE_SUGGESTED_BINDING
174 deviceBackend._XrInstance, profilePath);
175 suggestedBindings.countSuggestedBindings =
176 static_cast<uint32_t
>(bindings.size());
177 suggestedBindings.suggestedBindings = bindings.data();
178 return xrSuggestInteractionProfileBindings(deviceBackend._XrInstance,
182 for (
const auto &candidateProfile: candidateProfiles) {
183 std::vector<XrActionSuggestedBinding> bindings = coreBindings;
184 if (options.enableMenuSystemBindings) {
186 { _manageButtonsActions->_buttonMenuAction->getAction(),
188 deviceBackend._XrInstance,
189 "/user/hand/left/input/menu/click") });
191 { _manageButtonsActions->_buttonSystemAction->getAction(),
193 deviceBackend._XrInstance,
194 "/user/hand/right/input/system/click") });
197 XrResult result = suggestForProfile(candidateProfile, bindings);
198 if (result != XR_SUCCESS && options.enableMenuSystemBindings) {
199 this->getLogger().warning()
200 <<
"Failed to suggest bindings for profile " << candidateProfile
201 <<
" including menu/system, retrying without them: " << result;
202 result = suggestForProfile(candidateProfile, coreBindings);
204 if (result == XR_SUCCESS) {
205 this->getLogger().info()
206 <<
"Successfully suggested bindings for interaction profile: "
210 this->getLogger().warning()
211 <<
"Interaction profile rejected the suggested bindings: "
212 << candidateProfile <<
" (" << result <<
")";
215 this->getLogger().error()
216 <<
"Failed to suggest interaction profile bindings on any candidate "
static XrPath stringToPath(XrInstance instance, const std::string &pathString)
Converts a string to an OpenXR path.
static const std::vector< std::string > & getDefaultProfileCandidates()
Retrieves the default interaction profile candidates.
The XrDeviceBackend class is responsible for managing the OpenXR device backend, including instance c...
std::unique_ptr< XrHandsMotionActions > _handsMotionActions
Action manager for hand tracking actions.
std::unique_ptr< XrManageButtonsActions > _manageButtonsActions
Action manager for button actions.
XrManageActions(XrDeviceBackend &deviceBackend)
Initializes XrManageActions with OpenXR action management.
XrActionSet _actionSet
The primary OpenXR action set for the application.
std::unique_ptr< XrManageThumbStickActions > _manageThumbStickActions
Action manager for thumb stick analog inputs.
std::vector< std::shared_ptr< utility::event::Event > > pollActions(XrDeviceBackend &deviceBackend)
Polls for input events from the OpenXR runtime.
Small result wrapper used by helpers that must return both a status and a value (e....