Commit 214df875 authored by Brandon Jones's avatar Brandon Jones Committed by Commit Bot

Implement WebXR input for GVR

Includes support for both Cardboard (gaze cursor) and Daydream (3DoF)
input modes. In 3DoF mode the WebXR pointer and controller align with
the VR Shell versions.

Bug: 812287
Change-Id: I8dcfe7cdadc9f2c0216208e643c9f11211498e25
Reviewed-on: https://chromium-review.googlesource.com/956524Reviewed-by: default avatarMichael Thiessen <mthiesse@chromium.org>
Commit-Queue: Brandon Jones <bajones@chromium.org>
Cr-Commit-Position: refs/heads/master@{#541935}
parent 09496182
...@@ -145,6 +145,55 @@ device::GvrGamepadData VrController::GetGamepadData() { ...@@ -145,6 +145,55 @@ device::GvrGamepadData VrController::GetGamepadData() {
return pad; return pad;
} }
device::mojom::XRInputSourceStatePtr VrController::GetInputSourceState() {
device::mojom::XRInputSourceStatePtr state =
device::mojom::XRInputSourceState::New();
// Only one controller is supported, so the source id can be static.
state->source_id = 1;
// Set the primary button state.
state->primary_input_pressed =
controller_state_->GetButtonState(GVR_CONTROLLER_BUTTON_CLICK);
if (ButtonUpHappened(GVR_CONTROLLER_BUTTON_CLICK)) {
state->primary_input_clicked = true;
}
state->description = device::mojom::XRInputSourceDescription::New();
// It's a handheld pointing device.
state->description->pointer_origin = device::mojom::XRPointerOrigin::HAND;
// Controller uses an arm model.
state->description->emulated_position = true;
// Set handedness.
switch (handedness_) {
case GVR_CONTROLLER_LEFT_HANDED:
state->description->handedness = device::mojom::XRHandedness::LEFT;
break;
case GVR_CONTROLLER_RIGHT_HANDED:
state->description->handedness = device::mojom::XRHandedness::RIGHT;
break;
default:
state->description->handedness = device::mojom::XRHandedness::NONE;
break;
}
// Get the grip transform
gfx::Transform grip;
GetTransform(&grip);
state->grip = grip;
// Set the pointer offset from the grip transform.
gfx::Transform pointer;
GetRelativePointerTransform(&pointer);
state->description->pointer_offset = pointer;
return state;
}
bool VrController::IsTouching() { bool VrController::IsTouching() {
return controller_state_->IsTouching(); return controller_state_->IsTouching();
} }
...@@ -209,17 +258,31 @@ void VrController::GetTransform(gfx::Transform* out) const { ...@@ -209,17 +258,31 @@ void VrController::GetTransform(gfx::Transform* out) const {
out->matrix().postTranslate(position.x, position.y, position.z); out->matrix().postTranslate(position.x, position.y, position.z);
} }
void VrController::GetRelativePointerTransform(gfx::Transform* out) const {
*out = gfx::Transform();
out->RotateAboutXAxis(-kErgoAngleOffset * 180.0f / base::kPiFloat);
out->Translate3d(0, 0, -kLaserStartDisplacement);
}
void VrController::GetPointerTransform(gfx::Transform* out) const {
gfx::Transform controller;
GetTransform(&controller);
GetRelativePointerTransform(out);
out->ConcatTransform(controller);
}
float VrController::GetOpacity() const { float VrController::GetOpacity() const {
return alpha_value_; return alpha_value_;
} }
gfx::Point3F VrController::GetPointerStart() const { gfx::Point3F VrController::GetPointerStart() const {
gfx::Vector3dF pointer_direction{0.0f, -sin(kErgoAngleOffset), gfx::Transform pointer_transform;
-cos(kErgoAngleOffset)}; GetPointerTransform(&pointer_transform);
gfx::Transform rotation_mat(Orientation());
rotation_mat.TransformVector(&pointer_direction); gfx::Point3F pointer_position;
return Position() + pointer_transform.TransformPoint(&pointer_position);
gfx::ScaleVector3d(pointer_direction, kLaserStartDisplacement); return pointer_position;
} }
bool VrController::TouchDownHappened() { bool VrController::TouchDownHappened() {
......
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
#include "base/time/time.h" #include "base/time/time.h"
#include "chrome/browser/vr/platform_controller.h" #include "chrome/browser/vr/platform_controller.h"
#include "device/vr/android/gvr/gvr_gamepad_data_provider.h" #include "device/vr/android/gvr/gvr_gamepad_data_provider.h"
#include "device/vr/public/mojom/vr_service.mojom.h"
#include "third_party/gvr-android-sdk/src/libraries/headers/vr/gvr/capi/include/gvr_types.h" #include "third_party/gvr-android-sdk/src/libraries/headers/vr/gvr/capi/include/gvr_types.h"
#include "ui/gfx/geometry/point3_f.h" #include "ui/gfx/geometry/point3_f.h"
#include "ui/gfx/geometry/quaternion.h" #include "ui/gfx/geometry/quaternion.h"
...@@ -50,6 +51,7 @@ class VrController : public PlatformController { ...@@ -50,6 +51,7 @@ class VrController : public PlatformController {
void OnPause(); void OnPause();
device::GvrGamepadData GetGamepadData(); device::GvrGamepadData GetGamepadData();
device::mojom::XRInputSourceStatePtr GetInputSourceState();
// Called once per frame to update controller state. // Called once per frame to update controller state.
void UpdateState(const gvr::Mat4f& head_direction); void UpdateState(const gvr::Mat4f& head_direction);
...@@ -65,6 +67,8 @@ class VrController : public PlatformController { ...@@ -65,6 +67,8 @@ class VrController : public PlatformController {
gfx::Quaternion Orientation() const; gfx::Quaternion Orientation() const;
gfx::Point3F Position() const; gfx::Point3F Position() const;
void GetTransform(gfx::Transform* out) const; void GetTransform(gfx::Transform* out) const;
void GetRelativePointerTransform(gfx::Transform* out) const;
void GetPointerTransform(gfx::Transform* out) const;
float GetOpacity() const; float GetOpacity() const;
gfx::Point3F GetPointerStart() const; gfx::Point3F GetPointerStart() const;
......
...@@ -415,6 +415,10 @@ void VrShell::OnTriggerEvent(JNIEnv* env, ...@@ -415,6 +415,10 @@ void VrShell::OnTriggerEvent(JNIEnv* env,
} else { } else {
pending_cardboard_trigger_ = touched; pending_cardboard_trigger_ = touched;
} }
PostToGlThread(FROM_HERE,
base::BindOnce(&VrShellGl::OnTriggerEvent,
gl_thread_->GetVrShellGl(), touched));
} }
void VrShell::OnPause(JNIEnv* env, const JavaParamRef<jobject>& obj) { void VrShell::OnPause(JNIEnv* env, const JavaParamRef<jobject>& obj) {
......
...@@ -452,6 +452,8 @@ void VrShellGl::ConnectPresentingService( ...@@ -452,6 +452,8 @@ void VrShellGl::ConnectPresentingService(
// direct-draw-to-shared-buffer optimization. // direct-draw-to-shared-buffer optimization.
DVLOG(1) << "preserveDrawingBuffer=" DVLOG(1) << "preserveDrawingBuffer="
<< present_options->preserve_drawing_buffer; << present_options->preserve_drawing_buffer;
report_webxr_input_ = present_options->webxr_input;
} }
void VrShellGl::OnSwapContents(int new_content_id) { void VrShellGl::OnSwapContents(int new_content_id) {
...@@ -1573,6 +1575,17 @@ void VrShellGl::SendVSync(base::TimeTicks time, GetVSyncCallback callback) { ...@@ -1573,6 +1575,17 @@ void VrShellGl::SendVSync(base::TimeTicks time, GetVSyncCallback callback) {
device::GvrDelegate::GetVRPosePtrWithNeckModel(gvr_api_.get(), &head_mat, device::GvrDelegate::GetVRPosePtrWithNeckModel(gvr_api_.get(), &head_mat,
prediction_nanos); prediction_nanos);
if (report_webxr_input_) {
std::vector<device::mojom::XRInputSourceStatePtr> input_states;
device::mojom::XRInputSourceStatePtr input_state =
cardboard_ ? GetGazeInputSourceState()
: controller_->GetInputSourceState();
input_states.push_back(std::move(input_state));
pose->input_state = std::move(input_states);
}
webvr_head_pose_[frame_index % kPoseRingBufferSize] = head_mat; webvr_head_pose_[frame_index % kPoseRingBufferSize] = head_mat;
webvr_frame_oustanding_[frame_index % kPoseRingBufferSize] = true; webvr_frame_oustanding_[frame_index % kPoseRingBufferSize] = true;
webvr_time_pose_[frame_index % kPoseRingBufferSize] = base::TimeTicks::Now(); webvr_time_pose_[frame_index % kPoseRingBufferSize] = base::TimeTicks::Now();
...@@ -1596,6 +1609,42 @@ void VrShellGl::ClosePresentationBindings() { ...@@ -1596,6 +1609,42 @@ void VrShellGl::ClosePresentationBindings() {
binding_.Close(); binding_.Close();
} }
device::mojom::XRInputSourceStatePtr VrShellGl::GetGazeInputSourceState() {
device::mojom::XRInputSourceStatePtr state =
device::mojom::XRInputSourceState::New();
// Only one gaze input source to worry about, so it can have a static id.
state->source_id = 1;
// Report any trigger state changes made since the last call and reset the
// state here.
state->primary_input_pressed = cardboard_trigger_pressed_;
state->primary_input_clicked = cardboard_trigger_clicked_;
cardboard_trigger_clicked_ = false;
state->description = device::mojom::XRInputSourceDescription::New();
// It's a gaze-cursor-based device.
state->description->pointer_origin = device::mojom::XRPointerOrigin::HEAD;
state->description->emulated_position = true;
// No implicit handedness
state->description->handedness = device::mojom::XRHandedness::NONE;
// Pointer and grip transforms are omitted since this is a gaze-based source.
return state;
}
void VrShellGl::OnTriggerEvent(bool pressed) {
if (pressed) {
cardboard_trigger_pressed_ = true;
} else if (cardboard_trigger_pressed_) {
cardboard_trigger_pressed_ = false;
cardboard_trigger_clicked_ = true;
}
}
void VrShellGl::AcceptDoffPromptForTesting() { void VrShellGl::AcceptDoffPromptForTesting() {
ui_->AcceptDoffPromptForTesting(); ui_->AcceptDoffPromptForTesting();
} }
......
...@@ -82,7 +82,7 @@ class VrShellGl : public device::mojom::VRPresentationProvider { ...@@ -82,7 +82,7 @@ class VrShellGl : public device::mojom::VRPresentationProvider {
void Initialize(); void Initialize();
void InitializeGl(gfx::AcceleratedWidget window); void InitializeGl(gfx::AcceleratedWidget window);
void OnTriggerEvent(); void OnTriggerEvent(bool pressed);
void OnPause(); void OnPause();
void OnResume(); void OnResume();
void OnExitPresent(); void OnExitPresent();
...@@ -188,6 +188,8 @@ class VrShellGl : public device::mojom::VRPresentationProvider { ...@@ -188,6 +188,8 @@ class VrShellGl : public device::mojom::VRPresentationProvider {
void ClosePresentationBindings(); void ClosePresentationBindings();
device::mojom::XRInputSourceStatePtr GetGazeInputSourceState();
// samplerExternalOES texture data for WebVR content image. // samplerExternalOES texture data for WebVR content image.
int webvr_texture_id_ = 0; int webvr_texture_id_ = 0;
...@@ -256,6 +258,9 @@ class VrShellGl : public device::mojom::VRPresentationProvider { ...@@ -256,6 +258,9 @@ class VrShellGl : public device::mojom::VRPresentationProvider {
bool daydream_support_; bool daydream_support_;
bool is_exiting_ = false; bool is_exiting_ = false;
bool content_paused_; bool content_paused_;
bool report_webxr_input_ = false;
bool cardboard_trigger_pressed_ = false;
bool cardboard_trigger_clicked_ = false;
std::unique_ptr<VrController> controller_; std::unique_ptr<VrController> controller_;
......
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