Commit 7027cefe authored by mthiesse's avatar mthiesse Committed by Commit bot

Implement UI hit testing + Reticle scaling

BUG=641413

Review-Url: https://codereview.chromium.org/2367543002
Cr-Commit-Position: refs/heads/master@{#420623}
parent bd212bd6
...@@ -40,8 +40,8 @@ static constexpr float kDesktopScreenTiltDefault = 0; ...@@ -40,8 +40,8 @@ static constexpr float kDesktopScreenTiltDefault = 0;
static constexpr float kScreenHeightRatio = 1.0f; static constexpr float kScreenHeightRatio = 1.0f;
static constexpr float kScreenWidthRatio = 16.0f / 9.0f; static constexpr float kScreenWidthRatio = 16.0f / 9.0f;
static constexpr float kReticleWidth = 0.05f; static constexpr float kReticleWidth = 0.025f;
static constexpr float kReticleHeight = 0.05f; static constexpr float kReticleHeight = 0.025f;
static constexpr float kLaserWidth = 0.01f; static constexpr float kLaserWidth = 0.01f;
...@@ -51,11 +51,15 @@ static constexpr float kLaserWidth = 0.01f; ...@@ -51,11 +51,15 @@ static constexpr float kLaserWidth = 0.01f;
// where the main screen is placed. // where the main screen is placed.
static constexpr gvr::Vec3f kNeutralPose = {0.0f, 0.0f, -1.0f}; 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. // In lieu of an elbow model, we assume a position for the user's hand.
// TODO(mthiesse): Handedness options. // TODO(mthiesse): Handedness options.
static constexpr gvr::Vec3f kHandPosition = {0.2f, -0.5f, -0.2f}; 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;
// UI element 0 is the browser content rectangle. // UI element 0 is the browser content rectangle.
static constexpr int kBrowserUiElementId = 0; static constexpr int kBrowserUiElementId = 0;
...@@ -72,6 +76,7 @@ VrShell::VrShell(JNIEnv* env, jobject obj, ...@@ -72,6 +76,7 @@ VrShell::VrShell(JNIEnv* env, jobject obj,
: desktop_screen_tilt_(kDesktopScreenTiltDefault), : desktop_screen_tilt_(kDesktopScreenTiltDefault),
desktop_height_(kDesktopHeightDefault), desktop_height_(kDesktopHeightDefault),
desktop_position_(kDesktopPositionDefault), desktop_position_(kDesktopPositionDefault),
cursor_distance_(-kDesktopPositionDefault.z),
content_cvc_(content_core), content_cvc_(content_core),
delegate_(nullptr), delegate_(nullptr),
weak_ptr_factory_(this) { weak_ptr_factory_(this) {
...@@ -99,8 +104,6 @@ void VrShell::UpdateCompositorLayers(JNIEnv* env, ...@@ -99,8 +104,6 @@ void VrShell::UpdateCompositorLayers(JNIEnv* env,
void VrShell::Destroy(JNIEnv* env, const JavaParamRef<jobject>& obj) { void VrShell::Destroy(JNIEnv* env, const JavaParamRef<jobject>& obj) {
delete this; delete this;
g_instance = nullptr;
gl::init::ClearGLBindings();
} }
bool RegisterVrShell(JNIEnv* env) { bool RegisterVrShell(JNIEnv* env) {
...@@ -108,6 +111,8 @@ bool RegisterVrShell(JNIEnv* env) { ...@@ -108,6 +111,8 @@ bool RegisterVrShell(JNIEnv* env) {
} }
VrShell::~VrShell() { VrShell::~VrShell() {
g_instance = nullptr;
gl::init::ClearGLBindings();
} }
void VrShell::SetDelegate(JNIEnv* env, void VrShell::SetDelegate(JNIEnv* env,
...@@ -182,10 +187,40 @@ void VrShell::UpdateController() { ...@@ -182,10 +187,40 @@ void VrShell::UpdateController() {
translation.z += kHandPosition.z; translation.z += kHandPosition.z;
} }
// We can only be intersecting the desktop plane at the moment. float desktop_dist = scene_.GetUiElementById(kBrowserUiElementId)
float distance_to_plane = desktop_plane_->GetRayDistance(translation, ->GetRayDistance(translation, forward);
forward); gvr::Vec3f cursor_position = GetRayPoint(translation, forward, desktop_dist);
look_at_vector_ = GetRayPoint(translation, forward, distance_to_plane); 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 = 0;
int pixel_y = 0;
for (std::size_t i = 0; i < scene_.GetUiElements().size(); ++i) {
const ContentRectangle& plane = *scene_.GetUiElements()[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) { void ApplyNeckModel(gvr::Mat4f& mat_forward) {
...@@ -237,8 +272,6 @@ void VrShell::DrawFrame(JNIEnv* env, const JavaParamRef<jobject>& obj) { ...@@ -237,8 +272,6 @@ void VrShell::DrawFrame(JNIEnv* env, const JavaParamRef<jobject>& obj) {
void VrShell::DrawVrShell(int64_t time) { void VrShell::DrawVrShell(int64_t time) {
float screen_tilt = desktop_screen_tilt_ * M_PI / 180.0f; float screen_tilt = desktop_screen_tilt_ * M_PI / 180.0f;
forward_vector_ = getForwardVector(head_pose_);
gvr::Vec3f headPos = getTranslation(head_pose_); gvr::Vec3f headPos = getTranslation(head_pose_);
if (headPos.x == 0.0f && headPos.y == 0.0f && headPos.z == 0.0f) { 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. // This appears to be a 3DOF pose without a neck model. Add one.
...@@ -249,9 +282,9 @@ void VrShell::DrawVrShell(int64_t time) { ...@@ -249,9 +282,9 @@ void VrShell::DrawVrShell(int64_t time) {
ApplyNeckModel(head_pose_); ApplyNeckModel(head_pose_);
} }
desktop_plane_->translation.x = desktop_position_.x; forward_vector_ = getForwardVector(head_pose_);
desktop_plane_->translation.y = desktop_position_.y;
desktop_plane_->translation.z = desktop_position_.z; desktop_plane_->translation = desktop_position_;
// Update the render position of all UI elements (including desktop). // Update the render position of all UI elements (including desktop).
scene_.UpdateTransforms(screen_tilt, time); scene_.UpdateTransforms(screen_tilt, time);
...@@ -332,11 +365,15 @@ void VrShell::DrawUI() { ...@@ -332,11 +365,15 @@ void VrShell::DrawUI() {
void VrShell::DrawCursor() { void VrShell::DrawCursor() {
gvr::Mat4f mat; gvr::Mat4f mat;
SetIdentityM(mat); SetIdentityM(mat);
// Scale the pointer.
ScaleM(mat, mat, kReticleWidth, kReticleHeight, 1.0f); // Scale the pointer to have a fixed FOV size at any distance.
ScaleM(mat, mat, kReticleWidth * cursor_distance_,
kReticleHeight * cursor_distance_, 1.0f);
// Place the pointer at the screen plane intersection point. // Place the pointer at the screen plane intersection point.
TranslateM(mat, mat, look_at_vector_.x, look_at_vector_.y, TranslateM(mat, mat, look_at_vector_.x * kReticleZOffset,
look_at_vector_.z + kReticleZOffset); look_at_vector_.y * kReticleZOffset,
look_at_vector_.z * kReticleZOffset);
gvr::Mat4f mv = MatrixMul(view_matrix_, mat); gvr::Mat4f mv = MatrixMul(view_matrix_, mat);
gvr::Mat4f mvp = MatrixMul(projection_matrix_, mv); gvr::Mat4f mvp = MatrixMul(projection_matrix_, mv);
vr_shell_renderer_->GetReticleRenderer()->Draw(mvp); vr_shell_renderer_->GetReticleRenderer()->Draw(mvp);
......
...@@ -113,6 +113,7 @@ class VrShell : public device::GvrDelegate { ...@@ -113,6 +113,7 @@ class VrShell : public device::GvrDelegate {
gvr::Vec3f forward_vector_; gvr::Vec3f forward_vector_;
gvr::Sizei render_size_; gvr::Sizei render_size_;
float cursor_distance_;
std::unique_ptr<VrCompositor> content_compositor_view_; std::unique_ptr<VrCompositor> content_compositor_view_;
content::ContentViewCore* content_cvc_; content::ContentViewCore* content_cvc_;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment