OLD | NEW |
---|---|
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/android/vr_shell/vr_controller.h" | 5 #include "chrome/browser/android/vr_shell/vr_controller.h" |
6 | 6 |
7 #include <android/log.h> | |
8 | |
9 #include <cmath> | 7 #include <cmath> |
10 | 8 |
11 #include "third_party/WebKit/public/web/WebInputEvent.h" | 9 #include "third_party/WebKit/public/web/WebInputEvent.h" |
12 | 10 |
13 using blink::WebInputEvent; | 11 using blink::WebInputEvent; |
14 | 12 |
15 namespace vr_shell { | 13 namespace vr_shell { |
16 | 14 |
17 namespace { | 15 namespace { |
18 | 16 |
19 const GestureScroll kDefaultGestureScroll = {{0, 0}, 0, {0, 0}}; | |
20 const GestureButtonsChange kDefaultGestureButtonsChange = {{0, 0}, 0, 0}; | |
21 const GestureAngularMove kDefaultGestureAngularMove = {{0, 0, 0}, 0}; | |
22 | |
23 constexpr float kDisplacementScaleFactor = 800.0f; | 17 constexpr float kDisplacementScaleFactor = 800.0f; |
24 | 18 |
25 // A slop represents a small rectangular region around the first touch point of | 19 // A slop represents a small rectangular region around the first touch point of |
26 // a gesture. | 20 // a gesture. |
27 // If the user does not move outside of the slop, no gesture is detected. | 21 // If the user does not move outside of the slop, no gesture is detected. |
28 // Gestures start to be detected when the user moves outside of the slop. | 22 // Gestures start to be detected when the user moves outside of the slop. |
29 // Vertical distance from the border to the center of slop. | 23 // Vertical distance from the border to the center of slop. |
30 constexpr float kSlopVertical = 0.165f; | 24 constexpr float kSlopVertical = 0.165f; |
31 | 25 |
32 // Horizontal distance from the border to the center of slop. | 26 // Horizontal distance from the border to the center of slop. |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
122 controller_state_.Update(*controller_api_); | 116 controller_state_.Update(*controller_api_); |
123 // Print new API status and connection state, if they changed. | 117 // Print new API status and connection state, if they changed. |
124 if (controller_state_.GetApiStatus() != old_status || | 118 if (controller_state_.GetApiStatus() != old_status || |
125 controller_state_.GetConnectionState() != old_connection_state) { | 119 controller_state_.GetConnectionState() != old_connection_state) { |
126 VLOG(1) << "Controller Connection status: " | 120 VLOG(1) << "Controller Connection status: " |
127 << gvr_controller_connection_state_to_string( | 121 << gvr_controller_connection_state_to_string( |
128 controller_state_.GetConnectionState()); | 122 controller_state_.GetConnectionState()); |
129 } | 123 } |
130 } | 124 } |
131 | 125 |
132 void VrController::Update(bool touch_up, | 126 void VrController::Update() { |
133 bool touch_down, | |
134 bool is_touching, | |
135 const gvr::Vec2f position, | |
136 int64_t timestamp) { | |
137 CHECK(touch_info_ != nullptr) << "touch_info_ not initialized properly."; | 127 CHECK(touch_info_ != nullptr) << "touch_info_ not initialized properly."; |
138 touch_info_->touch_up = touch_up; | 128 gvr::Vec2f position; |
139 touch_info_->touch_down = touch_down; | 129 position.x = TouchPosX(); |
140 touch_info_->is_touching = is_touching; | 130 position.y = TouchPosY(); |
131 touch_info_->touch_up = IsTouchUp(); | |
132 touch_info_->touch_down = IsTouchDown(); | |
133 touch_info_->is_touching = IsTouching(); | |
141 touch_info_->touch_point.position = position; | 134 touch_info_->touch_point.position = position; |
142 Vector::ClampTouchpadPosition(&touch_info_->touch_point.position); | 135 Vector::ClampTouchpadPosition(&touch_info_->touch_point.position); |
143 touch_info_->touch_point.timestamp = timestamp; | 136 touch_info_->touch_point.timestamp = |
137 gvr::GvrApi::GetTimePointNow().monotonic_system_time_nanos; | |
144 | 138 |
145 UpdateGestureFromTouchInfo(); | 139 UpdateGestureFromTouchInfo(); |
146 } | 140 } |
147 | 141 |
148 void VrController::Initialize(gvr_context* gvr_context) { | 142 void VrController::Initialize(gvr_context* gvr_context) { |
149 CHECK(gvr_context != nullptr) << "invalid gvr_context"; | 143 CHECK(gvr_context != nullptr) << "invalid gvr_context"; |
150 controller_api_.reset(new gvr::ControllerApi); | 144 controller_api_.reset(new gvr::ControllerApi); |
151 int32_t options = gvr::ControllerApi::DefaultOptions(); | 145 int32_t options = gvr::ControllerApi::DefaultOptions(); |
152 | 146 |
153 // Enable non-default options, if you need them: | 147 // Enable non-default options, if you need them: |
154 // options |= GVR_CONTROLLER_ENABLE_GYRO; | 148 // options |= GVR_CONTROLLER_ENABLE_GYRO; |
155 CHECK(controller_api_->Init(options, gvr_context)); | 149 CHECK(controller_api_->Init(options, gvr_context)); |
156 controller_api_->Resume(); | 150 controller_api_->Resume(); |
157 } | 151 } |
158 | 152 |
159 VrGesture VrController::DetectGesture() { | 153 std::unique_ptr<VrGesture> VrController::DetectGesture() { |
160 if (controller_state_.GetConnectionState() == gvr::kControllerConnected) { | 154 gesture_.reset(new VrGesture()); |
cjgrant
2016/10/03 14:27:34
Maybe here, or in a future change, we should cut o
mthiesse
2016/10/03 15:39:15
Done.
| |
161 gvr::Vec2f position; | 155 if (controller_state_.GetConnectionState() != gvr::kControllerConnected) { |
162 position.x = TouchPosX(); | 156 return std::move(gesture_); |
163 position.y = TouchPosY(); | 157 } |
164 Update(IsTouchUp(), IsTouchDown(), IsTouching(), position, | 158 Update(); |
165 gvr::GvrApi::GetTimePointNow().monotonic_system_time_nanos); | |
166 if (GetGestureListSize() > 0 && | |
167 (GetGesturePtr(0)->type == WebInputEvent::GestureScrollBegin || | |
168 GetGesturePtr(0)->type == WebInputEvent::GestureScrollUpdate || | |
169 GetGesturePtr(0)->type == WebInputEvent::GestureScrollEnd)) { | |
170 switch (GetGesturePtr(0)->type) { | |
171 case WebInputEvent::GestureScrollBegin: | |
172 return VrGesture( | |
173 kDefaultGestureScroll, | |
174 gvr::GvrApi::GetTimePointNow().monotonic_system_time_nanos, | |
175 gvr::GvrApi::GetTimePointNow().monotonic_system_time_nanos, | |
176 GetGesturePtr(0)->displacement.x * kDisplacementScaleFactor, | |
177 GetGesturePtr(0)->displacement.y * kDisplacementScaleFactor, | |
178 WebInputEvent::GestureScrollBegin, Orientation()); | |
179 case WebInputEvent::GestureScrollUpdate: | |
180 return VrGesture( | |
181 kDefaultGestureScroll, | |
182 gvr::GvrApi::GetTimePointNow().monotonic_system_time_nanos, | |
183 gvr::GvrApi::GetTimePointNow().monotonic_system_time_nanos, | |
184 GetGesturePtr(0)->displacement.x * kDisplacementScaleFactor, | |
185 GetGesturePtr(0)->displacement.y * kDisplacementScaleFactor, | |
186 WebInputEvent::GestureScrollUpdate, Orientation()); | |
187 case WebInputEvent::GestureScrollEnd: | |
188 return VrGesture( | |
189 kDefaultGestureScroll, | |
190 gvr::GvrApi::GetTimePointNow().monotonic_system_time_nanos, | |
191 gvr::GvrApi::GetTimePointNow().monotonic_system_time_nanos, 0, 0, | |
192 WebInputEvent::GestureScrollEnd, Orientation()); | |
193 default: | |
194 LOG(ERROR) << "Unknown Gesture"; | |
195 return VrGesture(); | |
196 } | |
197 } | |
198 | 159 |
199 if (IsButtonDown(gvr::kControllerButtonClick)) { | 160 if (gesture_.get()->type == WebInputEvent::GestureScrollBegin || |
200 return VrGesture( | 161 gesture_.get()->type == WebInputEvent::GestureScrollUpdate || |
201 kDefaultGestureButtonsChange, | 162 gesture_.get()->type == WebInputEvent::GestureScrollEnd) { |
202 gvr::GvrApi::GetTimePointNow().monotonic_system_time_nanos, | 163 return std::move(gesture_); |
203 gvr::GvrApi::GetTimePointNow().monotonic_system_time_nanos, 1, 0, | |
204 Orientation()); | |
205 } | |
206 return VrGesture(kDefaultGestureAngularMove, | |
207 gvr::GvrApi::GetTimePointNow().monotonic_system_time_nanos, | |
208 gvr::GvrApi::GetTimePointNow().monotonic_system_time_nanos, | |
209 Orientation()); | |
210 } | 164 } |
211 return VrGesture(); | 165 |
166 if (IsButtonDown(gvr::kControllerButtonClick)) { | |
167 gesture_->type = WebInputEvent::GestureTap; | |
168 gesture_->details.buttons.down = 1; | |
169 gesture_->details.buttons.up = 0; | |
170 gesture_->details.buttons.pos.x = 0; | |
171 gesture_->details.buttons.pos.y = 0; | |
172 return std::move(gesture_); | |
173 } | |
174 | |
175 return std::move(gesture_); | |
212 } | 176 } |
213 | 177 |
214 void VrController::UpdateGestureFromTouchInfo() { | 178 void VrController::UpdateGestureFromTouchInfo() { |
215 // Clear the gesture list. | 179 gesture_->start_time = |
216 gesture_list_.clear(); | 180 gvr::GvrApi::GetTimePointNow().monotonic_system_time_nanos; |
217 | 181 gesture_->end_time = |
182 gvr::GvrApi::GetTimePointNow().monotonic_system_time_nanos; | |
218 switch (state_) { | 183 switch (state_) { |
219 // User has not put finger on touch pad. | 184 // User has not put finger on touch pad. |
220 case WAITING: | 185 case WAITING: |
221 HandleWaitingState(); | 186 HandleWaitingState(); |
222 break; | 187 break; |
223 // User has not started a gesture (by moving out of slop). | 188 // User has not started a gesture (by moving out of slop). |
224 case TOUCHING: | 189 case TOUCHING: |
225 HandleDetectingState(); | 190 HandleDetectingState(); |
226 break; | 191 break; |
227 // User is scrolling on touchpad | 192 // User is scrolling on touchpad |
228 case SCROLLING: | 193 case SCROLLING: |
229 HandleScrollingState(); | 194 HandleScrollingState(); |
230 break; | 195 break; |
231 default: | 196 default: |
232 LOG(ERROR) << "Wrong gesture detector state: " << state_; | 197 LOG(ERROR) << "Wrong gesture detector state: " << state_; |
233 break; | 198 break; |
234 } | 199 } |
235 } | 200 } |
236 | 201 |
237 const VrGesture* VrController::GetGesturePtr(const size_t index) { | |
238 CHECK(index < gesture_list_.size()) << "The gesture index exceeds the" | |
239 "size of gesture list."; | |
240 return const_cast<VrGesture*>(&gesture_list_[index]); | |
241 } | |
242 | |
243 void VrController::Update(const gvr_controller_state* controller_state) { | |
244 // Update touch information. | |
245 CHECK(touch_info_ != nullptr) << "touch_info_ not initialized properly."; | |
246 touch_info_->touch_up = gvr_controller_state_get_touch_up(controller_state); | |
247 touch_info_->touch_down = | |
248 gvr_controller_state_get_touch_down(controller_state); | |
249 touch_info_->is_touching = gvr_controller_state_is_touching(controller_state); | |
250 touch_info_->touch_point.position.x = | |
251 gvr_controller_state_get_touch_pos(controller_state).x; | |
252 touch_info_->touch_point.position.y = | |
253 gvr_controller_state_get_touch_pos(controller_state).y; | |
254 Vector::ClampTouchpadPosition(&(touch_info_->touch_point.position)); | |
255 touch_info_->touch_point.timestamp = | |
256 gvr_controller_state_get_last_touch_timestamp(controller_state); | |
257 | |
258 UpdateGestureFromTouchInfo(); | |
259 } | |
260 | |
261 void VrController::HandleWaitingState() { | 202 void VrController::HandleWaitingState() { |
262 // User puts finger on touch pad (or when the touch down for current gesture | 203 // User puts finger on touch pad (or when the touch down for current gesture |
263 // is missed, initiate gesture from current touch point). | 204 // is missed, initiate gesture from current touch point). |
264 if (touch_info_->touch_down || touch_info_->is_touching) { | 205 if (touch_info_->touch_down || touch_info_->is_touching) { |
265 // update initial touchpoint | 206 // update initial touchpoint |
266 *init_touch_point_ = touch_info_->touch_point; | 207 *init_touch_point_ = touch_info_->touch_point; |
267 // update current touchpoint | 208 // update current touchpoint |
268 *cur_touch_point_ = touch_info_->touch_point; | 209 *cur_touch_point_ = touch_info_->touch_point; |
269 state_ = TOUCHING; | 210 state_ = TOUCHING; |
270 } | 211 } |
271 } | 212 } |
272 | 213 |
273 void VrController::HandleDetectingState() { | 214 void VrController::HandleDetectingState() { |
274 // User lifts up finger from touch pad. | 215 // User lifts up finger from touch pad. |
275 if (touch_info_->touch_up || !(touch_info_->is_touching)) { | 216 if (touch_info_->touch_up || !(touch_info_->is_touching)) { |
276 Reset(); | 217 Reset(); |
277 return; | 218 return; |
278 } | 219 } |
279 | 220 |
280 // Touch position is changed and the touch point moves outside of slop. | 221 // Touch position is changed and the touch point moves outside of slop. |
281 if (UpdateCurrentTouchpoint() && touch_info_->is_touching && | 222 if (UpdateCurrentTouchpoint() && touch_info_->is_touching && |
282 !InSlop(touch_info_->touch_point.position)) { | 223 !InSlop(touch_info_->touch_point.position)) { |
283 state_ = SCROLLING; | 224 state_ = SCROLLING; |
284 VrGesture gesture; | 225 gesture_->type = WebInputEvent::GestureScrollBegin; |
285 gesture.type = WebInputEvent::GestureScrollBegin; | 226 UpdateGesture(gesture_.get()); |
286 UpdateGesture(&gesture); | 227 gesture_->details.scroll.delta.x = |
287 gesture_list_.push_back(gesture); | 228 gesture_->displacement.x * kDisplacementScaleFactor; |
229 gesture_->details.scroll.delta.y = | |
230 gesture_->displacement.y * kDisplacementScaleFactor; | |
231 gesture_->details.scroll.stop_fling = 0; | |
288 } | 232 } |
289 } | 233 } |
290 | 234 |
291 void VrController::HandleScrollingState() { | 235 void VrController::HandleScrollingState() { |
292 // Update current touch point. | 236 // Update current touch point. |
293 bool touch_position_changed = UpdateCurrentTouchpoint(); | 237 bool touch_position_changed = UpdateCurrentTouchpoint(); |
294 if (touch_info_->touch_up || !(touch_info_->is_touching)) { // gesture ends | 238 if (touch_info_->touch_up || !(touch_info_->is_touching)) { // gesture ends |
bshe
2016/10/03 12:09:23
nit: move comments to a new line
mthiesse
2016/10/03 15:39:15
Done.
| |
295 VrGesture scroll_end; | 239 gesture_->type = WebInputEvent::GestureScrollEnd; |
296 scroll_end.type = WebInputEvent::GestureScrollEnd; | 240 UpdateGesture(gesture_.get()); |
297 UpdateGesture(&scroll_end); | 241 gesture_->details.scroll.delta.x = 0; |
298 gesture_list_.push_back(scroll_end); | 242 gesture_->details.scroll.delta.y = 0; |
299 | 243 gesture_->details.scroll.stop_fling = 0; |
300 Reset(); | 244 Reset(); |
301 } else if (touch_position_changed) { // User continues scrolling and there is | 245 } else if (touch_position_changed) { // User continues scrolling and there is |
bshe
2016/10/03 12:09:23
ditto
mthiesse
2016/10/03 15:39:15
Done.
| |
302 // a change in touch position. | 246 // a change in touch position. |
303 VrGesture scroll_update; | 247 gesture_->type = WebInputEvent::GestureScrollUpdate; |
304 scroll_update.type = WebInputEvent::GestureScrollUpdate; | 248 UpdateGesture(gesture_.get()); |
305 UpdateGesture(&scroll_update); | 249 gesture_->details.scroll.delta.x = |
306 gesture_list_.push_back(scroll_update); | 250 gesture_->displacement.x * kDisplacementScaleFactor; |
251 gesture_->details.scroll.delta.y = | |
252 gesture_->displacement.y * kDisplacementScaleFactor; | |
253 gesture_->details.scroll.stop_fling = 0; | |
254 UpdateGesture(gesture_.get()); | |
307 } | 255 } |
308 } | 256 } |
309 | 257 |
310 bool VrController::InSlop(const gvr::Vec2f touch_position) { | 258 bool VrController::InSlop(const gvr::Vec2f touch_position) { |
311 return (std::abs(touch_position.x - init_touch_point_->position.x) < | 259 return (std::abs(touch_position.x - init_touch_point_->position.x) < |
312 kSlopHorizontal) && | 260 kSlopHorizontal) && |
313 (std::abs(touch_position.y - init_touch_point_->position.y) < | 261 (std::abs(touch_position.y - init_touch_point_->position.y) < |
314 kSlopVertical); | 262 kSlopVertical); |
315 } | 263 } |
316 | 264 |
(...skipping 25 matching lines...) Expand all Loading... | |
342 prev_touch_point_.swap(cur_touch_point_); | 290 prev_touch_point_.swap(cur_touch_point_); |
343 *cur_touch_point_ = touch_info_->touch_point; | 291 *cur_touch_point_ = touch_info_->touch_point; |
344 | 292 |
345 return true; | 293 return true; |
346 } | 294 } |
347 } | 295 } |
348 return false; | 296 return false; |
349 } | 297 } |
350 | 298 |
351 } // namespace vr_shell | 299 } // namespace vr_shell |
OLD | NEW |