1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4  * License, v. 2.0. If a copy of the MPL was not distributed with this
5  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 
7 #include "OpenVRControllerMapper.h"
8 #include "mozilla/StaticPrefs_dom.h"
9 
10 #include "VRSession.h"
11 
12 namespace mozilla::gfx {
13 
OpenVRControllerMapper()14 OpenVRControllerMapper::OpenVRControllerMapper()
15     : mNumButtons(0), mNumAxes(0) {}
16 
GetButtonValueFromAction(VRControllerState & aControllerState,const ControllerAction & aPressAction,const ControllerAction & aTouchAction)17 void OpenVRControllerMapper::GetButtonValueFromAction(
18     VRControllerState& aControllerState, const ControllerAction& aPressAction,
19     const ControllerAction& aTouchAction) {
20   vr::InputDigitalActionData_t actionData = {};
21   bool bPressed = false;
22   bool bTouched = false;
23   uint64_t mask = 0;
24 
25   if (aPressAction.handle &&
26       vr::VRInput()->GetDigitalActionData(
27           aPressAction.handle, &actionData, sizeof(actionData),
28           vr::k_ulInvalidInputValueHandle) == vr::VRInputError_None &&
29       actionData.bActive) {
30     bPressed = actionData.bState;
31     mask = (1ULL << mNumButtons);
32     aControllerState.triggerValue[mNumButtons] = bPressed ? 1.0 : 0.0f;
33     if (bPressed) {
34       aControllerState.buttonPressed |= mask;
35     } else {
36       aControllerState.buttonPressed &= ~mask;
37     }
38     if (aTouchAction.handle &&
39         vr::VRInput()->GetDigitalActionData(
40             aTouchAction.handle, &actionData, sizeof(actionData),
41             vr::k_ulInvalidInputValueHandle) == vr::VRInputError_None) {
42       bTouched = actionData.bActive && actionData.bState;
43       mask = (1ULL << mNumButtons);
44       if (bTouched) {
45         aControllerState.buttonTouched |= mask;
46       } else {
47         aControllerState.buttonTouched &= ~mask;
48       }
49     }
50     ++mNumButtons;
51   }
52 }
53 
GetTriggerValueFromAction(VRControllerState & aControllerState,const ControllerAction & aAction)54 void OpenVRControllerMapper::GetTriggerValueFromAction(
55     VRControllerState& aControllerState, const ControllerAction& aAction) {
56   vr::InputAnalogActionData_t analogData = {};
57   const float triggerThreshold =
58       StaticPrefs::dom_vr_controller_trigger_threshold();
59 
60   if (aAction.handle &&
61       vr::VRInput()->GetAnalogActionData(
62           aAction.handle, &analogData, sizeof(analogData),
63           vr::k_ulInvalidInputValueHandle) == vr::VRInputError_None &&
64       analogData.bActive) {
65     VRSession::UpdateTrigger(aControllerState, mNumButtons, analogData.x,
66                              triggerThreshold);
67     ++mNumButtons;
68   }
69 }
70 
GetAxisValueFromAction(VRControllerState & aControllerState,const ControllerAction & aAction,bool aInvertAxis)71 void OpenVRControllerMapper::GetAxisValueFromAction(
72     VRControllerState& aControllerState, const ControllerAction& aAction,
73     bool aInvertAxis) {
74   vr::InputAnalogActionData_t analogData = {};
75   const float yAxisInvert = (aInvertAxis) ? -1.0f : 1.0f;
76 
77   if (aAction.handle &&
78       vr::VRInput()->GetAnalogActionData(
79           aAction.handle, &analogData, sizeof(analogData),
80           vr::k_ulInvalidInputValueHandle) == vr::VRInputError_None &&
81       analogData.bActive) {
82     aControllerState.axisValue[mNumAxes] = analogData.x;
83     ++mNumAxes;
84     aControllerState.axisValue[mNumAxes] = analogData.y * yAxisInvert;
85     ++mNumAxes;
86   }
87 }
88 
89 }  // namespace mozilla::gfx