Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(129)

Side by Side Diff: chrome/browser/android/vr_shell/vr_shell.cc

Issue 2378903005: Implement controller handling in vr_shell.cc (Closed)
Patch Set: Rebase Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 <thread> 7 #include <thread>
8 8
9 #include "chrome/browser/android/vr_shell/ui_scene.h" 9 #include "chrome/browser/android/vr_shell/ui_scene.h"
10 #include "chrome/browser/android/vr_shell/vr_compositor.h" 10 #include "chrome/browser/android/vr_shell/vr_compositor.h"
11 #include "chrome/browser/android/vr_shell/vr_controller.h"
11 #include "chrome/browser/android/vr_shell/vr_gl_util.h" 12 #include "chrome/browser/android/vr_shell/vr_gl_util.h"
13 #include "chrome/browser/android/vr_shell/vr_input_manager.h"
12 #include "chrome/browser/android/vr_shell/vr_math.h" 14 #include "chrome/browser/android/vr_shell/vr_math.h"
13 #include "chrome/browser/android/vr_shell/vr_shell_delegate.h" 15 #include "chrome/browser/android/vr_shell/vr_shell_delegate.h"
14 #include "chrome/browser/android/vr_shell/vr_shell_renderer.h" 16 #include "chrome/browser/android/vr_shell/vr_shell_renderer.h"
15 #include "content/public/browser/android/content_view_core.h" 17 #include "content/public/browser/android/content_view_core.h"
16 #include "content/public/browser/navigation_controller.h" 18 #include "content/public/browser/navigation_controller.h"
17 #include "content/public/browser/render_widget_host.h" 19 #include "content/public/browser/render_widget_host.h"
18 #include "content/public/browser/render_widget_host_view.h" 20 #include "content/public/browser/render_widget_host_view.h"
19 #include "content/public/browser/web_contents.h" 21 #include "content/public/browser/web_contents.h"
20 #include "content/public/common/referrer.h" 22 #include "content/public/common/referrer.h"
21 #include "jni/VrShell_jni.h" 23 #include "jni/VrShell_jni.h"
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after
174 } 176 }
175 177
176 void VrShell::GvrInit(JNIEnv* env, 178 void VrShell::GvrInit(JNIEnv* env,
177 const JavaParamRef<jobject>& obj, 179 const JavaParamRef<jobject>& obj,
178 jlong native_gvr_api) { 180 jlong native_gvr_api) {
179 gvr_api_ = 181 gvr_api_ =
180 gvr::GvrApi::WrapNonOwned(reinterpret_cast<gvr_context*>(native_gvr_api)); 182 gvr::GvrApi::WrapNonOwned(reinterpret_cast<gvr_context*>(native_gvr_api));
181 183
182 if (delegate_) 184 if (delegate_)
183 delegate_->OnVrShellReady(this); 185 delegate_->OnVrShellReady(this);
186 controller_.reset(
187 new VrController(reinterpret_cast<gvr_context*>(native_gvr_api)));
188 content_input_manager_ = new VrInputManager(content_cvc_->GetWebContents());
189 ui_input_manager_ = new VrInputManager(ui_cvc_->GetWebContents());
184 } 190 }
185 191
186 void VrShell::InitializeGl(JNIEnv* env, 192 void VrShell::InitializeGl(JNIEnv* env,
187 const JavaParamRef<jobject>& obj, 193 const JavaParamRef<jobject>& obj,
188 jint content_texture_handle, 194 jint content_texture_handle,
189 jint ui_texture_handle) { 195 jint ui_texture_handle) {
190 CHECK(gl::GetGLImplementation() != gl::kGLImplementationNone || 196 CHECK(gl::GetGLImplementation() != gl::kGLImplementationNone ||
191 gl::init::InitializeGLOneOff()); 197 gl::init::InitializeGLOneOff());
192 198
193 content_texture_id_ = content_texture_handle; 199 content_texture_id_ = content_texture_handle;
194 ui_texture_id_ = ui_texture_handle; 200 ui_texture_id_ = ui_texture_handle;
195 201
196 gvr_api_->InitializeGl(); 202 gvr_api_->InitializeGl();
197 std::vector<gvr::BufferSpec> specs; 203 std::vector<gvr::BufferSpec> specs;
198 specs.push_back(gvr_api_->CreateBufferSpec()); 204 specs.push_back(gvr_api_->CreateBufferSpec());
199 render_size_ = specs[0].GetSize(); 205 render_size_ = specs[0].GetSize();
200 swap_chain_.reset(new gvr::SwapChain(gvr_api_->CreateSwapchain(specs))); 206 swap_chain_.reset(new gvr::SwapChain(gvr_api_->CreateSwapchain(specs)));
201 207
202 vr_shell_renderer_.reset(new VrShellRenderer()); 208 vr_shell_renderer_.reset(new VrShellRenderer());
203 buffer_viewport_list_.reset( 209 buffer_viewport_list_.reset(
204 new gvr::BufferViewportList(gvr_api_->CreateEmptyBufferViewportList())); 210 new gvr::BufferViewportList(gvr_api_->CreateEmptyBufferViewportList()));
205 buffer_viewport_.reset( 211 buffer_viewport_.reset(
206 new gvr::BufferViewport(gvr_api_->CreateBufferViewport())); 212 new gvr::BufferViewport(gvr_api_->CreateBufferViewport()));
207 } 213 }
208 214
209 void VrShell::UpdateController(const gvr::Vec3f& forward_vector) { 215 void VrShell::UpdateController(const gvr::Vec3f& forward_vector) {
210 if (!controller_active_) { 216 controller_->UpdateState();
217 std::unique_ptr<VrGesture> gesture = controller_->DetectGesture();
218
219 // TODO(asimjour) for now, scroll is sent to the main content.
220 if (gesture->type == WebInputEvent::GestureScrollBegin ||
221 gesture->type == WebInputEvent::GestureScrollUpdate ||
222 gesture->type == WebInputEvent::GestureScrollEnd) {
223 content_input_manager_->ProcessUpdatedGesture(*gesture.get());
224 }
225
226 WebInputEvent::Type original_type = gesture->type;
227 if (!controller_->IsConnected()) {
211 // No controller detected, set up a gaze cursor that tracks the 228 // No controller detected, set up a gaze cursor that tracks the
212 // forward direction. 229 // forward direction.
213 controller_quat_ = GetRotationFromZAxis(forward_vector); 230 controller_quat_ = GetRotationFromZAxis(forward_vector);
231 } else {
232 controller_quat_ = controller_->Orientation();
214 } 233 }
215 234
216 gvr::Mat4f mat = QuatToMatrix(controller_quat_); 235 gvr::Mat4f mat = QuatToMatrix(controller_quat_);
217 gvr::Vec3f forward = MatrixVectorMul(mat, kNeutralPose); 236 gvr::Vec3f forward = MatrixVectorMul(mat, kNeutralPose);
218 gvr::Vec3f origin = kHandPosition; 237 gvr::Vec3f origin = kHandPosition;
219 238
220 target_element_ = nullptr;; 239 target_element_ = nullptr;
221 float distance = scene_.GetUiElementById(kBrowserUiElementId) 240 float distance = scene_.GetUiElementById(kBrowserUiElementId)
222 ->GetRayDistance(origin, forward); 241 ->GetRayDistance(origin, forward);
223 242
224 // Find distance to a corner of the content quad, and limit the cursor 243 // Find distance to a corner of the content quad, and limit the cursor
225 // distance to a multiple of that distance. This lets us keep the reticle on 244 // distance to a multiple of that distance. This lets us keep the reticle on
226 // the content plane near the content window, and on the surface of a sphere 245 // the content plane near the content window, and on the surface of a sphere
227 // in other directions. 246 // in other directions.
228 // TODO(cjgrant): Note that this approach uses distance from controller, 247 // TODO(cjgrant): Note that this approach uses distance from controller,
229 // rather than eye, for simplicity. This will make the sphere slightly 248 // rather than eye, for simplicity. This will make the sphere slightly
230 // off-center. 249 // off-center.
231 gvr::Vec3f corner = {0.5f, 0.5f, 0.0f}; 250 gvr::Vec3f corner = {0.5f, 0.5f, 0.0f};
232 corner = MatrixVectorMul(desktop_plane_->transform.to_world, corner); 251 corner = MatrixVectorMul(desktop_plane_->transform.to_world, corner);
233 float max_distance = Distance(origin, corner) * kReticleDistanceMultiplier; 252 float max_distance = Distance(origin, corner) * kReticleDistanceMultiplier;
234 if (distance > max_distance || distance <= 0.0f) { 253 if (distance > max_distance || distance <= 0.0f) {
235 distance = max_distance; 254 distance = max_distance;
236 } 255 }
237 target_point_ = GetRayPoint(origin, forward, distance); 256 target_point_ = GetRayPoint(origin, forward, distance);
238 257
239 // Determine which UI element (if any) the cursor is pointing to. 258 // Determine which UI element (if any) the cursor is pointing to.
240 float closest_element = std::numeric_limits<float>::infinity(); 259 float closest_element_distance = std::numeric_limits<float>::infinity();
260 int pixel_x = 0;
261 int pixel_y = 0;
262 VrInputManager* input_target = nullptr;
263
241 for (std::size_t i = 0; i < scene_.GetUiElements().size(); ++i) { 264 for (std::size_t i = 0; i < scene_.GetUiElements().size(); ++i) {
242 const ContentRectangle& plane = *scene_.GetUiElements()[i].get(); 265 const ContentRectangle& plane = *scene_.GetUiElements()[i].get();
266 if (!plane.visible) {
267 continue;
268 }
243 float distance_to_plane = plane.GetRayDistance(origin, forward); 269 float distance_to_plane = plane.GetRayDistance(origin, forward);
244 gvr::Vec3f plane_intersection_point = 270 gvr::Vec3f plane_intersection_point =
245 GetRayPoint(origin, forward, distance_to_plane); 271 GetRayPoint(origin, forward, distance_to_plane);
246 272
247 gvr::Vec3f rect_2d_point = 273 gvr::Vec3f rect_2d_point =
248 MatrixVectorMul(plane.transform.from_world, plane_intersection_point); 274 MatrixVectorMul(plane.transform.from_world, plane_intersection_point);
249 float x = rect_2d_point.x + 0.5f; 275 float x = rect_2d_point.x + 0.5f;
250 float y = 0.5f - rect_2d_point.y; 276 float y = 0.5f - rect_2d_point.y;
251 if (distance_to_plane > 0 && distance_to_plane < closest_element) { 277 if (distance_to_plane > 0 && distance_to_plane < closest_element_distance) {
252 bool is_inside = x >= 0.0f && x < 1.0f && y >= 0.0f && y < 1.0f; 278 bool is_inside = x >= 0.0f && x < 1.0f && y >= 0.0f && y < 1.0f;
253 if (is_inside) { 279 if (is_inside) {
254 closest_element = distance_to_plane; 280 closest_element_distance = distance_to_plane;
281 pixel_x =
282 static_cast<int>(plane.copy_rect.width * x + plane.copy_rect.x);
283 pixel_y =
284 static_cast<int>(plane.copy_rect.height * y + plane.copy_rect.y);
285
255 target_point_ = plane_intersection_point; 286 target_point_ = plane_intersection_point;
256 target_element_ = &plane; 287 target_element_ = &plane;
288 input_target = (plane.id == kBrowserUiElementId)
289 ? content_input_manager_.get() : ui_input_manager_.get();
257 } 290 }
258 } 291 }
259 } 292 }
293 bool new_target = input_target != current_input_target_;
294 if (new_target && current_input_target_ != nullptr) {
295 // Send a move event indicating that the pointer moved off of an element.
296 gesture->type = WebInputEvent::MouseLeave;
297 gesture->details.move.delta.x = 0;
298 gesture->details.move.delta.y = 0;
299 current_input_target_->ProcessUpdatedGesture(*gesture.get());
300 }
301 current_input_target_ = input_target;
302 if (current_input_target_ == nullptr) {
303 return;
304 }
305
306 gesture->type = new_target ? WebInputEvent::MouseEnter
307 : WebInputEvent::MouseMove;
308 gesture->details.move.delta.x = pixel_x;
asimjour1 2016/10/04 13:30:07 On the experimental branch we have gesture->detai
mthiesse 2016/10/04 14:05:26 It actually doesn't work yet, because the copy rec
309 gesture->details.move.delta.y = pixel_y;
310 current_input_target_->ProcessUpdatedGesture(*gesture.get());
311
312 if (original_type == WebInputEvent::GestureTap) {
313 gesture->type = WebInputEvent::GestureTap;
314 gesture->details.buttons.pos.x = pixel_x;
asimjour1 2016/10/04 13:30:07 same as above
mthiesse 2016/10/04 14:05:26 Acknowledged.
315 gesture->details.buttons.pos.y = pixel_y;
316 current_input_target_->ProcessUpdatedGesture(*gesture.get());
317 }
260 } 318 }
261 319
262 void ApplyNeckModel(gvr::Mat4f& mat_forward) { 320 void ApplyNeckModel(gvr::Mat4f& mat_forward) {
263 // This assumes that the input matrix is a pure rotation matrix. The 321 // This assumes that the input matrix is a pure rotation matrix. The
264 // input object_from_reference matrix has the inverse rotation of 322 // input object_from_reference matrix has the inverse rotation of
265 // the head rotation. Invert it (this is just a transpose). 323 // the head rotation. Invert it (this is just a transpose).
266 gvr::Mat4f mat = MatrixTranspose(mat_forward); 324 gvr::Mat4f mat = MatrixTranspose(mat_forward);
267 325
268 // Position of the point between the eyes, relative to the neck pivot: 326 // Position of the point between the eyes, relative to the neck pivot:
269 const float kNeckHorizontalOffset = -0.080f; // meters in Z 327 const float kNeckHorizontalOffset = -0.080f; // meters in Z
(...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after
470 vr_shell_renderer_->GetWebVrRenderer()->Draw(content_texture_id_); 528 vr_shell_renderer_->GetWebVrRenderer()->Draw(content_texture_id_);
471 529
472 if (!webvr_secure_origin_) { 530 if (!webvr_secure_origin_) {
473 // TODO(klausw): Draw the insecure origin warning here. 531 // TODO(klausw): Draw the insecure origin warning here.
474 } 532 }
475 } 533 }
476 534
477 void VrShell::OnPause(JNIEnv* env, const JavaParamRef<jobject>& obj) { 535 void VrShell::OnPause(JNIEnv* env, const JavaParamRef<jobject>& obj) {
478 if (gvr_api_ == nullptr) 536 if (gvr_api_ == nullptr)
479 return; 537 return;
538 controller_->OnPause();
480 gvr_api_->PauseTracking(); 539 gvr_api_->PauseTracking();
481 } 540 }
482 541
483 void VrShell::OnResume(JNIEnv* env, const JavaParamRef<jobject>& obj) { 542 void VrShell::OnResume(JNIEnv* env, const JavaParamRef<jobject>& obj) {
484 if (gvr_api_ == nullptr) 543 if (gvr_api_ == nullptr)
485 return; 544 return;
486 545
487 gvr_api_->RefreshViewerProfile(); 546 gvr_api_->RefreshViewerProfile();
488 gvr_api_->ResumeTracking(); 547 gvr_api_->ResumeTracking();
548 controller_->OnResume();
489 } 549 }
490 550
491 base::WeakPtr<VrShell> VrShell::GetWeakPtr() { 551 base::WeakPtr<VrShell> VrShell::GetWeakPtr() {
492 // TODO: Ensure that only ui webcontents can request this weak ptr. 552 // TODO: Ensure that only ui webcontents can request this weak ptr.
493 if (g_instance != nullptr) 553 if (g_instance != nullptr)
494 return g_instance->weak_ptr_factory_.GetWeakPtr(); 554 return g_instance->weak_ptr_factory_.GetWeakPtr();
495 return base::WeakPtr<VrShell>(nullptr); 555 return base::WeakPtr<VrShell>(nullptr);
496 } 556 }
497 557
498 void VrShell::OnDomContentsLoaded() { 558 void VrShell::OnDomContentsLoaded() {
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
593 content::WebContents::FromJavaWebContents(content_web_contents)); 653 content::WebContents::FromJavaWebContents(content_web_contents));
594 content::ContentViewCore* ui_core = content::ContentViewCore::FromWebContents( 654 content::ContentViewCore* ui_core = content::ContentViewCore::FromWebContents(
595 content::WebContents::FromJavaWebContents(ui_web_contents)); 655 content::WebContents::FromJavaWebContents(ui_web_contents));
596 return reinterpret_cast<intptr_t>(new VrShell( 656 return reinterpret_cast<intptr_t>(new VrShell(
597 env, obj, c_core, 657 env, obj, c_core,
598 reinterpret_cast<ui::WindowAndroid*>(content_window_android), ui_core, 658 reinterpret_cast<ui::WindowAndroid*>(content_window_android), ui_core,
599 reinterpret_cast<ui::WindowAndroid*>(ui_window_android))); 659 reinterpret_cast<ui::WindowAndroid*>(ui_window_android)));
600 } 660 }
601 661
602 } // namespace vr_shell 662 } // namespace vr_shell
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698