| /* |
| * Copyright (C) 2021 Igalia, S.L. |
| * |
| * This library is free software; you can redistribute it and/or |
| * modify it under the terms of the GNU Library General Public |
| * License as published by the Free Software Foundation; either |
| * version 2 of the License, or (at your option) any later version. |
| * |
| * This library is distributed in the hope that it will be useful, |
| * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| * Library General Public License for more details. |
| * |
| * You should have received a copy of the GNU Library General Public License |
| * aint with this library; see the file COPYING.LIB. If not, write to |
| * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
| * Boston, MA 02110-1301, USA. |
| */ |
| |
| #include "config.h" |
| #include "OpenXRInput.h" |
| |
| #if ENABLE(WEBXR) && USE(OPENXR) |
| #include "OpenXRInputSource.h" |
| |
| using namespace WebCore; |
| |
| namespace PlatformXR { |
| |
| std::unique_ptr<OpenXRInput> OpenXRInput::create(XrInstance instance, XrSession session, XrSpace space) |
| { |
| auto input = std::unique_ptr<OpenXRInput>(new OpenXRInput(instance, session, space)); |
| if (XR_FAILED(input->initialize())) |
| return nullptr; |
| return input; |
| } |
| |
| OpenXRInput::OpenXRInput(XrInstance instance, XrSession session, XrSpace space) |
| : m_instance(instance) |
| , m_session(session) |
| , m_localSpace(space) |
| { |
| } |
| |
| XrResult OpenXRInput::initialize() |
| { |
| std::array<XRHandedness, 2> hands { |
| XRHandedness::Left, XRHandedness::Right |
| }; |
| |
| for (auto handeness : hands) { |
| m_handleIndex++;; |
| if (auto inputSource = OpenXRInputSource::create(m_instance, m_session, handeness, m_handleIndex)) |
| m_inputSources.append(makeUniqueRefFromNonNullUniquePtr(WTFMove(inputSource))); |
| } |
| |
| OpenXRInputSource::SuggestedBindings bindings; |
| Vector<XrActionSet> actionSets; |
| for (auto& input : m_inputSources) { |
| input->suggestBindings(bindings); |
| actionSets.append(input->actionSet()); |
| } |
| |
| for (auto& binding : bindings) { |
| auto suggestedBinding = createStructure<XrInteractionProfileSuggestedBinding, XR_TYPE_INTERACTION_PROFILE_SUGGESTED_BINDING>(); |
| RETURN_RESULT_IF_FAILED(xrStringToPath(m_instance, binding.key, &suggestedBinding.interactionProfile), m_instance); |
| suggestedBinding.countSuggestedBindings = binding.value.size(); |
| suggestedBinding.suggestedBindings = binding.value.data(); |
| RETURN_RESULT_IF_FAILED(xrSuggestInteractionProfileBindings(m_instance, &suggestedBinding), m_instance); |
| } |
| |
| auto attachInfo = createStructure<XrSessionActionSetsAttachInfo, XR_TYPE_SESSION_ACTION_SETS_ATTACH_INFO>(); |
| attachInfo.countActionSets = actionSets.size(); |
| attachInfo.actionSets = actionSets.data(); |
| RETURN_RESULT_IF_FAILED(xrAttachSessionActionSets(m_session, &attachInfo), m_instance); |
| |
| return XR_SUCCESS; |
| } |
| |
| Vector<Device::FrameData::InputSource> OpenXRInput::collectInputSources(const XrFrameState& frameState) const |
| { |
| Vector<XrActiveActionSet> actionSets; |
| for (auto& input : m_inputSources) |
| actionSets.append(XrActiveActionSet { input->actionSet(), XR_NULL_PATH }); |
| |
| auto syncInfo = createStructure<XrActionsSyncInfo, XR_TYPE_ACTIONS_SYNC_INFO>(); |
| syncInfo.countActiveActionSets = actionSets.size(); |
| syncInfo.activeActionSets = actionSets.data(); |
| RETURN_IF_FAILED(xrSyncActions(m_session, &syncInfo), "xrSyncActions", m_instance, { }); |
| |
| Vector<Device::FrameData::InputSource> result; |
| for (auto& input : m_inputSources) { |
| if (auto data = input->getInputSource(m_localSpace, frameState)) |
| result.append(*data); |
| } |
| |
| return result; |
| } |
| |
| void OpenXRInput::updateInteractionProfile() |
| { |
| for (auto& input : m_inputSources) |
| input->updateInteractionProfile(); |
| } |
| |
| } // namespace PlatformXR |
| |
| #endif // ENABLE(WEBXR) && USE(OPENXR) |