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.h" | 5 #include "chrome/browser/android/vr_shell/vr_shell.h" |
| 6 | 6 |
| 7 #include "chrome/browser/android/vr_shell/ui_scene.h" | 7 #include "chrome/browser/android/vr_shell/ui_scene.h" |
| 8 #include "chrome/browser/android/vr_shell/vr_compositor.h" | 8 #include "chrome/browser/android/vr_shell/vr_compositor.h" |
| 9 #include "chrome/browser/android/vr_shell/vr_controller.h" | 9 #include "chrome/browser/android/vr_shell/vr_controller.h" |
| 10 #include "chrome/browser/android/vr_shell/vr_gl_util.h" | 10 #include "chrome/browser/android/vr_shell/vr_gl_util.h" |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 42 static constexpr float kDesktopScreenTiltDefault = 0; | 42 static constexpr float kDesktopScreenTiltDefault = 0; |
| 43 | 43 |
| 44 static constexpr float kScreenHeightRatio = 1.0f; | 44 static constexpr float kScreenHeightRatio = 1.0f; |
| 45 static constexpr float kScreenWidthRatio = 16.0f / 9.0f; | 45 static constexpr float kScreenWidthRatio = 16.0f / 9.0f; |
| 46 | 46 |
| 47 static constexpr float kReticleWidth = 0.025f; | 47 static constexpr float kReticleWidth = 0.025f; |
| 48 static constexpr float kReticleHeight = 0.025f; | 48 static constexpr float kReticleHeight = 0.025f; |
| 49 | 49 |
| 50 static constexpr float kLaserWidth = 0.01f; | 50 static constexpr float kLaserWidth = 0.01f; |
| 51 | 51 |
| 52 // The neutral direction is fixed in world space, this is the | 52 // Angle (radians) the beam down from the controller axis, for wrist comfort. |
| 53 // reference angle pointing forward towards the horizon when the | 53 static constexpr float kErgoAngleOffset = 0.26f; |
| 54 // controller orientation is reset. This should match the yaw angle | |
| 55 // where the main screen is placed. | |
| 56 static constexpr gvr::Vec3f kNeutralPose = {0.0f, 0.0f, -1.0f}; | |
| 57 | 54 |
| 58 static constexpr gvr::Vec3f kOrigin = {0.0f, 0.0f, 0.0f}; | 55 static constexpr gvr::Vec3f kOrigin = {0.0f, 0.0f, 0.0f}; |
| 59 | 56 |
| 60 // In lieu of an elbow model, we assume a position for the user's hand. | 57 // In lieu of an elbow model, we assume a position for the user's hand. |
| 61 // TODO(mthiesse): Handedness options. | 58 // TODO(mthiesse): Handedness options. |
| 62 static constexpr gvr::Vec3f kHandPosition = {0.2f, -0.5f, -0.2f}; | 59 static constexpr gvr::Vec3f kHandPosition = {0.2f, -0.5f, -0.2f}; |
| 63 | 60 |
| 64 // Fraction of the distance to the object the cursor is drawn at to avoid | 61 // Fraction of the distance to the object the cursor is drawn at to avoid |
| 65 // rounding errors drawing the cursor behind the object. | 62 // rounding errors drawing the cursor behind the object. |
| 66 static constexpr float kReticleOffset = 0.99f; | 63 static constexpr float kReticleOffset = 0.99f; |
| (...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 232 std::unique_ptr<VrGesture> gesture = controller_->DetectGesture(); | 229 std::unique_ptr<VrGesture> gesture = controller_->DetectGesture(); |
| 233 | 230 |
| 234 // TODO(asimjour) for now, scroll is sent to the main content. | 231 // TODO(asimjour) for now, scroll is sent to the main content. |
| 235 if (gesture->type == WebInputEvent::GestureScrollBegin || | 232 if (gesture->type == WebInputEvent::GestureScrollBegin || |
| 236 gesture->type == WebInputEvent::GestureScrollUpdate || | 233 gesture->type == WebInputEvent::GestureScrollUpdate || |
| 237 gesture->type == WebInputEvent::GestureScrollEnd) { | 234 gesture->type == WebInputEvent::GestureScrollEnd) { |
| 238 content_input_manager_->ProcessUpdatedGesture(*gesture.get()); | 235 content_input_manager_->ProcessUpdatedGesture(*gesture.get()); |
| 239 } | 236 } |
| 240 | 237 |
| 241 WebInputEvent::Type original_type = gesture->type; | 238 WebInputEvent::Type original_type = gesture->type; |
| 239 gvr::Vec3f ergo_neutral_pose; | |
| 242 if (!controller_->IsConnected()) { | 240 if (!controller_->IsConnected()) { |
| 243 // No controller detected, set up a gaze cursor that tracks the | 241 // No controller detected, set up a gaze cursor that tracks the |
| 244 // forward direction. | 242 // forward direction. |
| 243 ergo_neutral_pose = {0.0f, 0.0f, -1.0f}; | |
| 245 controller_quat_ = GetRotationFromZAxis(forward_vector); | 244 controller_quat_ = GetRotationFromZAxis(forward_vector); |
| 246 } else { | 245 } else { |
| 246 ergo_neutral_pose = {0.0f, -sin(kErgoAngleOffset), -cos(kErgoAngleOffset)}; | |
| 247 controller_quat_ = controller_->Orientation(); | 247 controller_quat_ = controller_->Orientation(); |
| 248 } | 248 } |
| 249 | 249 |
| 250 gvr::Mat4f mat = QuatToMatrix(controller_quat_); | 250 gvr::Mat4f mat = QuatToMatrix(controller_quat_); |
| 251 gvr::Vec3f forward = MatrixVectorMul(mat, kNeutralPose); | 251 gvr::Vec3f forward = MatrixVectorMul(mat, ergo_neutral_pose); |
| 252 gvr::Vec3f origin = kHandPosition; | 252 gvr::Vec3f origin = kHandPosition; |
| 253 | 253 |
| 254 target_element_ = nullptr; | 254 target_element_ = nullptr; |
| 255 float distance = scene_.GetUiElementById(kBrowserUiElementId) | 255 float distance = scene_.GetUiElementById(kBrowserUiElementId) |
| 256 ->GetRayDistance(origin, forward); | 256 ->GetRayDistance(origin, forward); |
| 257 | 257 |
| 258 // If we place the reticle based on elements intersecting the controller beam, | 258 // If we place the reticle based on elements intersecting the controller beam, |
| 259 // we can end up with the reticle hiding behind elements, or jumping laterally | 259 // we can end up with the reticle hiding behind elements, or jumping laterally |
| 260 // in the field of view. This is physically correct, but hard to use. For | 260 // in the field of view. This is physically correct, but hard to use. For |
| 261 // usability, do the following instead: | 261 // usability, do the following instead: |
| (...skipping 240 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 502 TranslateM(mat, mat, target_point_.x * kReticleOffset, | 502 TranslateM(mat, mat, target_point_.x * kReticleOffset, |
| 503 target_point_.y * kReticleOffset, | 503 target_point_.y * kReticleOffset, |
| 504 target_point_.z * kReticleOffset); | 504 target_point_.z * kReticleOffset); |
| 505 | 505 |
| 506 gvr::Mat4f transform = MatrixMul(render_matrix, mat); | 506 gvr::Mat4f transform = MatrixMul(render_matrix, mat); |
| 507 vr_shell_renderer_->GetReticleRenderer()->Draw(transform); | 507 vr_shell_renderer_->GetReticleRenderer()->Draw(transform); |
| 508 | 508 |
| 509 // Draw the laser. | 509 // Draw the laser. |
| 510 | 510 |
| 511 // Find the length of the beam (from hand to target). | 511 // Find the length of the beam (from hand to target). |
| 512 float laser_length = Distance(kHandPosition, target_point_); | 512 const float laser_length = Distance(kHandPosition, target_point_); |
| 513 | 513 |
| 514 // Build a beam, originating from the origin. | 514 // Build a beam, originating from the origin. |
| 515 SetIdentityM(mat); | 515 SetIdentityM(mat); |
| 516 | 516 |
| 517 // Move the beam half its height so that its end sits on the origin. | 517 // Move the beam half its height so that its end sits on the origin. |
| 518 TranslateM(mat, mat, 0.0f, 0.5f, 0.0f); | 518 TranslateM(mat, mat, 0.0f, 0.5f, 0.0f); |
| 519 ScaleM(mat, mat, kLaserWidth, laser_length, 1); | 519 ScaleM(mat, mat, kLaserWidth, laser_length, 1); |
| 520 | 520 |
| 521 // Tip back 90 degrees to flat, pointing at the scene. | 521 // Tip back 90 degrees to flat, pointing at the scene. |
| 522 auto q = QuatFromAxisAngle({1.0f, 0.0f, 0.0f}, -M_PI / 2); | 522 const gvr::Quatf q = QuatFromAxisAngle({1.0f, 0.0f, 0.0f}, -M_PI / 2); |
| 523 auto m = QuatToMatrix(q); | 523 mat = MatrixMul(QuatToMatrix(q), mat); |
| 524 mat = MatrixMul(m, mat); | |
| 525 | 524 |
| 526 // Orient according to controller position. | 525 const gvr::Vec3f beam_direction = { |
| 527 mat = MatrixMul(QuatToMatrix(controller_quat_), mat); | 526 target_point_.x - kHandPosition.x, |
| 527 target_point_.y - kHandPosition.y, | |
| 528 target_point_.z - kHandPosition.z | |
| 529 }; | |
| 530 const gvr::Mat4f beam_direction_mat = | |
|
cjgrant
2016/10/06 15:07:51
I was recomputing the matrix in the loop (needless
| |
| 531 QuatToMatrix(GetRotationFromZAxis(beam_direction)); | |
| 528 | 532 |
| 529 // Move the beam origin to the hand. | |
| 530 TranslateM(mat, mat, kHandPosition.x, kHandPosition.y, kHandPosition.z); | |
| 531 | 533 |
| 532 transform = MatrixMul(render_matrix, mat); | 534 // Render multiple faces to make the laser appear cylindrical. |
| 533 vr_shell_renderer_->GetLaserRenderer()->Draw(transform); | 535 const int faces = 4; |
| 536 for (int i = 0; i < faces; i++) { | |
| 537 // Rotate around Z. | |
| 538 const float angle = M_PI * 2 * i / faces; | |
| 539 const gvr::Quatf rot = QuatFromAxisAngle({0.0f, 0.0f, 1.0f}, angle); | |
| 540 gvr::Mat4f face_transform = MatrixMul(QuatToMatrix(rot), mat); | |
| 541 | |
| 542 // Orient according to target direction. | |
| 543 face_transform = MatrixMul(beam_direction_mat, face_transform); | |
| 544 | |
| 545 // Move the beam origin to the hand. | |
| 546 TranslateM(face_transform, face_transform, kHandPosition.x, kHandPosition.y, | |
| 547 kHandPosition.z); | |
| 548 | |
| 549 transform = MatrixMul(render_matrix, face_transform); | |
| 550 vr_shell_renderer_->GetLaserRenderer()->Draw(transform); | |
| 551 } | |
| 534 } | 552 } |
| 535 | 553 |
| 536 void VrShell::DrawWebVr() { | 554 void VrShell::DrawWebVr() { |
| 537 // Don't need face culling, depth testing, blending, etc. Turn it all off. | 555 // Don't need face culling, depth testing, blending, etc. Turn it all off. |
| 538 glDisable(GL_CULL_FACE); | 556 glDisable(GL_CULL_FACE); |
| 539 glDepthMask(GL_FALSE); | 557 glDepthMask(GL_FALSE); |
| 540 glDisable(GL_DEPTH_TEST); | 558 glDisable(GL_DEPTH_TEST); |
| 541 glDisable(GL_SCISSOR_TEST); | 559 glDisable(GL_SCISSOR_TEST); |
| 542 glDisable(GL_BLEND); | 560 glDisable(GL_BLEND); |
| 543 glDisable(GL_POLYGON_OFFSET_FILL); | 561 glDisable(GL_POLYGON_OFFSET_FILL); |
| (...skipping 248 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 792 content::WebContents::FromJavaWebContents(content_web_contents)); | 810 content::WebContents::FromJavaWebContents(content_web_contents)); |
| 793 content::ContentViewCore* ui_core = content::ContentViewCore::FromWebContents( | 811 content::ContentViewCore* ui_core = content::ContentViewCore::FromWebContents( |
| 794 content::WebContents::FromJavaWebContents(ui_web_contents)); | 812 content::WebContents::FromJavaWebContents(ui_web_contents)); |
| 795 return reinterpret_cast<intptr_t>(new VrShell( | 813 return reinterpret_cast<intptr_t>(new VrShell( |
| 796 env, obj, c_core, | 814 env, obj, c_core, |
| 797 reinterpret_cast<ui::WindowAndroid*>(content_window_android), ui_core, | 815 reinterpret_cast<ui::WindowAndroid*>(content_window_android), ui_core, |
| 798 reinterpret_cast<ui::WindowAndroid*>(ui_window_android))); | 816 reinterpret_cast<ui::WindowAndroid*>(ui_window_android))); |
| 799 } | 817 } |
| 800 | 818 |
| 801 } // namespace vr_shell | 819 } // namespace vr_shell |
| OLD | NEW |