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 22 matching lines...) Expand all Loading... | |
33 namespace vr_shell { | 33 namespace vr_shell { |
34 | 34 |
35 namespace { | 35 namespace { |
36 // TODO(mthiesse): If gvr::PlatformInfo().GetPosePredictionTime() is ever | 36 // TODO(mthiesse): If gvr::PlatformInfo().GetPosePredictionTime() is ever |
37 // exposed, use that instead (it defaults to 50ms on most platforms). | 37 // exposed, use that instead (it defaults to 50ms on most platforms). |
38 static constexpr int64_t kPredictionTimeWithoutVsyncNanos = 50000000; | 38 static constexpr int64_t kPredictionTimeWithoutVsyncNanos = 50000000; |
39 | 39 |
40 static constexpr float kZNear = 0.1f; | 40 static constexpr float kZNear = 0.1f; |
41 static constexpr float kZFar = 1000.0f; | 41 static constexpr float kZFar = 1000.0f; |
42 | 42 |
43 // Screen angle in degrees. 0 = vertical, positive = top closer. | |
44 static constexpr float kDesktopScreenTiltDefault = 0; | |
45 | |
46 static constexpr float kReticleWidth = 0.025f; | 43 static constexpr float kReticleWidth = 0.025f; |
47 static constexpr float kReticleHeight = 0.025f; | 44 static constexpr float kReticleHeight = 0.025f; |
48 | 45 |
49 static constexpr float kLaserWidth = 0.01f; | 46 static constexpr float kLaserWidth = 0.01f; |
50 | 47 |
51 // Angle (radians) the beam down from the controller axis, for wrist comfort. | 48 // Angle (radians) the beam down from the controller axis, for wrist comfort. |
52 static constexpr float kErgoAngleOffset = 0.26f; | 49 static constexpr float kErgoAngleOffset = 0.26f; |
53 | 50 |
54 static constexpr gvr::Vec3f kOrigin = {0.0f, 0.0f, 0.0f}; | 51 static constexpr gvr::Vec3f kOrigin = {0.0f, 0.0f, 0.0f}; |
55 | 52 |
(...skipping 425 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
481 // that the sphere is centered at the controller, rather than the eye, for | 478 // that the sphere is centered at the controller, rather than the eye, for |
482 // simplicity. | 479 // simplicity. |
483 float distance = scene_->GetBackgroundDistance(); | 480 float distance = scene_->GetBackgroundDistance(); |
484 target_point_ = GetRayPoint(origin, forward, distance); | 481 target_point_ = GetRayPoint(origin, forward, distance); |
485 gvr::Vec3f eye_to_target = target_point_; | 482 gvr::Vec3f eye_to_target = target_point_; |
486 NormalizeVector(eye_to_target); | 483 NormalizeVector(eye_to_target); |
487 | 484 |
488 // Determine which UI element (if any) intersects the line between the eyes | 485 // Determine which UI element (if any) intersects the line between the eyes |
489 // and the controller target position. | 486 // and the controller target position. |
490 float closest_element_distance = VectorLength(target_point_); | 487 float closest_element_distance = VectorLength(target_point_); |
491 int pixel_x = 0; | |
492 int pixel_y = 0; | |
493 target_element_ = nullptr; | 488 target_element_ = nullptr; |
489 float target_x; | |
490 float target_y; | |
494 | 491 |
495 for (const auto& plane : scene_->GetUiElements()) { | 492 for (const auto& plane : scene_->GetUiElements()) { |
496 if (!plane->IsHitTestable()) | 493 if (!plane->IsHitTestable()) |
497 continue; | 494 continue; |
498 | 495 |
499 float distance_to_plane = plane->GetRayDistance(kOrigin, eye_to_target); | 496 float distance_to_plane; |
497 if (!plane->GetRayDistance(kOrigin, eye_to_target, &distance_to_plane)) | |
498 continue; | |
499 | |
500 if (distance_to_plane < 0 || distance_to_plane >= closest_element_distance) | |
501 continue; | |
502 | |
500 gvr::Vec3f plane_intersection_point = | 503 gvr::Vec3f plane_intersection_point = |
501 GetRayPoint(kOrigin, eye_to_target, distance_to_plane); | 504 GetRayPoint(kOrigin, eye_to_target, distance_to_plane); |
505 gvr::Vec2f unit_xy_point = | |
506 plane->GetUnitRectangleCoordinates(plane_intersection_point); | |
502 | 507 |
503 gvr::Vec3f rect_2d_point = | 508 float x = 0.5f + unit_xy_point.x; |
504 MatrixVectorMul(plane->transform.from_world, plane_intersection_point); | 509 float y = 0.5f - unit_xy_point.y; |
505 if (distance_to_plane < 0 || | 510 if (x < 0.0f || x >= 1.0f || y < 0.0f || y >= 1.0f) |
506 distance_to_plane >= closest_element_distance) { | |
507 continue; | |
508 } | |
509 | |
510 float x = rect_2d_point.x + 0.5f; | |
511 float y = 0.5f - rect_2d_point.y; | |
512 bool is_inside = x >= 0.0f && x < 1.0f && y >= 0.0f && y < 1.0f; | |
513 if (!is_inside) | |
514 continue; | 511 continue; |
515 | 512 |
516 closest_element_distance = distance_to_plane; | 513 closest_element_distance = distance_to_plane; |
517 Rectf pixel_rect; | |
518 if (plane->fill == Fill::CONTENT) { | |
519 pixel_rect = {0, 0, content_tex_css_width_, content_tex_css_height_}; | |
520 } else { | |
521 pixel_rect = {plane->copy_rect.x, plane->copy_rect.y, | |
522 plane->copy_rect.width, plane->copy_rect.height}; | |
523 } | |
524 pixel_x = pixel_rect.width * x + pixel_rect.x; | |
525 pixel_y = pixel_rect.height * y + pixel_rect.y; | |
526 | |
527 target_point_ = plane_intersection_point; | 514 target_point_ = plane_intersection_point; |
528 target_element_ = plane.get(); | 515 target_element_ = plane.get(); |
516 target_x = x; | |
517 target_y = y; | |
529 } | 518 } |
530 | 519 |
531 // Treat UI elements, which do not show web content, as NONE input | 520 // Treat UI elements, which do not show web content, as NONE input |
532 // targets since they cannot make use of the input anyway. | 521 // targets since they cannot make use of the input anyway. |
533 InputTarget input_target = InputTarget::NONE; | 522 InputTarget input_target = InputTarget::NONE; |
523 int pixel_x = 0; | |
524 int pixel_y = 0; | |
525 | |
534 if (target_element_ != nullptr) { | 526 if (target_element_ != nullptr) { |
cjgrant
2017/03/03 21:30:34
For the record - I haven't fully tested this on de
mthiesse
2017/03/06 17:26:07
I trust you'll do so before submitting :P
cjgrant
2017/03/06 17:43:34
I should never have tried to hastily post this bef
| |
527 Rectf pixel_rect; | |
528 if (target_element_->fill == Fill::CONTENT) { | |
529 pixel_rect = {0, 0, content_tex_css_width_, content_tex_css_height_}; | |
530 } else { | |
531 pixel_rect = {target_element_->copy_rect.x, target_element_->copy_rect.y, | |
532 target_element_->copy_rect.width, | |
533 target_element_->copy_rect.height}; | |
534 } | |
535 pixel_x = pixel_rect.x + pixel_rect.width * target_x; | |
536 pixel_y = pixel_rect.y + pixel_rect.height * target_y; | |
537 | |
535 switch (target_element_->fill) { | 538 switch (target_element_->fill) { |
536 case Fill::CONTENT: | 539 case Fill::CONTENT: |
537 input_target = InputTarget::CONTENT; | 540 input_target = InputTarget::CONTENT; |
538 break; | 541 break; |
539 case Fill::SPRITE: | 542 case Fill::SPRITE: |
540 input_target = InputTarget::UI; | 543 input_target = InputTarget::UI; |
541 break; | 544 break; |
542 default: | 545 default: |
543 input_target = InputTarget::NONE; | |
544 break; | 546 break; |
545 } | 547 } |
546 } | 548 } |
547 SendEventsToTarget(input_target, pixel_x, pixel_y); | 549 SendEventsToTarget(input_target, pixel_x, pixel_y); |
548 } | 550 } |
549 | 551 |
550 void VrShellGl::SendEventsToTarget(InputTarget input_target, | 552 void VrShellGl::SendEventsToTarget(InputTarget input_target, |
551 int pixel_x, | 553 int pixel_x, |
552 int pixel_y) { | 554 int pixel_y) { |
553 std::vector<std::unique_ptr<WebGestureEvent>> gesture_list = | 555 std::vector<std::unique_ptr<WebGestureEvent>> gesture_list = |
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
701 if (position.x == 0.0f && position.y == 0.0f && position.z == 0.0f) { | 703 if (position.x == 0.0f && position.y == 0.0f && position.z == 0.0f) { |
702 // This appears to be a 3DOF pose without a neck model. Add one. | 704 // This appears to be a 3DOF pose without a neck model. Add one. |
703 // The head pose has redundant data. Assume we're only using the | 705 // The head pose has redundant data. Assume we're only using the |
704 // object_from_reference_matrix, we're not updating position_external. | 706 // object_from_reference_matrix, we're not updating position_external. |
705 // TODO: Not sure what object_from_reference_matrix is. The new api removed | 707 // TODO: Not sure what object_from_reference_matrix is. The new api removed |
706 // it. For now, removing it seems working fine. | 708 // it. For now, removing it seems working fine. |
707 gvr_api_->ApplyNeckModel(head_pose, 1.0f); | 709 gvr_api_->ApplyNeckModel(head_pose, 1.0f); |
708 } | 710 } |
709 | 711 |
710 // Update the render position of all UI elements (including desktop). | 712 // Update the render position of all UI elements (including desktop). |
711 const float screen_tilt = kDesktopScreenTiltDefault * M_PI / 180.0f; | 713 scene_->UpdateTransforms(TimeInMicroseconds()); |
712 scene_->UpdateTransforms(screen_tilt, TimeInMicroseconds()); | |
713 | 714 |
714 UpdateController(GetForwardVector(head_pose)); | 715 UpdateController(GetForwardVector(head_pose)); |
715 | 716 |
716 DrawVrShell(head_pose, frame); | 717 DrawVrShell(head_pose, frame); |
717 | 718 |
718 frame.Unbind(); | 719 frame.Unbind(); |
719 frame.Submit(*buffer_viewport_list_, head_pose); | 720 frame.Submit(*buffer_viewport_list_, head_pose); |
720 | 721 |
721 // No need to swap buffers for surfaceless rendering. | 722 // No need to swap buffers for surfaceless rendering. |
722 if (!surfaceless_rendering_) { | 723 if (!surfaceless_rendering_) { |
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
827 DrawCursor(render_matrix); | 828 DrawCursor(render_matrix); |
828 } | 829 } |
829 } | 830 } |
830 } | 831 } |
831 | 832 |
832 void VrShellGl::DrawElements( | 833 void VrShellGl::DrawElements( |
833 const gvr::Mat4f& view_proj_matrix, | 834 const gvr::Mat4f& view_proj_matrix, |
834 const gvr::Mat4f& view_matrix, | 835 const gvr::Mat4f& view_matrix, |
835 const std::vector<const ContentRectangle*>& elements) { | 836 const std::vector<const ContentRectangle*>& elements) { |
836 for (const auto* rect : elements) { | 837 for (const auto* rect : elements) { |
837 gvr::Mat4f transform = | 838 gvr::Mat4f transform = MatrixMul(view_proj_matrix, rect->TransformMatrix()); |
838 MatrixMul(view_proj_matrix, rect->transform.to_world); | |
839 | 839 |
840 switch (rect->fill) { | 840 switch (rect->fill) { |
841 case Fill::SPRITE: { | 841 case Fill::SPRITE: { |
842 Rectf copy_rect; | 842 Rectf copy_rect; |
843 copy_rect.x = static_cast<float>(rect->copy_rect.x) / ui_tex_css_width_; | 843 copy_rect.x = static_cast<float>(rect->copy_rect.x) / ui_tex_css_width_; |
844 copy_rect.y = | 844 copy_rect.y = |
845 static_cast<float>(rect->copy_rect.y) / ui_tex_css_height_; | 845 static_cast<float>(rect->copy_rect.y) / ui_tex_css_height_; |
846 copy_rect.width = | 846 copy_rect.width = |
847 static_cast<float>(rect->copy_rect.width) / ui_tex_css_width_; | 847 static_cast<float>(rect->copy_rect.width) / ui_tex_css_width_; |
848 copy_rect.height = | 848 copy_rect.height = |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
883 | 883 |
884 std::vector<const ContentRectangle*> VrShellGl::GetElementsInDrawOrder( | 884 std::vector<const ContentRectangle*> VrShellGl::GetElementsInDrawOrder( |
885 const gvr::Mat4f& view_matrix, | 885 const gvr::Mat4f& view_matrix, |
886 const std::vector<const ContentRectangle*>& elements) { | 886 const std::vector<const ContentRectangle*>& elements) { |
887 typedef std::pair<float, const ContentRectangle*> DistanceElementPair; | 887 typedef std::pair<float, const ContentRectangle*> DistanceElementPair; |
888 std::vector<DistanceElementPair> zOrderedElementPairs; | 888 std::vector<DistanceElementPair> zOrderedElementPairs; |
889 zOrderedElementPairs.reserve(elements.size()); | 889 zOrderedElementPairs.reserve(elements.size()); |
890 | 890 |
891 for (const auto* element : elements) { | 891 for (const auto* element : elements) { |
892 // Distance is the abs(z) value in view space. | 892 // Distance is the abs(z) value in view space. |
893 gvr::Vec3f element_position = GetTranslation(element->transform.to_world); | 893 gvr::Vec3f element_position = GetTranslation(element->TransformMatrix()); |
894 float distance = | 894 float distance = |
895 std::fabs(MatrixVectorMul(view_matrix, element_position).z); | 895 std::fabs(MatrixVectorMul(view_matrix, element_position).z); |
896 zOrderedElementPairs.push_back(std::make_pair(distance, element)); | 896 zOrderedElementPairs.push_back(std::make_pair(distance, element)); |
897 } | 897 } |
898 | 898 |
899 // Sort elements primarily based on their draw phase (lower draw phase first) | 899 // Sort elements primarily based on their draw phase (lower draw phase first) |
900 // and secondarily based on their distance (larger distance first). | 900 // and secondarily based on their distance (larger distance first). |
901 std::sort( | 901 std::sort( |
902 zOrderedElementPairs.begin(), zOrderedElementPairs.end(), | 902 zOrderedElementPairs.begin(), zOrderedElementPairs.end(), |
903 [](const DistanceElementPair& first, const DistanceElementPair& second) { | 903 [](const DistanceElementPair& first, const DistanceElementPair& second) { |
(...skipping 254 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1158 const base::Callback<void(device::mojom::VRDisplayInfoPtr)>& callback, | 1158 const base::Callback<void(device::mojom::VRDisplayInfoPtr)>& callback, |
1159 uint32_t device_id) { | 1159 uint32_t device_id) { |
1160 device::mojom::VRDisplayInfoPtr info = VrShell::CreateVRDisplayInfo( | 1160 device::mojom::VRDisplayInfoPtr info = VrShell::CreateVRDisplayInfo( |
1161 gvr_api_.get(), content_tex_physical_size_, device_id); | 1161 gvr_api_.get(), content_tex_physical_size_, device_id); |
1162 main_thread_task_runner_->PostTask( | 1162 main_thread_task_runner_->PostTask( |
1163 FROM_HERE, | 1163 FROM_HERE, |
1164 base::Bind(&RunVRDisplayInfoCallback, callback, base::Passed(&info))); | 1164 base::Bind(&RunVRDisplayInfoCallback, callback, base::Passed(&info))); |
1165 } | 1165 } |
1166 | 1166 |
1167 } // namespace vr_shell | 1167 } // namespace vr_shell |
OLD | NEW |