Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(293)

Side by Side Diff: device/vr/openvr/openvr_gamepad_data_fetcher.cc

Issue 2825203004: Added support for OpenVR controllers (Closed)
Patch Set: Handle power cycle of controllers Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « device/vr/openvr/openvr_gamepad_data_fetcher.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(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 : display_id_(display_id) {
39 DVLOG(1) << __FUNCTION__ << "=" << this;
40 }
41
42 OpenVRGamepadDataFetcher::Factory::~Factory() {
43 DVLOG(1) << __FUNCTION__ << "=" << this;
44 }
45
46 std::unique_ptr<GamepadDataFetcher>
47 OpenVRGamepadDataFetcher::Factory::CreateDataFetcher() {
48 return base::MakeUnique<OpenVRGamepadDataFetcher>(display_id_);
49 }
50
51 GamepadSource OpenVRGamepadDataFetcher::Factory::source() {
52 return GAMEPAD_SOURCE_OPENVR;
53 }
54
55 OpenVRGamepadDataFetcher::OpenVRGamepadDataFetcher(unsigned int display_id)
56 : display_id_(display_id), vr_system_(nullptr) {
57 DVLOG(1) << __FUNCTION__ << "=" << this;
58 }
59
60 OpenVRGamepadDataFetcher::~OpenVRGamepadDataFetcher() {
61 DVLOG(1) << __FUNCTION__ << "=" << this;
62 }
63
64 GamepadSource OpenVRGamepadDataFetcher::source() {
65 return GAMEPAD_SOURCE_OPENVR;
66 }
67
68 void OpenVRGamepadDataFetcher::OnAddedToProvider() {
69 vr::EVRInitError init_error = vr::VRInitError_None;
70 vr_system_ =
71 vr::VR_Init(&init_error, vr::EVRApplicationType::VRApplication_Scene);
billorr 2017/04/19 17:27:37 Is vr_init safe to call multiple times? I can't f
72
73 if (init_error != vr::VRInitError_None) {
74 LOG(ERROR) << vr::VR_GetVRInitErrorAsEnglishDescription(init_error);
75 vr_system_ = nullptr;
76 return;
77 }
78 }
79
80 void OpenVRGamepadDataFetcher::GetGamepadData(bool devices_changed_hint) {
81 if (!vr_system_)
82 return;
83
84 vr::TrackedDevicePose_t tracked_devices_poses[vr::k_unMaxTrackedDeviceCount];
85 vr_system_->GetDeviceToAbsoluteTrackingPose(vr::TrackingUniverseStanding,
86 0.0f, tracked_devices_poses,
87 vr::k_unMaxTrackedDeviceCount);
88
89 for (uint32_t i = 0; i < vr::k_unMaxTrackedDeviceCount; ++i) {
90 if (vr_system_->GetTrackedDeviceClass(i) !=
91 vr::TrackedDeviceClass_Controller)
92 continue;
93
94 PadState* state = GetPadState(i);
95 if (!state)
96 continue;
97
98 Gamepad& pad = state->data;
99
100 vr::VRControllerState_t controller_state;
101 if (vr_system_->GetControllerState(i, &controller_state,
102 sizeof(controller_state))) {
103 pad.timestamp = controller_state.unPacketNum;
104 pad.connected = true;
105
106 pad.pose.not_null = true;
107
108 pad.pose.has_orientation = true;
109 pad.pose.has_position = true;
110
111 vr::TrackedPropertyError error = vr::TrackedProp_Success;
112 char attached_device_id[vr::k_unMaxPropertyStringSize];
113 vr_system_->GetStringTrackedDeviceProperty(
114 i, vr::Prop_AttachedDeviceId_String, attached_device_id,
115 vr::k_unMaxPropertyStringSize, &error);
116
117 if (error == vr::TrackedProp_Success) {
118 swprintf(pad.id, Gamepad::kIdLengthCap,
119 base::UTF8ToUTF16(attached_device_id).c_str());
120 } else {
121 swprintf(pad.id, Gamepad::kIdLengthCap, L"OpenVR Controller");
122 }
123 swprintf(pad.mapping, Gamepad::kMappingLengthCap, L"");
124
125 pad.display_id = display_id_;
126
127 vr::ETrackedControllerRole hand =
128 vr_system_->GetControllerRoleForTrackedDeviceIndex(i);
129
130 switch (hand) {
131 case vr::TrackedControllerRole_Invalid:
132 pad.hand = GamepadHand::kNone;
133 break;
134 case vr::TrackedControllerRole_LeftHand:
135 pad.hand = GamepadHand::kLeft;
136 break;
137 case vr::TrackedControllerRole_RightHand:
138 pad.hand = GamepadHand::kRight;
139 break;
140 }
141
142 uint64_t supported_buttons = vr_system_->GetUint64TrackedDeviceProperty(
143 i, vr::Prop_SupportedButtons_Uint64);
144
145 pad.buttons_length = 0;
146 pad.axes_length = 0;
147
148 for (int j = 0; j < vr::k_unControllerStateAxisCount; ++j) {
149 int32_t axis_type = vr_system_->GetInt32TrackedDeviceProperty(
150 i, static_cast<vr::TrackedDeviceProperty>(vr::Prop_Axis0Type_Int32 +
151 j));
152 switch (axis_type) {
153 case vr::k_eControllerAxis_Joystick:
154 case vr::k_eControllerAxis_TrackPad:
155 pad.axes[pad.axes_length++] = controller_state.rAxis[j].x;
156 pad.axes[pad.axes_length++] = controller_state.rAxis[j].y;
157
158 SetGamepadButton(
159 &pad, controller_state, supported_buttons,
160 static_cast<vr::EVRButtonId>(vr::k_EButton_Axis0 + j));
161
162 break;
163 case vr::k_eControllerAxis_Trigger:
164 pad.buttons[pad.buttons_length].value = controller_state.rAxis[j].x;
165
166 uint64_t button_mask = vr::ButtonMaskFromId(
167 static_cast<vr::EVRButtonId>(vr::k_EButton_Axis0 + j));
168 if ((supported_buttons & button_mask) != 0) {
169 pad.buttons[pad.buttons_length].pressed =
170 (controller_state.ulButtonPressed & button_mask) != 0;
171 }
172
173 pad.buttons_length++;
174 break;
175 }
176 }
177
178 SetGamepadButton(&pad, controller_state, supported_buttons,
179 vr::k_EButton_A);
180 SetGamepadButton(&pad, controller_state, supported_buttons,
181 vr::k_EButton_Grip);
182 SetGamepadButton(&pad, controller_state, supported_buttons,
183 vr::k_EButton_ApplicationMenu);
184 SetGamepadButton(&pad, controller_state, supported_buttons,
185 vr::k_EButton_DPad_Left);
186 SetGamepadButton(&pad, controller_state, supported_buttons,
187 vr::k_EButton_DPad_Up);
188 SetGamepadButton(&pad, controller_state, supported_buttons,
189 vr::k_EButton_DPad_Right);
190 SetGamepadButton(&pad, controller_state, supported_buttons,
191 vr::k_EButton_DPad_Down);
192 }
193
194 const vr::TrackedDevicePose_t& pose = tracked_devices_poses[i];
195 if (pose.bPoseIsValid) {
196 const vr::HmdMatrix34_t& mat = pose.mDeviceToAbsoluteTracking;
197 gfx::Transform transform(
198 mat.m[0][0], mat.m[0][1], mat.m[0][2], mat.m[0][3], mat.m[1][0],
199 mat.m[1][1], mat.m[1][2], mat.m[1][3], mat.m[2][0], mat.m[2][1],
200 mat.m[2][2], mat.m[2][3], 0, 0, 0, 1);
201
202 gfx::DecomposedTransform decomposed_transform;
203 gfx::DecomposeTransform(&decomposed_transform, transform);
204
205 pad.pose.orientation.not_null = true;
206 pad.pose.orientation.x = decomposed_transform.quaternion[0];
207 pad.pose.orientation.y = decomposed_transform.quaternion[1];
208 pad.pose.orientation.z = decomposed_transform.quaternion[2];
209 pad.pose.orientation.w = decomposed_transform.quaternion[3];
210
211 pad.pose.position.not_null = true;
212 pad.pose.position.x = decomposed_transform.translate[0];
213 pad.pose.position.y = decomposed_transform.translate[1];
214 pad.pose.position.z = decomposed_transform.translate[2];
215
216 pad.pose.angular_velocity.not_null = true;
217 pad.pose.angular_velocity.x = pose.vAngularVelocity.v[0];
218 pad.pose.angular_velocity.y = pose.vAngularVelocity.v[1];
219 pad.pose.angular_velocity.z = pose.vAngularVelocity.v[2];
220
221 pad.pose.linear_velocity.not_null = true;
222 pad.pose.linear_velocity.x = pose.vVelocity.v[0];
223 pad.pose.linear_velocity.y = pose.vVelocity.v[1];
224 pad.pose.linear_velocity.z = pose.vVelocity.v[2];
225 } else {
226 pad.pose.orientation.not_null = false;
227 pad.pose.position.not_null = false;
228 pad.pose.angular_velocity.not_null = false;
229 pad.pose.linear_velocity.not_null = false;
230 }
231 }
232 }
233
234 void OpenVRGamepadDataFetcher::PauseHint(bool paused) {}
235
236 } // namespace device
OLDNEW
« no previous file with comments | « device/vr/openvr/openvr_gamepad_data_fetcher.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698