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

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

Issue 2392023002: VrShell: Restore smooth reticle positioning in the user FOV. (Closed)
Patch Set: 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 unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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.h" 5 #include "chrome/browser/android/vr_shell/vr_shell.h"
6 6
7 #include <thread> 7 #include <thread>
8 8
9 #include "chrome/browser/android/vr_shell/ui_scene.h" 9 #include "chrome/browser/android/vr_shell/ui_scene.h"
10 #include "chrome/browser/android/vr_shell/vr_compositor.h" 10 #include "chrome/browser/android/vr_shell/vr_compositor.h"
(...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after
233 } 233 }
234 234
235 gvr::Mat4f mat = QuatToMatrix(controller_quat_); 235 gvr::Mat4f mat = QuatToMatrix(controller_quat_);
236 gvr::Vec3f forward = MatrixVectorMul(mat, kNeutralPose); 236 gvr::Vec3f forward = MatrixVectorMul(mat, kNeutralPose);
237 gvr::Vec3f origin = kHandPosition; 237 gvr::Vec3f origin = kHandPosition;
238 238
239 target_element_ = nullptr; 239 target_element_ = nullptr;
240 float distance = scene_.GetUiElementById(kBrowserUiElementId) 240 float distance = scene_.GetUiElementById(kBrowserUiElementId)
241 ->GetRayDistance(origin, forward); 241 ->GetRayDistance(origin, forward);
242 242
243 // If we place the reticle based on elements intersecting the controller beam,
244 // we can end up with the reticle hiding behind elements, or jumping laterally
245 // in the field of view. This is physically correct, but hard to use. For
246 // usability, do the following instead:
247 //
248 // - Project the controller laser onto an outer surface, which is the
249 // closer of the desktop plane, or a distance-limiting sphere.
250 // - Create a vector between the eyes and the outer surface point.
251 // - If any UI elements intersect this vector, choose the closest to the eyes,
252 // and place the reticle at the intersection point.
253
243 // Find distance to a corner of the content quad, and limit the cursor 254 // Find distance to a corner of the content quad, and limit the cursor
244 // distance to a multiple of that distance. This lets us keep the reticle on 255 // distance to a multiple of that distance. This lets us keep the reticle on
245 // the content plane near the content window, and on the surface of a sphere 256 // the content plane near the content window, and on the surface of a sphere
246 // in other directions. 257 // in other directions. Note that this approach uses distance from
bshe 2016/10/04 18:56:00 nit: remove extra space before "Note"
247 // TODO(cjgrant): Note that this approach uses distance from controller, 258 // controller, rather than eye, for simplicity. This will make the sphere
bshe 2016/10/04 18:56:00 nit: remove extra space before "This"
248 // rather than eye, for simplicity. This will make the sphere slightly 259 // slightly off-center.
249 // off-center.
250 gvr::Vec3f corner = {0.5f, 0.5f, 0.0f}; 260 gvr::Vec3f corner = {0.5f, 0.5f, 0.0f};
251 corner = MatrixVectorMul(desktop_plane_->transform.to_world, corner); 261 corner = MatrixVectorMul(desktop_plane_->transform.to_world, corner);
252 float max_distance = Distance(origin, corner) * kReticleDistanceMultiplier; 262 float max_distance = Distance(origin, corner) * kReticleDistanceMultiplier;
253 if (distance > max_distance || distance <= 0.0f) { 263 if (distance > max_distance || distance <= 0.0f) {
254 distance = max_distance; 264 distance = max_distance;
255 } 265 }
256 target_point_ = GetRayPoint(origin, forward, distance); 266 target_point_ = GetRayPoint(origin, forward, distance);
267 gvr::Vec3f eye_to_target = target_point_;
268 NormalizeVector(eye_to_target);
257 269
258 // Determine which UI element (if any) the cursor is pointing to. 270 // Determine which UI element (if any) intersects the line between the eyes
271 // and the controller target position.
259 float closest_element_distance = std::numeric_limits<float>::infinity(); 272 float closest_element_distance = std::numeric_limits<float>::infinity();
260 int pixel_x = 0; 273 int pixel_x = 0;
261 int pixel_y = 0; 274 int pixel_y = 0;
262 VrInputManager* input_target = nullptr; 275 VrInputManager* input_target = nullptr;
263 276
264 for (std::size_t i = 0; i < scene_.GetUiElements().size(); ++i) { 277 for (std::size_t i = 0; i < scene_.GetUiElements().size(); ++i) {
265 const ContentRectangle& plane = *scene_.GetUiElements()[i].get(); 278 const ContentRectangle& plane = *scene_.GetUiElements()[i].get();
266 if (!plane.visible) { 279 if (!plane.visible) {
267 continue; 280 continue;
268 } 281 }
269 float distance_to_plane = plane.GetRayDistance(origin, forward); 282 float distance_to_plane = plane.GetRayDistance(kOrigin, eye_to_target);
270 gvr::Vec3f plane_intersection_point = 283 gvr::Vec3f plane_intersection_point =
271 GetRayPoint(origin, forward, distance_to_plane); 284 GetRayPoint(kOrigin, eye_to_target, distance_to_plane);
272 285
273 gvr::Vec3f rect_2d_point = 286 gvr::Vec3f rect_2d_point =
274 MatrixVectorMul(plane.transform.from_world, plane_intersection_point); 287 MatrixVectorMul(plane.transform.from_world, plane_intersection_point);
275 float x = rect_2d_point.x + 0.5f;
276 float y = 0.5f - rect_2d_point.y;
277 if (distance_to_plane > 0 && distance_to_plane < closest_element_distance) { 288 if (distance_to_plane > 0 && distance_to_plane < closest_element_distance) {
289 float x = rect_2d_point.x + 0.5f;
290 float y = 0.5f - rect_2d_point.y;
278 bool is_inside = x >= 0.0f && x < 1.0f && y >= 0.0f && y < 1.0f; 291 bool is_inside = x >= 0.0f && x < 1.0f && y >= 0.0f && y < 1.0f;
279 if (is_inside) { 292 if (is_inside) {
280 closest_element_distance = distance_to_plane; 293 closest_element_distance = distance_to_plane;
281 pixel_x = 294 pixel_x =
282 static_cast<int>(plane.copy_rect.width * x + plane.copy_rect.x); 295 static_cast<int>(plane.copy_rect.width * x + plane.copy_rect.x);
283 pixel_y = 296 pixel_y =
284 static_cast<int>(plane.copy_rect.height * y + plane.copy_rect.y); 297 static_cast<int>(plane.copy_rect.height * y + plane.copy_rect.y);
285 298
286 target_point_ = plane_intersection_point; 299 target_point_ = plane_intersection_point;
287 target_element_ = &plane; 300 target_element_ = &plane;
(...skipping 365 matching lines...) Expand 10 before | Expand all | Expand 10 after
653 content::WebContents::FromJavaWebContents(content_web_contents)); 666 content::WebContents::FromJavaWebContents(content_web_contents));
654 content::ContentViewCore* ui_core = content::ContentViewCore::FromWebContents( 667 content::ContentViewCore* ui_core = content::ContentViewCore::FromWebContents(
655 content::WebContents::FromJavaWebContents(ui_web_contents)); 668 content::WebContents::FromJavaWebContents(ui_web_contents));
656 return reinterpret_cast<intptr_t>(new VrShell( 669 return reinterpret_cast<intptr_t>(new VrShell(
657 env, obj, c_core, 670 env, obj, c_core,
658 reinterpret_cast<ui::WindowAndroid*>(content_window_android), ui_core, 671 reinterpret_cast<ui::WindowAndroid*>(content_window_android), ui_core,
659 reinterpret_cast<ui::WindowAndroid*>(ui_window_android))); 672 reinterpret_cast<ui::WindowAndroid*>(ui_window_android)));
660 } 673 }
661 674
662 } // namespace vr_shell 675 } // namespace vr_shell
OLDNEW
« 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