Skip to content

Commit

Permalink
Merge pull request #8352 from rlnilsen/motion-controller-support-via-…
Browse files Browse the repository at this point in the history
…cemuhook-protocol

Support for motion controllers like the DualShock 4
  • Loading branch information
delroth committed Oct 28, 2019
2 parents a825e7e + da1f153 commit 1f3d1a9
Show file tree
Hide file tree
Showing 39 changed files with 1,548 additions and 45 deletions.
1 change: 1 addition & 0 deletions Source/Core/Common/CommonPaths.h
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@
#define GFX_CONFIG "GFX.ini" #define GFX_CONFIG "GFX.ini"
#define DEBUGGER_CONFIG "Debugger.ini" #define DEBUGGER_CONFIG "Debugger.ini"
#define LOGGER_CONFIG "Logger.ini" #define LOGGER_CONFIG "Logger.ini"
#define DUALSHOCKUDPCLIENT_CONFIG "DSUClient.ini"


// Files in the directory returned by GetUserPath(D_LOGS_IDX) // Files in the directory returned by GetUserPath(D_LOGS_IDX)
#define MAIN_LOG "dolphin.log" #define MAIN_LOG "dolphin.log"
Expand Down
12 changes: 9 additions & 3 deletions Source/Core/Common/Config/Config.cpp
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -133,9 +133,15 @@ void ClearCurrentRunLayer()
} }


static const std::map<System, std::string> system_to_name = { static const std::map<System, std::string> system_to_name = {
{System::Main, "Dolphin"}, {System::GCPad, "GCPad"}, {System::WiiPad, "Wiimote"}, {System::Main, "Dolphin"},
{System::GCKeyboard, "GCKeyboard"}, {System::GFX, "Graphics"}, {System::Logger, "Logger"}, {System::GCPad, "GCPad"},
{System::Debugger, "Debugger"}, {System::SYSCONF, "SYSCONF"}}; {System::WiiPad, "Wiimote"},
{System::GCKeyboard, "GCKeyboard"},
{System::GFX, "Graphics"},
{System::Logger, "Logger"},
{System::Debugger, "Debugger"},
{System::SYSCONF, "SYSCONF"},
{System::DualShockUDPClient, "DualShockUDPClient"}};


const std::string& GetSystemName(System system) const std::string& GetSystemName(System system)
{ {
Expand Down
1 change: 1 addition & 0 deletions Source/Core/Common/Config/Enums.h
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ enum class System
GFX, GFX,
Logger, Logger,
Debugger, Debugger,
DualShockUDPClient,
}; };


