Chromium Code Reviews| 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_shell_gl.h" | 5 #include "chrome/browser/android/vr_shell/vr_shell_gl.h" |
| 6 | 6 |
| 7 #include <limits> | 7 #include <limits> |
| 8 #include <utility> | 8 #include <utility> |
| 9 | 9 |
| 10 #include "base/android/jni_android.h" | 10 #include "base/android/jni_android.h" |
| (...skipping 475 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 486 touch_pending_ = false; | 486 touch_pending_ = false; |
| 487 std::unique_ptr<WebGestureEvent> gesture(new WebGestureEvent( | 487 std::unique_ptr<WebGestureEvent> gesture(new WebGestureEvent( |
| 488 WebInputEvent::GestureTapDown, WebInputEvent::NoModifiers, | 488 WebInputEvent::GestureTapDown, WebInputEvent::NoModifiers, |
| 489 (base::TimeTicks::Now() - base::TimeTicks()).InSecondsF())); | 489 (base::TimeTicks::Now() - base::TimeTicks()).InSecondsF())); |
| 490 gesture->sourceDevice = blink::WebGestureDeviceTouchpad; | 490 gesture->sourceDevice = blink::WebGestureDeviceTouchpad; |
| 491 gesture->x = 0; | 491 gesture->x = 0; |
| 492 gesture->y = 0; | 492 gesture->y = 0; |
| 493 SendGesture(InputTarget::CONTENT, std::move(gesture)); | 493 SendGesture(InputTarget::CONTENT, std::move(gesture)); |
| 494 DVLOG(1) << __FUNCTION__ << ": sent CLICK gesture"; | 494 DVLOG(1) << __FUNCTION__ << ": sent CLICK gesture"; |
| 495 } | 495 } |
| 496 | |
| 497 return; | |
|
cjgrant
2017/03/23 21:24:47
I'm not sure why we were returning here.
mthiesse
2017/03/23 21:34:23
Fine to remove, as long as the check below stays.
| |
| 498 } | 496 } |
| 499 | 497 |
| 500 gvr::Vec3f ergo_neutral_pose; | 498 gvr::Vec3f ergo_neutral_pose; |
| 501 if (!controller_->IsConnected()) { | 499 if (!controller_->IsConnected()) { |
| 502 // No controller detected, set up a gaze cursor that tracks the | 500 // No controller detected, set up a gaze cursor that tracks the |
| 503 // forward direction. | 501 // forward direction. |
| 504 ergo_neutral_pose = {0.0f, 0.0f, -1.0f}; | 502 ergo_neutral_pose = {0.0f, 0.0f, -1.0f}; |
| 505 controller_quat_ = GetRotationFromZAxis(forward_vector); | 503 controller_quat_ = GetRotationFromZAxis(forward_vector); |
| 506 } else { | 504 } else { |
| 507 ergo_neutral_pose = {0.0f, -sin(kErgoAngleOffset), -cos(kErgoAngleOffset)}; | 505 ergo_neutral_pose = {0.0f, -sin(kErgoAngleOffset), -cos(kErgoAngleOffset)}; |
| 508 controller_quat_ = controller_->Orientation(); | 506 controller_quat_ = controller_->Orientation(); |
| 509 } | 507 } |
| 510 | 508 |
| 511 gvr::Mat4f mat = QuatToMatrix(controller_quat_); | 509 gvr::Mat4f mat = QuatToMatrix(controller_quat_); |
| 512 gvr::Vec3f controller_direction = MatrixVectorMul(mat, ergo_neutral_pose); | 510 gvr::Vec3f controller_direction = MatrixVectorMul(mat, ergo_neutral_pose); |
| 513 | 511 |
| 512 HandleControllerAppButtonActivity(controller_direction); | |
| 513 | |
| 514 if (ShouldDrawWebVr()) { | |
|
cjgrant
2017/03/23 21:24:47
On second thought, this is bad, and I'll revert th
mthiesse
2017/03/23 21:34:23
On third thought, don't revert this check.
cjgrant
2017/03/23 21:35:35
On third thought, lets keep this, as it moves the
| |
| 515 return; | |
| 516 } | |
| 517 | |
| 514 // If we place the reticle based on elements intersecting the controller beam, | 518 // If we place the reticle based on elements intersecting the controller beam, |
| 515 // we can end up with the reticle hiding behind elements, or jumping laterally | 519 // we can end up with the reticle hiding behind elements, or jumping laterally |
| 516 // in the field of view. This is physically correct, but hard to use. For | 520 // in the field of view. This is physically correct, but hard to use. For |
| 517 // usability, do the following instead: | 521 // usability, do the following instead: |
| 518 // | 522 // |
| 519 // - Project the controller laser onto a distance-limiting sphere. | 523 // - Project the controller laser onto a distance-limiting sphere. |
| 520 // - Create a vector between the eyes and the outer surface point. | 524 // - Create a vector between the eyes and the outer surface point. |
| 521 // - If any UI elements intersect this vector, and is within the bounding | 525 // - If any UI elements intersect this vector, and is within the bounding |
| 522 // sphere, choose the closest to the eyes, and place the reticle at the | 526 // sphere, choose the closest to the eyes, and place the reticle at the |
| 523 // intersection point. | 527 // intersection point. |
| 524 | 528 |
| 525 // Compute the distance from the eyes to the distance limiting sphere. Note | 529 // Compute the distance from the eyes to the distance limiting sphere. Note |
| 526 // that the sphere is centered at the controller, rather than the eye, for | 530 // that the sphere is centered at the controller, rather than the eye, for |
| 527 // simplicity. | 531 // simplicity. |
| 528 float distance = scene_->GetBackgroundDistance(); | 532 float distance = scene_->GetBackgroundDistance(); |
| 529 target_point_ = GetRayPoint(kHandPosition, controller_direction, distance); | 533 target_point_ = GetRayPoint(kHandPosition, controller_direction, distance); |
| 530 gvr::Vec3f eye_to_target = target_point_; | 534 gvr::Vec3f eye_to_target = target_point_; |
| 531 NormalizeVector(eye_to_target); | 535 NormalizeVector(eye_to_target); |
| 532 | 536 |
| 533 // Note that button up/down state is transient, so ButtonDownHappened only | |
|
cjgrant
2017/03/23 21:24:47
Broken out to a function for readability.
| |
| 534 // returns true for a single frame (and we're guaranteed not to miss it). | |
| 535 if (controller_->ButtonDownHappened( | |
| 536 gvr::ControllerButton::GVR_CONTROLLER_BUTTON_APP)) { | |
| 537 controller_start_direction_ = controller_direction; | |
| 538 } | |
| 539 if (controller_->ButtonUpHappened( | |
| 540 gvr::ControllerButton::GVR_CONTROLLER_BUTTON_APP)) { | |
| 541 // A gesture is a movement of the controller while holding the App button. | |
| 542 // If the angle of the movement is within a threshold, the action is | |
| 543 // considered a regular click | |
| 544 // TODO(asimjour1): We need to refactor the gesture recognition outside of | |
| 545 // VrShellGl. | |
| 546 UiInterface::Direction direction = UiInterface::NONE; | |
| 547 float gesture_xz_angle; | |
| 548 bool valid_angle = XZAngle(controller_start_direction_, | |
| 549 controller_direction, &gesture_xz_angle); | |
| 550 DCHECK(valid_angle); | |
| 551 if (fabs(gesture_xz_angle) > kMinAppButtonGestureAngleRad) { | |
| 552 direction = gesture_xz_angle < 0 ? UiInterface::LEFT : UiInterface::RIGHT; | |
| 553 main_thread_task_runner_->PostTask( | |
| 554 FROM_HERE, base::Bind(&VrShell::AppButtonGesturePerformed, | |
| 555 weak_vr_shell_, direction)); | |
| 556 } | |
| 557 if (direction == UiInterface::NONE) { | |
| 558 main_thread_task_runner_->PostTask( | |
| 559 FROM_HERE, base::Bind(&VrShell::AppButtonPressed, weak_vr_shell_)); | |
| 560 } | |
| 561 } | |
| 562 | |
| 563 // Determine which UI element (if any) intersects the line between the eyes | 537 // Determine which UI element (if any) intersects the line between the eyes |
| 564 // and the controller target position. | 538 // and the controller target position. |
| 565 float closest_element_distance = VectorLength(target_point_); | 539 float closest_element_distance = VectorLength(target_point_); |
| 566 target_element_ = nullptr; | 540 target_element_ = nullptr; |
| 567 float target_x; | 541 float target_x; |
| 568 float target_y; | 542 float target_y; |
| 569 | 543 |
| 570 for (const auto& plane : scene_->GetUiElements()) { | 544 for (const auto& plane : scene_->GetUiElements()) { |
| 571 if (!plane->IsHitTestable()) | 545 if (!plane->IsHitTestable()) |
| 572 continue; | 546 continue; |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 620 case Fill::SPRITE: | 594 case Fill::SPRITE: |
| 621 input_target = InputTarget::UI; | 595 input_target = InputTarget::UI; |
| 622 break; | 596 break; |
| 623 default: | 597 default: |
| 624 break; | 598 break; |
| 625 } | 599 } |
| 626 } | 600 } |
| 627 SendEventsToTarget(input_target, pixel_x, pixel_y); | 601 SendEventsToTarget(input_target, pixel_x, pixel_y); |
| 628 } | 602 } |
| 629 | 603 |
| 604 void VrShellGl::HandleControllerAppButtonActivity( | |
| 605 const gvr::Vec3f& controller_direction) { | |
| 606 // Note that button up/down state is transient, so ButtonDownHappened only | |
| 607 // returns true for a single frame (and we're guaranteed not to miss it). | |
| 608 if (controller_->ButtonDownHappened( | |
| 609 gvr::ControllerButton::GVR_CONTROLLER_BUTTON_APP)) { | |
| 610 controller_start_direction_ = controller_direction; | |
| 611 } | |
| 612 if (controller_->ButtonUpHappened( | |
| 613 gvr::ControllerButton::GVR_CONTROLLER_BUTTON_APP)) { | |
| 614 // A gesture is a movement of the controller while holding the App button. | |
| 615 // If the angle of the movement is within a threshold, the action is | |
| 616 // considered a regular click | |
| 617 // TODO(asimjour1): We need to refactor the gesture recognition outside of | |
| 618 // VrShellGl. | |
| 619 UiInterface::Direction direction = UiInterface::NONE; | |
| 620 float gesture_xz_angle; | |
| 621 if (XZAngle(controller_start_direction_, controller_direction, | |
| 622 &gesture_xz_angle)) { | |
| 623 if (fabs(gesture_xz_angle) > kMinAppButtonGestureAngleRad) { | |
| 624 direction = | |
| 625 gesture_xz_angle < 0 ? UiInterface::LEFT : UiInterface::RIGHT; | |
| 626 main_thread_task_runner_->PostTask( | |
| 627 FROM_HERE, base::Bind(&VrShell::AppButtonGesturePerformed, | |
| 628 weak_vr_shell_, direction)); | |
| 629 } | |
| 630 } | |
| 631 if (direction == UiInterface::NONE) { | |
| 632 main_thread_task_runner_->PostTask( | |
| 633 FROM_HERE, base::Bind(&VrShell::AppButtonPressed, weak_vr_shell_)); | |
| 634 } | |
| 635 } | |
| 636 } | |
| 637 | |
| 630 void VrShellGl::SendEventsToTarget(InputTarget input_target, | 638 void VrShellGl::SendEventsToTarget(InputTarget input_target, |
| 631 int pixel_x, | 639 int pixel_x, |
| 632 int pixel_y) { | 640 int pixel_y) { |
| 633 std::vector<std::unique_ptr<WebGestureEvent>> gesture_list = | 641 std::vector<std::unique_ptr<WebGestureEvent>> gesture_list = |
| 634 controller_->DetectGestures(); | 642 controller_->DetectGestures(); |
| 635 double timestamp = gesture_list.front()->timeStampSeconds(); | 643 double timestamp = gesture_list.front()->timeStampSeconds(); |
| 636 | 644 |
| 637 if (touch_pending_) { | 645 if (touch_pending_) { |
| 638 touch_pending_ = false; | 646 touch_pending_ = false; |
| 639 std::unique_ptr<WebGestureEvent> event(new WebGestureEvent( | 647 std::unique_ptr<WebGestureEvent> event(new WebGestureEvent( |
| (...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 810 // object_from_reference_matrix, we're not updating position_external. | 818 // object_from_reference_matrix, we're not updating position_external. |
| 811 // TODO: Not sure what object_from_reference_matrix is. The new api removed | 819 // TODO: Not sure what object_from_reference_matrix is. The new api removed |
| 812 // it. For now, removing it seems working fine. | 820 // it. For now, removing it seems working fine. |
| 813 gvr_api_->ApplyNeckModel(head_pose, 1.0f); | 821 gvr_api_->ApplyNeckModel(head_pose, 1.0f); |
| 814 } | 822 } |
| 815 | 823 |
| 816 // Update the render position of all UI elements (including desktop). | 824 // Update the render position of all UI elements (including desktop). |
| 817 scene_->UpdateTransforms(TimeInMicroseconds()); | 825 scene_->UpdateTransforms(TimeInMicroseconds()); |
| 818 | 826 |
| 819 { | 827 { |
| 828 // TODO(crbug.com/704690): Acquire controller state in a way that's timely | |
| 829 // for both the gamepad API and UI input handling. | |
| 820 TRACE_EVENT0("gpu", "VrShellGl::UpdateController"); | 830 TRACE_EVENT0("gpu", "VrShellGl::UpdateController"); |
| 831 UpdateController(); | |
| 821 HandleControllerInput(GetForwardVector(head_pose)); | 832 HandleControllerInput(GetForwardVector(head_pose)); |
| 822 } | 833 } |
| 823 | 834 |
| 824 DrawWorldElements(head_pose); | 835 DrawWorldElements(head_pose); |
| 825 | 836 |
| 826 frame.Unbind(); | 837 frame.Unbind(); |
| 827 | 838 |
| 828 // Draw head-locked elements to a separate, non-reprojected buffer. | 839 // Draw head-locked elements to a separate, non-reprojected buffer. |
| 829 if (scene_->HasVisibleHeadLockedElements()) { | 840 if (scene_->HasVisibleHeadLockedElements()) { |
| 830 frame.BindBuffer(kFrameHeadlockedBuffer); | 841 frame.BindBuffer(kFrameHeadlockedBuffer); |
| (...skipping 358 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1189 | 1200 |
| 1190 // Don't send VSyncs until we have a timebase/interval. | 1201 // Don't send VSyncs until we have a timebase/interval. |
| 1191 if (vsync_interval_.is_zero()) | 1202 if (vsync_interval_.is_zero()) |
| 1192 return; | 1203 return; |
| 1193 target = now + vsync_interval_; | 1204 target = now + vsync_interval_; |
| 1194 int64_t intervals = (target - vsync_timebase_) / vsync_interval_; | 1205 int64_t intervals = (target - vsync_timebase_) / vsync_interval_; |
| 1195 target = vsync_timebase_ + intervals * vsync_interval_; | 1206 target = vsync_timebase_ + intervals * vsync_interval_; |
| 1196 task_runner_->PostDelayedTask(FROM_HERE, vsync_task_.callback(), | 1207 task_runner_->PostDelayedTask(FROM_HERE, vsync_task_.callback(), |
| 1197 target - now); | 1208 target - now); |
| 1198 | 1209 |
| 1199 // Get controller data now so that it's ready for both WebVR's | |
| 1200 // gamepad API input and VrShell's own processing. | |
| 1201 UpdateController(); | |
| 1202 | |
| 1203 base::TimeDelta time = intervals * vsync_interval_; | 1210 base::TimeDelta time = intervals * vsync_interval_; |
| 1204 if (!callback_.is_null()) { | 1211 if (!callback_.is_null()) { |
| 1205 SendVSync(time, base::ResetAndReturn(&callback_)); | 1212 SendVSync(time, base::ResetAndReturn(&callback_)); |
| 1206 } else { | 1213 } else { |
| 1207 pending_vsync_ = true; | 1214 pending_vsync_ = true; |
| 1208 pending_time_ = time; | 1215 pending_time_ = time; |
| 1209 } | 1216 } |
| 1210 if (!ShouldDrawWebVr()) { | 1217 if (!ShouldDrawWebVr()) { |
| 1211 DrawFrame(-1); | 1218 DrawFrame(-1); |
| 1212 } | 1219 } |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1283 // appropriate recommended render resolution as the default size during | 1290 // appropriate recommended render resolution as the default size during |
| 1284 // InitializeGl. Revisit if the initialization order changes. | 1291 // InitializeGl. Revisit if the initialization order changes. |
| 1285 device::mojom::VRDisplayInfoPtr info = VrShell::CreateVRDisplayInfo( | 1292 device::mojom::VRDisplayInfoPtr info = VrShell::CreateVRDisplayInfo( |
| 1286 gvr_api_.get(), webvr_surface_size_, device_id); | 1293 gvr_api_.get(), webvr_surface_size_, device_id); |
| 1287 main_thread_task_runner_->PostTask( | 1294 main_thread_task_runner_->PostTask( |
| 1288 FROM_HERE, | 1295 FROM_HERE, |
| 1289 base::Bind(&RunVRDisplayInfoCallback, callback, base::Passed(&info))); | 1296 base::Bind(&RunVRDisplayInfoCallback, callback, base::Passed(&info))); |
| 1290 } | 1297 } |
| 1291 | 1298 |
| 1292 } // namespace vr_shell | 1299 } // namespace vr_shell |
| OLD | NEW |