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

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

Issue 2795793002: Implementation of elbow model for the controller position and rotation. (Closed)
Patch Set: Rebasing. Created 3 years, 8 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
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 29 matching lines...) Expand all
40 40
41 namespace { 41 namespace {
42 static constexpr float kZNear = 0.1f; 42 static constexpr float kZNear = 0.1f;
43 static constexpr float kZFar = 1000.0f; 43 static constexpr float kZFar = 1000.0f;
44 44
45 static constexpr float kReticleWidth = 0.025f; 45 static constexpr float kReticleWidth = 0.025f;
46 static constexpr float kReticleHeight = 0.025f; 46 static constexpr float kReticleHeight = 0.025f;
47 47
48 static constexpr float kLaserWidth = 0.01f; 48 static constexpr float kLaserWidth = 0.01f;
49 49
50 // Angle (radians) the beam down from the controller axis, for wrist comfort.
51 static constexpr float kErgoAngleOffset = 0.26f;
52
53 static constexpr gfx::Point3F kOrigin = {0.0f, 0.0f, 0.0f}; 50 static constexpr gfx::Point3F kOrigin = {0.0f, 0.0f, 0.0f};
54 51
55 // In lieu of an elbow model, we assume a position for the user's hand.
56 // TODO(mthiesse): Handedness options.
57 static constexpr gfx::Point3F kHandPosition = {0.2f, -0.5f, -0.2f};
58
59 // Fraction of the distance to the object the cursor is drawn at to avoid 52 // Fraction of the distance to the object the cursor is drawn at to avoid
60 // rounding errors drawing the cursor behind the object. 53 // rounding errors drawing the cursor behind the object.
61 static constexpr float kReticleOffset = 0.99f; 54 static constexpr float kReticleOffset = 0.99f;
62 55
63 // GVR buffer indices for use with viewport->SetSourceBufferIndex 56 // GVR buffer indices for use with viewport->SetSourceBufferIndex
64 // or frame.BindBuffer. We use one for world content (with reprojection) 57 // or frame.BindBuffer. We use one for world content (with reprojection)
65 // including main VrShell and WebVR content plus world-space UI. 58 // including main VrShell and WebVR content plus world-space UI.
66 // The headlocked buffer is for UI that should not use reprojection. 59 // The headlocked buffer is for UI that should not use reprojection.
67 static constexpr int kFramePrimaryBuffer = 0; 60 static constexpr int kFramePrimaryBuffer = 0;
68 static constexpr int kFrameHeadlockedBuffer = 1; 61 static constexpr int kFrameHeadlockedBuffer = 1;
(...skipping 436 matching lines...) Expand 10 before | Expand all | Expand 10 after
505 webvr_right_viewport_.reset( 498 webvr_right_viewport_.reset(
506 new gvr::BufferViewport(gvr_api_->CreateBufferViewport())); 499 new gvr::BufferViewport(gvr_api_->CreateBufferViewport()));
507 buffer_viewport_list_->GetBufferViewport(GVR_RIGHT_EYE, 500 buffer_viewport_list_->GetBufferViewport(GVR_RIGHT_EYE,
508 webvr_right_viewport_.get()); 501 webvr_right_viewport_.get());
509 webvr_right_viewport_->SetSourceBufferIndex(kFramePrimaryBuffer); 502 webvr_right_viewport_->SetSourceBufferIndex(kFramePrimaryBuffer);
510 503
511 main_thread_task_runner_->PostTask( 504 main_thread_task_runner_->PostTask(
512 FROM_HERE, base::Bind(&VrShell::GvrDelegateReady, weak_vr_shell_)); 505 FROM_HERE, base::Bind(&VrShell::GvrDelegateReady, weak_vr_shell_));
513 } 506 }
514 507
515 void VrShellGl::UpdateController() { 508 void VrShellGl::UpdateController(const gfx::Vector3dF& head_direction) {
516 controller_->UpdateState(); 509 controller_->UpdateState(head_direction);
510 pointer_start_ = controller_->GetPointerStart();
517 511
518 device::GvrGamepadData pad = controller_->GetGamepadData(); 512 device::GvrGamepadData pad = controller_->GetGamepadData();
519 main_thread_task_runner_->PostTask( 513 main_thread_task_runner_->PostTask(
520 FROM_HERE, base::Bind(&VrShell::UpdateGamepadData, weak_vr_shell_, pad)); 514 FROM_HERE, base::Bind(&VrShell::UpdateGamepadData, weak_vr_shell_, pad));
521 } 515 }
522 516
523 void VrShellGl::HandleControllerInput(const gfx::Vector3dF& forward_vector) { 517 void VrShellGl::HandleControllerInput(const gfx::Vector3dF& head_direction) {
524 if (ShouldDrawWebVr()) { 518 if (ShouldDrawWebVr()) {
525 // Process screen touch events for Cardboard button compatibility. 519 // Process screen touch events for Cardboard button compatibility.
526 // Also send tap events for controller "touchpad click" events. 520 // Also send tap events for controller "touchpad click" events.
527 if (touch_pending_ || 521 if (touch_pending_ ||
528 controller_->ButtonUpHappened( 522 controller_->ButtonUpHappened(
529 gvr::ControllerButton::GVR_CONTROLLER_BUTTON_CLICK)) { 523 gvr::ControllerButton::GVR_CONTROLLER_BUTTON_CLICK)) {
530 touch_pending_ = false; 524 touch_pending_ = false;
531 std::unique_ptr<WebGestureEvent> gesture(new WebGestureEvent( 525 std::unique_ptr<WebGestureEvent> gesture(new WebGestureEvent(
532 WebInputEvent::kGestureTapDown, WebInputEvent::kNoModifiers, 526 WebInputEvent::kGestureTapDown, WebInputEvent::kNoModifiers,
533 (base::TimeTicks::Now() - base::TimeTicks()).InSecondsF())); 527 (base::TimeTicks::Now() - base::TimeTicks()).InSecondsF()));
534 gesture->source_device = blink::kWebGestureDeviceTouchpad; 528 gesture->source_device = blink::kWebGestureDeviceTouchpad;
535 gesture->x = 0; 529 gesture->x = 0;
536 gesture->y = 0; 530 gesture->y = 0;
537 SendGesture(InputTarget::CONTENT, std::move(gesture)); 531 SendGesture(InputTarget::CONTENT, std::move(gesture));
538 DVLOG(1) << __FUNCTION__ << ": sent CLICK gesture"; 532 DVLOG(1) << __FUNCTION__ << ": sent CLICK gesture";
539 } 533 }
540 } 534 }
541 535
542 gfx::Vector3dF ergo_neutral_pose; 536 gfx::Vector3dF ergo_neutral_pose;
543 if (!controller_->IsConnected()) { 537 if (!controller_->IsConnected()) {
544 // No controller detected, set up a gaze cursor that tracks the 538 // No controller detected, set up a gaze cursor that tracks the
545 // forward direction. 539 // forward direction.
546 ergo_neutral_pose = {0.0f, 0.0f, -1.0f}; 540 ergo_neutral_pose = {0.0f, 0.0f, -1.0f};
547 controller_quat_ = GetRotationFromZAxis(forward_vector); 541 controller_quat_ = GetRotationFromZAxis(head_direction);
548 } else { 542 } else {
549 ergo_neutral_pose = {0.0f, -sin(kErgoAngleOffset), -cos(kErgoAngleOffset)}; 543 ergo_neutral_pose = {0.0f, -sin(kErgoAngleOffset), -cos(kErgoAngleOffset)};
550 controller_quat_ = controller_->Orientation(); 544 controller_quat_ = controller_->Orientation();
551 } 545 }
552 546
553 vr::Mat4f mat; 547 vr::Mat4f mat;
554 QuatToMatrix(controller_quat_, &mat); 548 QuatToMatrix(controller_quat_, &mat);
555 gfx::Vector3dF controller_direction = 549 gfx::Vector3dF controller_direction =
556 vr::MatrixVectorMul(mat, ergo_neutral_pose); 550 vr::MatrixVectorMul(mat, ergo_neutral_pose);
557 551
(...skipping 12 matching lines...) Expand all
570 // - Create a vector between the eyes and the outer surface point. 564 // - Create a vector between the eyes and the outer surface point.
571 // - If any UI elements intersect this vector, and is within the bounding 565 // - If any UI elements intersect this vector, and is within the bounding
572 // sphere, choose the closest to the eyes, and place the reticle at the 566 // sphere, choose the closest to the eyes, and place the reticle at the
573 // intersection point. 567 // intersection point.
574 568
575 // Compute the distance from the eyes to the distance limiting sphere. Note 569 // Compute the distance from the eyes to the distance limiting sphere. Note
576 // that the sphere is centered at the controller, rather than the eye, for 570 // that the sphere is centered at the controller, rather than the eye, for
577 // simplicity. 571 // simplicity.
578 float distance = scene_->GetBackgroundDistance(); 572 float distance = scene_->GetBackgroundDistance();
579 target_point_ = 573 target_point_ =
580 vr::GetRayPoint(kHandPosition, controller_direction, distance); 574 vr::GetRayPoint(pointer_start_, controller_direction, distance);
581 gfx::Vector3dF eye_to_target = target_point_ - kOrigin; 575 gfx::Vector3dF eye_to_target = target_point_ - kOrigin;
582 vr::NormalizeVector(&eye_to_target); 576 vr::NormalizeVector(&eye_to_target);
583 577
584 // Determine which UI element (if any) intersects the line between the eyes 578 // Determine which UI element (if any) intersects the line between the eyes
585 // and the controller target position. 579 // and the controller target position.
586 float closest_element_distance = (target_point_ - kOrigin).Length(); 580 float closest_element_distance = (target_point_ - kOrigin).Length();
587 target_element_ = nullptr; 581 target_element_ = nullptr;
588 float target_x; 582 float target_x;
589 float target_y; 583 float target_y;
590 584
(...skipping 266 matching lines...) Expand 10 before | Expand all | Expand 10 after
857 device::GvrDelegate::GetGvrPoseWithNeckModel(gvr_api_.get(), &head_pose); 851 device::GvrDelegate::GetGvrPoseWithNeckModel(gvr_api_.get(), &head_pose);
858 } 852 }
859 853
860 // Update the render position of all UI elements (including desktop). 854 // Update the render position of all UI elements (including desktop).
861 scene_->UpdateTransforms(current_time); 855 scene_->UpdateTransforms(current_time);
862 856
863 { 857 {
864 // TODO(crbug.com/704690): Acquire controller state in a way that's timely 858 // TODO(crbug.com/704690): Acquire controller state in a way that's timely
865 // for both the gamepad API and UI input handling. 859 // for both the gamepad API and UI input handling.
866 TRACE_EVENT0("gpu", "VrShellGl::UpdateController"); 860 TRACE_EVENT0("gpu", "VrShellGl::UpdateController");
867 UpdateController(); 861 auto head_direction = vr::GetForwardVector(head_pose);
868 HandleControllerInput(vr::GetForwardVector(head_pose)); 862 UpdateController(head_direction);
863 HandleControllerInput(head_direction);
869 } 864 }
870 865
871 DrawWorldElements(head_pose); 866 DrawWorldElements(head_pose);
872 867
873 frame.Unbind(); 868 frame.Unbind();
874 869
875 // Draw head-locked elements to a separate, non-reprojected buffer. 870 // Draw head-locked elements to a separate, non-reprojected buffer.
876 if (scene_->HasVisibleHeadLockedElements()) { 871 if (scene_->HasVisibleHeadLockedElements()) {
877 frame.BindBuffer(kFrameHeadlockedBuffer); 872 frame.BindBuffer(kFrameHeadlockedBuffer);
878 DrawHeadLockedElements(); 873 DrawHeadLockedElements();
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
974 vr::Mat4f render_matrix; 969 vr::Mat4f render_matrix;
975 vr::Mat4f perspective_matrix; 970 vr::Mat4f perspective_matrix;
976 GvrMatToMatf(PerspectiveMatrixFromView(buffer_viewport_->GetSourceFov(), 971 GvrMatToMatf(PerspectiveMatrixFromView(buffer_viewport_->GetSourceFov(),
977 kZNear, kZFar), 972 kZNear, kZFar),
978 &perspective_matrix); 973 &perspective_matrix);
979 974
980 vr::MatrixMul(perspective_matrix, eye_view_matrix, &render_matrix); 975 vr::MatrixMul(perspective_matrix, eye_view_matrix, &render_matrix);
981 976
982 DrawElements(render_matrix, elementsInDrawOrder); 977 DrawElements(render_matrix, elementsInDrawOrder);
983 if (draw_cursor) { 978 if (draw_cursor) {
979 DrawController(render_matrix);
984 DrawCursor(render_matrix); 980 DrawCursor(render_matrix);
985 DrawController(render_matrix);
986 } 981 }
987 } 982 }
988 } 983 }
989 984
990 void VrShellGl::DrawElements(const vr::Mat4f& view_proj_matrix, 985 void VrShellGl::DrawElements(const vr::Mat4f& view_proj_matrix,
991 const std::vector<const UiElement*>& elements) { 986 const std::vector<const UiElement*>& elements) {
992 for (const auto* rect : elements) { 987 for (const auto* rect : elements) {
993 vr::Mat4f transform; 988 vr::Mat4f transform;
994 vr::MatrixMul(view_proj_matrix, rect->TransformMatrix(), &transform); 989 vr::MatrixMul(view_proj_matrix, rect->TransformMatrix(), &transform);
995 990
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
1093 vr::TranslateM(mat, target_point - kOrigin, &mat); 1088 vr::TranslateM(mat, target_point - kOrigin, &mat);
1094 1089
1095 vr::Mat4f transform; 1090 vr::Mat4f transform;
1096 vr::MatrixMul(render_matrix, mat, &transform); 1091 vr::MatrixMul(render_matrix, mat, &transform);
1097 vr_shell_renderer_->GetReticleRenderer()->Draw(transform); 1092 vr_shell_renderer_->GetReticleRenderer()->Draw(transform);
1098 1093
1099 // Draw the laser. 1094 // Draw the laser.
1100 1095
1101 // Find the length of the beam (from hand to target). 1096 // Find the length of the beam (from hand to target).
1102 const float laser_length = 1097 const float laser_length =
1103 std::sqrt(kHandPosition.SquaredDistanceTo(target_point)); 1098 std::sqrt(pointer_start_.SquaredDistanceTo(target_point));
1104 1099
1105 // Build a beam, originating from the origin. 1100 // Build a beam, originating from the origin.
1106 vr::SetIdentityM(&mat); 1101 vr::SetIdentityM(&mat);
1107 1102
1108 // Move the beam half its height so that its end sits on the origin. 1103 // Move the beam half its height so that its end sits on the origin.
1109 vr::TranslateM(mat, {0.0f, 0.5f, 0.0f}, &mat); 1104 vr::TranslateM(mat, {0.0f, 0.5f, 0.0f}, &mat);
1110 vr::ScaleM(mat, {kLaserWidth, laser_length, 1}, &mat); 1105 vr::ScaleM(mat, {kLaserWidth, laser_length, 1}, &mat);
1111 1106
1112 // Tip back 90 degrees to flat, pointing at the scene. 1107 // Tip back 90 degrees to flat, pointing at the scene.
1113 const vr::Quatf quat = vr::QuatFromAxisAngle({1.0f, 0.0f, 0.0f, -M_PI / 2}); 1108 const vr::Quatf quat = vr::QuatFromAxisAngle({1.0f, 0.0f, 0.0f, -M_PI / 2});
1114 vr::QuatToMatrix(quat, &rotation_mat); 1109 vr::QuatToMatrix(quat, &rotation_mat);
1115 vr::MatrixMul(rotation_mat, mat, &mat); 1110 vr::MatrixMul(rotation_mat, mat, &mat);
1116 1111
1117 const gfx::Vector3dF beam_direction = target_point_ - kHandPosition; 1112 const gfx::Vector3dF beam_direction = target_point_ - pointer_start_;
1118 1113
1119 vr::Mat4f beam_direction_mat; 1114 vr::Mat4f beam_direction_mat;
1120 vr::QuatToMatrix(GetRotationFromZAxis(beam_direction), &beam_direction_mat); 1115 vr::QuatToMatrix(GetRotationFromZAxis(beam_direction), &beam_direction_mat);
1121 1116
1117 float opacity = controller_->GetOpacity();
1122 // Render multiple faces to make the laser appear cylindrical. 1118 // Render multiple faces to make the laser appear cylindrical.
1123 const int faces = 4; 1119 const int faces = 4;
1124 for (int i = 0; i < faces; i++) { 1120 for (int i = 0; i < faces; i++) {
1125 // Rotate around Z. 1121 // Rotate around Z.
1126 const float angle = M_PI * 2 * i / faces; 1122 const float angle = M_PI * 2 * i / faces;
1127 const vr::Quatf rot = vr::QuatFromAxisAngle({0.0f, 0.0f, 1.0f, angle}); 1123 const vr::Quatf rot = vr::QuatFromAxisAngle({0.0f, 0.0f, 1.0f, angle});
1128 vr::Mat4f face_transform; 1124 vr::Mat4f face_transform;
1129 vr::QuatToMatrix(rot, &face_transform); 1125 vr::QuatToMatrix(rot, &face_transform);
1130 vr::MatrixMul(face_transform, mat, &face_transform); 1126 vr::MatrixMul(face_transform, mat, &face_transform);
1131 // Orient according to target direction. 1127 // Orient according to target direction.
1132 vr::MatrixMul(beam_direction_mat, face_transform, &face_transform); 1128 vr::MatrixMul(beam_direction_mat, face_transform, &face_transform);
1133 1129
1134 // Move the beam origin to the hand. 1130 // Move the beam origin to the hand.
1135 vr::TranslateM(face_transform, kHandPosition - kOrigin, &face_transform); 1131 vr::TranslateM(face_transform, pointer_start_ - kOrigin, &face_transform);
1136 1132
1137 vr::MatrixMul(render_matrix, face_transform, &transform); 1133 vr::MatrixMul(render_matrix, face_transform, &transform);
1138 vr_shell_renderer_->GetLaserRenderer()->Draw(transform); 1134 vr_shell_renderer_->GetLaserRenderer()->Draw(opacity, transform);
1139 } 1135 }
1140 } 1136 }
1141 1137
1142 void VrShellGl::DrawController(const vr::Mat4f& view_proj_matrix) { 1138 void VrShellGl::DrawController(const vr::Mat4f& view_proj_matrix) {
1143 if (!vr_shell_renderer_->GetControllerRenderer()->IsSetUp()) 1139 if (!vr_shell_renderer_->GetControllerRenderer()->IsSetUp())
1144 return; 1140 return;
1141 auto state = controller_->GetModelState();
1142 auto opacity = controller_->GetOpacity();
1145 vr::Mat4f controller_transform; 1143 vr::Mat4f controller_transform;
1146 controller_->GetTransform(&controller_transform); 1144 controller_->GetTransform(&controller_transform);
1147 vr::Mat4f transform; 1145 vr::Mat4f transform;
1148 vr::MatrixMul(view_proj_matrix, controller_transform, &transform); 1146 vr::MatrixMul(view_proj_matrix, controller_transform, &transform);
1149 auto state = controller_->GetModelState(); 1147 vr_shell_renderer_->GetControllerRenderer()->Draw(state, opacity, transform);
1150 vr_shell_renderer_->GetControllerRenderer()->Draw(state, transform);
1151 } 1148 }
1152 1149
1153 bool VrShellGl::ShouldDrawWebVr() { 1150 bool VrShellGl::ShouldDrawWebVr() {
1154 return web_vr_mode_ && scene_->GetWebVrRenderingEnabled(); 1151 return web_vr_mode_ && scene_->GetWebVrRenderingEnabled();
1155 } 1152 }
1156 1153
1157 void VrShellGl::DrawWebVr() { 1154 void VrShellGl::DrawWebVr() {
1158 TRACE_EVENT0("gpu", "VrShellGl::DrawWebVr"); 1155 TRACE_EVENT0("gpu", "VrShellGl::DrawWebVr");
1159 // Don't need face culling, depth testing, blending, etc. Turn it all off. 1156 // Don't need face culling, depth testing, blending, etc. Turn it all off.
1160 glDisable(GL_CULL_FACE); 1157 glDisable(GL_CULL_FACE);
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after
1325 // InitializeGl. Revisit if the initialization order changes. 1322 // InitializeGl. Revisit if the initialization order changes.
1326 device::mojom::VRDisplayInfoPtr info = 1323 device::mojom::VRDisplayInfoPtr info =
1327 device::GvrDelegate::CreateVRDisplayInfo(gvr_api_.get(), 1324 device::GvrDelegate::CreateVRDisplayInfo(gvr_api_.get(),
1328 webvr_surface_size_, device_id); 1325 webvr_surface_size_, device_id);
1329 main_thread_task_runner_->PostTask( 1326 main_thread_task_runner_->PostTask(
1330 FROM_HERE, 1327 FROM_HERE,
1331 base::Bind(&RunVRDisplayInfoCallback, callback, base::Passed(&info))); 1328 base::Bind(&RunVRDisplayInfoCallback, callback, base::Passed(&info)));
1332 } 1329 }
1333 1330
1334 } // namespace vr_shell 1331 } // namespace vr_shell
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698