Chromium Code Reviews| 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 |