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 "base/metrics/histogram_macros.h" | 7 #include "base/metrics/histogram_macros.h" |
8 #include "chrome/browser/android/vr_shell/ui_elements.h" | 8 #include "chrome/browser/android/vr_shell/ui_elements.h" |
9 #include "chrome/browser/android/vr_shell/ui_interface.h" | 9 #include "chrome/browser/android/vr_shell/ui_interface.h" |
10 #include "chrome/browser/android/vr_shell/ui_scene.h" | 10 #include "chrome/browser/android/vr_shell/ui_scene.h" |
(...skipping 308 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
319 | 319 |
320 // Determine which UI element (if any) intersects the line between the eyes | 320 // Determine which UI element (if any) intersects the line between the eyes |
321 // and the controller target position. | 321 // and the controller target position. |
322 float closest_element_distance = std::numeric_limits<float>::infinity(); | 322 float closest_element_distance = std::numeric_limits<float>::infinity(); |
323 int pixel_x = 0; | 323 int pixel_x = 0; |
324 int pixel_y = 0; | 324 int pixel_y = 0; |
325 VrInputManager* input_target = nullptr; | 325 VrInputManager* input_target = nullptr; |
326 | 326 |
327 for (std::size_t i = 0; i < scene_->GetUiElements().size(); ++i) { | 327 for (std::size_t i = 0; i < scene_->GetUiElements().size(); ++i) { |
328 const ContentRectangle* plane = scene_->GetUiElements()[i].get(); | 328 const ContentRectangle* plane = scene_->GetUiElements()[i].get(); |
329 if (!plane->visible) { | 329 if (!plane->visible || !plane->hit_testable) { |
330 continue; | 330 continue; |
331 } | 331 } |
332 float distance_to_plane = plane->GetRayDistance(kOrigin, eye_to_target); | 332 float distance_to_plane = plane->GetRayDistance(kOrigin, eye_to_target); |
333 gvr::Vec3f plane_intersection_point = | 333 gvr::Vec3f plane_intersection_point = |
334 GetRayPoint(kOrigin, eye_to_target, distance_to_plane); | 334 GetRayPoint(kOrigin, eye_to_target, distance_to_plane); |
335 | 335 |
336 gvr::Vec3f rect_2d_point = | 336 gvr::Vec3f rect_2d_point = |
337 MatrixVectorMul(plane->transform.from_world, plane_intersection_point); | 337 MatrixVectorMul(plane->transform.from_world, plane_intersection_point); |
338 if (distance_to_plane > 0 && distance_to_plane < closest_element_distance) { | 338 if (distance_to_plane > 0 && distance_to_plane < closest_element_distance) { |
339 float x = rect_2d_point.x + 0.5f; | 339 float x = rect_2d_point.x + 0.5f; |
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
449 void VrShell::DrawVrShell(const gvr::Mat4f& head_pose) { | 449 void VrShell::DrawVrShell(const gvr::Mat4f& head_pose) { |
450 float screen_tilt = desktop_screen_tilt_ * M_PI / 180.0f; | 450 float screen_tilt = desktop_screen_tilt_ * M_PI / 180.0f; |
451 | 451 |
452 HandleQueuedTasks(); | 452 HandleQueuedTasks(); |
453 | 453 |
454 // Update the render position of all UI elements (including desktop). | 454 // Update the render position of all UI elements (including desktop). |
455 scene_->UpdateTransforms(screen_tilt, UiScene::TimeInMicroseconds()); | 455 scene_->UpdateTransforms(screen_tilt, UiScene::TimeInMicroseconds()); |
456 | 456 |
457 UpdateController(GetForwardVector(head_pose)); | 457 UpdateController(GetForwardVector(head_pose)); |
458 | 458 |
459 // Everything should be positioned now, ready for drawing. | |
460 gvr::Mat4f left_eye_view_matrix = | |
461 MatrixMul(gvr_api_->GetEyeFromHeadMatrix(GVR_LEFT_EYE), head_pose); | |
462 gvr::Mat4f right_eye_view_matrix = | |
463 MatrixMul(gvr_api_->GetEyeFromHeadMatrix(GVR_RIGHT_EYE), head_pose); | |
464 | |
465 // Use culling to remove back faces. | 459 // Use culling to remove back faces. |
466 glEnable(GL_CULL_FACE); | 460 glEnable(GL_CULL_FACE); |
467 | 461 |
468 // Enable depth testing. | 462 // Enable depth testing. |
469 glEnable(GL_DEPTH_TEST); | 463 glEnable(GL_DEPTH_TEST); |
470 glEnable(GL_SCISSOR_TEST); | 464 glEnable(GL_SCISSOR_TEST); |
471 | 465 |
472 glClearColor(0.1f, 0.1f, 0.1f, 1.0f); | 466 glClearColor(0.1f, 0.1f, 0.1f, 1.0f); |
473 | 467 |
474 buffer_viewport_list_->GetBufferViewport(GVR_LEFT_EYE, | 468 buffer_viewport_list_->GetBufferViewport(GVR_LEFT_EYE, |
475 buffer_viewport_.get()); | 469 buffer_viewport_.get()); |
476 DrawEye(left_eye_view_matrix, *buffer_viewport_); | 470 DrawEye(GVR_LEFT_EYE, head_pose, *buffer_viewport_); |
477 buffer_viewport_list_->GetBufferViewport(GVR_RIGHT_EYE, | 471 buffer_viewport_list_->GetBufferViewport(GVR_RIGHT_EYE, |
478 buffer_viewport_.get()); | 472 buffer_viewport_.get()); |
479 DrawEye(right_eye_view_matrix, *buffer_viewport_); | 473 DrawEye(GVR_RIGHT_EYE, head_pose, *buffer_viewport_); |
480 } | 474 } |
481 | 475 |
482 void VrShell::DrawEye(const gvr::Mat4f& view_matrix, | 476 void VrShell::DrawEye(gvr::Eye eye, |
| 477 const gvr::Mat4f& head_pose, |
483 const gvr::BufferViewport& params) { | 478 const gvr::BufferViewport& params) { |
| 479 gvr::Mat4f eye_matrix = gvr_api_->GetEyeFromHeadMatrix(eye); |
| 480 gvr::Mat4f view_matrix = MatrixMul(eye_matrix, head_pose); |
| 481 |
484 gvr::Recti pixel_rect = | 482 gvr::Recti pixel_rect = |
485 CalculatePixelSpaceRect(render_size_, params.GetSourceUv()); | 483 CalculatePixelSpaceRect(render_size_, params.GetSourceUv()); |
486 glViewport(pixel_rect.left, pixel_rect.bottom, | 484 glViewport(pixel_rect.left, pixel_rect.bottom, |
487 pixel_rect.right - pixel_rect.left, | 485 pixel_rect.right - pixel_rect.left, |
488 pixel_rect.top - pixel_rect.bottom); | 486 pixel_rect.top - pixel_rect.bottom); |
489 glScissor(pixel_rect.left, pixel_rect.bottom, | 487 glScissor(pixel_rect.left, pixel_rect.bottom, |
490 pixel_rect.right - pixel_rect.left, | 488 pixel_rect.right - pixel_rect.left, |
491 pixel_rect.top - pixel_rect.bottom); | 489 pixel_rect.top - pixel_rect.bottom); |
492 | 490 |
493 gvr::Mat4f render_matrix = MatrixMul( | 491 const gvr::Mat4f fov_render_matrix = MatrixMul( |
| 492 PerspectiveMatrixFromView(params.GetSourceFov(), kZNear, kZFar), |
| 493 eye_matrix); |
| 494 const gvr::Mat4f world_render_matrix = MatrixMul( |
494 PerspectiveMatrixFromView(params.GetSourceFov(), kZNear, kZFar), | 495 PerspectiveMatrixFromView(params.GetSourceFov(), kZNear, kZFar), |
495 view_matrix); | 496 view_matrix); |
496 | 497 |
497 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); | 498 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); |
498 | 499 |
499 // TODO(mthiesse): Draw order for transparency. | 500 // TODO(mthiesse): Draw order for transparency. |
500 DrawUI(render_matrix); | 501 DrawUI(world_render_matrix, fov_render_matrix); |
501 DrawCursor(render_matrix); | 502 DrawCursor(world_render_matrix); |
502 } | 503 } |
503 | 504 |
504 bool VrShell::IsUiTextureReady() { | 505 bool VrShell::IsUiTextureReady() { |
505 return ui_tex_width_ > 0 && ui_tex_height_ > 0; | 506 return ui_tex_width_ > 0 && ui_tex_height_ > 0; |
506 } | 507 } |
507 | 508 |
508 Rectf VrShell::MakeUiGlCopyRect(Recti pixel_rect) { | 509 Rectf VrShell::MakeUiGlCopyRect(Recti pixel_rect) { |
509 CHECK(IsUiTextureReady()); | 510 CHECK(IsUiTextureReady()); |
510 return Rectf({ | 511 return Rectf({ |
511 static_cast<float>(pixel_rect.x) / ui_tex_width_, | 512 static_cast<float>(pixel_rect.x) / ui_tex_width_, |
512 static_cast<float>(pixel_rect.y) / ui_tex_height_, | 513 static_cast<float>(pixel_rect.y) / ui_tex_height_, |
513 static_cast<float>(pixel_rect.width) / ui_tex_width_, | 514 static_cast<float>(pixel_rect.width) / ui_tex_width_, |
514 static_cast<float>(pixel_rect.height) / ui_tex_height_}); | 515 static_cast<float>(pixel_rect.height) / ui_tex_height_}); |
515 } | 516 } |
516 | 517 |
517 void VrShell::DrawUI(const gvr::Mat4f& render_matrix) { | 518 void VrShell::DrawUI(const gvr::Mat4f& world_matrix, |
| 519 const gvr::Mat4f& fov_matrix) { |
518 for (const auto& rect : scene_->GetUiElements()) { | 520 for (const auto& rect : scene_->GetUiElements()) { |
519 if (!rect->visible) { | 521 if (!rect->visible) { |
520 continue; | 522 continue; |
521 } | 523 } |
522 | 524 |
523 Rectf copy_rect; | 525 Rectf copy_rect; |
524 jint texture_handle; | 526 jint texture_handle; |
525 if (rect->id == kBrowserUiElementId) { | 527 if (rect->id == kBrowserUiElementId) { |
526 copy_rect = {0, 0, 1, 1}; | 528 copy_rect = {0, 0, 1, 1}; |
527 texture_handle = content_texture_id_; | 529 texture_handle = content_texture_id_; |
528 } else { | 530 } else { |
529 copy_rect.x = static_cast<float>(rect->copy_rect.x) / ui_tex_width_; | 531 copy_rect.x = static_cast<float>(rect->copy_rect.x) / ui_tex_width_; |
530 copy_rect.y = static_cast<float>(rect->copy_rect.y) / ui_tex_height_; | 532 copy_rect.y = static_cast<float>(rect->copy_rect.y) / ui_tex_height_; |
531 copy_rect.width = static_cast<float>(rect->copy_rect.width) / | 533 copy_rect.width = static_cast<float>(rect->copy_rect.width) / |
532 ui_tex_width_; | 534 ui_tex_width_; |
533 copy_rect.height = static_cast<float>(rect->copy_rect.height) / | 535 copy_rect.height = static_cast<float>(rect->copy_rect.height) / |
534 ui_tex_height_; | 536 ui_tex_height_; |
535 texture_handle = ui_texture_id_; | 537 texture_handle = ui_texture_id_; |
536 } | 538 } |
537 | 539 |
538 gvr::Mat4f transform = MatrixMul(render_matrix, rect->transform.to_world); | 540 const gvr::Mat4f& view_matrix = |
| 541 rect->lock_to_fov ? fov_matrix : world_matrix; |
| 542 gvr::Mat4f transform = MatrixMul(view_matrix, rect->transform.to_world); |
539 vr_shell_renderer_->GetTexturedQuadRenderer()->Draw( | 543 vr_shell_renderer_->GetTexturedQuadRenderer()->Draw( |
540 texture_handle, transform, copy_rect); | 544 texture_handle, transform, copy_rect); |
541 } | 545 } |
542 } | 546 } |
543 | 547 |
544 void VrShell::DrawCursor(const gvr::Mat4f& render_matrix) { | 548 void VrShell::DrawCursor(const gvr::Mat4f& render_matrix) { |
545 gvr::Mat4f mat; | 549 gvr::Mat4f mat; |
546 SetIdentityM(mat); | 550 SetIdentityM(mat); |
547 | 551 |
548 // Draw the reticle. | 552 // Draw the reticle. |
(...skipping 327 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
876 const JavaParamRef<jobject>& ui_web_contents, | 880 const JavaParamRef<jobject>& ui_web_contents, |
877 jlong ui_window_android) { | 881 jlong ui_window_android) { |
878 return reinterpret_cast<intptr_t>(new VrShell( | 882 return reinterpret_cast<intptr_t>(new VrShell( |
879 env, obj, content::WebContents::FromJavaWebContents(content_web_contents), | 883 env, obj, content::WebContents::FromJavaWebContents(content_web_contents), |
880 reinterpret_cast<ui::WindowAndroid*>(content_window_android), | 884 reinterpret_cast<ui::WindowAndroid*>(content_window_android), |
881 content::WebContents::FromJavaWebContents(ui_web_contents), | 885 content::WebContents::FromJavaWebContents(ui_web_contents), |
882 reinterpret_cast<ui::WindowAndroid*>(ui_window_android))); | 886 reinterpret_cast<ui::WindowAndroid*>(ui_window_android))); |
883 } | 887 } |
884 | 888 |
885 } // namespace vr_shell | 889 } // namespace vr_shell |
OLD | NEW |