constexpr std::array<LayerType, 7> SEARCH_ORDER{{ constexpr std::array<LayerType, 7> SEARCH_ORDER{{
Expand Down
2 changes: 2 additions & 0 deletions Source/Core/Common/FileUtil.cpp
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -794,6 +794,8 @@ static void RebuildUserDirectories(unsigned int dir_index)
s_user_paths[F_GFXCONFIG_IDX] = s_user_paths[D_CONFIG_IDX] + GFX_CONFIG; s_user_paths[F_GFXCONFIG_IDX] = s_user_paths[D_CONFIG_IDX] + GFX_CONFIG;
s_user_paths[F_DEBUGGERCONFIG_IDX] = s_user_paths[D_CONFIG_IDX] + DEBUGGER_CONFIG; s_user_paths[F_DEBUGGERCONFIG_IDX] = s_user_paths[D_CONFIG_IDX] + DEBUGGER_CONFIG;
s_user_paths[F_LOGGERCONFIG_IDX] = s_user_paths[D_CONFIG_IDX] + LOGGER_CONFIG; s_user_paths[F_LOGGERCONFIG_IDX] = s_user_paths[D_CONFIG_IDX] + LOGGER_CONFIG;
s_user_paths[F_DUALSHOCKUDPCLIENTCONFIG_IDX] =
s_user_paths[D_CONFIG_IDX] + DUALSHOCKUDPCLIENT_CONFIG;
s_user_paths[F_MAINLOG_IDX] = s_user_paths[D_LOGS_IDX] + MAIN_LOG; s_user_paths[F_MAINLOG_IDX] = s_user_paths[D_LOGS_IDX] + MAIN_LOG;
s_user_paths[F_MEM1DUMP_IDX] = s_user_paths[D_DUMP_IDX] + MEM1_DUMP; s_user_paths[F_MEM1DUMP_IDX] = s_user_paths[D_DUMP_IDX] + MEM1_DUMP;
s_user_paths[F_MEM2DUMP_IDX] = s_user_paths[D_DUMP_IDX] + MEM2_DUMP; s_user_paths[F_MEM2DUMP_IDX] = s_user_paths[D_DUMP_IDX] + MEM2_DUMP;
Expand Down
1 change: 1 addition & 0 deletions Source/Core/Common/FileUtil.h
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ enum
F_MEMORYWATCHERLOCATIONS_IDX, F_MEMORYWATCHERLOCATIONS_IDX,
F_MEMORYWATCHERSOCKET_IDX, F_MEMORYWATCHERSOCKET_IDX,
F_WIISDCARD_IDX, F_WIISDCARD_IDX,
F_DUALSHOCKUDPCLIENTCONFIG_IDX,
NUM_PATH_INDICES NUM_PATH_INDICES
}; };


Expand Down
1 change: 1 addition & 0 deletions Source/Core/Core/ConfigLoaders/BaseConfigLoader.cpp
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ const std::map<Config::System, int> system_to_ini = {
{Config::System::GFX, F_GFXCONFIG_IDX}, {Config::System::GFX, F_GFXCONFIG_IDX},
{Config::System::Logger, F_LOGGERCONFIG_IDX}, {Config::System::Logger, F_LOGGERCONFIG_IDX},
{Config::System::Debugger, F_DEBUGGERCONFIG_IDX}, {Config::System::Debugger, F_DEBUGGERCONFIG_IDX},
{Config::System::DualShockUDPClient, F_DUALSHOCKUDPCLIENTCONFIG_IDX},
}; };


// INI layer configuration loader // INI layer configuration loader
Expand Down
3 changes: 3 additions & 0 deletions Source/Core/Core/ConfigLoaders/IsSettingSaveable.cpp
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ namespace ConfigLoaders
{ {
bool IsSettingSaveable(const Config::ConfigLocation& config_location) bool IsSettingSaveable(const Config::ConfigLocation& config_location)
{ {
if (config_location.system == Config::System::DualShockUDPClient)
return true;

if (config_location.system == Config::System::Logger) if (config_location.system == Config::System::Logger)
return true; return true;


Expand Down
2 changes: 1 addition & 1 deletion Source/Core/Core/Core.vcxproj
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -629,4 +629,4 @@
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets"> <ImportGroup Label="ExtensionTargets">
</ImportGroup> </ImportGroup>
</Project> </Project>
5 changes: 4 additions & 1 deletion Source/Core/Core/Core.vcxproj.filters
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -1661,8 +1661,11 @@
<ClInclude Include="HW\AddressSpace.h"> <ClInclude Include="HW\AddressSpace.h">
<Filter>HW %28Flipper/Hollywood%29</Filter> <Filter>HW %28Flipper/Hollywood%29</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="HW\WiimoteEmu\Constants.h">
<Filter>HW %28Flipper/Hollywood%29\Wiimote\Emu</Filter>
</ClInclude>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Text Include="CMakeLists.txt" /> <Text Include="CMakeLists.txt" />
</ItemGroup> </ItemGroup>
</Project> </Project>
87 changes: 87 additions & 0 deletions Source/Core/Core/HW/WiimoteEmu/Dynamics.cpp
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@
#include "InputCommon/ControllerEmu/ControlGroup/Buttons.h" #include "InputCommon/ControllerEmu/ControlGroup/Buttons.h"
#include "InputCommon/ControllerEmu/ControlGroup/Cursor.h" #include "InputCommon/ControllerEmu/ControlGroup/Cursor.h"
#include "InputCommon/ControllerEmu/ControlGroup/Force.h" #include "InputCommon/ControllerEmu/ControlGroup/Force.h"
#include "InputCommon/ControllerEmu/ControlGroup/IMUAccelerometer.h"
#include "InputCommon/ControllerEmu/ControlGroup/IMUCursor.h"
#include "InputCommon/ControllerEmu/ControlGroup/IMUGyroscope.h"
#include "InputCommon/ControllerEmu/ControlGroup/Tilt.h" #include "InputCommon/ControllerEmu/ControlGroup/Tilt.h"


namespace namespace
Expand Down Expand Up @@ -268,6 +271,90 @@ void ApproachAngleWithAccel(RotationalState* state, const Common::Vec3& angle_ta
} }
} }


static Common::Vec3 NormalizeAngle(Common::Vec3 angle)
{
// TODO: There must be a more elegant way to do this
angle.x = fmod(angle.x, float(MathUtil::TAU));
angle.y = fmod(angle.y, float(MathUtil::TAU));
angle.z = fmod(angle.z, float(MathUtil::TAU));
angle.x += angle.x < 0 ? float(MathUtil::TAU) : 0;
angle.y += angle.y < 0 ? float(MathUtil::TAU) : 0;
angle.z += angle.z < 0 ? float(MathUtil::TAU) : 0;
return angle;
}

static Common::Vec3 ComplementaryFilter(const Common::Vec3& angle,
const Common::Vec3& accelerometer,
const Common::Vec3& gyroscope, float time_elapsed)
{
Common::Vec3 gyroangle = angle + gyroscope * time_elapsed;
gyroangle = NormalizeAngle(gyroangle);

// Calculate accelerometer tilt angles
Common::Vec3 accangle = gyroangle;
if ((accelerometer.x != 0 && accelerometer.y != 0) || accelerometer.z != 0)
{
float accpitch = -atan2(accelerometer.y, -accelerometer.z) + float(MathUtil::PI);
float accroll = atan2(accelerometer.x, -accelerometer.z) + float(MathUtil::PI);
accangle = {accpitch, accroll, gyroangle.z};
}

// Massage accelerometer and gyroscope angle values so that averaging them works when they are on
// opposite sides of TAU / zero (which both represent the same angle)
// TODO: There must be a more elegant way to do this
constexpr float DEG360 = float(MathUtil::TAU);
constexpr float DEG270 = DEG360 * 0.75f;
constexpr float DEG90 = DEG360 * 0.25f;
if (accangle.x < DEG90 && gyroangle.x > DEG270)
accangle.x += DEG360;
else if (gyroangle.x < DEG90 && accangle.x > DEG270)
gyroangle.x += DEG360;
if (accangle.y < DEG90 && gyroangle.y > DEG270)
accangle.y += DEG360;
else if (gyroangle.y < DEG90 && accangle.y > DEG270)
gyroangle.y += DEG360;

// Combine accelerometer and gyroscope angles
return NormalizeAngle((gyroangle * 0.98f) + (accangle * 0.02f));
}

void EmulateIMUCursor(std::optional<RotationalState>* state, ControllerEmu::IMUCursor* imu_ir_group,
ControllerEmu::IMUAccelerometer* imu_accelerometer_group,
ControllerEmu::IMUGyroscope* imu_gyroscope_group, float time_elapsed)
{
// Avoid having to double dereference
auto& st = *state;

auto accel = imu_accelerometer_group->GetState();
auto ang_vel = imu_gyroscope_group->GetState();

// The IMU Cursor requires both an accelerometer and a gyroscope to function correctly.
if (!(accel.has_value() && ang_vel.has_value()))
{
st = std::nullopt;
return;
}

if (!st.has_value())
st = RotationalState{};

st->angle = ComplementaryFilter(st->angle, accel.value(), ang_vel.value(), time_elapsed);

// Reset camera yaw angle
constexpr ControlState BUTTON_THRESHOLD = 0.5;
if (imu_ir_group->controls[0]->control_ref->State() > BUTTON_THRESHOLD)
st->angle.z = 0;

// Limit camera yaw angle
float totalyaw = float(imu_ir_group->GetTotalYaw());
float yawmax = totalyaw / 2;
float yawmin = float(MathUtil::TAU) - totalyaw / 2;
if (st->angle.z > yawmax && st->angle.z <= float(MathUtil::PI))
st->angle.z = yawmax;
if (st->angle.z < yawmin && st->angle.z > float(MathUtil::PI))
st->angle.z = yawmin;
}

void ApproachPositionWithJerk(PositionalState* state, const Common::Vec3& position_target, void ApproachPositionWithJerk(PositionalState* state, const Common::Vec3& position_target,
const Common::Vec3& max_jerk, float time_elapsed) const Common::Vec3& max_jerk, float time_elapsed)
{ {
Expand Down
6 changes: 6 additions & 0 deletions Source/Core/Core/HW/WiimoteEmu/Dynamics.h
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@
#include "InputCommon/ControllerEmu/ControlGroup/Buttons.h" #include "InputCommon/ControllerEmu/ControlGroup/Buttons.h"
#include "InputCommon/ControllerEmu/ControlGroup/Cursor.h" #include "InputCommon/ControllerEmu/ControlGroup/Cursor.h"
#include "InputCommon/ControllerEmu/ControlGroup/Force.h" #include "InputCommon/ControllerEmu/ControlGroup/Force.h"
#include "InputCommon/ControllerEmu/ControlGroup/IMUAccelerometer.h"
#include "InputCommon/ControllerEmu/ControlGroup/IMUCursor.h"
#include "InputCommon/ControllerEmu/ControlGroup/IMUGyroscope.h"
#include "InputCommon/ControllerEmu/ControlGroup/Tilt.h" #include "InputCommon/ControllerEmu/ControlGroup/Tilt.h"


namespace WiimoteEmu namespace WiimoteEmu
Expand Down Expand Up @@ -53,6 +56,9 @@ void EmulateShake(PositionalState* state, ControllerEmu::Shake* shake_group, flo
void EmulateTilt(RotationalState* state, ControllerEmu::Tilt* tilt_group, float time_elapsed); void EmulateTilt(RotationalState* state, ControllerEmu::Tilt* tilt_group, float time_elapsed);
void EmulateSwing(MotionState* state, ControllerEmu::Force* swing_group, float time_elapsed); void EmulateSwing(MotionState* state, ControllerEmu::Force* swing_group, float time_elapsed);
void EmulateCursor(MotionState* state, ControllerEmu::Cursor* ir_group, float time_elapsed); void EmulateCursor(MotionState* state, ControllerEmu::Cursor* ir_group, float time_elapsed);
void EmulateIMUCursor(std::optional<RotationalState>* state, ControllerEmu::IMUCursor* imu_ir_group,
ControllerEmu::IMUAccelerometer* imu_accelerometer_group,
ControllerEmu::IMUGyroscope* imu_gyroscope_group, float time_elapsed);


// Convert m/s/s acceleration data to the format used by Wiimote/Nunchuk (10-bit unsigned integers). // Convert m/s/s acceleration data to the format used by Wiimote/Nunchuk (10-bit unsigned integers).
WiimoteCommon::DataReportBuilder::AccelData ConvertAccelData(const Common::Vec3& accel, u16 zero_g, WiimoteCommon::DataReportBuilder::AccelData ConvertAccelData(const Common::Vec3& accel, u16 zero_g,
Expand Down
80 changes: 68 additions & 12 deletions Source/Core/Core/HW/WiimoteEmu/WiimoteEmu.cpp
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@
#include "InputCommon/ControllerEmu/ControlGroup/ControlGroup.h" #include "InputCommon/ControllerEmu/ControlGroup/ControlGroup.h"
#include "InputCommon/ControllerEmu/ControlGroup/Cursor.h" #include "InputCommon/ControllerEmu/ControlGroup/Cursor.h"
#include "InputCommon/ControllerEmu/ControlGroup/Force.h" #include "InputCommon/ControllerEmu/ControlGroup/Force.h"
#include "InputCommon/ControllerEmu/ControlGroup/IMUAccelerometer.h"
#include "InputCommon/ControllerEmu/ControlGroup/IMUCursor.h"
#include "InputCommon/ControllerEmu/ControlGroup/IMUGyroscope.h"
#include "InputCommon/ControllerEmu/ControlGroup/ModifySettingsButton.h" #include "InputCommon/ControllerEmu/ControlGroup/ModifySettingsButton.h"
#include "InputCommon/ControllerEmu/ControlGroup/Tilt.h" #include "InputCommon/ControllerEmu/ControlGroup/Tilt.h"


Expand Down Expand Up @@ -150,6 +153,7 @@ void Wiimote::Reset()
m_tilt_state = {}; m_tilt_state = {};
m_cursor_state = {}; m_cursor_state = {};
m_shake_state = {}; m_shake_state = {};
m_imu_cursor_state = {};
} }


Wiimote::Wiimote(const unsigned int index) : m_index(index) Wiimote::Wiimote(const unsigned int index) : m_index(index)
Expand All @@ -169,6 +173,11 @@ Wiimote::Wiimote(const unsigned int index) : m_index(index)
groups.emplace_back(m_swing = new ControllerEmu::Force(_trans("Swing"))); groups.emplace_back(m_swing = new ControllerEmu::Force(_trans("Swing")));
groups.emplace_back(m_tilt = new ControllerEmu::Tilt(_trans("Tilt"))); groups.emplace_back(m_tilt = new ControllerEmu::Tilt(_trans("Tilt")));
groups.emplace_back(m_shake = new ControllerEmu::Shake(_trans("Shake"))); groups.emplace_back(m_shake = new ControllerEmu::Shake(_trans("Shake")));
groups.emplace_back(m_imu_accelerometer = new ControllerEmu::IMUAccelerometer(
"IMUAccelerometer", _trans("Accelerometer")));
groups.emplace_back(m_imu_gyroscope =
new ControllerEmu::IMUGyroscope("IMUGyroscope", _trans("Gyroscope")));
groups.emplace_back(m_imu_ir = new ControllerEmu::IMUCursor("IMUIR", _trans("Point")));


// Extension // Extension
groups.emplace_back(m_attachments = new ControllerEmu::Attachments(_trans("Extension"))); groups.emplace_back(m_attachments = new ControllerEmu::Attachments(_trans("Extension")));
Expand Down Expand Up @@ -263,6 +272,12 @@ ControllerEmu::ControlGroup* Wiimote::GetWiimoteGroup(WiimoteGroup group)
return m_options; return m_options;
case WiimoteGroup::Hotkeys: case WiimoteGroup::Hotkeys:
return m_hotkeys; return m_hotkeys;
case WiimoteGroup::IMUAccelerometer:
return m_imu_accelerometer;
case WiimoteGroup::IMUGyroscope:
return m_imu_gyroscope;
case WiimoteGroup::IMUPoint:
return m_imu_ir;
default: default:
assert(false); assert(false);
return nullptr; return nullptr;
Expand Down Expand Up @@ -447,7 +462,7 @@ void Wiimote::SendDataReport()
{ {
// Calibration values are 8-bit but we want 10-bit precision, so << 2. // Calibration values are 8-bit but we want 10-bit precision, so << 2.
DataReportBuilder::AccelData accel = DataReportBuilder::AccelData accel =
ConvertAccelData(GetAcceleration(), ACCEL_ZERO_G << 2, ACCEL_ONE_G << 2); ConvertAccelData(GetTotalAcceleration(), ACCEL_ZERO_G << 2, ACCEL_ONE_G << 2);
rpt_builder.SetAccelData(accel); rpt_builder.SetAccelData(accel);
} }


Expand All @@ -456,7 +471,7 @@ void Wiimote::SendDataReport()
{ {
// Note: Camera logic currently contains no changing state so we can just update it here. // Note: Camera logic currently contains no changing state so we can just update it here.
// If that changes this should be moved to Wiimote::Update(); // If that changes this should be moved to Wiimote::Update();
m_camera_logic.Update(GetTransformation()); m_camera_logic.Update(GetTotalTransformation());


// The real wiimote reads camera data from the i2c bus starting at offset 0x37: // The real wiimote reads camera data from the i2c bus starting at offset 0x37:
const u8 camera_data_offset = const u8 camera_data_offset =
Expand All @@ -477,7 +492,7 @@ void Wiimote::SendDataReport()
if (m_is_motion_plus_attached) if (m_is_motion_plus_attached)
{ {
// TODO: Make input preparation triggered by bus read. // TODO: Make input preparation triggered by bus read.
m_motion_plus.PrepareInput(GetAngularVelocity()); m_motion_plus.PrepareInput(GetTotalAngularVelocity());
} }


u8* ext_data = rpt_builder.GetExtDataPtr(); u8* ext_data = rpt_builder.GetExtDataPtr();
Expand Down Expand Up @@ -670,6 +685,20 @@ void Wiimote::LoadDefaults(const ControllerInterface& ciface)
m_dpad->SetControlExpression(3, "Right"); // Right m_dpad->SetControlExpression(3, "Right"); // Right
#endif #endif


// Motion Source
m_imu_accelerometer->SetControlExpression(0, "Accel Left");
m_imu_accelerometer->SetControlExpression(1, "Accel Right");
m_imu_accelerometer->SetControlExpression(2, "Accel Forward");
m_imu_accelerometer->SetControlExpression(3, "Accel Backward");
m_imu_accelerometer->SetControlExpression(4, "Accel Up");
m_imu_accelerometer->SetControlExpression(5, "Accel Down");
m_imu_gyroscope->SetControlExpression(0, "Gyro Pitch Up");
m_imu_gyroscope->SetControlExpression(1, "Gyro Pitch Down");
m_imu_gyroscope->SetControlExpression(2, "Gyro Roll Left");
m_imu_gyroscope->SetControlExpression(3, "Gyro Roll Right");
m_imu_gyroscope->SetControlExpression(4, "Gyro Yaw Left");
m_imu_gyroscope->SetControlExpression(5, "Gyro Yaw Right");

// Enable Nunchuk: // Enable Nunchuk:
constexpr ExtensionNumber DEFAULT_EXT = ExtensionNumber::NUNCHUK; constexpr ExtensionNumber DEFAULT_EXT = ExtensionNumber::NUNCHUK;
m_attachments->SetSelectedAttachment(DEFAULT_EXT); m_attachments->SetSelectedAttachment(DEFAULT_EXT);
Expand Down Expand Up @@ -720,36 +749,36 @@ void Wiimote::StepDynamics()
EmulateTilt(&m_tilt_state, m_tilt, 1.f / ::Wiimote::UPDATE_FREQ); EmulateTilt(&m_tilt_state, m_tilt, 1.f / ::Wiimote::UPDATE_FREQ);
EmulateCursor(&m_cursor_state, m_ir, 1.f / ::Wiimote::UPDATE_FREQ); EmulateCursor(&m_cursor_state, m_ir, 1.f / ::Wiimote::UPDATE_FREQ);
EmulateShake(&m_shake_state, m_shake, 1.f / ::Wiimote::UPDATE_FREQ); EmulateShake(&m_shake_state, m_shake, 1.f / ::Wiimote::UPDATE_FREQ);
EmulateIMUCursor(&m_imu_cursor_state, m_imu_ir, m_imu_accelerometer, m_imu_gyroscope,
1.f / ::Wiimote::UPDATE_FREQ);
} }


Common::Vec3 Wiimote::GetAcceleration() Common::Vec3 Wiimote::GetAcceleration(Common::Vec3 extra_acceleration)
{ {
Common::Vec3 accel = Common::Vec3 accel = GetOrientation() * GetTransformation().Transform(
GetOrientation() * m_swing_state.acceleration + extra_acceleration, 0);
GetTransformation().Transform(
m_swing_state.acceleration + Common::Vec3(0, 0, float(GRAVITY_ACCELERATION)), 0);


// Our shake effects have never been affected by orientation. Should they be? // Our shake effects have never been affected by orientation. Should they be?
accel += m_shake_state.acceleration; accel += m_shake_state.acceleration;


return accel; return accel;
} }


Common::Vec3 Wiimote::GetAngularVelocity() Common::Vec3 Wiimote::GetAngularVelocity(Common::Vec3 extra_angular_velocity)
{ {
return GetOrientation() * (m_tilt_state.angular_velocity + m_swing_state.angular_velocity + return GetOrientation() * (m_tilt_state.angular_velocity + m_swing_state.angular_velocity +
m_cursor_state.angular_velocity); m_cursor_state.angular_velocity + extra_angular_velocity);
} }


Common::Matrix44 Wiimote::GetTransformation() const Common::Matrix44 Wiimote::GetTransformation(Common::Vec3 extra_rotation) const
{ {
// Includes positional and rotational effects of: // Includes positional and rotational effects of:
// Cursor, Swing, Tilt, Shake // Cursor, Swing, Tilt, Shake


// TODO: Think about and clean up matrix order + make nunchuk match. // TODO: Think about and clean up matrix order + make nunchuk match.
return Common::Matrix44::Translate(-m_shake_state.position) * return Common::Matrix44::Translate(-m_shake_state.position) *
Common::Matrix44::FromMatrix33(GetRotationalMatrix( Common::Matrix44::FromMatrix33(GetRotationalMatrix(
-m_tilt_state.angle - m_swing_state.angle - m_cursor_state.angle)) * -m_tilt_state.angle - m_swing_state.angle - m_cursor_state.angle - extra_rotation)) *
Common::Matrix44::Translate(-m_swing_state.position - m_cursor_state.position); Common::Matrix44::Translate(-m_swing_state.position - m_cursor_state.position);
} }


Expand All @@ -759,4 +788,31 @@ Common::Matrix33 Wiimote::GetOrientation() const
Common::Matrix33::RotateX(float(MathUtil::TAU / 4 * IsUpright())); Common::Matrix33::RotateX(float(MathUtil::TAU / 4 * IsUpright()));
} }


Common::Vec3 Wiimote::GetTotalAcceleration()
{
auto accel = m_imu_accelerometer->GetState();
if (accel.has_value())
return GetAcceleration(accel.value());
else
return GetAcceleration();
}

Common::Vec3 Wiimote::GetTotalAngularVelocity()
{
auto ang_vel = m_imu_gyroscope->GetState();
if (ang_vel.has_value())
return GetAngularVelocity(ang_vel.value());
else
return GetAngularVelocity();
}

Common::Matrix44 Wiimote::GetTotalTransformation() const
{
auto state = m_imu_cursor_state;
if (state.has_value())
return GetTransformation(state->angle);
else
return GetTransformation();
}

} // namespace WiimoteEmu } // namespace WiimoteEmu
Loading

0 comments on commit 1f3d1a9

Please sign in to comment.