Chromium Code Reviews| 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 66cc25e717ec5e57ebffcd523ed6362d2d6857aa..d3de2e238f5fd60003fadc02d9c79d148f9166a5 100644 |
| --- a/chrome/browser/android/vr_shell/vr_shell.cc |
| +++ b/chrome/browser/android/vr_shell/vr_shell.cc |
| @@ -38,8 +38,8 @@ static constexpr float kDesktopScreenTiltDefault = 0; |
| static constexpr float kScreenHeightRatio = 1.0f; |
| static constexpr float kScreenWidthRatio = 16.0f / 9.0f; |
| -static constexpr float kReticleWidth = 0.05f; |
| -static constexpr float kReticleHeight = 0.05f; |
| +static constexpr float kReticleWidth = 0.025f; |
| +static constexpr float kReticleHeight = 0.025f; |
| static constexpr float kLaserWidth = 0.01f; |
| @@ -49,11 +49,15 @@ static constexpr float kLaserWidth = 0.01f; |
| // where the main screen is placed. |
| static constexpr gvr::Vec3f kNeutralPose = {0.0f, 0.0f, -1.0f}; |
| +static constexpr gvr::Vec3f kOrigin = {0.0f, 0.0f, 0.0f}; |
| + |
| // In lieu of an elbow model, we assume a position for the user's hand. |
| // TODO(mthiesse): Handedness options. |
| static constexpr gvr::Vec3f kHandPosition = {0.2f, -0.5f, -0.2f}; |
| -static constexpr float kReticleZOffset = 0.01f; |
| +// Fraction of the z-distance to the object the cursor is drawn at to avoid |
| +// rounding errors drawing the cursor behind the object. |
| +static constexpr float kReticleZOffset = 0.99f; |
| } // namespace |
| @@ -65,6 +69,7 @@ VrShell::VrShell(JNIEnv* env, jobject obj, |
| : desktop_screen_tilt_(kDesktopScreenTiltDefault), |
| desktop_height_(kDesktopHeightDefault), |
| desktop_position_(kDesktopPositionDefault), |
| + cursor_distance_(-kDesktopPositionDefault.z), |
| content_cvc_(content_core) { |
| j_vr_shell_.Reset(env, obj); |
| content_compositor_view_.reset(new VrCompositor(content_window)); |
| @@ -169,10 +174,38 @@ void VrShell::UpdateController() { |
| translation.z += kHandPosition.z; |
| } |
| - // We can only be intersecting the desktop plane at the moment. |
| - float distance_to_plane = desktop_plane_->GetRayDistance(translation, |
| - forward); |
| - look_at_vector_ = GetRayPoint(translation, forward, distance_to_plane); |
| + float desktop_dist = ui_rects_[0]->GetRayDistance(translation, forward); |
|
cjgrant
2016/09/22 18:59:04
Should use desktop_plane_ or scene_.GetUiElementBy
mthiesse
2016/09/22 22:01:33
Done.
|
| + gvr::Vec3f cursor_position = GetRayPoint(translation, forward, desktop_dist); |
|
cjgrant
2016/09/22 18:59:03
If you want, there's a better way to do this. Sin
mthiesse
2016/09/22 22:01:33
I'll get back to this when we have working control
|
| + look_at_vector_ = cursor_position; |
| + cursor_distance_ = desktop_dist; |
| + |
| + // Determine which UI element (if any) the cursor is pointing to. |
| + float closest_element = std::numeric_limits<float>::infinity(); |
| + int closest_element_index = -1; |
| + int pixel_x, pixel_y; |
| + |
| + for (std::size_t i = 0; i < ui_rects_.size(); ++i) { |
| + const ContentRectangle& plane = *ui_rects_[i].get(); |
| + float distance_to_plane = plane.GetRayDistance(kOrigin, cursor_position); |
| + gvr::Vec3f plane_intersection_point = |
| + GetRayPoint(kOrigin, cursor_position, 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) { |
| + bool is_inside = x >= 0.0f && x < 1.0f && y >= 0.0f && y < 1.0f; |
| + if (is_inside) { |
| + closest_element = distance_to_plane; |
| + cursor_distance_ = desktop_dist * distance_to_plane; |
| + closest_element_index = i; |
| + pixel_x = int((plane.copy_rect.width * x) + plane.copy_rect.x); |
| + pixel_y = int((plane.copy_rect.height * y) + plane.copy_rect.y); |
| + look_at_vector_ = plane_intersection_point; |
| + } |
| + } |
| + } |
| + // TODO(mthiesse): Create input events for CVC using pixel_x/y. |
| } |
| void ApplyNeckModel(gvr::Mat4f& mat_forward) { |
| @@ -227,8 +260,6 @@ void VrShell::DrawVrShell() { |
| float screen_tilt = desktop_screen_tilt_ * M_PI / 180.0f; |
| - forward_vector_ = getForwardVector(head_pose_); |
| - |
| gvr::Vec3f headPos = getTranslation(head_pose_); |
| if (headPos.x == 0.0f && headPos.y == 0.0f && headPos.z == 0.0f) { |
| // This appears to be a 3DOF pose without a neck model. Add one. |
| @@ -239,6 +270,8 @@ void VrShell::DrawVrShell() { |
| ApplyNeckModel(head_pose_); |
| } |
| + forward_vector_ = getForwardVector(head_pose_); |
| + |
| desktop_plane_->size = {screen_width, screen_height, 1.0f}; |
| desktop_plane_->translation.x = desktop_position_.x; |
| desktop_plane_->translation.y = desktop_position_.y; |
| @@ -309,11 +342,15 @@ void VrShell::DrawUI() { |
| void VrShell::DrawCursor() { |
| gvr::Mat4f mat; |
| SetIdentityM(mat); |
| + |
| // Scale the pointer. |
|
cjgrant
2016/09/22 18:59:04
... to have a fixed FOV size at any distance. (?)
mthiesse
2016/09/22 22:01:33
Done.
|
| - ScaleM(mat, mat, kReticleWidth, kReticleHeight, 1.0f); |
| + ScaleM(mat, mat, kReticleWidth * cursor_distance_, |
| + kReticleHeight * cursor_distance_, 1.0f); |
| + |
| // Place the pointer at the screen plane intersection point. |
| - TranslateM(mat, mat, look_at_vector_.x, look_at_vector_.y, |
| - look_at_vector_.z + kReticleZOffset); |
| + TranslateM(mat, mat, look_at_vector_.x * kReticleZOffset, |
|
cjgrant
2016/09/22 18:59:03
Why are x and y also being offset?
mthiesse
2016/09/22 22:01:33
We're moving it slightly towards the viewer while
|
| + look_at_vector_.y * kReticleZOffset, |
| + look_at_vector_.z * kReticleZOffset); |
| gvr::Mat4f mv = MatrixMul(view_matrix_, mat); |
| gvr::Mat4f mvp = MatrixMul(projection_matrix_, mv); |
| vr_shell_renderer_->GetReticleRenderer()->Draw(mvp); |