| OLD | NEW |
| (Empty) | |
| 1 // Copyright 2017 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #include "device/vr/openvr/openvr_gamepad_data_fetcher.h" |
| 6 |
| 7 #include <memory> |
| 8 |
| 9 #include "base/logging.h" |
| 10 #include "base/strings/utf_string_conversions.h" |
| 11 #include "device/gamepad/public/cpp/gamepads.h" |
| 12 #include "third_party/openvr/src/headers/openvr.h" |
| 13 #include "ui/gfx/transform.h" |
| 14 #include "ui/gfx/transform_util.h" |
| 15 |
| 16 namespace device { |
| 17 |
| 18 namespace { |
| 19 |
| 20 void SetGamepadButton(Gamepad* pad, |
| 21 const vr::VRControllerState_t& controller_state, |
| 22 uint64_t supported_buttons, |
| 23 vr::EVRButtonId button_id) { |
| 24 uint64_t button_mask = vr::ButtonMaskFromId(button_id); |
| 25 if ((supported_buttons & button_mask) != 0) { |
| 26 bool button_pressed = (controller_state.ulButtonPressed & button_mask) != 0; |
| 27 bool button_touched = (controller_state.ulButtonTouched & button_mask) != 0; |
| 28 pad->buttons[pad->buttons_length].touched = button_touched; |
| 29 pad->buttons[pad->buttons_length].pressed = button_pressed; |
| 30 pad->buttons[pad->buttons_length].value = button_pressed ? 1.0 : 0.0; |
| 31 pad->buttons_length++; |
| 32 } |
| 33 } |
| 34 |
| 35 } // namespace |
| 36 |
| 37 OpenVRGamepadDataFetcher::Factory::Factory(unsigned int display_id, |
| 38 vr::IVRSystem* vr) |
| 39 : display_id_(display_id), vr_system_(vr) { |
| 40 DVLOG(1) << __FUNCTION__ << "=" << this; |
| 41 } |
| 42 |
| 43 OpenVRGamepadDataFetcher::Factory::~Factory() { |
| 44 DVLOG(1) << __FUNCTION__ << "=" << this; |
| 45 } |
| 46 |
| 47 std::unique_ptr<GamepadDataFetcher> |
| 48 OpenVRGamepadDataFetcher::Factory::CreateDataFetcher() { |
| 49 return base::MakeUnique<OpenVRGamepadDataFetcher>(display_id_, vr_system_); |
| 50 } |
| 51 |
| 52 GamepadSource OpenVRGamepadDataFetcher::Factory::source() { |
| 53 return GAMEPAD_SOURCE_OPENVR; |
| 54 } |
| 55 |
| 56 OpenVRGamepadDataFetcher::OpenVRGamepadDataFetcher(unsigned int display_id, |
| 57 vr::IVRSystem* vr) |
| 58 : display_id_(display_id), vr_system_(vr) { |
| 59 DVLOG(1) << __FUNCTION__ << "=" << this; |
| 60 } |
| 61 |
| 62 OpenVRGamepadDataFetcher::~OpenVRGamepadDataFetcher() { |
| 63 DVLOG(1) << __FUNCTION__ << "=" << this; |
| 64 } |
| 65 |
| 66 GamepadSource OpenVRGamepadDataFetcher::source() { |
| 67 return GAMEPAD_SOURCE_OPENVR; |
| 68 } |
| 69 |
| 70 void OpenVRGamepadDataFetcher::OnAddedToProvider() {} |
| 71 |
| 72 void OpenVRGamepadDataFetcher::GetGamepadData(bool devices_changed_hint) { |
| 73 if (!vr_system_) |
| 74 return; |
| 75 |
| 76 vr::TrackedDevicePose_t tracked_devices_poses[vr::k_unMaxTrackedDeviceCount]; |
| 77 vr_system_->GetDeviceToAbsoluteTrackingPose(vr::TrackingUniverseSeated, 0.0f, |
| 78 tracked_devices_poses, |
| 79 vr::k_unMaxTrackedDeviceCount); |
| 80 |
| 81 for (uint32_t i = 0; i < vr::k_unMaxTrackedDeviceCount; ++i) { |
| 82 if (vr_system_->GetTrackedDeviceClass(i) != |
| 83 vr::TrackedDeviceClass_Controller) |
| 84 continue; |
| 85 |
| 86 PadState* state = GetPadState(i); |
| 87 if (!state) |
| 88 continue; |
| 89 |
| 90 Gamepad& pad = state->data; |
| 91 |
| 92 vr::VRControllerState_t controller_state; |
| 93 if (vr_system_->GetControllerState(i, &controller_state, |
| 94 sizeof(controller_state))) { |
| 95 pad.timestamp = controller_state.unPacketNum; |
| 96 pad.connected = true; |
| 97 |
| 98 pad.pose.not_null = true; |
| 99 |
| 100 pad.pose.has_orientation = true; |
| 101 pad.pose.has_position = true; |
| 102 |
| 103 vr::TrackedPropertyError error = vr::TrackedProp_Success; |
| 104 char attached_device_id[vr::k_unMaxPropertyStringSize]; |
| 105 vr_system_->GetStringTrackedDeviceProperty( |
| 106 i, vr::Prop_AttachedDeviceId_String, attached_device_id, |
| 107 vr::k_unMaxPropertyStringSize, &error); |
| 108 |
| 109 if (error == vr::TrackedProp_Success) { |
| 110 swprintf(pad.id, Gamepad::kIdLengthCap, |
| 111 base::UTF8ToUTF16(attached_device_id).c_str()); |
| 112 } else { |
| 113 swprintf(pad.id, Gamepad::kIdLengthCap, L"OpenVR Controller"); |
| 114 } |
| 115 swprintf(pad.mapping, Gamepad::kMappingLengthCap, L""); |
| 116 |
| 117 pad.display_id = display_id_; |
| 118 |
| 119 vr::ETrackedControllerRole hand = |
| 120 vr_system_->GetControllerRoleForTrackedDeviceIndex(i); |
| 121 |
| 122 switch (hand) { |
| 123 case vr::TrackedControllerRole_Invalid: |
| 124 pad.hand = GamepadHand::kNone; |
| 125 break; |
| 126 case vr::TrackedControllerRole_LeftHand: |
| 127 pad.hand = GamepadHand::kLeft; |
| 128 break; |
| 129 case vr::TrackedControllerRole_RightHand: |
| 130 pad.hand = GamepadHand::kRight; |
| 131 break; |
| 132 } |
| 133 |
| 134 uint64_t supported_buttons = vr_system_->GetUint64TrackedDeviceProperty( |
| 135 i, vr::Prop_SupportedButtons_Uint64); |
| 136 |
| 137 pad.buttons_length = 0; |
| 138 pad.axes_length = 0; |
| 139 |
| 140 for (int j = 0; j < vr::k_unControllerStateAxisCount; ++j) { |
| 141 int32_t axis_type = vr_system_->GetInt32TrackedDeviceProperty( |
| 142 i, static_cast<vr::TrackedDeviceProperty>(vr::Prop_Axis0Type_Int32 + |
| 143 j)); |
| 144 switch (axis_type) { |
| 145 case vr::k_eControllerAxis_Joystick: |
| 146 case vr::k_eControllerAxis_TrackPad: |
| 147 pad.axes[pad.axes_length++] = controller_state.rAxis[j].x; |
| 148 pad.axes[pad.axes_length++] = controller_state.rAxis[j].y; |
| 149 |
| 150 SetGamepadButton( |
| 151 &pad, controller_state, supported_buttons, |
| 152 static_cast<vr::EVRButtonId>(vr::k_EButton_Axis0 + j)); |
| 153 |
| 154 break; |
| 155 case vr::k_eControllerAxis_Trigger: |
| 156 pad.buttons[pad.buttons_length].value = controller_state.rAxis[j].x; |
| 157 |
| 158 uint64_t button_mask = vr::ButtonMaskFromId( |
| 159 static_cast<vr::EVRButtonId>(vr::k_EButton_Axis0 + j)); |
| 160 if ((supported_buttons & button_mask) != 0) { |
| 161 pad.buttons[pad.buttons_length].pressed = |
| 162 (controller_state.ulButtonPressed & button_mask) != 0; |
| 163 } |
| 164 |
| 165 pad.buttons_length++; |
| 166 break; |
| 167 } |
| 168 } |
| 169 |
| 170 SetGamepadButton(&pad, controller_state, supported_buttons, |
| 171 vr::k_EButton_A); |
| 172 SetGamepadButton(&pad, controller_state, supported_buttons, |
| 173 vr::k_EButton_Grip); |
| 174 SetGamepadButton(&pad, controller_state, supported_buttons, |
| 175 vr::k_EButton_ApplicationMenu); |
| 176 SetGamepadButton(&pad, controller_state, supported_buttons, |
| 177 vr::k_EButton_DPad_Left); |
| 178 SetGamepadButton(&pad, controller_state, supported_buttons, |
| 179 vr::k_EButton_DPad_Up); |
| 180 SetGamepadButton(&pad, controller_state, supported_buttons, |
| 181 vr::k_EButton_DPad_Right); |
| 182 SetGamepadButton(&pad, controller_state, supported_buttons, |
| 183 vr::k_EButton_DPad_Down); |
| 184 } |
| 185 |
| 186 const vr::TrackedDevicePose_t& pose = tracked_devices_poses[i]; |
| 187 if (pose.bPoseIsValid) { |
| 188 const vr::HmdMatrix34_t& mat = pose.mDeviceToAbsoluteTracking; |
| 189 gfx::Transform transform( |
| 190 mat.m[0][0], mat.m[0][1], mat.m[0][2], mat.m[0][3], mat.m[1][0], |
| 191 mat.m[1][1], mat.m[1][2], mat.m[1][3], mat.m[2][0], mat.m[2][1], |
| 192 mat.m[2][2], mat.m[2][3], 0, 0, 0, 1); |
| 193 |
| 194 gfx::DecomposedTransform decomposed_transform; |
| 195 gfx::DecomposeTransform(&decomposed_transform, transform); |
| 196 |
| 197 pad.pose.orientation.not_null = true; |
| 198 pad.pose.orientation.x = decomposed_transform.quaternion[0]; |
| 199 pad.pose.orientation.y = decomposed_transform.quaternion[1]; |
| 200 pad.pose.orientation.z = decomposed_transform.quaternion[2]; |
| 201 pad.pose.orientation.w = decomposed_transform.quaternion[3]; |
| 202 |
| 203 pad.pose.position.not_null = true; |
| 204 pad.pose.position.x = decomposed_transform.translate[0]; |
| 205 pad.pose.position.y = decomposed_transform.translate[1]; |
| 206 pad.pose.position.z = decomposed_transform.translate[2]; |
| 207 |
| 208 pad.pose.angular_velocity.not_null = true; |
| 209 pad.pose.angular_velocity.x = pose.vAngularVelocity.v[0]; |
| 210 pad.pose.angular_velocity.y = pose.vAngularVelocity.v[1]; |
| 211 pad.pose.angular_velocity.z = pose.vAngularVelocity.v[2]; |
| 212 |
| 213 pad.pose.linear_velocity.not_null = true; |
| 214 pad.pose.linear_velocity.x = pose.vVelocity.v[0]; |
| 215 pad.pose.linear_velocity.y = pose.vVelocity.v[1]; |
| 216 pad.pose.linear_velocity.z = pose.vVelocity.v[2]; |
| 217 } else { |
| 218 pad.pose.orientation.not_null = false; |
| 219 pad.pose.position.not_null = false; |
| 220 pad.pose.angular_velocity.not_null = false; |
| 221 pad.pose.linear_velocity.not_null = false; |
| 222 } |
| 223 } |
| 224 } |
| 225 |
| 226 void OpenVRGamepadDataFetcher::PauseHint(bool paused) {} |
| 227 |
| 228 } // namespace device |
| OLD | NEW |