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

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

Issue 2770353002: WebVR: add angular velocity estimate to pose (Closed)
Patch Set: Enable linear accel, fix angular velocity to be in seated space Created 3 years, 8 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 <android/native_window_jni.h> 7 #include <android/native_window_jni.h>
8 8
9 #include <string> 9 #include <string>
10 #include <utility> 10 #include <utility>
11 11
12 #include "base/android/jni_string.h" 12 #include "base/android/jni_string.h"
13 #include "base/memory/ptr_util.h" 13 #include "base/memory/ptr_util.h"
14 #include "base/metrics/histogram_macros.h" 14 #include "base/metrics/histogram_macros.h"
15 #include "base/threading/platform_thread.h" 15 #include "base/threading/platform_thread.h"
16 #include "base/threading/thread.h" 16 #include "base/threading/thread.h"
17 #include "base/threading/thread_restrictions.h" 17 #include "base/threading/thread_restrictions.h"
18 #include "base/threading/thread_task_runner_handle.h" 18 #include "base/threading/thread_task_runner_handle.h"
19 #include "base/values.h" 19 #include "base/values.h"
20 #include "chrome/browser/android/tab_android.h" 20 #include "chrome/browser/android/tab_android.h"
21 #include "chrome/browser/android/vr_shell/android_ui_gesture_target.h" 21 #include "chrome/browser/android/vr_shell/android_ui_gesture_target.h"
22 #include "chrome/browser/android/vr_shell/vr_compositor.h" 22 #include "chrome/browser/android/vr_shell/vr_compositor.h"
23 #include "chrome/browser/android/vr_shell/vr_gl_thread.h" 23 #include "chrome/browser/android/vr_shell/vr_gl_thread.h"
24 #include "chrome/browser/android/vr_shell/vr_input_manager.h" 24 #include "chrome/browser/android/vr_shell/vr_input_manager.h"
25 #include "chrome/browser/android/vr_shell/vr_math.h"
25 #include "chrome/browser/android/vr_shell/vr_shell_delegate.h" 26 #include "chrome/browser/android/vr_shell/vr_shell_delegate.h"
26 #include "chrome/browser/android/vr_shell/vr_shell_gl.h" 27 #include "chrome/browser/android/vr_shell/vr_shell_gl.h"
27 #include "chrome/browser/android/vr_shell/vr_usage_monitor.h" 28 #include "chrome/browser/android/vr_shell/vr_usage_monitor.h"
28 #include "chrome/browser/android/vr_shell/vr_web_contents_observer.h" 29 #include "chrome/browser/android/vr_shell/vr_web_contents_observer.h"
29 #include "content/public/browser/navigation_controller.h" 30 #include "content/public/browser/navigation_controller.h"
30 #include "content/public/browser/render_view_host.h" 31 #include "content/public/browser/render_view_host.h"
31 #include "content/public/browser/render_widget_host.h" 32 #include "content/public/browser/render_widget_host.h"
32 #include "content/public/browser/render_widget_host_view.h" 33 #include "content/public/browser/render_widget_host_view.h"
33 #include "content/public/browser/web_contents.h" 34 #include "content/public/browser/web_contents.h"
34 #include "content/public/common/content_features.h" 35 #include "content/public/common/content_features.h"
(...skipping 613 matching lines...) Expand 10 before | Expand all | Expand 10 after
648 } 649 }
649 } 650 }
650 651
651 void VrShell::RegisterGamepadDataFetcher( 652 void VrShell::RegisterGamepadDataFetcher(
652 device::GvrGamepadDataFetcher* fetcher) { 653 device::GvrGamepadDataFetcher* fetcher) {
653 DVLOG(1) << __FUNCTION__ << "(" << fetcher << ")"; 654 DVLOG(1) << __FUNCTION__ << "(" << fetcher << ")";
654 gamepad_data_fetcher_ = fetcher; 655 gamepad_data_fetcher_ = fetcher;
655 } 656 }
656 657
657 /* static */ 658 /* static */
658 device::mojom::VRPosePtr VrShell::VRPosePtrFromGvrPose(gvr::Mat4f head_mat) { 659 device::mojom::VRPosePtr VrShell::VRPosePtrFromGvrPose(gvr::Mat4f head_mat,
660 gvr::Mat4f head_mat_2,
661 int64_t epsilon_nanos) {
659 device::mojom::VRPosePtr pose = device::mojom::VRPose::New(); 662 device::mojom::VRPosePtr pose = device::mojom::VRPose::New();
660 663
661 pose->orientation.emplace(4); 664 pose->orientation.emplace(4);
662 665
663 gfx::Transform inv_transform( 666 gfx::Transform inv_transform(
664 head_mat.m[0][0], head_mat.m[0][1], head_mat.m[0][2], head_mat.m[0][3], 667 head_mat.m[0][0], head_mat.m[0][1], head_mat.m[0][2], head_mat.m[0][3],
665 head_mat.m[1][0], head_mat.m[1][1], head_mat.m[1][2], head_mat.m[1][3], 668 head_mat.m[1][0], head_mat.m[1][1], head_mat.m[1][2], head_mat.m[1][3],
666 head_mat.m[2][0], head_mat.m[2][1], head_mat.m[2][2], head_mat.m[2][3], 669 head_mat.m[2][0], head_mat.m[2][1], head_mat.m[2][2], head_mat.m[2][3],
667 head_mat.m[3][0], head_mat.m[3][1], head_mat.m[3][2], head_mat.m[3][3]); 670 head_mat.m[3][0], head_mat.m[3][1], head_mat.m[3][2], head_mat.m[3][3]);
668 671
669 gfx::Transform transform; 672 gfx::Transform transform;
670 if (inv_transform.GetInverse(&transform)) { 673 if (inv_transform.GetInverse(&transform)) {
671 gfx::DecomposedTransform decomposed_transform; 674 gfx::DecomposedTransform decomposed_transform;
672 gfx::DecomposeTransform(&decomposed_transform, transform); 675 gfx::DecomposeTransform(&decomposed_transform, transform);
673 676
674 pose->orientation.value()[0] = decomposed_transform.quaternion[0]; 677 pose->orientation.value()[0] = decomposed_transform.quaternion[0];
675 pose->orientation.value()[1] = decomposed_transform.quaternion[1]; 678 pose->orientation.value()[1] = decomposed_transform.quaternion[1];
676 pose->orientation.value()[2] = decomposed_transform.quaternion[2]; 679 pose->orientation.value()[2] = decomposed_transform.quaternion[2];
677 pose->orientation.value()[3] = decomposed_transform.quaternion[3]; 680 pose->orientation.value()[3] = decomposed_transform.quaternion[3];
678 681
679 pose->position.emplace(3); 682 pose->position.emplace(3);
680 pose->position.value()[0] = decomposed_transform.translate[0]; 683 pose->position.value()[0] = decomposed_transform.translate[0];
681 pose->position.value()[1] = decomposed_transform.translate[1]; 684 pose->position.value()[1] = decomposed_transform.translate[1];
682 pose->position.value()[2] = decomposed_transform.translate[2]; 685 pose->position.value()[2] = decomposed_transform.translate[2];
683 } 686 }
684 687
688 // The angular velocity is a 3-element vector pointing along the rotation
689 // axis with magnitude equal to rotation speed in radians/second, expressed
690 // in the seated frame of reference.
691 //
692 // The spec isn't very clear on details, clarification requested in
693 // https://github.com/w3c/webvr/issues/212 .
694 //
695 // Assuming that pose prediction is simply based on adding a time * angular
696 // velocity rotation to the pose, we can approximate the angular velocity
697 // from the difference between two successive poses. This is a first order
698 // estimate that assumes small enough rotations so that we can do linear
699 // approximation.
700 //
701 // See:
702 // https://en.wikipedia.org/wiki/Angular_velocity#Calculation_from_the_orienta tion_matrix
703 pose->angularVelocity.emplace(3);
704 // Assume that epsilon is nonzero since it's a compile-time constant
705 // provided by the caller.
706 double epsilon_seconds = epsilon_nanos * 1e-9;
707 gvr::Mat4f delta_mat;
708 gvr::Mat4f inverse_head_mat;
709 // Calculate difference matrix, and inverse head matrix rotation.
710 // For the inverse rotation, just transpose the 3x3 subsection.
711 for (int j = 0; j < 3; ++j) {
712 for (int i = 0; i < 3; ++i) {
713 delta_mat.m[j][i] =
714 (head_mat_2.m[j][i] - head_mat.m[j][i]) / epsilon_seconds;
715 inverse_head_mat.m[j][i] = head_mat.m[i][j];
716 }
717 delta_mat.m[j][3] = delta_mat.m[3][j] = 0.0;
718 inverse_head_mat.m[j][3] = inverse_head_mat.m[3][j] = 0.0;
719 }
720 delta_mat.m[3][3] = 1.0;
721 inverse_head_mat.m[3][3] = 1.0;
722 gvr::Mat4f omega_mat = MatrixMul(delta_mat, inverse_head_mat);
723 gvr::Vec3f omega_vec;
724 omega_vec.x = -omega_mat.m[2][1];
725 omega_vec.y = omega_mat.m[2][0];
726 omega_vec.z = -omega_mat.m[1][0];
727
728 // Rotate by inverse head matrix to bring into seated space.
729 gvr::Vec3f accel_vec = MatrixVectorRotate(inverse_head_mat, omega_vec);
730 pose->angularVelocity.value()[0] = accel_vec.x;
billorr 2017/03/27 17:33:53 nit: velocity not accel?
klausw 2017/03/27 17:55:42 Indeed, done.
731 pose->angularVelocity.value()[1] = accel_vec.y;
732 pose->angularVelocity.value()[2] = accel_vec.z;
685 return pose; 733 return pose;
686 } 734 }
687 735
688 /* static */ 736 /* static */
689 gvr::Sizei VrShell::GetRecommendedWebVrSize(gvr::GvrApi* gvr_api) { 737 gvr::Sizei VrShell::GetRecommendedWebVrSize(gvr::GvrApi* gvr_api) {
690 // Pick a reasonable default size for the WebVR transfer surface 738 // Pick a reasonable default size for the WebVR transfer surface
691 // based on a downscaled 1:1 render resolution. This size will also 739 // based on a downscaled 1:1 render resolution. This size will also
692 // be reported to the client via CreateVRDisplayInfo as the 740 // be reported to the client via CreateVRDisplayInfo as the
693 // client-recommended renderWidth/renderHeight and for the GVR 741 // client-recommended renderWidth/renderHeight and for the GVR
694 // framebuffer. If the client chooses a different size or resizes it 742 // framebuffer. If the client chooses a different size or resizes it
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
779 jboolean reprojected_rendering) { 827 jboolean reprojected_rendering) {
780 return reinterpret_cast<intptr_t>(new VrShell( 828 return reinterpret_cast<intptr_t>(new VrShell(
781 env, obj, reinterpret_cast<ui::WindowAndroid*>(content_window_android), 829 env, obj, reinterpret_cast<ui::WindowAndroid*>(content_window_android),
782 content::WebContents::FromJavaWebContents(ui_web_contents), 830 content::WebContents::FromJavaWebContents(ui_web_contents),
783 reinterpret_cast<ui::WindowAndroid*>(ui_window_android), for_web_vr, 831 reinterpret_cast<ui::WindowAndroid*>(ui_window_android), for_web_vr,
784 VrShellDelegate::GetNativeVrShellDelegate(env, delegate), 832 VrShellDelegate::GetNativeVrShellDelegate(env, delegate),
785 reinterpret_cast<gvr_context*>(gvr_api), reprojected_rendering)); 833 reinterpret_cast<gvr_context*>(gvr_api), reprojected_rendering));
786 } 834 }
787 835
788 } // namespace vr_shell 836 } // namespace vr_shell
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698