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

Unified Diff: chrome/browser/android/vr_shell/vr_shell.cc

Issue 2392023002: VrShell: Restore smooth reticle positioning in the user FOV. (Closed)
Patch Set: Fix comment nits. Created 4 years, 2 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chrome/browser/android/vr_shell/vr_shell.cc
diff --git a/chrome/browser/android/vr_shell/vr_shell.cc b/chrome/browser/android/vr_shell/vr_shell.cc
index 6bf4311be0d4b793a9d418e12f8b72f80c90fc24..d84ecfa63230ef1e58b8ba03a6a04415cb4a1313 100644
--- a/chrome/browser/android/vr_shell/vr_shell.cc
+++ b/chrome/browser/android/vr_shell/vr_shell.cc
@@ -67,7 +67,7 @@ static constexpr gvr::Vec3f kHandPosition = {0.2f, -0.5f, -0.2f};
static constexpr float kReticleOffset = 0.99f;
// Limit the rendering distance of the reticle to the distance to a corner of
-// the content quad, times this value. This lets the rendering distance
+// the content quad, times this value. This lets the rendering distance
// adjust according to content quad placement.
static constexpr float kReticleDistanceMultiplier = 1.5f;
@@ -87,7 +87,7 @@ float Distance(const gvr::Vec3f& vec1, const gvr::Vec3f& vec2) {
}
// Generate a quaternion representing the rotation from the negative Z axis
-// (0, 0, -1) to a specified vector. This is an optimized version of a more
+// (0, 0, -1) to a specified vector. This is an optimized version of a more
// general vector-to-vector calculation.
gvr::Quatf GetRotationFromZAxis(gvr::Vec3f vec) {
vr_shell::NormalizeVector(vec);
@@ -240,12 +240,22 @@ void VrShell::UpdateController(const gvr::Vec3f& forward_vector) {
float distance = scene_.GetUiElementById(kBrowserUiElementId)
->GetRayDistance(origin, forward);
+ // If we place the reticle based on elements intersecting the controller beam,
+ // we can end up with the reticle hiding behind elements, or jumping laterally
+ // in the field of view. This is physically correct, but hard to use. For
+ // usability, do the following instead:
+ //
+ // - Project the controller laser onto an outer surface, which is the
+ // closer of the desktop plane, or a distance-limiting sphere.
+ // - Create a vector between the eyes and the outer surface point.
+ // - If any UI elements intersect this vector, choose the closest to the eyes,
+ // and place the reticle at the intersection point.
+
// Find distance to a corner of the content quad, and limit the cursor
- // distance to a multiple of that distance. This lets us keep the reticle on
+ // distance to a multiple of that distance. This lets us keep the reticle on
// the content plane near the content window, and on the surface of a sphere
- // in other directions.
- // TODO(cjgrant): Note that this approach uses distance from controller,
- // rather than eye, for simplicity. This will make the sphere slightly
+ // in other directions. Note that this approach uses distance from controller,
+ // rather than eye, for simplicity. This will make the sphere slightly
// off-center.
gvr::Vec3f corner = {0.5f, 0.5f, 0.0f};
corner = MatrixVectorMul(desktop_plane_->transform.to_world, corner);
@@ -254,8 +264,11 @@ void VrShell::UpdateController(const gvr::Vec3f& forward_vector) {
distance = max_distance;
}
target_point_ = GetRayPoint(origin, forward, distance);
+ gvr::Vec3f eye_to_target = target_point_;
+ NormalizeVector(eye_to_target);
- // Determine which UI element (if any) the cursor is pointing to.
+ // Determine which UI element (if any) intersects the line between the eyes
+ // and the controller target position.
float closest_element_distance = std::numeric_limits<float>::infinity();
int pixel_x = 0;
int pixel_y = 0;
@@ -266,15 +279,15 @@ void VrShell::UpdateController(const gvr::Vec3f& forward_vector) {
if (!plane.visible) {
continue;
}
- float distance_to_plane = plane.GetRayDistance(origin, forward);
+ float distance_to_plane = plane.GetRayDistance(kOrigin, eye_to_target);
gvr::Vec3f plane_intersection_point =
- GetRayPoint(origin, forward, distance_to_plane);
+ GetRayPoint(kOrigin, eye_to_target, distance_to_plane);
gvr::Vec3f rect_2d_point =
MatrixVectorMul(plane.transform.from_world, plane_intersection_point);
- float x = rect_2d_point.x + 0.5f;
- float y = 0.5f - rect_2d_point.y;
if (distance_to_plane > 0 && distance_to_plane < closest_element_distance) {
+ float x = rect_2d_point.x + 0.5f;
+ float y = 0.5f - rect_2d_point.y;
bool is_inside = x >= 0.0f && x < 1.0f && y >= 0.0f && y < 1.0f;
if (is_inside) {
closest_element_distance = distance_to_plane;
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698