Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use hardware accelerometer as input device #1883

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 17 additions & 3 deletions cobalt/input/camera_3d_input_poller.cc
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,11 @@ namespace input {
Camera3DInputPoller::Camera3DInputPoller(
const scoped_refptr<input::InputPoller>& input_poller)
: roll_in_radians_(0.0f),
roll_offset_in_radians_(0.0f),
pitch_in_radians_(0.0f),
pitch_offset_in_radians_(0.0f),
yaw_in_radians_(0.0f),
yaw_offset_in_radians_(0.0f),
input_poller_(input_poller),
width_to_height_aspect_ratio_(16.0f / 9.0f),
vertical_fov_(60.0f) {}
Expand All @@ -54,9 +57,12 @@ void Camera3DInputPoller::ClearAllKeyMappings() {
}

glm::quat Camera3DInputPoller::orientation() const {
return glm::angleAxis(-roll_in_radians_, glm::vec3(0, 0, 1)) *
glm::angleAxis(-pitch_in_radians_, glm::vec3(1, 0, 0)) *
glm::angleAxis(-yaw_in_radians_, glm::vec3(0, 1, 0));
return glm::angleAxis(-roll_in_radians_ + roll_offset_in_radians_,
glm::vec3(0, 0, 1)) *
glm::angleAxis(-pitch_in_radians_ + pitch_offset_in_radians_,
glm::vec3(1, 0, 0)) *
glm::angleAxis(-yaw_in_radians_ + +yaw_offset_in_radians_,
glm::vec3(0, 1, 0));
}

glm::quat Camera3DInputPoller::GetOrientation() const {
Expand Down Expand Up @@ -90,6 +96,9 @@ void Camera3DInputPoller::Reset() {
roll_in_radians_ = 0.0f;
pitch_in_radians_ = 0.0f;
yaw_in_radians_ = 0.0f;
roll_offset_in_radians_ = 0.0f;
pitch_offset_in_radians_ = 0.0f;
yaw_offset_in_radians_ = 0.0f;
}

void Camera3DInputPoller::SetInput(const scoped_refptr<Camera3D>& other) {
Expand All @@ -116,6 +125,11 @@ void Camera3DInputPoller::AccumulateOrientation() {
delta = kMaxTimeDelta;
}

// Get offsets from gyro sensor
pitch_offset_in_radians_ = std::get<0>(input_poller_->GyroSensorAngles());
yaw_offset_in_radians_ = std::get<1>(input_poller_->GyroSensorAngles());
roll_offset_in_radians_ = std::get<2>(input_poller_->GyroSensorAngles());

// Accumulate new rotation from all mapped inputs.
for (KeycodeMap::const_iterator iter = keycode_map_.begin();
iter != keycode_map_.end(); ++iter) {
Expand Down
3 changes: 3 additions & 0 deletions cobalt/input/camera_3d_input_poller.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,11 @@ class Camera3DInputPoller : public Camera3D {

// The current accumulated camera orientation state.
float roll_in_radians_;
float roll_offset_in_radians_;
float pitch_in_radians_;
float pitch_offset_in_radians_;
float yaw_in_radians_;
float yaw_offset_in_radians_;

// The time that the last update to the camera's state has occurred.
base::Optional<base::TimeTicks> last_update_;
Expand Down
6 changes: 6 additions & 0 deletions cobalt/input/input_device_manager_desktop.cc
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,7 @@ void UpdateMouseEventInitButtons(const system_window::InputEvent* input_event,
case system_window::InputEvent::kTouchpadMove:
case system_window::InputEvent::kTouchscreenMove:
case system_window::InputEvent::kWheel:
case system_window::InputEvent::kGyroSensorMove:
break;
}

Expand Down Expand Up @@ -264,6 +265,9 @@ void InputDeviceManagerDesktop::HandlePointerEvent(
case system_window::InputEvent::kWheel:
pointer_event.set_pointer_type("mouse");
break;
case system_window::InputEvent::kGyroSensorMove:
pointer_event.set_pointer_type("gyroscope");
break;
}
pointer_event.set_pointer_id(input_event->device_id());
pointer_event.set_width(value_or(input_event->size().x(), 0.0f));
Expand Down Expand Up @@ -367,6 +371,8 @@ void InputDeviceManagerDesktop::HandleSystemWindowInputEvent(
break;
case system_window::InputEvent::kKeyMove:
break;
case system_window::InputEvent::kGyroSensorMove:
break;
}

InputPollerImpl* input_poller_impl =
Expand Down
4 changes: 4 additions & 0 deletions cobalt/input/input_poller.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
#ifndef COBALT_INPUT_INPUT_POLLER_H_
#define COBALT_INPUT_INPUT_POLLER_H_

#include <tuple>

#include "base/memory/ref_counted.h"
#include "starboard/key.h"

Expand All @@ -34,6 +36,8 @@ class InputPoller : public base::RefCountedThreadSafe<InputPoller> {
// Returns analog position. The value is normalized to a range from
// -1.0 to 1.0
virtual float AnalogInput(SbKey analog_input_id) = 0;

virtual const std::tuple<float, float, float>& GyroSensorAngles() = 0;
};

} // namespace input
Expand Down
12 changes: 11 additions & 1 deletion cobalt/input/input_poller_impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@
namespace cobalt {
namespace input {

InputPollerImpl::InputPollerImpl() : InputPoller() {
InputPollerImpl::InputPollerImpl()
: InputPoller(), gyro_sensor_data_{0.f, 0.f, 0.f} {
// Initialize the joystick key mapping.
key_offset_map_[kSbKeyGamepadLeftStickUp] = 0.0f;
key_offset_map_[kSbKeyGamepadLeftStickDown] = 0.0f;
Expand Down Expand Up @@ -106,8 +107,17 @@ void InputPollerImpl::UpdateInputEvent(
case system_window::InputEvent::kWheel:
// Pointer and Wheel events are ignored here.
break;
case system_window::InputEvent::kGyroSensorMove: {
gyro_sensor_data_ = {input_event->gyro_sensor_angle().x(),
input_event->gyro_sensor_angle().y(),
input_event->gyro_sensor_angle().z()};
} break;
}
}

const std::tuple<float, float, float>& InputPollerImpl::GyroSensorAngles() {
return gyro_sensor_data_;
}

} // namespace input
} // namespace cobalt
3 changes: 3 additions & 0 deletions cobalt/input/input_poller_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#define COBALT_INPUT_INPUT_POLLER_IMPL_H_

#include <map>
#include <tuple>

#include "base/containers/hash_tables.h"
#include "base/containers/small_map.h"
Expand All @@ -40,13 +41,15 @@ class InputPollerImpl : public InputPoller {
// -1.0 to 1.0
float AnalogInput(SbKey analog_input_id) override;
void UpdateInputEvent(const system_window::InputEvent* input_event);
const std::tuple<float, float, float>& GyroSensorAngles();

private:
typedef base::small_map<std::map<SbKey, float>, 8> KeyOffsetMap;

starboard::Mutex input_mutex_;
base::hash_set<int> pressed_keys_;
KeyOffsetMap key_offset_map_;
std::tuple<float, float, float> gyro_sensor_data_;
};

} // namespace input
Expand Down
10 changes: 8 additions & 2 deletions cobalt/system_window/input_event.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include <string>

#include "cobalt/base/event.h"
#include "cobalt/math/point3_f.h"
#include "cobalt/math/point_f.h"
#include "starboard/event.h"
#include "starboard/time.h"
Expand All @@ -42,6 +43,7 @@ class InputEvent : public base::Event {
kTouchscreenUp,
kTouchscreenMove,
kWheel,
kGyroSensorMove,
};

// Bit-mask of key modifiers. These correspond to the |SbKeyModifiers| values
Expand All @@ -65,7 +67,8 @@ class InputEvent : public base::Event {
const math::PointF& delta = math::PointF(), float pressure = 0,
const math::PointF& size = math::PointF(),
const math::PointF& tilt = math::PointF(),
const std::string& input_text = "", bool is_composing = false)
const std::string& input_text = "", bool is_composing = false,
const math::Point3F& angle = math::Point3F())
: timestamp_(timestamp),
type_(type),
device_id_(device_id),
Expand All @@ -78,7 +81,8 @@ class InputEvent : public base::Event {
size_(size),
tilt_(tilt),
input_text_(input_text),
is_composing_(is_composing) {}
is_composing_(is_composing),
gyro_sensor_angle_(angle) {}

~InputEvent() {}

Expand All @@ -95,6 +99,7 @@ class InputEvent : public base::Event {
const math::PointF& tilt() const { return tilt_; }
const std::string& input_text() const { return input_text_; }
bool is_composing() const { return is_composing_; }
const math::Point3F& gyro_sensor_angle() const { return gyro_sensor_angle_; }

BASE_EVENT_SUBCLASS(InputEvent);

Expand All @@ -112,6 +117,7 @@ class InputEvent : public base::Event {
math::PointF tilt_;
std::string input_text_;
bool is_composing_;
math::Point3F gyro_sensor_angle_;
};

// The Starboard Event handler SbHandleEvent should call this function on
Expand Down
24 changes: 16 additions & 8 deletions cobalt/system_window/system_window.cc
Original file line number Diff line number Diff line change
Expand Up @@ -156,18 +156,21 @@ void SystemWindow::DispatchInputEvent(const SbEvent* event,
case InputEvent::kTouchpadUp:
case InputEvent::kTouchscreenUp:
case InputEvent::kWheel:
case InputEvent::kGyroSensorMove:
break;
}
}

std::unique_ptr<InputEvent> input_event(
new InputEvent(timestamp, type, data.device_id, key_code, modifiers,
is_repeat, math::PointF(data.position.x, data.position.y),
math::PointF(data.delta.x, data.delta.y), pressure,
math::PointF(data.size.x, data.size.y),
math::PointF(data.tilt.x, data.tilt.y),
data.input_text ? data.input_text : "",
data.is_composing ? data.is_composing : false));
std::unique_ptr<InputEvent> input_event(new InputEvent(
timestamp, type, data.device_id, key_code, modifiers, is_repeat,
math::PointF(data.position.x, data.position.y),
math::PointF(data.delta.x, data.delta.y), pressure,
math::PointF(data.size.x, data.size.y),
math::PointF(data.tilt.x, data.tilt.y),
data.input_text ? data.input_text : "",
data.is_composing ? data.is_composing : false,
math::Point3F(data.gyroscope_data.angle.x, data.gyroscope_data.angle.y,
data.gyroscope_data.angle.z)));
event_dispatcher()->DispatchEvent(
std::unique_ptr<base::Event>(input_event.release()));
}
Expand Down Expand Up @@ -256,6 +259,11 @@ void SystemWindow::HandleInputEvent(const SbEvent* event) {
DispatchInputEvent(event, InputEvent::kInput, false /* is_repeat */);
break;
}
case kSbInputEventTypeGyroSensor: {
DispatchInputEvent(event, InputEvent::kGyroSensorMove,
false /* is_repeat */);
break;
}
default:
break;
}
Expand Down
24 changes: 24 additions & 0 deletions starboard/input.h
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,11 @@ typedef enum SbInputDeviceType {
//
// Produces |Input| events.
kSbInputDeviceTypeOnScreenKeyboard,

// Input from a gyroscope
//
// Produces |Input| event
kSbInputDeviceGyroSensor,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@y4vor WDYT about this addition to Starboard?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please guard all API changes with the SB_API_VERSION checks. Also update starboard/CHANGELOG.md.

Here are the instructions of how to introduce a Starboard API change:
https://g3doc.corp.google.com/company/teams/cobalt/team/components/starboard.md#make-changes-in-trunk-to-the-latest-unreleased-starboard-version1

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't have access to this doc. Could you share it with us via docs.google.com?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Based on an org decision today, we won't be planning new changes for NX so this CL won't be needed at this time. Apologies for the timing of this happening after you started the effort on this CL. I'll close the PR and link to it in the bug for future reference if we ever need to reconsider using accelerometer.

} SbInputDeviceType;

// The action that an input event represents.
Expand All @@ -99,6 +104,10 @@ typedef enum SbInputEventType {

// https://w3c.github.io/uievents/#event-type-input
kSbInputEventTypeInput,

// Gyroscope rotation. Provides rotation angles of |Controller|
// or |Device| which has built in gyroscope
kSbInputEventTypeGyroSensor,
} SbInputEventType;

// A 2-dimensional vector used to represent points and motion vectors.
Expand All @@ -107,6 +116,18 @@ typedef struct SbInputVector {
float y;
} SbInputVector;

// A 3-dimensional vector used to represent points and motion vectors.
typedef struct SbInput3DVector {
float x;
float y;
float z;
} SbInput3DVector;

// Gyroscope input data
typedef struct SbInputGyroSensor {
SbInput3DVector angle;
} SbInputGyroSensor;

// Event data for |kSbEventTypeInput| events.
typedef struct SbInputData {
// The window in which the input was generated.
Expand Down Expand Up @@ -173,6 +194,9 @@ typedef struct SbInputData {

// Set to true if the input event is part of a composition event.
bool is_composing;

// Giroscope input data. The (x, y, z) angle in degrees.
SbInputGyroSensor gyroscope_data;
} SbInputData;

#ifdef __cplusplus
Expand Down