diff --git a/src/core/frontend/input.h b/src/core/frontend/input.h index 6770475cfb..9da0d28297 100644 --- a/src/core/frontend/input.h +++ b/src/core/frontend/input.h @@ -119,25 +119,7 @@ using ButtonDevice = InputDevice; using AnalogDevice = InputDevice>; /** - * A motion device is an input device that returns a tuple of accelerometer state vector and - * gyroscope state vector. - * - * For both vectors: - * x+ is the same direction as LEFT on D-pad. - * y+ is normal to the touch screen, pointing outward. - * z+ is the same direction as UP on D-pad. - * - * For accelerometer state vector - * Units: g (gravitational acceleration) - * - * For gyroscope state vector: - * Orientation is determined by right-hand rule. - * Units: deg/sec - */ -using MotionDevice = InputDevice, Common::Vec3>>; - -/** - * A real motion device is an input device that returns a tuple of accelerometer state vector, + * A motion status is an object that returns a tuple of accelerometer state vector, * gyroscope state vector, rotation state vector and orientation state matrix. * * For both vectors: @@ -160,8 +142,13 @@ using MotionDevice = InputDevice, Common::Vec3, Common::Vec3, - Common::Vec3, std::array>>; +using MotionStatus = std::tuple, Common::Vec3, Common::Vec3, + std::array>; + +/** + * A motion device is an input device that returns a motion status object + */ +using MotionDevice = InputDevice; /** * A touch device is an input device that returns a tuple of two floats and a bool. The floats are diff --git a/src/core/hle/service/hid/controllers/npad.cpp b/src/core/hle/service/hid/controllers/npad.cpp index 9701318b54..2e06372a4a 100644 --- a/src/core/hle/service/hid/controllers/npad.cpp +++ b/src/core/hle/service/hid/controllers/npad.cpp @@ -251,7 +251,7 @@ void Controller_NPad::OnLoadInputDevices() { sticks[i].begin(), Input::CreateDevice); std::transform(players[i].motions.begin() + Settings::NativeMotion::MOTION_HID_BEGIN, players[i].motions.begin() + Settings::NativeMotion::MOTION_HID_END, - motions[i].begin(), Input::CreateDevice); + motions[i].begin(), Input::CreateDevice); } } @@ -397,7 +397,8 @@ void Controller_NPad::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* std::tie(motion_devices[e].accel, motion_devices[e].gyro, motion_devices[e].rotation, motion_devices[e].orientation) = device->GetStatus(); - sixaxis_at_rest = sixaxis_at_rest && motion_devices[e].gyro.Length2() < 1.0f; + sixaxis_at_rest = + sixaxis_at_rest && motion_devices[e].gyro.Length2() < 0.00005f; } } } diff --git a/src/core/hle/service/hid/controllers/npad.h b/src/core/hle/service/hid/controllers/npad.h index 99d7e459ac..7b07d2e8b0 100644 --- a/src/core/hle/service/hid/controllers/npad.h +++ b/src/core/hle/service/hid/controllers/npad.h @@ -299,9 +299,9 @@ private: struct MotionDevice { Common::Vec3f accel; - Common::Vec3f gyro{}; + Common::Vec3f gyro; Common::Vec3f rotation; - std::array orientation{}; + std::array orientation; }; struct NPadEntry { @@ -358,9 +358,9 @@ private: using StickArray = std::array< std::array, Settings::NativeAnalog::NUM_STICKS_HID>, 10>; - using MotionArray = std::array, - Settings::NativeMotion::NUM_MOTION_HID>, - 10>; + using MotionArray = std::array< + std::array, Settings::NativeMotion::NUM_MOTION_HID>, + 10>; ButtonArray buttons; StickArray sticks; MotionArray motions; diff --git a/src/input_common/motion_emu.cpp b/src/input_common/motion_emu.cpp index d4cdf76a3f..69fd3c1d2c 100644 --- a/src/input_common/motion_emu.cpp +++ b/src/input_common/motion_emu.cpp @@ -56,7 +56,7 @@ public: is_tilting = false; } - std::tuple, Common::Vec3> GetStatus() { + Input::MotionStatus GetStatus() { std::lock_guard guard{status_mutex}; return status; } @@ -76,7 +76,7 @@ private: Common::Event shutdown_event; - std::tuple, Common::Vec3> status; + Input::MotionStatus status; std::mutex status_mutex; // Note: always keep the thread declaration at the end so that other objects are initialized @@ -113,10 +113,19 @@ private: gravity = QuaternionRotate(inv_q, gravity); angular_rate = QuaternionRotate(inv_q, angular_rate); + // TODO: Calculate the correct rotation vector and orientation matrix + const auto matrix4x4 = q.ToMatrix(); + const auto rotation = Common::MakeVec(0.0f, 0.0f, 0.0f); + const std::array orientation{ + Common::Vec3f(matrix4x4[0], matrix4x4[1], -matrix4x4[2]), + Common::Vec3f(matrix4x4[4], matrix4x4[5], -matrix4x4[6]), + Common::Vec3f(-matrix4x4[8], -matrix4x4[9], matrix4x4[10]), + }; + // Update the sensor state { std::lock_guard guard{status_mutex}; - status = std::make_tuple(gravity, angular_rate); + status = std::make_tuple(gravity, angular_rate, rotation, orientation); } } } @@ -131,7 +140,7 @@ public: device = std::make_shared(update_millisecond, sensitivity); } - std::tuple, Common::Vec3> GetStatus() const override { + Input::MotionStatus GetStatus() const override { return device->GetStatus(); } diff --git a/src/input_common/udp/client.cpp b/src/input_common/udp/client.cpp index 3f4eaf4483..91e13482db 100644 --- a/src/input_common/udp/client.cpp +++ b/src/input_common/udp/client.cpp @@ -170,10 +170,18 @@ void Client::OnPadData(Response::PadData data) { // directions correspond to the ones of the Switch Common::Vec3f accel = Common::MakeVec(data.accel.x, data.accel.y, data.accel.z); Common::Vec3f gyro = Common::MakeVec(data.gyro.pitch, data.gyro.yaw, data.gyro.roll); + + // TODO: Calculate the correct rotation vector and orientation matrix + const auto rotation = Common::MakeVec(0.0f, 0.0f, 0.0f); + const std::array orientation{ + Common::Vec3f(1.0f, 0.0f, 0.0f), + Common::Vec3f(0.0f, 1.0f, 0.0f), + Common::Vec3f(0.0f, 0.0f, 1.0f), + }; { std::lock_guard guard(status->update_mutex); - status->motion_status = {accel, gyro}; + status->motion_status = {accel, gyro, rotation, orientation}; // TODO: add a setting for "click" touch. Click touch refers to a device that differentiates // between a simple "tap" and a hard press that causes the touch screen to click. diff --git a/src/input_common/udp/client.h b/src/input_common/udp/client.h index b8c6547554..a73283ae8c 100644 --- a/src/input_common/udp/client.h +++ b/src/input_common/udp/client.h @@ -14,6 +14,7 @@ #include "common/common_types.h" #include "common/thread.h" #include "common/vector_math.h" +#include "core/frontend/input.h" namespace InputCommon::CemuhookUDP { @@ -30,7 +31,7 @@ struct Version; struct DeviceStatus { std::mutex update_mutex; - std::tuple, Common::Vec3> motion_status; + Input::MotionStatus motion_status; std::tuple touch_status; // calibration data for scaling the device's touch area to 3ds diff --git a/src/input_common/udp/udp.cpp b/src/input_common/udp/udp.cpp index 4b347e47e9..03bae5752a 100644 --- a/src/input_common/udp/udp.cpp +++ b/src/input_common/udp/udp.cpp @@ -29,7 +29,7 @@ private: class UDPMotionDevice final : public Input::MotionDevice { public: explicit UDPMotionDevice(std::shared_ptr status_) : status(std::move(status_)) {} - std::tuple, Common::Vec3> GetStatus() const override { + Input::MotionStatus GetStatus() const override { std::lock_guard guard(status->update_mutex); return status->motion_status; }