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

Side by Side Diff: chrome/browser/android/vr_shell/vr_shell_gl.cc

Issue 2878543002: Refactor VR Shell Input. Locks input to click/scroll targets. (Closed)
Patch Set: Address comments Created 3 years, 7 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 | « chrome/browser/android/vr_shell/vr_shell_gl.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
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 <chrono> 7 #include <chrono>
8 #include <limits> 8 #include <limits>
9 #include <utility> 9 #include <utility>
10 10
(...skipping 10 matching lines...) Expand all
21 #include "chrome/browser/android/vr_shell/ui_scene_manager.h" 21 #include "chrome/browser/android/vr_shell/ui_scene_manager.h"
22 #include "chrome/browser/android/vr_shell/vr_controller.h" 22 #include "chrome/browser/android/vr_shell/vr_controller.h"
23 #include "chrome/browser/android/vr_shell/vr_gl_thread.h" 23 #include "chrome/browser/android/vr_shell/vr_gl_thread.h"
24 #include "chrome/browser/android/vr_shell/vr_gl_util.h" 24 #include "chrome/browser/android/vr_shell/vr_gl_util.h"
25 #include "chrome/browser/android/vr_shell/vr_shell.h" 25 #include "chrome/browser/android/vr_shell/vr_shell.h"
26 #include "chrome/browser/android/vr_shell/vr_shell_renderer.h" 26 #include "chrome/browser/android/vr_shell/vr_shell_renderer.h"
27 #include "device/vr/android/gvr/gvr_delegate.h" 27 #include "device/vr/android/gvr/gvr_delegate.h"
28 #include "device/vr/android/gvr/gvr_device.h" 28 #include "device/vr/android/gvr/gvr_device.h"
29 #include "device/vr/android/gvr/gvr_gamepad_data_provider.h" 29 #include "device/vr/android/gvr/gvr_gamepad_data_provider.h"
30 #include "device/vr/vr_math.h" 30 #include "device/vr/vr_math.h"
31 #include "third_party/WebKit/public/platform/WebGestureEvent.h"
31 #include "third_party/WebKit/public/platform/WebInputEvent.h" 32 #include "third_party/WebKit/public/platform/WebInputEvent.h"
32 #include "third_party/WebKit/public/platform/WebMouseEvent.h" 33 #include "third_party/WebKit/public/platform/WebMouseEvent.h"
33 #include "ui/gl/android/scoped_java_surface.h" 34 #include "ui/gl/android/scoped_java_surface.h"
34 #include "ui/gl/android/surface_texture.h" 35 #include "ui/gl/android/surface_texture.h"
35 #include "ui/gl/gl_bindings.h" 36 #include "ui/gl/gl_bindings.h"
36 #include "ui/gl/gl_context.h" 37 #include "ui/gl/gl_context.h"
37 #include "ui/gl/gl_surface.h" 38 #include "ui/gl/gl_surface.h"
38 #include "ui/gl/init/gl_factory.h" 39 #include "ui/gl/init/gl_factory.h"
39 40
40 namespace vr_shell { 41 namespace vr_shell {
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
130 result.m[0][2] = A; 131 result.m[0][2] = A;
131 result.m[1][1] = Y; 132 result.m[1][1] = Y;
132 result.m[1][2] = B; 133 result.m[1][2] = B;
133 result.m[2][2] = C; 134 result.m[2][2] = C;
134 result.m[2][3] = D; 135 result.m[2][3] = D;
135 result.m[3][2] = -1; 136 result.m[3][2] = -1;
136 137
137 return result; 138 return result;
138 } 139 }
139 140
140 std::unique_ptr<blink::WebMouseEvent> MakeMouseEvent(WebInputEvent::Type type, 141 std::unique_ptr<blink::WebMouseEvent> MakeMouseEvent(
141 double timestamp, 142 blink::WebInputEvent::Type type,
142 float x, 143 double timestamp,
143 float y) { 144 const gfx::Point& loc) {
144 std::unique_ptr<blink::WebMouseEvent> mouse_event(new blink::WebMouseEvent( 145 std::unique_ptr<blink::WebMouseEvent> mouse_event(new blink::WebMouseEvent(
145 type, blink::WebInputEvent::kNoModifiers, timestamp)); 146 type, blink::WebInputEvent::kNoModifiers, timestamp));
146 mouse_event->pointer_type = blink::WebPointerProperties::PointerType::kMouse; 147 mouse_event->pointer_type = blink::WebPointerProperties::PointerType::kMouse;
147 mouse_event->SetPositionInWidget(x, y); 148 mouse_event->SetPositionInWidget(loc.x(), loc.y());
148 mouse_event->click_count = 1; 149 mouse_event->click_count = 1;
149 150
150 return mouse_event; 151 return mouse_event;
151 } 152 }
152 153
153 enum class ViewerType { 154 enum class ViewerType {
154 UNKNOWN_TYPE = 0, 155 UNKNOWN_TYPE = 0,
155 CARDBOARD = 1, 156 CARDBOARD = 1,
156 DAYDREAM = 2, 157 DAYDREAM = 2,
157 VIEWER_TYPE_MAX, 158 VIEWER_TYPE_MAX,
(...skipping 18 matching lines...) Expand all
176 gvr::Rectf UVFromGfxRect(gfx::RectF rect) { 177 gvr::Rectf UVFromGfxRect(gfx::RectF rect) {
177 return {rect.x(), rect.x() + rect.width(), 1.0f - rect.bottom(), 178 return {rect.x(), rect.x() + rect.width(), 1.0f - rect.bottom(),
178 1.0f - rect.y()}; 179 1.0f - rect.y()};
179 } 180 }
180 181
181 gfx::RectF GfxRectFromUV(gvr::Rectf rect) { 182 gfx::RectF GfxRectFromUV(gvr::Rectf rect) {
182 return gfx::RectF(rect.left, 1.0 - rect.top, rect.right - rect.left, 183 return gfx::RectF(rect.left, 1.0 - rect.top, rect.right - rect.left,
183 rect.top - rect.bottom); 184 rect.top - rect.bottom);
184 } 185 }
185 186
187 double NowSeconds() {
188 return (base::TimeTicks::Now() - base::TimeTicks()).InSecondsF();
189 }
190
186 } // namespace 191 } // namespace
187 192
188 VrShellGl::VrShellGl(VrBrowserInterface* browser, 193 VrShellGl::VrShellGl(VrBrowserInterface* browser,
189 gvr_context* gvr_api, 194 gvr_context* gvr_api,
190 bool initially_web_vr, 195 bool initially_web_vr,
191 bool reprojected_rendering, 196 bool reprojected_rendering,
192 UiScene* scene) 197 UiScene* scene)
193 : web_vr_mode_(initially_web_vr), 198 : web_vr_mode_(initially_web_vr),
194 surfaceless_rendering_(reprojected_rendering), 199 surfaceless_rendering_(reprojected_rendering),
195 task_runner_(base::ThreadTaskRunnerHandle::Get()), 200 task_runner_(base::ThreadTaskRunnerHandle::Get()),
(...skipping 301 matching lines...) Expand 10 before | Expand all | Expand 10 after
497 } 502 }
498 503
499 void VrShellGl::UpdateController(const gfx::Vector3dF& head_direction) { 504 void VrShellGl::UpdateController(const gfx::Vector3dF& head_direction) {
500 controller_->UpdateState(head_direction); 505 controller_->UpdateState(head_direction);
501 pointer_start_ = controller_->GetPointerStart(); 506 pointer_start_ = controller_->GetPointerStart();
502 507
503 browser_->UpdateGamepadData(controller_->GetGamepadData()); 508 browser_->UpdateGamepadData(controller_->GetGamepadData());
504 } 509 }
505 510
506 void VrShellGl::HandleControllerInput(const gfx::Vector3dF& head_direction) { 511 void VrShellGl::HandleControllerInput(const gfx::Vector3dF& head_direction) {
507 if (ShouldDrawWebVr()) { 512 HandleWebVrCompatibilityClick();
508 // Process screen touch events for Cardboard button compatibility.
509 // Also send tap events for controller "touchpad click" events.
510 if (touch_pending_ ||
511 controller_->ButtonUpHappened(
512 gvr::ControllerButton::GVR_CONTROLLER_BUTTON_CLICK)) {
513 touch_pending_ = false;
514 std::unique_ptr<WebGestureEvent> gesture(new WebGestureEvent(
515 WebInputEvent::kGestureTapDown, WebInputEvent::kNoModifiers,
516 (base::TimeTicks::Now() - base::TimeTicks()).InSecondsF()));
517 gesture->source_device = blink::kWebGestureDeviceTouchpad;
518 gesture->x = 0;
519 gesture->y = 0;
520 SendGestureToContent(std::move(gesture));
521 DVLOG(1) << __FUNCTION__ << ": sent CLICK gesture";
522 }
523 }
524 513
525 gfx::Vector3dF ergo_neutral_pose; 514 gfx::Vector3dF ergo_neutral_pose;
526 if (!controller_->IsConnected()) { 515 if (!controller_->IsConnected()) {
527 // No controller detected, set up a gaze cursor that tracks the 516 // No controller detected, set up a gaze cursor that tracks the
528 // forward direction. 517 // forward direction.
529 ergo_neutral_pose = {0.0f, 0.0f, -1.0f}; 518 ergo_neutral_pose = {0.0f, 0.0f, -1.0f};
530 controller_quat_ = GetRotationFromZAxis(head_direction); 519 controller_quat_ = GetRotationFromZAxis(head_direction);
531 } else { 520 } else {
532 ergo_neutral_pose = {0.0f, -sin(kErgoAngleOffset), -cos(kErgoAngleOffset)}; 521 ergo_neutral_pose = {0.0f, -sin(kErgoAngleOffset), -cos(kErgoAngleOffset)};
533 controller_quat_ = controller_->Orientation(); 522 controller_quat_ = controller_->Orientation();
534 } 523 }
535 524
536 vr::Mat4f mat; 525 vr::Mat4f mat;
537 QuatToMatrix(controller_quat_, &mat); 526 QuatToMatrix(controller_quat_, &mat);
538 gfx::Vector3dF controller_direction = 527 gfx::Vector3dF controller_direction =
539 vr::MatrixVectorMul(mat, ergo_neutral_pose); 528 vr::MatrixVectorMul(mat, ergo_neutral_pose);
540 529
541 HandleControllerAppButtonActivity(controller_direction); 530 HandleControllerAppButtonActivity(controller_direction);
542 531
543 if (ShouldDrawWebVr()) { 532 if (ShouldDrawWebVr())
544 return; 533 return;
545 } 534 gfx::PointF target_local_point;
546 535 gfx::Vector3dF eye_to_target;
536 cursor_render_target_ = nullptr;
537 GetVisualTargetElement(controller_direction, eye_to_target, target_point_,
538 &cursor_render_target_, target_local_point);
539
540 UiElement* target_element = nullptr;
541 if (input_locked_element_) {
542 gfx::Point3F plane_intersection_point;
543 float distance_to_plane;
544 GetTargetLocalPoint(eye_to_target, *input_locked_element_,
545 2 * scene_->GetBackgroundDistance(), target_local_point,
546 plane_intersection_point, distance_to_plane);
547 target_element = input_locked_element_;
548 } else if (!in_scroll_ && !in_click_) {
549 target_element = cursor_render_target_;
550 }
551
552 // Handle input targeting on the content quad, ignoring any other elements.
553 // Content is treated specially to accomodate scrolling, flings, etc.
554 gfx::Point local_point_pixels;
555 if (target_element && (target_element->fill() == Fill::CONTENT)) {
556 gfx::RectF pixel_rect(0, 0, content_tex_css_width_,
557 content_tex_css_height_);
558 local_point_pixels.set_x(pixel_rect.x() +
559 pixel_rect.width() * target_local_point.x());
560 local_point_pixels.set_y(pixel_rect.y() +
561 pixel_rect.height() * target_local_point.y());
562 }
563 std::unique_ptr<GestureList> gesture_list_ptr = controller_->DetectGestures();
564 GestureList& gesture_list = *gesture_list_ptr;
565 for (const std::unique_ptr<blink::WebGestureEvent>& gesture : gesture_list) {
566 gesture->x = local_point_pixels.x();
567 gesture->y = local_point_pixels.y();
568 }
569 SendFlingCancel(gesture_list);
570 // For simplicity, don't allow scrolling while clicking until we need to.
571 if (!in_click_) {
572 SendScrollEnd(gesture_list);
573 if (!SendScrollBegin(target_element, gesture_list)) {
574 SendScrollUpdate(gesture_list);
575 }
576 }
577 // If we're still scrolling, don't hover (and we can't be clicking, because
578 // click ends scroll).
579 if (in_scroll_)
580 return;
581 SendHoverLeave(target_element);
582 if (!SendHoverEnter(target_element, target_local_point, local_point_pixels)) {
583 SendHoverMove(target_local_point, local_point_pixels);
584 }
585 SendButtonDown(target_element, target_local_point);
586 if (!SendButtonUp(target_element, target_local_point))
587 SendTap(target_element, target_local_point, local_point_pixels);
588 }
589
590 void VrShellGl::HandleWebVrCompatibilityClick() {
591 if (!ShouldDrawWebVr())
592 return;
593
594 // Process screen touch events for Cardboard button compatibility.
595 // Also send tap events for controller "touchpad click" events.
596 if (touch_pending_ ||
597 controller_->ButtonUpHappened(gvr::kControllerButtonClick)) {
598 touch_pending_ = false;
599 std::unique_ptr<blink::WebGestureEvent> gesture(new blink::WebGestureEvent(
600 blink::WebInputEvent::kGestureTapDown,
601 blink::WebInputEvent::kNoModifiers, NowSeconds()));
602 gesture->source_device = blink::kWebGestureDeviceTouchpad;
603 gesture->x = 0;
604 gesture->y = 0;
605 SendGestureToContent(std::move(gesture));
606 DVLOG(1) << __FUNCTION__ << ": sent CLICK gesture";
607 }
608 }
609
610 void VrShellGl::SendFlingCancel(GestureList& gesture_list) {
611 if (!fling_target_)
612 return;
613 if (gesture_list.empty() || (gesture_list.front()->GetType() !=
614 blink::WebInputEvent::kGestureFlingCancel))
615 return;
616 // Scrolling currently only supported on content window.
617 DCHECK_EQ(fling_target_->fill(), Fill::CONTENT);
618 SendGestureToContent(std::move(gesture_list.front()));
619 gesture_list.erase(gesture_list.begin());
620 }
621
622 void VrShellGl::SendScrollEnd(GestureList& gesture_list) {
623 if (!in_scroll_)
624 return;
625 DCHECK_NE(input_locked_element_, nullptr);
626 if (controller_->ButtonDownHappened(gvr::kControllerButtonClick)) {
627 DCHECK_GT(gesture_list.size(), 0LU);
628 DCHECK_EQ(gesture_list.front()->GetType(),
629 blink::WebInputEvent::kGestureScrollEnd);
630 }
631 // Scrolling currently only supported on content window.
632 DCHECK_EQ(input_locked_element_->fill(), Fill::CONTENT);
633 if (gesture_list.empty() || (gesture_list.front()->GetType() !=
634 blink::WebInputEvent::kGestureScrollEnd))
635 return;
636 DCHECK_LE(gesture_list.size(), 2LU);
637 SendGestureToContent(std::move(gesture_list.front()));
638 gesture_list.erase(gesture_list.begin());
639 if (!gesture_list.empty()) {
640 DCHECK_EQ(gesture_list.front()->GetType(),
641 blink::WebInputEvent::kGestureFlingStart);
642 SendGestureToContent(std::move(gesture_list.front()));
643 fling_target_ = input_locked_element_;
644 gesture_list.erase(gesture_list.begin());
645 }
646 input_locked_element_ = nullptr;
647 in_scroll_ = false;
648 }
649
650 bool VrShellGl::SendScrollBegin(UiElement* target, GestureList& gesture_list) {
651 if (in_scroll_ || !target)
652 return false;
653 // Scrolling currently only supported on content window.
654 if (target->fill() != Fill::CONTENT)
655 return false;
656 if (gesture_list.empty() || (gesture_list.front()->GetType() !=
657 blink::WebInputEvent::kGestureScrollBegin))
658 return false;
659 input_locked_element_ = target;
660 in_scroll_ = true;
661
662 SendGestureToContent(std::move(gesture_list.front()));
663 gesture_list.erase(gesture_list.begin());
664 return true;
665 }
666
667 void VrShellGl::SendScrollUpdate(GestureList& gesture_list) {
668 if (!in_scroll_)
669 return;
670 DCHECK(input_locked_element_);
671 if (gesture_list.empty() || (gesture_list.front()->GetType() !=
672 blink::WebInputEvent::kGestureScrollUpdate))
673 return;
674 // Scrolling currently only supported on content window.
675 DCHECK_EQ(input_locked_element_->fill(), Fill::CONTENT);
676 SendGestureToContent(std::move(gesture_list.front()));
677 gesture_list.erase(gesture_list.begin());
678 }
679
680 void VrShellGl::SendHoverLeave(UiElement* target) {
681 if (!hover_target_ || (target == hover_target_))
682 return;
683 if (hover_target_->fill() == Fill::CONTENT) {
684 SendGestureToContent(MakeMouseEvent(blink::WebInputEvent::kMouseLeave,
685 NowSeconds(), gfx::Point()));
686 } else {
687 hover_target_->OnHoverLeave();
688 }
689 hover_target_ = nullptr;
690 }
691
692 bool VrShellGl::SendHoverEnter(UiElement* target,
693 const gfx::PointF& target_point,
694 const gfx::Point& local_point_pixels) {
695 if (!target || target == hover_target_)
696 return false;
697 if (target->fill() == Fill::CONTENT) {
698 SendGestureToContent(MakeMouseEvent(blink::WebInputEvent::kMouseEnter,
699 NowSeconds(), local_point_pixels));
700 } else {
701 target->OnHoverEnter(target_point);
702 }
703 hover_target_ = target;
704 return true;
705 }
706
707 void VrShellGl::SendHoverMove(const gfx::PointF& target_point,
708 const gfx::Point& local_point_pixels) {
709 if (!hover_target_)
710 return;
711 if (hover_target_->fill() == Fill::CONTENT) {
712 SendGestureToContent(MakeMouseEvent(blink::WebInputEvent::kMouseMove,
713 NowSeconds(), local_point_pixels));
714 } else {
715 hover_target_->OnMove(target_point);
716 }
717 }
718
719 void VrShellGl::SendButtonDown(UiElement* target,
720 const gfx::PointF& target_point) {
721 if (in_click_)
722 return;
723 if (!controller_->ButtonDownHappened(gvr::kControllerButtonClick))
724 return;
725 input_locked_element_ = target;
726 in_click_ = true;
727 // We don't support down/up for content yet.
728 if (!target || target->fill() == Fill::CONTENT)
729 return;
730 target->OnButtonDown(target_point);
731 }
732
733 bool VrShellGl::SendButtonUp(UiElement* target,
734 const gfx::PointF& target_point) {
735 if (!in_click_)
736 return false;
737 if (!controller_->ButtonUpHappened(gvr::kControllerButtonClick))
738 return false;
739 DCHECK(input_locked_element_ == target);
740 input_locked_element_ = nullptr;
741 in_click_ = false;
742 // We don't support down/up for content yet.
743 if (target->fill() == Fill::CONTENT)
744 return false;
745 target->OnButtonUp(target_point);
746 return true;
747 }
748
749 void VrShellGl::SendTap(UiElement* target,
750 const gfx::PointF& target_point,
751 const gfx::Point& local_point_pixels) {
752 if (!target)
753 return;
754 if (controller_->ButtonUpHappened(gvr::kControllerButtonClick) &&
755 target->fill() == Fill::CONTENT)
756 touch_pending_ = true;
757 if (!touch_pending_)
758 return;
759 touch_pending_ = false;
760 if (target->fill() == Fill::CONTENT) {
761 auto gesture = base::MakeUnique<blink::WebGestureEvent>(
762 blink::WebInputEvent::kGestureTapDown,
763 blink::WebInputEvent::kNoModifiers, NowSeconds());
764 gesture->source_device = blink::kWebGestureDeviceTouchpad;
765 gesture->x = local_point_pixels.x();
766 gesture->y = local_point_pixels.y();
767 SendGestureToContent(std::move(gesture));
768 } else {
769 target->OnButtonDown(target_point);
770 target->OnButtonUp(target_point);
771 }
772 }
773
774 void VrShellGl::GetVisualTargetElement(
775 const gfx::Vector3dF& controller_direction,
776 gfx::Vector3dF& eye_to_target,
777 gfx::Point3F& target_point,
778 UiElement** target_element,
779 gfx::PointF& target_local_point) const {
547 // If we place the reticle based on elements intersecting the controller beam, 780 // If we place the reticle based on elements intersecting the controller beam,
548 // we can end up with the reticle hiding behind elements, or jumping laterally 781 // we can end up with the reticle hiding behind elements, or jumping laterally
549 // in the field of view. This is physically correct, but hard to use. For 782 // in the field of view. This is physically correct, but hard to use. For
550 // usability, do the following instead: 783 // usability, do the following instead:
551 // 784 //
552 // - Project the controller laser onto a distance-limiting sphere. 785 // - Project the controller laser onto a distance-limiting sphere.
553 // - Create a vector between the eyes and the outer surface point. 786 // - Create a vector between the eyes and the outer surface point.
554 // - If any UI elements intersect this vector, and is within the bounding 787 // - If any UI elements intersect this vector, and is within the bounding
555 // sphere, choose the closest to the eyes, and place the reticle at the 788 // sphere, choose the closest to the eyes, and place the reticle at the
556 // intersection point. 789 // intersection point.
557 790
558 // Compute the distance from the eyes to the distance limiting sphere. Note 791 // Compute the distance from the eyes to the distance limiting sphere. Note
559 // that the sphere is centered at the controller, rather than the eye, for 792 // that the sphere is centered at the controller, rather than the eye, for
560 // simplicity. 793 // simplicity.
561 float distance = scene_->GetBackgroundDistance(); 794 float distance = scene_->GetBackgroundDistance();
562 target_point_ = 795 target_point =
563 vr::GetRayPoint(pointer_start_, controller_direction, distance); 796 vr::GetRayPoint(pointer_start_, controller_direction, distance);
564 gfx::Vector3dF eye_to_target = target_point_ - kOrigin; 797 eye_to_target = target_point - kOrigin;
565 vr::NormalizeVector(&eye_to_target); 798 vr::NormalizeVector(&eye_to_target);
566 799
567 // Determine which UI element (if any) intersects the line between the eyes 800 // Determine which UI element (if any) intersects the line between the eyes
568 // and the controller target position. 801 // and the controller target position.
569 float closest_element_distance = (target_point_ - kOrigin).Length(); 802 float closest_element_distance = (target_point - kOrigin).Length();
570 previous_target_element_ = target_element_;
571 target_element_ = nullptr;
572 float target_x;
573 float target_y;
574 803
575 for (auto& plane : scene_->GetUiElements()) { 804 for (auto& element : scene_->GetUiElements()) {
576 if (!plane->IsHitTestable()) 805 if (!element->IsHitTestable())
806 continue;
807 gfx::PointF local_point;
808 gfx::Point3F plane_intersection_point;
809 float distance_to_plane;
810 if (!GetTargetLocalPoint(eye_to_target, *element.get(),
811 closest_element_distance, local_point,
812 plane_intersection_point, distance_to_plane))
577 continue; 813 continue;
578 814
579 float distance_to_plane; 815 if (local_point.x() < 0.0f || local_point.x() >= 1.0f ||
580 if (!plane->GetRayDistance(kOrigin, eye_to_target, &distance_to_plane)) 816 local_point.y() < 0.0f || local_point.y() >= 1.0f)
581 continue;
582
583 if (distance_to_plane < 0 || distance_to_plane >= closest_element_distance)
584 continue;
585
586 gfx::Point3F plane_intersection_point =
587 vr::GetRayPoint(kOrigin, eye_to_target, distance_to_plane);
588 gfx::PointF unit_xy_point =
589 plane->GetUnitRectangleCoordinates(plane_intersection_point);
590
591 float x = 0.5f + unit_xy_point.x();
592 float y = 0.5f - unit_xy_point.y();
593 if (x < 0.0f || x >= 1.0f || y < 0.0f || y >= 1.0f)
594 continue; 817 continue;
595 818
596 closest_element_distance = distance_to_plane; 819 closest_element_distance = distance_to_plane;
597 target_point_ = plane_intersection_point; 820 target_point = plane_intersection_point;
598 target_element_ = plane.get(); 821 *target_element = element.get();
599 target_x = x; 822 target_local_point = local_point;
600 target_y = y;
601 } 823 }
824 }
602 825
603 // Handle input targeting on the content quad, ignoring any other elements. 826 bool VrShellGl::GetTargetLocalPoint(const gfx::Vector3dF& eye_to_target,
604 // Content is treated specially to accomodate scrolling, flings, etc. 827 const UiElement& element,
605 InputTarget input_target = InputTarget::NONE; 828 float max_distance_to_plane,
606 int pixel_x = 0; 829 gfx::PointF& target_local_point,
607 int pixel_y = 0; 830 gfx::Point3F& target_point,
608 if (target_element_ != nullptr && target_element_->fill() == Fill::CONTENT) { 831 float& distance_to_plane) const {
609 input_target = InputTarget::CONTENT; 832 if (!element.GetRayDistance(kOrigin, eye_to_target, &distance_to_plane))
610 gfx::RectF pixel_rect(0, 0, content_tex_css_width_, 833 return false;
611 content_tex_css_height_);
612 pixel_x = pixel_rect.x() + pixel_rect.width() * target_x;
613 pixel_y = pixel_rect.y() + pixel_rect.height() * target_y;
614 }
615 SendInputToContent(input_target, pixel_x, pixel_y);
616 834
617 // Handle input targeting on all non-content elements. 835 if (distance_to_plane < 0 || distance_to_plane >= max_distance_to_plane)
618 SendInputToUiElements(target_element_); 836 return false;
837
838 target_point = vr::GetRayPoint(kOrigin, eye_to_target, distance_to_plane);
839 gfx::PointF unit_xy_point = element.GetUnitRectangleCoordinates(target_point);
840
841 target_local_point.set_x(0.5f + unit_xy_point.x());
842 target_local_point.set_y(0.5f - unit_xy_point.y());
843 return true;
619 } 844 }
620 845
621 void VrShellGl::HandleControllerAppButtonActivity( 846 void VrShellGl::HandleControllerAppButtonActivity(
622 const gfx::Vector3dF& controller_direction) { 847 const gfx::Vector3dF& controller_direction) {
623 // Note that button up/down state is transient, so ButtonDownHappened only 848 // Note that button up/down state is transient, so ButtonDownHappened only
624 // returns true for a single frame (and we're guaranteed not to miss it). 849 // returns true for a single frame (and we're guaranteed not to miss it).
625 if (controller_->ButtonDownHappened( 850 if (controller_->ButtonDownHappened(
626 gvr::ControllerButton::GVR_CONTROLLER_BUTTON_APP)) { 851 gvr::ControllerButton::GVR_CONTROLLER_BUTTON_APP)) {
627 controller_start_direction_ = controller_direction; 852 controller_start_direction_ = controller_direction;
628 } 853 }
(...skipping 12 matching lines...) Expand all
641 direction = 866 direction =
642 gesture_xz_angle < 0 ? UiInterface::LEFT : UiInterface::RIGHT; 867 gesture_xz_angle < 0 ? UiInterface::LEFT : UiInterface::RIGHT;
643 browser_->AppButtonGesturePerformed(direction); 868 browser_->AppButtonGesturePerformed(direction);
644 } 869 }
645 } 870 }
646 if (direction == UiInterface::NONE) 871 if (direction == UiInterface::NONE)
647 browser_->AppButtonClicked(); 872 browser_->AppButtonClicked();
648 } 873 }
649 } 874 }
650 875
651 void VrShellGl::SendInputToContent(InputTarget input_target,
652 int pixel_x,
653 int pixel_y) {
654 std::vector<std::unique_ptr<WebGestureEvent>> gesture_list =
655 controller_->DetectGestures();
656 double timestamp = gesture_list.front()->TimeStampSeconds();
657
658 if (touch_pending_) {
659 touch_pending_ = false;
660 std::unique_ptr<WebGestureEvent> event(
661 new WebGestureEvent(WebInputEvent::kGestureTapDown,
662 WebInputEvent::kNoModifiers, timestamp));
663 event->source_device = blink::kWebGestureDeviceTouchpad;
664 event->x = pixel_x;
665 event->y = pixel_y;
666 gesture_list.push_back(std::move(event));
667 }
668
669 for (auto& gesture : gesture_list) {
670 gesture->x = pixel_x;
671 gesture->y = pixel_y;
672 auto movableGesture = base::MakeUnique<WebGestureEvent>(*gesture);
673
674 switch (gesture->GetType()) {
675 // Once the user starts scrolling send all the scroll events to this
676 // element until the scrolling stops.
677 case WebInputEvent::kGestureScrollBegin:
678 current_scroll_target_ = input_target;
679 if (current_scroll_target_ != InputTarget::NONE) {
680 SendGestureToContent(std::move(movableGesture));
681 }
682 break;
683 case WebInputEvent::kGestureScrollEnd:
684 if (current_scroll_target_ != InputTarget::NONE) {
685 SendGestureToContent(std::move(movableGesture));
686 }
687 current_fling_target_ = current_scroll_target_;
688 current_scroll_target_ = InputTarget::NONE;
689 break;
690 case WebInputEvent::kGestureScrollUpdate:
691 if (current_scroll_target_ != InputTarget::NONE) {
692 SendGestureToContent(std::move(movableGesture));
693 }
694 break;
695 case WebInputEvent::kGestureFlingStart:
696 if (current_fling_target_ != InputTarget::NONE) {
697 SendGestureToContent(std::move(movableGesture));
698 }
699 current_fling_target_ = InputTarget::NONE;
700 break;
701 case WebInputEvent::kGestureFlingCancel:
702 current_fling_target_ = InputTarget::NONE;
703 if (input_target != InputTarget::NONE) {
704 SendGestureToContent(std::move(movableGesture));
705 }
706 break;
707 case WebInputEvent::kGestureTapDown:
708 current_fling_target_ = InputTarget::NONE;
709 if (input_target != InputTarget::NONE) {
710 SendGestureToContent(std::move(movableGesture));
711 }
712 break;
713 case WebInputEvent::kUndefined:
714 break;
715 default:
716 NOTREACHED();
717 }
718 }
719
720 // Hover support
721 bool new_target = input_target != current_input_target_;
722 if (new_target && current_input_target_ != InputTarget::NONE) {
723 // Send a move event indicating that the pointer moved off of an element.
724 SendGestureToContent(
725 MakeMouseEvent(WebInputEvent::kMouseLeave, timestamp, 0, 0));
726 }
727 current_input_target_ = input_target;
728 if (current_input_target_ != InputTarget::NONE) {
729 WebInputEvent::Type type =
730 new_target ? WebInputEvent::kMouseEnter : WebInputEvent::kMouseMove;
731 SendGestureToContent(MakeMouseEvent(type, timestamp, pixel_x, pixel_y));
732 }
733 }
734
735 void VrShellGl::SendInputToUiElements(UiElement* target_element) {
736 if (target_element != previous_target_element_) {
737 if (previous_target_element_ &&
738 previous_target_element_->fill() != Fill::CONTENT) {
739 task_runner_->PostTask(
740 FROM_HERE, base::Bind(&UiElement::OnHoverLeave,
741 base::Unretained(previous_target_element_)));
742 }
743 if (target_element && target_element->fill() != Fill::CONTENT) {
744 task_runner_->PostTask(FROM_HERE,
745 base::Bind(&UiElement::OnHoverEnter,
746 base::Unretained(target_element)));
747 }
748 click_target_element_ = nullptr;
749 }
750 if (target_element && target_element->fill() != Fill::CONTENT) {
751 if (controller_->ButtonDownHappened(
752 gvr::ControllerButton::GVR_CONTROLLER_BUTTON_CLICK)) {
753 task_runner_->PostTask(FROM_HERE,
754 base::Bind(&UiElement::OnButtonDown,
755 base::Unretained(target_element)));
756 click_target_element_ = target_element;
757 }
758 if (controller_->ButtonUpHappened(
759 gvr::ControllerButton::GVR_CONTROLLER_BUTTON_CLICK)) {
760 if (click_target_element_ == target_element) {
761 task_runner_->PostTask(FROM_HERE,
762 base::Bind(&UiElement::OnButtonUp,
763 base::Unretained(target_element)));
764 }
765 click_target_element_ = nullptr;
766 }
767 }
768 }
769
770 void VrShellGl::SendGestureToContent( 876 void VrShellGl::SendGestureToContent(
771 std::unique_ptr<blink::WebInputEvent> event) { 877 std::unique_ptr<blink::WebInputEvent> event) {
772 browser_->ProcessContentGesture(std::move(event)); 878 browser_->ProcessContentGesture(std::move(event));
773 } 879 }
774 880
775 void VrShellGl::DrawFrame(int16_t frame_index) { 881 void VrShellGl::DrawFrame(int16_t frame_index) {
776 TRACE_EVENT1("gpu", "VrShellGl::DrawFrame", "frame", frame_index); 882 TRACE_EVENT1("gpu", "VrShellGl::DrawFrame", "frame", frame_index);
777 883
778 base::TimeTicks current_time = base::TimeTicks::Now(); 884 base::TimeTicks current_time = base::TimeTicks::Now();
779 885
(...skipping 290 matching lines...) Expand 10 before | Expand all | Expand 10 after
1070 1176
1071 // Scale the pointer to have a fixed FOV size at any distance. 1177 // Scale the pointer to have a fixed FOV size at any distance.
1072 const float eye_to_target = 1178 const float eye_to_target =
1073 std::sqrt(target_point_.SquaredDistanceTo(kOrigin)); 1179 std::sqrt(target_point_.SquaredDistanceTo(kOrigin));
1074 vr::ScaleM( 1180 vr::ScaleM(
1075 mat, 1181 mat,
1076 {kReticleWidth * eye_to_target, kReticleHeight * eye_to_target, 1.0f}, 1182 {kReticleWidth * eye_to_target, kReticleHeight * eye_to_target, 1.0f},
1077 &mat); 1183 &mat);
1078 1184
1079 vr::Quatf rotation; 1185 vr::Quatf rotation;
1080 if (target_element_ != nullptr) { 1186 if (cursor_render_target_ != nullptr) {
1081 // Make the reticle planar to the element it's hitting. 1187 // Make the reticle planar to the element it's hitting.
1082 rotation = GetRotationFromZAxis(target_element_->GetNormal()); 1188 rotation = GetRotationFromZAxis(cursor_render_target_->GetNormal());
1083 } else { 1189 } else {
1084 // Rotate the cursor to directly face the eyes. 1190 // Rotate the cursor to directly face the eyes.
1085 rotation = GetRotationFromZAxis(target_point_ - kOrigin); 1191 rotation = GetRotationFromZAxis(target_point_ - kOrigin);
1086 } 1192 }
1087 vr::Mat4f rotation_mat; 1193 vr::Mat4f rotation_mat;
1088 vr::QuatToMatrix(rotation, &rotation_mat); 1194 vr::QuatToMatrix(rotation, &rotation_mat);
1089 vr::MatrixMul(rotation_mat, mat, &mat); 1195 vr::MatrixMul(rotation_mat, mat, &mat);
1090 1196
1091 gfx::Point3F target_point = ScalePoint(target_point_, kReticleOffset); 1197 gfx::Point3F target_point = ScalePoint(target_point_, kReticleOffset);
1092 // Place the pointer slightly in front of the plane intersection point. 1198 // Place the pointer slightly in front of the plane intersection point.
(...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after
1324 // This assumes that the initial webvr_surface_size_ was set to the 1430 // This assumes that the initial webvr_surface_size_ was set to the
1325 // appropriate recommended render resolution as the default size during 1431 // appropriate recommended render resolution as the default size during
1326 // InitializeGl. Revisit if the initialization order changes. 1432 // InitializeGl. Revisit if the initialization order changes.
1327 device::mojom::VRDisplayInfoPtr info = 1433 device::mojom::VRDisplayInfoPtr info =
1328 device::GvrDelegate::CreateVRDisplayInfo(gvr_api_.get(), 1434 device::GvrDelegate::CreateVRDisplayInfo(gvr_api_.get(),
1329 webvr_surface_size_, device_id); 1435 webvr_surface_size_, device_id);
1330 browser_->RunVRDisplayInfoCallback(callback, &info); 1436 browser_->RunVRDisplayInfoCallback(callback, &info);
1331 } 1437 }
1332 1438
1333 } // namespace vr_shell 1439 } // namespace vr_shell
OLDNEW
« no previous file with comments | « chrome/browser/android/vr_shell/vr_shell_gl.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698