| 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::UpdateTouchInfo() { |
| 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 = |
| 144 | 137 gvr::GvrApi::GetTimePointNow().monotonic_system_time_nanos; |
| 145 UpdateGestureFromTouchInfo(); | |
| 146 } | 138 } |
| 147 | 139 |
| 148 void VrController::Initialize(gvr_context* gvr_context) { | 140 void VrController::Initialize(gvr_context* gvr_context) { |
| 149 CHECK(gvr_context != nullptr) << "invalid gvr_context"; | 141 CHECK(gvr_context != nullptr) << "invalid gvr_context"; |
| 150 controller_api_.reset(new gvr::ControllerApi); | 142 controller_api_.reset(new gvr::ControllerApi); |
| 151 int32_t options = gvr::ControllerApi::DefaultOptions(); | 143 int32_t options = gvr::ControllerApi::DefaultOptions(); |
| 152 | 144 |
| 153 // Enable non-default options, if you need them: | 145 // Enable non-default options, if you need them: |
| 154 // options |= GVR_CONTROLLER_ENABLE_GYRO; | 146 // options |= GVR_CONTROLLER_ENABLE_GYRO; |
| 155 CHECK(controller_api_->Init(options, gvr_context)); | 147 CHECK(controller_api_->Init(options, gvr_context)); |
| 156 controller_api_->Resume(); | 148 controller_api_->Resume(); |
| 157 } | 149 } |
| 158 | 150 |
| 159 VrGesture VrController::DetectGesture() { | 151 std::unique_ptr<VrGesture> VrController::DetectGesture() { |
| 160 if (controller_state_.GetConnectionState() == gvr::kControllerConnected) { | 152 std::unique_ptr<VrGesture> gesture(new VrGesture()); |
| 161 gvr::Vec2f position; | 153 if (controller_state_.GetConnectionState() != gvr::kControllerConnected) { |
| 162 position.x = TouchPosX(); | 154 return gesture; |
| 163 position.y = TouchPosY(); | 155 } |
| 164 Update(IsTouchUp(), IsTouchDown(), IsTouching(), position, | 156 UpdateTouchInfo(); |
| 165 gvr::GvrApi::GetTimePointNow().monotonic_system_time_nanos); | 157 UpdateGestureFromTouchInfo(gesture.get()); |
| 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 | 158 |
| 199 if (IsButtonDown(gvr::kControllerButtonClick)) { | 159 if (gesture->type == WebInputEvent::GestureScrollBegin || |
| 200 return VrGesture( | 160 gesture->type == WebInputEvent::GestureScrollUpdate || |
| 201 kDefaultGestureButtonsChange, | 161 gesture->type == WebInputEvent::GestureScrollEnd) { |
| 202 gvr::GvrApi::GetTimePointNow().monotonic_system_time_nanos, | 162 return 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 } | 163 } |
| 211 return VrGesture(); | 164 |
| 165 if (IsButtonDown(gvr::kControllerButtonClick)) { |
| 166 gesture->type = WebInputEvent::GestureTap; |
| 167 gesture->details.buttons.down = 1; |
| 168 gesture->details.buttons.up = 0; |
| 169 gesture->details.buttons.pos.x = 0; |
| 170 gesture->details.buttons.pos.y = 0; |
| 171 return gesture; |
| 172 } |
| 173 |
| 174 return gesture; |
| 212 } | 175 } |
| 213 | 176 |
| 214 void VrController::UpdateGestureFromTouchInfo() { | 177 void VrController::UpdateGestureFromTouchInfo(VrGesture* gesture) { |
| 215 // Clear the gesture list. | 178 gesture->start_time = |
| 216 gesture_list_.clear(); | 179 gvr::GvrApi::GetTimePointNow().monotonic_system_time_nanos; |
| 217 | 180 gesture->end_time = |
| 181 gvr::GvrApi::GetTimePointNow().monotonic_system_time_nanos; |
| 218 switch (state_) { | 182 switch (state_) { |
| 219 // User has not put finger on touch pad. | 183 // User has not put finger on touch pad. |
| 220 case WAITING: | 184 case WAITING: |
| 221 HandleWaitingState(); | 185 HandleWaitingState(); |
| 222 break; | 186 break; |
| 223 // User has not started a gesture (by moving out of slop). | 187 // User has not started a gesture (by moving out of slop). |
| 224 case TOUCHING: | 188 case TOUCHING: |
| 225 HandleDetectingState(); | 189 HandleDetectingState(gesture); |
| 226 break; | 190 break; |
| 227 // User is scrolling on touchpad | 191 // User is scrolling on touchpad |
| 228 case SCROLLING: | 192 case SCROLLING: |
| 229 HandleScrollingState(); | 193 HandleScrollingState(gesture); |
| 230 break; | 194 break; |
| 231 default: | 195 default: |
| 232 LOG(ERROR) << "Wrong gesture detector state: " << state_; | 196 LOG(ERROR) << "Wrong gesture detector state: " << state_; |
| 233 break; | 197 break; |
| 234 } | 198 } |
| 235 } | 199 } |
| 236 | 200 |
| 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() { | 201 void VrController::HandleWaitingState() { |
| 262 // User puts finger on touch pad (or when the touch down for current gesture | 202 // User puts finger on touch pad (or when the touch down for current gesture |
| 263 // is missed, initiate gesture from current touch point). | 203 // is missed, initiate gesture from current touch point). |
| 264 if (touch_info_->touch_down || touch_info_->is_touching) { | 204 if (touch_info_->touch_down || touch_info_->is_touching) { |
| 265 // update initial touchpoint | 205 // update initial touchpoint |
| 266 *init_touch_point_ = touch_info_->touch_point; | 206 *init_touch_point_ = touch_info_->touch_point; |
| 267 // update current touchpoint | 207 // update current touchpoint |
| 268 *cur_touch_point_ = touch_info_->touch_point; | 208 *cur_touch_point_ = touch_info_->touch_point; |
| 269 state_ = TOUCHING; | 209 state_ = TOUCHING; |
| 270 } | 210 } |
| 271 } | 211 } |
| 272 | 212 |
| 273 void VrController::HandleDetectingState() { | 213 void VrController::HandleDetectingState(VrGesture* gesture) { |
| 274 // User lifts up finger from touch pad. | 214 // User lifts up finger from touch pad. |
| 275 if (touch_info_->touch_up || !(touch_info_->is_touching)) { | 215 if (touch_info_->touch_up || !(touch_info_->is_touching)) { |
| 276 Reset(); | 216 Reset(); |
| 277 return; | 217 return; |
| 278 } | 218 } |
| 279 | 219 |
| 280 // Touch position is changed and the touch point moves outside of slop. | 220 // Touch position is changed and the touch point moves outside of slop. |
| 281 if (UpdateCurrentTouchpoint() && touch_info_->is_touching && | 221 if (UpdateCurrentTouchpoint() && touch_info_->is_touching && |
| 282 !InSlop(touch_info_->touch_point.position)) { | 222 !InSlop(touch_info_->touch_point.position)) { |
| 283 state_ = SCROLLING; | 223 state_ = SCROLLING; |
| 284 VrGesture gesture; | 224 gesture->type = WebInputEvent::GestureScrollBegin; |
| 285 gesture.type = WebInputEvent::GestureScrollBegin; | 225 UpdateGesture(gesture); |
| 286 UpdateGesture(&gesture); | 226 gesture->details.scroll.delta.x = |
| 287 gesture_list_.push_back(gesture); | 227 gesture->displacement.x * kDisplacementScaleFactor; |
| 228 gesture->details.scroll.delta.y = |
| 229 gesture->displacement.y * kDisplacementScaleFactor; |
| 230 gesture->details.scroll.stop_fling = 0; |
| 288 } | 231 } |
| 289 } | 232 } |
| 290 | 233 |
| 291 void VrController::HandleScrollingState() { | 234 void VrController::HandleScrollingState(VrGesture* gesture) { |
| 292 // Update current touch point. | 235 // Update current touch point. |
| 293 bool touch_position_changed = UpdateCurrentTouchpoint(); | 236 bool touch_position_changed = UpdateCurrentTouchpoint(); |
| 294 if (touch_info_->touch_up || !(touch_info_->is_touching)) { // gesture ends | 237 if (touch_info_->touch_up || !(touch_info_->is_touching)) { |
| 295 VrGesture scroll_end; | 238 // Gesture ends. |
| 296 scroll_end.type = WebInputEvent::GestureScrollEnd; | 239 gesture->type = WebInputEvent::GestureScrollEnd; |
| 297 UpdateGesture(&scroll_end); | 240 UpdateGesture(gesture); |
| 298 gesture_list_.push_back(scroll_end); | 241 gesture->details.scroll.delta.x = 0; |
| 299 | 242 gesture->details.scroll.delta.y = 0; |
| 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) { |
| 302 // a change in touch position. | 246 // User continues scrolling and there is a change in touch position. |
| 303 VrGesture scroll_update; | 247 gesture->type = WebInputEvent::GestureScrollUpdate; |
| 304 scroll_update.type = WebInputEvent::GestureScrollUpdate; | 248 UpdateGesture(gesture); |
| 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; |
| 307 } | 254 } |
| 308 } | 255 } |
| 309 | 256 |
| 310 bool VrController::InSlop(const gvr::Vec2f touch_position) { | 257 bool VrController::InSlop(const gvr::Vec2f touch_position) { |
| 311 return (std::abs(touch_position.x - init_touch_point_->position.x) < | 258 return (std::abs(touch_position.x - init_touch_point_->position.x) < |
| 312 kSlopHorizontal) && | 259 kSlopHorizontal) && |
| 313 (std::abs(touch_position.y - init_touch_point_->position.y) < | 260 (std::abs(touch_position.y - init_touch_point_->position.y) < |
| 314 kSlopVertical); | 261 kSlopVertical); |
| 315 } | 262 } |
| 316 | 263 |
| (...skipping 25 matching lines...) Expand all Loading... |
| 342 prev_touch_point_.swap(cur_touch_point_); | 289 prev_touch_point_.swap(cur_touch_point_); |
| 343 *cur_touch_point_ = touch_info_->touch_point; | 290 *cur_touch_point_ = touch_info_->touch_point; |
| 344 | 291 |
| 345 return true; | 292 return true; |
| 346 } | 293 } |
| 347 } | 294 } |
| 348 return false; | 295 return false; |
| 349 } | 296 } |
| 350 | 297 |
| 351 } // namespace vr_shell | 298 } // namespace vr_shell |
| OLD | NEW |