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

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: nit 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
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 438 matching lines...) Expand 10 before | Expand all | Expand 10 after
507 webvr_right_viewport_.reset( 500 webvr_right_viewport_.reset(
508 new gvr::BufferViewport(gvr_api_->CreateBufferViewport())); 501 new gvr::BufferViewport(gvr_api_->CreateBufferViewport()));
509 buffer_viewport_list_->GetBufferViewport(GVR_RIGHT_EYE, 502 buffer_viewport_list_->GetBufferViewport(GVR_RIGHT_EYE,
510 webvr_right_viewport_.get()); 503 webvr_right_viewport_.get());
511 webvr_right_viewport_->SetSourceBufferIndex(kFramePrimaryBuffer); 504 webvr_right_viewport_->SetSourceBufferIndex(kFramePrimaryBuffer);
512 505
513 main_thread_task_runner_->PostTask( 506 main_thread_task_runner_->PostTask(
514 FROM_HERE, base::Bind(&VrShell::GvrDelegateReady, weak_vr_shell_)); 507 FROM_HERE, base::Bind(&VrShell::GvrDelegateReady, weak_vr_shell_));
515 } 508 }
516 509
517 void VrShellGl::UpdateController() { 510 void VrShellGl::UpdateController(const gfx::Vector3dF& head_direction) {
518 controller_->UpdateState(); 511 controller_->UpdateState(head_direction);
512 pointer_start_ = controller_->GetPointerStart();
519 513
520 device::GvrGamepadData pad = controller_->GetGamepadData(); 514 device::GvrGamepadData pad = controller_->GetGamepadData();
521 main_thread_task_runner_->PostTask( 515 main_thread_task_runner_->PostTask(
522 FROM_HERE, base::Bind(&VrShell::UpdateGamepadData, weak_vr_shell_, pad)); 516 FROM_HERE, base::Bind(&VrShell::UpdateGamepadData, weak_vr_shell_, pad));
523 } 517 }
524 518
525 void VrShellGl::HandleControllerInput(const gfx::Vector3dF& forward_vector) { 519 void VrShellGl::HandleControllerInput(const gfx::Vector3dF& head_direction) {
526 if (ShouldDrawWebVr()) { 520 if (ShouldDrawWebVr()) {
527 // Process screen touch events for Cardboard button compatibility. 521 // Process screen touch events for Cardboard button compatibility.
528 // Also send tap events for controller "touchpad click" events. 522 // Also send tap events for controller "touchpad click" events.
529 if (touch_pending_ || 523 if (touch_pending_ ||
530 controller_->ButtonUpHappened( 524 controller_->ButtonUpHappened(
531 gvr::ControllerButton::GVR_CONTROLLER_BUTTON_CLICK)) { 525 gvr::ControllerButton::GVR_CONTROLLER_BUTTON_CLICK)) {
532 touch_pending_ = false; 526 touch_pending_ = false;
533 std::unique_ptr<WebGestureEvent> gesture(new WebGestureEvent( 527 std::unique_ptr<WebGestureEvent> gesture(new WebGestureEvent(
534 WebInputEvent::kGestureTapDown, WebInputEvent::kNoModifiers, 528 WebInputEvent::kGestureTapDown, WebInputEvent::kNoModifiers,
535 (base::TimeTicks::Now() - base::TimeTicks()).InSecondsF())); 529 (base::TimeTicks::Now() - base::TimeTicks()).InSecondsF()));
536 gesture->source_device = blink::kWebGestureDeviceTouchpad; 530 gesture->source_device = blink::kWebGestureDeviceTouchpad;
537 gesture->x = 0; 531 gesture->x = 0;
538 gesture->y = 0; 532 gesture->y = 0;
539 SendGesture(InputTarget::CONTENT, std::move(gesture)); 533 SendGesture(InputTarget::CONTENT, std::move(gesture));
540 DVLOG(1) << __FUNCTION__ << ": sent CLICK gesture"; 534 DVLOG(1) << __FUNCTION__ << ": sent CLICK gesture";
541 } 535 }
542 } 536 }
543 537
544 gfx::Vector3dF ergo_neutral_pose; 538 gfx::Vector3dF ergo_neutral_pose;
545 if (!controller_->IsConnected()) { 539 if (!controller_->IsConnected()) {
546 // No controller detected, set up a gaze cursor that tracks the 540 // No controller detected, set up a gaze cursor that tracks the
547 // forward direction. 541 // forward direction.
548 ergo_neutral_pose = {0.0f, 0.0f, -1.0f}; 542 ergo_neutral_pose = {0.0f, 0.0f, -1.0f};
549 controller_quat_ = GetRotationFromZAxis(forward_vector); 543 controller_quat_ = GetRotationFromZAxis(head_direction);
550 } else { 544 } else {
551 ergo_neutral_pose = {0.0f, -sin(kErgoAngleOffset), -cos(kErgoAngleOffset)}; 545 ergo_neutral_pose = {0.0f, -sin(kErgoAngleOffset), -cos(kErgoAngleOffset)};
552 controller_quat_ = controller_->Orientation(); 546 controller_quat_ = controller_->Orientation();
553 } 547 }
554 548
555 vr::Mat4f mat; 549 vr::Mat4f mat;
556 QuatToMatrix(controller_quat_, &mat); 550 QuatToMatrix(controller_quat_, &mat);
557 gfx::Vector3dF controller_direction = 551 gfx::Vector3dF controller_direction =
558 vr::MatrixVectorMul(mat, ergo_neutral_pose); 552 vr::MatrixVectorMul(mat, ergo_neutral_pose);
559 553
(...skipping 12 matching lines...) Expand all
572 // - Create a vector between the eyes and the outer surface point. 566 // - Create a vector between the eyes and the outer surface point.
573 // - If any UI elements intersect this vector, and is within the bounding 567 // - If any UI elements intersect this vector, and is within the bounding
574 // sphere, choose the closest to the eyes, and place the reticle at the 568 // sphere, choose the closest to the eyes, and place the reticle at the
575 // intersection point. 569 // intersection point.
576 570
577 // Compute the distance from the eyes to the distance limiting sphere. Note 571 // Compute the distance from the eyes to the distance limiting sphere. Note
578 // that the sphere is centered at the controller, rather than the eye, for 572 // that the sphere is centered at the controller, rather than the eye, for
579 // simplicity. 573 // simplicity.
580 float distance = scene_->GetBackgroundDistance(); 574 float distance = scene_->GetBackgroundDistance();
581 target_point_ = 575 target_point_ =
582 vr::GetRayPoint(kHandPosition, controller_direction, distance); 576 vr::GetRayPoint(pointer_start_, controller_direction, distance);
583 gfx::Vector3dF eye_to_target = target_point_ - kOrigin; 577 gfx::Vector3dF eye_to_target = target_point_ - kOrigin;
584 vr::NormalizeVector(&eye_to_target); 578 vr::NormalizeVector(&eye_to_target);
585 579
586 // Determine which UI element (if any) intersects the line between the eyes 580 // Determine which UI element (if any) intersects the line between the eyes
587 // and the controller target position. 581 // and the controller target position.
588 float closest_element_distance = (target_point_ - kOrigin).Length(); 582 float closest_element_distance = (target_point_ - kOrigin).Length();
589 target_element_ = nullptr; 583 target_element_ = nullptr;
590 float target_x; 584 float target_x;
591 float target_y; 585 float target_y;
592 586
(...skipping 266 matching lines...) Expand 10 before | Expand all | Expand 10 after
859 device::GvrDelegate::GetGvrPoseWithNeckModel(gvr_api_.get(), &head_pose); 853 device::GvrDelegate::GetGvrPoseWithNeckModel(gvr_api_.get(), &head_pose);
860 } 854 }
861 855
862 // Update the render position of all UI elements (including desktop). 856 // Update the render position of all UI elements (including desktop).
863 scene_->UpdateTransforms(current_time); 857 scene_->UpdateTransforms(current_time);
864 858
865 { 859 {
866 // TODO(crbug.com/704690): Acquire controller state in a way that's timely 860 // TODO(crbug.com/704690): Acquire controller state in a way that's timely
867 // for both the gamepad API and UI input handling. 861 // for both the gamepad API and UI input handling.
868 TRACE_EVENT0("gpu", "VrShellGl::UpdateController"); 862 TRACE_EVENT0("gpu", "VrShellGl::UpdateController");
869 UpdateController(); 863 auto head_direction = vr::GetForwardVector(head_pose);
870 HandleControllerInput(vr::GetForwardVector(head_pose)); 864 UpdateController(head_direction);
865 HandleControllerInput(head_direction);
871 } 866 }
872 867
873 DrawWorldElements(head_pose); 868 DrawWorldElements(head_pose);
874 869
875 frame.Unbind(); 870 frame.Unbind();
876 871
877 // Draw head-locked elements to a separate, non-reprojected buffer. 872 // Draw head-locked elements to a separate, non-reprojected buffer.
878 if (scene_->HasVisibleHeadLockedElements()) { 873 if (scene_->HasVisibleHeadLockedElements()) {
879 frame.BindBuffer(kFrameHeadlockedBuffer); 874 frame.BindBuffer(kFrameHeadlockedBuffer);
880 DrawHeadLockedElements(); 875 DrawHeadLockedElements();
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
976 vr::Mat4f render_matrix; 971 vr::Mat4f render_matrix;
977 vr::Mat4f perspective_matrix; 972 vr::Mat4f perspective_matrix;
978 GvrMatToMatf(PerspectiveMatrixFromView(buffer_viewport_->GetSourceFov(), 973 GvrMatToMatf(PerspectiveMatrixFromView(buffer_viewport_->GetSourceFov(),
979 kZNear, kZFar), 974 kZNear, kZFar),
980 &perspective_matrix); 975 &perspective_matrix);
981 976
982 vr::MatrixMul(perspective_matrix, eye_view_matrix, &render_matrix); 977 vr::MatrixMul(perspective_matrix, eye_view_matrix, &render_matrix);
983 978
984 DrawElements(render_matrix, elementsInDrawOrder); 979 DrawElements(render_matrix, elementsInDrawOrder);
985 if (draw_cursor) { 980 if (draw_cursor) {
981 DrawController(render_matrix);
986 DrawCursor(render_matrix); 982 DrawCursor(render_matrix);
987 DrawController(render_matrix);
988 } 983 }
989 } 984 }
990 } 985 }
991 986
992 void VrShellGl::DrawElements(const vr::Mat4f& view_proj_matrix, 987 void VrShellGl::DrawElements(const vr::Mat4f& view_proj_matrix,
993 const std::vector<const UiElement*>& elements) { 988 const std::vector<const UiElement*>& elements) {
994 for (const auto* rect : elements) { 989 for (const auto* rect : elements) {
995 vr::Mat4f transform; 990 vr::Mat4f transform;
996 vr::MatrixMul(view_proj_matrix, rect->TransformMatrix(), &transform); 991 vr::MatrixMul(view_proj_matrix, rect->TransformMatrix(), &transform);
997 992
(...skipping 95 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
« no previous file with comments | « chrome/browser/android/vr_shell/vr_shell_gl.h ('k') | chrome/browser/android/vr_shell/vr_shell_renderer.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698