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 |