| 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 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 50 | 50 |
| 51 // Angle (radians) the beam down from the controller axis, for wrist comfort. | 51 // Angle (radians) the beam down from the controller axis, for wrist comfort. |
| 52 static constexpr float kErgoAngleOffset = 0.26f; | 52 static constexpr float kErgoAngleOffset = 0.26f; |
| 53 | 53 |
| 54 static constexpr gvr::Vec3f kOrigin = {0.0f, 0.0f, 0.0f}; | 54 static constexpr gvr::Vec3f kOrigin = {0.0f, 0.0f, 0.0f}; |
| 55 | 55 |
| 56 // In lieu of an elbow model, we assume a position for the user's hand. | 56 // In lieu of an elbow model, we assume a position for the user's hand. |
| 57 // TODO(mthiesse): Handedness options. | 57 // TODO(mthiesse): Handedness options. |
| 58 static constexpr gvr::Vec3f kHandPosition = {0.2f, -0.5f, -0.2f}; | 58 static constexpr gvr::Vec3f kHandPosition = {0.2f, -0.5f, -0.2f}; |
| 59 | 59 |
| 60 // If there is no content quad, and the reticle isn't hitting another element, | |
| 61 // draw the reticle at this distance. | |
| 62 static constexpr float kDefaultReticleDistance = 2.0f; | |
| 63 | |
| 64 // Fraction of the distance to the object the cursor is drawn at to avoid | 60 // Fraction of the distance to the object the cursor is drawn at to avoid |
| 65 // rounding errors drawing the cursor behind the object. | 61 // rounding errors drawing the cursor behind the object. |
| 66 static constexpr float kReticleOffset = 0.99f; | 62 static constexpr float kReticleOffset = 0.99f; |
| 67 | 63 |
| 68 // Limit the rendering distance of the reticle to the distance to a corner of | |
| 69 // the content quad, times this value. This lets the rendering distance | |
| 70 // adjust according to content quad placement. | |
| 71 static constexpr float kReticleDistanceMultiplier = 1.5f; | |
| 72 | |
| 73 // GVR buffer indices for use with viewport->SetSourceBufferIndex | 64 // GVR buffer indices for use with viewport->SetSourceBufferIndex |
| 74 // or frame.BindBuffer. We use one for world content (with reprojection) | 65 // or frame.BindBuffer. We use one for world content (with reprojection) |
| 75 // including main VrShell and WebVR content plus world-space UI. | 66 // including main VrShell and WebVR content plus world-space UI. |
| 76 // The headlocked buffer is for UI that should not use reprojection. | 67 // The headlocked buffer is for UI that should not use reprojection. |
| 77 static constexpr int kFramePrimaryBuffer = 0; | 68 static constexpr int kFramePrimaryBuffer = 0; |
| 78 static constexpr int kFrameHeadlockedBuffer = 1; | 69 static constexpr int kFrameHeadlockedBuffer = 1; |
| 79 | 70 |
| 80 // Pixel dimensions and field of view for the head-locked content. This | 71 // Pixel dimensions and field of view for the head-locked content. This |
| 81 // is currently sized to fit the WebVR "insecure transport" warnings, | 72 // is currently sized to fit the WebVR "insecure transport" warnings, |
| 82 // adjust it as needed if there is additional content. | 73 // adjust it as needed if there is additional content. |
| (...skipping 381 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 464 | 455 |
| 465 gvr::Mat4f mat = QuatToMatrix(controller_quat_); | 456 gvr::Mat4f mat = QuatToMatrix(controller_quat_); |
| 466 gvr::Vec3f forward = MatrixVectorMul(mat, ergo_neutral_pose); | 457 gvr::Vec3f forward = MatrixVectorMul(mat, ergo_neutral_pose); |
| 467 gvr::Vec3f origin = kHandPosition; | 458 gvr::Vec3f origin = kHandPosition; |
| 468 | 459 |
| 469 // If we place the reticle based on elements intersecting the controller beam, | 460 // If we place the reticle based on elements intersecting the controller beam, |
| 470 // we can end up with the reticle hiding behind elements, or jumping laterally | 461 // we can end up with the reticle hiding behind elements, or jumping laterally |
| 471 // in the field of view. This is physically correct, but hard to use. For | 462 // in the field of view. This is physically correct, but hard to use. For |
| 472 // usability, do the following instead: | 463 // usability, do the following instead: |
| 473 // | 464 // |
| 474 // - Project the controller laser onto an outer surface, which is the | 465 // - Project the controller laser onto a distance-limiting sphere. |
| 475 // closer of the desktop plane, or a distance-limiting sphere. | |
| 476 // - Create a vector between the eyes and the outer surface point. | 466 // - Create a vector between the eyes and the outer surface point. |
| 477 // - If any UI elements intersect this vector, choose the closest to the eyes, | 467 // - If any UI elements intersect this vector, and is within the bounding |
| 478 // and place the reticle at the intersection point. | 468 // sphere, choose the closest to the eyes, and place the reticle at the |
| 469 // intersection point. |
| 479 | 470 |
| 480 // Find distance to a corner of the content quad, and limit the cursor | 471 // Compute the distance from the eyes to the distance limiting sphere. Note |
| 481 // distance to a multiple of that distance. This lets us keep the reticle on | 472 // that the sphere is centered at the controller, rather than the eye, for |
| 482 // the content plane near the content window, and on the surface of a sphere | 473 // simplicity. |
| 483 // in other directions. Note that this approach uses distance from controller, | 474 float distance = scene_->GetBackgroundDistance(); |
| 484 // rather than eye, for simplicity. This will make the sphere slightly | |
| 485 // off-center. | |
| 486 float distance = kDefaultReticleDistance; | |
| 487 ContentRectangle* content_plane = scene_->GetContentQuad(); | |
| 488 if (content_plane) { | |
| 489 distance = content_plane->GetRayDistance(origin, forward); | |
| 490 gvr::Vec3f corner = {0.5f, 0.5f, 0.0f}; | |
| 491 corner = MatrixVectorMul(content_plane->transform.to_world, corner); | |
| 492 float max_distance = Distance(origin, corner) * kReticleDistanceMultiplier; | |
| 493 if (distance > max_distance || distance <= 0.0f) { | |
| 494 distance = max_distance; | |
| 495 } | |
| 496 } | |
| 497 | |
| 498 target_point_ = GetRayPoint(origin, forward, distance); | 475 target_point_ = GetRayPoint(origin, forward, distance); |
| 499 gvr::Vec3f eye_to_target = target_point_; | 476 gvr::Vec3f eye_to_target = target_point_; |
| 500 NormalizeVector(eye_to_target); | 477 NormalizeVector(eye_to_target); |
| 501 | 478 |
| 502 // Determine which UI element (if any) intersects the line between the eyes | 479 // Determine which UI element (if any) intersects the line between the eyes |
| 503 // and the controller target position. | 480 // and the controller target position. |
| 504 float closest_element_distance = std::numeric_limits<float>::infinity(); | 481 float closest_element_distance = VectorLength(target_point_); |
| 505 int pixel_x = 0; | 482 int pixel_x = 0; |
| 506 int pixel_y = 0; | 483 int pixel_y = 0; |
| 507 target_element_ = nullptr; | 484 target_element_ = nullptr; |
| 508 | 485 |
| 509 for (const auto& plane : scene_->GetUiElements()) { | 486 for (const auto& plane : scene_->GetUiElements()) { |
| 510 if (!plane->IsHitTestable()) | 487 if (!plane->IsHitTestable()) |
| 511 continue; | 488 continue; |
| 512 | 489 |
| 513 float distance_to_plane = plane->GetRayDistance(kOrigin, eye_to_target); | 490 float distance_to_plane = plane->GetRayDistance(kOrigin, eye_to_target); |
| 514 gvr::Vec3f plane_intersection_point = | 491 gvr::Vec3f plane_intersection_point = |
| (...skipping 657 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1172 const base::Callback<void(device::mojom::VRDisplayInfoPtr)>& callback, | 1149 const base::Callback<void(device::mojom::VRDisplayInfoPtr)>& callback, |
| 1173 uint32_t device_id) { | 1150 uint32_t device_id) { |
| 1174 device::mojom::VRDisplayInfoPtr info = VrShell::CreateVRDisplayInfo( | 1151 device::mojom::VRDisplayInfoPtr info = VrShell::CreateVRDisplayInfo( |
| 1175 gvr_api_.get(), content_tex_physical_size_, device_id); | 1152 gvr_api_.get(), content_tex_physical_size_, device_id); |
| 1176 main_thread_task_runner_->PostTask( | 1153 main_thread_task_runner_->PostTask( |
| 1177 FROM_HERE, | 1154 FROM_HERE, |
| 1178 base::Bind(&RunVRDisplayInfoCallback, callback, base::Passed(&info))); | 1155 base::Bind(&RunVRDisplayInfoCallback, callback, base::Passed(&info))); |
| 1179 } | 1156 } |
| 1180 | 1157 |
| 1181 } // namespace vr_shell | 1158 } // namespace vr_shell |
| OLD | NEW |