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

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

Issue 2378903005: Implement controller handling in vr_shell.cc (Closed)
Patch Set: 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"
12 #include "chrome/browser/android/vr_shell/vr_controller.h"
cjgrant 2016/09/30 20:26:39 Duplicate include.
mthiesse 2016/10/03 16:30:13 Done.
11 #include "chrome/browser/android/vr_shell/vr_gl_util.h" 13 #include "chrome/browser/android/vr_shell/vr_gl_util.h"
14 #include "chrome/browser/android/vr_shell/vr_input_manager.h"
12 #include "chrome/browser/android/vr_shell/vr_math.h" 15 #include "chrome/browser/android/vr_shell/vr_math.h"
13 #include "chrome/browser/android/vr_shell/vr_shell_delegate.h" 16 #include "chrome/browser/android/vr_shell/vr_shell_delegate.h"
14 #include "chrome/browser/android/vr_shell/vr_shell_renderer.h" 17 #include "chrome/browser/android/vr_shell/vr_shell_renderer.h"
15 #include "content/public/browser/android/content_view_core.h" 18 #include "content/public/browser/android/content_view_core.h"
16 #include "content/public/browser/navigation_controller.h" 19 #include "content/public/browser/navigation_controller.h"
17 #include "content/public/browser/render_widget_host.h" 20 #include "content/public/browser/render_widget_host.h"
18 #include "content/public/browser/render_widget_host_view.h" 21 #include "content/public/browser/render_widget_host_view.h"
19 #include "content/public/browser/web_contents.h" 22 #include "content/public/browser/web_contents.h"
20 #include "content/public/common/referrer.h" 23 #include "content/public/common/referrer.h"
21 #include "jni/VrShell_jni.h" 24 #include "jni/VrShell_jni.h"
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after
174 } 177 }
175 178
176 void VrShell::GvrInit(JNIEnv* env, 179 void VrShell::GvrInit(JNIEnv* env,
177 const JavaParamRef<jobject>& obj, 180 const JavaParamRef<jobject>& obj,
178 jlong native_gvr_api) { 181 jlong native_gvr_api) {
179 gvr_api_ = 182 gvr_api_ =
180 gvr::GvrApi::WrapNonOwned(reinterpret_cast<gvr_context*>(native_gvr_api)); 183 gvr::GvrApi::WrapNonOwned(reinterpret_cast<gvr_context*>(native_gvr_api));
181 184
182 if (delegate_) 185 if (delegate_)
183 delegate_->OnVrShellReady(this); 186 delegate_->OnVrShellReady(this);
187 controller_.reset(
188 new VrController(reinterpret_cast<gvr_context*>(native_gvr_api)));
189 content_input_manager_ = new VrInputManager(content_cvc_->GetWebContents());
190 ui_input_manager_ = new VrInputManager(ui_cvc_->GetWebContents());
184 } 191 }
185 192
186 void VrShell::InitializeGl(JNIEnv* env, 193 void VrShell::InitializeGl(JNIEnv* env,
187 const JavaParamRef<jobject>& obj, 194 const JavaParamRef<jobject>& obj,
188 jint content_texture_handle, 195 jint content_texture_handle,
189 jint ui_texture_handle) { 196 jint ui_texture_handle) {
190 CHECK(gl::GetGLImplementation() != gl::kGLImplementationNone || 197 CHECK(gl::GetGLImplementation() != gl::kGLImplementationNone ||
191 gl::init::InitializeGLOneOff()); 198 gl::init::InitializeGLOneOff());
192 199
193 content_texture_id_ = content_texture_handle; 200 content_texture_id_ = content_texture_handle;
194 ui_texture_id_ = ui_texture_handle; 201 ui_texture_id_ = ui_texture_handle;
195 202
196 gvr_api_->InitializeGl(); 203 gvr_api_->InitializeGl();
197 std::vector<gvr::BufferSpec> specs; 204 std::vector<gvr::BufferSpec> specs;
198 specs.push_back(gvr_api_->CreateBufferSpec()); 205 specs.push_back(gvr_api_->CreateBufferSpec());
199 render_size_ = specs[0].GetSize(); 206 render_size_ = specs[0].GetSize();
200 swap_chain_.reset(new gvr::SwapChain(gvr_api_->CreateSwapchain(specs))); 207 swap_chain_.reset(new gvr::SwapChain(gvr_api_->CreateSwapchain(specs)));
201 208
202 vr_shell_renderer_.reset(new VrShellRenderer()); 209 vr_shell_renderer_.reset(new VrShellRenderer());
203 buffer_viewport_list_.reset( 210 buffer_viewport_list_.reset(
204 new gvr::BufferViewportList(gvr_api_->CreateEmptyBufferViewportList())); 211 new gvr::BufferViewportList(gvr_api_->CreateEmptyBufferViewportList()));
205 buffer_viewport_.reset( 212 buffer_viewport_.reset(
206 new gvr::BufferViewport(gvr_api_->CreateBufferViewport())); 213 new gvr::BufferViewport(gvr_api_->CreateBufferViewport()));
207 } 214 }
208 215
209 void VrShell::UpdateController(const gvr::Vec3f& forward_vector) { 216 void VrShell::UpdateController(const gvr::Vec3f& forward_vector) {
217 controller_->UpdateState();
218 std::unique_ptr<VrGesture> gesture = controller_->DetectGesture();
219
220 // TODO (asimjour) for now, scroll is sent to the main content.
bshe 2016/10/03 12:23:21 nit: s/TODO (asimjour)/TODO(asimjour):
mthiesse 2016/10/03 16:30:13 Done.
221 if (gesture->type == WebInputEvent::GestureScrollBegin ||
222 gesture->type == WebInputEvent::GestureScrollUpdate ||
223 gesture->type == WebInputEvent::GestureScrollEnd) {
224 content_input_manager_->ProcessUpdatedGesture(*gesture.get());
225 }
226
227 WebInputEvent::Type original_type = gesture->type;
228 controller_active_ = controller_->IsConnected();
cjgrant 2016/09/30 20:26:39 Rebase needed.
asimjour1 2016/10/03 15:54:38 It looks that controller_active_ is not needed. yo
mthiesse 2016/10/03 16:30:13 Acknowledged.
mthiesse 2016/10/03 16:30:13 Done.
210 if (!controller_active_) { 229 if (!controller_active_) {
211 // No controller detected, set up a gaze cursor that tracks the 230 // No controller detected, set up a gaze cursor that tracks the
212 // forward direction. 231 // forward direction.
213 controller_quat_ = GetRotationFromZAxis(forward_vector); 232 controller_quat_ = GetRotationFromZAxis(forward_vector);
233 } else {
234 controller_quat_ = controller_->Orientation();
214 } 235 }
215 236
216 gvr::Mat4f mat = QuatToMatrix(controller_quat_); 237 gvr::Mat4f mat = QuatToMatrix(controller_quat_);
217 gvr::Vec3f forward = MatrixVectorMul(mat, kNeutralPose); 238 gvr::Vec3f forward = MatrixVectorMul(mat, kNeutralPose);
218 gvr::Vec3f origin = kHandPosition; 239 gvr::Vec3f origin = kHandPosition;
219 240
220 target_element_ = nullptr;; 241 target_element_ = nullptr;;
221 float distance = scene_.GetUiElementById(kBrowserUiElementId) 242 float distance = scene_.GetUiElementById(kBrowserUiElementId)
222 ->GetRayDistance(origin, forward); 243 ->GetRayDistance(origin, forward);
223 244
224 // Find distance to a corner of the content quad, and limit the cursor 245 // 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 246 // 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 247 // the content plane near the content window, and on the surface of a sphere
227 // in other directions. 248 // in other directions.
228 // TODO(cjgrant): Note that this approach uses distance from controller, 249 // TODO(cjgrant): Note that this approach uses distance from controller,
229 // rather than eye, for simplicity. This will make the sphere slightly 250 // rather than eye, for simplicity. This will make the sphere slightly
230 // off-center. 251 // off-center.
231 gvr::Vec3f corner = {0.5f, 0.5f, 0.0f}; 252 gvr::Vec3f corner = {0.5f, 0.5f, 0.0f};
232 corner = MatrixVectorMul(desktop_plane_->transform.to_world, corner); 253 corner = MatrixVectorMul(desktop_plane_->transform.to_world, corner);
233 float max_distance = Distance(origin, corner) * kReticleDistanceMultiplier; 254 float max_distance = Distance(origin, corner) * kReticleDistanceMultiplier;
234 if (distance > max_distance || distance <= 0.0f) { 255 if (distance > max_distance || distance <= 0.0f) {
235 distance = max_distance; 256 distance = max_distance;
236 } 257 }
237 target_point_ = GetRayPoint(origin, forward, distance); 258 target_point_ = GetRayPoint(origin, forward, distance);
238 259
239 // Determine which UI element (if any) the cursor is pointing to. 260 // Determine which UI element (if any) the cursor is pointing to.
261 int closest_element_index = -1;
240 float closest_element = std::numeric_limits<float>::infinity(); 262 float closest_element = std::numeric_limits<float>::infinity();
bshe 2016/10/03 12:23:21 nit: s/closest_element/closest_element_distance ?
mthiesse 2016/10/03 16:30:13 Done.
263 int pixel_x = 0;
264 int pixel_y = 0;
241 for (std::size_t i = 0; i < scene_.GetUiElements().size(); ++i) { 265 for (std::size_t i = 0; i < scene_.GetUiElements().size(); ++i) {
242 const ContentRectangle& plane = *scene_.GetUiElements()[i].get(); 266 const ContentRectangle& plane = *scene_.GetUiElements()[i].get();
267 if (!plane.visible) {
268 continue;
269 }
243 float distance_to_plane = plane.GetRayDistance(origin, forward); 270 float distance_to_plane = plane.GetRayDistance(origin, forward);
244 gvr::Vec3f plane_intersection_point = 271 gvr::Vec3f plane_intersection_point =
245 GetRayPoint(origin, forward, distance_to_plane); 272 GetRayPoint(origin, forward, distance_to_plane);
246 273
247 gvr::Vec3f rect_2d_point = 274 gvr::Vec3f rect_2d_point =
248 MatrixVectorMul(plane.transform.from_world, plane_intersection_point); 275 MatrixVectorMul(plane.transform.from_world, plane_intersection_point);
249 float x = rect_2d_point.x + 0.5f; 276 float x = rect_2d_point.x + 0.5f;
250 float y = 0.5f - rect_2d_point.y; 277 float y = 0.5f - rect_2d_point.y;
251 if (distance_to_plane > 0 && distance_to_plane < closest_element) { 278 if (distance_to_plane > 0 && distance_to_plane < closest_element) {
252 bool is_inside = x >= 0.0f && x < 1.0f && y >= 0.0f && y < 1.0f; 279 bool is_inside = x >= 0.0f && x < 1.0f && y >= 0.0f && y < 1.0f;
253 if (is_inside) { 280 if (is_inside) {
281 closest_element_index = i;
254 closest_element = distance_to_plane; 282 closest_element = distance_to_plane;
283 pixel_x =
284 static_cast<int>(plane.copy_rect.width * x + plane.copy_rect.x);
285 pixel_y =
286 static_cast<int>(plane.copy_rect.height * y + plane.copy_rect.y);
287
255 target_point_ = plane_intersection_point; 288 target_point_ = plane_intersection_point;
256 target_element_ = &plane; 289 target_element_ = &plane;
257 } 290 }
258 } 291 }
259 } 292 }
293 if (closest_element_index != current_ui_rect_ && current_ui_rect_ >= 0) {
294 // Send a move event indicating that the pointer moved off of an element.
295 gesture->type = WebInputEvent::MouseMove;
296 gesture->details.move.delta.x = 0;
297 gesture->details.move.delta.y = 0;
298 gesture->details.move.type = 2;
cjgrant 2016/09/30 20:26:39 Type should be an enum.
mthiesse 2016/10/03 16:30:13 Done.
299 if (current_ui_rect_ == 0) {
cjgrant 2016/09/30 20:26:39 kBrowserUiElementId
mthiesse 2016/10/03 16:30:13 Done.
300 content_input_manager_->ProcessUpdatedGesture(*gesture.get());
301 } else {
302 ui_input_manager_->ProcessUpdatedGesture(*gesture.get());
303 }
304 current_ui_rect_ = 1;
bshe 2016/10/03 12:23:21 why 1?
mthiesse 2016/10/03 16:30:12 Removed.
305 }
306
307 if (closest_element_index >= 0) {
308 if (current_ui_rect_ != closest_element_index) {
309 gesture->type = WebInputEvent::MouseMove;
310 gesture->details.move.delta.x = pixel_x;
311 gesture->details.move.delta.y = pixel_y;
312 gesture->details.move.type = 1;
cjgrant 2016/09/30 20:26:39 Enum here as well, and elsewhere.
mthiesse 2016/10/03 16:30:12 Done.
313 if (closest_element_index > 0) {
cjgrant 2016/09/30 20:26:39 != kBrowserUiElementId, here and elsewhere.
mthiesse 2016/10/03 16:30:13 Done.
314 ui_input_manager_->ProcessUpdatedGesture(*gesture.get());
315 } else {
316 content_input_manager_->ProcessUpdatedGesture(*gesture.get());
317 }
318 }
319 if (closest_element_index > 0) {
320 if (original_type == WebInputEvent::GestureTap) {
321 gesture->type = WebInputEvent::GestureTap;
322 gesture->details.buttons.pos.x = pixel_x;
323 gesture->details.buttons.pos.y = pixel_y;
324 ui_input_manager_->ProcessUpdatedGesture(*gesture.get());
325 }
326 gesture->type = WebInputEvent::MouseMove;
327 gesture->details.move.delta.x = pixel_x;
328 gesture->details.move.delta.y = pixel_y;
329 gesture->details.move.type = 0;
330 ui_input_manager_->ProcessUpdatedGesture(*gesture.get());
bshe 2016/10/03 12:23:21 it looks like line 320 - 330 is very similar to li
mthiesse 2016/10/03 16:30:13 Done.
331 } else {
332 if (original_type == WebInputEvent::GestureTap) {
333 gesture->type = WebInputEvent::GestureTap;
334 gesture->details.buttons.pos.x = pixel_x;
335 gesture->details.buttons.pos.y = pixel_y;
336 content_input_manager_->ProcessUpdatedGesture(*gesture.get());
337 }
338 gesture->type = WebInputEvent::MouseMove;
339 gesture->details.move.delta.x = pixel_x;
340 gesture->details.move.delta.y = pixel_y;
341 gesture->details.move.type = 0;
342 content_input_manager_->ProcessUpdatedGesture(*gesture.get());
343 }
344 current_ui_rect_ = closest_element_index;
345 }
260 } 346 }
261 347
262 void ApplyNeckModel(gvr::Mat4f& mat_forward) { 348 void ApplyNeckModel(gvr::Mat4f& mat_forward) {
263 // This assumes that the input matrix is a pure rotation matrix. The 349 // This assumes that the input matrix is a pure rotation matrix. The
264 // input object_from_reference matrix has the inverse rotation of 350 // input object_from_reference matrix has the inverse rotation of
265 // the head rotation. Invert it (this is just a transpose). 351 // the head rotation. Invert it (this is just a transpose).
266 gvr::Mat4f mat = MatrixTranspose(mat_forward); 352 gvr::Mat4f mat = MatrixTranspose(mat_forward);
267 353
268 // Position of the point between the eyes, relative to the neck pivot: 354 // Position of the point between the eyes, relative to the neck pivot:
269 const float kNeckHorizontalOffset = -0.080f; // meters in Z 355 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_); 556 vr_shell_renderer_->GetWebVrRenderer()->Draw(content_texture_id_);
471 557
472 if (!webvr_secure_origin_) { 558 if (!webvr_secure_origin_) {
473 // TODO(klausw): Draw the insecure origin warning here. 559 // TODO(klausw): Draw the insecure origin warning here.
474 } 560 }
475 } 561 }
476 562
477 void VrShell::OnPause(JNIEnv* env, const JavaParamRef<jobject>& obj) { 563 void VrShell::OnPause(JNIEnv* env, const JavaParamRef<jobject>& obj) {
478 if (gvr_api_ == nullptr) 564 if (gvr_api_ == nullptr)
479 return; 565 return;
566 controller_->OnPause();
480 gvr_api_->PauseTracking(); 567 gvr_api_->PauseTracking();
481 } 568 }
482 569
483 void VrShell::OnResume(JNIEnv* env, const JavaParamRef<jobject>& obj) { 570 void VrShell::OnResume(JNIEnv* env, const JavaParamRef<jobject>& obj) {
484 if (gvr_api_ == nullptr) 571 if (gvr_api_ == nullptr)
485 return; 572 return;
486 573
487 gvr_api_->RefreshViewerProfile(); 574 gvr_api_->RefreshViewerProfile();
488 gvr_api_->ResumeTracking(); 575 gvr_api_->ResumeTracking();
576 controller_->OnResume();
489 } 577 }
490 578
491 base::WeakPtr<VrShell> VrShell::GetWeakPtr() { 579 base::WeakPtr<VrShell> VrShell::GetWeakPtr() {
492 // TODO: Ensure that only ui webcontents can request this weak ptr. 580 // TODO: Ensure that only ui webcontents can request this weak ptr.
493 if (g_instance != nullptr) 581 if (g_instance != nullptr)
494 return g_instance->weak_ptr_factory_.GetWeakPtr(); 582 return g_instance->weak_ptr_factory_.GetWeakPtr();
495 return base::WeakPtr<VrShell>(nullptr); 583 return base::WeakPtr<VrShell>(nullptr);
496 } 584 }
497 585
498 void VrShell::OnDomContentsLoaded() { 586 void VrShell::OnDomContentsLoaded() {
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
593 content::WebContents::FromJavaWebContents(content_web_contents)); 681 content::WebContents::FromJavaWebContents(content_web_contents));
594 content::ContentViewCore* ui_core = content::ContentViewCore::FromWebContents( 682 content::ContentViewCore* ui_core = content::ContentViewCore::FromWebContents(
595 content::WebContents::FromJavaWebContents(ui_web_contents)); 683 content::WebContents::FromJavaWebContents(ui_web_contents));
596 return reinterpret_cast<intptr_t>(new VrShell( 684 return reinterpret_cast<intptr_t>(new VrShell(
597 env, obj, c_core, 685 env, obj, c_core,
598 reinterpret_cast<ui::WindowAndroid*>(content_window_android), ui_core, 686 reinterpret_cast<ui::WindowAndroid*>(content_window_android), ui_core,
599 reinterpret_cast<ui::WindowAndroid*>(ui_window_android))); 687 reinterpret_cast<ui::WindowAndroid*>(ui_window_android)));
600 } 688 }
601 689
602 } // namespace vr_shell 690 } // namespace vr_shell
OLDNEW
« chrome/browser/android/vr_shell/vr_shell.h ('K') | « chrome/browser/android/vr_shell/vr_shell.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698